diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-12-31 13:59:18 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-12-31 15:58:17 +0200 |
commit | 00e6c3c3ed06a258a02943fc49fa7c528025d747 (patch) | |
tree | 52530660be48fb5f4611bcc9393886bab8a70b72 /lib/addrfmt.c | |
parent | 7f204cc788de3e03a51087b1273deb5b59288cf2 (diff) | |
download | pies-00e6c3c3ed06a258a02943fc49fa7c528025d747.tar.gz pies-00e6c3c3ed06a258a02943fc49fa7c528025d747.tar.bz2 |
Command-line control interface.
* configure.ac (DEFAULT_CONTROL_URL): New subst variable.
* grecs: Upgrade.
* ident/pam.c (overwrite_and_free): Free ptr.
* lib/Makefile.am: Add new sources.
* src/addrfmt.c: Move to lib/addrfmt.c
* lib/grecsasrt.c: New file.
* lib/grecsasrt.h: New file.
* lib/mkfilename.c: New file.
* lib/netrc.c: New file.
* lib/pp.c: New file.
* lib/split3.c: New file.
* src/url.c: Move from lib/url.c
(pies_url_free_user, pies_url_free_passwd): New finctions.
* lib/libpies.h (strsplit3): New proto.
(pies_url_create, pies_url_destroy)
(pies_url_get_arg, pies_url_copy)
(pies_url_free_user, pies_url_free_passwd)
(netrc_scan)
(pp_add_option, pp_command_line, mkfilename)
(sockaddr_to_str, sockaddr_to_astr): New protos
* src/Makefile.am (bin_PROGRAMS): New program: piesctl
(pies_SOURCES): Remove addrfmt.c and url.c.
(noinst_HEADERS, BUILT_SOURCES): Add piesctl-cl.h
* src/cmdline.opt: Use pp_* function family to build
preprocessor command line.
* src/ctl.c (http_header_hash): Use case-insensitive hashing.
(ctlio_finalize_reply): Don't close connection after sending 401
response.
(input): Remove ws and wsflags. All uses changed.
(input_append): Use strsplit3 to parse the request line.
* src/pies.c: Use pp_* function family to build
preprocessor command line.
Move assert_, mkfilename and _cb+_url functions into libpies.
* src/pies.h (pies_sockaddr_storage): Move to libpies.h
* src/piesctl.c: New file.
* src/piesctl-cl.opt: New file.
Diffstat (limited to 'lib/addrfmt.c')
-rw-r--r-- | lib/addrfmt.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/lib/addrfmt.c b/lib/addrfmt.c new file mode 100644 index 0000000..ff615dd --- /dev/null +++ b/lib/addrfmt.c @@ -0,0 +1,174 @@ +/* This file is part of GNU Pies + Copyright (C) 2009, 2010, 2013, 2015 Sergey Poznyakoff + + GNU Pies is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GNU Pies 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include "libpies.h" +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/un.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> + +int +str2port (char *str) +{ + struct servent *serv; + char *p; + int port; + + /* First try to read it from /etc/services */ + serv = getservbyname (str, "tcp"); + + if (serv != NULL) + port = ntohs (serv->s_port); + else + { + unsigned long l; + /* Not in services, maybe a number? */ + l = strtoul (str, &p, 0); + + if (*p || l < 0 || l > USHRT_MAX) + return -1; + + port = l; + } + + return port; +} + +static size_t +_my_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; + } +} + +#define S_UN_NAME(sa, salen) \ + ((salen < offsetof (struct sockaddr_un,sun_path)) ? "" : (sa)->sun_path) + +static size_t +format_uint (char **bufptr, size_t *buflen, unsigned n) +{ + char *buf = *bufptr; + size_t len = *buflen; + size_t i; + + if (buf && len == 0) + return 0; + + for (i = 0;;) + { + unsigned x = n % 10; + if (buf) + { + if (len == 1) + break; + *buf++ = x + '0'; + --len; + } + n /= 10; + ++i; + if (n == 0) + break; + } + + if (buf) + { + char *p = *bufptr; + *bufptr = buf; + *buf = 0; + while (--buf > p) + { + char c = *p; + *p++ = *buf; + *buf = c; + } + } + return i; +} + +void +sockaddr_to_str (const struct sockaddr *sa, int salen, + char *bufptr, size_t buflen, + size_t *plen) +{ + size_t len = 0; + switch (sa->sa_family) + { + case AF_INET: + { + struct sockaddr_in s_in = *(struct sockaddr_in *)sa; + len += _my_stpcpy (&bufptr, &buflen, inet_ntoa (s_in.sin_addr)); + len += _my_stpcpy (&bufptr, &buflen, ":"); + len += format_uint (&bufptr, &buflen, ntohs (s_in.sin_port)); + break; + } + + case AF_UNIX: + { + struct sockaddr_un *s_un = (struct sockaddr_un *)sa; + if (S_UN_NAME(s_un, salen)[0] == 0) + len += _my_stpcpy (&bufptr, &buflen, "anonymous socket"); + else + { + len += _my_stpcpy (&bufptr, &buflen, "socket "); + len += _my_stpcpy (&bufptr, &buflen, s_un->sun_path); + } + break; + } + + default: + len += _my_stpcpy (&bufptr, &buflen, "{Unsupported family: "); + len += format_uint (&bufptr, &buflen, sa->sa_family); + len += _my_stpcpy (&bufptr, &buflen, "}"); + } + if (plen) + *plen = len + 1; +} + +char * +sockaddr_to_astr (const struct sockaddr *sa, int salen) +{ + size_t size; + char *p; + + sockaddr_to_str (sa, salen, NULL, 0, &size); + p = malloc (size); + if (!p) + grecs_alloc_die (); + sockaddr_to_str (sa, salen, p, size, NULL); + return p; +} |