diff options
Diffstat (limited to 'libc')
-rw-r--r-- | libc/inet/ether_addr.c | 1 | ||||
-rw-r--r-- | libc/inet/getaddrinfo.c | 1393 | ||||
-rw-r--r-- | libc/inet/gethostent_r.c (renamed from libc/inet/resolvename.c) | 2 | ||||
-rw-r--r-- | libc/inet/herror.c | 14 | ||||
-rw-r--r-- | libc/inet/hostid.c | 2 | ||||
-rw-r--r-- | libc/inet/ifaddrs.c | 22 | ||||
-rw-r--r-- | libc/inet/ifaddrs.h | 76 | ||||
-rw-r--r-- | libc/inet/netlinkaccess.h | 25 | ||||
-rw-r--r-- | libc/inet/rpc/rpc_thread.c | 2 | ||||
-rw-r--r-- | libc/inet/socketcalls.c | 34 | ||||
-rw-r--r-- | libc/pwd_grp/__getgrouplist_internal.c | 8 | ||||
-rw-r--r-- | libc/pwd_grp/getgrouplist.c (renamed from libc/inet/resolveaddress.c) | 4 | ||||
-rw-r--r-- | libc/pwd_grp/pwd_grp.c | 129 | ||||
-rw-r--r-- | libc/stdio/open_memstream.c | 4 | ||||
-rw-r--r-- | libc/stdio/vsnprintf.c | 2 |
15 files changed, 787 insertions, 931 deletions
diff --git a/libc/inet/ether_addr.c b/libc/inet/ether_addr.c index bcea9ba46..8e19a0f09 100644 --- a/libc/inet/ether_addr.c +++ b/libc/inet/ether_addr.c @@ -31,7 +31,6 @@ #include <netinet/ether.h> #include <netinet/if_ether.h> -libc_hidden_proto(ether_aton_r) libc_hidden_proto(ether_ntoa_r) libc_hidden_proto(sprintf) #ifdef __UCLIBC_HAS_XLOCALE__ diff --git a/libc/inet/getaddrinfo.c b/libc/inet/getaddrinfo.c index 25c1c32fa..82c784075 100644 --- a/libc/inet/getaddrinfo.c +++ b/libc/inet/getaddrinfo.c @@ -58,7 +58,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <netdb.h> #include <stdio.h> #include <stdlib.h> -#include <resolv.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> @@ -68,7 +67,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <sys/un.h> #include <sys/utsname.h> #include <net/if.h> -#include "ifaddrs.h" +#include <ifaddrs.h> /* Experimentally off - libc_hidden_proto(memcpy) */ /* Experimentally off - libc_hidden_proto(memset) */ @@ -80,7 +79,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. libc_hidden_proto(socket) libc_hidden_proto(close) libc_hidden_proto(getservbyname_r) -libc_hidden_proto(gethostbyname_r) libc_hidden_proto(gethostbyname2_r) libc_hidden_proto(gethostbyaddr_r) libc_hidden_proto(inet_pton) @@ -100,888 +98,795 @@ libc_hidden_proto(in6addr_loopback) #define UNIX_PATH_MAX 108 #endif -struct gaih_service -{ - const char *name; - int num; +/* Useful for having small structure members/global variables */ +typedef int8_t socktype_t; +typedef int8_t family_t; +typedef int8_t protocol_t; +struct BUG_too_small { + char BUG_socktype_t_too_small[(0 + | SOCK_STREAM + | SOCK_DGRAM + | SOCK_RAW + ) <= 127 ? 1 : -1]; + char BUG_family_t_too_small[(0 + | AF_UNSPEC + | AF_INET + | AF_INET6 + ) <= 127 ? 1 : -1]; + char BUG_protocol_t_too_small[(0 + | IPPROTO_TCP + | IPPROTO_UDP + ) <= 127 ? 1 : -1]; }; -struct gaih_servtuple -{ - struct gaih_servtuple *next; - int socktype; - int protocol; - int port; +struct gaih_service { + const char *name; + int num; }; -static const struct gaih_servtuple nullserv; - -struct gaih_addrtuple -{ - struct gaih_addrtuple *next; - int family; - char addr[16]; - uint32_t scopeid; +struct gaih_servtuple { + struct gaih_servtuple *next; + int socktype; + int protocol; + int port; }; -struct gaih_typeproto -{ - int socktype; - int protocol; - char name[4]; - int protoflag; +struct gaih_addrtuple { + struct gaih_addrtuple *next; + int family; + char addr[16]; + uint32_t scopeid; }; +struct gaih_typeproto { + socktype_t socktype; + protocol_t protocol; + int8_t protoflag; + char name[4]; +}; /* Values for `protoflag'. */ -#define GAI_PROTO_NOSERVICE 1 -#define GAI_PROTO_PROTOANY 2 - -static const struct gaih_typeproto gaih_inet_typeproto[] = -{ - { 0, 0, "", 0 }, - { SOCK_STREAM, IPPROTO_TCP, "tcp", 0 }, - { SOCK_DGRAM, IPPROTO_UDP, "udp", 0 }, - { SOCK_RAW, 0, "raw", GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE }, - { 0, 0, "", 0 } +#define GAI_PROTO_NOSERVICE 1 +#define GAI_PROTO_PROTOANY 2 + +static const struct gaih_typeproto gaih_inet_typeproto[] = { + { 0 , 0 , 0, "" }, + { SOCK_STREAM, IPPROTO_TCP, 0, "tcp" }, + { SOCK_DGRAM , IPPROTO_UDP, 0, "udp" }, + { SOCK_RAW , 0 , GAI_PROTO_PROTOANY|GAI_PROTO_NOSERVICE, "raw" }, + { 0 , 0 , 0, "" }, }; -struct gaih -{ - int family; - int (*gaih)(const char *name, const struct gaih_service *service, - const struct addrinfo *req, struct addrinfo **pai); +struct gaih { + int family; + int (*gaih)(const char *name, const struct gaih_service *service, + const struct addrinfo *req, struct addrinfo **pai); }; -#if PF_UNSPEC == 0 -static const struct addrinfo default_hints; -#else -static const struct addrinfo default_hints = -{ 0, PF_UNSPEC, 0, 0, 0, NULL, NULL, NULL }; -#endif - #define SEEN_IPV4 1 #define SEEN_IPV6 2 -static unsigned __check_pf (void) +static unsigned __check_pf(void) { - unsigned seen = 0; + unsigned seen = 0; #if defined __UCLIBC_SUPPORT_AI_ADDRCONFIG__ - { - /* Get the interface list via getifaddrs. */ - struct ifaddrs *ifa = NULL; - struct ifaddrs *runp; - if (getifaddrs (&ifa) != 0) - { - /* We cannot determine what interfaces are available. Be - optimistic. */ + { + /* Get the interface list via getifaddrs. */ + struct ifaddrs *ifa = NULL; + struct ifaddrs *runp; + if (getifaddrs(&ifa) != 0) { + /* We cannot determine what interfaces are available. + * Be optimistic. */ #if defined __UCLIBC_HAS_IPV4__ - seen |= SEEN_IPV4; + seen |= SEEN_IPV4; #endif /* __UCLIBC_HAS_IPV4__ */ #if defined __UCLIBC_HAS_IPV6__ - seen |= SEEN_IPV6; + seen |= SEEN_IPV6; #endif /* __UCLIBC_HAS_IPV6__ */ - return seen; - } + return seen; + } - for (runp = ifa; runp != NULL; runp = runp->ifa_next) + for (runp = ifa; runp != NULL; runp = runp->ifa_next) #if defined __UCLIBC_HAS_IPV4__ - if (runp->ifa_addr->sa_family == PF_INET) - seen |= SEEN_IPV4; + if (runp->ifa_addr->sa_family == PF_INET) + seen |= SEEN_IPV4; #endif /* __UCLIBC_HAS_IPV4__ */ -#if defined __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__ - else /* can't be both at once */ -#endif /* __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__ */ #if defined __UCLIBC_HAS_IPV6__ - if (runp->ifa_addr->sa_family == PF_INET6) - seen |= SEEN_IPV6; + if (runp->ifa_addr->sa_family == PF_INET6) + seen |= SEEN_IPV6; #endif /* __UCLIBC_HAS_IPV6__ */ - (void) freeifaddrs (ifa); - } + freeifaddrs(ifa); + } #else - /* AI_ADDRCONFIG is disabled, assume both ipv4 and ipv6 available. */ + /* AI_ADDRCONFIG is disabled, assume both ipv4 and ipv6 available. */ #if defined __UCLIBC_HAS_IPV4__ - seen |= SEEN_IPV4; + seen |= SEEN_IPV4; #endif /* __UCLIBC_HAS_IPV4__ */ #if defined __UCLIBC_HAS_IPV6__ - seen |= SEEN_IPV6; + seen |= SEEN_IPV6; #endif /* __UCLIBC_HAS_IPV6__ */ #endif /* __UCLIBC_SUPPORT_AI_ADDRCONFIG__ */ - return seen; + return seen; } -static int addrconfig (sa_family_t af) +static int addrconfig(sa_family_t af) { - int s; - int ret; - int saved_errno = errno; - unsigned seen; + int s; + int ret; + int saved_errno = errno; + unsigned seen; - seen = __check_pf(); + seen = __check_pf(); #if defined __UCLIBC_HAS_IPV4__ - if (af == AF_INET) - ret = seen & SEEN_IPV4; - else + if (af == AF_INET) + ret = seen & SEEN_IPV4; + else #endif #if defined __UCLIBC_HAS_IPV6__ - if (af == AF_INET6) - ret = seen & SEEN_IPV6; - else + if (af == AF_INET6) + ret = seen & SEEN_IPV6; + else #endif - { - s = socket(af, SOCK_DGRAM, 0); - ret = 1; /* Assume PF_UNIX. */ - if (s < 0) { - if (errno != EMFILE) - ret = 0; + { + s = socket(af, SOCK_DGRAM, 0); + ret = 1; /* Assume PF_UNIX. */ + if (s < 0) { + if (errno != EMFILE) + ret = 0; + } else + close(s); } - else - close(s); - } - __set_errno (saved_errno); - return ret; + __set_errno(saved_errno); + return ret; } #if 0 /* Using Unix sockets this way is a security risk. */ static int -gaih_local (const char *name, const struct gaih_service *service, - const struct addrinfo *req, struct addrinfo **pai) +gaih_local(const char *name, const struct gaih_service *service, + const struct addrinfo *req, struct addrinfo **pai) { - struct utsname utsname; - - if ((name != NULL) && (req->ai_flags & AI_NUMERICHOST)) - return GAIH_OKIFUNSPEC | -EAI_NONAME; - - if ((name != NULL) || (req->ai_flags & AI_CANONNAME)) - if (uname (&utsname) < 0) - return -EAI_SYSTEM; - - if (name != NULL) - { - if (strcmp(name, "localhost") && - strcmp(name, "local") && - strcmp(name, "unix") && - strcmp(name, utsname.nodename)) - return GAIH_OKIFUNSPEC | -EAI_NONAME; - } - - if (req->ai_protocol || req->ai_socktype) - { - const struct gaih_typeproto *tp = gaih_inet_typeproto + 1; - - while (tp->name[0] - && ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0 - || (req->ai_socktype != 0 && req->ai_socktype != tp->socktype) - || (req->ai_protocol != 0 - && !(tp->protoflag & GAI_PROTO_PROTOANY) - && req->ai_protocol != tp->protocol))) - ++tp; - - if (! tp->name[0]) - { - if (req->ai_socktype) - return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE); - else - return (GAIH_OKIFUNSPEC | -EAI_SERVICE); - } - } - - *pai = malloc (sizeof (struct addrinfo) + sizeof (struct sockaddr_un) - + ((req->ai_flags & AI_CANONNAME) - ? (strlen(utsname.nodename) + 1): 0)); - if (*pai == NULL) - return -EAI_MEMORY; - - (*pai)->ai_next = NULL; - (*pai)->ai_flags = req->ai_flags; - (*pai)->ai_family = AF_LOCAL; - (*pai)->ai_socktype = req->ai_socktype ? req->ai_socktype : SOCK_STREAM; - (*pai)->ai_protocol = req->ai_protocol; - (*pai)->ai_addrlen = sizeof (struct sockaddr_un); - (*pai)->ai_addr = (void *) (*pai) + sizeof (struct addrinfo); + struct utsname utsname; + struct addrinfo *ai = *pai; + + if ((name != NULL) && (req->ai_flags & AI_NUMERICHOST)) + return (GAIH_OKIFUNSPEC | -EAI_NONAME); + + if ((name != NULL) || (req->ai_flags & AI_CANONNAME)) + if (uname(&utsname) < 0) + return -EAI_SYSTEM; + + if (name != NULL) { + if (strcmp(name, "localhost") && + strcmp(name, "local") && + strcmp(name, "unix") && + strcmp(name, utsname.nodename)) + return (GAIH_OKIFUNSPEC | -EAI_NONAME); + } + + if (req->ai_protocol || req->ai_socktype) { + const struct gaih_typeproto *tp = gaih_inet_typeproto + 1; + + while (tp->name[0] + && ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0 + || (req->ai_socktype != 0 && req->ai_socktype != tp->socktype) + || (req->ai_protocol != 0 && !(tp->protoflag & GAI_PROTO_PROTOANY) && req->ai_protocol != tp->protocol)) + ) { + ++tp; + } + if (! tp->name[0]) { + if (req->ai_socktype) + return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE); + return (GAIH_OKIFUNSPEC | -EAI_SERVICE); + } + } + *pai = ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_un) + + ((req->ai_flags & AI_CANONNAME) + ? (strlen(utsname.nodename) + 1) : 0)); + if (ai == NULL) + return -EAI_MEMORY; + + ai->ai_next = NULL; + ai->ai_flags = req->ai_flags; + ai->ai_family = AF_LOCAL; + ai->ai_socktype = req->ai_socktype ? req->ai_socktype : SOCK_STREAM; + ai->ai_protocol = req->ai_protocol; + ai->ai_addrlen = sizeof(struct sockaddr_un); + ai->ai_addr = (void *)ai + sizeof(struct addrinfo); #if SALEN - ((struct sockaddr_un *) (*pai)->ai_addr)->sun_len = - sizeof (struct sockaddr_un); + ((struct sockaddr_un *)ai->ai_addr)->sun_len = sizeof(struct sockaddr_un); #endif /* SALEN */ - ((struct sockaddr_un *)(*pai)->ai_addr)->sun_family = AF_LOCAL; - memset(((struct sockaddr_un *)(*pai)->ai_addr)->sun_path, 0, UNIX_PATH_MAX); + ((struct sockaddr_un *)ai->ai_addr)->sun_family = AF_LOCAL; + memset(((struct sockaddr_un *)ai->ai_addr)->sun_path, 0, UNIX_PATH_MAX); - if (service) - { - struct sockaddr_un *sunp = (struct sockaddr_un *) (*pai)->ai_addr; + if (service) { + struct sockaddr_un *sunp = (struct sockaddr_un *)ai->ai_addr; - if (strchr (service->name, '/') != NULL) - { - if (strlen (service->name) >= sizeof (sunp->sun_path)) - return GAIH_OKIFUNSPEC | -EAI_SERVICE; + if (strchr(service->name, '/') != NULL) { + if (strlen(service->name) >= sizeof(sunp->sun_path)) + return GAIH_OKIFUNSPEC | -EAI_SERVICE; - strcpy (sunp->sun_path, service->name); + strcpy(sunp->sun_path, service->name); + } else { + if (strlen(P_tmpdir "/") + 1 + strlen(service->name) >= sizeof(sunp->sun_path)) + return (GAIH_OKIFUNSPEC | -EAI_SERVICE); + stpcpy(stpcpy(sunp->sun_path, P_tmpdir "/"), service->name); + } + } else { + /* This is a dangerous use of the interface since there is a time + window between the test for the file and the actual creation + (done by the caller) in which a file with the same name could + be created. */ + char *buf = ((struct sockaddr_un *)ai->ai_addr)->sun_path; + + if (__path_search(buf, L_tmpnam, NULL, NULL, 0) != 0 + || __gen_tempname(buf, __GT_NOCREATE) != 0 + ) { + return -EAI_SYSTEM; + } } - else - { - if (strlen (P_tmpdir "/") + 1 + strlen (service->name) >= - sizeof (sunp->sun_path)) - return GAIH_OKIFUNSPEC | -EAI_SERVICE; - stpcpy (stpcpy (sunp->sun_path, P_tmpdir "/"), service->name); - } - } - else - { - /* This is a dangerous use of the interface since there is a time - window between the test for the file and the actual creation - (done by the caller) in which a file with the same name could - be created. */ - char *buf = ((struct sockaddr_un *) (*pai)->ai_addr)->sun_path; - - if (__builtin_expect (__path_search (buf, L_tmpnam, NULL, NULL, 0), - 0) != 0 - || __builtin_expect (__gen_tempname (buf, __GT_NOCREATE), 0) != 0) - return -EAI_SYSTEM; - } - - if (req->ai_flags & AI_CANONNAME) - (*pai)->ai_canonname = strcpy ((char *) *pai + sizeof (struct addrinfo) - + sizeof (struct sockaddr_un), - utsname.nodename); - else - (*pai)->ai_canonname = NULL; - return 0; + ai->ai_canonname = NULL; + if (req->ai_flags & AI_CANONNAME) + ai->ai_canonname = strcpy((char *)(ai + 1) + sizeof(struct sockaddr_un), + utsname.nodename); + return 0; } #endif /* 0 */ static int -gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, +gaih_inet_serv(const char *servicename, const struct gaih_typeproto *tp, const struct addrinfo *req, struct gaih_servtuple *st) { - struct servent *s; - size_t tmpbuflen = 1024; - struct servent ts; - char *tmpbuf; - int r; - - do - { - tmpbuf = alloca (tmpbuflen); - - r = getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen, - &s); - if (r != 0 || s == NULL) - { - if (r == ERANGE) + struct servent *s; + size_t tmpbuflen = 1024; + struct servent ts; + char *tmpbuf; + int r; + + while (1) { + tmpbuf = alloca(tmpbuflen); + r = getservbyname_r(servicename, tp->name, &ts, tmpbuf, tmpbuflen, &s); + if (r == 0 && s != NULL) + break; + if (r != ERANGE) + return (GAIH_OKIFUNSPEC | -EAI_SERVICE); tmpbuflen *= 2; - else - return GAIH_OKIFUNSPEC | -EAI_SERVICE; } - } - while (r); - - st->next = NULL; - st->socktype = tp->socktype; - st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) - ? req->ai_protocol : tp->protocol); - st->port = s->s_port; - - return 0; + st->next = NULL; + st->socktype = tp->socktype; + st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) ? req->ai_protocol : tp->protocol); + st->port = s->s_port; + return 0; } -#define gethosts(_family, _type) \ -{ \ - int i, herrno; \ - size_t tmpbuflen; \ - struct hostent th; \ - char *tmpbuf; \ - tmpbuflen = 512; \ - no_data = 0; \ - do { \ - tmpbuflen *= 2; \ - tmpbuf = alloca (tmpbuflen); \ - rc = gethostbyname2_r (name, _family, &th, tmpbuf, \ - tmpbuflen, &h, &herrno); \ - } while (rc == ERANGE && herrno == NETDB_INTERNAL); \ - if (rc != 0) \ - { \ - if (herrno == NETDB_INTERNAL) \ - { \ - __set_h_errno (herrno); \ - return -EAI_SYSTEM; \ - } \ - if (herrno == TRY_AGAIN) \ - no_data = EAI_AGAIN; \ - else \ - no_data = herrno == NO_DATA; \ - } \ - else if (h != NULL) \ - { \ - for (i = 0; h->h_addr_list[i]; i++) \ - { \ - if (*pat == NULL) { \ - *pat = alloca (sizeof(struct gaih_addrtuple)); \ - (*pat)->scopeid = 0; \ - } \ - (*pat)->next = NULL; \ - (*pat)->family = _family; \ - memcpy ((*pat)->addr, h->h_addr_list[i], \ - sizeof(_type)); \ - pat = &((*pat)->next); \ - } \ - } \ +/* NB: also uses h,pat,rc,no_data variables */ +#define gethosts(_family, _type) \ +{ \ + int i, herrno; \ + size_t tmpbuflen; \ + struct hostent th; \ + char *tmpbuf; \ + \ + tmpbuflen = 512; \ + no_data = 0; \ + do { \ + tmpbuflen *= 2; \ + tmpbuf = alloca(tmpbuflen); \ + rc = gethostbyname2_r(name, _family, &th, tmpbuf, \ + tmpbuflen, &h, &herrno); \ + } while (rc == ERANGE && herrno == NETDB_INTERNAL); \ + if (rc != 0) { \ + if (herrno == NETDB_INTERNAL) { \ + __set_h_errno(herrno); \ + return -EAI_SYSTEM; \ + } \ + if (herrno == TRY_AGAIN) \ + no_data = EAI_AGAIN; \ + else \ + no_data = (herrno == NO_DATA); \ + } else if (h != NULL) { \ + for (i = 0; h->h_addr_list[i]; i++) { \ + if (*pat == NULL) { \ + *pat = alloca(sizeof(struct gaih_addrtuple)); \ + (*pat)->scopeid = 0; \ + } \ + (*pat)->next = NULL; \ + (*pat)->family = _family; \ + memcpy((*pat)->addr, h->h_addr_list[i], sizeof(_type)); \ + pat = &((*pat)->next); \ + } \ + } \ } static int -gaih_inet (const char *name, const struct gaih_service *service, - const struct addrinfo *req, struct addrinfo **pai) +gaih_inet(const char *name, const struct gaih_service *service, + const struct addrinfo *req, struct addrinfo **pai) { - const struct gaih_typeproto *tp = gaih_inet_typeproto; - struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv; - struct gaih_addrtuple *at = NULL; - int rc; - int v4mapped = (req->ai_family == PF_UNSPEC || req->ai_family == PF_INET6) && - (req->ai_flags & AI_V4MAPPED); - unsigned seen = __check_pf(); - - if (req->ai_protocol || req->ai_socktype) - { - ++tp; - - while (tp->name[0] - && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype) - || (req->ai_protocol != 0 - && !(tp->protoflag & GAI_PROTO_PROTOANY) - && req->ai_protocol != tp->protocol))) - ++tp; - - if (! tp->name[0]) - { - if (req->ai_socktype) - return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE); - else - return (GAIH_OKIFUNSPEC | -EAI_SERVICE); - } - } - - if (service != NULL) - { - if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0) - return (GAIH_OKIFUNSPEC | -EAI_SERVICE); - - if (service->num < 0) - { - if (tp->name[0]) - { - st = (struct gaih_servtuple *) - alloca (sizeof (struct gaih_servtuple)); - - if ((rc = gaih_inet_serv (service->name, tp, req, st))) - return rc; - } - else - { - struct gaih_servtuple **pst = &st; - for (tp++; tp->name[0]; tp++) - { - struct gaih_servtuple *newp; - - if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0) - continue; - - if (req->ai_socktype != 0 - && req->ai_socktype != tp->socktype) - continue; - if (req->ai_protocol != 0 - && !(tp->protoflag & GAI_PROTO_PROTOANY) - && req->ai_protocol != tp->protocol) - continue; - - newp = (struct gaih_servtuple *) - alloca (sizeof (struct gaih_servtuple)); - - if ((rc = gaih_inet_serv (service->name, tp, req, newp))) - { - if (rc & GAIH_OKIFUNSPEC) - continue; - return rc; - } - - *pst = newp; - pst = &(newp->next); + struct gaih_servtuple nullserv; + + const struct gaih_typeproto *tp = gaih_inet_typeproto; + struct gaih_servtuple *st = &nullserv; + struct gaih_addrtuple *at = NULL; + int rc; + int v4mapped = (req->ai_family == PF_UNSPEC || req->ai_family == PF_INET6) + && (req->ai_flags & AI_V4MAPPED); + unsigned seen = __check_pf(); + + memset(&nullserv, 0, sizeof(nullserv)); + + if (req->ai_protocol || req->ai_socktype) { + ++tp; + while (tp->name[0] + && ((req->ai_socktype != 0 && req->ai_socktype != tp->socktype) + || (req->ai_protocol != 0 && !(tp->protoflag & GAI_PROTO_PROTOANY) && req->ai_protocol != tp->protocol) + ) + ) { + ++tp; + } + if (! tp->name[0]) { + if (req->ai_socktype) + return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE); + return (GAIH_OKIFUNSPEC | -EAI_SERVICE); } - if (st == (struct gaih_servtuple *) &nullserv) - return (GAIH_OKIFUNSPEC | -EAI_SERVICE); - } - } - else - { - st = alloca (sizeof (struct gaih_servtuple)); - st->next = NULL; - st->socktype = tp->socktype; - st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) - ? req->ai_protocol : tp->protocol); - st->port = htons (service->num); } - } - else if (req->ai_socktype || req->ai_protocol) - { - st = alloca (sizeof (struct gaih_servtuple)); - st->next = NULL; - st->socktype = tp->socktype; - st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) - ? req->ai_protocol : tp->protocol); - st->port = 0; - } - else - { - /* - * Neither socket type nor protocol is set. Return all socket types - * we know about. - */ - struct gaih_servtuple **lastp = &st; - for (++tp; tp->name[0]; ++tp) - { - struct gaih_servtuple *newp; - newp = alloca (sizeof (struct gaih_servtuple)); - newp->next = NULL; - newp->socktype = tp->socktype; - newp->protocol = tp->protocol; - newp->port = 0; - - *lastp = newp; - lastp = &newp->next; + if (service != NULL) { + if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0) + return (GAIH_OKIFUNSPEC | -EAI_SERVICE); + + if (service->num < 0) { + if (tp->name[0]) { + st = alloca(sizeof(struct gaih_servtuple)); + rc = gaih_inet_serv(service->name, tp, req, st); + if (rc) + return rc; + } else { + struct gaih_servtuple **pst = &st; + for (tp++; tp->name[0]; tp++) { + struct gaih_servtuple *newp; + + if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0) + continue; + + if (req->ai_socktype != 0 && req->ai_socktype != tp->socktype) + continue; + if (req->ai_protocol != 0 + && !(tp->protoflag & GAI_PROTO_PROTOANY) + && req->ai_protocol != tp->protocol) + continue; + + newp = alloca(sizeof(struct gaih_servtuple)); + rc = gaih_inet_serv(service->name, tp, req, newp); + if (rc) { + if (rc & GAIH_OKIFUNSPEC) + continue; + return rc; + } + + *pst = newp; + pst = &(newp->next); + } + if (st == &nullserv) + return (GAIH_OKIFUNSPEC | -EAI_SERVICE); + } + } else { + st = alloca(sizeof(struct gaih_servtuple)); + st->next = NULL; + st->socktype = tp->socktype; + st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) + ? req->ai_protocol : tp->protocol); + st->port = htons(service->num); + } + } else if (req->ai_socktype || req->ai_protocol) { + st = alloca(sizeof(struct gaih_servtuple)); + st->next = NULL; + st->socktype = tp->socktype; + st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY) + ? req->ai_protocol : tp->protocol); + st->port = 0; + } else { + /* + * Neither socket type nor protocol is set. Return all socket types + * we know about. + */ + struct gaih_servtuple **lastp = &st; + for (++tp; tp->name[0]; ++tp) { + struct gaih_servtuple *newp; + + newp = alloca(sizeof(struct gaih_servtuple)); + newp->next = NULL; + newp->socktype = tp->socktype; + newp->protocol = tp->protocol; + newp->port = 0; + + *lastp = newp; + lastp = &newp->next; + } } - } - - if (name != NULL) - { - at = alloca (sizeof (struct gaih_addrtuple)); - at->family = AF_UNSPEC; - at->scopeid = 0; - at->next = NULL; - - if (inet_pton (AF_INET, name, at->addr) > 0) - { - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET || v4mapped) - at->family = AF_INET; - else - return -EAI_FAMILY; - } + if (name != NULL) { + at = alloca(sizeof(struct gaih_addrtuple)); + at->family = AF_UNSPEC; + at->scopeid = 0; + at->next = NULL; + + if (inet_pton(AF_INET, name, at->addr) > 0) { + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET || v4mapped) + at->family = AF_INET; + else + return -EAI_FAMILY; + } #if defined __UCLIBC_HAS_IPV6__ - if (at->family == AF_UNSPEC) - { - char *namebuf = strdupa (name); - char *scope_delim; - - scope_delim = strchr (namebuf, SCOPE_DELIMITER); - if (scope_delim != NULL) - *scope_delim = '\0'; - - if (inet_pton (AF_INET6, namebuf, at->addr) > 0) - { - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) - at->family = AF_INET6; - else - return -EAI_FAMILY; - - if (scope_delim != NULL) - { - int try_numericscope = 0; - if (IN6_IS_ADDR_LINKLOCAL (at->addr) - || IN6_IS_ADDR_MC_LINKLOCAL (at->addr)) - { - at->scopeid = if_nametoindex (scope_delim + 1); - if (at->scopeid == 0) - try_numericscope = 1; - } - else - try_numericscope = 1; - - if (try_numericscope != 0) - { - char *end; - assert (sizeof (uint32_t) <= sizeof (unsigned long)); - at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end, - 10); - if (*end != '\0') - return GAIH_OKIFUNSPEC | -EAI_NONAME; - } + if (at->family == AF_UNSPEC) { + char *namebuf = strdupa(name); + char *scope_delim; + + scope_delim = strchr(namebuf, SCOPE_DELIMITER); + if (scope_delim != NULL) + *scope_delim = '\0'; + + if (inet_pton(AF_INET6, namebuf, at->addr) > 0) { + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) + at->family = AF_INET6; + else + return -EAI_FAMILY; + + if (scope_delim != NULL) { + int try_numericscope = 0; + if (IN6_IS_ADDR_LINKLOCAL(at->addr) || IN6_IS_ADDR_MC_LINKLOCAL(at->addr)) { + at->scopeid = if_nametoindex(scope_delim + 1); + if (at->scopeid == 0) + try_numericscope = 1; + } else + try_numericscope = 1; + + if (try_numericscope != 0) { + char *end; + assert(sizeof(uint32_t) <= sizeof(unsigned long)); + at->scopeid = (uint32_t)strtoul(scope_delim + 1, &end, 10); + if (*end != '\0') + return (GAIH_OKIFUNSPEC | -EAI_NONAME); + } + } + } } - } - } #endif - if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0) - { - struct hostent *h; - struct gaih_addrtuple **pat = &at; - int no_data = 0; - int no_inet6_data; - - /* - * If we are looking for both IPv4 and IPv6 address we don't want - * the lookup functions to automatically promote IPv4 addresses to - * IPv6 addresses. - */ - + if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0) { + struct hostent *h; + struct gaih_addrtuple **pat = &at; + int no_data = 0; + int no_inet6_data; + + /* + * If we are looking for both IPv4 and IPv6 address we don't want + * the lookup functions to automatically promote IPv4 addresses to + * IPv6 addresses. + */ #if defined __UCLIBC_HAS_IPV6__ - if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) - if (!(req->ai_flags & AI_ADDRCONFIG) || (seen & SEEN_IPV6)) - gethosts (AF_INET6, struct in6_addr); + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) + if (!(req->ai_flags & AI_ADDRCONFIG) || (seen & SEEN_IPV6)) + gethosts(AF_INET6, struct in6_addr); #endif - no_inet6_data = no_data; - - if (req->ai_family == AF_INET || - (!v4mapped && req->ai_family == AF_UNSPEC) || - (v4mapped && (no_inet6_data != 0 || (req->ai_flags & AI_ALL)))) - if (!(req->ai_flags & AI_ADDRCONFIG) || (seen & SEEN_IPV4)) - gethosts (AF_INET, struct in_addr); - - if (no_data != 0 && no_inet6_data != 0) - { - /* If both requests timed out report this. */ - if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN) - return -EAI_AGAIN; - - /* - * We made requests but they turned out no data. - * The name is known, though. - */ - return (GAIH_OKIFUNSPEC | -EAI_AGAIN); - } - } - - if (at->family == AF_UNSPEC) - return (GAIH_OKIFUNSPEC | -EAI_NONAME); - } - else - { - struct gaih_addrtuple *atr; - atr = at = alloca (sizeof (struct gaih_addrtuple)); - memset (at, '\0', sizeof (struct gaih_addrtuple)); + no_inet6_data = no_data; + + if (req->ai_family == AF_INET + || (!v4mapped && req->ai_family == AF_UNSPEC) + || (v4mapped && (no_inet6_data != 0 || (req->ai_flags & AI_ALL))) + ) { + if (!(req->ai_flags & AI_ADDRCONFIG) || (seen & SEEN_IPV4)) + gethosts(AF_INET, struct in_addr); + } + + if (no_data != 0 && no_inet6_data != 0) { + /* If both requests timed out report this. */ + if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN) + return -EAI_AGAIN; + /* + * We made requests but they turned out no data. + * The name is known, though. + */ + return (GAIH_OKIFUNSPEC | -EAI_AGAIN); + } + } - if (req->ai_family == 0) - { - at->next = alloca (sizeof (struct gaih_addrtuple)); - memset (at->next, '\0', sizeof (struct gaih_addrtuple)); - } + if (at->family == AF_UNSPEC) + return (GAIH_OKIFUNSPEC | -EAI_NONAME); + } else { + struct gaih_addrtuple *atr; + atr = at = alloca(sizeof(struct gaih_addrtuple)); + memset(at, '\0', sizeof(struct gaih_addrtuple)); + if (req->ai_family == 0) { + at->next = alloca(sizeof(struct gaih_addrtuple)); + memset(at->next, '\0', sizeof(struct gaih_addrtuple)); + } #if defined __UCLIBC_HAS_IPV6__ - if (req->ai_family == 0 || req->ai_family == AF_INET6) - { - at->family = AF_INET6; - if ((req->ai_flags & AI_PASSIVE) == 0) - memcpy (at->addr, &in6addr_loopback, sizeof (struct in6_addr)); - atr = at->next; - } + if (req->ai_family == 0 || req->ai_family == AF_INET6) { + at->family = AF_INET6; + if ((req->ai_flags & AI_PASSIVE) == 0) + memcpy(at->addr, &in6addr_loopback, sizeof(struct in6_addr)); + atr = at->next; + } #endif - - if (req->ai_family == 0 || req->ai_family == AF_INET) - { - atr->family = AF_INET; - if ((req->ai_flags & AI_PASSIVE) == 0) - *(uint32_t *) atr->addr = htonl (INADDR_LOOPBACK); + if (req->ai_family == 0 || req->ai_family == AF_INET) { + atr->family = AF_INET; + if ((req->ai_flags & AI_PASSIVE) == 0) + *(uint32_t*)atr->addr = htonl(INADDR_LOOPBACK); + } } - } - - if (pai == NULL) - return 0; - - { - const char *c = NULL; - struct gaih_servtuple *st2; - struct gaih_addrtuple *at2 = at; - size_t socklen, namelen; - sa_family_t family; - /* - * buffer is the size of an unformatted IPv6 address in - * printable format. - */ - char buffer[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; + if (pai == NULL) + return 0; - while (at2 != NULL) { - if (req->ai_flags & AI_CANONNAME) - { - struct hostent *h = NULL; - - int herrno; - struct hostent th; - size_t tmpbuflen = 512; - char *tmpbuf; - - do - { - tmpbuflen *= 2; - tmpbuf = alloca (tmpbuflen); - - if (tmpbuf == NULL) - return -EAI_MEMORY; - - rc = gethostbyaddr_r (at2->addr, - ((at2->family == AF_INET6) - ? sizeof(struct in6_addr) - : sizeof(struct in_addr)), - at2->family, &th, tmpbuf, tmpbuflen, - &h, &herrno); - - } - while (rc == errno && herrno == NETDB_INTERNAL); - - if (rc != 0 && herrno == NETDB_INTERNAL) - { - __set_h_errno (herrno); - return -EAI_SYSTEM; - } - - if (h == NULL) - c = inet_ntop (at2->family, at2->addr, buffer, sizeof(buffer)); - else - c = h->h_name; + const char *c = NULL; + struct gaih_servtuple *st2; + struct gaih_addrtuple *at2 = at; + size_t socklen, namelen; + sa_family_t family; - if (c == NULL) - return GAIH_OKIFUNSPEC | -EAI_NONAME; - - namelen = strlen (c) + 1; - } - else - namelen = 0; + /* + * buffer is the size of an unformatted IPv6 address in + * printable format. + */ + char buffer[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; + + while (at2 != NULL) { + if (req->ai_flags & AI_CANONNAME) { + struct hostent *h = NULL; + int herrno; + struct hostent th; + size_t tmpbuflen = 512; + char *tmpbuf; + + do { + tmpbuflen *= 2; + tmpbuf = alloca(tmpbuflen); + //if (tmpbuf == NULL) + // return -EAI_MEMORY; + rc = gethostbyaddr_r(at2->addr, + ((at2->family == AF_INET6) + ? sizeof(struct in6_addr) + : sizeof(struct in_addr)), + at2->family, + &th, tmpbuf, tmpbuflen, + &h, &herrno); + } while (rc == errno && herrno == NETDB_INTERNAL); + + if (rc != 0 && herrno == NETDB_INTERNAL) { + __set_h_errno(herrno); + return -EAI_SYSTEM; + } + + if (h == NULL) + c = inet_ntop(at2->family, at2->addr, buffer, sizeof(buffer)); + else + c = h->h_name; + + if (c == NULL) + return (GAIH_OKIFUNSPEC | -EAI_NONAME); + + namelen = strlen(c) + 1; + } else + namelen = 0; #if defined __UCLIBC_HAS_IPV6__ - if (at2->family == AF_INET6 || v4mapped) - { - family = AF_INET6; - socklen = sizeof (struct sockaddr_in6); - } + if (at2->family == AF_INET6 || v4mapped) { + family = AF_INET6; + socklen = sizeof(struct sockaddr_in6); + } #endif #if defined __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__ - else + else #endif #if defined __UCLIBC_HAS_IPV4__ - { - family = AF_INET; - socklen = sizeof (struct sockaddr_in); - } + { + family = AF_INET; + socklen = sizeof(struct sockaddr_in); + } #endif - for (st2 = st; st2 != NULL; st2 = st2->next) - { - if (req->ai_flags & AI_ADDRCONFIG) { - if (family == AF_INET && !(seen & SEEN_IPV4)) - break; + for (st2 = st; st2 != NULL; st2 = st2->next) { + if (req->ai_flags & AI_ADDRCONFIG) { + if (family == AF_INET && !(seen & SEEN_IPV4)) + break; #if defined __UCLIBC_HAS_IPV6__ - else if (family == AF_INET6 && !(seen & SEEN_IPV6)) - break; + else if (family == AF_INET6 && !(seen & SEEN_IPV6)) + break; #endif - } - *pai = malloc (sizeof (struct addrinfo) + socklen + namelen); - if (*pai == NULL) - return -EAI_MEMORY; - - (*pai)->ai_flags = req->ai_flags; - (*pai)->ai_family = family; - (*pai)->ai_socktype = st2->socktype; - (*pai)->ai_protocol = st2->protocol; - (*pai)->ai_addrlen = socklen; - (*pai)->ai_addr = (void *) (*pai) + sizeof(struct addrinfo); + } + *pai = malloc(sizeof(struct addrinfo) + socklen + namelen); + if (*pai == NULL) + return -EAI_MEMORY; + + (*pai)->ai_flags = req->ai_flags; + (*pai)->ai_family = family; + (*pai)->ai_socktype = st2->socktype; + (*pai)->ai_protocol = st2->protocol; + (*pai)->ai_addrlen = socklen; + (*pai)->ai_addr = (void *) (*pai) + sizeof(struct addrinfo); #if SALEN - (*pai)->ai_addr->sa_len = socklen; + (*pai)->ai_addr->sa_len = socklen; #endif /* SALEN */ - (*pai)->ai_addr->sa_family = family; + (*pai)->ai_addr->sa_family = family; #if defined __UCLIBC_HAS_IPV6__ - if (family == AF_INET6) - { - struct sockaddr_in6 *sin6p = - (struct sockaddr_in6 *) (*pai)->ai_addr; - - sin6p->sin6_flowinfo = 0; - if (at2->family == AF_INET6) - { - memcpy (&sin6p->sin6_addr, - at2->addr, sizeof (struct in6_addr)); - } - else - { - sin6p->sin6_addr.s6_addr32[0] = 0; - sin6p->sin6_addr.s6_addr32[1] = 0; - sin6p->sin6_addr.s6_addr32[2] = htonl(0x0000ffff); - memcpy(&sin6p->sin6_addr.s6_addr32[3], - at2->addr, sizeof (sin6p->sin6_addr.s6_addr32[3])); - } - sin6p->sin6_port = st2->port; - sin6p->sin6_scope_id = at2->scopeid; - } + if (family == AF_INET6) { + struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *) (*pai)->ai_addr; + + sin6p->sin6_flowinfo = 0; + if (at2->family == AF_INET6) { + memcpy(&sin6p->sin6_addr, + at2->addr, sizeof(struct in6_addr)); + } else { + sin6p->sin6_addr.s6_addr32[0] = 0; + sin6p->sin6_addr.s6_addr32[1] = 0; + sin6p->sin6_addr.s6_addr32[2] = htonl(0x0000ffff); + memcpy(&sin6p->sin6_addr.s6_addr32[3], + at2->addr, sizeof(sin6p->sin6_addr.s6_addr32[3])); + } + sin6p->sin6_port = st2->port; + sin6p->sin6_scope_id = at2->scopeid; + } #endif #if defined __UCLIBC_HAS_IPV4__ && defined __UCLIBC_HAS_IPV6__ - else + else #endif #if defined __UCLIBC_HAS_IPV4__ - { - struct sockaddr_in *sinp = - (struct sockaddr_in *) (*pai)->ai_addr; - - memcpy (&sinp->sin_addr, - at2->addr, sizeof (struct in_addr)); - sinp->sin_port = st2->port; - memset (sinp->sin_zero, '\0', sizeof (sinp->sin_zero)); - } + { + struct sockaddr_in *sinp = (struct sockaddr_in *) (*pai)->ai_addr; + + memcpy(&sinp->sin_addr, at2->addr, sizeof(struct in_addr)); + sinp->sin_port = st2->port; + memset(sinp->sin_zero, '\0', sizeof(sinp->sin_zero)); + } #endif - if (c) - { - (*pai)->ai_canonname = ((void *) (*pai) + - sizeof (struct addrinfo) + socklen); - strcpy ((*pai)->ai_canonname, c); + if (c) { + (*pai)->ai_canonname = ((void *) (*pai) + + sizeof(struct addrinfo) + socklen); + strcpy((*pai)->ai_canonname, c); + } else { + (*pai)->ai_canonname = NULL; + } + (*pai)->ai_next = NULL; + pai = &((*pai)->ai_next); + } + + at2 = at2->next; } - else - (*pai)->ai_canonname = NULL; - - (*pai)->ai_next = NULL; - pai = &((*pai)->ai_next); - } - - at2 = at2->next; } - } - return 0; + return 0; } -static struct gaih gaih[] = -{ +static const struct gaih gaih[] = { #if defined __UCLIBC_HAS_IPV6__ - { PF_INET6, gaih_inet }, + { PF_INET6, gaih_inet }, #endif - { PF_INET, gaih_inet }, + { PF_INET, gaih_inet }, #if 0 - { PF_LOCAL, gaih_local }, + { PF_LOCAL, gaih_local }, #endif - { PF_UNSPEC, NULL } + { PF_UNSPEC, NULL } }; libc_hidden_proto(freeaddrinfo) void -freeaddrinfo (struct addrinfo *ai) +freeaddrinfo(struct addrinfo *ai) { - struct addrinfo *p; - - while (ai != NULL) - { - p = ai; - ai = ai->ai_next; - free (p); - } + struct addrinfo *p; + + while (ai != NULL) { + p = ai; + ai = ai->ai_next; + free(p); + } } libc_hidden_def(freeaddrinfo) libc_hidden_proto(getaddrinfo) int -getaddrinfo (const char *name, const char *service, +getaddrinfo(const char *name, const char *service, const struct addrinfo *hints, struct addrinfo **pai) { - int i = 0, j = 0, last_i = 0; - struct addrinfo *p = NULL, **end; - struct gaih *g = gaih, *pg = NULL; - struct gaih_service gaih_service, *pservice; - - if (name != NULL && name[0] == '*' && name[1] == 0) - name = NULL; - - if (service != NULL && service[0] == '*' && service[1] == 0) - service = NULL; - - if (name == NULL && service == NULL) - return EAI_NONAME; - - if (hints == NULL) - hints = &default_hints; - - if (hints->ai_flags & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST| - AI_ADDRCONFIG|AI_V4MAPPED|AI_NUMERICSERV|AI_ALL)) - return EAI_BADFLAGS; - - if ((hints->ai_flags & AI_CANONNAME) && name == NULL) - return EAI_BADFLAGS; + int i = 0, j, last_i = 0; + struct addrinfo *p = NULL, **end; + const struct gaih *g = gaih, *pg = NULL; + struct gaih_service gaih_service, *pservice; + struct addrinfo default_hints; + + if (name != NULL && name[0] == '*' && name[1] == 0) + name = NULL; + + if (service != NULL && service[0] == '*' && service[1] == 0) + service = NULL; + + if (name == NULL && service == NULL) + return EAI_NONAME; + + if (hints == NULL) { + memset(&default_hints, 0, sizeof(default_hints)); + if (AF_UNSPEC) + default_hints.ai_family = AF_UNSPEC; + hints = &default_hints; + } - if (service && service[0]) - { - char *c; - gaih_service.name = service; - gaih_service.num = strtoul (gaih_service.name, &c, 10); - if (*c != '\0') { - if (hints->ai_flags & AI_NUMERICSERV) - return EAI_NONAME; + if (hints->ai_flags & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST| + AI_ADDRCONFIG|AI_V4MAPPED|AI_NUMERICSERV|AI_ALL)) + return EAI_BADFLAGS; + + if ((hints->ai_flags & AI_CANONNAME) && name == NULL) + return EAI_BADFLAGS; + + if (service && service[0]) { + char *c; + gaih_service.name = service; + gaih_service.num = strtoul(gaih_service.name, &c, 10); + if (*c != '\0') { + if (hints->ai_flags & AI_NUMERICSERV) + return EAI_NONAME; + gaih_service.num = -1; + } else { + /* + * Can't specify a numerical socket unless a protocol + * family was given. + */ + if (hints->ai_socktype == 0 && hints->ai_protocol == 0) + return EAI_SERVICE; + } + pservice = &gaih_service; + } else + pservice = NULL; - gaih_service.num = -1; - } - else - /* - * Can't specify a numerical socket unless a protocol - * family was given. - */ - if (hints->ai_socktype == 0 && hints->ai_protocol == 0) - return EAI_SERVICE; - pservice = &gaih_service; - } - else - pservice = NULL; - - if (pai) - end = &p; - else end = NULL; - - while (g->gaih) - { - if (hints->ai_family == g->family || hints->ai_family == AF_UNSPEC) - { - if ((hints->ai_flags & AI_ADDRCONFIG) && !addrconfig(g->family)) - { - ++g; - continue; - } - j++; - if (pg == NULL || pg->gaih != g->gaih) - { - pg = g; - i = g->gaih (name, pservice, hints, end); - if (i != 0) - { - last_i = i; - - if (hints->ai_family == AF_UNSPEC && (i & GAIH_OKIFUNSPEC)) - continue; - - if (p) - freeaddrinfo (p); - - return -(i & GAIH_EAI); + if (pai) + end = &p; + + j = 0; + while (g->gaih) { + if (hints->ai_family == g->family || hints->ai_family == AF_UNSPEC) { + if ((hints->ai_flags & AI_ADDRCONFIG) && !addrconfig(g->family)) { + ++g; + continue; + } + j++; + if (pg == NULL || pg->gaih != g->gaih) { + pg = g; + i = g->gaih(name, pservice, hints, end); + if (i != 0) { + last_i = i; + if (hints->ai_family == AF_UNSPEC && (i & GAIH_OKIFUNSPEC)) + continue; + if (p) + freeaddrinfo(p); + return -(i & GAIH_EAI); + } + if (end) + while (*end) + end = &((*end)->ai_next); + } } - if (end) - while(*end) end = &((*end)->ai_next); - } + ++g; } - ++g; - } - if (j == 0) - return EAI_FAMILY; + if (j == 0) + return EAI_FAMILY; - if (p) - { - *pai = p; - return 0; - } + if (p) { + *pai = p; + return 0; + } - if (pai == NULL && last_i == 0) - return 0; + if (pai == NULL && last_i == 0) + return 0; - if (p) - freeaddrinfo (p); + /* if (p) - never happens, see above */ + /* freeaddrinfo(p); */ - return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME; + return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME; } libc_hidden_def(getaddrinfo) diff --git a/libc/inet/resolvename.c b/libc/inet/gethostent_r.c index 157878fd1..aeade155d 100644 --- a/libc/inet/resolvename.c +++ b/libc/inet/gethostent_r.c @@ -4,5 +4,5 @@ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -#define L_resolvename +#define L_gethostent_r #include "resolv.c" diff --git a/libc/inet/herror.c b/libc/inet/herror.c index 063f6e93e..b46578388 100644 --- a/libc/inet/herror.c +++ b/libc/inet/herror.c @@ -26,7 +26,7 @@ libc_hidden_proto(fprintf) libc_hidden_proto(__h_errno_location) -static const char *error_msg = "Resolver error"; +static const char error_msg[] = "Resolver error"; static const char *const h_errlist[] = { "Error 0", "Unknown host", /* 1 HOST_NOT_FOUND */ @@ -52,7 +52,7 @@ void herror(const char *s) } p = error_msg; if ((h_errno >= 0) && (h_errno < h_nerr)) { - p = h_errlist[h_errno]; + p = h_errlist[h_errno]; } fprintf(stderr, "%s%s%s\n", s, c, p); } @@ -61,10 +61,8 @@ libc_hidden_def(herror) const char *hstrerror(int err) { - if (err < 0) { - return(error_msg); - } else if (err < h_nerr) { - return(h_errlist[err]); - } - return(error_msg); + if ((unsigned)err < h_nerr) + return(h_errlist[err]); + + return error_msg; } diff --git a/libc/inet/hostid.c b/libc/inet/hostid.c index 33668a2fe..2528a8ce6 100644 --- a/libc/inet/hostid.c +++ b/libc/inet/hostid.c @@ -25,7 +25,7 @@ libc_hidden_proto(read) libc_hidden_proto(write) libc_hidden_proto(getuid) libc_hidden_proto(geteuid) -libc_hidden_proto(gethostbyname) +libc_hidden_proto(gethostbyname_r) libc_hidden_proto(gethostname) #define HOSTID "/etc/hostid" diff --git a/libc/inet/ifaddrs.c b/libc/inet/ifaddrs.c index a96b19a54..46be5f6b5 100644 --- a/libc/inet/ifaddrs.c +++ b/libc/inet/ifaddrs.c @@ -22,7 +22,7 @@ #include <alloca.h> #include <assert.h> #include <errno.h> -#include "ifaddrs.h" +#include <ifaddrs.h> #include <net/if.h> #include <netinet/in.h> #include <netpacket/packet.h> @@ -308,9 +308,6 @@ __netlink_open (struct netlink_handle *h) close_and_out: __netlink_close (h); out: -#if __ASSUME_NETLINK_SUPPORT == 0 - __no_netlink_support = 1; -#endif return -1; } /* Determine the ID the kernel assigned for this netlink connection. @@ -333,7 +330,7 @@ __netlink_open (struct netlink_handle *h) that a RTM_NEWADDR index is not known to this map. */ static int internal_function -map_newlink (int index, struct ifaddrs_storage *ifas, int *map, int max) +map_newlink (int idx, struct ifaddrs_storage *ifas, int *map, int max) { int i; @@ -341,12 +338,12 @@ map_newlink (int index, struct ifaddrs_storage *ifas, int *map, int max) { if (map[i] == -1) { - map[i] = index; + map[i] = idx; if (i > 0) ifas[i - 1].ifa.ifa_next = &ifas[i].ifa; return i; } - else if (map[i] == index) + else if (map[i] == idx) return i; } /* This should never be reached. If this will be reached, we have @@ -374,18 +371,11 @@ getifaddrs (struct ifaddrs **ifap) if (ifap) *ifap = NULL; - if (! __no_netlink_support && __netlink_open (&nh) < 0) + if (__netlink_open (&nh) < 0) { -#if __ASSUME_NETLINK_SUPPORT != 0 return -1; -#endif } -#if __ASSUME_NETLINK_SUPPORT == 0 - if (__no_netlink_support) - return fallback_getifaddrs (ifap); -#endif - /* Tell the kernel that we wish to get a list of all active interfaces, collect all data for every interface. */ if (__netlink_request (&nh, RTM_GETLINK) < 0) @@ -864,13 +854,11 @@ getifaddrs (struct ifaddrs **ifap) } -#if __ASSUME_NETLINK_SUPPORT != 0 void freeifaddrs (struct ifaddrs *ifa) { free (ifa); } -#endif #endif /* __UCLIBC_SUPPORT_AI_ADDRCONFIG__ */ diff --git a/libc/inet/ifaddrs.h b/libc/inet/ifaddrs.h deleted file mode 100644 index f65bcaba3..000000000 --- a/libc/inet/ifaddrs.h +++ /dev/null @@ -1,76 +0,0 @@ -/* ifaddrs.h -- declarations for getting network interface addresses - Copyright (C) 2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C 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 2.1 of the License, or (at your option) any later version. - - The GNU C 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 the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _IFADDRS_H -#define _IFADDRS_H 1 - -#include <features.h> -#include <sys/socket.h> -#include <stdbool.h> -#include <stdint.h> - -__BEGIN_DECLS - -/* The `getifaddrs' function generates a linked list of these structures. - Each element of the list describes one network interface. */ -struct ifaddrs -{ - struct ifaddrs *ifa_next; /* Pointer to the next structure. */ - - char *ifa_name; /* Name of this network interface. */ - unsigned int ifa_flags; /* Flags as from SIOCGIFFLAGS ioctl. */ - - struct sockaddr *ifa_addr; /* Network address of this interface. */ - struct sockaddr *ifa_netmask; /* Netmask of this interface. */ - union - { - /* At most one of the following two is valid. If the IFF_BROADCAST - bit is set in `ifa_flags', then `ifa_broadaddr' is valid. If the - IFF_POINTOPOINT bit is set, then `ifa_dstaddr' is valid. - It is never the case that both these bits are set at once. */ - struct sockaddr *ifu_broadaddr; /* Broadcast address of this interface. */ - struct sockaddr *ifu_dstaddr; /* Point-to-point destination address. */ - } ifa_ifu; - /* These very same macros are defined by <net/if.h> for `struct ifaddr'. - So if they are defined already, the existing definitions will be fine. */ -# ifndef ifa_broadaddr -# define ifa_broadaddr ifa_ifu.ifu_broadaddr -# endif -# ifndef ifa_dstaddr -# define ifa_dstaddr ifa_ifu.ifu_dstaddr -# endif - - void *ifa_data; /* Address-specific data (may be unused). */ -}; - - -/* Create a linked list of `struct ifaddrs' structures, one for each - network interface on the host machine. If successful, store the - list in *IFAP and return 0. On errors, return -1 and set `errno'. - - The storage returned in *IFAP is allocated dynamically and can - only be properly freed by passing it to `freeifaddrs'. */ -extern int getifaddrs (struct ifaddrs **__ifap) __THROW; - -/* Reclaim the storage allocated by a previous `getifaddrs' call. */ -extern void freeifaddrs (struct ifaddrs *__ifa) __THROW; - -__END_DECLS - -#endif /* ifaddrs.h */ diff --git a/libc/inet/netlinkaccess.h b/libc/inet/netlinkaccess.h index acadcb544..5111d3802 100644 --- a/libc/inet/netlinkaccess.h +++ b/libc/inet/netlinkaccess.h @@ -24,6 +24,7 @@ #include <unistd.h> #include <sys/types.h> +#if defined __ASSUME_NETLINK_SUPPORT || defined __UCLIBC_USE_NETLINK__ #define _LINUX_TYPES_H typedef uint8_t __u8; typedef uint16_t __u16; @@ -33,16 +34,6 @@ typedef int32_t __s32; #include <linux/rtnetlink.h> #include <linux/netlink.h> -/* Should prob be a configure option or something */ -#ifndef __ASSUME_NETLINK_SUPPORT -#ifdef __UCLIBC_USE_NETLINK__ -# define __ASSUME_NETLINK_SUPPORT 1 -#else -# define __ASSUME_NETLINK_SUPPORT 0 -#endif -#endif - - struct netlink_res { struct netlink_res *next; @@ -62,19 +53,17 @@ struct netlink_handle }; -#ifdef __UCLIBC_SUPPORT_AI_ADDRCONFIG__ -#if __ASSUME_NETLINK_SUPPORT == 0 -extern smallint __no_netlink_support attribute_hidden; -#else -# define __no_netlink_support 0 +#ifndef __ASSUME_NETLINK_SUPPORT +#define __ASSUME_NETLINK_SUPPORT 1 #endif -#endif /* __UCLIBC_SUPPORT_AI_ADDRCONFIG__ */ - extern int __netlink_open (struct netlink_handle *h) attribute_hidden; extern void __netlink_close (struct netlink_handle *h) attribute_hidden; extern void __netlink_free_handle (struct netlink_handle *h) attribute_hidden; extern int __netlink_request (struct netlink_handle *h, int type) attribute_hidden; +#else +#define __ASSUME_NETLINK_SUPPORT 0 +#endif -#endif /* netlinkaccess.h */ +#endif /* _NETLINKACCESS_H */ diff --git a/libc/inet/rpc/rpc_thread.c b/libc/inet/rpc/rpc_thread.c index 5b6579e14..441aa75a8 100644 --- a/libc/inet/rpc/rpc_thread.c +++ b/libc/inet/rpc/rpc_thread.c @@ -35,7 +35,7 @@ __rpc_thread_destroy (void) if (tvp != NULL && tvp != &__libc_tsd_RPC_VARS_mem) { __rpc_thread_svc_cleanup (); __rpc_thread_clnt_cleanup (); - //__rpc_thread_key_cleanup (); + /*__rpc_thread_key_cleanup (); */ free (tvp->authnone_private_s); free (tvp->clnt_perr_buf_s); free (tvp->clntraw_private_s); diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index 9211b01ce..66cf8f865 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -44,7 +44,7 @@ extern int __socketcall(int call, unsigned long *args) attribute_hidden; extern __typeof(accept) __libc_accept; #ifdef __NR_accept #define __NR___libc_accept __NR_accept -_syscall3(int, __libc_accept, int, call, struct sockaddr *, addr, socklen_t *,addrlen); +_syscall3(int, __libc_accept, int, call, struct sockaddr *, addr, socklen_t *,addrlen) #elif defined(__NR_socketcall) int __libc_accept(int s, struct sockaddr *addr, socklen_t * addrlen) { @@ -74,7 +74,7 @@ libc_hidden_weak(accept) #ifdef L_bind libc_hidden_proto(bind) #ifdef __NR_bind -_syscall3(int, bind, int, sockfd, const struct sockaddr *, myaddr, socklen_t, addrlen); +_syscall3(int, bind, int, sockfd, const struct sockaddr *, myaddr, socklen_t, addrlen) #elif defined(__NR_socketcall) int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen) { @@ -93,7 +93,7 @@ libc_hidden_def(bind) extern __typeof(connect) __libc_connect; #ifdef __NR_connect #define __NR___libc_connect __NR_connect -_syscall3(int, __libc_connect, int, sockfd, const struct sockaddr *, saddr, socklen_t, addrlen); +_syscall3(int, __libc_connect, int, sockfd, const struct sockaddr *, saddr, socklen_t, addrlen) #elif defined(__NR_socketcall) int __libc_connect(int sockfd, const struct sockaddr *saddr, socklen_t addrlen) { @@ -121,7 +121,7 @@ libc_hidden_weak(connect) #ifdef L_getpeername #ifdef __NR_getpeername -_syscall3(int, getpeername, int, sockfd, struct sockaddr *, addr, socklen_t *,paddrlen); +_syscall3(int, getpeername, int, sockfd, struct sockaddr *, addr, socklen_t *,paddrlen) #elif defined(__NR_socketcall) int getpeername(int sockfd, struct sockaddr *addr, socklen_t * paddrlen) { @@ -138,7 +138,7 @@ int getpeername(int sockfd, struct sockaddr *addr, socklen_t * paddrlen) #ifdef L_getsockname libc_hidden_proto(getsockname) #ifdef __NR_getsockname -_syscall3(int, getsockname, int, sockfd, struct sockaddr *, addr, socklen_t *,paddrlen); +_syscall3(int, getsockname, int, sockfd, struct sockaddr *, addr, socklen_t *,paddrlen) #elif defined(__NR_socketcall) int getsockname(int sockfd, struct sockaddr *addr, socklen_t * paddrlen) { @@ -155,7 +155,7 @@ libc_hidden_def(getsockname) #ifdef L_getsockopt #ifdef __NR_getsockopt -_syscall5(int, getsockopt, int, fd, int, level, int, optname, __ptr_t, optval, socklen_t *, optlen); +_syscall5(int, getsockopt, int, fd, int, level, int, optname, __ptr_t, optval, socklen_t *, optlen) #elif defined(__NR_socketcall) int getsockopt(int fd, int level, int optname, __ptr_t optval, socklen_t * optlen) @@ -175,7 +175,7 @@ int getsockopt(int fd, int level, int optname, __ptr_t optval, #ifdef L_listen libc_hidden_proto(listen) #ifdef __NR_listen -_syscall2(int, listen, int, sockfd, int, backlog); +_syscall2(int, listen, int, sockfd, int, backlog) #elif defined(__NR_socketcall) int listen(int sockfd, int backlog) { @@ -194,7 +194,7 @@ extern __typeof(recv) __libc_recv; #ifdef __NR_recv #define __NR___libc_recv __NR_recv _syscall4(ssize_t, __libc_recv, int, sockfd, __ptr_t, buffer, size_t, len, - int, flags); + int, flags) #elif defined(__NR_socketcall) /* recv, recvfrom added by bir7@leland.stanford.edu */ ssize_t __libc_recv(int sockfd, __ptr_t buffer, size_t len, int flags) @@ -233,7 +233,7 @@ extern __typeof(recvfrom) __libc_recvfrom; #ifdef __NR_recvfrom #define __NR___libc_recvfrom __NR_recvfrom _syscall6(ssize_t, __libc_recvfrom, int, sockfd, __ptr_t, buffer, size_t, len, - int, flags, struct sockaddr *, to, socklen_t *, tolen); + int, flags, struct sockaddr *, to, socklen_t *, tolen) #elif defined(__NR_socketcall) /* recv, recvfrom added by bir7@leland.stanford.edu */ ssize_t __libc_recvfrom(int sockfd, __ptr_t buffer, size_t len, int flags, @@ -268,7 +268,7 @@ libc_hidden_weak(recvfrom) extern __typeof(recvmsg) __libc_recvmsg; #ifdef __NR_recvmsg #define __NR___libc_recvmsg __NR_recvmsg -_syscall3(ssize_t, __libc_recvmsg, int, sockfd, struct msghdr *, msg, int, flags); +_syscall3(ssize_t, __libc_recvmsg, int, sockfd, struct msghdr *, msg, int, flags) #elif defined(__NR_socketcall) ssize_t __libc_recvmsg(int sockfd, struct msghdr *msg, int flags) { @@ -298,7 +298,7 @@ libc_hidden_weak(recvmsg) extern __typeof(send) __libc_send; #ifdef __NR_send #define __NR___libc_send __NR_send -_syscall4(ssize_t, __libc_send, int, sockfd, const void *, buffer, size_t, len, int, flags); +_syscall4(ssize_t, __libc_send, int, sockfd, const void *, buffer, size_t, len, int, flags) #elif defined(__NR_socketcall) /* send, sendto added by bir7@leland.stanford.edu */ ssize_t __libc_send(int sockfd, const void *buffer, size_t len, int flags) @@ -336,7 +336,7 @@ libc_hidden_weak(send) extern __typeof(sendmsg) __libc_sendmsg; #ifdef __NR_sendmsg #define __NR___libc_sendmsg __NR_sendmsg -_syscall3(ssize_t, __libc_sendmsg, int, sockfd, const struct msghdr *, msg, int, flags); +_syscall3(ssize_t, __libc_sendmsg, int, sockfd, const struct msghdr *, msg, int, flags) #elif defined(__NR_socketcall) ssize_t __libc_sendmsg(int sockfd, const struct msghdr *msg, int flags) { @@ -367,7 +367,7 @@ extern __typeof(sendto) __libc_sendto; #ifdef __NR_sendto #define __NR___libc_sendto __NR_sendto _syscall6(ssize_t, __libc_sendto, int, sockfd, const void *, buffer, - size_t, len, int, flags, const struct sockaddr *, to, socklen_t, tolen); + size_t, len, int, flags, const struct sockaddr *, to, socklen_t, tolen) #elif defined(__NR_socketcall) /* send, sendto added by bir7@leland.stanford.edu */ ssize_t __libc_sendto(int sockfd, const void *buffer, size_t len, int flags, @@ -401,7 +401,7 @@ libc_hidden_weak(sendto) #ifdef L_setsockopt libc_hidden_proto(setsockopt) #ifdef __NR_setsockopt -_syscall5(int, setsockopt, int, fd, int, level, int, optname, const void *, optval, socklen_t, optlen); +_syscall5(int, setsockopt, int, fd, int, level, int, optname, const void *, optval, socklen_t, optlen) #elif defined(__NR_socketcall) /* [sg]etsockoptions by bir7@leland.stanford.edu */ int setsockopt(int fd, int level, int optname, const void *optval, @@ -422,7 +422,7 @@ libc_hidden_def(setsockopt) #ifdef L_shutdown #ifdef __NR_shutdown -_syscall2(int, shutdown, int, sockfd, int, how); +_syscall2(int, shutdown, int, sockfd, int, how) #elif defined(__NR_socketcall) /* shutdown by bir7@leland.stanford.edu */ int shutdown(int sockfd, int how) @@ -439,7 +439,7 @@ int shutdown(int sockfd, int how) #ifdef L_socket libc_hidden_proto(socket) #ifdef __NR_socket -_syscall3(int, socket, int, family, int, type, int, protocol); +_syscall3(int, socket, int, family, int, type, int, protocol) #elif defined(__NR_socketcall) int socket(int family, int type, int protocol) { @@ -456,7 +456,7 @@ libc_hidden_def(socket) #ifdef L_socketpair #ifdef __NR_socketpair -_syscall4(int, socketpair, int, family, int, type, int, protocol, int *, sockvec); +_syscall4(int, socketpair, int, family, int, type, int, protocol, int *, sockvec) #elif defined(__NR_socketcall) int socketpair(int family, int type, int protocol, int sockvec[2]) { diff --git a/libc/pwd_grp/__getgrouplist_internal.c b/libc/pwd_grp/__getgrouplist_internal.c new file mode 100644 index 000000000..c2edc99cf --- /dev/null +++ b/libc/pwd_grp/__getgrouplist_internal.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L___getgrouplist_internal +#include "pwd_grp.c" diff --git a/libc/inet/resolveaddress.c b/libc/pwd_grp/getgrouplist.c index d57366c98..a4eba7dbb 100644 --- a/libc/inet/resolveaddress.c +++ b/libc/pwd_grp/getgrouplist.c @@ -4,5 +4,5 @@ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -#define L_resolveaddress -#include "resolv.c" +#define L_getgrouplist +#include "pwd_grp.c" diff --git a/libc/pwd_grp/pwd_grp.c b/libc/pwd_grp/pwd_grp.c index 217ed39a7..5af1f0c15 100644 --- a/libc/pwd_grp/pwd_grp.c +++ b/libc/pwd_grp/pwd_grp.c @@ -64,6 +64,8 @@ extern int __parsespent(void *sp, char *line) attribute_hidden; extern int __pgsreader(int (*__parserfunc)(void *d, char *line), void *data, char *__restrict line_buff, size_t buflen, FILE *f) attribute_hidden; +extern gid_t* __getgrouplist_internal(const char *user, gid_t gid, int *ngroups) attribute_hidden; + /**********************************************************************/ /* For the various fget??ent_r funcs, return * @@ -684,62 +686,105 @@ struct spwd *sgetspent(const char *string) #endif /**********************************************************************/ -#ifdef L_initgroups +#ifdef L___getgrouplist_internal -#ifdef __USE_BSD - -libc_hidden_proto(setgroups) - -int initgroups(const char *user, gid_t gid) +gid_t attribute_hidden *__getgrouplist_internal(const char *user, gid_t gid, int *ngroups) { FILE *grfile; gid_t *group_list; - int num_groups, rv; - char **m; + int num_groups; struct group group; char buff[__UCLIBC_PWD_BUFFER_SIZE__]; - rv = -1; + *ngroups = num_groups = 1; /* We alloc space for 8 gids at a time. */ - if (((group_list = (gid_t *) malloc(8*sizeof(gid_t *))) != NULL) - && ((grfile = fopen(_PATH_GROUP, "r")) != NULL) - ) { - - __STDIO_SET_USER_LOCKING(grfile); - - *group_list = gid; - num_groups = 1; - - while (!__pgsreader(__parsegrent, &group, buff, sizeof(buff), grfile)) { - assert(group.gr_mem); /* Must have at least a NULL terminator. */ - if (group.gr_gid != gid) { - for (m=group.gr_mem ; *m ; m++) { - if (!strcmp(*m, user)) { - if (!(num_groups & 7)) { - gid_t *tmp = (gid_t *) - realloc(group_list, - (num_groups+8) * sizeof(gid_t *)); - if (!tmp) { - rv = -1; - goto DO_CLOSE; - } - group_list = tmp; - } - group_list[num_groups++] = group.gr_gid; - break; - } - } + group_list = malloc(8 * sizeof(group_list[0])); + if (!group_list) + return NULL; + + group_list[0] = gid; + grfile = fopen(_PATH_GROUP, "r"); + /* If /etc/group doesn't exist, we still return 1-element vector */ + if (!grfile) + return group_list; + + __STDIO_SET_USER_LOCKING(grfile); + + while (!__pgsreader(__parsegrent, &group, buff, sizeof(buff), grfile)) { + char **m; + + assert(group.gr_mem); /* Must have at least a NULL terminator. */ + if (group.gr_gid == gid) + continue; + for (m = group.gr_mem; *m; m++) { + if (strcmp(*m, user) != 0) + continue; + if (!(num_groups & 7)) { + gid_t *tmp = realloc(group_list, (num_groups+8) * sizeof(group_list[0])); + if (!tmp) + goto DO_CLOSE; + group_list = tmp; } + group_list[num_groups++] = group.gr_gid; + break; } + } + + DO_CLOSE: + fclose(grfile); + *ngroups = num_groups; + return group_list; +} + +#endif +/**********************************************************************/ +#ifdef L_getgrouplist - rv = setgroups(num_groups, group_list); - DO_CLOSE: - fclose(grfile); +#if defined __USE_BSD || defined __USE_GNU +int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups) +{ + int sz = *ngroups; + gid_t *group_list = __getgrouplist_internal(user, gid, ngroups); + + if (!group_list) { + /* malloc failure - what shall we do? + * fail with ENOMEM? I bet users never check for that */ + /* *ngroups = 1; - already done by __getgrouplist_internal */ + if (sz) { + groups[0] = gid; + return 1; + } + return -1; } + /* *ngroups is non-zero here */ + + if (sz > *ngroups) + sz = *ngroups; + if (sz) + memcpy(groups, group_list, sz * sizeof(group_list[0])); + free(group_list); + if (sz < *ngroups) + return -1; + return sz; +} +#endif + +#endif +/**********************************************************************/ +#ifdef L_initgroups - /* group_list will be NULL if initial malloc failed, which may trigger - * warnings from various malloc debuggers. */ +#ifdef __USE_BSD +libc_hidden_proto(setgroups) + +int initgroups(const char *user, gid_t gid) +{ + int rv; + int num_groups = ((unsigned)~0) >> 1; /* INT_MAX */ + gid_t *group_list = __getgrouplist_internal(user, gid, &num_groups); + if (!group_list) + return -1; + rv = setgroups(num_groups, group_list); free(group_list); return rv; } diff --git a/libc/stdio/open_memstream.c b/libc/stdio/open_memstream.c index e7b1cf435..5861017e4 100644 --- a/libc/stdio/open_memstream.c +++ b/libc/stdio/open_memstream.c @@ -97,7 +97,7 @@ static int oms_seek(register void *cookie, __offmax_t *pos, int whence) if (buf) { *COOKIE->bufloc = COOKIE->buf = buf; COOKIE->len = leastlen; - memset(buf + COOKIE->eof, leastlen - COOKIE->eof, 0); /* 0-fill */ + memset(buf + COOKIE->eof, 0, leastlen - COOKIE->eof); /* 0-fill */ } else { /* TODO: check glibc errno setting... */ return -1; @@ -107,7 +107,7 @@ static int oms_seek(register void *cookie, __offmax_t *pos, int whence) *pos = COOKIE->pos = --leastlen; if (leastlen > COOKIE->eof) { - memset(COOKIE->buf + COOKIE->eof, leastlen - COOKIE->eof, 0); + memset(COOKIE->buf + COOKIE->eof, 0, leastlen - COOKIE->eof); *COOKIE->sizeloc = COOKIE->eof; } diff --git a/libc/stdio/vsnprintf.c b/libc/stdio/vsnprintf.c index 8bc697a48..5cdb6ebf8 100644 --- a/libc/stdio/vsnprintf.c +++ b/libc/stdio/vsnprintf.c @@ -46,7 +46,7 @@ int vsnprintf(char *__restrict buf, size_t size, __INIT_MBSTATE(&(f.__state)); #endif /* __STDIO_MBSTATE */ -#if defined(__USE_OLD_VFPRINTF__) && defined(__UCLIBC_HAS_THREADS__) +#if (defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__)) && defined(__UCLIBC_HAS_THREADS__) f.__user_locking = 1; /* Set user locking. */ STDIO_INIT_MUTEX(f.__lock); #endif |