Files
sics/taskobj.c
zolliker 8096212c52 - introduced "stopexe run"
- fixed "task ps" to show names containing ':' correctly
2013-05-24 05:44:52 +00:00

225 lines
5.9 KiB
C

/**
* This is the SICS interface object to the tasker module
*
* copyright: GPL
*
* Mark Koennecke, December 2012
*/
#include <sics.h>
#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);
}