- merged "offline" and "disconnected" stati

This commit is contained in:
2018-07-03 11:14:18 +02:00
parent 6085b22c18
commit aac014618c
2 changed files with 55 additions and 19 deletions

62
ascon.c
View File

@ -17,11 +17,50 @@
static double lastClose = 0; /* time of last close operation */ static double lastClose = 0; /* time of last close operation */
static AsconProtocol *protocols = NULL; static AsconProtocol *protocols = NULL;
long parse_dotted_adr(const char *dottedadr) {
int ip[4];
int i;
if (sscanf(dottedadr, "%d.%d.%d.%d", ip, ip+1, ip+2, ip+3) != 4) return 0;
for (i=0; i<3; i++) {
if (ip[i] < 0 || ip[i] > 255) return 0;
}
return ip[0] + (ip[1] << 8) + (ip[2] << 16) + (ip[3] << 24);
}
long ns_lookup(char *hostname) {
FILE *fil;
char line[256];
long ipadr;
ipadr = parse_dotted_adr(hostname);
if (ipadr) return ipadr;
snprintf(line, sizeof line, "timeout 1 nslookup %s", hostname);
fil = popen(line, "r");
if (fil == NULL) {
return 0;
}
while (fgets(line, sizeof(line), fil) != NULL) {
if (strncmp(line, "Address: ", 9) == 0) {
ipadr = parse_dotted_adr(line+9);
if (ipadr) {
fclose(fil);
return ipadr;
}
}
}
fclose(fil);
return 0;
}
/* /*
CreateSocketAdress stolen from Tcl. Thanks to John Ousterhout Based on CreateSocketAdress from John Ousterhout
Use ns_lookup instead of gethostbyname, as the latter uses a cache, which
is not sufficient in some cases (switching off and on a LakeShore 336 does
acquire a new address, but the value in the cache is not updates)
*/ */
static int CreateSocketAdress(struct sockaddr_in *sockaddrPtr, /* Socket address */ static int MakeSocketAdress(struct sockaddr_in *sockaddrPtr, /* Socket address */
char *host, /* Host. NULL implies INADDR_ANY */ char *host, /* Host. NULL implies INADDR_ANY */
int port) int port)
{ /* Port number */ { /* Port number */
@ -34,15 +73,12 @@ static int CreateSocketAdress(struct sockaddr_in *sockaddrPtr, /* Socket addres
if (host == NULL) { if (host == NULL) {
addr.s_addr = INADDR_ANY; addr.s_addr = INADDR_ANY;
} else { } else {
addr.s_addr = ns_lookup(host);
if (addr.s_addr == 0) { /* try gethostbyname only if ns_lookup failed */
hostent = gethostbyname(host); hostent = gethostbyname(host);
if (hostent != NULL) { if (hostent == NULL) return 0; /* error */
memcpy((char *) &addr, memcpy((char *) &addr,
(char *) hostent->h_addr_list[0], (size_t) hostent->h_length); (char *) hostent->h_addr_list[0], (size_t) hostent->h_length);
} else {
addr.s_addr = inet_addr(host);
if (addr.s_addr == (unsigned int) -1) {
return 0; /* error */
}
} }
} }
/* /*
@ -68,7 +104,7 @@ void AsconError(Ascon *a, char *msg, int errorno)
"read done", "read done",
"idle", "idle",
"failed", "failed",
"timeout" "no response"
}; };
char *state; char *state;
char num[8]; char num[8];
@ -108,6 +144,7 @@ static void AsconConnect(Ascon * a)
char *colon; char *colon;
int port; int port;
int oldopts; int oldopts;
char ipaddress[16];
/* wait 0.5 sec before connecting again after a close /* wait 0.5 sec before connecting again after a close
2 reasons for that: 2 reasons for that:
@ -135,7 +172,7 @@ static void AsconConnect(Ascon * a)
colon = strchr(a->hostport, ':'); colon = strchr(a->hostport, ':');
if (colon == NULL) { if (colon == NULL) {
if (strcmp(a->hostport, "unconnected") == 0) { if (strcmp(a->hostport, "unconnected") == 0) {
AsconError(a, "offline", 0); AsconError(a, "disconnected", 0);
} else { } else {
AsconError(a, "expected 'host:port' or 'unconnected'", 0); AsconError(a, "expected 'host:port' or 'unconnected'", 0);
} }
@ -147,7 +184,7 @@ static void AsconConnect(Ascon * a)
return; return;
} }
*colon = '\0'; *colon = '\0';
ret = CreateSocketAdress(&adr, a->hostport, port); ret = MakeSocketAdress(&adr, a->hostport, port);
*colon = ':'; *colon = ':';
if (ret == 0) { if (ret == 0) {
a->ip = 0; a->ip = 0;
@ -157,8 +194,7 @@ static void AsconConnect(Ascon * a)
a->ip = adr.sin_addr.s_addr; a->ip = adr.sin_addr.s_addr;
oldopts = fcntl(a->fd, F_GETFL, 0); oldopts = fcntl(a->fd, F_GETFL, 0);
fcntl(a->fd, F_SETFL, oldopts | O_NONBLOCK); fcntl(a->fd, F_SETFL, oldopts | O_NONBLOCK);
ret = ret = connect(a->fd, (struct sockaddr *) &adr, sizeof(struct sockaddr_in));
connect(a->fd, (struct sockaddr *) &adr, sizeof(struct sockaddr_in));
if (ret < 0) { if (ret < 0) {
switch (errno) { switch (errno) {
case EINPROGRESS: case EINPROGRESS:

View File

@ -254,7 +254,7 @@ int DevQueueTask(void *ds)
LogResponse(devser,0); LogResponse(devser,0);
} }
} else if (devser->status == AsconOffline) { } else if (devser->status == AsconOffline) {
replyData = "ASCERR: offline"; replyData = "ASCERR: disconnected";
} else { } else {
return 1; return 1;
} }
@ -602,7 +602,7 @@ char *DevStatus(DevSer *devser) {
if (strncmp(str, "ASCERR: ", 8) == 0) { if (strncmp(str, "ASCERR: ", 8) == 0) {
str += 8; str += 8;
} }
pos = strchr(str, '('); pos = strstr(str, " (");
if (pos != 0) { if (pos != 0) {
snprintf(buf, sizeof buf, "%s", str); snprintf(buf, sizeof buf, "%s", str);
buf[pos-str] = 0; buf[pos-str] = 0;