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:
95
ascon.c
95
ascon.c
@ -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);
|
||||
|
Reference in New Issue
Block a user