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;
-}
-