diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sockaddr.c | 64 | ||||
-rw-r--r-- | src/tree.c | 7 |
2 files changed, 66 insertions, 5 deletions
diff --git a/src/sockaddr.c b/src/sockaddr.c index 8cd790d..83f2450 100644 --- a/src/sockaddr.c +++ b/src/sockaddr.c @@ -1,5 +1,5 @@ /* grecs - Gray's Extensible Configuration System - Copyright (C) 2007-2016 Sergey Poznyakoff + Copyright (C) 2007-2017 Sergey Poznyakoff Grecs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -19,6 +19,7 @@ #ifdef HAVE_CONFIG_H # include <config.h> #endif +#include <stddef.h> #include <string.h> #include <ctype.h> #include <sys/types.h> @@ -36,6 +37,7 @@ grecs_sockaddr_new(size_t s) { struct grecs_sockaddr *sp = grecs_malloc(sizeof(*sp)); sp->next = NULL; + sp->str = NULL; sp->sa = grecs_zalloc(s); sp->len = s; return sp; @@ -47,6 +49,7 @@ grecs_sockaddr_free(struct grecs_sockaddr *p) while (p) { struct grecs_sockaddr *next = p->next; free(p->sa); + free(p->str); free(p); p = next; } @@ -279,3 +282,62 @@ grecs_str_to_sockaddr(struct grecs_sockaddr **sap, return parse_inet(sap, AF_UNSPEC, arg, arg, gh, locus); } + +#define S_UN_NAME(sa, salen) \ + ((salen < offsetof(struct sockaddr_un,sun_path)) ? \ + "" : (sa)->sun_path) + +static int +sockaddr_str(struct sockaddr *sa, socklen_t salen, char **pbuf, size_t *psz) +{ + int rc; + + switch (sa->sa_family) { + case AF_INET: + case AF_INET6: { + char host[NI_MAXHOST]; + char srv[NI_MAXSERV]; + if (getnameinfo(sa, salen, + host, sizeof(host), srv, sizeof(srv), + NI_NUMERICHOST|NI_NUMERICSERV) == 0) + rc = grecs_asprintf(pbuf, psz, "%s://%s:%s", + sa->sa_family == AF_INET ? + "inet" : "inet6", + host, srv); + else + rc = grecs_asprintf(pbuf, psz, + "%s://[getnameinfo failed]", + sa->sa_family == AF_INET ? + "inet" : "inet6"); + break; + } + case AF_UNIX: { + struct sockaddr_un *s_un = (struct sockaddr_un *)sa; + if (S_UN_NAME(s_un, salen)[0] == 0) + rc = grecs_asprintf(pbuf, psz, + "unix://[anonymous socket]"); + else + rc = grecs_asprintf(pbuf, psz, "unix://%s", + s_un->sun_path); + break; + } + + default: + rc = grecs_asprintf(pbuf, psz, "family:%d", sa->sa_family); + } + return rc; +} + +char const * +grecs_sockaddr_str(struct grecs_sockaddr *sa) +{ + if (!sa->str) { + size_t sz = 0; + if (sockaddr_str(sa->sa, sa->len, &sa->str, &sz)) { + //FIXME + abort(); + } + } + return sa->str; +} + @@ -120,14 +120,13 @@ grecs_node_bind(struct grecs_node *master, struct grecs_node *node, int dn) int grecs_node_unlink(struct grecs_node *node) { + if (node->up && node->up->down == node) + node->up->down = node->prev; if (node->prev) node->prev->next = node->next; - else if (node->up) - node->up->down = node->next; - else - return 1; if (node->next) node->next->prev = node->prev; + node->up = node->prev = node->next = NULL; return 0; } |