- 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
73 lines
2.4 KiB
C
73 lines
2.4 KiB
C
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <netdb.h>
|
|
#include <arpa/inet.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
int MakeSocketAddr(
|
|
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 addr */
|
|
/*
|
|
Workaround for cases, where the local cache is not updated (yet)
|
|
often, gethostbyname gets a cached value, but dig will get a fresh one
|
|
note after an internet research: dig is 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;
|
|
}
|
|
|
|
int CreateSocketAdress(struct sockaddr_in *sockaddrPtr, /* Socket address */
|
|
char *host, /* Host. NULL implies INADDR_ANY */
|
|
int port)
|
|
{
|
|
return MakeSocketAddr((struct sockaddr *)sockaddrPtr, host, port, NULL);
|
|
}
|