various improvements

- use dig for resolving host names
- ascon.c: fix terminator parsing
- property callback: change property before callback
- logger.c:default for logger period must be the old value instead of 1
- add frappy type history writing
- increase max. logreader line length
- HIPNONE returns "null" with json protocol
- encode strings properly in formatNameValue
- fix memory leak in json2tcl
- scriptcontext: do not show debug messages when script starts with underscore or when the "send" property is empty
- scriptcontext: remove args for action timestamp
- scriptcontext: "que" function will replace an already queued action, e.g. for 'halt
- introduced updatestatus script
This commit is contained in:
2021-09-16 12:26:18 +02:00
parent 8de1fd4183
commit 61341b52f4
24 changed files with 2352 additions and 304 deletions

View File

@@ -41,6 +41,7 @@
#include "arrayutil.h"
#include "HistMem.h"
#include "asynnet.h"
#include <json-c/json.h>
#define MAX_HDB_PATH 1024
@@ -455,6 +456,7 @@ int formatNameValue(Protocol protocol, char *name, char *value,
pDynString result, int hdtype)
{
char *char_arr, *ptr;
char token[8], ch;
switch (protocol) {
case normal_protocol:
@@ -465,6 +467,7 @@ int formatNameValue(Protocol protocol, char *name, char *value,
case json_protocol:
switch (hdtype) {
case HIPNONE:
DynStringCopy(result, "null");
break;
case HIPINT:
case HIPFLOAT:
@@ -478,7 +481,27 @@ int formatNameValue(Protocol protocol, char *name, char *value,
DynStringCopy(result, "{\"");
DynStringConcat(result, name);
DynStringConcat(result, "\": \"");
DynStringConcat(result, value);
ptr = NULL;
for (ch=*value; ch!=0; ch=*++value) {
switch (ch) {
case '"': strcpy(token, "\\\"");
case '\\': strcpy(token, "\\\\");
default:
if (ch > 127 || ch < 32) {
snprintf(token, sizeof token, "\\u%4.4x", (unsigned char)ch);
} else {
if (!ptr) ptr = value;
continue;
}
}
if (ptr) {
DynStringConcatBytes(result, ptr, value - ptr);
}
DynStringConcat(result, token);
}
if (ptr) {
DynStringConcatBytes(result, ptr, value - ptr);
}
DynStringConcat(result, "\"}");
break;
case HIPINTAR:
@@ -593,8 +616,11 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
pHdbIDMessage idm = NULL;
pHdbPtrMessage cmm = NULL;
pHdbDataMessage mm = NULL;
hdbPropertyChange *propm = NULL;
hdbValue *hvalue;
SConnection *tstCon;
char updatePath[1024];
char *geterror;
cbInfo = (HdbCBInfo *) userData;
@@ -650,9 +676,20 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
}
/*
* Deal with update messages
* Deal with update and geterror property messages
*/
if ((mm = GetHdbUpdateMessage(message)) == NULL) {
if ((propm = GetPropertyChangeMessage(message)) != NULL) {
if (strcmp(propm->key, "geterror") != 0) {
/* this is a property change of an other property */
return hdbContinue;
}
geterror = propm->value;
hvalue = &node->value;
} else if ((mm = GetHdbUpdateMessage(message)) != NULL) {
geterror = GetHdbProp(node, "geterror");
hvalue = mm->v;
} else {
return hdbContinue;
}
@@ -663,19 +700,26 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
else
outCode = eEvent;
if (geterror && *geterror) {
/* send geterror */
strlcat(updatePath, ".geterror", sizeof updatePath);
formatNameValue(protocol, updatePath, geterror, result, HIPTEXT);
SCPureSockWrite(cbInfo->pCon, Dyn2Cstring(result), outCode);
return hdbContinue;
} /* else normal notify */
/**
* if transfer = zip always transfer data in zipped form
*/
if (GetHdbProperty(node, "transfer", value, 80) == 1) {
if (strstr(value, "zip") != NULL || strstr(value,"bin") != NULL) {
status = sendZippedNodeData(node, *(mm->v), cbInfo->pCon);
status = sendZippedNodeData(node, *hvalue, cbInfo->pCon);
DeleteDynString(result);
return hdbContinue;
}
}
if (mm->v->arrayLength < 100) {
printedData = formatValue(*(mm->v), node);
if (hvalue->arrayLength <= 400) {
printedData = formatValue(*hvalue, node);
if (printedData == NULL || result == NULL) {
SCWrite(cbInfo->pCon, "ERROR: out of memory formatting data",
eEvent);
@@ -686,7 +730,7 @@ static hdbCallbackReturn SICSNotifyCallback(pHdb node, void *userData,
return hdbContinue;
}
formatNameValue(protocol, updatePath, GetCharArray(printedData), result,
mm->v->dataType);
hvalue->dataType);
#ifdef SITE_ANSTO
SCWrite(cbInfo->pCon, GetCharArray(result), outCode);
#else
@@ -792,8 +836,10 @@ static hdbCallbackReturn TreeChangeCallback(pHdb node, void *userData,
outCode = eHdbEvent;
else
outCode = eEvent;
/* formatNameValue(protocol, "treechange", path, result,
node->value.dataType); */
formatNameValue(protocol, "treechange", path, result,
node->value.dataType);
HIPTEXT);
SCWrite(cbInfo->pCon, GetCharArray(result), outCode);
DeleteDynString(result);
free(path);
@@ -814,7 +860,9 @@ pHdbCallback MakeTreeChangeCallback(SConnection * pCon, int id)
if (cbInfo->pCon == NULL) {
return NULL;
}
SCsetMacro(cbInfo->pCon, 0);
cbInfo->ID = id;
cbInfo->internalID = -1;
return MakeHipadabaCallback(TreeChangeCallback, cbInfo, cbKill);
}
@@ -3024,11 +3072,12 @@ static pDynString formatPlainList(pHdb node)
}
/*---------------------------------------------------------------------------*/
static pDynString formatJSONList(pHdb node)
static pDynString formatJSONList(pHdb node, int withValues)
{
pHdb current;
pDynString result = NULL;
pDynString data = NULL;
char *str;
if (node->child == NULL)
return NULL;
@@ -3037,22 +3086,44 @@ static pDynString formatJSONList(pHdb node)
return NULL;
}
if (node->child->value.dataType == HIPNONE)
DynStringCopy(result, "[");
else
if (withValues)
DynStringCopy(result, "{");
else
DynStringCopy(result, "[");
current = node->child;
while (current != NULL) {
DynStringConcat(result, "\"");
DynStringConcatChar(result, '"');
DynStringConcat(result, current->name);
DynStringConcat(result, "\"");
if (current->value.dataType != HIPNONE) {
data = formatValue(current->value, current);
if (data != NULL) {
DynStringConcat(result, ": ");
DynStringConcat(result, GetCharArray(data));
DeleteDynString(data);
DynStringConcatChar(result, '"');
if (withValues) {
DynStringConcat(result, ": ");
if (current->value.dataType == HIPTEXT) {
DynStringConcatChar(result, '"');
data = formatValue(current->value, current);
if (data != NULL) {
/* lazy approach: remove \ and " */
for (str = GetCharArray(data); *str != 0; str++) {
if (*str == '\\' || *str == '"') {
*str = '_';
}
}
DynStringConcat(result, GetCharArray(data));
DeleteDynString(data);
}
DynStringConcatChar(result, '"');
} else {
if (current->value.dataType != HIPINT && current->value.dataType != HIPFLOAT) {
data = NULL;
} else {
data = formatValue(current->value, current);
}
if (data != NULL) {
DynStringConcat(result, GetCharArray(data));
DeleteDynString(data);
} else {
DynStringConcat(result, "null");
}
}
}
if (current->next != NULL)
@@ -3060,10 +3131,10 @@ static pDynString formatJSONList(pHdb node)
current = current->next;
}
if (node->child->value.dataType == HIPNONE)
DynStringConcat(result, "]");
else
if (withValues)
DynStringConcat(result, "}");
else
DynStringConcat(result, "]");
return result;
}
@@ -3197,31 +3268,34 @@ static int ListHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData,
return 0;
}
/* do not modify arguments!
if (pathArg == 2) {
strtolower(argv[1]);
}
if (strcmp(argv[1], "-val") == 0) {
listData = formatListWithVal(node);
} else if (strcmp(argv[1], "-cli") == 0) {
*/
outCode = eValue;
if (strcasecmp(argv[1], "-val") == 0) {
if (isJSON(pCon, 0)) {
listData = formatJSONList(node, 1);
outCode = eHdbEvent;
} else {
listData = formatListWithVal(node);
}
} else if (strcasecmp(argv[1], "-cli") == 0) {
listData = formatClientList(node);
} else {
if ((protocol = isJSON(pCon, 0)) == 1) {
listData = formatJSONList(node);
listData = formatJSONList(node, 0);
outCode = eHdbEvent;
} else {
listData = formatPlainList(node);
outCode = eValue;
}
}
if (listData == NULL) {
SCWrite(pCon, "ERROR: failed to format list", eError);
return 0;
}
if ((strcmp(argv[1], "-val") == 0) || (strcmp(argv[1], "-cli") == 0)) {
SCWrite(pCon, GetCharArray(listData), eValue);
} else {
SCWrite(pCon, GetCharArray(listData), outCode);
}
SCWrite(pCon, GetCharArray(listData), outCode);
DeleteDynString(listData);
return 1;
}