X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gnulib%2Fgetaddrinfo.c;h=6aa676c89ce4e13030da78867c22ba8d30203392;hb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;hp=55462c43f9c3a2ff68b4fb667326810dcbc64957;hpb=94a044f90357edefa6f4ae9f0b1d5885b0e34aee;p=debian%2Famanda diff --git a/gnulib/getaddrinfo.c b/gnulib/getaddrinfo.c index 55462c4..6aa676c 100644 --- a/gnulib/getaddrinfo.c +++ b/gnulib/getaddrinfo.c @@ -1,11 +1,10 @@ /* Get address information (partial implementation). - Copyright (C) 1997, 2001, 2002, 2004, 2005, 2006, 2007 Free Software - Foundation, Inc. + Copyright (C) 1997, 2001-2002, 2004-2010 Free Software Foundation, Inc. Contributed by Simon Josefsson . 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) + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -19,12 +18,19 @@ #include -#include "getaddrinfo.h" +/* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc + optimizes away the sa == NULL test below. */ +#define _GL_ARG_NONNULL(params) + +#include #if HAVE_NETINET_IN_H # include #endif +/* Get inet_ntop. */ +#include + /* Get calloc. */ #include @@ -40,10 +46,6 @@ #define _(String) gettext (String) #define N_(String) String -#include "inet_ntop.h" - -extern int h_errno; - /* BeOS has AF_INET, but not PF_INET. */ #ifndef PF_INET # define PF_INET AF_INET @@ -59,12 +61,12 @@ extern int h_errno; #ifdef WIN32_NATIVE typedef int (WSAAPI *getaddrinfo_func) (const char*, const char*, - const struct addrinfo*, - struct addrinfo**); + const struct addrinfo*, + struct addrinfo**); typedef void (WSAAPI *freeaddrinfo_func) (struct addrinfo*); typedef int (WSAAPI *getnameinfo_func) (const struct sockaddr*, - socklen_t, char*, DWORD, - char*, DWORD, int); + socklen_t, char*, DWORD, + char*, DWORD, int); static getaddrinfo_func getaddrinfo_ptr = NULL; static freeaddrinfo_func freeaddrinfo_ptr = NULL; @@ -124,9 +126,9 @@ validate_family (int family) socket addresses. */ int getaddrinfo (const char *restrict nodename, - const char *restrict servname, - const struct addrinfo *restrict hints, - struct addrinfo **restrict res) + const char *restrict servname, + const struct addrinfo *restrict hints, + struct addrinfo **restrict res) { struct addrinfo *tmp; int port = 0; @@ -151,29 +153,25 @@ getaddrinfo (const char *restrict nodename, return getaddrinfo_ptr (nodename, servname, hints, res); #endif - if (hints && (hints->ai_flags & ~(AI_CANONNAME | AI_PASSIVE))) + if (hints && (hints->ai_flags & ~(AI_CANONNAME|AI_PASSIVE))) /* FIXME: Support more flags. */ return EAI_BADFLAGS; if (hints && !validate_family (hints->ai_family)) return EAI_FAMILY; - if ((hints != NULL) && - (hints->ai_socktype != 0) && - (hints->ai_socktype != SOCK_STREAM) && - (hints->ai_socktype != SOCK_DGRAM)) - { - /* FIXME: Support other socktype. */ - return EAI_SOCKTYPE; /* FIXME: Better return code? */ - } + if (hints && + hints->ai_socktype != SOCK_STREAM && hints->ai_socktype != SOCK_DGRAM) + /* FIXME: Support other socktype. */ + return EAI_SOCKTYPE; /* FIXME: Better return code? */ if (!nodename) { - if (hints && !(hints->ai_flags & AI_PASSIVE)) - return EAI_NONAME; + if (!(hints->ai_flags & AI_PASSIVE)) + return EAI_NONAME; #ifdef HAVE_IPV6 - nodename = (hints && (hints->ai_family == AF_INET6)) ? "::" : "0.0.0.0"; + nodename = (hints->ai_family == AF_INET6) ? "::" : "0.0.0.0"; #else nodename = "0.0.0.0"; #endif @@ -183,28 +181,28 @@ getaddrinfo (const char *restrict nodename, { struct servent *se = NULL; const char *proto = - (hints && hints->ai_socktype == SOCK_DGRAM) ? "udp" : "tcp"; + (hints && hints->ai_socktype == SOCK_DGRAM) ? "udp" : "tcp"; if (hints == NULL || !(hints->ai_flags & AI_NUMERICSERV)) - /* FIXME: Use getservbyname_r if available. */ - se = getservbyname (servname, proto); + /* FIXME: Use getservbyname_r if available. */ + se = getservbyname (servname, proto); if (!se) - { - char *c; - if (!(*servname >= '0' && *servname <= '9')) - return EAI_NONAME; - port = strtoul (servname, &c, 10); - if (*c || port > 0xffff) - return EAI_NONAME; - port = htons (port); - } + { + char *c; + if (!(*servname >= '0' && *servname <= '9')) + return EAI_NONAME; + port = strtoul (servname, &c, 10); + if (*c || port > 0xffff) + return EAI_NONAME; + port = htons (port); + } else - port = se->s_port; + port = se->s_port; } /* FIXME: Use gethostbyname_r if available. */ - he = gethostbyname(nodename); + he = gethostbyname (nodename); if (!he || he->h_addr_list[0] == NULL) return EAI_NONAME; @@ -235,23 +233,23 @@ getaddrinfo (const char *restrict nodename, #if HAVE_IPV6 case PF_INET6: { - struct v6_pair *p = storage; - struct sockaddr_in6 *sinp = &p->sockaddr_in6; - tmp = &p->addrinfo; + struct v6_pair *p = storage; + struct sockaddr_in6 *sinp = &p->sockaddr_in6; + tmp = &p->addrinfo; - if (port) - sinp->sin6_port = port; + if (port) + sinp->sin6_port = port; - if (he->h_length != sizeof (sinp->sin6_addr)) - { - free (storage); - return EAI_SYSTEM; /* FIXME: Better return code? Set errno? */ - } + if (he->h_length != sizeof (sinp->sin6_addr)) + { + free (storage); + return EAI_SYSTEM; /* FIXME: Better return code? Set errno? */ + } - memcpy (&sinp->sin6_addr, he->h_addr_list[0], sizeof sinp->sin6_addr); + memcpy (&sinp->sin6_addr, he->h_addr_list[0], sizeof sinp->sin6_addr); - tmp->ai_addr = (struct sockaddr *) sinp; - tmp->ai_addrlen = sizeof *sinp; + tmp->ai_addr = (struct sockaddr *) sinp; + tmp->ai_addrlen = sizeof *sinp; } break; #endif @@ -259,23 +257,23 @@ getaddrinfo (const char *restrict nodename, #if HAVE_IPV4 case PF_INET: { - struct v4_pair *p = storage; - struct sockaddr_in *sinp = &p->sockaddr_in; - tmp = &p->addrinfo; + struct v4_pair *p = storage; + struct sockaddr_in *sinp = &p->sockaddr_in; + tmp = &p->addrinfo; - if (port) - sinp->sin_port = port; + if (port) + sinp->sin_port = port; - if (he->h_length != sizeof (sinp->sin_addr)) - { - free (storage); - return EAI_SYSTEM; /* FIXME: Better return code? Set errno? */ - } + if (he->h_length != sizeof (sinp->sin_addr)) + { + free (storage); + return EAI_SYSTEM; /* FIXME: Better return code? Set errno? */ + } - memcpy (&sinp->sin_addr, he->h_addr_list[0], sizeof sinp->sin_addr); + memcpy (&sinp->sin_addr, he->h_addr_list[0], sizeof sinp->sin_addr); - tmp->ai_addr = (struct sockaddr *) sinp; - tmp->ai_addrlen = sizeof *sinp; + tmp->ai_addr = (struct sockaddr *) sinp; + tmp->ai_addrlen = sizeof *sinp; } break; #endif @@ -285,20 +283,20 @@ getaddrinfo (const char *restrict nodename, return EAI_NODATA; } - if (hints && (hints->ai_flags & AI_CANONNAME)) + if (hints && hints->ai_flags & AI_CANONNAME) { const char *cn; if (he->h_name) - cn = he->h_name; + cn = he->h_name; else - cn = nodename; + cn = nodename; tmp->ai_canonname = strdup (cn); if (!tmp->ai_canonname) - { - free (storage); - return EAI_MEMORY; - } + { + free (storage); + return EAI_MEMORY; + } } tmp->ai_protocol = (hints) ? hints->ai_protocol : 0; @@ -306,6 +304,22 @@ getaddrinfo (const char *restrict nodename, tmp->ai_addr->sa_family = he->h_addrtype; tmp->ai_family = he->h_addrtype; +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + switch (he->h_addrtype) + { +#if HAVE_IPV4 + case AF_INET: + tmp->ai_addr->sa_len = sizeof (struct sockaddr_in); + break; +#endif +#if HAVE_IPV6 + case AF_INET6: + tmp->ai_addr->sa_len = sizeof (struct sockaddr_in6); + break; +#endif + } +#endif + /* FIXME: If more than one address, create linked list of addrinfo's. */ *res = tmp; @@ -332,24 +346,27 @@ freeaddrinfo (struct addrinfo *ai) cur = ai; ai = ai->ai_next; - if (cur->ai_canonname) free (cur->ai_canonname); + free (cur->ai_canonname); free (cur); } } -int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, - char *restrict node, socklen_t nodelen, - char *restrict service, socklen_t servicelen, - int flags) +int +getnameinfo (const struct sockaddr *restrict sa, socklen_t salen, + char *restrict node, socklen_t nodelen, + char *restrict service, socklen_t servicelen, + int flags) { #ifdef WIN32_NATIVE if (use_win32_p ()) return getnameinfo_ptr (sa, salen, node, nodelen, - service, servicelen, flags); + service, servicelen, flags); #endif /* FIXME: Support other flags. */ - if (flags & ~(NI_NUMERICHOST | NI_NUMERICSERV)) + if ((node && nodelen > 0 && !(flags & NI_NUMERICHOST)) || + (service && servicelen > 0 && !(flags & NI_NUMERICHOST)) || + (flags & ~(NI_NUMERICHOST|NI_NUMERICSERV))) return EAI_BADFLAGS; if (sa == NULL || salen < sizeof (sa->sa_family)) @@ -360,102 +377,47 @@ int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, #if HAVE_IPV4 case AF_INET: if (salen < sizeof (struct sockaddr_in)) - return EAI_FAMILY; + return EAI_FAMILY; break; #endif #if HAVE_IPV6 case AF_INET6: if (salen < sizeof (struct sockaddr_in6)) - return EAI_FAMILY; + return EAI_FAMILY; break; #endif default: return EAI_FAMILY; } - if (node && (nodelen > 0)) + if (node && nodelen > 0 && flags & NI_NUMERICHOST) { - char addrbuf[256]; - switch (sa->sa_family) - { + { #if HAVE_IPV4 - case AF_INET: - if (flags & NI_NUMERICHOST) - { - if (!inet_ntop (AF_INET, - &(((const struct sockaddr_in *) sa)->sin_addr), - addrbuf, sizeof(addrbuf))) - return EAI_SYSTEM; - } - else - { - struct hostent *host_ent = gethostbyaddr( - (char *)&(((struct sockaddr_in *)sa)->sin_addr), - sizeof(struct sockaddr_in), - sa->sa_family); - if (host_ent != NULL) - { - if (nodelen <= snprintf(node, nodelen, "%s", - host_ent->h_name)) - return EAI_OVERFLOW; - } - else - { - if (!inet_ntop (AF_INET, - &(((const struct sockaddr_in *) sa)->sin_addr), - addrbuf, sizeof(addrbuf))) - { - return EAI_SYSTEM; - } - if (nodelen <= snprintf(node, nodelen, "%s", addrbuf)) - return EAI_OVERFLOW; - } - } - break; + case AF_INET: + if (!inet_ntop (AF_INET, + &(((const struct sockaddr_in *) sa)->sin_addr), + node, nodelen)) + return EAI_SYSTEM; + break; #endif #if HAVE_IPV6 - case AF_INET6: - if (flags & NI_NUMERICHOST) - { - if (!inet_ntop (AF_INET6, - &(((const struct sockaddr_in6 *) sa)->sin6_addr), - addrbuf, sizeof(addrbuf))) - return EAI_SYSTEM; - } - else - { - struct hostent *host_ent = gethostbyaddr( - (char *)&(((struct sockaddr_in6 *)sa)->sin6_addr), - sizeof(struct sockaddr_in6), - sa->sa_family); - if (host_ent != NULL) - { - if (nodelen <= snprintf(node, nodelen, "%s", - host_ent->h_name)) - return EAI_OVERFLOW; - } - else - { - if (!inet_ntop (AF_INET6, - &(((const struct sockaddr_in6 *) sa)->sin6_addr), - addrbuf, sizeof(addrbuf))) - { - return EAI_SYSTEM; - } - if (nodelen <= snprintf(node, nodelen, "%s", addrbuf)) - return EAI_OVERFLOW; - } - } - break; + case AF_INET6: + if (!inet_ntop (AF_INET6, + &(((const struct sockaddr_in6 *) sa)->sin6_addr), + node, nodelen)) + return EAI_SYSTEM; + break; #endif - default: - return EAI_FAMILY; - } + + default: + return EAI_FAMILY; + } } - if (service && (servicelen > 0)) + if (service && servicelen > 0 && flags & NI_NUMERICSERV) switch (sa->sa_family) { #if HAVE_IPV4 @@ -464,13 +426,13 @@ int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen, #if HAVE_IPV6 case AF_INET6: #endif - { - unsigned short int port - = ntohs (((const struct sockaddr_in *) sa)->sin_port); - if (servicelen <= snprintf (service, servicelen, "%u", port)) - return EAI_OVERFLOW; - } - break; + { + unsigned short int port + = ntohs (((const struct sockaddr_in *) sa)->sin_port); + if (servicelen <= snprintf (service, servicelen, "%u", port)) + return EAI_OVERFLOW; + } + break; } return 0;