From c8a492e2deb0d043629465fb2fe4008540ce1b5a Mon Sep 17 00:00:00 2001 From: zolliker Date: Tue, 19 Jun 2012 06:44:30 +0000 Subject: [PATCH] - added status function - added hostport function - added update script - added reconnenct script - added "sct parent" command --- scriptcontext.c | 316 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 294 insertions(+), 22 deletions(-) diff --git a/scriptcontext.c b/scriptcontext.c index 33c9e594..1a8d5b18 100644 --- a/scriptcontext.c +++ b/scriptcontext.c @@ -48,6 +48,12 @@ typedef struct SctData { Hdb *node; } SctData; +/* data for updatescript */ +typedef struct SctUpdatescript { + char *name; + SctController *controller; +} SctUpdatescript; + static ScriptContext *sct = NULL; static SctData *queueData = NULL; @@ -55,6 +61,8 @@ static struct { char *name; } actionCallback; +static struct SctUpdatescript updatescriptCallback; + void PushContext(Hdb * node, SctController * controller) { ContextItem *new; @@ -177,7 +185,7 @@ int SctCommand(SConnection * con, SicsInterp * sics, void *object, } /* - * get path + * get path (pure sct command) */ if (argc <= 1) { GetHdbPath(node, value, sizeof value); @@ -236,19 +244,6 @@ int SctCommand(SConnection * con, SicsInterp * sics, void *object, return 1; } - /* - * send command - */ - if (strcmp(argv[1], "send") == 0 && argc > 2) { - if (sct->sendNode != node) { - SCPrintf(con, eError, "ERROR: %s may be called only in action scripts", - argv[0]); - return 0; - } - sct->sendCalled = 1; - /* continue with property handling */ - } - /* * with command (execute a script in the context of an other node) */ @@ -273,6 +268,37 @@ int SctCommand(SConnection * con, SicsInterp * sics, void *object, return 1; } + /* + * parent command (return path of parent node) + */ + if (strcmp(argv[1], "parent") == 0) { + if (argc > 3) { + SCPrintf(con, eError, "ERROR: syntax must be: %s %s [path]", + argv[0], argv[1]); + return 0; + } + if (argc == 3) { + node = FindHdbNode(NULL, argv[2], con); + } + GetHdbPath(node->mama, value, sizeof value); + /* returns an empty string on error */ + SCWrite(con, value, eValue); + return 1; + } + + /* + * send command + */ + if (strcmp(argv[1], "send") == 0 && argc > 2) { + if (sct->sendNode != node) { + SCPrintf(con, eError, "ERROR: %s may be called only in action scripts", + argv[0]); + return 0; + } + sct->sendCalled = 1; + /* continue with property handling */ + } + /* * property handling */ @@ -377,7 +403,7 @@ static char *SctActionHandler(void *actionData, char *lastReply, SConnection *con; char eprop[80]; char msg[1024]; - char path[1024]; + char path[MAX_HDB_PATH]; char origScript[80]; char *blank; char *emsg; @@ -387,6 +413,7 @@ static char *SctActionHandler(void *actionData, char *lastReply, char timeKey[50], timeVal[50]; int iMacro; + assert(data->name); if (queueData != NULL && queueData->conCtx != NULL) { con = queueData->conCtx; } else { @@ -637,7 +664,6 @@ static hdbCallbackReturn SctMainCallback(Hdb * node, void *userData, hdbDataMessage *mm; hdbPtrMessage *pm; hdbMessage *km; - ContextItem *s; SConnection *con; char *geterror; char error[256]; @@ -699,7 +725,6 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData, hdbDataSearch *dsm; hdbDataMessage *mm; hdbPtrMessage *pm; - hdbMessage *km; SctData *data = userData; Hdb *target; char *script; @@ -746,8 +771,10 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData, if (script != NULL) { if (SctCallInContext(con, script, node, data->controller, &error) == 0) { - SCPrintf(con, eError, "ERROR: in {%s}: %s", script, error); + /* SCPrintf(con, eError, "ERROR: in {%s}: %s", script, error); */ + SCPrintf(con, eError, "ERROR: %s", error); /* nicer for the user */ SetHdbProperty(node, "target", NULL); + SetHdbProperty(node, "requested", NULL); return hdbAbort; } } @@ -858,8 +885,10 @@ static void SctKillData(void *d) { SctData *data = d; - if (data->name) + if (data->name) { free(data->name); + data->name = NULL; + } if (data->conCtx) SCDeleteConnection(data->conCtx); free(data); @@ -1135,6 +1164,180 @@ static int SctQueueCmd(pSICSOBJ ccmd, SConnection * con, return 1; } +static void SctKillUpdatescript(void *d) +{ + SctUpdatescript *us = d; + + if (us->name) { + free(us->name); + } + free(us); +} + +/* + * This is the callback for update scripts + */ +static hdbCallbackReturn SctUpdatescriptCallback(Hdb * node, + void *userData, + hdbMessage * msg) +{ + SctUpdatescript *us = userData; + hdbDataSearch *dsm; + hdbDataMessage *mm; + hdbPtrMessage *pm; + SConnection *con; + char *result; + char *script; + char path[MAX_HDB_PATH]; + pDynString text; + char *arg; + + pm = GetKillPtrMessage(msg); + if (pm != NULL) { + if (us->controller == pm->pPtr) { + return hdbKill; + } + if (pm->pPtr == &updatescriptCallback + && strcmp(us->name, updatescriptCallback.name) == 0 + && us->controller == updatescriptCallback.controller) { + return hdbKill; + } + return hdbContinue; + } + dsm = GetHdbDataSearchMessage(msg); + if (dsm != NULL) { + if (dsm->testPtr == &updatescriptCallback) { + if (strcasecmp(us->name, updatescriptCallback.name) == 0 && + us->controller == updatescriptCallback.controller) { + dsm->result = us; + } + return hdbAbort; + } + return hdbContinue; + } + mm = GetHdbUpdateMessage(msg); + if (mm != NULL) { + con = mm->callData; + + script = GetProp(node, us->controller->node, us->name); + if (script == NULL) script = us->name; + + text = formatValue(*(mm->v), node); + arg = GetCharArray(text); + arg = Arg2Tcl(1, &arg, NULL, 0); + DynStringCopy(text, script); + DynStringConcat(text, " "); + DynStringConcat(text, arg); + free(arg); + script = GetCharArray(text); + + if (!SctCallInContext(con, script, node, us->controller, &result)) { + + GetHdbPath(node, path, sizeof path); + SCPrintf(con, eError, "ERROR: in updatescript {%s} node %s: %s", + script, path, result); + } + DeleteDynString(text); + return hdbContinue; + } + + return hdbContinue; +} + +int SctUpdatescriptNode(SctController * controller, Hdb * node, char *action) +{ + SctUpdatescript *us; + hdbCallback *cb; + + updatescriptCallback.name = action; + updatescriptCallback.controller = controller; + us = FindHdbCallbackData(node, &updatescriptCallback); + if (us != NULL) { + return 0; + } + us = calloc(1, sizeof(*us)); + us->name = strdup(action); + us->controller = controller; + cb = MakeHipadabaCallback(SctUpdatescriptCallback, us, SctKillUpdatescript); + assert(cb); + AppendHipadabaCallback(node, cb); + + return 1; +} + +int SctUpdatescriptKill(SctController * controller, Hdb * node, char *action) +{ + updatescriptCallback.name = action; + updatescriptCallback.controller = controller; + RemoveSICSInternalCallbackFrom(node, &updatescriptCallback); + return 1; +} + +static int SctUpdatescriptCmd(pSICSOBJ ccmd, SConnection * con, + Hdb * cmdNode, Hdb * par[], int nPar) +{ + Hdb *node; + SctController *controller; + double interval; + char *path; + char *action; + SctData *data; + char *prioText; + + if (nPar < 2) { + SCPrintf(con, eError, + "ERROR: should be: %s updatescript ", + ccmd->objectNode->name); + return 0; + } + controller = ccmd->pPrivate; + path = ParText(cmdNode, "node", nPar, ""); + node = FindHdbNode(NULL, path, con); + if (node == NULL) { + SCPrintf(con, eError, "ERROR: %s not found", path); + return 0; + } + action = ParText(cmdNode, "action", nPar, "updatescript"); + + if (SctUpdatescriptNode(controller, node, action)) { + SCPrintf(con, eValue, "%s registered for update on %s", action, path); + } else { + SCPrintf(con, eValue, "%s already registered for update on %s", action, path); + } + return 1; +} + +static int SctKillUpdatescriptCmd(pSICSOBJ ccmd, SConnection * con, + Hdb * cmdNode, Hdb * par[], int nPar) +{ + Hdb *node; + SctController *controller; + double interval; + char *path; + char *action; + SctData *data; + char *prioText; + + if (nPar < 2) { + SCPrintf(con, eError, + "ERROR: should be: %s killupdatescript ", + ccmd->objectNode->name); + return 0; + } + controller = ccmd->pPrivate; + path = ParText(cmdNode, "node", nPar, ""); + node = FindHdbNode(NULL, path, con); + if (node == NULL) { + SCPrintf(con, eError, "ERROR: %s not found", path); + return 0; + } + action = ParText(cmdNode, "action", nPar, "updatescript"); + + SctUpdatescriptKill(controller, node, action); + SCPrintf(con, eValue, "kill %s updatescript on %s", action, path); + return 1; +} + typedef struct SctTransact { char *command; char *reply; @@ -1191,16 +1394,37 @@ static char *TransactionHandler(void *actionData, char *lastReply, } */ /* printf("Transact: %s got %s\n", st->command, lastReply); */ - if(st->controller != NULL){ + if (lastReply == NULL) { + lastReply = ""; + } + if(st->controller != NULL){ traceIO(st->controller->node->name, "transreply:%s", lastReply); } else { traceIO("sctunknown", "transreply:%s", lastReply); } - st->reply = strdup(lastReply); + st->reply = strdup(lastReply); return NULL; } } +static char *SendHandler(void *actionData, char *lastReply, + int commError) +{ + pSctTransact st = (pSctTransact) actionData; + char *result = TransactionHandler(actionData, lastReply, commError); + + if (st->sent == 2) { + SetHdbProperty(st->controller->node, "reply", lastReply); + if (st->controller->verbose) { + SCPrintf(st->con, eLog, "%6.3f reply : %s", secondsOfMinute(), lastReply); + } + if (st->controller->fd != NULL) { + fprintf(st->controller->fd, "%6.3f reply : %s\n", secondsOfMinute(), lastReply); + } + } + return result; +} + static int SctTransactMatch(void *d1, void *d2) { return d1 == d2; @@ -1280,8 +1504,9 @@ static int SctSendCmd(pSICSOBJ ccmd, SConnection * con, prio = WritePRIO; } + SetHdbProperty(c->node, "reply", ""); DevQueue(c->devser, st, prio, - TransactionHandler, SctTransactMatch, KillSctTransact, NULL); + SendHandler, SctTransactMatch, KillSctTransact, NULL); return 1; } @@ -1299,9 +1524,17 @@ static int SctReconnect(pSICSOBJ ccmd, SConnection * con, Hdb * cmdNode, Hdb * par[], int nPar) { SctController *c; + char *reconnectScript, *result; c = (SctController *) ccmd->pPrivate; DevReconnect(c->devser, ParText(cmdNode, "hostport", nPar, "")); + reconnectScript = GetProp(c->node, c->node, "reconnect_script"); + if (reconnectScript && reconnectScript[0] != '\0') { + if (SctCallInContext(con, reconnectScript, c->node, c, &result) == 0) { + SCPrintf(con, eError, "ERROR: %s", result); + return 0; + } + } return 1; } @@ -1342,6 +1575,30 @@ static int SctStatistics(pSICSOBJ ccmd, SConnection * con, return 1; } +static int SctHostport(pSICSOBJ ccmd, SConnection * con, + Hdb * cmdNode, Hdb * par[], int nPar) +{ + SctController *c; + char *result; + + c = (SctController *) ccmd->pPrivate; + result = DevHostport(c->devser); + SCWrite(con, result, eValue); + return 1; +} + +static int SctStatus(pSICSOBJ ccmd, SConnection * con, + Hdb * cmdNode, Hdb * par[], int nPar) +{ + SctController *c; + char *result; + + c = (SctController *) ccmd->pPrivate; + result = DevStatus(c->devser); + SCWrite(con, result, eValue); + return 1; +} + static int SctLog(pSICSOBJ ccmd, SConnection * con, Hdb * cmdNode, Hdb * par[], int nPar) { @@ -1517,6 +1774,15 @@ static int SctMakeController(SConnection * con, SicsInterp * sics, AddSICSHdbPar(cmd, "prio", usMugger, MakeHdbText("write")); AddSICSHdbPar(cmd, "action", usMugger, MakeHdbText("write")); + cmd = AddSICSHdbPar(controller->node, + "updatescript", usMugger, MakeSICSFunc(SctUpdatescriptCmd)); + AddSICSHdbPar(cmd, "node", usMugger, MakeHdbText("")); + AddSICSHdbPar(cmd, "action", usMugger, MakeHdbText("updatescript")); + + cmd = AddSICSHdbPar(controller->node, + "killupdatescript", usMugger, MakeSICSFunc(SctKillUpdatescriptCmd)); + AddSICSHdbPar(cmd, "node", usMugger, MakeHdbText("")); + AddSICSHdbPar(cmd, "action", usMugger, MakeHdbText("updatescript")); cmd = AddSICSHdbPar(controller->node, "log", usMugger, MakeSICSFunc(SctLog)); @@ -1546,6 +1812,12 @@ static int SctMakeController(SConnection * con, SicsInterp * sics, cmd = AddSICSHdbPar(controller->node, "statistics", usSpy, MakeSICSFunc(SctStatistics)); + cmd = AddSICSHdbPar(controller->node, + "hostport", usSpy, MakeSICSFunc(SctHostport)); + + cmd = AddSICSHdbPar(controller->node, + "status", usSpy, MakeSICSFunc(SctStatus)); + cb = MakeHipadabaCallback(SctDebugCallback, controller, NULL); if (cb) AppendHipadabaCallback(par, cb);