- merged "offline" and "disconnected" stati
This commit is contained in:
70
ascon.c
70
ascon.c
@ -17,13 +17,52 @@
|
||||
static double lastClose = 0; /* time of last close operation */
|
||||
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 */
|
||||
char *host, /* Host. NULL implies INADDR_ANY */
|
||||
int port)
|
||||
static int MakeSocketAdress(struct sockaddr_in *sockaddrPtr, /* Socket address */
|
||||
char *host, /* Host. NULL implies INADDR_ANY */
|
||||
int port)
|
||||
{ /* Port number */
|
||||
struct hostent *hostent; /* Host database entry */
|
||||
struct in_addr addr; /* For 64/32 bit madness */
|
||||
@ -34,15 +73,12 @@ static int CreateSocketAdress(struct sockaddr_in *sockaddrPtr, /* Socket addres
|
||||
if (host == NULL) {
|
||||
addr.s_addr = INADDR_ANY;
|
||||
} else {
|
||||
hostent = gethostbyname(host);
|
||||
if (hostent != NULL) {
|
||||
addr.s_addr = ns_lookup(host);
|
||||
if (addr.s_addr == 0) { /* try gethostbyname only if ns_lookup failed */
|
||||
hostent = gethostbyname(host);
|
||||
if (hostent == NULL) return 0; /* error */
|
||||
memcpy((char *) &addr,
|
||||
(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",
|
||||
"idle",
|
||||
"failed",
|
||||
"timeout"
|
||||
"no response"
|
||||
};
|
||||
char *state;
|
||||
char num[8];
|
||||
@ -108,7 +144,8 @@ static void AsconConnect(Ascon * a)
|
||||
char *colon;
|
||||
int port;
|
||||
int oldopts;
|
||||
|
||||
char ipaddress[16];
|
||||
|
||||
/* wait 0.5 sec before connecting again after a close
|
||||
2 reasons for that:
|
||||
- it seems that connecting immediately to a closed port fails.
|
||||
@ -135,7 +172,7 @@ static void AsconConnect(Ascon * a)
|
||||
colon = strchr(a->hostport, ':');
|
||||
if (colon == NULL) {
|
||||
if (strcmp(a->hostport, "unconnected") == 0) {
|
||||
AsconError(a, "offline", 0);
|
||||
AsconError(a, "disconnected", 0);
|
||||
} else {
|
||||
AsconError(a, "expected 'host:port' or 'unconnected'", 0);
|
||||
}
|
||||
@ -147,7 +184,7 @@ static void AsconConnect(Ascon * a)
|
||||
return;
|
||||
}
|
||||
*colon = '\0';
|
||||
ret = CreateSocketAdress(&adr, a->hostport, port);
|
||||
ret = MakeSocketAdress(&adr, a->hostport, port);
|
||||
*colon = ':';
|
||||
if (ret == 0) {
|
||||
a->ip = 0;
|
||||
@ -157,8 +194,7 @@ static void AsconConnect(Ascon * a)
|
||||
a->ip = adr.sin_addr.s_addr;
|
||||
oldopts = fcntl(a->fd, F_GETFL, 0);
|
||||
fcntl(a->fd, F_SETFL, oldopts | O_NONBLOCK);
|
||||
ret =
|
||||
connect(a->fd, (struct sockaddr *) &adr, sizeof(struct sockaddr_in));
|
||||
ret = connect(a->fd, (struct sockaddr *) &adr, sizeof(struct sockaddr_in));
|
||||
if (ret < 0) {
|
||||
switch (errno) {
|
||||
case EINPROGRESS:
|
||||
|
Reference in New Issue
Block a user