From: Sebastian Harl Date: Mon, 12 Jan 2015 17:43:35 +0000 (+0100) Subject: os utils: Added sdb_resolve(). X-Git-Tag: sysdb-0.7.0~75 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=4bab2b402db650122d5338c47d27e47f814f5977;p=sysdb.git os utils: Added sdb_resolve(). This is a convenient wrapper around getaddrinfo(). --- diff --git a/src/include/utils/os.h b/src/include/utils/os.h index 38d53b2..8ffca4b 100644 --- a/src/include/utils/os.h +++ b/src/include/utils/os.h @@ -29,6 +29,7 @@ #define SDB_UTILS_OS_H 1 #include +#include #ifdef __cplusplus extern "C" { @@ -100,6 +101,30 @@ sdb_select(int fd, int type); ssize_t sdb_write(int fd, size_t msg_len, const void *msg); +enum { + SDB_NET_TCP = 1 << 0, + SDB_NET_UDP = 1 << 1, + SDB_NET_IP = SDB_NET_TCP | SDB_NET_UDP, + + SDB_NET_V4 = 1 << 2, + SDB_NET_V6 = 1 << 3, +}; + +/* + * sdb_resolve: + * Resolve the specified address on the specified network which may be a + * bitwise OR of the SDB_NET constants. The network addresses are returned in + * the list pointed to by 'res'. The list is allocated dynamically and has to + * be freed using freeaddrinfo(). + * + * Returns: + * - zero on success + * - an error code else; use gai_strerror() to translate the error into a + * human readable string + */ +int +sdb_resolve(int network, const char *address, struct addrinfo **res); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/utils/os.c b/src/utils/os.c index 747a370..d8f7074 100644 --- a/src/utils/os.c +++ b/src/utils/os.c @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -45,6 +46,7 @@ #include #include +#include #include /* @@ -248,5 +250,62 @@ sdb_write(int fd, size_t msg_len, const void *msg) return (ssize_t)msg_len; } /* sdb_write */ +int +sdb_resolve(int network, const char *address, struct addrinfo **res) +{ + struct addrinfo ai_hints; + const char *host; + char *port; + int status; + + if (! res) { + errno = EINVAL; + return EAI_SYSTEM; + } + + if (address) { + host = address; + port = strchr(host, ':'); + if (port) { + *port = '\0'; + ++port; + } + if (! *host) + host = NULL; + } + else { + host = NULL; + port = NULL; + } + + memset(&ai_hints, 0, sizeof(ai_hints)); + ai_hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; + if (network & SDB_NET_V4) + ai_hints.ai_family = AF_INET; + else if (network & SDB_NET_V6) + ai_hints.ai_family = AF_INET6; + else + ai_hints.ai_family = AF_UNSPEC; + if ((network & SDB_NET_IP) == SDB_NET_IP) { + ai_hints.ai_socktype = 0; + ai_hints.ai_protocol = 0; + } + else if (network & SDB_NET_TCP) { + ai_hints.ai_socktype = SOCK_STREAM; + ai_hints.ai_protocol = IPPROTO_TCP; + } + else if (network & SDB_NET_UDP) { + ai_hints.ai_socktype = SOCK_DGRAM; + ai_hints.ai_socktype = IPPROTO_UDP; + } + + status = getaddrinfo(host, port, &ai_hints, res); + if (port) { + --port; + *port = ':'; + } + return status; +} /* sdb_resolve */ + /* vim: set tw=78 sw=4 ts=4 noexpandtab : */