Mercurial > hg > octave-lyh > gnulib-hg
changeset 6224:85d0a6143cc4
* modules/canon-host: Add canon-host.h. Depend on getaddrinfo. Make
LGPL.
* modules/getaddrinfo: Add link to opengroup spec. Depend on strdup.
Make canon-host require getaddrinfo.
* m4/canon-host.m4 (gl_CANON_HOST): Remove most dependencies.
AC_LIBSOURCE canon-host.h. Call...
(gl_PREREQ_CANON_HOST): ...this new function, which requires
gl_GETADDRINFO.
* m4/getaddrinfo.m4 (gl_GETADDRINFO): Compile gai_strerror when
needed.
Return usable errors from canon-host.
* lib/canon-host.h: New file.
* lib/canon-host.c (canon_host): Wrap...
(canon_host_r): ...this new function, which now relies exclusively on
getaddrinfo.
(ch_strerror): New function.
(last_cherror): New global.
* lib/getaddrinfo.c: Move include of getaddrinfo.h first to test
interface.
(getaddrinfo): Add AI_CANONNAME functionality. Don't do arithmetic
on void *.
(freeaddrinfo): Free ai->ai_canonname when set.
author | Derek R. Price <derek@ximbiot.com> |
---|---|
date | Tue, 13 Sep 2005 04:15:15 +0000 |
parents | 1c8ef7732db0 |
children | f50680a85bd4 |
files | ChangeLog lib/ChangeLog lib/canon-host.c lib/canon-host.h lib/getaddrinfo.c lib/getaddrinfo.h m4/ChangeLog m4/canon-host.m4 m4/getaddrinfo.m4 modules/canon-host modules/getaddrinfo |
diffstat | 11 files changed, 163 insertions(+), 115 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-09-12 Derek Price <derek@ximbiot.com> + + * modules/canon-host: Add canon-host.h. Depend on getaddrinfo. Make + LGPL. + * modules/getaddrinfo: Add link to opengroup spec. Depend on strdup. + 2005-09-12 Derek Price <derek@ximbiot.com> Paul Eggert <eggert@cs.ucla.edu>
--- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,17 @@ +2005-09-12 Derek Price <derek@ximbiot.com> + + Return usable errors from canon-host. + * canon-host.h: New file. + * canon-host.c (canon_host): Wrap... + (canon_host_r): ...this new function, which now relies exclusively on + getaddrinfo. + (ch_strerror): New function. + (last_cherror): New global. + * getaddrinfo.c: Move include of getaddrinfo.h first to test interface. + (getaddrinfo): Add AI_CANONNAME functionality. Don't do arithmetic on + void *. + (freeaddrinfo): Free ai->ai_canonname when set. + 2005-09-12 Derek Price <derek@ximbiot.com> Paul Eggert <eggert@cs.ucla.edu>
--- a/lib/canon-host.c +++ b/lib/canon-host.c @@ -1,9 +1,9 @@ /* Host name canonicalization - Copyright (C) 1995, 1999, 2000, 2002, 2003, 2004, 2005 Free Software + Copyright (C) 2005 Free Software Foundation, Inc. - Written by Miles Bader <miles@gnu.ai.mit.edu> + Written by Derek Price <derek@ximbiot.com>. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -23,105 +23,77 @@ # include <config.h> #endif -#include <sys/types.h> -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif -#include <stdlib.h> -#include <string.h> -#ifdef HAVE_NETDB_H -# include <netdb.h> -#endif -#ifdef HAVE_SYS_SOCKET_H -# include <sys/socket.h> -#endif +#include "canon-host.h" -#ifdef HAVE_NETINET_IN_H -# include <netinet/in.h> -#endif -#ifdef HAVE_ARPA_INET_H -# include <arpa/inet.h> -#endif - +#include "getaddrinfo.h" #include "strdup.h" -/* Returns the canonical hostname associated with HOST (allocated in a static - buffer), or NULL if it can't be determined. */ -char * -canon_host (char const *host) -{ - char *h_addr_copy = NULL; + -#if HAVE_GETADDRINFO - { - struct addrinfo hint = { 0, }; - struct addrinfo *res = NULL; - hint.ai_flags = AI_CANONNAME; - if (getaddrinfo (host, NULL, &hint, &res) == 0) - { - h_addr_copy = strdup (res->ai_canonname); - freeaddrinfo (res); - } - } -#elif HAVE_GETHOSTBYNAME - { - struct hostent *he = gethostbyname (host); +/* Store the last error for the single-threaded version of this function. */ +static int last_cherror; - if (he) - { -# ifdef HAVE_GETHOSTBYADDR - char *addr = NULL; + - /* Try and get an ascii version of the numeric host address. */ - switch (he->h_addrtype) - { -# ifdef HAVE_INET_NTOA - case AF_INET: - addr = inet_ntoa (*(struct in_addr *) he->h_addr); - break; -# endif /* HAVE_INET_NTOA */ - } - - if (addr && strcmp (he->h_name, addr) == 0) - { - /* gethostbyname has returned a string representation of the IP - address, for example, "127.0.0.1". So now, look up the host - name via the address. Although it may seem reasonable to look - up the host name via the address, we must not pass `he->h_addr' - directly to gethostbyaddr because on some systems he->h_addr - is located in a static library buffer that is reused in the - gethostbyaddr call. Make a copy and use that instead. */ - h_addr_copy = (char *) malloc (he->h_length); - if (h_addr_copy == NULL) - he = NULL; - else - { - memcpy (h_addr_copy, he->h_addr, he->h_length); - he = gethostbyaddr (h_addr_copy, he->h_length, he->h_addrtype); - free (h_addr_copy); - } - } -# endif /* HAVE_GETHOSTBYADDR */ - - if (he) - h_addr_copy = strdup (he->h_name); - } - } -#endif /* HAVE_GETHOSTBYNAME */ - - return h_addr_copy; +/* Single-threaded of wrapper for canon_host_r. After a NULL return, error + messages may be retrieved via ch_strerror(). + */ +char * +canon_host (const char *host) +{ + return canon_host_r (host, &last_cherror); } -#ifdef TEST_CANON_HOST -int -main (int argc, char **argv) + + +/* Returns a malloc'd string containing the canonical hostname associated with + HOST, or NULL if a canonical name cannot be determined. On NULL return, if + CHERROR is not NULL, *CHERROR will be set to an error code as returned by + getaddrinfo(). Error codes from CHERROR may be converted to a string + suitable for error messages by ch_strerror_r() or gai_strerror(). + + WARNINGS + HOST must be a string representation of a resolvable name for this host. + Strings containing an IP address in dotted decimal notation will be + returned as-is, without further resolution. + + The use of the word "canonical" in this context is unfortunate but + entrenched. The value returned by this function will be the end result + of the resolution of any CNAME chains in the DNS. There may only be one + such value for any given hostname, though the actual IP address + referenced by this value and the device using that IP address may each + actually have any number of such "canonical" hostnames. See the POSIX + getaddrinfo spec <http://www.opengroup.org/susv3xsh/getaddrinfo.html">, + RFC 1034 <http://www.faqs.org/rfcs/rfc1034.html>, & RFC 2181 + <http://www.faqs.org/rfcs/rfc2181.html> for more on what this confusing + term really refers to. + */ +char * +canon_host_r (char const *host, int *cherror) { - int i; - for (i = 1; i < argc; i++) + char *retval = NULL; + static struct addrinfo hints; + struct addrinfo *res = NULL; + int status; + + hints.ai_flags = AI_CANONNAME; + status = getaddrinfo (host, NULL, &hints, &res); + if (!status) { - char *s = canon_host (argv[i]); - printf ("%s: %s\n", argv[i], (s ? s : "<undef>")); + retval = strdup (res->ai_canonname); + freeaddrinfo (res); } - exit (0); + else if (cherror) + *cherror = status; + + return retval; } -#endif /* TEST_CANON_HOST */ + + + +/* Return a string describing the last error encountered by canon_host. */ +const char * +ch_strerror (void) +{ + return gai_strerror (last_cherror); +}
new file mode 100644 --- /dev/null +++ b/lib/canon-host.h @@ -0,0 +1,30 @@ +/* Host name canonicalization + + Copyright (C) 2005 Free Software Foundation, Inc. + + Written by Derek Price <derek@ximbiot.com> + + This program 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 2, or (at + your option) any later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef CANON_HOST_H +# define CANON_HOST_H 1 + +char *canon_host (char const *host); +char *canon_host_r (char const *host, int *cherror); + +const char *ch_strerror (void); +#define ch_strerror_r(cherror) gai_strerror (cherror); + +#endif /* !CANON_HOST_H */
--- a/lib/getaddrinfo.c +++ b/lib/getaddrinfo.c @@ -20,6 +20,8 @@ # include <config.h> #endif +#include "getaddrinfo.h" + /* Get calloc. */ #include <stdlib.h> @@ -35,7 +37,7 @@ #define _(String) gettext (String) #define N_(String) String -#include "getaddrinfo.h" +#include "strdup.h" static inline bool validate_family (int family) @@ -67,7 +69,7 @@ struct hostent *he; size_t sinlen; - if (hints && hints->ai_flags) + if (hints && (hints->ai_flags & ~AI_CANONNAME)) /* FIXME: Support more flags. */ return EAI_BADFLAGS; @@ -127,7 +129,7 @@ #if HAVE_IPV6 case PF_INET6: { - struct sockaddr_in6 *sinp = (void *) tmp + sizeof (*tmp); + struct sockaddr_in6 *sinp = (char *) tmp + sizeof (*tmp); if (se) sinp->sin6_port = se->s_port; @@ -146,7 +148,7 @@ #if HAVE_IPV4 case PF_INET: { - struct sockaddr_in *sinp = (void *) tmp + sizeof (*tmp); + struct sockaddr_in *sinp = (char *) tmp + sizeof (*tmp); if (se) sinp->sin_port = se->s_port; @@ -167,6 +169,22 @@ return EAI_NODATA; } + if (hints && hints->ai_flags & AI_CANONNAME) + { + const char *cn; + if (he->h_name) + cn = he->h_name; + else + cn = nodename; + + tmp->ai_canonname = strdup (cn); + if (!tmp->ai_canonname) + { + free (tmp); + return EAI_MEMORY; + } + } + tmp->ai_protocol = (hints) ? hints->ai_protocol : 0; tmp->ai_socktype = (hints) ? hints->ai_socktype : 0; tmp->ai_addr->sa_family = he->h_addrtype; @@ -188,6 +206,8 @@ cur = ai; ai = ai->ai_next; + + if (cur->ai_canonname) free (cur->ai_canonname); free (cur); } }
--- a/lib/getaddrinfo.h +++ b/lib/getaddrinfo.h @@ -25,7 +25,7 @@ # include <sys/socket.h> # include <netdb.h> -# if defined HAVE_GETADDRINFO && !HAVE_GETADDRINFO +# if !HAVE_GETADDRINFO /* Structure to contain information about address of a service provider. */ struct addrinfo @@ -90,6 +90,6 @@ <http://www.opengroup.org/susv3xsh/gai_strerror.html>. */ extern const char *gai_strerror (int ecode); -# endif +# endif /* !HAVE_GETADDRINFO */ #endif /* GETADDRINFO_H */
--- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,12 @@ +2005-09-12 Derek Price <derek@ximbiot.com> + + Make canon-host require getaddrinfo. + * canon-host.m4 (gl_CANON_HOST): Remove most dependencies. + AC_LIBSOURCE canon-host.h. Call... + (gl_PREREQ_CANON_HOST): ...this new function, which requires + gl_GETADDRINFO. + * getaddrinfo.m4 (gl_GETADDRINFO): Compile gai_strerror when needed. + 2005-09-12 Derek Price <derek@ximbiot.com> Paul Eggert <eggert@cs.ucla.edu>
--- a/m4/canon-host.m4 +++ b/m4/canon-host.m4 @@ -1,4 +1,4 @@ -# canon-host.m4 serial 6 +# canon-host.m4 serial 7 dnl Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -6,18 +6,11 @@ AC_DEFUN([gl_CANON_HOST], [ - AC_LIBSOURCES([canon-host.c]) + AC_LIBSOURCES([canon-host.c, canon-host.h]) AC_LIBOBJ([canon-host]) - - dnl Prerequisites of lib/canon-host.c. - AC_CHECK_HEADERS_ONCE(unistd.h) - AC_CHECK_HEADERS(netdb.h sys/socket.h netinet/in.h arpa/inet.h) + gl_PREREQ_CANON_HOST +]) - dnl Add any libraries as early as possible. - dnl In particular, inet_ntoa needs -lnsl at least on Solaris 2.5.1, - dnl so we have to add -lnsl to LIBS before checking for that function. - AC_SEARCH_LIBS(gethostbyname, [inet nsl]) - - dnl These come from -lnsl on Solaris 2.5.1. - AC_CHECK_FUNCS(getaddrinfo gethostbyname gethostbyaddr inet_ntoa) +AC_DEFUN([gl_PREREQ_CANON_HOST], [ + AC_REQUIRE([gl_GETADDRINFO]) ])
--- a/m4/getaddrinfo.m4 +++ b/m4/getaddrinfo.m4 @@ -1,4 +1,4 @@ -# getaddrinfo.m4 serial 2 +# getaddrinfo.m4 serial 3 dnl Copyright (C) 2004 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -7,7 +7,7 @@ AC_DEFUN([gl_GETADDRINFO], [ AC_SEARCH_LIBS(getaddrinfo, nsl socket) - AC_REPLACE_FUNCS(getaddrinfo) + AC_REPLACE_FUNCS(getaddrinfo gai_strerror) gl_PREREQ_GETADDRINFO ])