/*------------------------------------------------------------------------ S I C S C R O N A cron like command facility for SICS which allows to repeat a command at given time intervals. copyright: see copyright.h Mark Koennecke, November 1999 modified to give more error output: Mark Koennecke, December 2010 ------------------------------------------------------------------------*/ #include #include #include #include "macro.h" #include "fortify.h" #include "sics.h" #include "splitter.h" #include "sicscron.h" #include "commandlog.h" typedef struct { int iInterval; time_t tNext; char *pCommand; SConnection *pCon; int iEnd; Statistics *stat; } Cron, *pCron; typedef struct { SConnection *pCon; int dolater; } CronListData; /*------------------------------------------------------------------------*/ static void KillCron(void *pData) { pCron self = (pCron) pData; if (!self) { return; } if (self->pCommand) { free(self->pCommand); } if (self->pCon) { SCDeleteConnection(self->pCon); } if (self->stat) { StatisticsKill(self->stat); } free(self); } /*-----------------------------------------------------------------------*/ static int CronTask(void *pData) { Statistics *old; pCron self = (pCron) pData; int iRet; Tcl_Interp *pTcl = pServ->pSics->pTcl; time_t now; struct tm *nowtm; char buffer[1024]; if (!self) { return 0; } now = time(NULL); if (now >= self->tNext) { MacroPush(self->pCon); old = StatisticsBegin(self->stat); iRet = Tcl_Eval(pTcl, self->pCommand); StatisticsEnd(old); MacroPop(); if (iRet != TCL_OK) { if (strcmp(pTcl->result, "stop") == 0) { snprintf(buffer,1024,"sicscron script '%s' stopped", self->pCommand); SCPrintf(self->pCon, eLogError, buffer); WriteToCommandLog("SICSCRON:", buffer); self->iEnd = 0; return 0; } snprintf(buffer,1024,"ERROR in sicscron script '%s': %s", self->pCommand, pTcl->result); SCPrintf(self->pCon, eLogError,buffer); WriteToCommandLog("SICSCRON:", buffer); } if (self->iEnd == 2) { /* dolater command */ self->iEnd = 0; return 0; } self->tNext += self->iInterval; if (now > self->tNext) self->tNext = now; } /* printf("CronTask return: %d\n", self->iEnd > 0);*/ if(self->iEnd <= 0){ snprintf(buffer,1024,"crontask terminating at %s on %d", ctime(&now), self->iEnd); WriteToCommandLog("SICSCRON", buffer); } return self->iEnd > 0; } /*-----------------------------------------------------------------------*/ static void CronSignal(void *pData, int iID, void *pSigData) { pCron self = (pCron) pData; int *iInt; struct tm tm; char datim[24]; CronListData *data; if (iID == SICSINT) { iInt = (int *) pSigData; if (*iInt == eEndServer) { self->iEnd = 0; } } if (iID == CRONLIST) { data = pSigData; if (self->iEnd == 2 && data->dolater) { tm = *localtime(&self->tNext); strftime(datim, sizeof datim, "%Y-%m-%d %T", &tm); SCPrintf(data->pCon, eLog, "%s %s", datim, self->pCommand); } else if (self->iEnd == 1 && !data->dolater) { tm = *localtime(&self->tNext); strftime(datim, sizeof datim, "%Y-%m-%d %T", &tm); SCPrintf(data->pCon, eLog, "%s %8d %s", datim, self->iInterval, self->pCommand); } } } /*-----------------------------------------------------------------------*/ int MakeCron(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) { pCron pNew = NULL; int iVal, iRet, rights; char *cmd; CronListData data; /* need user priv. */ if (!SCMatchRights(pCon, usUser)) { return 0; } if (argc == 2 && strcasecmp(argv[1], "list") == 0) { if (strcasecmp(argv[0], "dolater") == 0) { data.dolater = 1; SCPrintf(pCon, eError, "Date Time Command"); } else { data.dolater = 0; SCPrintf(pCon, eError, "Date Time Interval Command"); } data.pCon = pCon; TaskSignal(pServ->pTasker, CRONLIST, &data); return 1; } /* enough arguments? */ if (argc < 3) { SCPrintf(pCon, eError, "ERROR: usage: %s