Module Name: src Committed By: christos Date: Tue Aug 27 09:53:33 UTC 2013
Modified Files: src/distrib/utils/libhack: Makefile Makefile.inc gethost.c Log Message: avoid copying most of libc (except gethostent_r, which unfortunately adds a resolver dependency) by callling the internal nsswitch functions. To generate a diff of this commit: cvs rdiff -u -r1.23 -r1.24 src/distrib/utils/libhack/Makefile cvs rdiff -u -r1.24 -r1.25 src/distrib/utils/libhack/Makefile.inc cvs rdiff -u -r1.10 -r1.11 src/distrib/utils/libhack/gethost.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/utils/libhack/Makefile diff -u src/distrib/utils/libhack/Makefile:1.23 src/distrib/utils/libhack/Makefile:1.24 --- src/distrib/utils/libhack/Makefile:1.23 Thu Oct 11 13:11:16 2012 +++ src/distrib/utils/libhack/Makefile Tue Aug 27 05:53:33 2013 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.23 2012/10/11 17:11:16 christos Exp $ +# $NetBSD: Makefile,v 1.24 2013/08/27 09:53:33 christos Exp $ # # Stubs to kill off some things from libc: # This save space on a boot system. @@ -13,11 +13,12 @@ CPPFLAGS+= -DSMALL CPPFLAGS.runetable.c+= -I${HACKSRC}/../../../lib/libc/citrus \ -DALL_80_TO_FF_SW1 CPPFLAGS.syslog.c+= -I${HACKSRC}/../../../lib/libc/include +CPPFLAGS.gethost.c+= -I${HACKSRC}/../../../lib/libc/net LIB= hack SRCS= getcap.c getgrent.c getnet.c getnetgr.c getpwent.c \ localeconv.c multibyte.c perror.c runetable.c setlocale.c \ - strerror.c strsignal.c syslog.c utmp.c yplib.c + strerror.c strsignal.c syslog.c utmp.c yplib.c gethost.c WARNS= 1 NOLINKLIB= # defined Index: src/distrib/utils/libhack/Makefile.inc diff -u src/distrib/utils/libhack/Makefile.inc:1.24 src/distrib/utils/libhack/Makefile.inc:1.25 --- src/distrib/utils/libhack/Makefile.inc:1.24 Thu Oct 11 13:11:16 2012 +++ src/distrib/utils/libhack/Makefile.inc Tue Aug 27 05:53:33 2013 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.inc,v 1.24 2012/10/11 17:11:16 christos Exp $ +# $NetBSD: Makefile.inc,v 1.25 2013/08/27 09:53:33 christos Exp $ # # Include this fragment to build libhack.o # It is .o and not .a to make sure these are the @@ -25,6 +25,7 @@ CPPFLAGS.runetable.c+= -I${HACKSRC}/../. -DALL_80_TO_FF_SW1 CPPFLAGS.syslog.c+= -I${HACKSRC}/../../../lib/libc/include +CPPFLAGS.gethost.c+= -I${HACKSRC}/../../../lib/libc/net libhack.o: ${HACKOBJS} ${LD} -r -o $@ ${HACKOBJS} Index: src/distrib/utils/libhack/gethost.c diff -u src/distrib/utils/libhack/gethost.c:1.10 src/distrib/utils/libhack/gethost.c:1.11 --- src/distrib/utils/libhack/gethost.c:1.10 Sun Aug 25 04:46:34 2013 +++ src/distrib/utils/libhack/gethost.c Tue Aug 27 05:53:33 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: gethost.c,v 1.10 2013/08/25 08:46:34 christos Exp $ */ +/* $NetBSD: gethost.c,v 1.11 2013/08/27 09:53:33 christos Exp $ */ /*- * Copyright (c) 1985, 1988, 1993 @@ -49,10 +49,7 @@ * --Copyright-- */ -/* - * Copied from: lib/libc/net/gethostnamadr.c - * and then gutted, leaving only /etc/hosts support. - */ +/* Provide just /etc/hosts lookup support */ #include <sys/cdefs.h> @@ -61,217 +58,175 @@ #define gethostbyname _gethostbyname #endif -#include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> #include <netdb.h> -#include <resolv.h> -#include <stdio.h> -#include <ctype.h> -#include <errno.h> #include <string.h> +#include <nsswitch.h> +#include <errno.h> +#include <arpa/nameser.h> +#include <arpa/inet.h> +#include <sys/socket.h> + +#include "hostent.h" #ifdef __weak_alias __weak_alias(gethostbyaddr,_gethostbyaddr); __weak_alias(gethostbyname,_gethostbyname); #endif -#define MAXALIASES 35 -#define MAXADDRS 35 - -static char *h_addr_ptrs[MAXADDRS + 1]; - -static struct hostent host; -static char *host_aliases[MAXALIASES]; -static char hostbuf[BUFSIZ+1]; -static struct in_addr host_addr; - -FILE *_h_file = NULL; -void sethostent_r(FILE **); -void endhostent_r(FILE **); - -struct hostent *_gethtent(void); -struct hostent *_gethtbyname(const char *); -struct hostent *_gethtbyaddr(const void *, socklen_t, int); - - -#if PACKETSZ > 1024 -#define MAXPACKET PACKETSZ -#else -#define MAXPACKET 1024 -#endif - extern int h_errno; +FILE *_h_file; +static struct hostent h_ent; +static char h_buf[4096]; + +static struct hostent * +getby(int (*f)(void *, void *, va_list), struct getnamaddr *info, ...) +{ + va_list ap; + int e; + + va_start(ap, info); + e = (*f)(info, NULL, ap); + va_end(ap); + switch (e) { + case NS_SUCCESS: + return info->hp; + default: + return NULL; + } +} struct hostent * -gethostbyname(const char *name) +gethostbyname_r(const char *name, struct hostent *hp, char *buf, size_t bufsiz, + int *he) { - const char *cp; - - /* - * disallow names consisting only of digits/dots, unless - * they end in a dot. - */ - if (isdigit((unsigned char)name[0])) - for (cp = name;; ++cp) { - if (!*cp) { - if (*--cp == '.') - break; - /* - * All-numeric, no dot at the end. - * Fake up a hostent as if we'd actually - * done a lookup. - */ - if (!inet_aton(name, &host_addr)) { - h_errno = HOST_NOT_FOUND; - return((struct hostent *) NULL); - } - host.h_name = (char *)name; - host.h_aliases = host_aliases; - host_aliases[0] = NULL; - host.h_addrtype = AF_INET; - host.h_length = sizeof(u_int32_t); - h_addr_ptrs[0] = (char *)&host_addr; - h_addr_ptrs[1] = NULL; - host.h_addr_list = h_addr_ptrs; - return &host; - } - if (!isdigit((unsigned char)*cp) && *cp != '.') - break; - } - - /* XXX - Force host table lookup. */ - return _gethtbyname(name); + struct getnamaddr info; + info.hp = hp; + info.buf = buf; + info.buflen = bufsiz; + info.he = he; + return getby(_hf_gethtbyname, &info, name, 0, AF_INET); } + struct hostent * -gethostbyaddr(const void *addr, socklen_t len, int type) +gethostbyname(const char *name) { -#if 0 - char qbuf[MAXDNAME]; -#endif - - if (type != AF_INET) - return NULL; -#if 0 - (void)snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u.in-addr.arpa", - ((unsigned)addr[3] & 0xff), ((unsigned)addr[2] & 0xff), - ((unsigned)addr[1] & 0xff), ((unsigned)addr[0] & 0xff)); -#endif - - /* XXX - Force host table lookup. */ - return _gethtbyaddr(addr, len, type); + return gethostbyname_r(name, &h_ent, h_buf, sizeof(h_buf), &h_errno); } -void -sethostent_r(FILE **hf) +struct hostent * +gethostbyaddr_r(const void *addr, socklen_t len, int type, struct hostent *hp, + char *buf, size_t bufsiz, int *he) { - if (*hf == NULL) - *hf = fopen(_PATH_HOSTS, "r"); - else - rewind(*hf); + struct getnamaddr info; + info.hp = hp; + info.buf = buf; + info.buflen = bufsiz; + info.he = he; + return getby(_hf_gethtbyaddr, &info, addr, len, type); } -void -endhostent_r(FILE **hf) +struct hostent * +gethostbyaddr(const void *addr, socklen_t len, int type) { - if (*hf) { - (void)fclose(*hf); - *hf = NULL; - } + return gethostbyaddr_r(addr, len, type, &h_ent, h_buf, sizeof(h_buf), + &h_errno); } struct hostent * -_gethtent(void) +gethostent_r(FILE *hf, struct hostent *hent, char *buf, size_t buflen, int *he) { - char *p; + char *p, *name; char *cp, **q; - - if (_h_file == NULL && (_h_file = fopen(_PATH_HOSTS, "r" )) == NULL) + int af, len; + size_t llen, anum; + char *aliases[MAXALIASES]; + struct in6_addr host_addr; + + if (hf == NULL) { + *he = NETDB_INTERNAL; + errno = EINVAL; return NULL; -again: - if ((p = fgets(hostbuf, BUFSIZ, _h_file)) == NULL) + } + again: + if ((p = fgetln(hf, &llen)) == NULL) { + *he = HOST_NOT_FOUND; return NULL; + } + if (llen < 1) + goto again; if (*p == '#') goto again; - cp = strpbrk(p, "#\n"); - if (cp == NULL) + p[llen] = '\0'; + if (!(cp = strpbrk(p, "#\n"))) goto again; *cp = '\0'; - cp = strpbrk(p, " \t"); - if (cp == NULL) + if (!(cp = strpbrk(p, " \t"))) goto again; *cp++ = '\0'; - /* THIS STUFF IS INTERNET SPECIFIC */ - h_addr_ptrs[0] = (char *)&host_addr; - h_addr_ptrs[1] = NULL; - (void) inet_aton(p, &host_addr); - host.h_addr_list = h_addr_ptrs; - host.h_length = sizeof(u_int32_t); - host.h_addrtype = AF_INET; + if (inet_pton(AF_INET6, p, &host_addr) > 0) { + af = AF_INET6; + len = NS_IN6ADDRSZ; + } else if (inet_pton(AF_INET, p, &host_addr) > 0) { +#if 0 + res_state res = __res_get_state(); + if (res == NULL) + return NULL; + if (res->options & RES_USE_INET6) { + map_v4v6_address(buf, buf); + af = AF_INET6; + len = NS_IN6ADDRSZ; + } else { +#endif + af = AF_INET; + len = NS_INADDRSZ; +#if 0 + } + __res_put_state(res); +#endif + } else { + goto again; + } + /* if this is not something we're looking for, skip it. */ + if (hent->h_addrtype != 0 && hent->h_addrtype != af) + goto again; + if (hent->h_length != 0 && hent->h_length != len) + goto again; + while (*cp == ' ' || *cp == '\t') cp++; - host.h_name = cp; - q = host.h_aliases = host_aliases; - cp = strpbrk(cp, " \t"); - if (cp != NULL) + if ((cp = strpbrk(name = cp, " \t")) != NULL) *cp++ = '\0'; + q = aliases; while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { cp++; continue; } - if (q < &host_aliases[MAXALIASES - 1]) - *q++ = cp; - cp = strpbrk(cp, " \t"); - if (cp != NULL) + if (q >= &aliases[__arraycount(aliases)]) + goto nospc; + *q++ = cp; + if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0'; } - *q = NULL; - return &host; + hent->h_length = len; + hent->h_addrtype = af; + HENT_ARRAY(hent->h_addr_list, 1, buf, buflen); + anum = (size_t)(q - aliases); + HENT_ARRAY(hent->h_aliases, anum, buf, buflen); + HENT_COPY(hent->h_addr_list[0], &host_addr, hent->h_length, buf, + buflen); + hent->h_addr_list[1] = NULL; + + HENT_SCOPY(hent->h_name, name, buf, buflen); + for (size_t i = 0; i < anum; i++) + HENT_SCOPY(hent->h_aliases[i], aliases[i], buf, buflen); + hent->h_aliases[anum] = NULL; + + *he = NETDB_SUCCESS; + return hent; +nospc: + errno = ENOSPC; + *he = NETDB_INTERNAL; + return NULL; } - -struct hostent * -_gethtbyname(const char *name) -{ - struct hostent *p; - char **cp; - FILE *hf = NULL; - - sethostent_r(&hf); - if (hf == NULL) - return NULL; - while ((p = _gethtent()) != NULL) { - if (strcasecmp(p->h_name, name) == 0) - break; - for (cp = p->h_aliases; *cp != 0; cp++) - if (strcasecmp(*cp, name) == 0) - goto found; - } -found: - endhostent_r(&hf); - if (p == NULL) - h_errno = HOST_NOT_FOUND; - return p; -} - -struct hostent * -_gethtbyaddr(const void *addr, socklen_t len, int type) -{ - struct hostent *p; - FILE *hf = NULL; - - sethostent_r(&hf); - if (hf == NULL) - return NULL; - while ((p = _gethtent()) != NULL) - if (p->h_addrtype == type && !memcmp(p->h_addr, addr, len)) - break; - endhostent_r(&hf); - if (p == NULL) - h_errno = HOST_NOT_FOUND; - return p; -} -