summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: af4c2ce)
raw | patch | inline | side by side (parent: af4c2ce)
author | Sebastian Harl <sh@tokkee.org> | |
Mon, 12 Jan 2015 17:43:35 +0000 (18:43 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Mon, 12 Jan 2015 17:43:35 +0000 (18:43 +0100) |
This is a convenient wrapper around getaddrinfo().
src/include/utils/os.h | patch | blob | history | |
src/utils/os.c | patch | blob | history |
diff --git a/src/include/utils/os.h b/src/include/utils/os.h
index 38d53b2a8bb1281aa13987403ea60f96b3375a6d..8ffca4bcd70a5b6ea117ba748cd3b75cb2cf6c47 100644 (file)
--- a/src/include/utils/os.h
+++ b/src/include/utils/os.h
#define SDB_UTILS_OS_H 1
#include <sys/types.h>
+#include <netdb.h>
#ifdef __cplusplus
extern "C" {
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 747a3700014bd248f19230bfd0363ccba55437ee..d8f707418b9cadb57040ef20473e6ee7d9b1de7d 100644 (file)
--- a/src/utils/os.c
+++ b/src/utils/os.c
#include <errno.h>
#include <sys/types.h>
+#include <sys/socket.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <libgen.h>
+#include <netdb.h>
#include <pwd.h>
/*
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 : */