/** * This is the SICS interface object to the tasker module * * copyright: GPL * * Mark Koennecke, December 2012 */ #include #include "sicsobj.h" #include "sicshipadaba.h" #include "stptok.h" #include "macro.h" typedef struct { char *scriptName; SConnection *con; } TclFunc, *pTclFunc; /*-------------------------------------------------------------------------*/ static int ListCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, pHdb par[], int nPar) { pDynString result = NULL; char buffer[256], *pDes, *pPtr, name[80], time[80], id[80], gid[80]; pTaskHead it = NULL; result = CreateDynString(128,128); if(result == NULL){ SCWrite(pCon,"ERROR: out of memory in ListCmd", eError); return 0; } snprintf(buffer,sizeof(buffer),"%20s %20s %12s", "Task", "Start_Time", "ID"); DynStringConcat(result,buffer); DynStringConcatChar(result,'\n'); for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)){ pDes = TaskDescription(it); if(pDes != NULL){ pPtr = stptok(pDes,name,sizeof(name),"|"); pPtr = stptok(pPtr,time,sizeof(time),"|"); pPtr = stptok(pPtr,id,sizeof(id),"|"); pPtr = stptok(pPtr,gid,sizeof(gid),"|"); snprintf(buffer,sizeof(buffer),"%20s %20s %12s %10s", name,time,id,gid); DynStringConcat(result,buffer); DynStringConcatChar(result,'\n'); free(pDes); } } SCWrite(pCon,GetCharArray(result),eValue); DeleteDynString(result); return 1; } /*----------------------------------------------------------------------*/ static int KillCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, pHdb par[], int nPar) { int status; if(nPar < 1){ SCWrite(pCon,"ERROR: need name of task to stop", eError); return 0; } if(!SCMatchRights(pCon,usMugger)){ return 0; } status = StopTask(pServ->pTasker,par[0]->value.v.text); if(status == 0) { SCWrite(pCon,"ERROR: cannot commit suicide!", eError); return 0; } SCSendOK(pCon); return 1; } /*--------------------------------------------------------------------*/ static int TclTaskFunction(void *pData) { int retVal, status ; Tcl_Interp *pTcl; pTclFunc self = (pTclFunc)pData; assert(self != NULL); pTcl = InterpGetTcl(pServ->pSics); assert(pTcl != NULL); MacroPush(self->con); status = Tcl_Eval(pTcl, self->scriptName); MacroPop(); traceSys("task","Executed %s with results %d and %s",self->scriptName, status, Tcl_GetStringResult(pTcl)); if(status == 0){ retVal = atoi(Tcl_GetStringResult(pTcl)); } else { return 1; } return retVal; } /*--------------------------------------------------------------------*/ static void KillTclFunc(void *pData) { pTclFunc self = (pTclFunc)pData; if(self == NULL){ return; } if(self->scriptName){ free(self->scriptName); } if(self->con) { SCDeleteConnection(self->con); } free(self); } /*------------------------------------------------------------------*/ static void TclFuncSignal(void *pData, int iSignal, void *pSigData) { int *iInt; pTclFunc self = NULL; self = (pTclFunc) pData; assert(self); if (iSignal == SICSINT) { iInt = (int *) pSigData; SCSetInterrupt(self->con,*iInt); } } /*----------------------------------------------------------------------*/ static int RunCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, pHdb par[], int nPar) { pTclFunc data = NULL; if(nPar < 1) { SCWrite(pCon,"ERROR: need the name of a script to run",eError); return 0; } data = malloc(sizeof(TclFunc)); if(data == NULL){ SCWrite(pCon,"ERROR: out of memory in RunCmd",eError); return 0; } memset(data,0,sizeof(TclFunc)); data->con = SCCreateDummyConnection(pServ->pSics); data->scriptName = strdup(par[0]->value.v.text); TaskRegisterN(pServ->pTasker, data->scriptName, TclTaskFunction, TclFuncSignal, KillTclFunc, data, 0); traceSys("task","Started task %s",data->scriptName); SCSendOK(pCon); return 1; } /*--------------------------------------------------------------------*/ int TaskOBJFactory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { pSICSOBJ pNew = NULL; pHdb cmd = NULL, node; pNew = SetupSICSOBJ(pCon,pSics,pData,argc,argv); if(pNew == NULL){ return 0; } cmd = AddSICSHdbPar(pNew->objectNode, "ps", usSpy, MakeSICSFunc(ListCmd)); cmd = AddSICSHdbPar(pNew->objectNode, "kill", usSpy, MakeSICSFunc(KillCmd)); SetHdbProperty(cmd,"type","command"); SetHdbProperty(cmd,"priv","spy"); node = MakeSICSHdbPar("task",usSpy,MakeHdbText("banana")); AddHipadabaChild(cmd,node,NULL); cmd = AddSICSHdbPar(pNew->objectNode, "run", usSpy, MakeSICSFunc(RunCmd)); SetHdbProperty(cmd,"type","command"); SetHdbProperty(cmd,"priv","spy"); node = MakeSICSHdbPar("script",usSpy,MakeHdbText("banana")); AddHipadabaChild(cmd,node,NULL); return 1; } /*-------------------------------------------------------------------*/ void InitTaskOBJ() { pSICSOBJ pNew = NULL; pHdb cmd = NULL, node; pNew = MakeSICSOBJv("task", "TaskOBJ", HIPNONE, usInternal); if (pNew == NULL) { SCWrite(pServ->dummyCon, "ERROR: out of memory creating new SICS object", eError); return; } cmd = AddSICSHdbPar(pNew->objectNode, "ps", usSpy, MakeSICSFunc(ListCmd)); cmd = AddSICSHdbPar(pNew->objectNode, "kill", usSpy, MakeSICSFunc(KillCmd)); SetHdbProperty(cmd,"type","command"); SetHdbProperty(cmd,"priv","spy"); node = MakeSICSHdbPar("task",usSpy,MakeHdbText("banana")); AddHipadabaChild(cmd,node,NULL); cmd = AddSICSHdbPar(pNew->objectNode, "run", usSpy, MakeSICSFunc(RunCmd)); SetHdbProperty(cmd,"type","command"); SetHdbProperty(cmd,"priv","spy"); node = MakeSICSHdbPar("script",usSpy,MakeHdbText("banana")); AddHipadabaChild(cmd,node,NULL); AddCommand(pServ->pSics, "task", InterInvokeSICSOBJ, KillSICSOBJ, pNew); }