aboutsummaryrefslogtreecommitdiff
path: root/src/sockaddr.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-08-14 16:10:58 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-08-14 16:14:24 +0300
commit5938aedc98430070bc009c88696829462e7bd273 (patch)
treebacd78a135892aede7a89811ac35ce30d95ff7e9 /src/sockaddr.c
parent4e9e225408eeaa1f161ae366f68715529bea2d2a (diff)
downloadgrecs-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/sockaddr.c')
-rw-r--r--src/sockaddr.c64
1 files changed, 63 insertions, 1 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;
+}
+

Return to:

Send suggestions and report system problems to the System administrator.