diff options
Diffstat (limited to 'libmailutils')
29 files changed, 1899 insertions, 672 deletions
diff --git a/libmailutils/Makefile.am b/libmailutils/Makefile.am index ed1aeb019..5aef3382d 100644 --- a/libmailutils/Makefile.am +++ b/libmailutils/Makefile.am @@ -13,24 +13,26 @@ # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General # Public License along with this library. If not, see # <http://www.gnu.org/licenses/>. -SUBDIRS = auth base address cfg diag filter mailbox mailer mime\ +SUBDIRS = auth base address sockaddr cidr cfg diag filter mailbox mailer mime\ server string stream stdstream property url . tests lib_LTLIBRARIES = libmailutils.la libmailutils_la_SOURCES = libmailutils_la_LIBADD = \ @MU_COMMON_LIBRARIES@\ auth/libauth.la\ base/libbase.la\ address/libaddress.la\ + sockaddr/libsockaddr.la\ + cidr/libcidr.la\ cfg/libcfg.la\ diag/libdiag.la\ filter/libfilter.la\ mailbox/libmailbox.la\ mailer/libmailer.la\ mime/libmime.la\ diff --git a/libmailutils/cidr/Makefile.am b/libmailutils/cidr/Makefile.am new file mode 100644 index 000000000..408806f79 --- /dev/null +++ b/libmailutils/cidr/Makefile.am @@ -0,0 +1,27 @@ +# GNU Mailutils -- a suite of utilities for electronic mail +# Copyright (C) 2011 Free Software Foundation, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 3 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library. If not, see +# <http://www.gnu.org/licenses/>. + +noinst_LTLIBRARIES = libcidr.la + +libcidr_la_SOURCES = \ + fromsa.c\ + fromstr.c\ + match.c\ + tosa.c\ + tostr.c + +INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils diff --git a/libmailutils/cidr/fromsa.c b/libmailutils/cidr/fromsa.c new file mode 100644 index 000000000..a2fda6680 --- /dev/null +++ b/libmailutils/cidr/fromsa.c @@ -0,0 +1,101 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2011 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <string.h> +#include <stdlib.h> +#include <mailutils/cidr.h> +#include <mailutils/errno.h> + +static void +uint32_to_bytes (unsigned char *bytes, uint32_t u) +{ + int i; + + for (i = 0; i < 4; i++) + { + bytes[i] = u & 0xff; + u >>= 8; + } +} + +int +_mu_inaddr_to_bytes (int af, void *buf, unsigned char *bytes) +{ + uint32_t u; + + switch (af) + { + case AF_INET: + memcpy (&u, buf, sizeof u); + uint32_to_bytes (bytes, u); + return 4; + +#ifdef MAILUTILS_IPV6 + case AF_INET6: + memcpy (bytes, buf, 16); + return 16; +#endif + } + return 0; +} + +int +_mu_sockaddr_to_bytes (unsigned char *bytes, struct sockaddr const *sa) +{ + switch (sa->sa_family) + { + case AF_INET: + uint32_to_bytes (bytes, ((struct sockaddr_in*)sa)->sin_addr.s_addr); + return 4; + +#ifdef MAILUTILS_IPV6 + case AF_INET6: + memcpy (bytes, &((struct sockaddr_in6*)sa)->sin6_addr, 16); + return 16; +#endif + } + return 0; +} + +int +mu_cidr_from_sockaddr (struct mu_cidr *cidr, const struct sockaddr *sa) +{ + unsigned char address[MU_INADDR_BYTES]; + int len; + int i; + + len = _mu_sockaddr_to_bytes (address, sa); + if (len == 0) + return MU_ERR_FAMILY; + cidr->family = sa->sa_family; + cidr->len = len; + memcpy (cidr->address, address, sizeof (cidr->address)); + for (i = 0; i < MU_INADDR_BYTES; i++) + cidr->netmask[i] = 0xff; + return 0; +} + + diff --git a/libmailutils/cidr/fromstr.c b/libmailutils/cidr/fromstr.c new file mode 100644 index 000000000..4e7a56f80 --- /dev/null +++ b/libmailutils/cidr/fromstr.c @@ -0,0 +1,128 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2011 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <string.h> +#include <stdlib.h> +#include <arpa/inet.h> +#include <mailutils/cidr.h> +#include <mailutils/errno.h> +#include <mailutils/sockaddr.h> + +static void +masklen_to_netmask (unsigned char *buf, size_t len, size_t masklen) +{ + int i, cnt; + + cnt = masklen / 8; + for (i = 0; i < cnt; i++) + buf[i] = 0xff; + if (i == MU_INADDR_BYTES) + return; + cnt = 8 - masklen % 8; + buf[i++] = (0xff >> cnt) << cnt; + for (; i < MU_INADDR_BYTES; i++) + buf[i] = 0; +} + +int +mu_cidr_from_string (struct mu_cidr *pcidr, const char *str) +{ + int rc; + char ipbuf[41]; + struct mu_cidr cidr; + char *p; + size_t len; + union + { + struct in_addr in; +#ifdef MAILUTILS_IPV6 + struct in6_addr in6; +#endif + } inaddr; + + p = strchr (str, '/'); + if (p) + len = p - str; + else + len = strlen (str); + + if (len > sizeof (ipbuf)) + return MU_ERR_BUFSPACE; + + memcpy (ipbuf, str, len); + ipbuf[len] = 0; + + if (mu_str_is_ipv4 (ipbuf)) + cidr.family = AF_INET; +#ifdef MAILUTILS_IPV6 + else if (mu_str_is_ipv6 (ipbuf)) + cidr.family = AF_INET6; +#endif + else + return MU_ERR_FAMILY; + + rc = inet_pton (cidr.family, ipbuf, &inaddr); + if (rc == -1) + return MU_ERR_FAMILY; + else if (rc == 0) + return MU_ERR_NONAME; + else if (rc != 1) + return MU_ERR_FAILURE; + + cidr.len = _mu_inaddr_to_bytes (cidr.family, &inaddr, cidr.address); + if (cidr.len == 0) + return MU_ERR_FAMILY; + + if (p) + { + char *end; + unsigned long masklen; + + p++; + + masklen = strtoul (p, &end, 10); + if (*end == 0) + masklen_to_netmask (cidr.netmask, cidr.len, masklen); + else if ((cidr.family == AF_INET && mu_str_is_ipv4 (p)) +#ifdef MAILUTILS_IPV6 + || (cidr.family == AF_INET6 && mu_str_is_ipv6 (ipbuf)) +#endif + ) + { + rc = inet_pton (cidr.family, p, &inaddr); + if (rc == -1) + return MU_ERR_FAMILY; + else if (rc == 0) + return MU_ERR_NONAME; + else if (rc != 1) + return MU_ERR_FAILURE; + + _mu_inaddr_to_bytes (cidr.family, &inaddr, cidr.netmask); + } + else + return MU_ERR_FAMILY; + } + else + masklen_to_netmask (cidr.netmask, cidr.len, cidr.len * 8); + + memcpy (pcidr, &cidr, sizeof (*pcidr)); + return 0; +} + diff --git a/libmailutils/cidr/match.c b/libmailutils/cidr/match.c new file mode 100644 index 000000000..dff9194ee --- /dev/null +++ b/libmailutils/cidr/match.c @@ -0,0 +1,38 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2011 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <mailutils/cidr.h> +#include <mailutils/errno.h> + +int +mu_cidr_match (struct mu_cidr *a, struct mu_cidr *b) +{ + int i; + + if (a->family != b->family) + return 1; + for (i = 0; i < a->len; i++) + { + if (a->address[i] != (b->address[i] & a->netmask[i])) + return 1; + } + return 0; +} + diff --git a/libmailutils/cidr/tosa.c b/libmailutils/cidr/tosa.c new file mode 100644 index 000000000..c14a995da --- /dev/null +++ b/libmailutils/cidr/tosa.c @@ -0,0 +1,78 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2011 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <string.h> +#include <stdlib.h> +#include <mailutils/cidr.h> +#include <mailutils/errno.h> + +int +mu_cidr_to_sockaddr (struct mu_cidr *cidr, struct sockaddr **psa) +{ + union + { + struct sockaddr sa; + struct sockaddr_in s_in; +#ifdef MAILUTILS_IPV6 + struct sockaddr_in6 s_in6; +#endif + } addr; + struct sockaddr *sa; + int socklen; + int i; + + memset (&addr, 0, sizeof (addr)); + addr.sa.sa_family = cidr->family; + switch (cidr->family) + { + case AF_INET: + socklen = sizeof (addr.s_in); + for (i = 0; i < cidr->len; i++) + { + addr.s_in.sin_addr.s_addr <<= 8; + addr.s_in.sin_addr.s_addr |= cidr->address[i]; + } + break; + +#ifdef MAILUTILS_IPV6 + case AF_INET6: + socklen = sizeof (addr.s_in6); + memcpy (&addr.s_in6.sin6_addr, cidr->address, 16); + break; +#endif + + default: + return MU_ERR_FAMILY; + } + + sa = malloc (socklen); + if (!sa) + return ENOMEM; + memcpy (sa, &addr, socklen); + *psa = sa; + return 0; +} + diff --git a/libmailutils/cidr/tostr.c b/libmailutils/cidr/tostr.c new file mode 100644 index 000000000..3d1ee5f49 --- /dev/null +++ b/libmailutils/cidr/tostr.c @@ -0,0 +1,159 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2011 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <string.h> +#include <stdlib.h> +#include <mailutils/cidr.h> +#include <mailutils/errno.h> + +static int +to_xdig (unsigned char b) +{ + if (b >= 0xa) + return 'A' + b - 0xa; + else + return '0' + b; +} + +static size_t +format_ipv6_bytes (const unsigned char *bytes, int len, + char *buf, size_t size) +{ + size_t total = 0; + int i; + + for (i = 0; i < len; i += 2) + { + if (i) + { + if (total++ < size) + *buf++ = ':'; + } + if (total++ < size) + *buf++ = to_xdig (*bytes >> 4); + if (total++ < size) + *buf++ = to_xdig (*bytes & 0xf); + bytes++; + if (total++ < size) + *buf++ = to_xdig (*bytes >> 4); + if (total++ < size) + *buf++ = to_xdig (*bytes & 0xf); + bytes++; + } + return total; +} + +static size_t +format_ipv4_bytes (const unsigned char *bytes, int len, + char *buf, size_t size) +{ + int i; + size_t total = 0; + + for (i = 0; i < len; i++) + { + unsigned char b = *bytes++; + char nbuf[3]; + int j; + + if (i) + { + if (total++ < size) + *buf++ = '.'; + } + + j = 0; + do + { + nbuf[j++] = b % 10 + '0'; + b /= 10; + } + while (b); + + for (; j; j--) + { + if (total++ < size) + *buf++ = nbuf[j - 1]; + } + } + return total; +} + +int +mu_cidr_to_string (struct mu_cidr *cidr, int flags, + char *buf, size_t size, size_t *pret) +{ + size_t (*fmt) (const unsigned char *bytes, int len, char *buf, size_t size); + size_t n, total = 0; + + if (size == 0) + return MU_ERR_BUFSPACE; + size--; + switch (cidr->family) + { + case AF_INET: + fmt = format_ipv4_bytes; + break; + +#ifdef MAILUTILS_IPV6 + case AF_INET6: + fmt = format_ipv6_bytes; + break; +#endif + + default: + return MU_ERR_FAMILY; + } + + n = fmt (cidr->address, cidr->len, buf, size); + if (buf) + buf += n; + total += n; + + if (!(flags & MU_CIDR_FMT_ADDRONLY)) + { + if (total++ < size) + *buf++ = '/'; + n = fmt (cidr->netmask, cidr->len, buf, size - total); + if (buf) + buf += n; + total += n; + } + + if (buf) + *buf++ = 0; + if (pret) + *pret = total; + return 0; +} + +int +mu_cidr_format (struct mu_cidr *cidr, int flags, char **pbuf) +{ + char buf[MU_CIDR_MAXBUFSIZE]; + int rc = mu_cidr_to_string (cidr, flags, buf, sizeof (buf), NULL); + if (rc) + return rc; + *pbuf = strdup (buf); + if (!*buf) + return ENOMEM; + return 0; +} + diff --git a/libmailutils/diag/debug.c b/libmailutils/diag/debug.c index 124311bd8..aa10e41ba 100644 --- a/libmailutils/diag/debug.c +++ b/libmailutils/diag/debug.c @@ -686,12 +686,13 @@ mu_debug_log (const char *fmt, ...) void mu_debug_log_begin (const char *fmt, ...) { va_list ap; mu_diag_init (); + mu_stream_flush (mu_strerr); va_start (ap, fmt); mu_stream_printf (mu_strerr, "\033s<%d>", MU_LOG_DEBUG); mu_stream_vprintf (mu_strerr, fmt, ap); va_end (ap); } diff --git a/libmailutils/diag/errors b/libmailutils/diag/errors index 869e4146f..03f71b715 100644 --- a/libmailutils/diag/errors +++ b/libmailutils/diag/errors @@ -1,6 +1,7 @@ + # Error messages for GNU Mailutils # Copyright (C) 2005, 2006, 2007, 2010, 2011 Free Software Foundation, # Inc. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -95,6 +96,13 @@ MU_ERR_NO_TRANSPORT _("Transport stream not set") MU_ERR_AUTH_NO_CRED _("No credentials supplied") MU_ERR_URL_MISS_PARTS _("URL missing required parts") MU_ERR_URL_EXTRA_PARTS _("URL has parts not allowed by its scheme") MU_ERR_INFO_UNAVAILABLE _("Information is not yet available") + +# The following are mapped to the corresponding EAI_ errors +MU_ERR_NONAME _("Name or service not known") +MU_ERR_BADFLAGS _("Bad value for flags") +MU_ERR_SOCKTYPE _("Socket type not supported") +MU_ERR_FAMILY _("Address family not supported") +MU_ERR_SERVICE _("Requested service not supported") diff --git a/libmailutils/server/acl.c b/libmailutils/server/acl.c index 0b7a507e0..ba1a4b86b 100644 --- a/libmailutils/server/acl.c +++ b/libmailutils/server/acl.c @@ -37,20 +37,26 @@ #include <mailutils/sys/debcat.h> #include <mailutils/error.h> #include <mailutils/errno.h> #include <mailutils/kwd.h> #include <mailutils/io.h> #include <mailutils/util.h> +#include <mailutils/sockaddr.h> +#include <mailutils/cidr.h> +#include <mailutils/stream.h> +#include <mailutils/stdstream.h> + +#ifndef MU_INADDR_BYTES +#define MU_INADDR_BYTES 16 +#endif struct _mu_acl_entry { mu_acl_action_t action; void *arg; - unsigned netmask; - int salen; - struct sockaddr sa[1]; + struct mu_cidr cidr; }; struct _mu_acl { mu_list_t aclist; }; @@ -61,58 +67,25 @@ _destroy_acl_entry (void *item) { struct _mu_acl_entry *p = item; free (p); /* FIXME: free arg? */ } -static size_t -mu_acl_entry_size (int salen) -{ - return sizeof (struct _mu_acl_entry) + salen - sizeof (struct sockaddr); -} - -static int -prepare_sa (struct sockaddr *sa) -{ - switch (sa->sa_family) - { - case AF_INET: - { - struct sockaddr_in *s_in = (struct sockaddr_in *)sa; - s_in->sin_addr.s_addr = ntohl (s_in->sin_addr.s_addr); - break; - } - - case AF_UNIX: - break; - - default: - return 1; - } - return 0; -} - int mu_acl_entry_create (struct _mu_acl_entry **pent, mu_acl_action_t action, void *data, - struct sockaddr *sa, int salen, unsigned long netmask) + struct mu_cidr *cidr) { - struct _mu_acl_entry *p = malloc (mu_acl_entry_size (salen)); + struct _mu_acl_entry *p = malloc (sizeof (*p)); if (!p) return EINVAL; p->action = action; p->arg = data; - p->netmask = ntohl (netmask); - p->salen = salen; - memcpy (p->sa, sa, salen); - if (prepare_sa (p->sa)) - { - free (p); - return EINVAL; - } + memcpy (&p->cidr, cidr, sizeof (p->cidr)); + *pent = p; return 0; } int @@ -162,21 +135,20 @@ mu_acl_get_iterator (mu_acl_t acl, mu_iterator_t *pitr) return EINVAL; return mu_list_get_iterator (acl->aclist, pitr); } int mu_acl_append (mu_acl_t acl, mu_acl_action_t act, - void *data, struct sockaddr *sa, int salen, - unsigned long netmask) + void *data, struct mu_cidr *cidr) { int rc; struct _mu_acl_entry *ent; if (!acl) return EINVAL; - rc = mu_acl_entry_create (&ent, act, data, sa, salen, netmask); + rc = mu_acl_entry_create (&ent, act, data, cidr); if (rc) { mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, ("Cannot allocate ACL entry: %s", mu_strerror (rc))); return ENOMEM; } @@ -190,20 +162,20 @@ mu_acl_append (mu_acl_t acl, mu_acl_action_t act, } return rc; } int mu_acl_prepend (mu_acl_t acl, mu_acl_action_t act, void *data, - struct sockaddr *sa, int salen, unsigned long netmask) + struct mu_cidr *cidr) { int rc; struct _mu_acl_entry *ent; if (!acl) return EINVAL; - rc = mu_acl_entry_create (&ent, act, data, sa, salen, netmask); + rc = mu_acl_entry_create (&ent, act, data, cidr); if (rc) { mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, ("Cannot allocate ACL entry: %s", mu_strerror (rc))); return ENOMEM; } @@ -216,14 +188,13 @@ mu_acl_prepend (mu_acl_t acl, mu_acl_action_t act, void *data, } return rc; } int mu_acl_insert (mu_acl_t acl, size_t pos, int before, - mu_acl_action_t act, void *data, - struct sockaddr *sa, int salen, unsigned long netmask) + mu_acl_action_t act, void *data, struct mu_cidr *cidr) { int rc; void *ptr; struct _mu_acl_entry *ent; if (!acl) @@ -233,13 +204,13 @@ mu_acl_insert (mu_acl_t acl, size_t pos, int before, if (rc) { mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, ("No such entry %lu", (unsigned long) pos)); return rc; } - rc = mu_acl_entry_create (&ent, act, data, sa, salen, netmask); + rc = mu_acl_entry_create (&ent, act, data, cidr); if (!ent) { mu_debug (MU_DEBCAT_ACL, MU_DEBUG_ERROR, ("Cannot allocate ACL entry: %s", mu_strerror (rc))); return ENOMEM; } @@ -276,207 +247,52 @@ mu_acl_string_to_action (const char *str, mu_acl_action_t *pres) int rc = mu_kwd_xlat_name (action_tab, str, &x); if (rc == 0) *pres = x; return rc; } -#define MU_S_UN_NAME(sa, salen) \ - ((salen < mu_offsetof (struct sockaddr_un,sun_path)) ? "" : (sa)->sun_path) - -static void -debug_sockaddr (struct sockaddr *sa, int salen) -{ - switch (sa->sa_family) - { - case AF_INET: - { - struct sockaddr_in s_in = *(struct sockaddr_in *)sa; - s_in.sin_addr.s_addr = htonl (s_in.sin_addr.s_addr); - mu_debug_log_cont ("{AF_INET %s:%d}", - inet_ntoa (s_in.sin_addr), ntohs (s_in.sin_port)); - break; - } - - case AF_UNIX: - { - struct sockaddr_un *s_un = (struct sockaddr_un *)sa; - if (MU_S_UN_NAME(s_un, salen)[0] == 0) - mu_debug_log_cont ("{AF_UNIX}"); - else - mu_debug_log_cont ("{AF_UNIX %s}", s_un->sun_path); - break; - } - - default: - mu_debug_log_cont ("{Unsupported family: %d}", sa->sa_family); - } -} - -size_t -mu_stpcpy (char **pbuf, size_t *psize, const char *src) -{ - size_t slen = strlen (src); - if (pbuf == NULL || *pbuf == NULL) - return slen; - else - { - char *buf = *pbuf; - size_t size = *psize; - if (size > slen) - size = slen; - memcpy (buf, src, size); - *psize -= size; - *pbuf += size; - if (*psize) - **pbuf = 0; - else - (*pbuf)[-1] = 0; - return size; - } -} - -void -mu_sockaddr_to_str (const struct sockaddr *sa, int salen, - char *bufptr, size_t buflen, - size_t *plen) +struct run_closure { - char *nbuf; - size_t len = 0; - switch (sa->sa_family) - { - case AF_INET: - { - struct sockaddr_in s_in = *(struct sockaddr_in *)sa; - len += mu_stpcpy (&bufptr, &buflen, inet_ntoa (s_in.sin_addr)); - len += mu_stpcpy (&bufptr, &buflen, ":"); - if (mu_asprintf (&nbuf, "%hu", ntohs (s_in.sin_port)) == 0) - { - len += mu_stpcpy (&bufptr, &buflen, nbuf); - free (nbuf); - } - break; - } - - case AF_UNIX: - { - struct sockaddr_un *s_un = (struct sockaddr_un *)sa; - if (MU_S_UN_NAME(s_un, salen)[0] == 0) - len += mu_stpcpy (&bufptr, &buflen, "anonymous socket"); - else - { - len += mu_stpcpy (&bufptr, &buflen, "socket "); - len += mu_stpcpy (&bufptr, &buflen, s_un->sun_path); - } - break; - } - - default: - len += mu_stpcpy (&bufptr, &buflen, "{Unsupported family"); - if (mu_asprintf (&nbuf, ": %d", sa->sa_family) == 0) - { - len += mu_stpcpy (&bufptr, &buflen, nbuf); - free (nbuf); - } - len += mu_stpcpy (&bufptr, &buflen, "}"); - } - if (plen) - *plen = len + 1; -} + unsigned idx; + struct mu_cidr addr; -char * -mu_sockaddr_to_astr (const struct sockaddr *sa, int salen) |