Files
sics/nxupdate.c
2015-07-29 17:47:46 +10:00

337 lines
9.0 KiB
C

/*-----------------------------------------------------------------------
Automatic update of NeXus files a scheduled time intervalls.
For more information see nxudpate.tex.
copyright: see file COPYRIGHT
Mark Koennecke, December 2003
----------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <time.h>
#include "fortify.h"
#include "sics.h"
#include "splitter.h"
#include "nxupdate.h"
#include "nxupdate.i"
/*-------------------------------------------------------------------*/
static int UpdateTask(void *pData)
{
pNXupdate self = NULL;
self = (pNXupdate) pData;
if (self == NULL) {
return 0;
}
if (self->onOff == 0) {
return 0;
}
/*
update when intervall reached or when end
*/
if (time(NULL) >= self->nextUpdate || self->iEnd == 1) {
if (self->updateScript != NULL && self->pCon != NULL) {
InterpExecute(pServ->pSics, self->pCon, self->updateScript);
}
self->nextUpdate = time(NULL) + self->updateIntervall;
}
if (self->iEnd == 1) {
self->pCon = NULL;
return 0;
} else {
return 1;
}
}
/*--------------------------------------------------------------------*/
static int CountCallback(int iEvent, void *pEventData, void *pUser)
{
pNXupdate self = NULL;
SConnection *pCon = NULL;
self = (pNXupdate) pUser;
pCon = (SConnection *) pEventData;
if (self->onOff == 0) {
return 1;
}
if (iEvent == COUNTSTART) {
assert(pCon);
assert(self);
/*
start file
*/
if (self->startScript != NULL) {
InterpExecute(pServ->pSics, pCon, self->startScript);
}
if (self->updateScript != NULL) {
InterpExecute(pServ->pSics, pCon, self->updateScript);
}
if (self->linkScript != NULL) {
InterpExecute(pServ->pSics, pCon, self->linkScript);
}
/*
register update function
*/
self->nextUpdate = time(NULL) + self->updateIntervall;
self->iEnd = 0;
self->pCon = pCon;
TaskRegisterN(pServ->pTasker, "NXupdater", UpdateTask, NULL, NULL, self, TASK_PRIO_HIGH);
return 1;
} else if (iEvent == COUNTEND) {
self->iEnd = 1;
assert(self);
return 1;
}
return 1;
}
/*----------------------------------------------------------------------*/
void KillUpdate(void *pData)
{
pNXupdate self = NULL;
self = (pNXupdate) pData;
if (self == NULL) {
return;
}
if (self->startScript != NULL) {
free(self->startScript);
self->startScript = NULL;
}
if (self->updateScript != NULL) {
free(self->updateScript);
self->updateScript = NULL;
}
if (self->linkScript != NULL) {
free(self->linkScript);
self->linkScript = NULL;
}
free(self);
}
/*-------------------------------------------------------------------*/
static void printUpdateList(SConnection * pCon, pNXupdate self, char *name)
{
char pBueffel[256];
snprintf(pBueffel, 255, "%s.startScript = %s", name, self->startScript);
SCWrite(pCon, pBueffel, eValue);
snprintf(pBueffel, 255, "%s.updateScript = %s", name,
self->updateScript);
SCWrite(pCon, pBueffel, eValue);
snprintf(pBueffel, 255, "%s.linkScript = %s", name, self->linkScript);
SCWrite(pCon, pBueffel, eValue);
snprintf(pBueffel, 255, "%s.updateIntervall = %d", name,
self->updateIntervall);
SCWrite(pCon, pBueffel, eValue);
snprintf(pBueffel, 255, "%s.onOff = %d", name, self->onOff);
SCWrite(pCon, pBueffel, eValue);
}
/*--------------------------------------------------------------------*/
static int printUpdateParameters(SConnection * pCon, pNXupdate self,
char *name, char *param)
{
char pBueffel[256];
if (strcmp(param, "list") == 0) {
printUpdateList(pCon, self, name);
return 1;
} else if (strcmp(param, "startscript") == 0) {
snprintf(pBueffel, 255, "%s.startScript = %s", name,
self->startScript);
SCWrite(pCon, pBueffel, eValue);
return 1;
} else if (strcmp(param, "updatescript") == 0) {
snprintf(pBueffel, 255, "%s.updateScript = %s", name,
self->updateScript);
SCWrite(pCon, pBueffel, eValue);
return 1;
} else if (strcmp(param, "linkscript") == 0) {
snprintf(pBueffel, 255, "%s.linkScript = %s", name, self->linkScript);
SCWrite(pCon, pBueffel, eValue);
return 1;
} else if (strcmp(param, "updateintervall") == 0) {
snprintf(pBueffel, 255, "%s.updateIntervall = %d", name,
self->updateIntervall);
SCWrite(pCon, pBueffel, eValue);
return 1;
} else if (strcmp(param, "onoff") == 0) {
snprintf(pBueffel, 255, "%s.onoff = %d", name, self->onOff);
SCWrite(pCon, pBueffel, eValue);
return 1;
} else {
snprintf(pBueffel, 255, "ERROR: parameter %s not known", param);
SCWrite(pCon, pBueffel, eValue);
return 0;
}
}
/*---------------------------------------------------------------------*/
static int configureUpdate(SConnection * pCon, pNXupdate self,
char *param, char *value)
{
char pBueffel[256];
int newUpdate;
if (strcmp(param, "startscript") == 0) {
if (self->startScript != NULL) {
free(self->startScript);
}
self->startScript = strdup(value);
SCSendOK(pCon);
return 1;
} else if (strcmp(param, "updatescript") == 0) {
if (self->updateScript != NULL) {
free(self->updateScript);
}
self->updateScript = strdup(value);
SCSendOK(pCon);
return 1;
} else if (strcmp(param, "linkscript") == 0) {
if (self->linkScript != NULL) {
free(self->linkScript);
}
self->linkScript = strdup(value);
SCSendOK(pCon);
return 1;
} else if (strcmp(param, "updateintervall") == 0) {
if (Tcl_GetInt(InterpGetTcl(pServ->pSics), value, &newUpdate) !=
TCL_OK) {
snprintf(pBueffel, 255,
"ERROR: %s not an int, cannot set updateIntervall", value);
SCWrite(pCon, pBueffel, eError);
return 0;
}
self->updateIntervall = newUpdate;
SCSendOK(pCon);
return 1;
} else if (strcmp(param, "onoff") == 0) {
if (Tcl_GetInt(InterpGetTcl(pServ->pSics), value, &newUpdate) !=
TCL_OK) {
snprintf(pBueffel, 255, "ERROR: %s not an int, cannot set onoff",
value);
SCWrite(pCon, pBueffel, eError);
return 0;
}
if (newUpdate >= 1) {
self->onOff = 1;
} else {
self->onOff = 0;
}
SCSendOK(pCon);
return 1;
} else {
snprintf(pBueffel, 255, "ERROR: parameter %s not known", param);
SCWrite(pCon, pBueffel, eValue);
return 0;
}
}
/*----------------------------------------------------------------------*/
int UpdateAction(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pNXupdate self = NULL;
char pBueffel[132];
self = (pNXupdate) pData;
assert(self);
if (argc < 2) {
snprintf(pBueffel, 131, "ERROR: need argument to %s", argv[0]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
if (argc < 3) {
strtolower(argv[1]);
return printUpdateParameters(pCon, self, argv[0], argv[1]);
} else {
Arg2Text(argc - 2, &argv[2], pBueffel, 131);
return configureUpdate(pCon, self, argv[1], pBueffel);
}
/*
not reached
*/
assert(0);
return 0;
}
/*----------------------------------------------------------------------*/
int UpdateFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pICountable pCount = NULL;
pICallBack pCall = NULL;
void *pPtr = NULL;
char pBueffel[256];
pNXupdate self = NULL;
CommandList *pCom = NULL;
if (argc < 3) {
SCWrite(pCon, "ERROR: insuffcient number of argument to UpdateFactory",
eError);
return 0;
}
/*
argv[1] = name
argv[2] = counter with which to register for automatic notifications
*/
pCom = FindCommand(pSics, argv[2]);
if (pCom) {
pPtr = pCom->pData;
}
if (!pPtr) {
snprintf(pBueffel, 255, "ERROR: cannot find %s to register to",
argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
pCount = GetCountableInterface(pPtr);
pCall = GetCallbackInterface(pPtr);
if (!pCount || !pCall) {
snprintf(pBueffel, 255, "ERROR: %s is not a usable counter", argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/*
allocate memory and initialize
*/
self = (pNXupdate) malloc(sizeof(NXupdate));
if (self == NULL) {
SCWrite(pCon, "ERROR: out of memory in UpdateFactory", eError);
return 0;
}
memset(self, 0, sizeof(NXupdate));
self->pDes = CreateDescriptor("AutoUpdate");
if (self->pDes == NULL) {
SCWrite(pCon, "ERROR: out of memory in UpdateFactory", eError);
return 0;
}
self->startScript = strdup("UNDEFINED");
self->updateScript = strdup("UNDEFINED");
self->linkScript = strdup("UNDEFINED");
self->updateIntervall = 1200; /* 20 min */
self->onOff = 1;
/*
register callbacks
*/
RegisterCallback(pCall, COUNTSTART, CountCallback, self, NULL);
RegisterCallback(pCall, COUNTEND, CountCallback, self, NULL);
AddCommand(pSics, argv[1], UpdateAction, KillUpdate, self);
return 1;
}