aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/sockaddr.c64
-rw-r--r--src/tree.c7
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;
+}
+
diff --git a/src/tree.c b/src/tree.c
index 5826abf..307682c 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -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;
}

Return to:

Send suggestions and report system problems to the System administrator.