diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-08-14 16:10:58 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-08-14 16:14:24 +0300 |
commit | 5938aedc98430070bc009c88696829462e7bd273 (patch) | |
tree | bacd78a135892aede7a89811ac35ce30d95ff7e9 /src | |
parent | 4e9e225408eeaa1f161ae366f68715529bea2d2a (diff) | |
download | grecs-5938aedc98430070bc009c88696829462e7bd273.tar.gz grecs-5938aedc98430070bc009c88696829462e7bd273.tar.bz2 |
Fix grecs_node_unlink function; implement grecs_sockaddr_str.
* include/grecs/sockaddr.h (grecs_sockaddr) <str>: New member.
(grecs_sockaddr_to_str): New proto.
* src/sockaddr.c (grecs_sockaddr_new): Initialize str.
(grecs_sockaddr_free): Free str.
(grecs_sockaddr_str): New function.
* src/tree.c (grecs_node_unlink): Fix.
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 @@ | |||
1 | /* grecs - Gray's Extensible Configuration System | 1 | /* grecs - Gray's Extensible Configuration System |
2 | Copyright (C) 2007-2016 Sergey Poznyakoff | 2 | Copyright (C) 2007-2017 Sergey Poznyakoff |
3 | 3 | ||
4 | Grecs is free software; you can redistribute it and/or modify it | 4 | Grecs is free software; you can redistribute it and/or modify it |
5 | under the terms of the GNU General Public License as published by the | 5 | under the terms of the GNU General Public License as published by the |
@@ -19,6 +19,7 @@ | |||
19 | #ifdef HAVE_CONFIG_H | 19 | #ifdef HAVE_CONFIG_H |
20 | # include <config.h> | 20 | # include <config.h> |
21 | #endif | 21 | #endif |
22 | #include <stddef.h> | ||
22 | #include <string.h> | 23 | #include <string.h> |
23 | #include <ctype.h> | 24 | #include <ctype.h> |
24 | #include <sys/types.h> | 25 | #include <sys/types.h> |
@@ -36,6 +37,7 @@ grecs_sockaddr_new(size_t s) | |||
36 | { | 37 | { |
37 | struct grecs_sockaddr *sp = grecs_malloc(sizeof(*sp)); | 38 | struct grecs_sockaddr *sp = grecs_malloc(sizeof(*sp)); |
38 | sp->next = NULL; | 39 | sp->next = NULL; |
40 | sp->str = NULL; | ||
39 | sp->sa = grecs_zalloc(s); | 41 | sp->sa = grecs_zalloc(s); |
40 | sp->len = s; | 42 | sp->len = s; |
41 | return sp; | 43 | return sp; |
@@ -47,6 +49,7 @@ grecs_sockaddr_free(struct grecs_sockaddr *p) | |||
47 | while (p) { | 49 | while (p) { |
48 | struct grecs_sockaddr *next = p->next; | 50 | struct grecs_sockaddr *next = p->next; |
49 | free(p->sa); | 51 | free(p->sa); |
52 | free(p->str); | ||
50 | free(p); | 53 | free(p); |
51 | p = next; | 54 | p = next; |
52 | } | 55 | } |
@@ -279,3 +282,62 @@ grecs_str_to_sockaddr(struct grecs_sockaddr **sap, | |||
279 | 282 | ||
280 | return parse_inet(sap, AF_UNSPEC, arg, arg, gh, locus); | 283 | return parse_inet(sap, AF_UNSPEC, arg, arg, gh, locus); |
281 | } | 284 | } |
285 | |||
286 | #define S_UN_NAME(sa, salen) \ | ||
287 | ((salen < offsetof(struct sockaddr_un,sun_path)) ? \ | ||
288 | "" : (sa)->sun_path) | ||
289 | |||
290 | static int | ||
291 | sockaddr_str(struct sockaddr *sa, socklen_t salen, char **pbuf, size_t *psz) | ||
292 | { | ||
293 | int rc; | ||
294 | |||
295 | switch (sa->sa_family) { | ||
296 | case AF_INET: | ||
297 | case AF_INET6: { | ||
298 | char host[NI_MAXHOST]; | ||
299 | char srv[NI_MAXSERV]; | ||
300 | if (getnameinfo(sa, salen, | ||
301 | host, sizeof(host), srv, sizeof(srv), | ||
302 | NI_NUMERICHOST|NI_NUMERICSERV) == 0) | ||
303 | rc = grecs_asprintf(pbuf, psz, "%s://%s:%s", | ||
304 | sa->sa_family == AF_INET ? | ||
305 | "inet" : "inet6", | ||
306 | host, srv); | ||
307 | else | ||
308 | rc = grecs_asprintf(pbuf, psz, | ||
309 | "%s://[getnameinfo failed]", | ||
310 | sa->sa_family == AF_INET ? | ||
311 | "inet" : "inet6"); | ||
312 | break; | ||
313 | } | ||
314 | case AF_UNIX: { | ||
315 | struct sockaddr_un *s_un = (struct sockaddr_un *)sa; | ||
316 | if (S_UN_NAME(s_un, salen)[0] == 0) | ||
317 | rc = grecs_asprintf(pbuf, psz, | ||
318 | "unix://[anonymous socket]"); | ||
319 | else | ||
320 | rc = grecs_asprintf(pbuf, psz, "unix://%s", | ||
321 | s_un->sun_path); | ||
322 | break; | ||
323 | } | ||
324 | |||
325 | default: | ||
326 | rc = grecs_asprintf(pbuf, psz, "family:%d", sa->sa_family); | ||
327 | } | ||
328 | return rc; | ||
329 | } | ||
330 | |||
331 | char const * | ||
332 | grecs_sockaddr_str(struct grecs_sockaddr *sa) | ||
333 | { | ||
334 | if (!sa->str) { | ||
335 | size_t sz = 0; | ||
336 | if (sockaddr_str(sa->sa, sa->len, &sa->str, &sz)) { | ||
337 | //FIXME | ||
338 | abort(); | ||
339 | } | ||
340 | } | ||
341 | return sa->str; | ||
342 | } | ||
343 | |||
@@ -120,14 +120,13 @@ grecs_node_bind(struct grecs_node *master, struct grecs_node *node, int dn) | |||
120 | int | 120 | int |
121 | grecs_node_unlink(struct grecs_node *node) | 121 | grecs_node_unlink(struct grecs_node *node) |
122 | { | 122 | { |
123 | if (node->up && node->up->down == node) | ||
124 | node->up->down = node->prev; | ||
123 | if (node->prev) | 125 | if (node->prev) |
124 | node->prev->next = node->next; | 126 | node->prev->next = node->next; |
125 | else if (node->up) | ||
126 | node->up->down = node->next; | ||
127 | else | ||
128 | return 1; | ||
129 | if (node->next) | 127 | if (node->next) |
130 | node->next->prev = node->prev; | 128 | node->next->prev = node->prev; |
129 | node->up = node->prev = node->next = NULL; | ||
131 | return 0; | 130 | return 0; |
132 | } | 131 | } |
133 | 132 | ||