PSI sics-cvs-psi-2006

This commit is contained in:
2006-05-08 02:00:00 +00:00
committed by Douglas Clowes
parent ae77364de2
commit 6e926b813f
388 changed files with 445529 additions and 14109 deletions

188
macro.c
View File

@@ -1,8 +1,8 @@
/*--------------------------------------------------------------------------
All you need to evaluate macros with SICS.
All you need to evaluate macros with SICS
The implmentation fo the macro stuff is complex and non intuitive.
The implmentation for the macro stuff is complex and non intuitive.
This is the price to pay for adding the extremly powerful and
strong Tcl-interpreter to SICS. The problem is that Tcl does not
know anything about connections and our error handling. We have
@@ -22,6 +22,8 @@
Mark Koennecke, December 1999
InternalFileEval added
Mark Koennecke, May 2004
Added protected exec called sys.
Copyright:
@@ -68,6 +70,7 @@
#include "ifile.h"
#include "Dbg.h"
#include "servlog.h"
#include "stringdict.h"
#define SICSERROR "005567SICS"
/*----------------------------------------------------------------------------
@@ -126,7 +129,7 @@
SConnection *pCon = NULL;
CommandList *pCommand = NULL;
char *lastCommand = NULL, comBuffer[132];
int iRet,i;
int iRet = 0,i;
int iMacro;
/* get the datastructures */
@@ -135,6 +138,7 @@
pSinter = pSics->pInter;
pCon = pSics->pCon[pSics->iStack];
lastCommand = pSics->lastUnknown[pSics->iStack];
pCon->sicsError = 0;
assert(pSinter);
assert(pCon);
@@ -163,21 +167,21 @@
{
if(strcmp(lastCommand,comBuffer) == 0)
{
Tcl_AppendResult(pInter,"ERROR: Never ending loop in unknown\n",
Tcl_AppendResult(pInter,"ERROR: Never ending loop in unknown\n",
"Offending command: ",comBuffer,
"Probably Tcl command not found",NULL);
" Probably Tcl command not found",NULL);
SCSetInterrupt(pCon,eAbortBatch);
return TCL_ERROR;
}
}
pSics->lastUnknown[pSics->iStack] = strdup(comBuffer);
if (pSics->lastUnknown[pSics->iStack]) free(pSics->lastUnknown[pSics->iStack]);
pSics->lastUnknown[pSics->iStack] = strdup(comBuffer);
/* invoke */
iMacro = SCinMacro(pCon);
SCsetMacro(pCon,1);
iRet = pCommand->OFunc(pCon,pSinter,pCommand->pData,margc, myarg);
SCsetMacro(pCon,iMacro);
/*
lastUnkown gets deeply stacked with each SICS command exec'd.
This is not reflected in code. However, lastUnknown has already
@@ -190,13 +194,14 @@
}
/* finish */
if(iRet)
if(iRet == 1)
{
return TCL_OK;
}
else
{
Tcl_SetVar(pInter,SICSERROR,"yes",TCL_GLOBAL_ONLY);
pCon->sicsError = 1;
return TCL_ERROR;
}
}
@@ -213,6 +218,84 @@
free(pData);
pUnbekannt = NULL;
}
/*-----------------------------------------------------------------------*/
void KillSicsUnknown(void) {
if (pUnbekannt) {
UnknownKill(pUnbekannt);
pUnbekannt = NULL;
}
}
/*------------------------------------------------------------------------
Implementation of a protected exec command
--------------------------------------------------------------------------*/
static pStringDict allowedCommands = NULL;
/*----------------------------------------------------------------------*/
int AllowExec(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
if(argc < 2)
{
SCWrite(pCon,"ERROR: not enough arguments to allowexec",eError);
return 0;
}
if(!SCMatchRights(pCon,usInternal))
{
return 0;
}
if(allowedCommands == NULL)
{
allowedCommands = CreateStringDict();
if(allowedCommands == NULL)
{
SCWrite(pCon,
"ERROR: not enough memory for list of allowed system commands",
eError);
return 0;
}
}
StringDictAddPair(allowedCommands,argv[1],"Allowed!");
return 1;
}
/*--------------------------------------------------------------------*/
static void KillExec(ClientData data)
{
if(allowedCommands != NULL)
{
DeleteStringDict(allowedCommands);
allowedCommands = NULL;
}
}
/*------------------------------------------------------------------------
This is in the Tcl sources
*/
extern int Tcl_ExecObjCmd(ClientData data, Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[]);
/*-----------------------------------------------------------------------*/
static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[])
{
char *test = NULL;
if(objc < 2)
{
return Tcl_ExecObjCmd(clientData,interp,objc, objv);
}
test = Tcl_GetStringFromObj(objv[1],NULL);
if(allowedCommands != NULL)
{
if(StringDictExists(allowedCommands,test))
{
return Tcl_ExecObjCmd(clientData,interp,objc, objv);
}
}
/*
if we are here, we are not allowed to invoke this command
*/
Tcl_AppendResult(interp,"System command NOT allowed!",NULL);
return TCL_ERROR;
}
/*--------------------------------------------------------------------------
initialises a Tcl-Interpreter, installs SICS unknown mechanism and kills
a few dangerous commands from the normal Tcl command set
@@ -244,15 +327,22 @@
pUnknown->iStack = 0;
pUnknown->pInter = pSics;
pUnbekannt = pUnknown;
Tcl_CreateCommand(pInter,"unknown",SicsUnknownProc,
/* the cast before SicsUnknwonProc is to avoid a warning
Tcl_CmdProc has a const char instead of char as argument M.Z. */
Tcl_CreateCommand(pInter,"unknown",(Tcl_CmdProc *)SicsUnknownProc,
pUnknown, UnknownKill);
/* delete dangers */
Tcl_DeleteCommand(pInter,"exit");
Tcl_DeleteCommand(pInter,"socket");
Tcl_DeleteCommand(pInter,"vwait");
Tcl_DeleteCommand(pInter,"exec");
/*
install protected exec command
*/
Tcl_CreateObjCommand(pInter,"exec",ProtectedExec,NULL,KillExec);
return pInter;
}
/*--------------------------------------------------------------------------*/
@@ -377,7 +467,6 @@
{
sprintf(pBueffel," Failed to open file -> %s <- ",argv[1]);
SCWrite(pCon,pBueffel,eError);
/* SCSetInterrupt(pCon,eAbortBatch); */
return 0;
}
@@ -435,7 +524,11 @@
{ /* Tcl error */
if(strlen(pTcl->result) > 2)
{
SCWrite(pCon,pTcl->result,eError);
/*
local copy in order to resolve a valgrind error
*/
strncpy(pBueffel,pTcl->result,511);
SCWrite(pCon,pBueffel,eError);
}
pCom = Tcl_DStringValue(&command);
SCWrite(pCon,"ERROR: in Tcl block:",eError);
@@ -453,7 +546,7 @@
fclose(fp);
Tcl_DStringFree(&command);
SCWrite(pCon,"ERROR: batch processing interrupted",eError);
SetStatus(eOld);
SetStatus(eEager);
return 0;
}
else
@@ -549,7 +642,7 @@
int ClientPut(SConnection *pCon, SicsInterp *pInter, void *pData,
int argc, char *argv[])
{
OutCode eOut = eStatus;
OutCode eOut = eWarning;
int i = 0, iCode, iLen;
int iMacro;
char *ppCode;
@@ -614,10 +707,19 @@
eOut = eWarning;
break;
case 7:
eOut = eFinish;
break;
case 8:
eOut = eEvent;
break;
case 9:
eOut = eWarning;
break;
case 10:
eOut = eError;
break;
default:
eOut = eStatus;
eOut = eWarning;
iCode = argc;
break;
}
@@ -742,8 +844,9 @@
int argc, char *argv[])
{
char pBueffel[1024];
char *pCommand;
pPubTcl self = NULL;
int iRet;
int iRet, length;
char *pPtr;
Tcl_Interp *pTcl = NULL;
@@ -762,28 +865,32 @@
}
/* make a string */
Arg2Text(argc,argv,pBueffel,1023);
iRet = Tcl_Eval(pTcl,pBueffel);
pCommand = Arg2Tcl(argc,argv,pBueffel,sizeof(pBueffel));
if (!pCommand) {
SCWrite(pCon, "ERROR: no more memory", eError);
return 0;
}
iRet = Tcl_Eval(pTcl,pCommand);
if (pCommand != pBueffel) free(pCommand);
if(iRet == TCL_OK)
{ /* possibly a bug here */
SCWrite(pCon,pTcl->result,eStatus);
{
/* we do not now why, but at some time it was found that
we need a copy, and can not use pTcl->result directly
SCWrite(pCon,pTcl->result,eStatus);
let us use SCPrintf, which maked always a copy
*/
SCPrintf(pCon, eStatus, "%s", pTcl->result);
return 1;
}
else
{
if(Tcl_GetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY) == NULL)
{
pPtr = strdup(pTcl->result);
SCWrite(pCon,pPtr,eError);
free(pPtr);
}
else
if(Tcl_GetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY) != NULL)
{
Tcl_UnsetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY);
SCWrite(pCon,pTcl->result,eError);
}
SCPrintf(pCon,eError,"%s",pTcl->result);
return 0;
}
return 1; /* not reached */
@@ -835,6 +942,13 @@
return 0;
}
/* check if the macro already exists */
pNew = FindCommandData(pSics, argv[1], "Macro");
if (pNew)
{ /* yes -> overwrite access code */
pNew->iUser = iUser;
return 0;
}
/* do a job !*/
pNew = CreatePublish(argv[1],iUser);
if(!pNew)
@@ -864,17 +978,21 @@
int TransactAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
char pCommand[1024], pStart[1024];
char pBuffer[1024];
char *pCommand;
int iRet;
Arg2Text(argc-1,&argv[1],pCommand,1023);
pCommand = Arg2Tcl(argc-1,&argv[1],pBuffer, sizeof(pBuffer));
if (!pCommand) {
SCWrite(pCon,"ERROR: no memory", eError);
return 0;
}
strtolower(argv[0]);
if(strcmp(argv[0],"fulltransact") == 0){
snprintf(pStart,1024,"TRANSACTIONSTART %s",pCommand);
SCWrite(pCon,pStart,eError);
SCPrintf(pCon,eError, "TRANSACTIONSTART %s",pCommand);
}
iRet = InterpExecute(pSics,pCon,pCommand);
SicsWait(1);
if (pCommand != pBuffer) free(pCommand);
SCWrite(pCon,"TRANSACTIONFINISHED",eError);
return iRet;
}