Files
sics/socketaddr.c
zolliker 61341b52f4 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
2021-09-16 12:26:18 +02:00

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);
}