[comp.sys.masscomp] resolver library for MASSCOMP

sob@cortex.neuro.bcm.tmc.edu (Stan Barber) (07/12/88)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	res/res_init.c
#	res/res_mkquery.c
#	res/res_query.c
#	res/res_send.c
# This archive created: Mon Jul  4 20:32:45 1988
export PATH; PATH=/bin:/usr/bin:$PATH
if test ! -d 'res'
then
	echo shar: "creating directory 'res'"
	mkdir 'res'
fi
echo shar: "entering directory 'res'"
cd 'res'
echo shar: "extracting 'res_init.c'" '(4721 characters)'
if test -f 'res_init.c'
then
	echo shar: "will not over-write existing file 'res_init.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'res_init.c'
	X/*
	X * Copyright (c) 1985 Regents of the University of California.
	X * All rights reserved.
	X *
	X * Redistribution and use in source and binary forms are permitted
	X * provided that this notice is preserved and that due credit is given
	X * to the University of California at Berkeley. The name of the University
	X * may not be used to endorse or promote products derived from this
	X * software without specific prior written permission. This software
	X * is provided ``as is'' without express or implied warranty.
	X */
	X
	X#if defined(LIBC_SCCS) && !defined(lint)
	Xstatic char sccsid[] = "@(#)res_init.c	6.8 (Berkeley) 3/7/88";
	X#endif /* LIBC_SCCS and not lint */
	X
	X#include <sys/types.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#endif
	X#include <sys/socket.h>
	X#include <netinet/in.h>
	X#include <stdio.h>
	X#include <arpa/nameser.h>
	X#include <resolv.h>
	X
	X/*
	X * Resolver configuration file. Contains the address of the
	X * inital name server to query and the default domain for
	X * non fully qualified domain names.
	X */
	X
	X#ifndef	CONFFILE
	X#define	CONFFILE	"/etc/resolv.conf"
	X#endif
	X
	X/*
	X * Resolver state default settings
	X */
	X
	Xstruct state _res = {
	X    RES_TIMEOUT,               	/* retransmition time interval */
	X    4,                         	/* number of times to retransmit */
	X    RES_DEFAULT,		/* options flags */
	X    1,                         	/* number of name servers */
	X};
	X
	X/*
	X * Set up default settings.  If the configuration file exist, the values
	X * there will have precedence.  Otherwise, the server address is set to
	X * INADDR_ANY and the default domain name comes from the gethostname().
	X *
	X * The configuration file should only be used if you want to redefine your
	X * domain or run without a server on your machine.
	X *
	X * Return 0 if completes successfully, -1 on error
	X */
	Xres_init()
	X{
	X    register FILE *fp;
	X    register char *cp, **pp;
	X    char buf[BUFSIZ];
	X    extern u_long inet_addr();
	X    extern char *index();
	X    extern char *strcpy(), *strncpy();
	X    extern char *getenv();
	X    int n = 0;    /* number of nameserver records read from file */
	X
	X    _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
	X    _res.nsaddr.sin_family = AF_INET;
	X    _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
	X    _res.nscount = 1;
	X    _res.defdname[0] = '\0';
	X
	X    if ((fp = fopen(CONFFILE, "r")) != NULL) {
	X        /* read the config file */
	X        while (fgets(buf, sizeof(buf), fp) != NULL) {
	X            /* read default domain name */
	X            if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
	X                cp = buf + sizeof("domain") - 1;
	X                while (*cp == ' ' || *cp == '\t')
	X                    cp++;
	X                if (*cp == '\0')
	X                    continue;
	X                (void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
	X                _res.defdname[sizeof(_res.defdname) - 1] = '\0';
	X                if ((cp = index(_res.defdname, '\n')) != NULL)
	X                    *cp = '\0';
	X                continue;
	X            }
	X            /* read nameservers to query */
	X            if (!strncmp(buf, "nameserver", 
	X               sizeof("nameserver") - 1) && (n < MAXNS)) {
	X                cp = buf + sizeof("nameserver") - 1;
	X                while (*cp == ' ' || *cp == '\t')
	X                    cp++;
	X                if (*cp == '\0')
	X                    continue;
	X                _res.nsaddr_list[n].sin_addr.s_addr = inet_addr(cp);
	X                if (_res.nsaddr_list[n].sin_addr.s_addr == (unsigned)-1) 
	X                    _res.nsaddr_list[n].sin_addr.s_addr = INADDR_ANY;
	X                _res.nsaddr_list[n].sin_family = AF_INET;
	X                _res.nsaddr_list[n].sin_port = htons(NAMESERVER_PORT);
	X                if ( ++n >= MAXNS) { 
	X                    n = MAXNS;
	X#ifdef DEBUG
	X                    if ( _res.options & RES_DEBUG )
	X                        printf("MAXNS reached, reading resolv.conf\n");
	X#endif DEBUG
	X                }
	X                continue;
	X            }
	X        }
	X        if ( n > 1 ) 
	X            _res.nscount = n;
	X        (void) fclose(fp);
	X    }
	X    if (_res.defdname[0] == 0) {
	X        if (gethostname(buf, sizeof(_res.defdname)) == 0 &&
	X           (cp = index(buf, '.')))
	X             (void)strcpy(_res.defdname, cp + 1);
	X    }
	X
	X    /* Allow user to override the local domain definition */
	X    if ((cp = getenv("LOCALDOMAIN")) != NULL)
	X        (void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
	X
	X    /* find components of local domain that might be searched */
	X    pp = _res.dnsrch;
	X    *pp++ = _res.defdname;
	X    for (cp = _res.defdname, n = 0; *cp; cp++)
	X	if (*cp == '.')
	X	    n++;
	X    cp = _res.defdname;
	X    for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDNSRCH; n--) {
	X	cp = index(cp, '.');
	X	*pp++ = ++cp;
	X    }
	X    _res.options |= RES_INIT;
	X    return(0);
	X}
SHAR_EOF
if test 4721 -ne "`wc -c < 'res_init.c'`"
then
	echo shar: "error transmitting 'res_init.c'" '(should have been 4721 characters)'
fi
fi
echo shar: "extracting 'res_mkquery.c'" '(5477 characters)'
if test -f 'res_mkquery.c'
then
	echo shar: "will not over-write existing file 'res_mkquery.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'res_mkquery.c'
	X/*
	X * Copyright (c) 1985 Regents of the University of California.
	X * All rights reserved.
	X *
	X * Redistribution and use in source and binary forms are permitted
	X * provided that this notice is preserved and that due credit is given
	X * to the University of California at Berkeley. The name of the University
	X * may not be used to endorse or promote products derived from this
	X * software without specific prior written permission. This software
	X * is provided ``as is'' without express or implied warranty.
	X */
	X
	X#if defined(LIBC_SCCS) && !defined(lint)
	Xstatic char sccsid[] = "@(#)res_mkquery.c	6.7 (Berkeley) 3/7/88";
	X#endif /* LIBC_SCCS and not lint */
	X
	X#include <stdio.h>
	X#include <sys/types.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#endif
	X#include <netinet/in.h>
	X#include <arpa/nameser.h>
	X#include <resolv.h>
	X
	X/*
	X * Form all types of queries.
	X * Returns the size of the result or -1.
	X */
	Xres_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen)
	X	int op;			/* opcode of query */
	X	char *dname;		/* domain name */
	X	int class, type;	/* class and type of query */
	X	char *data;		/* resource record data */
	X	int datalen;		/* length of data */
	X	struct rrec *newrr;	/* new rr for modify or append */
	X	char *buf;		/* buffer to put query */
	X	int buflen;		/* size of buffer */
	X{
	X	register HEADER *hp;
	X	register char *cp;
	X	register int n;
	X	char dnbuf[MAXDNAME];
	X	char *dnptrs[10], **dpp, **lastdnptr;
	X	extern char *index();
	X
	X#ifdef DEBUG
	X	if (_res.options & RES_DEBUG)
	X		printf("res_mkquery(%d, %s, %d, %d)\n", op, dname, class, type);
	X#endif DEBUG
	X	/*
	X	 * Initialize header fields.
	X	 */
	X	hp = (HEADER *) buf;
	X	hp->id = htons(++_res.id);
	X	hp->opcode = op;
	X	hp->qr = hp->aa = hp->tc = hp->ra = 0;
	X	hp->pr = (_res.options & RES_PRIMARY) != 0;
	X	hp->rd = (_res.options & RES_RECURSE) != 0;
	X	hp->rcode = NOERROR;
	X	hp->qdcount = 0;
	X	hp->ancount = 0;
	X	hp->nscount = 0;
	X	hp->arcount = 0;
	X	cp = buf + sizeof(HEADER);
	X	buflen -= sizeof(HEADER);
	X	dpp = dnptrs;
	X	*dpp++ = buf;
	X	*dpp++ = NULL;
	X	lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
	X	/*
	X	 * If the domain name contains no dots (single label), then
	X	 * append the default domain name to the one given.
	X	 */
	X	if ((_res.options & RES_DEFNAMES) && dname != 0 && dname[0] != '\0' &&
	X	    index(dname, '.') == NULL) {
	X		if (!(_res.options & RES_INIT))
	X			if (res_init() == -1)
	X				return(-1);
	X		if (_res.defdname[0] != '\0') {
	X			(void)sprintf(dnbuf, "%s.%s", dname, _res.defdname);
	X			dname = dnbuf;
	X		}
	X	}
	X	/*
	X	 * perform opcode specific processing
	X	 */
	X	switch (op) {
	X	case QUERY:
	X		buflen -= QFIXEDSZ;
	X		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
	X			return (-1);
	X		cp += n;
	X		buflen -= n;
	X		putshort(type, cp);
	X		cp += sizeof(u_short);
	X		putshort(class, cp);
	X		cp += sizeof(u_short);
	X		hp->qdcount = htons(1);
	X		if (op == QUERY || data == NULL)
	X			break;
	X		/*
	X		 * Make an additional record for completion domain.
	X		 */
	X		buflen -= RRFIXEDSZ;
	X		if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0)
	X			return (-1);
	X		cp += n;
	X		buflen -= n;
	X		putshort(T_NULL, cp);
	X		cp += sizeof(u_short);
	X		putshort(class, cp);
	X		cp += sizeof(u_short);
	X		putlong(0, cp);
	X		cp += sizeof(u_long);
	X		putshort(0, cp);
	X		cp += sizeof(u_short);
	X		hp->arcount = htons(1);
	X		break;
	X
	X	case IQUERY:
	X		/*
	X		 * Initialize answer section
	X		 */
	X		if (buflen < 1 + RRFIXEDSZ + datalen)
	X			return (-1);
	X		*cp++ = '\0';	/* no domain name */
	X		putshort(type, cp);
	X		cp += sizeof(u_short);
	X		putshort(class, cp);
	X		cp += sizeof(u_short);
	X		putlong(0, cp);
	X		cp += sizeof(u_long);
	X		putshort(datalen, cp);
	X		cp += sizeof(u_short);
	X		if (datalen) {
	X#ifdef SYS5
	X			(void)memcpy(cp, data, datalen);
	X#else
	X			bcopy(data, cp, datalen);
	X#endif
	X			cp += datalen;
	X		}
	X		hp->ancount = htons(1);
	X		break;
	X
	X#ifdef ALLOW_UPDATES
	X	/*
	X	 * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
	X	 * (Record to be modified is followed by its replacement in msg.)
	X	 */
	X	case UPDATEM:
	X	case UPDATEMA:
	X
	X	case UPDATED:
	X		/*
	X		 * The res code for UPDATED and UPDATEDA is the same; user
	X		 * calls them differently: specifies data for UPDATED; server
	X		 * ignores data if specified for UPDATEDA.
	X		 */
	X	case UPDATEDA:
	X		buflen -= RRFIXEDSZ + datalen;
	X		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
	X			return (-1);
	X		cp += n;
	X		putshort(type, cp);
	X                cp += sizeof(u_short);
	X                putshort(class, cp);
	X                cp += sizeof(u_short);
	X		putlong(0, cp);
	X		cp += sizeof(u_long);
	X		putshort(datalen, cp);
	X                cp += sizeof(u_short);
	X		if (datalen) {
	X#ifdef SYS5
	X			(void)memcpy(cp, data, datalen);
	X#else
	X			bcopy(data, cp, datalen);
	X#endif
	X			cp += datalen;
	X		}
	X		if ( (op == UPDATED) || (op == UPDATEDA) ) {
	X			hp->ancount = htons(0);
	X			break;
	X		}
	X		/* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
	X
	X	case UPDATEA:	/* Add new resource record */
	X		buflen -= RRFIXEDSZ + datalen;
	X		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
	X			return (-1);
	X		cp += n;
	X		putshort(newrr->r_type, cp);
	X                cp += sizeof(u_short);
	X                putshort(newrr->r_class, cp);
	X                cp += sizeof(u_short);
	X		putlong(0, cp);
	X		cp += sizeof(u_long);
	X		putshort(newrr->r_size, cp);
	X                cp += sizeof(u_short);
	X		if (newrr->r_size) {
	X#ifdef SYS5
	X			(void)memcpy(cp, newrr->r_data, newrr->r_size);
	X#else
	X			bcopy(newrr->r_data, cp, newrr->r_size);
	X#endif
	X			cp += newrr->r_size;
	X		}
	X		hp->ancount = htons(0);
	X		break;
	X
	X#endif ALLOW_UPDATES
	X	}
	X	return (cp - buf);
	X}
SHAR_EOF
if test 5477 -ne "`wc -c < 'res_mkquery.c'`"
then
	echo shar: "error transmitting 'res_mkquery.c'" '(should have been 5477 characters)'
fi
fi
echo shar: "extracting 'res_query.c'" '(6927 characters)'
if test -f 'res_query.c'
then
	echo shar: "will not over-write existing file 'res_query.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'res_query.c'
	X/*
	X * Copyright (c) 1988 Regents of the University of California.
	X * All rights reserved.
	X *
	X * Redistribution and use in source and binary forms are permitted
	X * provided that this notice is preserved and that due credit is given
	X * to the University of California at Berkeley. The name of the University
	X * may not be used to endorse or promote products derived from this
	X * software without specific prior written permission. This software
	X * is provided ``as is'' without express or implied warranty.
	X */
	X
	X#if defined(LIBC_SCCS) && !defined(lint)
	Xstatic char sccsid[] = "@(#)res_query.c	5.4 (Berkeley) 4/21/88";
	X#endif /* LIBC_SCCS and not lint */
	X
	X#include <sys/param.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#endif
	X#include <sys/socket.h>
	X#include <netinet/in.h>
	X#include <ctype.h>
	X#include <netdb.h>
	X#include <stdio.h>
	X#include <errno.h>
	X#ifdef SYS5
	X#include <string.h>
	X#else
	X#include <strings.h>
	X#endif
	X#ifndef EXOS
	X#include <arpa/inet.h>
	X#endif
	X#include <arpa/nameser.h>
	X#include <resolv.h>
	X
	X#if PACKETSZ > 1024
	X#define MAXPACKET	PACKETSZ
	X#else
	X#define MAXPACKET	1024
	X#endif
	X
	Xextern int errno;
	Xint h_errno;
	X
	X/*
	X * Formulate a normal query, send, and await answer.
	X * Returned answer is placed in supplied buffer "answer".
	X * Perform preliminary check of answer, returning success only
	X * if no error is indicated and the answer count is nonzero.
	X * Return the size of the response on success, -1 on error.
	X * Error number is left in h_errno.
	X * Caller must parse answer and determine whether it answers the question.
	X */
	Xres_query(name, class, type, answer, anslen)
	X	char *name;		/* domain name */
	X	int class, type;	/* class and type of query */
	X	u_char *answer;		/* buffer to put answer */
	X	int anslen;		/* size of answer buffer */
	X{
	X	char buf[MAXPACKET];
	X	HEADER *hp;
	X	int n;
	X
	X	if ((_res.options & RES_INIT) == 0 && res_init() == -1)
	X		return (-1);
	X#ifdef DEBUG
	X	if (_res.options & RES_DEBUG)
	X		printf("res_query(%s, %d, %d)\n", name, class, type);
	X#endif
	X	n = res_mkquery(QUERY, name, class, type, (char *)NULL, 0, NULL,
	X	    buf, sizeof(buf));
	X
	X	if (n <= 0) {
	X#ifdef DEBUG
	X		if (_res.options & RES_DEBUG)
	X			printf("res_query: mkquery failed\n");
	X#endif
	X		h_errno = NO_RECOVERY;
	X		return (n);
	X	}
	X	n = res_send(buf, n, answer, anslen);
	X	if (n < 0) {
	X#ifdef DEBUG
	X		if (_res.options & RES_DEBUG)
	X			printf("res_query: send error\n");
	X#endif
	X		h_errno = TRY_AGAIN;
	X		return(n);
	X	}
	X
	X	hp = (HEADER *) answer;
	X	if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
	X#ifdef DEBUG
	X		if (_res.options & RES_DEBUG)
	X			printf("rcode = %d, ancount=%d\n", hp->rcode,
	X			    ntohs(hp->ancount));
	X#endif
	X		switch (hp->rcode) {
	X			case NXDOMAIN:
	X				h_errno = HOST_NOT_FOUND;
	X				break;
	X			case SERVFAIL:
	X				h_errno = TRY_AGAIN;
	X				break;
	X			case NOERROR:
	X				h_errno = NO_DATA;
	X				break;
	X			case FORMERR:
	X			case NOTIMP:
	X			case REFUSED:
	X			default:
	X				h_errno = NO_RECOVERY;
	X				break;
	X		}
	X		return (-1);
	X	}
	X	return(n);
	X}
	X
	X/*
	X * Formulate a normal query, send, and retrieve answer in supplied buffer.
	X * Return the size of the response on success, -1 on error.
	X * If enabled, implement search rules until answer or unrecoverable failure
	X * is detected.  Error number is left in h_errno.
	X * Only useful for queries in the same name hierarchy as the local host
	X * (not, for example, for host address-to-name lookups in domain in-addr.arpa).
	X */
	Xres_search(name, class, type, answer, anslen)
	X	char *name;		/* domain name */
	X	int class, type;	/* class and type of query */
	X	u_char *answer;		/* buffer to put answer */
	X	int anslen;		/* size of answer */
	X{
	X	register char *cp, **domain;
	X	int n, ret, got_nodata = 0;
	X	char *hostalias();
	X
	X	if ((_res.options & RES_INIT) == 0 && res_init() == -1)
	X		return (-1);
	X
	X	errno = 0;
	X	h_errno = HOST_NOT_FOUND;		/* default, if we never query */
	X	for (cp = name, n = 0; *cp; cp++)
	X		if (*cp == '.')
	X			n++;
	X	if (n == 0 && (cp = hostalias(name)))
	X		return (res_query(cp, class, type, answer, anslen));
	X
	X	if ((n == 0 || *--cp != '.') && (_res.options & RES_DEFNAMES))
	X	    for (domain = _res.dnsrch; *domain; domain++) {
	X		ret = res_querydomain(name, *domain, class, type,
	X		    answer, anslen);
	X		if (ret > 0)
	X			return (ret);
	X		/*
	X		 * If no server present, give up.
	X		 * If name isn't found in this domain,
	X		 * keep trying higher domains in the search list
	X		 * (if that's enabled).
	X		 * On a NO_DATA error, keep trying, otherwise
	X		 * a wildcard entry of another type could keep us
	X		 * from finding this entry higher in the domain.
	X		 * If we get some other error (non-authoritative negative
	X		 * answer or server failure), then stop searching up,
	X		 * but try the input name below in case it's fully-qualified.
	X		 */
	X		if (errno == ECONNREFUSED) {
	X			h_errno = TRY_AGAIN;
	X			return (-1);
	X		}
	X		if (h_errno == NO_DATA)
	X			got_nodata++;
	X		if ((h_errno != HOST_NOT_FOUND && h_errno != NO_DATA) ||
	X		    (_res.options & RES_DNSRCH) == 0)
	X			break;
	X	}
	X	/*
	X	 * If the search/default failed, try the name as fully-qualified,
	X	 * but only if it contained at least one dot (even trailing).
	X	 */
	X	if (n)
	X		return (res_querydomain(name, (char *)NULL, class, type,
	X		    answer, anslen));
	X	if (got_nodata)
	X		h_errno = NO_DATA;
	X	else if (h_errno == 0)
	X		h_errno = HOST_NOT_FOUND;
	X	return (-1);
	X}
	X
	X/*
	X * Perform a call on res_query on the concatenation of name and domain,
	X * removing a trailing dot from name if domain is NULL.
	X */
	Xres_querydomain(name, domain, class, type, answer, anslen)
	X	char *name, *domain;
	X	int class, type;	/* class and type of query */
	X	u_char *answer;		/* buffer to put answer */
	X	int anslen;		/* size of answer */
	X{
	X	char nbuf[2*MAXDNAME+2];
	X	char *longname = nbuf;
	X	int n;
	X
	X#ifdef DEBUG
	X	if (_res.options & RES_DEBUG)
	X		printf("res_querydomain(%s, %s, %d, %d)\n",
	X		    name, domain, class, type);
	X#endif
	X	if (domain == NULL) {
	X		/*
	X		 * Check for trailing '.';
	X		 * copy without '.' if present.
	X		 */
	X		n = strlen(name) - 1;
	X		if (name[n] == '.' && n < sizeof(nbuf) - 1) {
	X#ifdef SYS5
	X			(void)memcpy(nbuf, name, n);
	X#else
	X			bcopy(name, nbuf, n);
	X#endif
	X			nbuf[n] = '\0';
	X		} else
	X			longname = name;
	X	} else
	X		(void)sprintf(nbuf, "%.*s.%.*s",
	X		    MAXDNAME, name, MAXDNAME, domain);
	X
	X	return (res_query(longname, class, type, answer, anslen));
	X}
	X
	Xchar *
	Xhostalias(name)
	X	register char *name;
	X{
	X	register char *C1, *C2;
	X	FILE *fp;
	X	char *file, *getenv(), *strcpy(), *strncpy();
	X	char buf[BUFSIZ];
	X	static char abuf[MAXDNAME];
	X
	X	file = getenv("HOSTALIASES");
	X	if (file == NULL || (fp = fopen(file, "r")) == NULL)
	X		return (NULL);
	X	buf[sizeof(buf) - 1] = '\0';
	X	while (fgets(buf, sizeof(buf), fp)) {
	X		for (C1 = buf; *C1 && !isspace(*C1); ++C1);
	X		if (!*C1)
	X			break;
	X		*C1 = '\0';
	X		if (!strcasecmp(buf, name)) {
	X			while (isspace(*++C1));
	X			if (!*C1)
	X				break;
	X			for (C2 = C1 + 1; *C2 && !isspace(*C2); ++C2);
	X			abuf[sizeof(abuf) - 1] = *C2 = '\0';
	X			(void)strncpy(abuf, C1, sizeof(abuf) - 1);
	X			fclose(fp);
	X			return (abuf);
	X		}
	X	}
	X	fclose(fp);
	X	return (NULL);
	X}
	X
	X
SHAR_EOF
if test 6927 -ne "`wc -c < 'res_query.c'`"
then
	echo shar: "error transmitting 'res_query.c'" '(should have been 6927 characters)'
fi
fi
echo shar: "extracting 'res_send.c'" '(9929 characters)'
if test -f 'res_send.c'
then
	echo shar: "will not over-write existing file 'res_send.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'res_send.c'
	X/*
	X * Copyright (c) 1985 Regents of the University of California.
	X * All rights reserved.
	X *
	X * Redistribution and use in source and binary forms are permitted
	X * provided that this notice is preserved and that due credit is given
	X * to the University of California at Berkeley. The name of the University
	X * may not be used to endorse or promote products derived from this
	X * software without specific prior written permission. This software
	X * is provided ``as is'' without express or implied warranty.
	X */
	X
	X#if defined(LIBC_SCCS) && !defined(lint)
	Xstatic char sccsid[] = "@(#)res_send.c	6.19 (Berkeley) 3/7/88";
	X#endif /* LIBC_SCCS and not lint */
	X
	X/*
	X * Send query to name server and wait for reply.
	X */
	X
	X#include <sys/param.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#endif
	X#include <sys/time.h>
	X#include <sys/socket.h>
	X#ifndef SYS5
	X#include <sys/uio.h>
	X#endif
	X#include <netinet/in.h>
	X#include <stdio.h>
	X#include <errno.h>
	X#include <arpa/nameser.h>
	X#include <resolv.h>
	X
	Xextern int errno;
	X
	Xstatic int s = -1;	/* socket used for communications */
	Xstatic struct sockaddr no_addr;
	X  
	X#ifndef SYS5
	X#ifndef FD_SET
	X#define	NFDBITS		32
	X#define	FD_SETSIZE	32
	X#define	FD_SET(n, p)	((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
	X#define	FD_CLR(n, p)	((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
	X#define	FD_ISSET(n, p)	((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
	X#define FD_ZERO(p)	bzero((char *)(p), sizeof(*(p)))
	X#endif
	X#endif
	X
	X#define KEEPOPEN (RES_USEVC|RES_STAYOPEN)
	X
	Xres_send(buf, buflen, answer, anslen)
	X	char *buf;
	X	int buflen;
	X	char *answer;
	X	int anslen;
	X{
	X	register int n;
	X	int retry, v_circuit, resplen, ns;
	X	int gotsomewhere = 0, connected = 0;
	X	u_short id, len;
	X	char *cp;
	X	HEADER *hp = (HEADER *) buf;
	X	HEADER *anhp = (HEADER *) answer;
	X#if defined(EXOS) || defined(MASSCOMP)
	X	int timeout, dsmask;
	X	struct sockaddr_in there;
	X#endif
	X#ifndef SYS5
	X	struct timeval timeout;
	X	fd_set dsmask;
	X	struct iovec iov[2];
	X#endif
	X	int terrno = ETIMEDOUT;
	X	char junk[512];
	X#ifdef EXOS
	X	there.sin_family = (u_short)AF_INET;
	X	there.sin_port = htons(NAMESERVER_PORT);
	X#endif
	X#ifdef DEBUG
	X	if (_res.options & RES_DEBUG) {
	X		printf("res_send()\n");
	X		p_query(buf);
	X	}
	X#endif DEBUG
	X	if (!(_res.options & RES_INIT))
	X		if (res_init() == -1) {
	X			return(-1);
	X		}
	X	v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
	X	id = hp->id;
	X	/*
	X	 * Send request, RETRY times, or until successful
	X	 */
	X	for (retry = _res.retry; retry > 0; retry--) {
	X	   for (ns = 0; ns < _res.nscount; ns++) {
	X#ifdef DEBUG
	X		if (_res.options & RES_DEBUG)
	X			printf("Querying server (# %d) address = %s\n", ns+1,
	X			      inet_ntoa(_res.nsaddr_list[ns].sin_addr));
	X#endif DEBUG
	X		if (v_circuit) {
	X			int truncated = 0;
	X
	X			/*
	X			 * Use virtual circuit.
	X			 */
	X			if (s < 0) {
	X#ifdef EXOS
	X				s = socket(SOCK_STREAM, 0, 0, 0);
	X#else
	X				s = socket(AF_INET, SOCK_STREAM, 0);
	X#endif
	X				if (s < 0) {
	X					terrno = errno;
	X#ifdef DEBUG
	X					if (_res.options & RES_DEBUG)
	X					    perror("socket failed");
	X#endif DEBUG
	X					continue;
	X				}
	X#ifdef EXOS
	X				if (connect(s,&(_res.nsaddr_list[ns])) < 0){
	X#else
	X				if (connect(s, &(_res.nsaddr_list[ns]),
	X				   sizeof(struct sockaddr)) < 0) {
	X#endif
	X					terrno = errno;
	X#ifdef DEBUG
	X					if (_res.options & RES_DEBUG)
	X					    perror("connect failed");
	X#endif DEBUG
	X					(void) close(s);
	X					s = -1;
	X					continue;
	X				}
	X			}
	X			/*
	X			 * Send length & message
	X			 */
	X			len = htons((u_short)buflen);
	X#ifdef SYS5
	X			if (write(s,(char *)&len,sizeof(len)) < sizeof(len) ||
	X			    write(s,buf,buflen) < buflen) {
	X#else
	X			iov[0].iov_base = (caddr_t)&len;
	X			iov[0].iov_len = sizeof(len);
	X			iov[1].iov_base = buf;
	X			iov[1].iov_len = buflen;
	X			if (writev(s, iov, 2) != sizeof(len) + buflen) {
	X#endif
	X				terrno = errno;
	X#ifdef DEBUG
	X				if (_res.options & RES_DEBUG)
	X					perror("write failed");
	X#endif DEBUG
	X				(void) close(s);
	X				s = -1;
	X				continue;
	X			}
	X			/*
	X			 * Receive length & response
	X			 */
	X			cp = answer;
	X			len = sizeof(short);
	X			while (len != 0 &&
	X			    (n = read(s, (char *)cp, (int)len)) > 0) {
	X				cp += n;
	X				len -= n;
	X			}
	X			if (n <= 0) {
	X				terrno = errno;
	X#ifdef DEBUG
	X				if (_res.options & RES_DEBUG)
	X					perror("read failed");
	X#endif DEBUG
	X				(void) close(s);
	X				s = -1;
	X				continue;
	X			}
	X			cp = answer;
	X			if ((resplen = ntohs(*(u_short *)cp)) > anslen) {
	X#ifdef DEBUG
	X				if (_res.options & RES_DEBUG)
	X					fprintf(stderr, "response truncated\n");
	X#endif DEBUG
	X				len = anslen;
	X				truncated = 1;
	X			} else
	X				len = resplen;
	X			while (len != 0 &&
	X			   (n = read(s, (char *)cp, (int)len)) > 0) {
	X				cp += n;
	X				len -= n;
	X			}
	X			if (n <= 0) {
	X				terrno = errno;
	X#ifdef DEBUG
	X				if (_res.options & RES_DEBUG)
	X					perror("read failed");
	X#endif DEBUG
	X				(void) close(s);
	X				s = -1;
	X				continue;
	X			}
	X			if (truncated) {
	X				/*
	X				 * Flush rest of answer
	X				 * so connection stays in synch.
	X				 */
	X				anhp->tc = 1;
	X				len = resplen - anslen;
	X				while (len != 0) {
	X					n = (len > sizeof(junk) ?
	X					    sizeof(junk) : len);
	X					if ((n = read(s, junk, n)) > 0)
	X						len -= n;
	X					else
	X						break;
	X				}
	X			}
	X		} else {
	X			/*
	X			 * Use datagrams.
	X			 */
	X			if (s < 0)
	X#ifdef EXOS
	X				s = socket(SOCK_DGRAM, 0, 0, 0);
	X#else
	X				s = socket(AF_INET, SOCK_DGRAM, 0);
	X#endif
	X#if	BSD >= 43
	X			if (_res.nscount == 1 || retry == _res.retry) {
	X				/*
	X				 * Don't use connect if we might
	X				 * still receive a response
	X				 * from another server.
	X				 */
	X				if (connected == 0) {
	X#ifdef EXOS
	X				if (connect(s,&(_res.nsaddr_list[ns])) < 0){
	X#else
	X					if (connect(s, &_res.nsaddr_list[ns],
	X					    sizeof(struct sockaddr)) < 0) {
	X#endif
	X#ifdef DEBUG
	X						if (_res.options & RES_DEBUG)
	X							perror("connect");
	X#endif DEBUG
	X						continue;
	X					}
	X					connected = 1;
	X				}
	X#ifdef EXOS
	X				errno = 0;
	X#ifdef SYS5
	X			        (void)memcpy(&there,&_res.nsaddr_list[ns],
	X#else
	X			        bcopy(&_res.nsaddr_list[ns],&there,
	X#endif
	X							sizeof(there));
	X				send(s,&there, buf, buflen);
	X				if (errno != 0) {
	X#else
	X				if (send(s, buf, buflen, 0) != buflen) {
	X#endif
	X#ifdef DEBUG
	X					if (_res.options & RES_DEBUG)
	X						perror("send");
	X#endif DEBUG
	X					continue;
	X				}
	X			} else
	X#endif BSD
	X#ifdef EXOS
	X			errno = 0;
	X#ifdef SYS5
	X			(void)memcpy(&there,&_res.nsaddr_list[ns],
	X								sizeof(there));
	X#else
	X			bcopy(&_res.nsaddr_list[ns],&there,sizeof(there));
	X#endif
	X			send(s,&there, buf, buflen);
	X			if (errno != 0){
	X#else
	X			if (sendto(s, buf, buflen, 0, &_res.nsaddr_list[ns],
	X			    sizeof(struct sockaddr)) != buflen) {
	X#endif
	X#ifdef DEBUG
	X				if (_res.options & RES_DEBUG)
	X#ifdef EXOS
	X					perror("send");
	X#else
	X					perror("sendto");
	X#endif
	X#endif DEBUG
	X				continue;
	X			}
	X
	X			/*
	X			 * Wait for reply
	X			 */
	X#if defined(EXOS) || defined(MASSCOMP)
	X			timeout = ((_res.retrans << (_res.retry - retry))
	X				/ _res.nscount) * 1000;
	X			if (timeout <= 0) timeout = 1000;
	X#else
	X			timeout.tv_sec = (_res.retrans << (_res.retry - retry))
	X				/ _res.nscount;
	X			if (timeout.tv_sec <= 0)
	X				timeout.tv_sec = 1;
	X			timeout.tv_usec = 0;
	X#endif
	Xwait:
	X#if defined(EXOS) || defined(MASSCOMP)
	X			dsmask = (1 << s) ;
	X			n = select(32,&dsmask,NULL,timeout);
	X#else
	X			FD_ZERO(&dsmask);
	X			FD_SET(s, &dsmask);
	X			n = select(s+1, &dsmask, (fd_set *)NULL,
	X						(fd_set *)NULL, &timeout);
	X#endif
	X			if (n < 0) {
	X#ifdef DEBUG
	X				if (_res.options & RES_DEBUG)
	X					perror("select");
	X#endif DEBUG
	X				continue;
	X			}
	X			if (n == 0) {
	X				/*
	X				 * timeout
	X				 */
	X#ifdef DEBUG
	X				if (_res.options & RES_DEBUG)
	X					printf("timeout\n");
	X#endif DEBUG
	X				/*
	X				 * Disconnect if we want to listen
	X				 * for responses from more than one server.
	X				 */
	X				if (_res.nscount > 1 && connected) {
	X#ifdef EXOS
	X#ifdef SYS5
	X					memset(&no_addr,'\0',sizeof(no_addr));
	X#else
	X					bzero(&no_addr,sizeof(no_addr));
	X#endif
	X					(void) connect(s, &no_addr);
	X#else
	X					(void) connect(s, &no_addr,
	X					    sizeof(no_addr));
	X#endif
	X					connected = 0;
	X				}
	X				gotsomewhere = 1;
	X				continue;
	X			}
	X#ifdef EXOS
	X#ifdef SYS5
	X			(void) memcpy(&there,&_res.nsaddr_list[ns],
	X								sizeof(there));
	X#else
	X			bcopy(&_res.nsaddr_list[ns],&there,sizeof(there));
	X#endif
	X			if((resplen = receive(s,&there,answer,anslen)) <= 0) {
	X#else
	X			if ((resplen = recv(s, answer, anslen, 0)) <= 0) {
	X#endif
	X#ifdef DEBUG
	X				if (_res.options & RES_DEBUG)
	X#ifdef EXOS
	X					perror("receive");
	X#else
	X					perror("recvfrom");
	X#endif
	X#endif DEBUG
	X				continue;
	X			}
	X			gotsomewhere = 1;
	X			if (id != anhp->id) {
	X				/*
	X				 * response from old query, ignore it
	X				 */
	X#ifdef DEBUG
	X				if (_res.options & RES_DEBUG) {
	X					printf("old answer:\n");
	X					p_query(answer);
	X				}
	X#endif DEBUG
	X				goto wait;
	X			}
	X			if (!(_res.options & RES_IGNTC) && anhp->tc) {
	X				/*
	X				 * get rest of answer
	X				 */
	X#ifdef DEBUG
	X				if (_res.options & RES_DEBUG)
	X					printf("truncated answer\n");
	X#endif DEBUG
	X				(void) close(s);
	X				s = -1;
	X				/*
	X				 * retry decremented on continue
	X				 * to desired starting value
	X				 */
	X				retry = _res.retry + 1;
	X				v_circuit = 1;
	X				continue;
	X			}
	X		}
	X#ifdef DEBUG
	X		if (_res.options & RES_DEBUG) {
	X			printf("got answer:\n");
	X			p_query(answer);
	X		}
	X#endif DEBUG
	X		/*
	X		 * We are going to assume that the first server is preferred
	X		 * over the rest (i.e. it is on the local machine) and only
	X		 * keep that one open.
	X		 */
	X		if ((_res.options & KEEPOPEN) == KEEPOPEN && ns == 0) {
	X			return (resplen);
	X		} else {
	X			(void) close(s);
	X			s = -1;
	X			return (resplen);
	X		}
	X	   }
	X	}
	X	if (s >= 0) {
	X		(void) close(s);
	X		s = -1;
	X	}
	X	if (v_circuit == 0)
	X		if (gotsomewhere == 0)
	X			errno = ECONNREFUSED;
	X		else
	X			errno = ETIMEDOUT;
	X	else
	X		errno = terrno;
	X	return (-1);
	X}
	X
	X/*
	X * This routine is for closing the socket if a virtual circuit is used and
	X * the program wants to close it.  This provides support for endhostent()
	X * which expects to close the socket.
	X *
	X * This routine is not expected to be user visible.
	X */
	X_res_close()
	X{
	X	if (s != -1) {
	X		(void) close(s);
	X		s = -1;
	X	}
	X}
SHAR_EOF
if test 9929 -ne "`wc -c < 'res_send.c'`"
then
	echo shar: "error transmitting 'res_send.c'" '(should have been 9929 characters)'
fi
fi
exit 0
#	End of shell archive
The MASSCOMP USERS' SOCIETY newsgroup is comp.sys.masscomp.
Articles to: masscomp@soma.bcm.tmc.edu or uunet!soma.bcm.tmc.edu!masscomp
Administrative stuff: masscomp-request@soma.bcm.tmc.edu
Stan Barber, Moderator

sob@cortex.neuro.bcm.tmc.edu (Stan Barber) (07/12/88)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	CHANGES
#	Makefile
#	README
#	include
#	res/named/Makefile
#	res/named/gethnamadr.c
#	res/named/sethostent.c
#	resolv.conf
# This archive created: Mon Jul  4 20:48:20 1988
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'CHANGES'" '(704 characters)'
if test -f 'CHANGES'
then
	echo shar: "will not over-write existing file 'CHANGES'"
else
sed 's/^	X//' << \SHAR_EOF > 'CHANGES'
	XChanges to the resolver library and tools for System V and EXCELAN EXOS 205
	Xfront end.
	X
	XBy Stan Barber, Baylor College of Medicine
	X
	XAdded two new compiler definitions. EXOS for EXCELAN specific changes and
	XSYS5 for System V specific changes.
	X
	XThe System V changes mostly involved the including of <string.h> instead of
	X<strings.h> and the use of memcpy for bcopy, memcmp for bcmp and memset
	Xfor bzero. One significant change was to change the name of gethostnamadr.c
	Xto gethnamadr.c to fit the filename into 14 characters.
	X
	XThe EXCELAN changes involved retrofiting BSD 4.1c sematics on the BSD 4.[2-3]
	Xsemantics.
	X
	XI added res_compat.c to include inet_ntoa and friends which are not supplied
	Xby EXCELAN.
	X
SHAR_EOF
if test 704 -ne "`wc -c < 'CHANGES'`"
then
	echo shar: "error transmitting 'CHANGES'" '(should have been 704 characters)'
fi
fi
echo shar: "extracting 'Makefile'" '(158 characters)'
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
sed 's/^	X//' << \SHAR_EOF > 'Makefile'
	X#
	X#
	X# Master Makefile for bind
	X#
	X#
	XSHELL=/bin/sh
	X#
	X#
	Xall:
	X	cd res; make ; cd ..
	X	cd tools; make 
	X
	Xclean:
	X	cd res; make clean; cd ..
	X	cd tools; make clean
	X
	X
	X	
SHAR_EOF
if test 158 -ne "`wc -c < 'Makefile'`"
then
	echo shar: "error transmitting 'Makefile'" '(should have been 158 characters)'
fi
fi
echo shar: "extracting 'README'" '(1355 characters)'
if test -f 'README'
then
	echo shar: "will not over-write existing file 'README'"
else
sed 's/^	X//' << \SHAR_EOF > 'README'
	XThis is a revised version of the resolver library supplied with BIND 4.8
	Xplus patches supplied in the bind mailinglist. This version will work
	Xunder SYSTEM V on the Unisys 5000 series of computer with the NET-5000
	Xproduct. It may work on ATT 3B computers. It will also continue to work
	Xon BSD-style computers since none of that code has been changed.
	X
	XTo install this libarary on Unisys 5000 computers do the following:
	X
	XEdit Makefile.resol in both tools and res subdirectories. Make sure
	Xit looks like  the following:
	X
	XCFLAGS=-O -DDEBUG -DEXOS -DSYS5 -I../include -I/usr/include/NET-5000
	X
	XEdit Makefile in tools/nslookup subdirectory so that it looks like:
	X
	XCFLAGS=-O -DEXOS -DSYS5 -I../../include -I/usr/include/NET-5000
	X
	XWrite the files and type "make library" at the unix prompt.
	XGo get a snack. This will take about 20 minutes.
{_	X
	XBecome the super user.
	X
	XCreate a file called /etc/resolv.conf to contain the following information:
	XYour domain suffix ("tmc.edu" or "dec.com" or "nsf.net") and up to three
	Xnameserver addresses.
	X[An EXAMPLE file is called resolv.conf in this directory. DO NOT use this file.
	XCreate your own.]
	X
	XYou can now use the programs nstest and nsquery in the tools subdirectory
	Xto test the system. You do not need to be the superuser to do this.
	X
	XFor more information, see the bind distribution kit.
	X
	X
	XStan Barber
	Xsob@tmc.edu
	X
SHAR_EOF
if test 1355 -ne "`wc -c < 'README'`"
then
	echo shar: "error transmitting 'README'" '(should have been 1355 characters)'
fi
fi
if test ! -d 'include'
then
	echo shar: "creating directory 'include'"
	mkdir 'include'
fi
echo shar: "entering directory 'include'"
cd 'include'
if test ! -d 'arpa'
then
	echo shar: "creating directory 'arpa'"
	mkdir 'arpa'
fi
echo shar: "entering directory 'arpa'"
cd 'arpa'
echo shar: "extracting 'nameser.h'" '(6859 characters)'
if test -f 'nameser.h'
then
	echo shar: "will not over-write existing file 'nameser.h'"
else
sed 's/^	X//' << \SHAR_EOF > 'nameser.h'
	X/*
	X * Copyright (c) 1983 Regents of the University of California.
	X * All rights reserved.  The Berkeley software License Agreement
	X * specifies the terms and conditions for redistribution.
	X *
	X *	@(#)nameser.h	5.17 (Berkeley) 11/17/87
	X */
	X
	X/*
	X * Define constants based on rfc883
	X */
	X#define PACKETSZ	512		/* maximum packet size */
	X#define MAXDNAME	256		/* maximum domain name */
	X#define MAXCDNAME	255		/* maximum compressed domain name */
	X#define MAXLABEL	63		/* maximum length of domain label */
	X	/* Number of bytes of fixed size data in query structure */
	X#define QFIXEDSZ	4
	X	/* number of bytes of fixed size data in resource record */
	X#define RRFIXEDSZ	10
	X
	X/*
	X * Internet nameserver port number
	X */
	X#define NAMESERVER_PORT	53
	X
	X/*
	X * Currently defined opcodes
	X */
	X#define QUERY		0x0		/* standard query */
	X#define IQUERY		0x1		/* inverse query */
	X#define STATUS		0x2		/* nameserver status query */
	X/*#define xxx		0x3		/* 0x3 reserved */
	X	/* non standard */
	X#define UPDATEA		0x9		/* add resource record */
	X#define UPDATED		0xa		/* delete a specific resource record */
	X#define UPDATEDA	0xb		/* delete all nemed resource record */
	X#define UPDATEM		0xc		/* modify a specific resource record */
	X#define UPDATEMA	0xd		/* modify all named resource record */
	X
	X#define ZONEINIT	0xe		/* initial zone transfer */
	X#define ZONEREF		0xf		/* incremental zone referesh */
	X
	X/*
	X * Currently defined response codes
	X */
	X#define NOERROR		0		/* no error */
	X#define FORMERR		1		/* format error */
	X#define SERVFAIL	2		/* server failure */
	X#define NXDOMAIN	3		/* non existent domain */
	X#define NOTIMP		4		/* not implemented */
	X#define REFUSED		5		/* query refused */
	X	/* non standard */
	X#define NOCHANGE	0xf		/* update failed to change db */
	X
	X/*
	X * Type values for resources and queries
	X */
	X#define T_A		1		/* host address */
	X#define T_NS		2		/* authoritative server */
	X#define T_MD		3		/* mail destination */
	X#define T_MF		4		/* mail forwarder */
	X#define T_CNAME		5		/* connonical name */
	X#define T_SOA		6		/* start of authority zone */
	X#define T_MB		7		/* mailbox domain name */
	X#define T_MG		8		/* mail group member */
	X#define T_MR		9		/* mail rename name */
	X#define T_NULL		10		/* null resource record */
	X#define T_WKS		11		/* well known service */
	X#define T_PTR		12		/* domain name pointer */
	X#define T_HINFO		13		/* host information */
	X#define T_MINFO		14		/* mailbox information */
	X#define T_MX		15		/* mail routing information */
	X	/* non standard */
	X#define T_UINFO		100		/* user (finger) information */
	X#define T_UID		101		/* user ID */
	X#define T_GID		102		/* group ID */
	X#define T_UNSPEC	103		/* Unspecified format (binary data) */
	X	/* Query type values which do not appear in resource records */
	X#define T_AXFR		252		/* transfer zone of authority */
	X#define T_MAILB		253		/* transfer mailbox records */
	X#define T_MAILA		254		/* transfer mail agent records */
	X#define T_ANY		255		/* wildcard match */
	X
	X/*
	X * Values for class field
	X */
	X
	X#define C_IN		1		/* the arpa internet */
	X#define C_CHAOS		3		/* for chaos net at MIT */
	X	/* Query class values which do not appear in resource records */
	X#define C_ANY		255		/* wildcard match */
	X
	X/*
	X * Status return codes for T_UNSPEC conversion routines
	X */
	X#define CONV_SUCCESS 0
	X#define CONV_OVERFLOW -1
	X#define CONV_BADFMT -2
	X#define CONV_BADCKSUM -3
	X#define CONV_BADBUFLEN -4
	X
	X/*
	X * Structure for query header, the order of the fields is machine and
	X * compiler dependent, in our case, the bits within a byte are assignd 
	X * least significant first, while the order of transmition is most 
	X * significant first.  This requires a somewhat confusing rearrangement.
	X */
	X
	Xtypedef struct {
	X	u_short	id;		/* query identification number */
	X#if defined (sun) || defined (sel) || defined (pyr) || defined (is68k) \
	X|| defined (tahoe) || defined(tower) || defined(MASSCOMP) || defined (BIT_ZERO_ON_LEFT)
	X	/* Bit zero on left:  Gould and similar architectures */
	X			/* fields in third byte */
	X	u_char	qr:1;		/* response flag */
	X	u_char	opcode:4;	/* purpose of message */
	X	u_char	aa:1;		/* authoritive answer */
	X	u_char	tc:1;		/* truncated message */
	X	u_char	rd:1;		/* recursion desired */
	X			/* fields in fourth byte */
	X	u_char	ra:1;		/* recursion available */
	X	u_char	pr:1;		/* primary server required (non standard) */
	X	u_char	unused:2;	/* unused bits */
	X	u_char	rcode:4;	/* response code */
	X#else
	X#if defined (vax) || defined(ns32000) || defined (BIT_ZERO_ON_RIGHT)
	X	/* Bit zero on right:  VAX */
	X			/* fields in third byte */
	X	u_char	rd:1;		/* recursion desired */
	X	u_char	tc:1;		/* truncated message */
	X	u_char	aa:1;		/* authoritive answer */
	X	u_char	opcode:4;	/* purpose of message */
	X	u_char	qr:1;		/* response flag */
	X			/* fields in fourth byte */
	X	u_char	rcode:4;	/* response code */
	X	u_char	unused:2;	/* unused bits */
	X	u_char	pr:1;		/* primary server required (non standard) */
	X	u_char	ra:1;		/* recursion available */
	X#else
	X#if defined (pdp11) || defined (BIT_ZERO_ON_RIGHT_BUT_COMPILER_STUPID)
	X	/* Bit zero on right, compiler doesn't like u_char bit fields:  PDP */
	X			/* fields in third byte */
	X	u_int	rd:1;		/* recursion desired */
	X	u_int	tc:1;		/* truncated message */
	X	u_int	aa:1;		/* authoritive answer */
	X	u_int	opcode:4;	/* purpose of message */
	X	u_int	qr:1;		/* response flag */
	X			/* fields in fourth byte */
	X	u_int	rcode:4;	/* response code */
	X	u_int	unused:2;	/* unused bits */
	X	u_int	pr:1;		/* primary server required (non standard) */
	X	u_int	ra:1;		/* recursion available */
	X#else
	X	/* you must determine what the correct bit order is for your compiler */
	X	UNDEFINED_BIT_ORDER;
	X#endif
	X#endif
	X#endif
	X			/* remaining bytes */
	X	u_short	qdcount;	/* number of question entries */
	X	u_short	ancount;	/* number of answer entries */
	X	u_short	nscount;	/* number of authority entries */
	X	u_short	arcount;	/* number of resource entries */
	X} HEADER;
	X
	X/*
	X * Defines for handling compressed domain names
	X */
	X#define INDIR_MASK	0xc0
	X
	X/*
	X * Structure for passing resource records around.
	X */
	Xstruct rrec {
	X	short	r_zone;			/* zone number */
	X	short	r_class;		/* class number */
	X	short	r_type;			/* type number */
	X	u_long	r_ttl;			/* time to live */
	X	int	r_size;			/* size of data area */
	X	char	*r_data;		/* pointer to data */
	X};
	X
	Xextern	u_short	_getshort();
	Xextern	u_long	_getlong();
	X
	X/*
	X * Inline versions of get/put short/long.
	X * Pointer is advanced; we assume that both arguments
	X * are lvalues and will already be in registers.
	X * cp MUST be u_char *.
	X */
	X#define GETSHORT(s, cp) { \
	X	(s) = *(cp)++ << 8; \
	X	(s) |= *(cp)++; \
	X}
	X
	X#define GETLONG(l, cp) { \
	X	(l) = *(cp)++ << 8; \
	X	(l) |= *(cp)++; (l) <<= 8; \
	X	(l) |= *(cp)++; (l) <<= 8; \
	X	(l) |= *(cp)++; \
	X}
	X
	X
	X#define PUTSHORT(s, cp) { \
	X	*(cp)++ = (s) >> 8; \
	X	*(cp)++ = (s); \
	X}
	X
	X/*
	X * Warning: PUTLONG destroys its first argument.
	X */
	X#define PUTLONG(l, cp) { \
	X	(cp)[3] = l; \
	X	(cp)[2] = (l >>= 8); \
	X	(cp)[1] = (l >>= 8); \
	X	(cp)[0] = l >> 8; \
	X	(cp) += sizeof(u_long); \
	X}
SHAR_EOF
if test 6859 -ne "`wc -c < 'nameser.h'`"
then
	echo shar: "error transmitting 'nameser.h'" '(should have been 6859 characters)'
fi
fi
echo shar: "done with directory 'arpa'"
cd ..
echo shar: "extracting 'netdb.h'" '(2419 characters)'
if test -f 'netdb.h'
then
	echo shar: "will not over-write existing file 'netdb.h'"
else
sed 's/^	X//' << \SHAR_EOF > 'netdb.h'
	X/*	@(#)netdb.h 1.1 86/07/07 SMI; from UCB	*/
	X/* Modified 87.06.20, S. Levy, adding h_addr_list field to hostent
	X * allowing simultaneous 4.2 and 4.3 compatibility
	X * (including compatibility with existing 4.2 binary library routines).
	X * This file combines 4.2, 4.3, SUN and Cray definitions.
	X * Domain resolver routines set both h_addr and h_addr_list fields.
	X */
	X
	X/*
	X * Structures returned by network
	X * data base library.  All addresses
	X * are supplied in host order, and
	X * returned in network order (suitable
	X * for use in system calls).
	X */
	Xstruct	hostent {
	X	char	*h_name;	/* official name of host */
	X	char	**h_aliases;	/* alias list */
	X	int	h_addrtype;	/* host address type */
	X	int	h_length;	/* length of address */
	X#define	h_addr	h_addr_0	/* Dummy to make resolver think we're 4.3 */
	X	char	*h_addr;	/* This field for 4.2 binary compatibility. */
	X	char	**h_addr_list;	/* list of addresses from name server */
	X};
	X
	X/*
	X * Assumption here is that a network number
	X * fits in 32 bits -- probably a poor one.
	X */
	Xstruct	netent {
	X	char		*n_name;	/* official name of net */
	X	char		**n_aliases;	/* alias list */
	X	int		n_addrtype;	/* net address type */
	X	unsigned long	n_net;		/* network # */
	X};
	X
	Xstruct	servent {
	X	char	*s_name;	/* official service name */
	X	char	**s_aliases;	/* alias list */
	X	int	s_port;		/* port # */
	X	char	*s_proto;	/* protocol to use */
	X};
	X
	Xstruct	protoent {
	X	char	*p_name;	/* official protocol name */
	X	char	**p_aliases;	/* alias list */
	X	int	p_proto;	/* protocol # */
	X};
	X
	Xstruct rpcent {
	X	char	*r_name;	/* name of server for this rpc program */
	X	char	**r_aliases;	/* alias list */
	X	int	r_number;	/* rpc program number */
	X};
	X
	Xstruct hostent	*gethostbyname(), *gethostbyaddr(), *gethostent();
	Xstruct netent	*getnetbyname(), *getnetbyaddr(), *getnetent();
	Xstruct servent	*getservbyname(), *getservbyport(), *getservent();
	Xstruct protoent	*getprotobyname(), *getprotobynumber(), *getprotoent();
	Xstruct rpcent	*getrpcbyname(), *getrpcbynumber(), *getrpcent();
	X
	X/*
	X * Error return codes from gethostbyname() and gethostbyaddr()
	X */
	X
	Xextern  int h_errno;	
	X
	X#define	HOST_NOT_FOUND	1 /* Authoritive Answer Host not found */
	X#define	TRY_AGAIN	2 /* Non-Authoritive Host not found, or SERVERFAIL */
	X#define	NO_RECOVERY	3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
	X#define	NO_DATA		4 /* Valid name, no data record of requested type */
	X#define	NO_ADDRESS	NO_DATA		/* no address, look for MX record */
SHAR_EOF
if test 2419 -ne "`wc -c < 'netdb.h'`"
then
	echo shar: "error transmitting 'netdb.h'" '(should have been 2419 characters)'
fi
fi
echo shar: "extracting 'netdb.h.4.2'" '(1920 characters)'
if test -f 'netdb.h.4.2'
then
	echo shar: "will not over-write existing file 'netdb.h.4.2'"
else
sed 's/^	X//' << \SHAR_EOF > 'netdb.h.4.2'
	X/*
	X * Copyright (c) 1980 Regents of the University of California.
	X * All rights reserved.  The Berkeley software License Agreement
	X * specifies the terms and conditions for redistribution.
	X *
	X *	@(#)netdb.h	5.8 (Berkeley) 11/18/87
	X */
	X
	X/*
	X * Structures returned by network
	X * data base library.  All addresses
	X * are supplied in host order, and
	X * returned in network order (suitable
	X * for use in system calls).
	X */
	Xstruct	hostent {
	X	char	*h_name;	/* official name of host */
	X	char	**h_aliases;	/* alias list */
	X	int	h_addrtype;	/* host address type */
	X	int	h_length;	/* length of address */
	X	char	*h_addr;	/* address */
	X};
	X
	X/*
	X * Assumption here is that a network number
	X * fits in 32 bits -- probably a poor one.
	X */
	Xstruct	netent {
	X	char		*n_name;	/* official name of net */
	X	char		**n_aliases;	/* alias list */
	X	int		n_addrtype;	/* net address type */
	X	unsigned long	n_net;		/* network # */
	X};
	X
	Xstruct	servent {
	X	char	*s_name;	/* official service name */
	X	char	**s_aliases;	/* alias list */
	X	int	s_port;		/* port # */
	X	char	*s_proto;	/* protocol to use */
	X};
	X
	Xstruct	protoent {
	X	char	*p_name;	/* official protocol name */
	X	char	**p_aliases;	/* alias list */
	X	int	p_proto;	/* protocol # */
	X};
	X
	Xstruct hostent	*gethostbyname(), *gethostbyaddr(), *gethostent();
	Xstruct netent	*getnetbyname(), *getnetbyaddr(), *getnetent();
	Xstruct servent	*getservbyname(), *getservbyport(), *getservent();
	Xstruct protoent	*getprotobyname(), *getprotobynumber(), *getprotoent();
	X
	X/*
	X * Error return codes from gethostbyname() and gethostbyaddr()
	X * (left in extern int h_errno).
	X */
	X
	X#define	HOST_NOT_FOUND	1 /* Authoritative Answer Host not found */
	X#define	TRY_AGAIN	2 /* Non-Authoritive Host not found, or SERVERFAIL */
	X#define	NO_RECOVERY	3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
	X#define	NO_DATA		4 /* Valid name, no data record of requested type */
	X#define	NO_ADDRESS	NO_DATA		/* no address, look for MX record */
SHAR_EOF
if test 1920 -ne "`wc -c < 'netdb.h.4.2'`"
then
	echo shar: "error transmitting 'netdb.h.4.2'" '(should have been 1920 characters)'
fi
fi
echo shar: "extracting 'resolv.h'" '(1773 characters)'
if test -f 'resolv.h'
then
	echo shar: "will not over-write existing file 'resolv.h'"
else
sed 's/^	X//' << \SHAR_EOF > 'resolv.h'
	X
	X/*
	X * Copyright (c) 1983, 1987 Regents of the University of California.
	X * All rights reserved.  The Berkeley software License Agreement
	X * specifies the terms and conditions for redistribution.
	X *
	X *	@(#)resolv.h	5.5 (Berkeley) 5/12/87
	X */
	X
	X/*
	X * Global defines and variables for resolver stub.
	X */
	X
	X
	X#define	MAXNS		3		/* max # name servers we'll track */
	X#define	MAXDNSRCH	3		/* max # default domain levels to try */
	X#define	LOCALDOMAINPARTS 2		/* min levels in name that is "local" */
	X
	X#define	RES_TIMEOUT	4		/* seconds between retries */
	X
	Xstruct state {
	X	int	retrans;	 	/* retransmition time interval */
	X	int	retry;			/* number of times to retransmit */
	X	long	options;		/* option flags - see below. */
	X	int	nscount;		/* number of name servers */
	X	struct	sockaddr_in nsaddr_list[MAXNS];	/* address of name server */
	X#define	nsaddr	nsaddr_list[0]		/* for backward compatibility */
	X	u_short	id;			/* current packet id */
	X	char	defdname[MAXDNAME];	/* default domain */
	X	char	*dnsrch[MAXDNSRCH+1];	/* components of domain to search */
	X};
	X
	X/*
	X * Resolver options
	X */
	X#define RES_INIT	0x0001		/* address initialized */
	X#define RES_DEBUG	0x0002		/* print debug messages */
	X#define RES_AAONLY	0x0004		/* authoritative answers only */
	X#define RES_USEVC	0x0008		/* use virtual circuit */
	X#define RES_PRIMARY	0x0010		/* query primary server only */
	X#define RES_IGNTC	0x0020		/* ignore trucation errors */
	X#define RES_RECURSE	0x0040		/* recursion desired */
	X#define RES_DEFNAMES	0x0080		/* use default domain name */
	X#define RES_STAYOPEN	0x0100		/* Keep TCP socket open */
	X#define RES_DNSRCH	0x0200		/* search up local domain tree */
	X
	X#define RES_DEFAULT	(RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
	X
	Xextern struct state _res;
	Xextern char *p_cdname(), *p_rr(), *p_type(), *p_class();
SHAR_EOF
if test 1773 -ne "`wc -c < 'resolv.h'`"
then
	echo shar: "error transmitting 'resolv.h'" '(should have been 1773 characters)'
fi
fi
echo shar: "done with directory 'include'"
cd ..
if test ! -d 'res'
then
	echo shar: "creating directory 'res'"
	mkdir 'res'
fi
echo shar: "entering directory 'res'"
cd 'res'
if test ! -d 'named'
then
	echo shar: "creating directory 'named'"
	mkdir 'named'
fi
echo shar: "entering directory 'named'"
cd 'named'
echo shar: "extracting 'Makefile'" '(1767 characters)'
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
sed 's/^	X//' << \SHAR_EOF > 'Makefile'
	X#
	X# Copyright (c) 1983 Regents of the University of California.
	X# All rights reserved.  The Berkeley software License Agreement
	X# specifies the terms and conditions for redistribution.
	X#
	X#	@(#)Makefile	6.4 (Berkeley) 6/6/87
	X#
	X
	XOBJS=	gethostnamadr.o sethostent.o
	X
	XSRCS=	gethostnamadr.c sethostent.c
	X
	XCFLAGS= -O ${DEFS} -I../../include	# Craig Finseth, MSC, April 1988
	XTAGSFILE= tags
	XDESTDIR=
	X
	X.c.o:
	X	${CC} -p -c ${CFLAGS} $*.c
	X	-ld -X -r $*.o
	X	mv a.out profiled/$*.o
	X	${CC} ${CFLAGS} -c $*.c
	X	-ld -x -r $*.o
	X	mv a.out $*.o
	X
	Xhostlib hostlib_p: ${OBJS} 
	X	@echo "building profiled hostlib"
	X	@cd profiled; ar cru ../hostlib_p ${OBJS}
	X	@echo "building normal hostlib"
	X	@ar cru hostlib ${OBJS}
	X
	Xtags:
	X	cwd=`pwd`; \
	X	for i in ${SRCS}; do \
	X		ctags -a -f ${TAGSFILE} $$cwd/$$i; \
	X	done
	X
	Xclean:
	X	rm -f *.o errs a.out core hostlib hostlib_p profiled/*.o tags
	X
	Xdepend:
	X	mkdep ${CFLAGS} ${SRCS}
	X
	X# DO NOT DELETE THIS LINE -- mkdep uses it.
	X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
	X
	Xgethostnamadr.c:
	Xgethostnamadr.o: gethostnamadr.c /usr/include/sys/param.h
	Xgethostnamadr.o: /usr/include/machine/param.h /usr/include/signal.h
	Xgethostnamadr.o: /usr/include/sys/types.h /usr/include/sys/sysmacros.h
	Xgethostnamadr.o: /usr/include/sys/socket.h /usr/include/netinet/in.h
	Xgethostnamadr.o: /usr/include/ctype.h ../../include/netdb.h
	Xgethostnamadr.o: /usr/include/stdio.h /usr/include/errno.h
	Xgethostnamadr.o: /usr/include/sys/errno.h /usr/include/arpa/inet.h
	Xgethostnamadr.o: ../../include/arpa/nameser.h ../../include/resolv.h
	Xsethostent.c:
	Xsethostent.o: sethostent.c /usr/include/sys/types.h
	Xsethostent.o: /usr/include/sys/sysmacros.h ../../include/arpa/nameser.h
	Xsethostent.o: /usr/include/netinet/in.h ../../include/resolv.h
	X
	X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
SHAR_EOF
if test 1767 -ne "`wc -c < 'Makefile'`"
then
	echo shar: "error transmitting 'Makefile'" '(should have been 1767 characters)'
fi
fi
echo shar: "extracting 'gethnamadr.c'" '(8573 characters)'
if test -f 'gethnamadr.c'
then
	echo shar: "will not over-write existing file 'gethnamadr.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'gethnamadr.c'
	X/*
	X * Copyright (c) 1985, 1988 Regents of the University of California.
	X * All rights reserved.
	X *
	X * Redistribution and use in source and binary forms are permitted
	X * provided that this notice is preserved and that due credit is given
	X * to the University of California at Berkeley. The name of the University
	X * may not be used to endorse or promote products derived from this
	X * software without specific prior written permission. This software
	X * is provided ``as is'' without express or implied warranty.
	X */
	X
	X#if defined(LIBC_SCCS) && !defined(lint)
	Xstatic char sccsid[] = "@(#)gethostnamadr.c	6.32 (Berkeley) 4/12/88";
	X#endif /* LIBC_SCCS and not lint */
	X
	X#include <sys/param.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#endif
	X#include <sys/socket.h>
	X#include <netinet/in.h>
	X#include <ctype.h>
	X#include <netdb.h>
	X#include <stdio.h>
	X#include <errno.h>
	X#ifndef EXOS
	X#include <arpa/inet.h>
	X#endif
	X#include <arpa/nameser.h>
	X#include <resolv.h>
	X
	X#define	MAXALIASES	35
	X#define	MAXADDRS	35
	X
	Xstatic char *h_addr_ptrs[MAXADDRS + 1];
	X
	Xstatic struct hostent host;
	Xstatic char *host_aliases[MAXALIASES];
	Xstatic char hostbuf[BUFSIZ+1];
	Xstatic struct in_addr host_addr;
	X#ifdef MASSCOMP
	Xstatic char HOSTDB[] = "/etc/net/hosts";
	X#else
	Xstatic char HOSTDB[] = "/etc/hosts";
	X#endif
	Xstatic FILE *hostf = NULL;
	Xstatic char hostaddr[MAXADDRS];
	Xstatic char *host_addrs[2];
	Xstatic int stayopen = 0;
	Xstatic char *any();
	X
	X#if PACKETSZ > 1024
	X#define	MAXPACKET	PACKETSZ
	X#else
	X#define	MAXPACKET	1024
	X#endif
	X
	Xtypedef union {
	X    HEADER hdr;
	X    u_char buf[MAXPACKET];
	X} querybuf;
	X
	Xstatic union {
	X    long al;
	X    char ac;
	X} align;
	X
	X
	Xint h_errno;
	Xextern errno;
	X
	Xstatic struct hostent *
	Xgetanswer(answer, anslen, iquery)
	X	querybuf *answer;
	X	int anslen;
	X	int iquery;
	X{
	X	register HEADER *hp;
	X	register u_char *cp;
	X	register int n;
	X	u_char *eom;
	X	char *bp, **ap;
	X	int type, class, buflen, ancount, qdcount;
	X	int haveanswer, getclass = C_ANY;
	X	char **hap;
	X
	X	eom = answer->buf + anslen;
	X	/*
	X	 * find first satisfactory answer
	X	 */
	X	hp = &answer->hdr;
	X	ancount = ntohs(hp->ancount);
	X	qdcount = ntohs(hp->qdcount);
	X	bp = hostbuf;
	X	buflen = sizeof(hostbuf);
	X	cp = answer->buf + sizeof(HEADER);
	X	if (qdcount) {
	X		if (iquery) {
	X			if ((n = dn_expand((char *)answer->buf, eom,
	X			     cp, bp, buflen)) < 0) {
	X				h_errno = NO_RECOVERY;
	X				return ((struct hostent *) NULL);
	X			}
	X			cp += n + QFIXEDSZ;
	X			host.h_name = bp;
	X			n = strlen(bp) + 1;
	X			bp += n;
	X			buflen -= n;
	X		} else
	X			cp += dn_skipname(cp, eom) + QFIXEDSZ;
	X		while (--qdcount > 0)
	X			cp += dn_skipname(cp, eom) + QFIXEDSZ;
	X	} else if (iquery) {
	X		if (hp->aa)
	X			h_errno = HOST_NOT_FOUND;
	X		else
	X			h_errno = TRY_AGAIN;
	X		return ((struct hostent *) NULL);
	X	}
	X	ap = host_aliases;
	X	host.h_aliases = host_aliases;
	X	hap = h_addr_ptrs;
	X#if BSD >= 43 || defined(h_addr)	/* new-style hostent structure */
	X	host.h_addr_list = h_addr_ptrs;
	X#endif
	X	haveanswer = 0;
	X	while (--ancount >= 0 && cp < eom) {
	X		if ((n = dn_expand((char *)answer->buf, eom, cp, bp, buflen)) < 0)
	X			break;
	X		cp += n;
	X		type = _getshort(cp);
	X 		cp += sizeof(u_short);
	X		class = _getshort(cp);
	X 		cp += sizeof(u_short) + sizeof(u_long);
	X		n = _getshort(cp);
	X		cp += sizeof(u_short);
	X		if (type == T_CNAME) {
	X			cp += n;
	X			if (ap >= &host_aliases[MAXALIASES-1])
	X				continue;
	X			*ap++ = bp;
	X			n = strlen(bp) + 1;
	X			bp += n;
	X			buflen -= n;
	X			continue;
	X		}
	X		if (iquery && type == T_PTR) {
	X			if ((n = dn_expand((char *)answer->buf, eom,
	X			    cp, bp, buflen)) < 0) {
	X				cp += n;
	X				continue;
	X			}
	X			cp += n;
	X			host.h_name = bp;
	X			return(&host);
	X		}
	X		if (iquery || type != T_A)  {
	X#ifdef DEBUG
	X			if (_res.options & RES_DEBUG)
	X				printf("unexpected answer type %d, size %d\n",
	X					type, n);
	X#endif
	X			cp += n;
	X			continue;
	X		}
	X		if (haveanswer) {
	X			if (n != host.h_length) {
	X				cp += n;
	X				continue;
	X			}
	X			if (class != getclass) {
	X				cp += n;
	X				continue;
	X			}
	X		} else {
	X			host.h_length = n;
	X			getclass = class;
	X			host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
	X			if (!iquery) {
	X				host.h_name = bp;
	X				bp += strlen(bp) + 1;
	X			}
	X		}
	X
	X		bp += sizeof(align) - ((u_long)bp % sizeof(align));
	X
	X		if (bp + n >= &hostbuf[sizeof(hostbuf)]) {
	X#ifdef DEBUG
	X			if (_res.options & RES_DEBUG)
	X				printf("size (%d) too big\n", n);
	X#endif
	X			break;
	X		}
	X#ifdef SYS5
	X		(void)memcpy(*hap++ = bp, cp, n);
	X#else
	X		bcopy(cp, *hap++ = bp, n);
	X#endif
	X		bp +=n;
	X		cp += n;
	X		haveanswer++;
	X	}
	X	if (haveanswer) {
	X		*ap = NULL;
	X#if BSD >= 43 || defined(h_addr)	/* new-style hostent structure */
	X		*hap = NULL;
	X#endif
	X		host.h_addr = h_addr_ptrs[0];
	X		return (&host);
	X	} else {
	X		h_errno = TRY_AGAIN;
	X		return ((struct hostent *) NULL);
	X	}
	X}
	X
	Xstruct hostent *
	Xgethostbyname(name)
	X	char *name;
	X{
	X	querybuf buf;
	X	register char *cp;
	X	int n;
	X	struct hostent *hp;
	X	extern struct hostent *_gethtbyname();
	X
	X	if (name == NULL || *name == '\0') {
	X		h_errno = HOST_NOT_FOUND;
	X		return ((struct hostent *) NULL);
	X	}
	X
	X	/*
	X	 * disallow names consisting only of digits/dots, unless
	X	 * they end in a dot.
	X	 */
	X	if (isdigit(name[0]))
	X		for (cp = name;; ++cp) {
	X			if (!*cp) {
	X				if (*--cp == '.')
	X					break;
	X				h_errno = HOST_NOT_FOUND;
	X				return ((struct hostent *) NULL);
	X			}
	X			if (!isdigit(*cp) && *cp != '.') 
	X				break;
	X		}
	X
	X	if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
	X#ifdef DEBUG
	X		if (_res.options & RES_DEBUG)
	X			printf("res_search failed\n");
	X#endif
	X		if (errno == ECONNREFUSED)
	X			return (_gethtbyname(name));
	X		else
	X			return ((struct hostent *) NULL);
	X	}
	X	return (getanswer(&buf, n, 0));
	X}
	X
	Xstruct hostent *
	Xgethostbyaddr(addr, len, type)
	X	char *addr;
	X	int len, type;
	X{
	X	int n;
	X	querybuf buf;
	X	register struct hostent *hp;
	X	char qbuf[MAXDNAME];
	X	extern struct hostent *_gethtbyaddr();
	X	
	X	if (type != AF_INET)
	X		return ((struct hostent *) NULL);
	X	(void)sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa",
	X		((unsigned)addr[3] & 0xff),
	X		((unsigned)addr[2] & 0xff),
	X		((unsigned)addr[1] & 0xff),
	X		((unsigned)addr[0] & 0xff));
	X	n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf));
	X	if (n < 0) {
	X#ifdef DEBUG
	X		if (_res.options & RES_DEBUG)
	X			printf("res_query failed\n");
	X#endif
	X		if (errno == ECONNREFUSED)
	X			return (_gethtbyaddr(addr, len, type));
	X		return ((struct hostent *) NULL);
	X	}
	X	hp = getanswer(&buf, n, 1);
	X	if (hp == NULL)
	X		return ((struct hostent *) NULL);
	X	hp->h_addrtype = type;
	X	hp->h_length = len;
	X	h_addr_ptrs[0] = (char *)&host_addr;
	X	h_addr_ptrs[1] = (char *)0;
	X	host_addr = *(struct in_addr *)addr;
	X	return(hp);
	X}
	X
	X_sethtent(f)
	X	int f;
	X{
	X	if (hostf == NULL)
	X		hostf = fopen(HOSTDB, "r" );
	X	else
	X		rewind(hostf);
	X	stayopen |= f;
	X}
	X
	X_endhtent()
	X{
	X	if (hostf && !stayopen) {
	X		(void) fclose(hostf);
	X		hostf = NULL;
	X	}
	X}
	X
	Xstruct hostent *
	X_gethtent()
	X{
	X	char *p;
	X	register char *cp, **q;
	X
	X	if (hostf == NULL && (hostf = fopen(HOSTDB, "r" )) == NULL)
	X		return (NULL);
	Xagain:
	X	if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
	X		return (NULL);
	X	if (*p == '#')
	X		goto again;
	X	cp = any(p, "#\n");
	X	if (cp == NULL)
	X		goto again;
	X	*cp = '\0';
	X	cp = any(p, " \t");
	X	if (cp == NULL)
	X		goto again;
	X	*cp++ = '\0';
	X	/* THIS STUFF IS INTERNET SPECIFIC */
	X#if BSD >= 43 || defined(h_addr)	/* new-style hostent structure */
	X	host.h_addr_list = host_addrs;
	X#endif
	X	host.h_addr = hostaddr;
	X	*((u_long *)host.h_addr) = inet_addr(p);
	X	host.h_length = sizeof (u_long);
	X	host.h_addrtype = AF_INET;
	X	while (*cp == ' ' || *cp == '\t')
	X		cp++;
	X	host.h_name = cp;
	X	q = host.h_aliases = host_aliases;
	X	cp = any(cp, " \t");
	X	if (cp != NULL) 
	X		*cp++ = '\0';
	X	while (cp && *cp) {
	X		if (*cp == ' ' || *cp == '\t') {
	X			cp++;
	X			continue;
	X		}
	X		if (q < &host_aliases[MAXALIASES - 1])
	X			*q++ = cp;
	X		cp = any(cp, " \t");
	X		if (cp != NULL)
	X			*cp++ = '\0';
	X	}
	X	*q = NULL;
	X	return (&host);
	X}
	X
	Xstatic char *
	Xany(cp, match)
	X	register char *cp;
	X	char *match;
	X{
	X	register char *mp, c;
	X
	X	while (c = *cp) {
	X		for (mp = match; *mp; mp++)
	X			if (*mp == c)
	X				return (cp);
	X		cp++;
	X	}
	X	return ((char *)0);
	X}
	X
	Xstruct hostent *
	X_gethtbyname(name)
	X	char *name;
	X{
	X	register struct hostent *p;
	X	register char **cp;
	X	
	X	_sethtent(0);
	X	while (p = _gethtent()) {
	X		if (strcasecmp(p->h_name, name) == 0)
	X			break;
	X		for (cp = p->h_aliases; *cp != 0; cp++)
	X			if (strcasecmp(*cp, name) == 0)
	X				goto found;
	X	}
	Xfound:
	X	_endhtent();
	X	return (p);
	X}
	X
	Xstruct hostent *
	X_gethtbyaddr(addr, len, type)
	X	char *addr;
	X	int len, type;
	X{
	X	register struct hostent *p;
	X
	X	_sethtent(0);
	X	while (p = _gethtent())
	X#ifdef SYS5
	X		if (p->h_addrtype == type && !memcmp(p->h_addr, addr, len))
	X#else
	X		if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
	X#endif
	X			break;
	X	_endhtent();
	X	return (p);
	X}
SHAR_EOF
if test 8573 -ne "`wc -c < 'gethnamadr.c'`"
then
	echo shar: "error transmitting 'gethnamadr.c'" '(should have been 8573 characters)'
fi
fi
echo shar: "extracting 'sethostent.c'" '(698 characters)'
if test -f 'sethostent.c'
then
	echo shar: "will not over-write existing file 'sethostent.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'sethostent.c'
	X/*
	X * Copyright (c) 1985 Regents of the University of California.
	X * All rights reserved.  The Berkeley software License Agreement
	X * specifies the terms and conditions for redistribution.
	X */
	X
	X#if defined(LIBC_SCCS) && !defined(lint)
	Xstatic char sccsid[] = "@(#)sethostent.c	6.3 (Berkeley) 4/10/86";
	X#endif LIBC_SCCS and not lint
	X
	X#include <sys/types.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#endif
	X#include <arpa/nameser.h>
	X#include <netinet/in.h>
	X#include <resolv.h>
	X
	Xsethostent(stayopen)
	X{
	X	if (stayopen)
	X		_res.options |= RES_STAYOPEN | RES_USEVC;
	X}
	X
	Xendhostent()
	X{
	X	_res.options &= ~(RES_STAYOPEN | RES_USEVC);
	X	_res_close();
	X}
	X
	Xsethostfile(name)
	Xchar *name;
	X{
	X#ifdef lint
	Xname = name;
	X#endif
	X}
SHAR_EOF
if test 698 -ne "`wc -c < 'sethostent.c'`"
then
	echo shar: "error transmitting 'sethostent.c'" '(should have been 698 characters)'
fi
fi
echo shar: "done with directory 'named'"
cd ..
echo shar: "done with directory 'res'"
cd ..
echo shar: "extracting 'resolv.conf'" '(508 characters)'
if test -f 'resolv.conf'
then
	echo shar: "will not over-write existing file 'resolv.conf'"
else
sed 's/^	X//' << \SHAR_EOF > 'resolv.conf'
	X#
	X# Sample resolv.conf file
	X#
	X# First, your domain suffix. This suffix will be appended to any
	X# hostname that does not contain dots.
	Xdomain snort.edu
	X# Now, the internet addresses of the name servers you want
	X# to use. A good rule here is to query servers on your local net first
	X# and this query those else where. You can have up to three servers here.
	Xnameserver 55.0.0.1
	Xnameserver 135.0.0.2
	Xnameserver 195.0.0.3
	X# note: these are not real internet addreses. Replace them with the
	X# real information!
	X#
	X
SHAR_EOF
if test 508 -ne "`wc -c < 'resolv.conf'`"
then
	echo shar: "error transmitting 'resolv.conf'" '(should have been 508 characters)'
fi
fi
exit 0
#	End of shell archive
The MASSCOMP USERS' SOCIETY newsgroup is comp.sys.masscomp.
Articles to: masscomp@soma.bcm.tmc.edu or uunet!soma.bcm.tmc.edu!masscomp
Administrative stuff: masscomp-request@soma.bcm.tmc.edu
Stan Barber, Moderator