- added status function

- added hostport function
- added update script
- added reconnenct script
- added "sct parent" command
This commit is contained in:
zolliker
2012-06-19 06:44:30 +00:00
parent aa84a9d578
commit c8a492e2de

View File

@ -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 <node> <action>",
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 <node> <action>",
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,6 +1394,9 @@ static char *TransactionHandler(void *actionData, char *lastReply,
}
*/
/* printf("Transact: %s got %s\n", st->command, lastReply); */
if (lastReply == NULL) {
lastReply = "";
}
if(st->controller != NULL){
traceIO(st->controller->node->name, "transreply:%s", lastReply);
} else {
@ -1201,6 +1407,24 @@ static char *TransactionHandler(void *actionData, char *lastReply,
}
}
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);