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

95
ascon.c
View File

@ -1,8 +1,5 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
@ -13,69 +10,11 @@
#include "splitter.h"
#include "ascon.i"
#include "uselect.h"
#include "socketaddr.h"
static double lastClose = 0; /* time of last close operation */
static AsconProtocol *protocols = NULL;
static int MakeSocketAdr(
struct sockaddr *sockaddrPtr, /* socket address */
char *hostname, /* name or ip of host. NULL implies INADDR_ANY */
int port, /* port number */
char dotted_ip[16]) { /* resolved ip adr */
/*
Workaround for the following case:
switching off and on a LakeShore 336 does acquire a new address,
but the value in the cache (for gethostbyname) is not updated.
node: dig seems to be recommended over nslookup
*/
struct hostent *hostent; /* Host database entry */
struct sockaddr_in *sadr = (struct sockaddr_in *)sockaddrPtr;
FILE *fil;
char line[256];
int l;
(void) memset(sadr, 0, sizeof(*sadr));
if (dotted_ip) { /* default value: failure */
dotted_ip[0] = 0;
}
sadr->sin_family = AF_INET;
sadr->sin_port = htons((unsigned short)port);
if (hostname == NULL) {
/* do not need to copy, as INADDR_ANY is all zero bytes */
return 1;
}
if (inet_pton(AF_INET, hostname, &sadr->sin_addr) == 1) {
/* resolved as dotted numbers notation */
return 1;
}
hostent = gethostbyname(hostname);
if (hostent == 0) {
/* we assume that when gethostname gets no entry, dig will also fail.
That way, dig will not be called repeatedly for no reason */
return 0;
}
/* copy the address: in case dig fails, we use the cached value */
memcpy(&sadr->sin_addr, hostent->h_addr_list[0], 4);
/* we use hostent->h_name instead of hostname here, as this has already
the proper domain added */
snprintf(line, sizeof line, "timeout 1 dig +short %s", hostent->h_name);
fil = popen(line, "r");
if (fil != NULL) {
if (fgets(line, sizeof(line), fil) != NULL) {
l = strlen(line);
if (line[l-1] <= ' ') line[l-1] = 0; /* strip off newline */
/* silently ignore return value, if it fails, we take the cached value */
inet_pton(AF_INET, line, &sadr->sin_addr);
}
fclose(fil);
}
if (dotted_ip) {
inet_ntop(AF_INET, &sadr->sin_addr, dotted_ip, 16);
}
return 1;
}
void AsconError(Ascon *a, char *msg, int errorno)
{
static char *stateText[]={
@ -171,7 +110,7 @@ static void AsconConnect(Ascon * a)
return;
}
*colon = '\0';
ret = MakeSocketAdr(&adr, a->hostport, port, a->ip);
ret = MakeSocketAddr(&adr, a->hostport, port, a->ip);
*colon = ':';
if (ret == 0) {
AsconError(a, "bad host specification", 0);
@ -548,6 +487,22 @@ int AsconStdHandler(Ascon * a)
return AsconBaseHandler(a);
}
static void checkTerminator(char *term) {
int c, l;
if (term == NULL) return;
l = strlen(term);
if (l > 1 && term[0] == '"' && term[l-1] == '"') {
memmove(term, term+1, l-2);
term[l-2] = 0;
}
if (strncmp(term,"0x",2) == 0) {
sscanf(term,"%x",&c);
term[0] = (char)c;
term[1] = '\0';
}
}
/**
* Treat hex strings as terminators right. Note that this
* is limited to single character terminators.
@ -558,18 +513,10 @@ int AsconStdHandler(Ascon * a)
*/
void AsconCheckTerminators(Ascon *a)
{
int c, i, l;
int i, l;
if (a->sendTerminator != NULL && strncmp(a->sendTerminator,"0x",2) == 0) {
sscanf(a->sendTerminator,"%x",&c);
a->sendTerminator[0] = (char)c;
a->sendTerminator[1] = '\0';
}
if (a->replyTerminator != NULL && strncmp(a->replyTerminator,"0x",2) == 0) {
sscanf(a->replyTerminator,"%x",&c);
a->replyTerminator[0] = (char)c;
a->replyTerminator[1] = '\0';
}
checkTerminator(a->sendTerminator);
checkTerminator(a->replyTerminator);
a->compositeTerminator = 0;
if (a->replyTerminator != NULL && a->replyTerminator[0] == '\'') {
l = strlen(a->replyTerminator);