/*------------------------------------------------------------------------ S I C S C R O N A cron like command facility for SICS which allows to repeat a command at given time intervalls. copyright: see copyright.h Mark Koennecke, November 1999 ------------------------------------------------------------------------*/ #include #include #include #include #include "fortify.h" #include "sics.h" #include "splitter.h" #include "sicscron.h" typedef struct { int iIntervall; time_t tNext; char *pCommand; SConnection *pCon; int iEnd; } Cron, *pCron; /*------------------------------------------------------------------------*/ static void KillCron(void *pData) { pCron self = (pCron)pData; if(!self) { return; } if(self->pCommand) { free(self->pCommand); } if(self->pCon) { SCDeleteConnection(self->pCon); } free(self); } /*-----------------------------------------------------------------------*/ static int CronTask(void *pData) { pCron self = (pCron)pData; if(!self) { return 0; } if(time(NULL) > self->tNext) { SCInvoke(self->pCon,pServ->pSics,self->pCommand); self->tNext = time(NULL) + self->iIntervall; } return self->iEnd; } /*-----------------------------------------------------------------------*/ static void CronSignal(void *pData, int iID, void *pSigData) { pCron self = (pCron)pData; int *iInt; if(iID == SICSINT) { iInt = (int *)pSigData; if(*iInt >= eEndServer) { self->iEnd = 0; } } } /*-----------------------------------------------------------------------*/ int MakeCron(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { pCron pNew = NULL; int iVal, iRet; char *cmd; /* only managers may do this */ if(!SCMatchRights(pCon,usMugger)) { return 0; } /* enough arguments? */ if(argc < 3) { SCWrite(pCon,"ERROR: not enough arguments to sicscron",eError); return 0; } /* interpret first argument as intervall in seconds */ iRet = Tcl_GetInt(pSics->pTcl,argv[1],&iVal); if(iRet != TCL_OK) { SCWrite(pCon,"ERROR: failed to convert intervall argument to int", eError); return 0; } /* concatenate the rest to the command */ cmd = Arg2Tcl(argc-2,&argv[2],NULL,0); /* create data structure and install task */ pNew = (pCron)malloc(sizeof(Cron)); if(!pNew || !cmd) { SCWrite(pCon,"ERROR: out of memory in sicscron",eError); return 0; } pNew->pCon = SCCreateDummyConnection(pSics); if(!pNew->pCon) { SCWrite(pCon,"ERROR: out of memory in sicscron",eError); return 0; } pNew->iIntervall = iVal; pNew->pCommand = cmd; pNew->tNext = 0; pNew->iEnd = 1; TaskRegister(pServ->pTasker, CronTask, CronSignal, KillCron, pNew, 1); SCSendOK(pCon); return 1; }