From 441550b546540ed129328eb5a088fb25f918aedc Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Fri, 30 Nov 2012 08:26:54 +1100 Subject: [PATCH] variuos changes --- sicshipadaba.c | 373 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 335 insertions(+), 38 deletions(-) diff --git a/sicshipadaba.c b/sicshipadaba.c index 2de06507..def1dbac 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -381,12 +381,12 @@ typedef struct { int internalID; } HdbCBInfo; -static Protocol isJSON(SConnection * pCon) +static Protocol isJSON(SConnection * pCon, int notify) { char proName[128]; void *pData; - if (SCinMacro(pCon)) { + if (notify == 0 && SCinMacro(pCon)) { return normal_protocol; } pData = FindCommandData(pServ->pSics, "protocol", "Protocol"); @@ -604,7 +604,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData, pPath = GetHipadabaPath(node); result = CreateDynString(128, 128); - if ((protocol = isJSON(cbInfo->pCon)) == 1) + if ((protocol = isJSON(cbInfo->pCon, 1)) == 1) outCode = eHdbEvent; else outCode = eEvent; @@ -733,7 +733,7 @@ static hdbCallbackReturn TreeChangeCallback(pHdb node, void *userData, return hdbAbort; } path = GetHipadabaPath(node); - if ((protocol = isJSON(cbInfo->pCon)) == 1) + if ((protocol = isJSON(cbInfo->pCon, 1)) == 1) outCode = eHdbEvent; else outCode = eEvent; @@ -1487,7 +1487,7 @@ pHdb FindHdbParent(char *rootpath, char *relpath, char **namePtr, } else { iret = snprintf(buffer, sizeof buffer, "%s/%s", rootpath, relpath); } - if (iret < 0 || iret >= sizeof(buffer)) { + if (iret < 0 || iret >= (int) sizeof(buffer)) { SCWrite(pCon, "ERROR: path too long", eError); return NULL; } @@ -1599,7 +1599,7 @@ int GetHdbPath(pHdb nodeArg, char *path, size_t pathlen) len = 0; for (node = nodeArg; node != NULL && node != root; node = node->mama) { len += strlen(node->name) + 1; - if (len >= pathlen) + if (len >= (int) pathlen) return 0; /* buffer overflow (recursive path?) */ parent = node; } @@ -1616,7 +1616,7 @@ int GetHdbPath(pHdb nodeArg, char *path, size_t pathlen) } l = strlen(sics); len += l; - if (len > pathlen) + if (len > (int) pathlen) return 0; /* buffer overflow */ strncpy(path, sics, l); } @@ -2283,6 +2283,71 @@ static int MakeHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData, return 1; } +/*--------------------------------------------------------------------------*/ +static int MakeHdbScriptNode(SConnection * pCon, SicsInterp * pSics, + void *pData, int argc, char *argv[]) +{ + int type = 0, i, length = 0; + char *name = NULL; + pHdb parent = NULL; + pHdb child = NULL; + pHdb current = NULL; + char *urgv[] = { "5", NULL }; + char driver[] = { "hdb" }; + char buffer[512], buffer2[512]; + + + if (!SCMatchRights(pCon, usMugger)) { + return 0; + } + + if (argc < 5) { + SCWrite(pCon, "ERROR: not enough arguments to MakeHdbNode", eError); + return 0; + } + + /* + * convert datatype + */ + strtolower(argv[4]); + type = convertHdbType(argv[4]); + if (type >= 7) { + SCWrite(pCon, + "ERROR: invalid type requested: none, int, float, text, intar, floatar, intvarar, floatvarar supported", + eError); + return 0; + } + if (type > 2) { + if (argc < 6) { + SCWrite(pCon, "ERROR: array length missing for array data type", + eError); + return 0; + } else { + length = atoi(argv[5]); + } + } + + parent = FindHdbParent(NULL, argv[1], &name, pCon); + if (parent == NULL) { + return 0; /* error messages written inside FindHdbParent */ + } + child = MakeSICSScriptPar(name, argv[3], argv[2], + makeHdbValue(type, length)); + if (child == NULL) { + SCWrite(pCon, "ERROR: out of memory creating node", eError); + return 0; + } + + AddHipadabaChild(parent, child, pCon); + /* + * have it polled automatically + */ + addPollObject(poller, pCon, GetHipadabaPath(child), driver, 1, urgv); + + SCSendOK(pCon); + return 1; +} + /*------------------------------------------------------------------------------*/ static int isNodeProtected(pHdb node) { @@ -2485,7 +2550,7 @@ static int ZipGetHdbNode(SConnection * pCon, SicsInterp * pSics, SCWrite(pCon, "ERROR: out of memory formatting data", eError); return 0; } - if ((protocol = isJSON(pCon)) == 1) + if ((protocol = isJSON(pCon, 0)) == 1) outCode = eHdbEvent; else outCode = eValue; @@ -2541,13 +2606,17 @@ static int GetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData, } } memset(&newValue, 0, sizeof(hdbValue)); - GetHipadabaPar(targetNode, &newValue, pCon); + /* ffr XXX I expect if status=0 then we don't have a valid value + Original code was causing a segfault for hdb text nodes + */ + if (0 == GetHipadabaPar(targetNode, &newValue, pCon)) + return 0; parData = formatValue(newValue, targetNode); if (parData == NULL) { SCWrite(pCon, "ERROR: out of memory formatting data", eError); return 0; } - if ((protocol = isJSON(pCon)) == 1) + if ((protocol = isJSON(pCon, 0)) == 1) outCode = eHdbEvent; else outCode = eValue; @@ -2585,13 +2654,14 @@ static int GetHdbVal(SConnection * pCon, SicsInterp * pSics, void *pData, return 0; } memset(&newValue, 0, sizeof(hdbValue)); - GetHipadabaPar(targetNode, &newValue, pCon); + if (0 == GetHipadabaPar(targetNode, &newValue, pCon)) + return 0; parData = formatValue(newValue, targetNode); if (parData == NULL) { SCWrite(pCon, "ERROR: out of memory formatting data", eError); return 0; } else { - if ((protocol = isJSON(pCon)) == 1) + if ((protocol = isJSON(pCon, 0)) == 1) outCode = eHdbEvent; else outCode = eValue; @@ -2897,7 +2967,7 @@ static int ListHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData, } else if (strcmp(argv[1], "-cli") == 0) { listData = formatClientList(node); } else { - if ((protocol = isJSON(pCon)) == 1) { + if ((protocol = isJSON(pCon, 0)) == 1) { listData = formatJSONList(node); outCode = eHdbEvent; } else { @@ -2969,6 +3039,62 @@ static int RemoveHdbCallback(SConnection * pCon, SicsInterp * pSics, return 1; } +/*---------------------------------------------------------------------------*/ +static int LinkHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData, + int argc, char *argv[]) +{ + pHdb node = NULL; + char buffer[256]; + pObjectDescriptor pDes = NULL; + + if (argc < 3) { + SCWrite(pCon, "ERROR: need path and object name to link", eError); + return 0; + } + if (!SCMatchRights(pCon, usMugger)) { + return 0; + } + + node = GetHipadabaNode(root, argv[1]); + if (node == NULL) { + snprintf(buffer, 255, "ERROR: path %s NOT found!", argv[1]); + SCWrite(pCon, buffer, eError); + return 0; + } + + pDes = FindCommandDescriptor(pSics, argv[2]); + if (pDes == NULL) { + snprintf(buffer, 255, "ERROR: failed to find object %s", argv[2]); + SCWrite(pCon, buffer, eError); + return 0; + } + if (pDes->parNode == NULL) { + snprintf(buffer, 255, + "ERROR: Object %s does not use Hipadaba natively and thus cannot be linked", + argv[2]); + SCWrite(pCon, buffer, eError); + return 0; + } + + if (pDes->parNode->mama != NULL) { + snprintf(buffer, 255, + "ERROR: Object %s is already linked somewhere else", argv[2]); + SCWrite(pCon, buffer, eError); + return 0; + } + + AddHipadabaChild(node, pDes->parNode, pCon); + + if (argc > 3) { + if (pDes->parNode->name != NULL) { + free(pDes->parNode->name); + } + pDes->parNode->name = strdup(argv[3]); + } + + SCSendOK(pCon); + return 1; +} /*-------------------------------------------------------------------------*/ static int isArrayNode(pHdb node) { @@ -3240,9 +3366,9 @@ static hdbCallbackReturn CommandSetCallback(pHdb node, void *userData, } current = current->next; } - SendHdbStatusMessage(node, "start"); +// SendHdbStatusMessage(node,"start"); status = HDBInvoke(pCon, pServ->pSics, GetCharArray(cmd)); - SendHdbStatusMessage(node, "stop"); +// SendHdbStatusMessage(node,"stop"); DeleteDynString(cmd); if (status == 1) { return hdbContinue; @@ -3273,6 +3399,60 @@ static hdbCallbackReturn CommandGetCallback(pHdb node, void *userData, return hdbContinue; } +/*--------------------------------------------------------------------------*/ +static int SicsCommandNode(SConnection * pCon, SicsInterp * pSics, + void *pData, int argc, char *argv[]) +{ + char *name = NULL; + pHdbCallback kalle = NULL; + pHdb parent = NULL, node = NULL; + + if (argc < 3) { + SCWrite(pCon, "ERROR: insufficent number of arguments to hcommand", + eError); + return 0; + } + if (!SCMatchRights(pCon, usMugger)) { + return 0; + } + + parent = FindHdbParent(NULL, argv[1], &name, pCon); + if (parent == NULL) { + return 0; /* error message already written */ + } + node = MakeHipadabaNode(name, HIPTEXT, 1); + if (node == NULL) { + SCWrite(pCon, "ERROR: out of memory in hcommand", eError); + return 0; + } + node->value.v.text = strdup(argv[2]); + node->value.arrayLength = strlen(argv[2]); + SetHdbProperty(node, "sicscommand", argv[2]); + // Set privillege of the node + if (argc > 3) { + SetHdbProperty(node, "priv", argv[3]); + } + + kalle = MakeHipadabaCallback(CommandSetCallback, NULL, NULL); + if (kalle == NULL) { + SCWrite(pCon, "ERROR: out of memory in hcommand", eError); + return 0; + } + AppendHipadabaCallback(node, kalle); + + kalle = MakeHipadabaCallback(CommandGetCallback, NULL, NULL); + if (kalle == NULL) { + SCWrite(pCon, "ERROR: out of memory in hcommand", eError); + return 0; + } + AppendHipadabaCallback(node, kalle); + + AddHipadabaChild(parent, node, pCon); + + SCSendOK(pCon); + return 1; +} + /*======================= Property Functions ================================*/ static int SetSICSHdbProperty(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) @@ -3322,6 +3502,30 @@ static int DelSICSHdbProperty(SConnection * pCon, SicsInterp * pSics, return 1; } +/*--------------------------------------------------------------------------*/ +static int HasSICSHdbProperty(SConnection * pCon, SicsInterp * pSics, + void *pData, int argc, char *argv[]) +{ + pHdb targetNode = NULL; + + if (argc < 3) { + SCWrite(pCon, "ERROR: need path key as parameters", eError); + return 0; + } + targetNode = FindHdbNode(NULL, argv[1], pCon); + if (targetNode == NULL) { + SCWrite(pCon, "ERROR: node not found", eError); + return 0; + } + if (HasHdbProperty(targetNode, argv[2])) { + SCPrintf(pCon, eValue, "%s", "true"); + return 1; + } else { + SCPrintf(pCon, eValue, "%s", "false"); + return 1; + } +} + /*--------------------------------------------------------------------------*/ static int GetSICSHdbProperty(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) @@ -3382,10 +3586,13 @@ static int ListSICSHdbProperty(SConnection * pCon, SicsInterp * pSics, char buffer[512]; const char *pKey = NULL; pDynString data = NULL; + int genTclList = 0; if (argc < 2) { SCWrite(pCon, "ERROR: need path as parameter", eError); return 0; + } else if (argc == 3) { + genTclList = 1; } targetNode = FindHdbNode(NULL, argv[1], pCon); if (targetNode == NULL) { @@ -3400,9 +3607,64 @@ static int ListSICSHdbProperty(SConnection * pCon, SicsInterp * pSics, InitHdbPropertySearch(targetNode); while ((pKey = GetNextHdbProperty(targetNode, buffer, 511)) != NULL) { DynStringConcat(data, (char *) pKey); - DynStringConcat(data, "="); - DynStringConcat(data, buffer); - DynStringConcat(data, "\n"); + if (genTclList) { + DynStringConcat(data, " "); + DynStringConcat(data, "{"); + DynStringConcat(data, buffer); + DynStringConcat(data, "}"); + DynStringConcat(data, " "); + } else { + DynStringConcat(data, "="); + DynStringConcat(data, buffer); + DynStringConcat(data, "\n"); + } + } + SCWrite(pCon, GetCharArray(data), eValue); + DeleteDynString(data); + return 1; +} + +static int ANSTO_ListSICSHdbProperty(SConnection * pCon, + SicsInterp * pSics, void *pData, + int argc, char *argv[]) +{ + pHdb targetNode = NULL; + char buffer[512], *globPtr = NULL; + int cmpSize = 0; + const char *pKey = NULL; + pDynString data = NULL; + + if (argc < 3) { + SCWrite(pCon, "ERROR: need path and search string as parameters", + eError); + return 0; + } + targetNode = FindHdbNode(NULL, argv[1], pCon); + if (targetNode == NULL) { + SCWrite(pCon, "ERROR: node not found", eError); + return 0; + } + data = CreateDynString(64, 64); + if (data == NULL) { + SCWrite(pCon, "ERROR: out of memory in ListSICSHdbProperty", eError); + return 0; + } + InitHdbPropertySearch(targetNode); + + /* Allow simple glob matches with '*' as a suffix + Eg hfindprop /hpath @* + */ + if ((globPtr = index(argv[2], '*')) != NULL) { + *globPtr = '\0'; + } + cmpSize = strlen(argv[2]); + while ((pKey = GetNextHdbProperty(targetNode, buffer, 511)) != NULL) { + if (strncasecmp(argv[2], pKey, cmpSize) == 0) { + DynStringConcat(data, (char *) pKey); + DynStringConcat(data, " "); + DynStringConcat(data, buffer); + DynStringConcat(data, "\n"); + } } SCWrite(pCon, GetCharArray(data), eValue); DeleteDynString(data); @@ -3410,23 +3672,46 @@ static int ListSICSHdbProperty(SConnection * pCon, SicsInterp * pSics, } /*---------------------------------------------------------------------------*/ -static pHdb matchHdbProp(pHdb root, char *propname, char *buffer) +static pHdb matchHdbProp(pHdb root, char *propname, char *buffer, + pDynString result, int invertmatch) { - char value[1024]; + char value[1024], *path = NULL; pHdb current = NULL, search; memset(value, 0, 1024); - if (GetHdbProperty(root, propname, value, 1023) == 1) { + if (strcmp(buffer, "*") == 0) { + if (GetHdbProperty(root, propname, value, 1023) == 1) { + if (!invertmatch) { + path = GetHipadabaPath(root); + DynStringConcat(result, path); + DynStringConcat(result, "\n"); + free(path); + } + } else if (invertmatch) { + path = GetHipadabaPath(root); + DynStringConcat(result, path); + DynStringConcat(result, "\n"); + free(path); + } + } else if (GetHdbProperty(root, propname, value, 1023) == 1) { if (strstr(buffer, value) != NULL) { - return root; + if (!invertmatch) { + path = GetHipadabaPath(root); + DynStringConcat(result, path); + DynStringConcat(result, "\n"); + free(path); + } + } else if (invertmatch) { + path = GetHipadabaPath(root); + DynStringConcat(result, path); + DynStringConcat(result, "\n"); + free(path); } } current = root->child; while (current != NULL) { - search = matchHdbProp(current, propname, buffer); - if (search != NULL) { - return search; - } + search = + matchHdbProp(current, propname, buffer, result, invertmatch); current = current->next; } @@ -3440,6 +3725,8 @@ static int MatchHdbProperty(SConnection * pCon, SicsInterp * pSics, pHdb root = NULL; pHdb foundNode = NULL; char buffer[1024], *path = NULL; + int node = 1, prop = 2, propval = 3, invertmatch = 0; + pDynString matchList = NULL; if (argc < 4) { SCWrite(pCon, @@ -3447,25 +3734,29 @@ static int MatchHdbProperty(SConnection * pCon, SicsInterp * pSics, eError); return 0; } + if (argc >= 5) { + if (strcasecmp(argv[1], "invert") == 0) { + invertmatch = 1; + node++; + prop++; + propval++; + } + } memset(buffer, 0, 1024); - Arg2Text(argc - 3, &argv[3], buffer, 1023); - root = GetHipadabaNode(GetHipadabaRoot(), argv[1]); + Arg2Text(argc - propval, &argv[propval], buffer, 1023); + root = GetHipadabaNode(GetHipadabaRoot(), argv[node]); if (root == NULL) { SCWrite(pCon, "ERROR: start node for search not found", eError); return 0; } - strtolower(argv[2]); + strtolower(argv[prop]); strtolower(buffer); - foundNode = matchHdbProp(root, argv[2], buffer); - - if (foundNode == NULL) { - SCWrite(pCon, "NONE", eValue); - } else { - path = GetHipadabaPath(foundNode); - SCWrite(pCon, path, eValue); - free(path); - } + matchList = CreateDynString(128, 128); + foundNode = + matchHdbProp(root, argv[prop], buffer, matchList, invertmatch); + SCWrite(pCon, GetCharArray(matchList), eValue); + DeleteDynString(matchList); return 1; } @@ -3486,7 +3777,9 @@ int InstallSICSHipadaba(SConnection * pCon, SicsInterp * pSics, { root = MakeHipadabaNode("/", HIPNONE, 0); + AddCommand(pSics, "hmake", MakeHdbNode, NULL, NULL); AddCommand(pSics, "hfactory", HdbNodeFactory, NULL, NULL); + AddCommand(pSics, "hmakescript", MakeHdbScriptNode, NULL, NULL); AddCommand(pSics, "hattach", SICSHdbAdapter, NULL, NULL); AddCommand(pSics, "hsubsamplehm", HdbSubSample, NULL, NULL); AddCommand(pSics, "hdel", DeleteHdbNode, NULL, NULL); @@ -3498,16 +3791,20 @@ int InstallSICSHipadaba(SConnection * pCon, SicsInterp * pSics, AddCommand(pSics, "hlist", ListHdbNode, NULL, NULL); AddCommand(pSics, "hnotify", AutoNotifyHdbNode, NULL, NULL); AddCommand(pSics, "hdelcb", RemoveHdbCallback, NULL, NULL); + AddCommand(pSics, "hlink", LinkHdbNode, NULL, NULL); AddCommand(pSics, "hinfo", HdbNodeInfo, NULL, NULL); AddCommand(pSics, "hval", HdbNodeVal, NULL, NULL); AddCommand(pSics, "hchain", ChainHdbNode, NULL, NULL); + AddCommand(pSics, "hcommand", SicsCommandNode, NULL, NULL); AddCommand(pSics, "harray", HdbArrayNode, NULL, NULL); AddCommand(pSics, "hsetprop", SetSICSHdbProperty, NULL, NULL); AddCommand(pSics, "hdelprop", DelSICSHdbProperty, NULL, NULL); AddCommand(pSics, "hgetprop", GetSICSHdbProperty, NULL, NULL); AddCommand(pSics, "hgetpropval", GetSICSHdbPropertyVal, NULL, NULL); AddCommand(pSics, "hmatchprop", MatchHdbProperty, NULL, NULL); + AddCommand(pSics, "hpropexists", HasSICSHdbProperty, NULL, NULL); AddCommand(pSics, "hlistprop", ListSICSHdbProperty, NULL, NULL); + AddCommand(pSics, "hfindprop", ANSTO_ListSICSHdbProperty, NULL, NULL); InstallSICSPoll(pCon, pSics, pData, argc, argv); poller = (pSicsPoll) FindCommandData(pSics, "sicspoll", "SicsPoll");