[comp.sys.masscomp] name server resolver library for MASSCOMP

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

If you are on the internet and want your Masscomp to understand the Domain
Name Service, here is the first step. This is the resolver library.
This code is based on BIND 4.8 with all patches to date.

Enjoy.


#! /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:
#	tools/Makefile.libc
#	tools/Makefile.resol
#	tools/installit
#	tools/makefile
#	tools/manroff
#	tools/mkdep
#	tools/nsquery.c
#	tools/nstest.c
# This archive created: Mon Jul  4 20:24:39 1988
export PATH; PATH=/bin:/usr/bin:$PATH
if test ! -d 'tools'
then
	echo shar: "creating directory 'tools'"
	mkdir 'tools'
fi
echo shar: "entering directory 'tools'"
cd 'tools'
echo shar: "extracting 'Makefile.libc'" '(1536 characters)'
if test -f 'Makefile.libc'
then
	echo shar: "will not over-write existing file 'Makefile.libc'"
else
sed 's/^	X//' << \SHAR_EOF > 'Makefile.libc'
	X#
	X# Copyright (c) 1987 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#	@(#)Makefile	4.7 (Berkeley) 4/6/88
	X#
	XSHELL=/bin/sh
	XCFLAGS=	-O -I../include
	XRES=	
	XLIBC=	/lib/libc.a
	XSRCS=	nsquery.c nstest.c
	XOBJS=	nsquery.o nstest.o
	X
	Xall: nsquery nstest nslookup
	X
	Xnsquery: ${LIBC}
	X	${CC} ${CFLAGS} -o $@ nsquery.c ${RES}
	X
	X# test programs and utilities
	Xnstest: ${LIBC}
	X	@echo "The resolver routines in libc must be compiled with the -DDEBUG"
	X	@echo "option or nstest will not have any output."
	X	${CC} ${CFLAGS}  -o $@ nstest.c ${RES}
	X
	Xnslookup: FRC
	X	cd nslookup; make ${MFLAGS} RES=${RES}
	X
	Xclean: FRC
	X	cd nslookup; make ${MFLAGS} clean
	X	rm -f ${OBJS} core nsquery nstest
	X
	Xdepend: FRC
	X	cd nslookup; make ${MFLAGS} depend
	X	./mkdep -p ${CFLAGS} ${SRCS}
	X
	Xinstall: FRC
	X	cd nslookup; make ${MFLAGS} DESTDIR=${DESTDIR} install
	X
	Xlint: FRC
	X	cd nslookup; make ${MFLAGS} lint
	X	lint ${CFLAGS} ${SRCS}
	X
	Xtags: FRC
	X	cd nslookup; make ${MFLAGS} tags
	X	ctags ${SRCS}
	X
	XFRC:
	X
	X# DO NOT DELETE THIS LINE -- mkdep uses it.
	X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
	X
	Xnsquery.c:
	Xnstest.c:
	X
	X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
SHAR_EOF
if test 1536 -ne "`wc -c < 'Makefile.libc'`"
then
	echo shar: "error transmitting 'Makefile.libc'" '(should have been 1536 characters)'
fi
fi
echo shar: "extracting 'Makefile.resol'" '(1617 characters)'
if test -f 'Makefile.resol'
then
	echo shar: "will not over-write existing file 'Makefile.resol'"
else
sed 's/^	X//' << \SHAR_EOF > 'Makefile.resol'
	X#
	X# Copyright (c) 1987 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#	@(#)Makefile	4.7 (Berkeley) 4/6/88
	X#
	XSHELL=/bin/sh
	XCFLAGS=	-O -DEXOS -DSYS5 -I../include -I/usr/include/NET-5000
	XRES=	../res/libresolv.a
	XLIBS=	-lsocket
	XLIBC=	/lib/libc.a
	XSRCS=	nsquery.c nstest.c
	XOBJS=	nsquery.o nstest.o
	X
	Xall: nsquery nstest nslookup
	X
	Xnsquery: ${LIBC}
	X	${CC} ${CFLAGS} -o $@ nsquery.c ${RES}
	X
	X# test programs and utilities
	Xnstest: ${LIBC}
	X	@echo "The resolver routines in libresolv.a must be compiled with the -DDEBUG"
	X	@echo "option or nstest will not have any output."
	X	${CC} ${CFLAGS}  -o $@ nstest.c ${RES}
	X
	Xnslookup: FRC
	X	cd nslookup; make ${MFLAGS} RES=../${RES}
	X
	Xclean: FRC
	X	cd nslookup; make ${MFLAGS} clean
	X	rm -f ${OBJS} core nsquery nstest
	X
	Xdepend: FRC
	X	cd nslookup; make ${MFLAGS} depend
	X	./mkdep -p ${CFLAGS} ${SRCS}
	X
	Xinstall: FRC
	X	cd nslookup; make ${MFLAGS} DESTDIR=${DESTDIR} install
	X
	Xlint: FRC
	X	cd nslookup; make ${MFLAGS} lint
	X	lint ${CFLAGS} ${SRCS}
	X
	Xtags: FRC
	X	cd nslookup; make ${MFLAGS} tags
	X	ctags ${SRCS}
	X
	XFRC:
	X
	X# DO NOT DELETE THIS LINE -- mkdep uses it.
	X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
	X
	Xnsquery.c:
	Xnstest.c:
	X
	X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
SHAR_EOF
if test 1617 -ne "`wc -c < 'Makefile.resol'`"
then
	echo shar: "error transmitting 'Makefile.resol'" '(should have been 1617 characters)'
fi
fi
echo shar: "extracting 'installit'" '(1284 characters)'
if test -f 'installit'
then
	echo shar: "will not over-write existing file 'installit'"
else
sed 's/^	X//' << \SHAR_EOF > 'installit'
	X#! /bin/sh
	X#
	X#	'@(#)installit	2.4	10/15/87'
	X#	From install.sh	4.8	(Berkeley)	3/6/86
	X#	on the 4.3 BSD distribution (with permission)
	X#
	XPATH=/bin:/etc:/usr/bin:/usr/ucb
	Xexport PATH
	Xcmd=""
	Xstripbefore=""
	Xstripafter=""
	Xchmod="chmod 755"
	Xchown="#"
	Xchgrp="#"
	Xwhile true ; do
	X	case $1 in
	X		-s )	if test $cmd 
	X			then	stripafter="strip"
	X			else	stripbefore="strip"
	X			fi
	X			shift
	X			;;
	X		-c )	if test $cmd 
	X			then	echo "install: multiple specifications of -c"
	X				exit 1
	X			fi
	X			cmd="cp"
	X			stripafter=$stripbefore
	X			stripbefore=""
	X			shift
	X			;;
	X		-m )	chmod="chmod $2"
	X			shift
	X			shift
	X			;;
	X		-o )	chown="chown $2"
	X			shift
	X			shift
	X			;;
	X		-g )	chgrp="chgrp $2"
	X			shift
	X			shift
	X			;;
	X		* )	break
	X			;;
	X	esac
	Xdone
	Xif test $cmd 
	Xthen true
	Xelse cmd="mv"
	Xfi
	X
	Xif test ! ${2-""} 
	Xthen	echo "install: no destination specified"
	X	exit 1
	Xfi
	Xif test ${3-""} 
	Xthen	echo "install: too many files specified -> $*"
	X	exit 1
	Xfi
	Xif test $1 = $2 -o $2 = . 
	Xthen	echo "install: can't move $1 onto itself"
	X	exit 1
	Xfi
	Xif test '!' -f $1 
	Xthen	echo "install: can't open $1"
	X	exit 1
	Xfi
	Xif test -d $2 
	Xthen	file=$2/`basename $1`
	Xelse	file=$2
	Xfi
	X/bin/rm -f $file
	Xif test $stripbefore 
	Xthen	$stripbefore $1
	Xfi
	X$cmd $1 $file
	Xif test $stripafter 
	Xthen	$stripafter $file
	Xfi
	X$chown $file
	X$chgrp $file
	X$chmod $file
SHAR_EOF
if test 1284 -ne "`wc -c < 'installit'`"
then
	echo shar: "error transmitting 'installit'" '(should have been 1284 characters)'
fi
chmod +x 'installit'
fi
echo shar: "extracting 'makefile'" '(1589 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) 1987 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#	@(#)Makefile	4.7 (Berkeley) 4/6/88
	X#
	XSHELL=/bin/sh
	XCFLAGS=	-O -DSYS5 -DMASSCOMP -I../include
	XRES=	../res/libresolv.a
	XLIBS=	
	XLIBC=	/lib/libc.a
	XSRCS=	nsquery.c nstest.c
	XOBJS=	nsquery.o nstest.o
	X
	Xall: nsquery nstest nslookup
	X
	Xnsquery: ${LIBC}
	X	${CC} ${CFLAGS} -o $@ nsquery.c ${RES}
	X
	X# test programs and utilities
	Xnstest: ${LIBC}
	X	@echo "The resolver routines in libresolv.a must be compiled with the -DDEBUG"
	X	@echo "option or nstest will not have any output."
	X	${CC} ${CFLAGS}  -o $@ nstest.c ${RES}
	X
	Xnslookup: FRC
	X	cd nslookup; make ${MFLAGS} RES=../${RES}
	X
	Xclean: FRC
	X	cd nslookup; make ${MFLAGS} clean
	X	rm -f ${OBJS} core nsquery nstest
	X
	Xdepend: FRC
	X	cd nslookup; make ${MFLAGS} depend
	X	./mkdep -p ${CFLAGS} ${SRCS}
	X
	Xinstall: FRC
	X	cd nslookup; make ${MFLAGS} DESTDIR=${DESTDIR} install
	X
	Xlint: FRC
	X	cd nslookup; make ${MFLAGS} lint
	X	lint ${CFLAGS} ${SRCS}
	X
	Xtags: FRC
	X	cd nslookup; make ${MFLAGS} tags
	X	ctags ${SRCS}
	X
	XFRC:
	X
	X# DO NOT DELETE THIS LINE -- mkdep uses it.
	X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
	X
	Xnsquery.c:
	Xnstest.c:
	X
	X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
SHAR_EOF
if test 1589 -ne "`wc -c < 'makefile'`"
then
	echo shar: "error transmitting 'makefile'" '(should have been 1589 characters)'
fi
fi
echo shar: "extracting 'manroff'" '(29 characters)'
if test -f 'manroff'
then
	echo shar: "will not over-write existing file 'manroff'"
else
sed 's/^	X//' << \SHAR_EOF > 'manroff'
	X#! /bin/sh
	X
	Xnroff -man -h $*
SHAR_EOF
if test 29 -ne "`wc -c < 'manroff'`"
then
	echo shar: "error transmitting 'manroff'" '(should have been 29 characters)'
fi
chmod +x 'manroff'
fi
echo shar: "extracting 'mkdep'" '(1788 characters)'
if test -f 'mkdep'
then
	echo shar: "will not over-write existing file 'mkdep'"
else
sed 's/^	X//' << \SHAR_EOF > 'mkdep'
	X#!/bin/sh -
	X#
	X# Copyright (c) 1987 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#	@(#)mkdep.sh	5.9 (Berkeley) 1/1/88
	X#
	X
	XPATH=/bin:/usr/bin:/usr/ucb
	Xexport PATH
	X
	XMAKE=Makefile			# default makefile name is "Makefile"
	X
	Xwhile :
	X	do case "$1" in
	X		# -f allows you to select a makefile name
	X		-f)
	X			MAKE=$2
	X			shift; shift ;;
	X
	X		# the -p flag produces "program: program.c" style dependencies
	X		# so .o's don't get produced
	X		-p)
	X			SED='-e s;\.o;;'
	X			shift ;;
	X		*)
	X			break ;;
	X	esac
	Xdone
	X
	Xif [ $# = 0 ] ; then
	X	echo 'usage: mkdep [-p] [-f makefile] [flags] file ...'
	X	exit 1
	Xfi
	X
	Xif [ ! -w $MAKE ]; then
	X	echo "mkdep: no writeable file \"$MAKE\""
	X	exit 1
	Xfi
	X
	XTMP=/tmp/mkdep$$
	X
	Xtrap 'rm -f $TMP ; exit 1' 1 2 3 13 15
	X
	Xcp $MAKE ${MAKE}.bak
	X
	Xsed -e '/DO NOT DELETE THIS LINE/,$d' < $MAKE > $TMP
	X
	Xcat << _EOF_ >> $TMP
	X# DO NOT DELETE THIS LINE -- mkdep uses it.
	X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
	X
	X_EOF_
	X
	Xcc -M $* | /bin/sed -e "s; \./; ;g" $SED | \
	X	awk ' { \
	X		if ($1 != prev) { \
	X			if (rec != "") \
	X				print rec; rec = $0; prev = $1; \
	X		} \
	X		else { \
	X			if (length(rec $2) > 78) { \
	X				print rec; rec = $0; \
	X			} else \
	X				rec = rec " " $2 \
	X		} \
	X	} \
	X	END { \
	X		print rec \
	X	} ' >> $TMP
	X
	Xcat << _EOF_ >> $TMP
	X
	X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
	X_EOF_
	X
	X# copy to preserve permissions
	Xcp $TMP $MAKE
	Xrm -f ${MAKE}.bak $TMP
	Xexit 0
SHAR_EOF
if test 1788 -ne "`wc -c < 'mkdep'`"
then
	echo shar: "error transmitting 'mkdep'" '(should have been 1788 characters)'
fi
chmod +x 'mkdep'
fi
echo shar: "extracting 'nsquery.c'" '(1270 characters)'
if test -f 'nsquery.c'
then
	echo shar: "will not over-write existing file 'nsquery.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'nsquery.c'
	X#ifndef lint
	Xstatic char sccsid[] = "@(#)nsquery.c	4.2 (Berkeley) 11/21/87";
	X#endif
	X
	X/*
	X * Copyright (c) 1986 Regents of the University of California
	X *	All Rights Reserved
	X */
	X
	X#include <stdio.h>
	X#include <sys/types.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#endif
	X#include <arpa/nameser.h>
	X#include <netdb.h>
	X
	X#include <sys/socket.h>
	X#include <netinet/in.h>
	X#include <resolv.h>
	X
	Xstruct state orig;
	Xextern struct state _res;
	Xextern int h_errno;
	X
	Xmain(c, v)
	X	char **v;
	X{
	X	char h[32];
	X	register struct hostent *hp;
	X	register char *s;
	X
	X	gethostname(h, 32);
	X	s = h;
	X	if (c < 2) {
	X		fprintf(stderr, "Usage: lookup host [server]\n");
	X		exit(1);
	X	}
	X	if (c > 2)
	X		s = v[2];
	X
	X	hp = gethostbyname(s);
	X	if (hp == NULL) {
	X		herror(h_errno);
	X		exit(1);
	X	}
	X	printanswer(hp);
	X
	X	_res.nsaddr.sin_addr = *(struct in_addr *)hp->h_addr;
	X	_res.options &= ~RES_DEFNAMES;
	X
	X	hp = gethostbyname(v[1]);
	X	if (hp == NULL) {
	X		herror(h_errno);
	X		exit(1);
	X	}
	X	printanswer(hp);
	X	exit(0);
	X}
	X
	Xprintanswer(hp)
	X	register struct hostent *hp;
	X{
	X	register char **cp;
	X	extern char *inet_ntoa();
	X
	X	printf("Name: %s\n", hp->h_name);
	X	printf("Address: %s\n", inet_ntoa(*(struct in_addr *)hp->h_addr));
	X	printf("Aliases:");
	X	for (cp = hp->h_aliases; cp && *cp && **cp; cp++)
	X		printf(" %s", *cp);
	X	printf("\n\n");
	X}
SHAR_EOF
if test 1270 -ne "`wc -c < 'nsquery.c'`"
then
	echo shar: "error transmitting 'nsquery.c'" '(should have been 1270 characters)'
fi
fi
echo shar: "extracting 'nstest.c'" '(8264 characters)'
if test -f 'nstest.c'
then
	echo shar: "will not over-write existing file 'nstest.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'nstest.c'
	X#ifndef lint
	Xstatic char sccsid[] = "@(#)nstest.c	4.6 (Berkeley) 12/7/86";
	X#endif
	X
	X/*
	X * Copyright (c) 1986 Regents of the University of California
	X *	All Rights Reserved
	X */
	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
	Xextern char *inet_ntoa();
	Xchar *progname;
	XFILE *log;
	X#define MAXDATA		256   /* really should get definition from named/db.h */
	Xmain(argc, argv)
	X	char **argv;
	X{
	X	register char *cp;
	X	struct hostent *hp;
	X	short port = htons(NAMESERVER_PORT);
	X	char buf[BUFSIZ];
	X	char packet[PACKETSZ];
	X	char answer[PACKETSZ];
	X	struct rrec NewRR;
	X	char OldRRData[MAXDATA];
	X	int n, dump_packet;
	X
	X	NewRR.r_data = (char *) malloc(MAXDATA);
	X	NewRR.r_data = (char *) malloc(MAXDATA);
	X	progname = argv[0];
	X	dump_packet = 0;
	X	_res.options |= RES_DEBUG|RES_RECURSE;
	X	while (argc > 1 && argv[1][0] == '-') {
	X		argc--;
	X		cp = *++argv;
	X		while (*++cp)
	X			switch (*cp) {
	X			case 'p':
	X				if (--argc <= 0)
	X					usage();
	X				port = htons(atoi(*++argv));
	X				break;
	X
	X			case 'i':
	X				_res.options |= RES_IGNTC;
	X				break;
	X
	X			case 'v':
	X				_res.options |= RES_USEVC|RES_STAYOPEN;
	X				break;
	X
	X			case 'r':
	X				_res.options &= ~RES_RECURSE;
	X				break;
	X
	X			case 'd':
	X				dump_packet++;
	X				break;
	X
	X			default:
	X				usage();
	X			}
	X	}
	X	_res.nsaddr.sin_family = AF_INET;
	X	_res.nsaddr.sin_addr.s_addr = INADDR_ANY;
	X	_res.nsaddr.sin_port = port;
	X 	if (argc > 1)
	X 		_res.nsaddr.sin_addr.s_addr = inet_addr(argv[1]);
	X 	if (argc > 2) {
	X 		log = fopen(argv[2],"w");
	X 		if (log == NULL) perror(argv[2]);
	X 	}
	X	for (;;) {
	X		printf("> ");
	X		fflush(stdout);
	X		if ((cp = (char *)gets(buf)) == NULL)
	X			break;
	X		switch (*cp++) {
	X		case 'a':
	X			n = res_mkquery(QUERY, cp, C_ANY, T_A, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'A':
	X			n = ntohl(inet_addr(cp));
	X			putlong(n, cp);
	X			n = res_mkquery(IQUERY, "", C_IN, T_A, cp, sizeof(long),
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'f':
	X			n = res_mkquery(QUERY, cp, C_ANY, T_UINFO, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'g':
	X			n = res_mkquery(QUERY, cp, C_ANY, T_GID, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'G':
	X			*(int *)cp = htonl(atoi(cp));
	X			n = res_mkquery(IQUERY, "", C_ANY, T_GID, cp,
	X				sizeof(int), NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'c':
	X			n = res_mkquery(QUERY, cp, C_IN, T_CNAME, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'h':
	X			n = res_mkquery(QUERY, cp, C_IN, T_HINFO, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'm':
	X			n = res_mkquery(QUERY, cp, C_IN, T_MX, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'M':
	X			n = res_mkquery(QUERY, cp, C_IN, T_MAILB, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'n':
	X			n = res_mkquery(QUERY, cp, C_IN, T_NS, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'p':
	X			n = res_mkquery(QUERY, cp, C_IN, T_PTR, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 's':
	X			n = res_mkquery(QUERY, cp, C_IN, T_SOA, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'u':
	X			n = res_mkquery(QUERY, cp, C_ANY, T_UID, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'U':
	X			*(int *)cp = htonl(atoi(cp));
	X			n = res_mkquery(IQUERY, "", C_ANY, T_UID, cp,
	X				sizeof(int), NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'x':
	X			n = res_mkquery(QUERY, cp, C_IN, T_AXFR, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'w':
	X			n = res_mkquery(QUERY, cp, C_IN, T_WKS, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'b':
	X			n = res_mkquery(QUERY, cp, C_IN, T_MB, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'B':
	X			n = res_mkquery(QUERY, cp, C_IN, T_MG, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'i':
	X			n = res_mkquery(QUERY, cp, C_IN, T_MINFO, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'r':
	X			n = res_mkquery(QUERY, cp, C_IN, T_MR, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X		case '*':
	X			n = res_mkquery(QUERY, cp, C_IN, T_ANY, (char *)0, 0,
	X				NULL, packet, sizeof(packet));
	X			break;
	X
	X#ifdef ALLOW_UPDATES
	X		case '^':
	X			{
	X			    char IType[10], TempStr[50];
	X			    int Type, oldnbytes, nbytes, i;
	X#ifdef ALLOW_T_UNSPEC
	X			    printf("Data type (a = T_A, u = T_UNSPEC): ");
	X			    gets(IType);
	X			    if (IType[0] == 'u') {
	X			    	Type = T_UNSPEC;
	X			    	printf("How many data bytes? ");
	X			    	gets(TempStr); /* Throw away CR */
	X			    	sscanf(TempStr, "%d", &nbytes);
	X			    	for (i = 0; i < nbytes; i++) {
	X			    		(NewRR.r_data)[i] = (char) i;
	X			    	}
	X			    } else {
	X#endif ALLOW_T_UNSPEC
	X			    	Type = T_A;
	X			    	nbytes = sizeof(u_long);
	X			    	printf("Inet addr for new dname (e.g., 192.4.3.2): ");
	X			    	gets(TempStr);
	X			    	putlong(ntohl(inet_addr(TempStr)), NewRR.r_data);
	X#ifdef ALLOW_T_UNSPEC
	X			    }
	X#endif ALLOW_T_UNSPEC
	X			    NewRR.r_class = C_IN;
	X			    NewRR.r_type = Type;
	X			    NewRR.r_size = nbytes;
	X			    NewRR.r_ttl = 99999999;
	X			    printf("Add, modify, or modify all (a/m/M)? ");
	X			    gets(TempStr);
	X			    if (TempStr[0] == 'a') {
	X			    	n = res_mkquery(UPDATEA, cp, C_IN, Type,
	X			    			OldRRData, nbytes,
	X			    			&NewRR, packet,
	X			    			sizeof(packet));
	X			    } else {
	X			    	if (TempStr[0] == 'm') {
	X			    	    printf("How many data bytes in old RR? ");
	X			    	    gets(TempStr); /* Throw away CR */
	X			    	    sscanf(TempStr, "%d", &oldnbytes);
	X				    for (i = 0; i < oldnbytes; i++) {
	X					    OldRRData[i] = (char) i;
	X				    }
	X					n = res_mkquery(UPDATEM, cp, C_IN, Type,
	X							OldRRData, oldnbytes,
	X							&NewRR, packet,
	X							sizeof(packet));
	X				} else { /* Modify all */
	X					n = res_mkquery(UPDATEMA, cp,
	X							C_IN, Type, NULL, 0,
	X							&NewRR, packet,
	X							sizeof(packet));
	X
	X				}
	X			    }
	X			}
	X			break;
	X
	X#ifdef ALLOW_T_UNSPEC
	X		case 'D':
	X			n = res_mkquery(UPDATEDA, cp, C_IN, T_UNSPEC, (char *)0,
	X					0, NULL, packet, sizeof(packet));
	X			break;
	X
	X		case 'd':
	X			{
	X				char TempStr[100];
	X				int nbytes, i;
	X				printf("How many data bytes in oldrr data? ");
	X				gets(TempStr); /* Throw away CR */
	X				sscanf(TempStr, "%d", &nbytes);
	X				for (i = 0; i < nbytes; i++) {
	X					OldRRData[i] = (char) i;
	X				}
	X				n = res_mkquery(UPDATED, cp, C_IN, T_UNSPEC,
	X						OldRRData, nbytes, NULL, packet,
	X						sizeof(packet));
	X			}
	X			break;
	X#endif ALLOW_T_UNSPEC
	X#endif ALLOW_UPDATES
	X
	X		default:
	X			printf("a{host} - query  T_A\n");
	X			printf("A{addr} - iquery T_A\n");
	X			printf("b{user} - query  T_MB\n");
	X			printf("B{user} - query  T_MG\n");
	X			printf("f{host} - query  T_UINFO\n");
	X			printf("g{host} - query  T_GID\n");
	X			printf("G{gid}  - iquery T_GID\n");
	X			printf("h{host} - query  T_HINFO\n");
	X			printf("i{host} - query  T_MINFO\n");
	X			printf("p{host} - query  T_PTR\n");
	X			printf("m{host} - query  T_MX\n");
	X			printf("M{host} - query  T_MAILB\n");
	X			printf("n{host} - query  T_NS\n");
	X			printf("r{host} - query  T_MR\n");
	X			printf("s{host} - query  T_SOA\n");
	X			printf("u{host} - query  T_UID\n");
	X			printf("U{uid}  - iquery T_UID\n");
	X			printf("x{host} - query  T_AXFR\n");
	X			printf("w{host} - query  T_WKS\n");
	X			printf("c{host} - query  T_CNAME\n");
	X			printf("*{host} - query  T_ANY\n");
	X#ifdef ALLOW_UPDATES
	X			printf("^{host} - add/mod/moda    (T_A/T_UNSPEC)\n");
	X#ifdef ALLOW_T_UNSPEC
	X			printf("D{host} - deletea T_UNSPEC\n");
	X			printf("d{host} - delete T_UNSPEC\n");
	X#endif ALLOW_T_UNSPEC
	X#endif ALLOW_UPDATES
	X			continue;
	X		}
	X		if (n < 0) {
	X			printf("res_mkquery: buffer too small\n");
	X			continue;
	X		}
	X		if (log) {
	X			fprintf(log,"SEND QUERY\n");
	X			fp_query(packet, log);
	X		}
	X		n = res_send(packet, n, answer, sizeof(answer));
	X		if (n < 0) {
	X			printf("res_send: send error\n");
	X			if (log) fprintf(log, "res_send: send error\n");
	X		}
	X		else {
	X			if (dump_packet) {
	X				int f;
	X				f = creat("ns_packet.dump", 0644);
	X				write(f, answer, n);
	X				(void) close(f);
	X			}
	X			if (log) {
	X				fprintf(log, "GOT ANSWER\n");
	X				fp_query(answer, log);
	X			}
	X		}
	X	}
	X}
	X
	Xusage()
	X{
	X	fprintf(stderr, "Usage: %s [-v] [-i] [-r] [-d] [-p port] hostaddr\n",
	X		progname);
	X	exit(1);
	X}
SHAR_EOF
if test 8264 -ne "`wc -c < 'nstest.c'`"
then
	echo shar: "error transmitting 'nstest.c'" '(should have been 8264 characters)'
fi
fi
exit 0
#	End of shell archive

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

If you are on the internet and want your Masscomp to understand the Domain
Name Service, here is the first step. This is the resolver library.
This code is based on BIND 4.8 with all patches to date.

Enjoy.

#! /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:
#	tools/nslookup/Makefile
#	tools/nslookup/commands.l
#	tools/nslookup/debug.c
#	tools/nslookup/getinfo.c
# This archive created: Mon Jul  4 20:27:53 1988
export PATH; PATH=/bin:/usr/bin:$PATH
if test ! -d 'tools'
then
	echo shar: "creating directory 'tools'"
	mkdir 'tools'
fi
echo shar: "entering directory 'tools'"
cd 'tools'
if test ! -d 'nslookup'
then
	echo shar: "creating directory 'nslookup'"
	mkdir 'nslookup'
fi
echo shar: "entering directory 'nslookup'"
cd 'nslookup'
echo shar: "extracting 'Makefile'" '(1666 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) 1987 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#	from @(#)Makefile	5.16 (Berkeley) 2/20/88
	X#
	XSHELL=/bin/sh
	XCFLAGS=	-O -DSYS5 -DEXOS -I../../include -I/usr/include/NET-5000
	XRES=	../../res/libresolv.a
	XLIBC=	/lib/libc.a
	XLIBS=	-ll ${RES} -lsocket
	XCSRCS=	main.c getinfo.c debug.c send.c skip.c list.c subr.c
	XSRCS=	${CSRCS} commands.c
	XOBJS=	main.o getinfo.o debug.o send.o skip.o list.o subr.o commands.o
	X
	X.SUFFIXES: .1 .0
	X
	X.1.0:
	X	../manroff $*.1 > $*.0
	X
	Xnslookup: ${OBJS} ${LIBC}
	X	${CC} -o $@ ${OBJS} ${LIBS}
	X
	Xclean: FRC
	X	rm -f ${OBJS} core nslookup commands.c nslookup.0 lex.yy.c lex.yy.o
	X
	Xdepend: ${SRCS} FRC
	X	../mkdep ${CFLAGS} ${SRCS}
	X
	Xinstall: nslookup.0 FRC
	X	../installit -s -o bin -g bin -m 755 nslookup ${DESTDIR}/usr/local/nslookup
	X	../installit -c -o bin -g bin -m 444 nslookup.help ${DESTDIR}/usr/local/nslookup.help
	X	../installit -c -o bin -g bin -m 444 nslookup.0 ${DESTDIR}/usr/local/man/cat1/nslookup.0
	X
	Xlint: ${SRCS} FRC
	X	lint ${CFLAGS} ${SRCS}
	X
	Xtags: ${CSRCS} FRC
	X	ctags ${CSRCS}
	X
	XFRC:
	X
	X# DO NOT DELETE THIS LINE -- mkdep uses it.
	X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
	X
	Xmain.c:
	Xgetinfo.c:
	Xdebug.c:
	Xsend.c:
	Xskip.c:
	Xlist.c:
	Xsubr.c:
	Xcommands.c:
	X
	X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
SHAR_EOF
if test 1666 -ne "`wc -c < 'Makefile'`"
then
	echo shar: "error transmitting 'Makefile'" '(should have been 1666 characters)'
fi
fi
echo shar: "extracting 'commands.l'" '(3974 characters)'
if test -f 'commands.l'
then
	echo shar: "will not over-write existing file 'commands.l'"
else
sed 's/^	X//' << \SHAR_EOF > 'commands.l'
	X%{
	X/*
	X *******************************************************************************
	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 *	@(#)commands.l	5.6 (Berkeley) 11/20/87
	X *
	X *  commands.l
	X *
	X *  	Andrew Cherenson 	CS298-26  Fall 1985
	X *
	X *	Lex input file for the nslookup program command interpreter.
	X *	When a sequence is recognized, the associated action
	X *	routine is called. The action routine may need to
	X *	parse the string for additional information.
	X *
	X *  Recognized commands: (identifiers are shown in uppercase)
	X *
	X *	server NAME	- set default server to NAME, using default server
	X *	lserver NAME	- set default server to NAME, using initial server
	X *	finger [NAME]	- finger the optional NAME
	X *	root		- set default server to the root
	X *	ls NAME		- list the domain NAME
	X *	view FILE	- sorts and view the file with more
	X *	set OPTION	- set an option
	X *	help 		- print help information
	X *	? 		- print help information
	X *	opt[ions]	- print options, current server, host
	X *	NAME		- print info about the host/domain NAME 
	X *			  using default server.
	X *	NAME1 NAME2	- as above, but use NAME2 as server
	X *
	X *
	X *   yylex Results:
	X *	0		upon end-of-file.
	X *	1		after each command.
	X *  
	X *******************************************************************************
	X */
	X
	X#include "res.h"
	Xextern char rootServerName[];
	X
	X%}
	XWS	[ \t]
	XLET	[A-Za-z0-9.*]
	XNAME	[A-Za-z0-9.*=_/-]
	X%%
	X^{WS}*server{WS}+{LET}{NAME}*{WS}*$ 	{ 
	X					    /* 
	X					     * 0 == use current server to find
	X					     *	    the new one.
	X					     * 1 == use original server to find
	X					     *	    the new one.
	X					     */
	X					    SetDefaultServer(yytext, 0); 
	X					    return(1);
	X					}
	X^{WS}*lserver{WS}+{LET}{NAME}*{WS}*$ 	{ 
	X					    SetDefaultServer(yytext, 1); 
	X					    return(1);
	X					}
	X^{WS}*root{WS}*$ 			{ 
	X					    SetDefaultServer(rootServerName, 1);
	X					    return(1);
	X					}
	X^{WS}*finger({WS}+{LET}{NAME}*)?{WS}+>>?{WS}*{NAME}+{WS}*$ 	{
	X					    /* 
	X					     * 2nd arg. 
	X					     *  0 == output to stdout
	X					     *  1 == output to file
	X					     */
	X					    Finger(yytext, 1); 
	X					    return(1);
	X					}
	X^{WS}*finger({WS}+{LET}{NAME}*)?{WS}*$ 	{ 
	X					    Finger(yytext, 0); 
	X					    return(1);
	X					}
	X^{WS}*view{WS}+{NAME}+{WS}*$ 	{ 
	X					    ViewList(yytext); 
	X					    return(1);
	X					}
	X^{WS}*ls{WS}+(("-a"|"-h"|"-m"|"-s"|"-d"){WS}+)?{LET}{NAME}*{WS}+>>?{WS}+{NAME}+{WS}*$	{ 
	X  					    /* 
	X  					     * 2nd arg. 
	X  					     *  0 == output to stdout
	X					     *  1 == output to file
	X					     */
	X					    ListHosts(yytext, 1);
	X					    return(1);
	X					}
	X^{WS}*ls{WS}+(("-a"|"-h"|"-m"|"-s"|"-d"){WS}+)?{LET}{NAME}*{WS}*$ 	{ 
	X					    ListHosts(yytext, 0);
	X					    return(1);
	X					}
	X^{WS}*set{WS}+{NAME}+{WS}*$	 	{ 
	X					    SetOption(yytext); 
	X					    return(1);
	X					}
	X^{WS}*help{WS}*$ 			{ 
	X					    extern void PrintHelp();
	X
	X					    PrintHelp();
	X					    return(1);
	X					}
	X^{WS}*"?"{WS}*$ 			{ 
	X					    PrintHelp();
	X					    return(1);
	X					}
	X^{WS}*opt(ions)?{WS}*$ 			{ 
	X					    ShowOptions(TRUE); 
	X					    return(1);
	X					}
	X^{WS}*{LET}{NAME}*{WS}+>>?{WS}*{NAME}+{WS}*$ 	{
	X					    /* 
	X					     * 0 == output to stdout
	X					     * 1 == output to file
	X					     */
	X					    LookupHost(yytext, 1); 
	X					    return(1);
	X					}
	X^{WS}*{LET}{NAME}*{WS}*$		{
	X					    LookupHost(yytext, 0); 
	X					    return(1);
	X					}
	X^{WS}*{LET}{NAME}*{WS}+{LET}{NAME}*{WS}+>>?{WS}*{NAME}+{WS}*$ 	{
	X					    /* 
	X					     * 0 == output to stdout
	X					     * 1 == output to file
	X					     */
	X					    LookupHostWithServer(yytext, 1); 
	X					    return(1);
	X					}
	X^{WS}*{LET}{NAME}*{WS}+{LET}{NAME}*{WS}*$	{
	X					    LookupHostWithServer(yytext, 0); 
	X					    return(1);
	X					}
	X^{WS}*\n				{ 
	X					    return(1);
	X					}
	X^.*\n					{ 
	X					    printf("Unrecognized command: %s", 
	X					    		yytext); 
	X					    return(1);
	X					}
	X\n					{ ; }
	X%%
SHAR_EOF
if test 3974 -ne "`wc -c < 'commands.l'`"
then
	echo shar: "error transmitting 'commands.l'" '(should have been 3974 characters)'
fi
fi
echo shar: "extracting 'debug.c'" '(8484 characters)'
if test -f 'debug.c'
then
	echo shar: "will not over-write existing file 'debug.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'debug.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#ifndef lint
	Xstatic char sccsid[] = "@(#)debug.c	5.11 (Berkeley) 4/5/88";
	X#endif /* not lint */
	X
	X/*
	X *******************************************************************************
	X *
	X *  debug.c --
	X *
	X *	Routines to print out packets received from a name server query.
	X *
	X *      Modified version of 4.3BSD BIND res_debug.c 5.6 9/14/85
	X *
	X *******************************************************************************
	X */
	X
	X#include <sys/types.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#endif
	X#include <netinet/in.h>
	X#include <stdio.h>
	X#include <arpa/nameser.h>
	X#include <resolv.h>
	X#include "res.h"
	X
	Xextern char ctime();
	X
	X/*
	X *  Imported from res_debug.c
	X */
	Xextern char *_res_resultcodes[];
	Xextern char *_res_opcodes[];
	X
	X/*
	X *  Used to highlight the start of a record when printing it.
	X */
	X#define INDENT "    ->  "
	X
	X
	X
	X/*
	X * Print the contents of a query.
	X * This is intended to be primarily a debugging routine.
	X */
	X
	XPrint_query(msg, eom, printHeader)
	X	char *msg, *eom;
	X	int printHeader;
	X{
	X	Fprint_query(msg, eom, printHeader,stdout);
	X}
	X
	XFprint_query(msg, eom, printHeader,file)
	X	char *msg, *eom;
	X	int printHeader;
	X	FILE *file;
	X{
	X	register char *cp;
	X	register HEADER *hp;
	X	register int n;
	X	short class;
	X	short type;
	X
	X	/*
	X	 * Print header fields.
	X	 */
	X	hp = (HEADER *)msg;
	X	cp = msg + sizeof(HEADER);
	X	if (printHeader || (_res.options & RES_DEBUG2)) {
	X	    fprintf(file,"    HEADER:\n");
	X	    fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
	X	    fprintf(file,", id = %d", ntohs(hp->id));
	X	    fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
	X	    fprintf(file,"\theader flags: ");
	X	    if (hp->qr) {
	X		    fprintf(file," response");
	X	    } else {
	X		    fprintf(file," query");
	X	    }
	X	    if (hp->aa)
	X		    fprintf(file,", auth. answer");
	X	    if (hp->tc)
	X		    fprintf(file,", truncation");
	X	    if (hp->rd)
	X		    fprintf(file,", want recursion");
	X	    if (hp->ra)
	X		    fprintf(file,", recursion avail.");
	X	    if (hp->pr)
	X		    fprintf(file,", primary");
	X	    fprintf(file,"\n\tquestions = %d", ntohs(hp->qdcount));
	X	    fprintf(file,",  answers = %d", ntohs(hp->ancount));
	X	    fprintf(file,",  auth. records = %d", ntohs(hp->nscount));
	X	    fprintf(file,",  additional = %d\n\n", ntohs(hp->arcount));
	X	}
	X
	X	/*
	X	 * Print question records.
	X	 */
	X	if (n = ntohs(hp->qdcount)) {
	X		fprintf(file,"    QUESTIONS:\n");
	X		while (--n >= 0) {
	X			fprintf(file,"\t");
	X			cp = Print_cdname(cp, msg, eom, file);
	X			if (cp == NULL)
	X				return;
	X			type = _getshort(cp);
	X			cp += sizeof(u_short);
	X			class = _getshort(cp);
	X			cp += sizeof(u_short);
	X			fprintf(file,", type = %s", p_type(type));
	X			fprintf(file,", class = %s\n", p_class(class));
	X		}
	X	}
	X	/*
	X	 * Print authoritative answer records
	X	 */
	X	if (n = ntohs(hp->ancount)) {
	X		fprintf(file,"    ANSWERS:\n");
	X		while (--n >= 0) {
	X			fprintf(file, INDENT);
	X			cp = Print_rr(cp, msg, eom, file);
	X			if (cp == NULL)
	X				return;
	X		}
	X	}
	X	/*
	X	 * print name server records
	X	 */
	X	if (n = ntohs(hp->nscount)) {
	X		fprintf(file,"    AUTHORITY RECORDS:\n");
	X		while (--n >= 0) {
	X			fprintf(file, INDENT);
	X			cp = Print_rr(cp, msg, eom, file);
	X			if (cp == NULL)
	X				return;
	X		}
	X	}
	X	/*
	X	 * print additional records
	X	 */
	X	if (n = ntohs(hp->arcount)) {
	X		fprintf(file,"    ADDITIONAL RECORDS:\n");
	X		while (--n >= 0) {
	X			fprintf(file, INDENT);
	X			cp = Print_rr(cp, msg, eom, file);
	X			if (cp == NULL)
	X				return;
	X		}
	X	}
	X	fprintf(file,"\n------------\n");
	X
	X}
	X
	X
	Xchar *
	XPrint_cdname_sub(cp, msg, eom, file, format)
	X	char *cp, *msg, *eom;
	X	FILE *file;
	X	int format;
	X{
	X	int n;
	X	char name[MAXDNAME];
	X	extern char *strcpy();
	X
	X	if ((n = dn_expand(msg, eom, cp, name, sizeof(name))) < 0)
	X		return (NULL);
	X	if (name[0] == '\0') {
	X	    (void) strcpy(name, "(root)");
	X	}
	X	if (format) {
	X	    fprintf(file, "%-30s", name);
	X	} else {
	X	    fputs(name, file);
	X	}
	X	return (cp + n);
	X}
	X
	Xchar *
	XPrint_cdname(cp, msg, eom, file)
	X	char *cp, *msg, *eom;
	X	FILE *file;
	X{
	X    return(Print_cdname_sub(cp, msg, eom, file, 0));
	X}
	X
	Xchar *
	XPrint_cdname2(cp, msg, eom, file)
	X	char *cp, *msg, *eom;
	X	FILE *file;
	X{
	X    return(Print_cdname_sub(cp, msg, eom, file, 1));
	X}
	X
	X/*
	X * Print resource record fields in human readable form.
	X */
	Xchar *
	XPrint_rr(cp, msg, eom, file)
	X	char *cp, *msg, *eom;
	X	FILE *file;
	X{
	X	int type, class, dlen, n, c;
	X	long ttl;
	X	struct in_addr inaddr;
	X	char *cp1;
	X
	X	if ((cp = Print_cdname(cp, msg, eom, file)) == NULL) {
	X		fprintf(file, "(name truncated?)\n");
	X		return (NULL);			/* compression error */
	X	}
	X
	X	type = _getshort(cp);
	X	cp += sizeof(u_short);
	X	class = _getshort(cp);
	X	cp += sizeof(u_short);
	X	ttl = _getlong(cp);
	X	cp += sizeof(u_long);
	X	dlen = _getshort(cp);
	X	cp += sizeof(u_short);
	X
	X	if (_res.options & RES_DEBUG2) {
	X	    fprintf(file,"\n\ttype = %s, class = %s, ttl = %u, dlen = %d",
	X			p_type(type), p_class(class), ttl, dlen);
	X	    fprintf(file,"\n");
	X	}
	X
	X	cp1 = cp;
	X
	X	/*
	X	 * Print type specific data, if appropriate
	X	 */
	X	switch (type) {
	X	case T_A:
	X		switch (class) {
	X		case C_IN:
	X#ifdef SYS5
	X			(void)memcpy((char *)&inaddr, cp, sizeof(inaddr));
	X#else
	X			bcopy(cp, (char *)&inaddr, sizeof(inaddr));
	X#endif
	X			if (dlen == 4) {
	X				fprintf(file,"\tinet address = %s\n",
	X					inet_ntoa(inaddr));
	X				cp += dlen;
	X			} else if (dlen == 7) {
	X				fprintf(file,"\tinet address = %s",
	X					inet_ntoa(inaddr));
	X				fprintf(file,", protocol = %d", cp[4]);
	X				fprintf(file,", port = %d\n",
	X					(cp[5] << 8) + cp[6]);
	X				cp += dlen;
	X			}
	X			break;
	X		default:
	X			fprintf(file,"\taddress, class = %d, len = %d\n",
	X			    class, dlen);
	X		}
	X		break;
	X
	X	case T_CNAME:
	X		fprintf(file,"\tcanonical name = ");
	X		goto doname;
	X
	X	case T_MX:
	X		fprintf(file,"\tpreference = %d",_getshort(cp));
	X		cp += sizeof(u_short);
	X		fprintf(file,", mail exchanger = ");
	X		goto doname;
	X
	X	case T_MG:
	X		fprintf(file,"\tmail group member = ");
	X		goto doname;
	X	case T_MB:
	X		fprintf(file,"\tmail box = ");
	X		goto doname;
	X	case T_MR:
	X		fprintf(file,"\tmailbox rename = ");
	X		goto doname;
	X	case T_NS:
	X		fprintf(file,"\tnameserver = ");
	X		goto doname;
	X	case T_PTR:
	X		fprintf(file,"\thost name = ");
	Xdoname:
	X		cp = Print_cdname(cp, msg, eom, file);
	X		fprintf(file,"\n");
	X		break;
	X
	X	case T_HINFO:
	X		if (n = *cp++) {
	X			fprintf(file,"\tCPU=%.*s", n, cp);
	X			cp += n;
	X		}
	X		if (n = *cp++) {
	X			fprintf(file,"\tOS=%.*s\n", n, cp);
	X			cp += n;
	X		}
	X		break;
	X
	X	case T_SOA:
	X		fprintf(file,"\torigin = ");
	X		cp = Print_cdname(cp, msg, eom, file);
	X		fprintf(file,"\n\tmail addr = ");
	X		cp = Print_cdname(cp, msg, eom, file);
	X		fprintf(file,"\n\tserial=%ld", _getlong(cp));
	X		cp += sizeof(u_long);
	X		fprintf(file,", refresh=%ld", _getlong(cp));
	X		cp += sizeof(u_long);
	X		fprintf(file,", retry=%ld", _getlong(cp));
	X		cp += sizeof(u_long);
	X		fprintf(file,", expire=%ld", _getlong(cp));
	X		cp += sizeof(u_long);
	X		fprintf(file,", min=%ld\n", _getlong(cp));
	X		cp += sizeof(u_long);
	X		break;
	X
	X	case T_MINFO:
	X		fprintf(file,"\trequests = ");
	X		cp = Print_cdname(cp, msg, eom, file);
	X		fprintf(file,"\n\terrors = ");
	X		cp = Print_cdname(cp, msg, eom, file);
	X		break;
	X
	X	case T_UINFO:
	X		fprintf(file,"\t%s\n", cp);
	X		cp += dlen;
	X		break;
	X
	X	case T_UID:
	X	case T_GID:
	X		if (dlen == 4) {
	X			fprintf(file,"\t%cid %ld\n", type == T_UID ? 'u' : 'g',
	X			    _getlong(cp));
	X			cp += sizeof(int);
	X		} else
	X			fprintf(file,"\t%cid of length %ld?\n",
	X			    type == T_UID ? 'u' : 'g', dlen);
	X		break;
	X
	X	case T_WKS:
	X		if (dlen < sizeof(u_long) + 1)
	X			break;
	X#ifdef SYS5
	X		(void)memcpy((char *)&inaddr, cp, sizeof(inaddr));
	X#else
	X		bcopy(cp, (char *)&inaddr, sizeof(inaddr));
	X#endif
	X		cp += sizeof(u_long);
	X		fprintf(file,"\tinet address = %s, protocol = %d\n\t",
	X			inet_ntoa(inaddr), *cp++);
	X		n = 0;
	X		while (cp < cp1 + dlen) {
	X			c = *cp++;
	X			do {
	X 				if (c & 0200)
	X					fprintf(file," %d", n);
	X 				c <<= 1;
	X			} while (++n & 07);
	X		}
	X		putc('\n',file);
	X		break;
	X
	X	case T_NULL:
	X		fprintf(file, "(type NULL, dlen %d)\n", dlen);
	X		break;
	X
	X	default:
	X		fprintf(file,"\t???\n");
	X		cp += dlen;
	X	}
	X	if (cp != cp1 + dlen)
	X		fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen);
	X	return (cp);
	X}
SHAR_EOF
if test 8484 -ne "`wc -c < 'debug.c'`"
then
	echo shar: "error transmitting 'debug.c'" '(should have been 8484 characters)'
fi
fi
echo shar: "extracting 'getinfo.c'" '(19262 characters)'
if test -f 'getinfo.c'
then
	echo shar: "will not over-write existing file 'getinfo.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'getinfo.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#ifndef lint
	Xstatic char sccsid[] = "@(#)getinfo.c	5.16 (Berkeley) 3/11/88";
	X#endif /* not lint */
	X
	X/*
	X *******************************************************************************
	X *
	X *  getinfo.c --
	X *
	X *	Routines to create requests to name servers 
	X *	and interpret the answers.
	X *
	X *	Adapted from 4.3BSD BIND gethostnamadr.c
	X *
	X *******************************************************************************
	X */
	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 <ctype.h>
	X#include <arpa/nameser.h>
	X#include <resolv.h>
	X#include "res.h"
	X
	Xextern char *_res_resultcodes[];
	Xextern char *res_skip();
	X
	X#define	MAXALIASES	35
	X#define MAXADDRS	35
	X#define MAXDOMAINS	35
	X#define MAXSERVERS	10
	X
	Xstatic char *addr_list[MAXADDRS + 1];
	X
	Xstatic char *host_aliases[MAXALIASES];
	Xstatic int   host_aliases_len[MAXALIASES];
	Xstatic char  hostbuf[BUFSIZ+1];
	X
	Xtypedef struct {
	X    char *name;
	X    char *domain[MAXDOMAINS];
	X    int   numDomains;
	X    char *address[MAXADDRS];
	X    int   numAddresses;
	X} ServerTable;
	X
	XServerTable server[MAXSERVERS];
	X
	Xtypedef union {
	X    HEADER qb1;
	X    char qb2[PACKETSZ];
	X} querybuf;
	X
	Xstatic union {
	X    long al;
	X    char ac;
	X} align;
	X
	X
	X/*
	X *******************************************************************************
	X *
	X *  GetAnswer --
	X *
	X *	Interprets an answer packet and retrieves the following
	X *	information:
	X *
	X *  Results:
	X *      SUCCESS         the info was retrieved.
	X *      NO_INFO         the packet did not contain an answer.
	X *	NONAUTH		non-authoritative information was found.
	X *      ERROR           the answer was malformed.
	X *      Other errors    returned in the packet header.
	X *
	X *******************************************************************************
	X */
	X
	Xstatic int
	XGetAnswer(nsAddrPtr, queryType, msg, msglen, iquery, hostPtr, isserver)
	X	struct in_addr 		*nsAddrPtr;
	X	char 			*msg;
	X	int 			queryType;
	X	int 			msglen;
	X	int 			iquery;
	X	register HostInfo 	*hostPtr;
	X	int			isserver;
	X{
	X	register HEADER 	*headerPtr;
	X	register char 		*cp;
	X	querybuf 		answer;
	X	char 			*eom, *bp, **aliasPtr;
	X	char 			**addrPtr;
	X	char			*namePtr;
	X	char			*dnamePtr;
	X	int 			type, class;
	X	int 			qdcount, ancount, arcount, nscount, buflen;
	X	int 			haveanswer, getclass;
	X	int 			numAliases = 0;
	X	int 			numAddresses = 0;
	X	int 			n, i, j;
	X	int 			len;
	X	int 			dlen;
	X	int 			status;
	X	int			numServers;
	X	int			found;
	X
	X
	X	/*
	X	 *  If the hostPtr was used before, free up 
	X	 *  the calloc'd areas.
	X	 */
	X	FreeHostInfoPtr(hostPtr);
	X	    
	X	status = SendRequest(nsAddrPtr, msg, msglen, (char *) &answer, 
	X				sizeof(answer), &n, !isserver);
	X
	X	if (status != SUCCESS) {
	X		if (_res.options & RES_DEBUG2)
	X			printf("SendRequest failed\n");
	X		return (status);
	X	}
	X	eom = (char *) &answer + n;
	X
	X	headerPtr = (HEADER *) &answer;
	X	qdcount = ntohs(headerPtr->qdcount);
	X	ancount = ntohs(headerPtr->ancount);
	X	arcount = ntohs(headerPtr->arcount);
	X	nscount = ntohs(headerPtr->nscount);
	X
	X	if (headerPtr->rcode != NOERROR) {
	X	    if (_res.options & RES_DEBUG && !isserver) {
	X		printf(
	X		"Failed: %s, num. answers = %d, ns = %d, additional = %d\n", 
	X			_res_resultcodes[headerPtr->rcode], ancount, nscount,
	X			arcount);
	X	    }
	X	    return (headerPtr->rcode);
	X	}
	X
	X	/*
	X	 * If there are no answer, n.s. or additional records 
	X	 * then return with an error.
	X	 */
	X	if (ancount == 0 && nscount == 0 && arcount == 0) {
	X	    return (NO_INFO);
	X	}
	X
	X
	X	bp 	= hostbuf;
	X	buflen 	= sizeof(hostbuf);
	X	cp 	= (char *) &answer + sizeof(HEADER);
	X
	X	/*
	X	 * For inverse queries, the desired information is returned
	X	 * in the question section. If there are no question records,
	X	 * return with an error.
	X	 *
	X	 */
	X	if (qdcount) {
	X	    if (iquery) {
	X		if ((n = dn_expand((char *)&answer, eom, cp, bp, buflen)) < 0) {
	X		    return (ERROR);
	X		}
	X		cp += n + QFIXEDSZ;
	X		len = strlen(bp) + 1;
	X		hostPtr->name = Calloc((unsigned)1, (unsigned)len);
	X#ifdef SYS5
	X		(void)memcpy(hostPtr->name, bp, len);
	X#else
	X		bcopy(bp, hostPtr->name, len);
	X#endif
	X	    } else {
	X		cp += dn_skipname(cp, eom) + QFIXEDSZ;
	X	    }
	X	    while (--qdcount > 0) {
	X		cp += dn_skipname(cp, eom) + QFIXEDSZ;
	X	    }
	X	} else if (iquery) {
	X	    return (NO_INFO);
	X	}
	X
	X	aliasPtr 	= host_aliases;
	X	addrPtr	 	= addr_list;
	X	haveanswer 	= 0;
	X
	X	/*
	X	 * Scan through the answer resource records.
	X	 * Answers for address query types are saved.
	X	 * Other query type answers are just printed.
	X	 */
	X	if (isserver == 0 && !headerPtr->aa && headerPtr->ancount)
	X	    printf("Non-authoritative answer:\n");
	X	while (--ancount >= 0 && cp < eom) {
	X	    if (queryType != T_A) {
	X		if ((cp = Print_rr(cp, (char *) &answer, eom, stdout)) == NULL) {
	X		    return(ERROR);
	X		}
	X		continue;
	X	    } else {
	X		if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) {
	X		    return(ERROR);
	X		}
	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		dlen = _getshort(cp);
	X		cp += sizeof(u_short);
	X		if (type == T_CNAME) {
	X		    /*
	X		     * Found an alias.
	X		     */
	X		    cp += dlen;
	X		    if (aliasPtr >= &host_aliases[MAXALIASES-1])
	X			    continue;
	X		    *aliasPtr++ = bp;
	X		    n = strlen(bp) + 1;
	X		    host_aliases_len[numAliases] = n;
	X		    numAliases++;
	X		    bp += n;
	X		    buflen -= n;
	X		    continue;
	X		} else if (type == T_PTR) {
	X		    /*
	X		     *  Found a "pointer" to the real name.
	X		     */
	X		    if((n= dn_expand((char *)&answer, eom, cp, bp, buflen)) < 0){
	X			cp += n;
	X			continue;
	X		    }
	X		    cp += n;
	X		    len = strlen(bp) + 1;
	X		    hostPtr->name = Calloc((unsigned)1, (unsigned)len);
	X#ifdef SYS5
	X		    (void)memcpy(hostPtr->name, bp, len);
	X#else
	X		    bcopy(bp, hostPtr->name, len);
	X#endif
	X		    haveanswer = 1;
	X		    break;
	X		} else if (type != T_A) {
	X		    cp += dlen;
	X		    continue;
	X		}
	X		if (haveanswer) {
	X		    if (n != hostPtr->addrLen) {
	X			cp += dlen;
	X			continue;
	X		    }
	X		    if (class != getclass) {
	X			cp += dlen;
	X			continue;
	X		    }
	X		} else {
	X		    hostPtr->addrLen = dlen;
	X		    getclass = class;
	X		    hostPtr->addrType = (class == C_IN) ? AF_INET : AF_UNSPEC;
	X		    if (!iquery) {
	X			len = strlen(bp) + 1;
	X			hostPtr->name = Calloc((unsigned)1, (unsigned)len);
	X#ifdef SYS5
	X			(void)memcpy(hostPtr->name, bp, len);
	X#else
	X			bcopy(bp, hostPtr->name, len);
	X#endif
	X		    }
	X		}
	X		bp += (((u_long)bp) % sizeof(align));
	X
	X		if (bp + dlen >= &hostbuf[sizeof(hostbuf)]) {
	X			if (_res.options & RES_DEBUG)
	X				printf("Size (%d) too big\n", dlen);
	X			break;
	X		}
	X#ifdef SYS5
	X		(void)memcpy(*addrPtr++ = bp, cp, dlen);
	X#else
	X		bcopy(cp, *addrPtr++ = bp, dlen);
	X#endif
	X		bp +=dlen;
	X		cp += dlen;
	X		numAddresses++;
	X		haveanswer = 1;
	X	    }
	X	}
	X
	X	if (queryType == T_A && haveanswer) {
	X
	X	    /*
	X	     *  Go through the alias and address lists and return them
	X	     *  in the hostPtr variable.
	X	     */
	X
	X	    if (numAliases > 0) {
	X		hostPtr->aliases = (char **) Calloc((unsigned)1+numAliases, 
	X							sizeof(char *));
	X		for (i = 0; i < numAliases; i++) {
	X		    hostPtr->aliases[i] = Calloc((unsigned)1, (unsigned)host_aliases_len[i]);
	X#ifdef SYS5
	X		    (void)memcpy( hostPtr->aliases[i], host_aliases[i],
	X#else
	X		    bcopy(host_aliases[i], hostPtr->aliases[i],
	X#endif
	X			    host_aliases_len[i]);
	X		}
	X		hostPtr->aliases[i] = NULL;
	X	    }
	X	    if (numAddresses > 0) {
	X		hostPtr->addrList = (char **) Calloc((unsigned)1+numAddresses, 
	X							sizeof(char *));
	X		for (i = 0; i < numAddresses; i++) {
	X		    hostPtr->addrList[i] = Calloc((unsigned)1, (unsigned)hostPtr->addrLen);
	X#ifdef SYS5
	X		    (void)memcpy( hostPtr->addrList[i], addr_list[i],
	X#else
	X		    bcopy(addr_list[i], hostPtr->addrList[i], 
	X#endif
	X			    hostPtr->addrLen);
	X		}
	X		hostPtr->addrList[i] = NULL;
	X	    }
	X	    hostPtr->servers= NULL;
	X	    return (SUCCESS);
	X	}
	X
	X	/*
	X	 * At this point, for the T_A query type, only empty answers remain.
	X	 * For other query types, additional information might be found
	X	 * in the additional resource records part.
	X	 */
	X
	X	cp = res_skip((char *) &answer, 2, eom);
	X
	X	numServers = 0;
	X	while (--nscount >= 0 && cp < eom) {
	X	    /*
	X	     *  Go through the NS records and retrieve the
	X	     *  names of hosts that server the requested domain, 
	X	     *  their addresses and other domains they might serve.
	X	     */
	X
	X	  if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) {
	X	      return(ERROR);
	X	  }
	X	  cp += n;
	X	  len = strlen(bp) + 1;
	X	  dnamePtr = Calloc((unsigned)1, (unsigned)len);   /* domain name */
	X#ifdef SYS5
	X	  (void)memcpy(dnamePtr, bp, len);
	X#else
	X	  bcopy(bp, dnamePtr, len);
	X#endif
	X	  type = _getshort(cp);
	X	  cp += sizeof(u_short);
	X	  class = _getshort(cp);
	X	  cp += sizeof(u_short) + sizeof(u_long);
	X	  dlen = _getshort(cp);
	X	  cp += sizeof(u_short);
	X
	X	  if (type != T_NS) {
	X	      cp += dlen;
	X	  } else {
	X	    if ((n = dn_expand((char *) &answer, eom, cp, bp, buflen)) < 0) {
	X	        return(ERROR);
	X	    }
	X	    cp += n;
	X	    len = strlen(bp) + 1;
	X	    namePtr = Calloc((unsigned)1, (unsigned)len); /* server host name */
	X#ifdef SYS5
	X	    (void)memcpy(namePtr, bp, len);
	X#else
	X	    bcopy(bp, namePtr, len);
	X#endif
	X	    /*
	X	     * Store the information keyed by the server host name.
	X	     */
	X	    found = FALSE;
	X	    for (j = 0; j < numServers; j++) {
	X		if (strcmp(namePtr, server[j].name) == 0) {
	X		    found = TRUE;
	X		    free(namePtr);
	X		    break;
	X		}
	X	    }
	X	    if (found) {
	X		server[j].numDomains++;
	X		if (server[j].numDomains <= MAXDOMAINS) {
	X		    server[j].domain[server[j].numDomains-1] = dnamePtr;
	X		}
	X	    } else {
	X		if (numServers > MAXSERVERS) {
	X		    break;
	X		}
	X		numServers++;
	X		server[numServers -1].name = namePtr;
	X		server[numServers -1].domain[0] = dnamePtr;
	X		server[numServers -1].numDomains = 1;
	X		server[numServers -1].numAddresses = 0;
	X	    }
	X	  }
	X	}
	X
	X	if (!headerPtr->aa && (queryType != T_A) && arcount > 0) {
	X	    printf("Authoritative answers can be found from:\n");
	X	}
	X
	X	/*
	X	 * Additional resource records contain addresses of
	X	 * servers.
	X	 */
	X	cp = res_skip((char *) &answer, 3, eom);
	X	while (--arcount >= 0 && cp < eom) {
	X	    /*
	X	     * If we don't need to save the record, just print it.
	X	     */
	X	    if (queryType != T_A) {
	X		if ((cp = Print_rr(cp, (char *) &answer, eom, stdout)) == NULL) {
	X		    return(ERROR);
	X		}
	X		continue;
	X
	X	    } else {
	X	      if ((n = dn_expand((char *) &answer, 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	      dlen = _getshort(cp);
	X	      cp += sizeof(u_short);
	X
	X	      if (type != T_A)  {
	X		  cp += dlen;
	X		  continue;
	X	      } else {
	X		for (j = 0; j < numServers; j++) {
	X		  if (strcmp(bp, server[j].name) == 0) {
	X		    server[j].numAddresses++;
	X		    if (server[j].numAddresses <= MAXADDRS) {
	X		     server[j].address[server[j].numAddresses-1]=Calloc((unsigned)1,(unsigned)dlen);
	X#ifdef SYS5
	X		     (void)memcpy(server[j].address[server[j].numAddresses-1],
	X				cp, dlen);
	X#else
	X		     bcopy(cp,server[j].address[server[j].numAddresses-1],
	X				dlen);
	X#endif
	X		     break;
	X		    }
	X		  }
	X		}
	X		cp += dlen;
	X	      }
	X	    }
	X	}
	X
	X	/*
	X	 * If we are returning name server info, transfer it to
	X	 * the hostPtr.
	X	 *
	X	 */
	X	if (numServers > 0) {
	X	  hostPtr->servers = (ServerInfo **) Calloc((unsigned)numServers+1, 
	X					sizeof(ServerInfo *));
	X	  for (i = 0; i < numServers; i++) {
	X	    hostPtr->servers[i] = (ServerInfo *) Calloc((unsigned)1, sizeof(ServerInfo));
	X	    hostPtr->servers[i]->name = server[i].name;
	X
	X
	X	    hostPtr->servers[i]->domains = (char **)
	X				Calloc((unsigned)server[i].numDomains+1,sizeof(char *));
	X	    for (j = 0; j < server[i].numDomains; j++) {
	X	      hostPtr->servers[i]->domains[j] = server[i].domain[j];
	X	    }
	X	    hostPtr->servers[i]->domains[j] = NULL;
	X
	X
	X	    hostPtr->servers[i]->addrList = (char **)
	X				Calloc((unsigned)server[i].numAddresses+1,sizeof(char *));
	X	    for (j = 0; j < server[i].numAddresses; j++) {
	X	      hostPtr->servers[i]->addrList[j] = server[i].address[j];
	X	    }
	X	    hostPtr->servers[i]->addrList[j] = NULL;
	X
	X	  }
	X	  hostPtr->servers[i] = NULL;
	X	}
	X
	X
	X	if (queryType != T_A) {
	X	    return(SUCCESS);
	X	} else {
	X	    return(NONAUTH);
	X	}
	X}
	X
	X/*
	X *******************************************************************************
	X *
	X *  GetHostInfo --
	X *
	X *	Retrieves host name, address and alias information
	X *	for a domain.
	X *
	X *  Results:
	X *	ERROR		- res_mkquery failed.
	X *	+ return values from GetAnswer()
	X *
	X *******************************************************************************
	X */
	X
	Xint
	XGetHostInfo(nsAddrPtr, queryClass, queryType, name, hostPtr, isserver)
	X	struct in_addr *nsAddrPtr;
	X	int 		queryClass;
	X	int 		queryType;
	X	char 		*name;
	X	HostInfo 	*hostPtr;
	X	int		isserver;
	X{
	X	int 	 n;
	X	int 	 result;
	X	register char *cp, **domain;
	X	querybuf buf;
	X	extern char *Calloc(), *hostalias();
	X
	X	/* catch explicit addresses */
	X	if (isdigit(*name) && (queryType == T_A)) {
	X	    long ina;
	X
	X	    ina = inet_addr(name);
	X
	X	    if (ina == -1)
	X		return(ERROR);
	X
	X	    hostPtr->name = Calloc((unsigned)strlen(name)+3,1);
	X	    (void)sprintf(hostPtr->name,"[%s]",name);
	X	    hostPtr->aliases = 0;
	X	    hostPtr->servers = 0;
	X	    hostPtr->addrType = AF_INET;
	X	    hostPtr->addrLen = 4;
	X	    hostPtr->addrList = (char **)Calloc((unsigned)2,sizeof(char *));
	X	    hostPtr->addrList[0] = Calloc(sizeof(long),sizeof(char));
	X#ifdef SYS5
	X	    (void)memcpy(hostPtr->addrList[0],(char *)&ina,sizeof(ina));
	X#else
	X	    bcopy((char *)&ina,hostPtr->addrList[0],sizeof(ina));
	X#endif
	X	    hostPtr->addrList[1] = 0;
	X
	X	    return(SUCCESS);
	X	}
	X
	X	for (cp = name, n = 0; *cp; cp++)
	X		if (*cp == '.')
	X			n++;
	X	if ((n && *--cp == '.') ||
	X	    (isserver == 0 && (_res.options & RES_DEFNAMES) == 0)) {
	X		int defflag = _res.options & RES_DEFNAMES;
	X
	X		_res.options &= ~RES_DEFNAMES;
	X		if (n && *cp == '.')
	X			*cp = 0;
	X		result = GetHostDomain(nsAddrPtr, queryClass, queryType,
	X			name, (char *)NULL, hostPtr, isserver);
	X		if (n && *cp == 0)
	X			*cp = '.';
	X		if (defflag)
	X			_res.options |= RES_DEFNAMES;
	X		return (result);
	X	}
	X	if (n == 0 && (cp = hostalias(name)))
	X		return (GetHostDomain(nsAddrPtr, queryClass, queryType,
	X			cp, (char *)NULL, hostPtr, isserver));
	X	for (domain = _res.dnsrch; *domain; domain++) {
	X		result = GetHostDomain(nsAddrPtr, queryClass, queryType,
	X			name, *domain, hostPtr, isserver);
	X		if ((result != NXDOMAIN && result != NO_INFO) ||
	X		    (_res.options & RES_DNSRCH) == 0)
	X			return (result);
	X	}
	X	if (n)
	X		return (GetHostDomain(nsAddrPtr, queryClass, queryType,
	X			name, (char *)NULL, hostPtr, isserver));
	X	return (result);
	X}
	X
	XGetHostDomain(nsAddrPtr, queryClass, queryType, name, domain, hostPtr, isserver)
	X	struct in_addr *nsAddrPtr;
	X	int 		queryClass;
	X	int 		queryType;
	X	char 		*name, *domain;
	X	HostInfo 	*hostPtr;
	X	int		isserver;
	X{
	X	querybuf buf;
	X	char nbuf[2*MAXDNAME+2];
	X	int n;
	X
	X	if (domain) {
	X		(void)sprintf(nbuf, "%.*s.%.*s",
	X			MAXDNAME, name, MAXDNAME, domain);
	X		name = nbuf;
	X	}
	X	n = res_mkquery(QUERY, name, queryClass, queryType,
	X			(char *)0, 0, (char *)0, (char *) &buf, sizeof(buf));
	X	if (n < 0) {
	X	    if (_res.options & RES_DEBUG) {
	X		printf("Res_mkquery failed\n");
	X	    }
	X	    return (ERROR);
	X	}
	X
	X	n = GetAnswer(nsAddrPtr, queryType, (char *) &buf, n, 0, hostPtr,
	X	    isserver);
	X
	X	/*
	X	 * GetAnswer didn't find a name, so set it to the specified one.
	X	 */
	X	if (n == NONAUTH) {
	X	    if (hostPtr->name == NULL) {
	X		int len = strlen(name) + 1;
	X		hostPtr->name = Calloc((unsigned)len, sizeof(char));
	X#ifdef SYS5
	X		(void)memcpy(hostPtr->name, name, len);
	X#else
	X		bcopy(name, hostPtr->name, len);
	X#endif
	X
	X	    }
	X	}
	X	return(n);
	X}
	X
	X
	X/*
	X *******************************************************************************
	X *
	X *  FindHostInfo --
	X *
	X *	Performs an inverse query to find the host name
	X *	that corresponds to the given address.
	X *
	X *  Results:
	X *	ERROR		- res_mkquery failed.
	X *	+ return values from GetAnswer()
	X *
	X *******************************************************************************
	X */
	X
	Xint
	XFindHostInfo(nsAddrPtr, address, len, hostPtr)
	X	struct in_addr 	*nsAddrPtr;
	X	struct in_addr	*address;
	X	int 		len;
	X	HostInfo 	*hostPtr;
	X{
	X	int 	 n;
	X	querybuf buf;
	X
	X	n = res_mkquery(IQUERY, (char *)0, C_IN, T_A,
	X		(char *)address, len, (char *)0, (char *) &buf, sizeof(buf));
	X	if (n < 0) {
	X	    if (_res.options & RES_DEBUG) {
	X		printf("Res_mkquery failed\n");
	X	    }
	X	    return (ERROR);
	X	}
	X	return(GetAnswer(nsAddrPtr, T_A, (char *) &buf, n, 1, hostPtr, 1));
	X}
	X
	X/*
	X *******************************************************************************
	X *
	X *  FreeHostInfoPtr --
	X *
	X *	Deallocates all the calloc'd areas for a HostInfo
	X *	variable.
	X *
	X *******************************************************************************
	X */
	X
	Xvoid
	XFreeHostInfoPtr(hostPtr)
	X    HostInfo *hostPtr;
	X{
	X	int i, j;
	X
	X	if (hostPtr->name != NULL) {
	X	    free(hostPtr->name);
	X	    hostPtr->name = NULL;
	X	}
	X
	X	if (hostPtr->aliases != NULL) {
	X	    i = 0;
	X	    while (hostPtr->aliases[i] != NULL) {
	X		free(hostPtr->aliases[i]);
	X		i++;
	X	    }
	X	    free((char *)hostPtr->aliases);
	X	    hostPtr->aliases = NULL;
	X	}
	X
	X	if (hostPtr->addrList != NULL) {
	X	    i = 0;
	X	    while (hostPtr->addrList[i] != NULL) {
	X		free(hostPtr->addrList[i]);
	X		i++;
	X	    }
	X	    free((char *)hostPtr->addrList);
	X	    hostPtr->addrList = NULL;
	X	}
	X
	X	if (hostPtr->servers != NULL) {
	X	    i = 0;
	X	    while (hostPtr->servers[i] != NULL) {
	X
	X		if (hostPtr->servers[i]->name != NULL) {
	X		    free(hostPtr->servers[i]->name);
	X		}
	X
	X		if (hostPtr->servers[i]->domains != NULL) {
	X		    j = 0;
	X		    while (hostPtr->servers[i]->domains[j] != NULL) {
	X			free(hostPtr->servers[i]->domains[j]);
	X			j++;
	X		    }
	X		    free((char *)hostPtr->servers[i]->domains);
	X		}
	X
	X		if (hostPtr->servers[i]->addrList != NULL) {
	X		    j = 0;
	X		    while (hostPtr->servers[i]->addrList[j] != NULL) {
	X			free(hostPtr->servers[i]->addrList[j]);
	X			j++;
	X		    }
	X		    free((char *)hostPtr->servers[i]->addrList);
	X		}
	X		free((char *)hostPtr->servers[i]);
	X		i++;
	X	    }
	X	    free((char *)hostPtr->servers);
	X	    hostPtr->servers = NULL;
	X	}
	X}
	X
	X/*
	X *******************************************************************************
	X *
	X *  GetHostList --
	X *
	X *	Performs a completion query when given an incomplete
	X *	name.
	X *
	X *	Still under development.
	X *
	X *******************************************************************************
	X */
	X
	X#if  notdef
	X
	Xint
	XGetHostList(nsAddrPtr, queryType, name, defaultName, hostPtr)
	X	struct in_addr 	*nsAddrPtr;
	X	int 		queryType;
	X	char 		*name, *defaultName;
	X	HostInfo 	*hostPtr;
	X{
	X	int 	 n;
	X	querybuf buf;
	X
	X	n = res_mkquery(CQUERYM, name, C_IN, T_A, defaultName, 0, (char *)0,
	X		(char *) &buf, sizeof(buf));
	X	if (n < 0) {
	X		if (_res.options & RES_DEBUG)
	X			printf("Res_mkquery failed\n");
	X		return (ERROR);
	X	}
	X	return(GetAnswer(nsAddrPtr, queryType, (char *)&buf, n, 0, hostPtr, 1));
	X}
	X#endif  notdef
SHAR_EOF
if test 19262 -ne "`wc -c < 'getinfo.c'`"
then
	echo shar: "error transmitting 'getinfo.c'" '(should have been 19262 characters)'
fi
fi
exit 0
#	End of shell archive

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

If you are on the internet and want your Masscomp to understand the Domain
Name Service, here is the first step. This is the resolver library.
This code is based on BIND 4.8 with all patches to date.

Enjoy.

#! /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:
#	tools/nslookup/nslookup.1
#	tools/nslookup/nslookup.help
#	tools/nslookup/res.h
#	tools/nslookup/send.c
#	tools/nslookup/skip.c
#	tools/nslookup/subr.c
# This archive created: Mon Jul  4 20:28:57 1988
export PATH; PATH=/bin:/usr/bin:$PATH
if test ! -d 'tools'
then
	echo shar: "creating directory 'tools'"
	mkdir 'tools'
fi
echo shar: "entering directory 'tools'"
cd 'tools'
if test ! -d 'nslookup'
then
	echo shar: "creating directory 'nslookup'"
	mkdir 'nslookup'
fi
echo shar: "entering directory 'nslookup'"
cd 'nslookup'
echo shar: "extracting 'nslookup.1'" '(7745 characters)'
if test -f 'nslookup.1'
then
	echo shar: "will not over-write existing file 'nslookup.1'"
else
sed 's/^	X//' << \SHAR_EOF > 'nslookup.1'
	X.\" Copyright (c) 1986 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.\"	@(#)nslookup.1	1.2 (Berkeley) 11/21/87
	X.\"
	X.TH NSLOOKUP 1 "November 21, 1987"
	X.UC 6
	X.SH NAME
	Xnslookup \- query name servers interactively
	X.SH SYNOPSIS
	X.B nslookup
	X[
	X.I host-to-find | \-
	X[
	X.I server address | server name
	X]] 
	X.SH DESCRIPTION
	X.IR Nslookup
	Xis a program to query DARPA Internet domain name servers. 
	XNslookup has two modes: interactive and non-interactive.
	XInteractive mode allows the user to query the name server for
	Xinformation about various  hosts and domains or print a list of hosts 
	Xin the domain. 
	XNon-interactive mode is used to print just the name and Internet address
	Xof a host or domain.
	X.sp 1
	X.SH ARGUMENTS
	XInteractive mode is entered in the following cases:
	X.IP a) 4
	Xwhen no arguments are given (the default name server will be used), and
	X.IP b) 4
	Xwhen the first argument is a hyphen (\-) and the second argument
	Xis the host name of a name server.
	X.LP
	XNon-interactive mode is used when the name of the host to be looked up
	Xis given as the first argument. The optional second argument specifies
	Xa name server.
	X.sp 1
	X.SH "INTERACTIVE COMMANDS"
	XCommands may be interrupted at any time by typing a control-C.
	XTo exit, type a control-D (EOF).
	XThe command line length must be less than 80 characters.
	X\fBN.B.\fP an unrecognized command will be interpreted as a host name.
	X.sp 1
	X.IP "host [server]"
	XLook up information for \fIhost\fP using the current default server
	Xor using \fIserver\fP if it is specified.
	X.sp 1
	X.IP "\fBserver\fP \fIdomain\fP"
	X.ns
	X.IP "\fBlserver\fP \fIdomain\fP"
	XChange the default server to \fIdomain\fP. 
	X\fBLserver\fP uses the initial server to look up 
	Xinformation about \fIdomain\fP while \fBserver\fP
	Xuses the current default server. 
	XIf an authoritative answer can't be found, the names of servers
	Xthat might have the answer are returned.
	X.sp 1
	X.IP \fBroot\fP
	XChanges the default server to the server for the root of the domain name space.
	XCurrently, the host sri-nic.arpa is used.
	X(This command is a synonym for the \fBlserver sri-nic.arpa\fP.)
	XThe name of the root server can be changed with the \fBset root\fP command.
	X.sp 1
	X.IP "\fBfinger\fP [\fIname\fP] [\fB>\fP \fIfilename\fP]"
	X.ns
	X.IP "\fBfinger\fP [\fIname\fP] [\fB>>\fP \fIfilename\fP]"
	XConnects with the finger server on the current host. 
	XThe current host is defined when a previous lookup for a host
	Xwas successful and returned address information (see the 
	X\fBset querytype=A\fP command).
	X\fIName\fP is optional. 
	X\fB>\fP and \fB>>\fP can be used to redirect output in the
	Xusual manner.
	X.sp 1
	X.IP "\fBls\fP \fIdomain\fP [\fB>\fP \fIfilename\fP]"
	X.ns
	X.IP "\fBls\fP \fIdomain\fP [\fB>>\fP \fIfilename\fP]"
	X.ns
	X.IP "\fBls -a\fP \fIdomain\fP [\fB>\fP \fIfilename\fP]"
	X.ns
	X.IP "\fBls -a\fP \fIdomain\fP [\fB>>\fP \fIfilename\fP]"
	X.ns
	X.IP "\fBls -h\fP \fIdomain\fP [\fB>\fP \fIfilename\fP]"
	X.ns
	X.IP "\fBls -h\fP \fIdomain\fP [\fB>>\fP \fIfilename\fP]"
	X.IP "\fBls -d\fP \fIdomain\fP [\fB>\fP \fIfilename\fP]"
	X.ns
	XList the information available for \fIdomain\fP. 
	XThe default output contains host names and their Internet addresses. 
	XThe \fB-a\fP option lists aliases of hosts in the domain.
	XThe \fB-h\fP option lists CPU and operating system information for the domain.
	XThe \fB-d\fP option lists all contents of a zone transfer.
	XWhen output is directed to a file, hash marks are printed for every
	X50 records received from the server.
	X.sp 1
	X.IP "\fBview\fP \fIfilename\fP"
	XSorts and lists the output of previous \fBls\fP command(s) with \fImore\fP(1).
	X.sp 1
	X.IP "\fBhelp\fP"
	X.ns
	X.IP "\fB?\fP"
	XPrints a brief summary of commands.
	X.sp 1
	X.IP "\fBset\fP \fIkeyword\fP[=\fIvalue\fP]"
	XThis command is used to change state information that affects the lookups.
	XValid keywords are:
	X.RS
	X.IP "\fBall\fP"
	XPrints the current values of the various options to \fBset\fP.
	XInformation about the  current default server and host is also printed.
	X.IP "\fB[no]debug\fP"
	XTurn debugging mode on. A lot more information is printed about the
	Xpacket sent to the server and the resulting answer.
	X.br
	X(Default = nodebug, abbreviation = [no]deb)
	X.IP "\fB[no]d2\fP"
	XTurn exhaustive debugging mode on.
	XEssentially all fields of every packet are printed.
	X.br
	X(Default = nod2)
	X.IP "\fB[no]defname\fP"
	XAppend the default domain name to every lookup.
	X.br
	X(Default = defname, abbreviation = [no]def)
	X.IP "\fB[no]search\fP"
	XWith defname, search for each name in parent domains of the current domain.
	X.br
	X(Default = search)
	X.IP "\fBdomain=\fIname\fR"
	XChange the default domain name to \fIname\fP. 
	XThe default domain name is appended to all lookup requests if 
	Xthe \fBdefname\fP option has been set.
	XThe search list is set to parents of the domain with at least two components
	Xin their names.
	X.br
	X(Default = value in hostname or /etc/resolv.conf, abbreviation = do)
	X.IP "\fBquerytype=\fIvalue\fR"
	X.IP "\fBtype=\fIvalue\fR"
	XChange the type of information returned from a query to one of:
	X.RS
	X.IP A 10
	Xthe host's Internet address (the default).
	X.IP CNAME  10
	Xthe canonical name for an alias. 
	X.IP HINFO 10
	Xthe host CPU and operating system type.
	X.IP MD 10
	Xthe mail destination.
	X.IP MX 10
	Xthe mail exchanger.
	X.IP MG     10
	Xthe mail group member.
	X.IP MINFO 10
	Xthe mailbox or mail list information.
	X.IP MR     10
	Xthe mail rename domain name.
	X.IP NS     10
	Xnameserver for the named zone.
	X.RE
	XOther types specified in the RFC883 document are valid but aren't
	Xvery useful.
	X.br
	X(Abbreviation = q)
	X.IP "\fB[no]recurse\fP"
	XTell the name server to query other servers if it does not have the
	Xinformation.
	X.br
	X(Default = recurse, abbreviation = [no]rec)
	X.IP \fBretry=\fInumber\fR
	XSet the number of retries to \fInumber\fP. 
	XWhen a reply to a request is not received within a certain 
	Xamount of time (changed with \fBset timeout\fP), 
	Xthe request is resent. 
	XThe retry value controls how many times a request is resent before giving up.
	X.br
	X(Default = 2, abbreviation = ret)
	X.IP \fBroot=\fIhost\fR
	XChange the name of the root server to \fIhost\fP. This
	Xaffects the \fBroot\fP command. 
	X.br
	X(Default = sri-nic.arpa, abbreviation = ro)
	X.IP \fBtimeout=\fInumber\fR
	XChange the time-out interval for waiting for a reply to \fInumber\fP seconds.
	X.br
	X(Default = 10 seconds, abbreviation = t)
	X.IP "\fB[no]vc\fP"
	XAlways use a virtual circuit when sending requests to the server.
	X.br
	X(Default = novc, abbreviation = [no]v)
	X.RE
	X.SH DIAGNOSTICS
	XIf the lookup request was not successful, an error message is printed.
	XPossible errors are:
	X.IP "Time-out"
	XThe server did not respond to a request after a certain amount of
	Xtime (changed with \fBset timeout=\fIvalue\fR) 
	Xand a certain number of retries (changed with \fBset retry=\fIvalue\fR).
	X.IP "No information"
	XDepending on the query type set with the \fBset querytype\fP command,
	Xno information about the host was available, though the host name is
	Xvalid.
	X.IP "Non-existent domain"
	XThe host or domain name does not exist.
	X.IP "Connection refused"
	X.ns
	X.IP "Network is unreachable"
	XThe connection to the name or finger server could not be made 
	Xat the current time.
	XThis error commonly occurs with \fBfinger\fP requests. 
	X.IP "Server failure"
	XThe name server found an internal inconsistency in its database
	Xand could not return a valid answer.
	X.IP "Refused"
	XThe name server refused to service the request.
	X.sp 1
	X.PP
	XThe following error should not occur and it indicates a bug in the program.
	X.IP "Format error"
	XThe name server found that the request packet was not in the proper format.
	X.sp 1
	X.SH FILES
	X/etc/resolv.conf	initial domain name and name server addresses.
	X.SH SEE ALSO
	Xresolver(3), resolver(5), named(8), RFC882, RFC883
	X.SH AUTHOR
	XAndrew Cherenson
SHAR_EOF
if test 7745 -ne "`wc -c < 'nslookup.1'`"
then
	echo shar: "error transmitting 'nslookup.1'" '(should have been 7745 characters)'
fi
fi
echo shar: "extracting 'nslookup.help'" '(1214 characters)'
if test -f 'nslookup.help'
then
	echo shar: "will not over-write existing file 'nslookup.help'"
else
sed 's/^	X//' << \SHAR_EOF > 'nslookup.help'
	XCommands: 	(identifiers are shown in uppercase, [] means optional)
	XNAME		- print info about the host/domain NAME using default server
	XNAME1 NAME2	- as above, but use NAME2 as server
	Xhelp or ?	- print help information
	Xset OPTION	- set an option
	X    all		- print options, current server and host
	X    [no]debug	- print debugging information
	X    [no]d2	- print exhaustive debugging information
	X    [no]defname	- append domain name to each query 
	X    [no]recurse	- ask for recursive answer to query
	X    [no]vc	- always use a virtual circuit
	X    domain=NAME	- set default domain name to NAME
	X    root=NAME	- set root server to NAME
	X    retry=X	- set number of retries to X
	X    timeout=X	- set time-out interval to X
	X    querytype=X	- set query type to one of A,CNAME,HINFO,MB,MG,MINFO,MR,MX
	X    type=X	- set query type to one of A,CNAME,HINFO,MB,MG,MINFO,MR,MX
	Xserver NAME	- set default server to NAME, using current default server
	Xlserver NAME	- set default server to NAME, using initial server
	Xfinger [NAME]	- finger the optional NAME
	Xroot		- set current default server to the root
	Xls NAME [> FILE]- list the domain NAME, with output optionally going to FILE
	Xview FILE	- sort an 'ls' output file and view it with more
SHAR_EOF
if test 1214 -ne "`wc -c < 'nslookup.help'`"
then
	echo shar: "error transmitting 'nslookup.help'" '(should have been 1214 characters)'
fi
fi
echo shar: "extracting 'res.h'" '(3169 characters)'
if test -f 'res.h'
then
	echo shar: "will not over-write existing file 'res.h'"
else
sed 's/^	X//' << \SHAR_EOF > 'res.h'
	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 *	@(#)res.h	5.3 (Berkeley) 2/17/88
	X */
	X
	X/*
	X *******************************************************************************
	X *
	X *  res.h --
	X *
	X *	Definitions used by modules of the name server 
	X *	lookup program.
	X *
	X *	Copyright (c) 1985 
	X *  	Andrew Cherenson
	X *  	CS298-26  Fall 1985
	X *  
	X *******************************************************************************
	X */
	X
	X#define TRUE	1
	X#define FALSE	0
	X
	X/*
	X *  Define return statuses in addtion to the ones defined in namserv.h
	X *   let SUCCESS be a synonym for NOERROR
	X *
	X *	TIME_OUT	- a socket connection timed out.
	X *	NO_INFO		- the server didn't find any info about the host.
	X *	ERROR		- one of the following types of errors:
	X *			   dn_expand, res_mkquery failed
	X *			   bad command line, socket operation failed, etc.
	X *	NONAUTH		- the server didn't have the desired info but
	X *			  returned the name(s) of some servers who should.
	X *
	X */
	X
	X#define  SUCCESS		0
	X#define  TIME_OUT		-1
	X#define  NO_INFO 		-2
	X#define  ERROR 			-3
	X#define  NONAUTH 		-4
	X
	X/*
	X *  Define additional options for the resolver state structure.
	X *
	X *   RES_DEBUG2		more verbose debug level 
	X */
	X
	X#define RES_DEBUG2	0x80000000
	X
	X/*
	X *  Maximum length of server, host and file names.
	X */
	X
	X#define NAME_LEN 80
	X
	X
	X/*
	X * Modified struct hostent from <netdb.h>
	X *
	X * "Structures returned by network data base library.  All addresses
	X * are supplied in host order, and returned in network order (suitable
	X * for use in system calls)."
	X */
	X
	Xtypedef struct	{
	X	char	*name;		/* official name of host */
	X	char	**domains;	/* domains it serves */
	X	char	**addrList;	/* list of addresses from name server */
	X} ServerInfo;
	X
	Xtypedef struct	{
	X	char	*name;		/* official name of host */
	X	char	**aliases;	/* alias list */
	X	char	**addrList;	/* list of addresses from name server */
	X	int	addrType;	/* host address type */
	X	int	addrLen;	/* length of address */
	X	ServerInfo **servers;
	X} HostInfo;
	X
	X
	X/*
	X *  SockFD is the file descriptor for sockets used to connect with
	X *  the name servers. It is global so the Control-C handler can close
	X *  it. Likewise for filePtr, which is used for directing listings
	X *  to a file.
	X */
	X
	Xextern int sockFD;
	Xextern FILE *filePtr;
	X
	X
	X/*
	X *  External routines:
	X */
	X
	Xextern int   Print_query();
	Xextern char *Print_cdname();
	Xextern char *Print_cdname2();	/* fixed width */
	Xextern char *Print_rr();
	Xextern char *DecodeType();	/* descriptive version of p_type */
	Xextern char *DecodeError();
	Xextern char *Calloc();
	Xextern void NsError();
	Xextern void PrintServer();
	Xextern void PrintHostInfo();
	Xextern void ShowOptions();
	Xextern void FreeHostInfoPtr();
	Xextern FILE *OpenFile();
	Xextern char *inet_ntoa();
	Xextern char *res_skip();
SHAR_EOF
if test 3169 -ne "`wc -c < 'res.h'`"
then
	echo shar: "error transmitting 'res.h'" '(should have been 3169 characters)'
fi
fi
echo shar: "extracting 'send.c'" '(6391 characters)'
if test -f 'send.c'
then
	echo shar: "will not over-write existing file 'send.c'"
else
sed 's/^	X//' << \SHAR_EOF > '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#ifndef lint
	Xstatic char sccsid[] = "@(#)send.c	5.6 (Berkeley) 2/17/88";
	X#endif /* not lint */
	X
	X/*
	X *******************************************************************************
	X *
	X *  send.c --
	X *
	X *	Routine to send request packets to a name server.
	X *
	X *	Modified version of 4.3BSD BIND  res_send.c 5.5 (Berkeley) 9/14/85
	X *
	X *******************************************************************************
	X */
	X
	X#include <sys/types.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#endif
	X#include <sys/time.h>
	X#include <sys/socket.h>
	X#include <netinet/in.h>
	X#include <stdio.h>
	X#include <arpa/nameser.h>
	X#include <resolv.h>
	X#include "res.h"
	X
	X/*
	X *  Initialize the socket address info struct.
	X */
	X
	Xstatic struct sockaddr_in sin = { 
	X    AF_INET,  
	X};
	X
	Xextern int errno;
	X
	X/*
	X *******************************************************************************
	X *
	X *   SendRequest --
	X *
	X *	Sends a request packet to a name server whose address
	X *	is specified by the first argument and returns with
	X *	the answer packet.
	X *
	X *  Results:
	X *	SUCCESS		- the request was sent and an answer 
	X *			  was received.
	X *	TIME_OUT	- the virtual circuit connection timed-out 
	X *			  or a reply to a datagram wasn't received.
	X *
	X *
	X *******************************************************************************
	X */
	X
	Xint
	XSendRequest(nsAddrPtr, buf, buflen, answer, anslen, trueLenPtr, printanswer)
	X	struct in_addr 	*nsAddrPtr;
	X	char 		*buf;
	X	int 		buflen;
	X	char 		*answer;
	X	int 		anslen;
	X	int 		*trueLenPtr;
	X	int		printanswer;
	X{
	X#ifdef EXOS
	X	int		timeout;
	X	struct sockaddr_in there;
	X#else
	X	struct timeval 	timeout;
	X#endif
	X	register int 	n;
	X	u_short 	packetId, len;
	X	short 		length;
	X	char 		*cp;
	X	int 		retry, v_circuit, resplen;
	X	int 		dsmask;
	X
	X	int 		numTimeOuts	= 0;
	X	HEADER 		*requestPtr	= (HEADER *) buf;
	X	HEADER 		*answerPtr	= (HEADER *) answer;
	X
	X
	X	if (_res.options & RES_DEBUG2) {
	X	    printf("------------\nSendRequest(), len %d\n", buflen);
	X	    Print_query(buf, buf+buflen, 1);
	X	}
	X	sockFD = -1;
	X
	X	/*
	X	 * See if a virtual circuit is required or desired.
	X	 */
	X	v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
	X
	X	packetId = requestPtr->id;
	X
	X	sin.sin_port	= htons(NAMESERVER_PORT);
	X	sin.sin_addr	= *nsAddrPtr;
	X
	X	/*
	X	 * Send request, RETRY times, or until successful
	X	 */
	X	for (retry = _res.retry; --retry >= 0; ) {
	X#ifdef EXOS
	X		there.sin_family = (u_short)AF_INET;
	X		there.sin_port = htons(NAMESERVER_PORT);
	X#endif
	X		if (v_circuit) {
	X			/*
	X			 * Use virtual circuit.
	X			 */
	X			if (sockFD < 0)
	X				sockFD = socket(AF_INET, SOCK_STREAM, 0);
	X
	X			if (connect(sockFD, &sin, sizeof(sin)) < 0) {
	X				if (_res.options & RES_DEBUG) {
	X				    perror("SendRequest");
	X				}
	X				(void) close(sockFD);
	X				sockFD = -1;
	X				continue;
	X			}
	X			/*
	X			 * Send length & message
	X			 */
	X			len = htons(buflen);
	X			if (write(sockFD, &len, sizeof(len)) != sizeof(len) ||
	X			    write(sockFD, buf, buflen) != buflen) {
	X				if (_res.options & RES_DEBUG) {
	X				    perror("SendRequest");
	X				}
	X				(void) close(sockFD);
	X				sockFD = -1;
	X				continue;
	X			}
	X			/*
	X			 * Receive length & response
	X			 */
	X			cp = answer;
	X			length = sizeof(short);
	X			while(length > 0 && (n = read(sockFD, cp, length)) > 0){
	X				cp += n;
	X				length -= n;
	X			}
	X			if (n <= 0) {
	X				if (_res.options & RES_DEBUG) {
	X				    perror("SendRequest");
	X				}
	X				(void) close(sockFD);
	X				sockFD = -1;
	X				continue;
	X			}
	X			cp = answer;
	X			resplen = length = ntohs(*(short *)cp);
	X			while(length > 0 && (n = read(sockFD, cp, length)) > 0){
	X				cp += n;
	X				length -= n;
	X			}
	X			if (n <= 0) {
	X				if (_res.options & RES_DEBUG) {
	X				    perror("SendRequest");
	X				}
	X				(void) close(sockFD);
	X				sockFD = -1;
	X				continue;
	X			}
	X		} else {
	X			/*
	X			 * Use datagrams.
	X			 */
	X			if (sockFD < 0)
	X#ifdef EXOS
	X				sockFD = socket(SOCK_DGRAM, 0, 0, 0);
	X
	X			errno = 0;
	X			send(sockFD, &sin, buf, buflen);
	X			if (errno != 0) {
	X#else
	X				sockFD = socket(AF_INET, SOCK_DGRAM, 0);
	X
	X			if (sendto(sockFD, buf, buflen, 0, &sin,
	X			    sizeof(sin)) != buflen) {
	X#endif
	X				if (_res.options & RES_DEBUG) {
	X				    perror("SendRequest");
	X				}
	X			}
	X			/*
	X			 * Wait for reply 
	X			 */
	X#ifdef EXOS
	X			timeout = ((_res.retrans << (_res.retry - retry))
	X				/ _res.nscount) * 1000;
	X			if (timeout <= 0) timeout = 1000;
	X			dsmask = (1 << sockFD) ;
	X			n = select(32,&dsmask,NULL,timeout);
	X#else
	X			timeout.tv_sec = _res.retrans;
	X			timeout.tv_usec = 0;
	X			dsmask = 1 << sockFD;
	X			n = select(sockFD+1, &dsmask, 0, 0, &timeout);
	X#endif
	X			if (n < 0) {
	X				if (_res.options & RES_DEBUG) {
	X				    perror("SendRequest");
	X				}
	X				continue;
	X			}
	X			if (n == 0) {
	X				/*
	X				 * timeout
	X				 */
	X				if (_res.options & RES_DEBUG) {
	X				    printf("Timeout %d\n", ++numTimeOuts);
	X				}
	X				continue;
	X			}
	X#ifdef EXOS
	X 			if ((resplen = receive(sockFD, &there,answer, anslen)) <= 0) {
	X#else
	X 			if ((resplen = recv(sockFD, answer, anslen, 0)) <= 0) {
	X#endif
	X				if (_res.options & RES_DEBUG) {
	X				    perror("SendRequest");
	X				}
	X				continue;
	X			}
	X			if (packetId != answerPtr->id) {
	X				/*
	X				 * response from old query, ignore it
	X				 */
	X				if (_res.options & RES_DEBUG2) {
	X					printf("------------\nOld answer:\n");
	X					Print_query(answer, answer+resplen, 1);
	X				}
	X				continue;
	X			}
	X			if (!(_res.options & RES_IGNTC) && answerPtr->tc) {
	X				/*
	X				 * get rest of answer
	X				 */
	X				if (_res.options & RES_DEBUG) {
	X					printf("truncated answer\n");
	X				}
	X				(void) close(sockFD);
	X				sockFD = -1;
	X				retry = _res.retry;
	X				v_circuit = 1;
	X				continue;
	X			}
	X		}
	X		if (_res.options & RES_DEBUG && printanswer) {
	X		    if (_res.options & RES_DEBUG2)
	X			printf("------------\nGot answer (%d bytes):\n",
	X			    resplen);
	X		    else
	X			printf("------------\nGot answer:\n");
	X		    Print_query(answer, answer+resplen, 1);
	X		}
	X		(void) close(sockFD);
	X		sockFD = -1;
	X		*trueLenPtr = resplen;
	X		return (SUCCESS);
	X	}
	X	(void) close(sockFD);
	X	sockFD = -1;
	X	return (TIME_OUT);
	X}
SHAR_EOF
if test 6391 -ne "`wc -c < 'send.c'`"
then
	echo shar: "error transmitting 'send.c'" '(should have been 6391 characters)'
fi
fi
echo shar: "extracting 'skip.c'" '(3718 characters)'
if test -f 'skip.c'
then
	echo shar: "will not over-write existing file 'skip.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'skip.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#ifndef lint
	Xstatic char sccsid[] = "@(#)skip.c	5.4 (Berkeley) 2/17/88";
	X#endif /* not lint */
	X
	X/*
	X *******************************************************************************
	X *
	X *  skip.c --
	X *
	X *	Routines to skip over portions of a query buffer.
	X *
	X *	Note: this file has been submitted for inclusion in
	X *	BIND resolver library. When this has been done, this file
	X *	is no longer necessary (assuming there haven't been any
	X *	changes).
	X *
	X *	Adapted from 4.3BSD BIND res_debug.c
	X *
	X *******************************************************************************
	X */
	X
	X#include <sys/types.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#endif
	X#include <netinet/in.h>
	X#include <stdio.h>
	X#include <arpa/nameser.h>
	X
	Xchar *res_skip_rr();
	X
	X
	X/*
	X *******************************************************************************
	X *
	X *  res_skip --
	X *
	X * 	Skip the contents of a query.
	X *
	X * 	Interpretation of numFieldsToSkip argument:
	X *            res_skip returns pointer to:
	X *    	1 ->  start of question records.
	X *    	2 ->  start of authoritative answer records.
	X *    	3 ->  start of additional records.
	X *    	4 ->  first byte after end of additional records.
	X *
	X *   Results:
	X *	(address)	- success operation.
	X *  	NULL 		- a resource record had an incorrect format.
	X *
	X *******************************************************************************
	X */
	X
	Xchar *
	Xres_skip(msg, numFieldsToSkip, eom)
	X	char *msg;
	X	int numFieldsToSkip;
	X	char *eom;
	X{
	X	register char *cp;
	X	register HEADER *hp;
	X	register int tmp;
	X	register int n;
	X
	X	/*
	X	 * Skip the header fields.
	X	 */
	X	hp = (HEADER *)msg;
	X	cp = msg + sizeof(HEADER);
	X
	X	/*
	X	 * skip question records.
	X	 */
	X	if (n = ntohs(hp->qdcount) ) {
	X		while (--n >= 0) {
	X			tmp = dn_skipname(cp, eom);
	X			if (tmp == -1) return(NULL);
	X			cp += tmp;
	X			cp += sizeof(u_short);	/* type 	*/
	X			cp += sizeof(u_short);	/* class 	*/
	X		}
	X	}
	X	if (--numFieldsToSkip <= 0) return(cp);
	X
	X	/*
	X	 * skip authoritative answer records
	X	 */
	X	if (n = ntohs(hp->ancount)) {
	X		while (--n >= 0) {
	X			cp = res_skip_rr(cp, eom);
	X			if (cp == NULL) return(NULL);
	X		}
	X	}
	X	if (--numFieldsToSkip == 0) return(cp);
	X
	X	/*
	X	 * skip name server records
	X	 */
	X	if (n = ntohs(hp->nscount)) {
	X		while (--n >= 0) {
	X			cp = res_skip_rr(cp, eom);
	X			if (cp == NULL) return(NULL);
	X		}
	X	}
	X	if (--numFieldsToSkip == 0) return(cp);
	X
	X	/*
	X	 * skip additional records
	X	 */
	X	if (n = ntohs(hp->arcount)) {
	X		while (--n >= 0) {
	X			cp = res_skip_rr(cp, eom);
	X			if (cp == NULL) return(NULL);
	X		}
	X	}
	X
	X	return(cp);
	X}
	X
	X
	X/*
	X *******************************************************************************
	X *
	X *  res_skip_rr --
	X *
	X * 	Skip over resource record fields.
	X *
	X *   Results:
	X *	(address)	- success operation.
	X *  	NULL 		- a resource record had an incorrect format.
	X *******************************************************************************
	X */
	X
	Xchar *
	Xres_skip_rr(cp, eom)
	X	char *cp;
	X	char *eom;
	X{
	X	int tmp;
	X	int dlen;
	X
	X	if ((tmp = dn_skipname(cp, eom)) == -1)
	X		return (NULL);			/* compression error */
	X	cp += tmp;
	X	cp += sizeof(u_short);	/* 	type 	*/
	X	cp += sizeof(u_short);	/* 	class 	*/
	X	cp += sizeof(u_long);	/* 	ttl 	*/
	X	dlen = _getshort(cp);
	X	cp += sizeof(u_short);	/* 	dlen 	*/
	X	cp += dlen;
	X	return (cp);
	X}
SHAR_EOF
if test 3718 -ne "`wc -c < 'skip.c'`"
then
	echo shar: "error transmitting 'skip.c'" '(should have been 3718 characters)'
fi
fi
echo shar: "extracting 'subr.c'" '(10791 characters)'
if test -f 'subr.c'
then
	echo shar: "will not over-write existing file 'subr.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'subr.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#ifndef lint
	Xstatic char sccsid[] = "@(#)subr.c	5.9 (Berkeley) 2/17/88";
	X#endif /* not lint */
	X
	X/*
	X *******************************************************************************
	X *
	X *  subr.c --
	X *
	X *	Miscellaneous subroutines for the name server 
	X *	lookup program.
	X *  
	X *	Copyright (c) 1985 
	X *  	Andrew Cherenson
	X *  	CS298-26  Fall 1985
	X *
	X *******************************************************************************
	X */
	X
	X#include <stdio.h>
	X#ifdef SYS5
	X#include <string.h>
	X#else
	X#include <strings.h>
	X#endif
	X#include <sys/types.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#endif
	X#include <netdb.h>
	X#include <sys/socket.h>
	X#include <netinet/in.h>
	X#include <arpa/nameser.h>
	X#include <signal.h>
	X#include <setjmp.h>
	X#include "res.h"
	X
	X
	X
	X/*
	X *******************************************************************************
	X *
	X *  IntrHandler --
	X *
	X *	This routine is called whenever a control-C is typed. 
	X *	It performs three main functions:
	X *	 - close an open socket connection.
	X *	 - close an open output file (used by LookupHost, et al.)
	X *	 - jump back to the main read-eval loop.
	X *		
	X *	Since a user may type a ^C in the middle of a routine that
	X *	is using a socket, the socket would never get closed by the 
	X *	routine. To prevent an overflow of the process's open file table,
	X *	the socket and output file descriptors are closed by
	X *	the interrupt handler.
	X *
	X *  Side effects:
	X *	If sockFD is valid, its socket is closed.
	X *	If filePtr is valid, its file is closed.
	X *	Flow of control returns to the main() routine.
	X *
	X *******************************************************************************
	X */
	X
	Xint
	XIntrHandler()
	X{
	X    extern jmp_buf env;
	X
	X    if (sockFD >= 0) {
	X	close(sockFD);
	X	sockFD = -1;
	X    }
	X    if (filePtr != NULL && filePtr != stdout) {
	X	fclose(filePtr);
	X	filePtr = NULL;
	X    }
	X    printf("\n");
	X    longjmp(env, 1);
	X}
	X
	X
	X/*
	X *******************************************************************************
	X *
	X *  Calloc --
	X *
	X *      Calls the calloc library routine with the interrupt
	X *      signal blocked.  The interrupt signal blocking is done
	X *      to prevent malloc from getting confused if a
	X *      control-C arrives in the middle of its bookkeeping
	X *      routines.  We need to do this because a control-C
	X *      causes a return to the main command loop instead
	X *      causing the program to die.
	X *
	X *	This method doesn't prevent the pointer returned
	X *	by calloc from getting lost, so it is possible
	X *	to get "core leaks".
	X *
	X *  Results:
	X *	(address)	- address of new buffer.
	X *	NULL		- calloc failed.
	X *
	X *******************************************************************************
	X */
	X
	Xchar *
	XCalloc(num, size)
	X    unsigned num, size;
	X{
	X	char 	*ptr;
	X	int 	saveMask;
	X	extern char *calloc();
	X
	X#ifdef SYS5
	X	saveMask = (int) signal(SIGINT,SIG_IGN);
	X#else
	X	saveMask = sigblock(1 << (SIGINT-1));
	X#endif
	X	ptr = calloc(num, size);
	X#ifdef SYS5
	X	signal(SIGINT,saveMask);
	X#else
	X	(void) sigsetmask(saveMask);
	X#endif
	X	if (ptr == NULL) {
	X	    fflush(stdout);
	X	    fprintf(stderr, "Calloc failed\n");
	X	    fflush(stderr);
	X	    abort();
	X	    /*NOTREACHED*/
	X	} else {
	X	    return(ptr);
	X	}
	X}
	X
	X/*
	X *******************************************************************************
	X *
	X *  PrintHostInfo --
	X *
	X *	Prints out the HostInfo structure for a host.
	X *
	X *******************************************************************************
	X */
	X
	Xvoid
	XPrintHostInfo(file, title, hp)
	X	FILE 	*file;
	X	char 	*title;
	X	register HostInfo *hp;
	X{
	X	register char 		**cp;
	X	register ServerInfo 	**sp;
	X	char 			comma;
	X	int  			i;
	X
	X	fprintf(file, "%-7s  %s\n", title, hp->name);
	X
	X	if (hp->addrList != NULL) {
	X	    if (hp->addrList[1] != NULL) {
	X		fprintf(file, "Addresses:");
	X	    } else {
	X		fprintf(file, "Address:");
	X	    }
	X	    comma = ' ';
	X	    i = 0;
	X	    for (cp = hp->addrList; cp && *cp; cp++) {
	X		i++;
	X		if (i > 4) {
	X		    fprintf(file, "\n\t");
	X		    comma = ' ';
	X		    i = 0;
	X		}
	X		fprintf(file,"%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
	X		comma = ',';
	X	    }
	X	}
	X
	X	if (hp->aliases != NULL) {
	X	    fprintf(file, "\nAliases:");
	X	    comma = ' ';
	X	    i = 10;
	X	    for (cp = hp->aliases; cp && *cp && **cp; cp++) {
	X		i += strlen(*cp) + 2;
	X		if (i > 75) {
	X		    fprintf(file, "\n\t");
	X		    comma = ' ';
	X		    i = 10;
	X		}
	X		fprintf(file, "%c %s", comma, *cp);
	X		comma = ',';
	X	    }
	X	}
	X
	X	if (hp->servers != NULL) {
	X	    fprintf(file, "Served by:\n");
	X	    for (sp = hp->servers; *sp != NULL ; sp++) {
	X
	X		fprintf(file, "- %s\n\t",  (*sp)->name);
	X
	X		comma = ' ';
	X		i = 0;
	X		for (cp = (*sp)->addrList; cp && *cp && **cp; cp++) {
	X		    i++;
	X		    if (i > 4) {
	X			fprintf(file, "\n\t");
	X			comma = ' ';
	X			i = 0;
	X		    }
	X		    fprintf(file, 
	X			"%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
	X		    comma = ',';
	X		}
	X		fprintf(file, "\n\t");
	X
	X		comma = ' ';
	X		i = 10;
	X		for (cp = (*sp)->domains; cp && *cp && **cp; cp++) {
	X		    i += strlen(*cp) + 2;
	X		    if (i > 75) {
	X			fprintf(file, "\n\t");
	X			comma = ' ';
	X			i = 10;
	X		    }
	X		    fprintf(file, "%c %s", comma, *cp);
	X		    comma = ',';
	X		}
	X		fprintf(file, "\n");
	X	    }
	X	}
	X
	X	fprintf(file, "\n\n");
	X}
	X
	X/*
	X *******************************************************************************
	X *
	X *  OpenFile --
	X *
	X *	Parses a command string for a file name and opens
	X *	the file.
	X *
	X *  Results:
	X *	file pointer	- the open was successful.
	X *	NULL		- there was an error opening the file or
	X *			  the input string was invalid.
	X *
	X *******************************************************************************
	X */
	X
	XFILE *
	XOpenFile(string, file)
	X    char *string;
	X    char *file;
	X{
	X	char 	*redirect;
	X	FILE 	*tmpPtr;
	X
	X	/*
	X	 *  Open an output file if we see '>' or >>'.
	X	 *  Check for overwrite (">") or concatenation (">>").
	X	 */
	X
	X	redirect = index(string, '>');
	X	if (redirect == NULL) {
	X	    return(NULL);
	X	}
	X	if (redirect[1] == '>') {
	X	    sscanf(redirect, ">> %s", file);
	X	    tmpPtr = fopen(file, "a+");
	X	} else {
	X	    sscanf(redirect, "> %s", file);
	X	    tmpPtr = fopen(file, "w");
	X	}
	X
	X	if (tmpPtr != NULL) {
	X	    redirect[0] = '\0';
	X	}
	X
	X	return(tmpPtr);
	X}
	X
	X/*
	X *******************************************************************************
	X *
	X *  DecodeError --
	X *
	X *	Converts an error code into a character string.
	X *
	X *******************************************************************************
	X */
	X
	Xchar *
	XDecodeError(result)
	X    int result;
	X{
	X	switch(result) {
	X	    case NOERROR: 	return("Success"); break;
	X	    case FORMERR:	return("Format error"); break;
	X	    case SERVFAIL:	return("Server failed"); break;
	X	    case NXDOMAIN:	return("Non-existent domain"); break;
	X	    case NOTIMP:	return("Not implemented"); break;
	X	    case REFUSED:	return("Query refused"); break;
	X	    case NOCHANGE:	return("No change"); break;
	X	    case NO_INFO: 	return("No information"); break;
	X	    case ERROR: 	return("Unspecified error"); break;
	X	    case TIME_OUT: 	return("Timed out"); break;
	X	    case NONAUTH: 	return("Non-authoritative answer"); break;
	X	    default: 		break;
	X	}
	X	return("BAD ERROR VALUE"); 
	X}
	X
	Xint
	XStringToClass(class, dflt)
	X    char *class;
	X    int dflt;
	X{
	X	if (strcasecmp(class, "IN") == 0)
	X		return(C_IN);
	X	if (strcasecmp(class, "CHAOS") == 0)
	X		return(C_CHAOS);
	X	if (strcasecmp(class, "ANY") == 0)
	X		return(C_ANY);
	X	fprintf(stderr, "unknown query class: %s\n", class);
	X	return(dflt);
	X}
	X/*
	X *******************************************************************************
	X *
	X *  StringToType --
	X *
	X *	Converts a string form of a query type name to its 
	X *	corresponding integer value.
	X *
	X *******************************************************************************
	X */
	X
	Xint
	XStringToType(type, dflt)
	X    char *type;
	X    int dflt;
	X{
	X	if (strcasecmp(type, "A") == 0)
	X		return(T_A);
	X	if (strcasecmp(type, "NS") == 0)
	X		return(T_NS);			/* authoritative server */
	X	if (strcasecmp(type, "MX") == 0)
	X		return(T_MX);			/* mail exchanger */
	X	if (strcasecmp(type, "CNAME") == 0)
	X		return(T_CNAME);		/* canonical name */
	X	if (strcasecmp(type, "SOA") == 0)
	X		return(T_SOA);			/* start of authority zone */
	X	if (strcasecmp(type, "MB") == 0)
	X		return(T_MB);			/* mailbox domain name */
	X	if (strcasecmp(type, "MG") == 0)
	X		return(T_MG);			/* mail group member */
	X	if (strcasecmp(type, "MR") == 0)
	X		return(T_MR);			/* mail rename name */
	X	if (strcasecmp(type, "WKS") == 0)
	X		return(T_WKS);			/* well known service */
	X	if (strcasecmp(type, "PTR") == 0)
	X		return(T_PTR);			/* domain name pointer */
	X	if (strcasecmp(type, "HINFO") == 0)
	X		return(T_HINFO);		/* host information */
	X	if (strcasecmp(type, "MINFO") == 0)
	X		return(T_MINFO);		/* mailbox information */
	X	if (strcasecmp(type, "AXFR") == 0)
	X		return(T_AXFR);			/* zone transfer */
	X	if (strcasecmp(type, "MAILB") == 0)
	X		return(T_MAILB);		/* mail box */
	X	if (strcasecmp(type, "ANY") == 0)
	X		return(T_ANY);			/* matches any type */
	X	if (strcasecmp(type, "UINFO") == 0)
	X		return(T_UINFO);		/* user info */
	X	if (strcasecmp(type, "UID") == 0)
	X		return(T_UID);			/* user id */
	X	if (strcasecmp(type, "GID") == 0)
	X		return(T_GID);			/* group id */
	X	fprintf(stderr, "unknown query type: %s\n", type);
	X	return(dflt);
	X}
	X
	X/*
	X *******************************************************************************
	X *
	X *  DecodeType --
	X *
	X *	Converts a query type to a descriptive name.
	X *	(A more verbose form of p_type.)
	X *
	X *
	X *******************************************************************************
	X */
	X
	Xstatic  char nbuf[20];
	X
	Xchar *
	XDecodeType(type)
	X	int type;
	X{
	X	switch (type) {
	X	case T_A:
	X		return("address");
	X	case T_NS:
	X		return("name server");
	X	case T_MX:		
	X		return("mail exchanger");
	X	case T_CNAME:		
	X		return("cannonical name");
	X	case T_SOA:		
	X		return("start of authority zone");
	X	case T_MB:		
	X		return("mailbox domain name");
	X	case T_MG:		
	X		return("mail group member");
	X	case T_MR:		
	X		return("mail rename name");
	X	case T_NULL:		
	X		return("null resource record");
	X	case T_WKS:		
	X		return("well known service");
	X	case T_PTR:		
	X		return("domain name pointer");
	X	case T_HINFO:		
	X		return("host");
	X	case T_MINFO:		
	X		return("mailbox (MINFO)");
	X	case T_AXFR:		
	X		return("zone transfer");
	X	case T_MAILB:		
	X		return("mail box");
	X	case T_ANY:		
	X		return("any type");
	X	case T_UINFO:
	X		return("user info");
	X	case T_UID:
	X		return("user id");
	X	case T_GID:
	X		return("group id");
	X	default:
	X		(void) sprintf(nbuf, "%d", type);
	X		return (nbuf);
	X	}
	X}
SHAR_EOF
if test 10791 -ne "`wc -c < 'subr.c'`"
then
	echo shar: "error transmitting 'subr.c'" '(should have been 10791 characters)'
fi
fi
exit 0
#	End of shell archive

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

If you are on the internet and want your Masscomp to understand the Domain
Name Service, here is the first step. This is the resolver library.
This code is based on BIND 4.8 with all patches to date.

Enjoy.

#! /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:
#	tools/nslookup/list.c
#	tools/nslookup/main.c
#	tools/nslookup/makefile
# This archive created: Mon Jul  4 20:28:26 1988
export PATH; PATH=/bin:/usr/bin:$PATH
if test ! -d 'tools'
then
	echo shar: "creating directory 'tools'"
	mkdir 'tools'
fi
echo shar: "entering directory 'tools'"
cd 'tools'
if test ! -d 'nslookup'
then
	echo shar: "creating directory 'nslookup'"
	mkdir 'nslookup'
fi
echo shar: "entering directory 'nslookup'"
cd 'nslookup'
echo shar: "extracting 'list.c'" '(20445 characters)'
if test -f 'list.c'
then
	echo shar: "will not over-write existing file 'list.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'list.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#ifndef lint
	Xstatic char sccsid[] = "@(#)list.c	5.10 (Berkeley) 2/17/88";
	X#endif /* not lint */
	X
	X/*
	X *******************************************************************************
	X *
	X *  list.c --
	X *
	X *	Routines to obtain info from name and finger servers.
	X *
	X *	Adapted from 4.3BSD BIND ns_init.c and from /usr/src/ucb/finger.c
	X *
	X *******************************************************************************
	X */
	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 <netdb.h>
	X#include <stdio.h>
	X#ifdef SYS5
	X#include <string.h>
	X#else
	X#include <strings.h>
	X#endif
	X#include <ctype.h>
	X#include <arpa/nameser.h>
	X#include <resolv.h>
	X#include "res.h"
	X
	X/*
	X *  Imported from res_debug.c
	X */
	Xextern char *_res_resultcodes[];
	X
	Xtypedef union {
	X    HEADER qb1;
	X    char qb2[PACKETSZ];
	X} querybuf;
	X
	Xextern u_long 		inet_addr();
	Xextern HostInfo 	*defaultPtr;
	Xextern HostInfo 	curHostInfo;
	Xextern int 		curHostValid;
	X
	X/*
	X *  During a listing to a file, hash marks are printed 
	X *  every HASH_SIZE records.
	X */
	X
	X#define HASH_SIZE 50
	X
	X
	X/*
	X *******************************************************************************
	X *
	X *  ListHosts --
	X *
	X *	Requests the name server to do a zone transfer so we
	X *	find out what hosts it knows about.
	X *
	X *	There are five types of output:
	X *	- internet addresses (default)
	X *	- cpu type and operating system (-h option)
	X *	- canonical and alias names  (-a option)
	X *	- well-known service names  (-s option)
	X *	- ALL records (-d option)
	X *	
	X *	To see all three types of information in sorted order, 
	X *	do the following:
	X *	  ls domain.edu > file
	X *	  ls -a domain.edu >> file
	X *	  ls -h domain.edu >> file
	X *	  ls -s domain.edu >> file
	X *	  view file
	X *
	X *  Results:
	X *	SUCCESS		the listing was successful.
	X *	ERROR		the server could not be contacted because 
	X *			a socket could not be obtained or an error
	X *			occured while receiving, or the output file
	X *			could not be opened.
	X *
	X *******************************************************************************
	X */
	X
	Xint
	XListHosts(string, putToFile)
	X    char *string;
	X    int  putToFile;
	X{
	X	querybuf 		buf;
	X	struct sockaddr_in 	sin;
	X	HEADER 			*headerPtr;
	X	int 			queryType;
	X	int 			msglen;
	X	int 			amtToRead;
	X	int 			numRead;
	X	int 			i;
	X	int 			numAnswers = 0;
	X	int 			result;
	X	int 			soacnt = 0;
	X	u_short 		len;
	X	char 			*cp, *nmp;
	X	char 			name[NAME_LEN];
	X	char 			dname[2][NAME_LEN];
	X	char 			option[NAME_LEN];
	X	char 			file[NAME_LEN];
	X	char			*namePtr;
	X	enum {
	X	    NO_ERRORS, 
	X	    ERR_READING_LEN, 
	X	    ERR_READING_MSG,
	X	    ERR_PRINTING,
	X	} error = NO_ERRORS;
	X
	X
	X	/*
	X	 *
	X    /*
	X     *  Parse the command line. It maybe of the form "ls domain",
	X     *  "ls -a domain" or "ls -h domain".
	X     */ 
	X	i = sscanf(string, " ls %s %s", option, name);
	X	if (putToFile && i == 2 && name[0] == '>') {
	X	    i--;
	X	}
	X	if (i == 2) {
	X	    if (strcmp("-a", option) == 0) {
	X		queryType = T_CNAME;
	X	    } else if (strcmp("-h", option) == 0) {
	X		queryType = T_HINFO;
	X	    } else if (strcmp("-m", option) == 0) {
	X		queryType = T_MX;
	X	    } else if (strcmp("-s", option) == 0) {
	X		queryType = T_WKS;
	X	    } else if (strcmp("-d", option) == 0) {
	X		queryType = T_ANY;
	X	    } else {
	X		queryType = T_A;
	X	    }
	X	    namePtr = name;
	X	} else if (i == 1) {
	X	    namePtr = option;
	X	    queryType = T_A;
	X	} else {
	X	    fprintf(stderr, "ListHosts: invalid request %s\n",string);
	X	    return(ERROR);
	X	}
	X
	X
	X	/*
	X	 *  Create a query packet for the requested domain name.
	X	 *
	X	 */
	X	msglen = res_mkquery(QUERY, namePtr, C_IN, T_AXFR,
	X				(char *)0, 0, (char *)0, 
	X				(char *) &buf, sizeof(buf));
	X	if (msglen < 0) {
	X	    if (_res.options & RES_DEBUG) {
	X		fprintf(stderr, "ListHosts: Res_mkquery failed\n");
	X	    }
	X	    return (ERROR);
	X	}
	X
	X#ifdef SYS5
	X	memset((char *)&sin, '\0',  sizeof(sin));
	X#else
	X	bzero((char *)&sin, sizeof(sin));
	X#endif
	X	sin.sin_family	= AF_INET;
	X	sin.sin_port	=  htons(NAMESERVER_PORT);
	X
	X	/*
	X	 *  Check to see if we have the address of the server or the
	X	 *  address of a server who knows about this domain.
	X	 *       
	X	 *  For now, just use the first address in the list.
	X	 */
	X
	X	if (defaultPtr->addrList != NULL) {
	X	  sin.sin_addr = *(struct in_addr *) defaultPtr->addrList[0];
	X	} else {
	X	  sin.sin_addr = *(struct in_addr *)defaultPtr->servers[0]->addrList[0];
	X	}
	X
	X	/*
	X	 *  Set up a virtual circuit to the server.
	X	 */
	X#ifdef EXOS
	X	if ((sockFD = socket(SOCK_STREAM, 0, 0, 0)) < 0) {
	X#else
	X	if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
	X#endif
	X	    perror("ListHosts");
	X	    return(ERROR);
	X	}	
	X#ifdef EXOS
	X	if (connect(sockFD, &sin) < 0) {
	X#else
	X	if (connect(sockFD, &sin, sizeof(sin)) < 0) {
	X#endif
	X	    perror("ListHosts");
	X	    (void) close(sockFD);
	X	    sockFD = -1;
	X	    return(ERROR);
	X	}	
	X
	X	/*
	X	 * Send length & message for zone transfer 
	X	 */
	X
	X        len = htons(msglen);
	X
	X        if (write(sockFD, (char *)&len, sizeof(len)) != sizeof(len) ||
	X            write(sockFD, (char *) &buf, msglen) != msglen) {
	X		perror("ListHosts");
	X		(void) close(sockFD);
	X		sockFD = -1;
	X		return(ERROR);
	X	}
	X
	X	fprintf(stdout,"[%s]\n",
	X		(defaultPtr->addrList != NULL) ? defaultPtr->name : 
	X		 defaultPtr->servers[0]->name);
	X
	X	if (!putToFile) {
	X	    filePtr = stdout;
	X	} else {
	X	    filePtr = OpenFile(string, file);
	X            if (filePtr == NULL) {
	X                fprintf(stderr, "*** Can't open %s for writing\n", file);
	X		(void) close(sockFD);
	X		sockFD = -1;
	X                return(ERROR);
	X            }
	X	    fprintf(filePtr, "> %s\n", string);
	X	    fprintf(filePtr,"[%s]\n",
	X		(defaultPtr->addrList != NULL) ? defaultPtr->name : 
	X		 defaultPtr->servers[0]->name);
	X	}
	X
	X	fprintf(filePtr, "%-30s", "Host or domain name");
	X	switch(queryType) {
	X	    case T_ANY:
	X		    fprintf(filePtr, " %-30s\n", "Resource record info");
	X		    break;
	X	    case T_A:
	X		    fprintf(filePtr, " %-30s\n", "Internet address");
	X		    break;
	X	    case T_HINFO:
	X		    fprintf(filePtr, " %-10s %s\n", "CPU", "OS");
	X		    break;
	X	    case T_CNAME:
	X		    fprintf(filePtr, " %-30s\n", "Alias");
	X		    break;
	X	    case T_MX:
	X		    fprintf(filePtr, " %3s %s\n", "Metric", "Host");
	X		    break;
	X	    case T_WKS:
	X		    fprintf(filePtr, " %-4s %s\n", "Protocol", "Services");
	X	}
	X
	X
	X	while (1) {
	X
	X	    /*
	X	     * Read the length of the response.
	X	     */
	X
	X	    cp = (char *) &buf;
	X	    amtToRead = sizeof(u_short);
	X	    while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){
	X		cp 	  += numRead;
	X		amtToRead -= numRead;
	X	    }
	X	    if (numRead <= 0) {
	X		error = ERR_READING_LEN;
	X		break;
	X	    }	
	X
	X	    if ((len = htons(*(u_short *)&buf)) == 0) {
	X		break;	/* nothing left to read */
	X	    }
	X
	X	    /*
	X	     * Read the response.
	X	     */
	X
	X	    amtToRead = len;
	X	    cp = (char *) &buf;
	X	    while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){
	X		cp += numRead;
	X		amtToRead -= numRead;
	X	    }
	X	    if (numRead <= 0) {
	X		error = ERR_READING_MSG;
	X		break;
	X	    }
	X
	X	    result = PrintListInfo(filePtr, (char *) &buf, cp, queryType);
	X	    if (result != SUCCESS) {
	X		error = ERR_PRINTING;
	X		break;
	X	    }
	X
	X	    numAnswers++;
	X	    if (putToFile && ((numAnswers % HASH_SIZE) == 0)) {
	X		fprintf(stdout, "#");
	X		fflush(stdout);
	X	    }
	X	    cp = buf.qb2 + sizeof(HEADER);
	X	    if (ntohs(buf.qb1.qdcount) > 0)
	X		cp += dn_skipname(cp, buf.qb2 + len) + QFIXEDSZ;
	X	    nmp = cp;
	X	    cp += dn_skipname(cp, (u_char *)&buf + len);
	X	    if ((_getshort(cp) == T_SOA)) {
	X		dn_expand(buf.qb2, buf.qb2 + len, nmp, dname[soacnt],
	X			sizeof(dname[0]));
	X	        if (soacnt) {
	X		    if (strcmp(dname[0], dname[1]) == 0)
	X			break;
	X		} else
	X		    soacnt++;
	X	    }
	X	}
	X
	X	if (putToFile) {
	X	    fprintf(stdout, "%sReceived %d record%s.\n", 
	X		(numAnswers >= HASH_SIZE) ? "\n" : "",
	X		numAnswers,
	X		(numAnswers > 1) ? "s" : "");
	X	}
	X
	X	(void) close(sockFD);
	X	sockFD = -1;
	X	if (putToFile) {
	X	    fclose(filePtr);
	X	    filePtr = NULL;
	X	}
	X
	X	switch ((int)error) {
	X	    case NO_ERRORS:
	X		return (SUCCESS);
	X
	X	    case ERR_READING_LEN:
	X		return(ERROR);
	X
	X	    case ERR_PRINTING:
	X		fprintf(stderr,"*** Error during listing of %s: %s\n", 
	X				namePtr, DecodeError(result));
	X		return(result);
	X
	X	    case ERR_READING_MSG:
	X		headerPtr = (HEADER *) &buf;
	X		fprintf(stderr,"ListHosts: error receiving zone transfer:\n");
	X		fprintf(stderr,
	X	       "  result: %s, answers = %d, authority = %d, additional = %d\n", 
	X		    	_res_resultcodes[headerPtr->rcode], 
	X		    	ntohs(headerPtr->ancount), ntohs(headerPtr->nscount), 
	X			ntohs(headerPtr->arcount));
	X		return(ERROR);
	X	    default:
	X		return(ERROR);
	X	}
	X}
	X
	X
	X/*
	X *******************************************************************************
	X *
	X *  PrintListInfo --
	X *
	X * 	Used by the ListInfo routine to print the answer 
	X *	received from the name server. Only the desired 
	X *	information is printed.
	X *
	X *  Results:
	X *	SUCCESS		the answer was printed without a problem.
	X *	NO_INFO		the answer packet did not contain an answer.
	X *	ERROR		the answer was malformed.
	X *      Misc. errors	returned in the packet header.
	X *
	X *******************************************************************************
	X */
	X
	X#define NAME_FORMAT " %-30s"
	X#define STRIP_DOMAIN(string) if((dot = index(string, '.')) != NULL) *dot = '\0'
	X
	X
	XPrintListInfo(file, msg, eom, queryType)
	X    FILE 	*file;
	X    char 	*msg, *eom;
	X    int 	queryType;
	X{
	X    register char 	*cp;
	X    HEADER 		*headerPtr;
	X    int 		type, class, dlen, nameLen;
	X    u_long		ttl;
	X    int 		n;
	X    struct in_addr 	inaddr;
	X    char 		name[NAME_LEN];
	X    char 		name2[NAME_LEN];
	X    char 		*dot;
	X
	X    /*
	X     * Read the header fields.
	X     */
	X    headerPtr = (HEADER *)msg;
	X    cp = msg + sizeof(HEADER);
	X    if (headerPtr->rcode != NOERROR) {
	X	return(headerPtr->rcode);
	X    }
	X
	X    /*
	X     *  We are looking for info from answer resource records.
	X     *  If there aren't any, return with an error. We assume
	X     *  there aren't any question records.
	X     */
	X
	X    if (ntohs(headerPtr->ancount) == 0) {
	X	return(NO_INFO);
	X    } else {
	X	if (ntohs(headerPtr->qdcount) > 0) {
	X	    nameLen = dn_skipname(cp, eom);
	X	    if (nameLen < 0)
	X		return (ERROR);
	X	    cp += nameLen + QFIXEDSZ;
	X	}
	X	if ((nameLen = dn_expand(msg, eom, cp, name, sizeof(name))) < 0) {
	X	    return (ERROR);
	X	}
	X	cp += nameLen;
	X	type = _getshort(cp);
	X	cp += sizeof(u_short);
	X	class = _getshort(cp);
	X	cp += sizeof(u_short);
	X	ttl = _getlong(cp);
	X	cp += sizeof(u_long);
	X	dlen = _getshort(cp);
	X	cp += sizeof(u_short);
	X	if (name[0] == 0)
	X		strcpy(name, "(root)");
	X
	X	/*
	X	 * QueryType is used to specify the type of desired information.
	X	 *  T_A   	- internet address
	X	 *  T_CNAME 	- aliases
	X	 *  T_HINFO	- cpu, OS type
	X	 *  T_MX	- mail routing
	X	 *  T_WKS	- well known service
	X	 *  T_ANY	- any
	X	 *
	X	 */
	X	switch (type) {
	X
	X	    case T_A:
	X		if (queryType != T_A && queryType != T_ANY)
	X		    break;
	X
	X		if ((_res.options & RES_DEBUG) == 0)
	X		    STRIP_DOMAIN(name);
	X		fprintf(file, NAME_FORMAT, name);
	X		if (queryType == T_ANY)
	X		    fprintf(file," %-5s", p_type(type));
	X		if (class == C_IN) {
	X#ifdef SYS5
	X		    (void)memcpy((char *)&inaddr, cp, sizeof(inaddr));
	X#else
	X		    bcopy(cp, (char *)&inaddr, sizeof(inaddr));
	X#endif
	X		    if (dlen == 4) {
	X			fprintf(file," %s", inet_ntoa(inaddr));
	X		    } else if (dlen == 7) {
	X			fprintf(file," %s", inet_ntoa(inaddr));
	X			fprintf(file," (%d, %d)", cp[4],(cp[5] << 8) + cp[6]);
	X		    } else
	X			fprintf(file, " (dlen = %d?)", dlen);
	X		    if (_res.options & RES_DEBUG)
	X			fprintf(file,"\t\t\t%lu", ttl);
	X		    fprintf(file,"\n");
	X		} else
	X		    goto other;
	X		break;
	X		
	X	    case T_CNAME:
	X		if (queryType != T_CNAME && queryType != T_ANY)
	X		    break;
	X
	X		if ((_res.options & RES_DEBUG) == 0)
	X			STRIP_DOMAIN(name);
	X		fprintf(file, NAME_FORMAT, name);
	X		if (queryType == T_ANY)
	X		    fprintf(file," %-5s", p_type(type));
	X		if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
	X		    fprintf(file, " ***\n");
	X		    return (ERROR);
	X		}
	X		/* 
	X		 * a bug -- cnames need not be in same domain!
	X		 * STRIP_DOMAIN(name2);
	X		 */
	X
	X		fprintf(file, NAME_FORMAT, name2);
	X		if (_res.options & RES_DEBUG)
	X		    fprintf(file,"\t%lu", ttl);
	X		fprintf(file,"\n");
	X		break;
	X		
	X	    case T_HINFO:
	X		if (queryType != T_HINFO && queryType != T_ANY)
	X		    break;
	X
	X		if ((_res.options & RES_DEBUG) == 0)
	X		    STRIP_DOMAIN(name);
	X		fprintf(file, NAME_FORMAT, name);
	X		if (queryType == T_ANY)
	X		    fprintf(file," %-5s", p_type(type));
	X		if (n = *cp++) {
	X		    (void)sprintf(name,"%.*s", n, cp);
	X		    fprintf(file," %-10s", name);
	X		    cp += n;
	X		} else {
	X		    fprintf(file," %-10s", " ");
	X		}
	X		if (n = *cp++) {
	X		    fprintf(file," %.*s", n, cp);
	X		    cp += n;
	X		}
	X		if (_res.options & RES_DEBUG)
	X		    fprintf(file,"\t\t%lu", ttl);
	X		fprintf(file,"\n");
	X		break;
	X
	X	    case T_MX:
	X		if (queryType != T_MX && queryType != T_ANY)
	X		    break;
	X
	X		if ((_res.options & RES_DEBUG) == 0)
	X		    STRIP_DOMAIN(name);
	X		fprintf(file, NAME_FORMAT, name);
	X		if (queryType == T_ANY)
	X		    fprintf(file," %-5s", p_type(type));
	X
	X		{
	X		    short pref;
	X
	X		    pref = _getshort(cp);
	X		    cp += sizeof(u_short);
	X		    fprintf(file," %-3d ",pref);
	X		}
	X		if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
	X		    fprintf(file, " ***\n");
	X		    return (ERROR);
	X		}
	X		fprintf(file, " %s", name2);
	X		if (_res.options & RES_DEBUG)
	X		    fprintf(file,"\t%lu", ttl);
	X		fprintf(file,"\n");
	X
	X		break;
	X
	X
	X	    case T_NS:
	X	    case T_PTR:
	X		if (queryType != T_A && queryType != T_ANY)
	X		    break;
	X		/*
	X		 *  Found a name server or pointer record.
	X		 */
	X		if ((_res.options & RES_DEBUG) == 0)
	X		    STRIP_DOMAIN(name);
	X		fprintf(file, NAME_FORMAT, name);
	X		if (queryType == T_ANY)
	X		    fprintf(file," %-5s", p_type(type));
	X		fprintf(file," %s = ", type == T_PTR ? "host" : "server");
	X		cp = Print_cdname2(cp, msg, eom, file);
	X		if (_res.options & RES_DEBUG)
	X		    fprintf(file,"\t%lu", ttl);
	X		fprintf(file,"\n");
	X		break;
	X
	X	    case T_WKS:
	X		if (queryType != T_WKS && queryType != T_ANY)
	X		    break;
	X
	X		if ((_res.options & RES_DEBUG) == 0)
	X		    STRIP_DOMAIN(name);
	X		fprintf(file, NAME_FORMAT, name);
	X		if (queryType == T_ANY)
	X		    fprintf(file," %-5s", p_type(type));
	X		if (class == C_IN) {
	X		    cp += 4; dlen -= 4;
	X		    {
	X			struct protoent *pp;
	X			struct servent *ss;
	X			u_short port;
	X#ifndef EXOS
	X
	X			setprotoent(1);
	X			setservent(1);
	X#endif
	X			n = *cp & 0377;
	X#ifdef EXOS
	X			pp = 0;
	X#else
	X			pp = getprotobynumber(n);
	X#endif
	X			if(pp == 0)  
	X			    fprintf(file," %-3d ", n);
	X			else
	X			    fprintf(file," %-3s ", pp->p_name);
	X			cp++; dlen--;
	X
	X			port = 0;
	X			while(dlen-- > 0) {
	X			    n = *cp++;
	X			    do {
	X				if(n & 0200) {
	X#ifdef EXOS
	X				     ss = 0;
	X#else
	X				     ss = getservbyport((int)htons(port), pp->p_name);
	X#endif
	X				    if(ss == 0)  
	X					fprintf(file," %d", port);
	X				    else
	X					fprintf(file," %s", ss->s_name);
	X				}
	X				    n <<= 1;
	X			    } while(++port & 07);
	X			}
	X		    } 
	X		} else
	X		    goto other;
	X		if (_res.options & RES_DEBUG)
	X		    fprintf(file,"\t%lu", ttl);
	X		fprintf(file,"\n");
	X#ifndef EXOS
	X		endprotoent();
	X		endservent();
	X#endif
	X		break;
	X
	X	    case T_SOA:
	X	    case T_AXFR:
	X		if (queryType != T_ANY)
	X		    break;
	X		fprintf(file, NAME_FORMAT, name);
	X		if (queryType == T_ANY)
	X		    fprintf(file," %-5s", p_type(type));
	X		if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
	X		    fprintf(file, " ***\n");
	X		    return (ERROR);
	X		}
	X		cp += nameLen;
	X		fprintf(file, " %s", name2);
	X		if ((nameLen = dn_expand(msg, eom, cp, name2, sizeof(name2))) < 0) {
	X		    fprintf(file, " ***\n");
	X		    return (ERROR);
	X		}
	X		cp += nameLen;
	X		fprintf(file, " %s. (", name2);
	X		for (n = 0; n < 5; n++) {
	X		    u_long u;
	X
	X		    u = _getlong(cp);
	X		    cp += sizeof(u_long);
	X		    fprintf(file,"%s%d", n? " " : "", u);
	X		}
	X		fprintf(file, ")", name2);
	X		if (_res.options & RES_DEBUG)
	X		    fprintf(file,"\t%lu", ttl);
	X		fprintf(file,"\n");
	X		break;
	X
	X	    default:
	X		/*
	X		 * Unwanted answer type -- ignore it.
	X		 */
	X		if (queryType != T_ANY)
	X		    break;
	X		if ((_res.options & RES_DEBUG) == 0)
	X		    STRIP_DOMAIN(name);
	X		fprintf(file, NAME_FORMAT, name);
	Xother:
	X		fprintf(file," type = %-5s", p_type(type));
	X		fprintf(file,", class = %-5s", p_class(class));
	X		if (_res.options & RES_DEBUG)
	X		    fprintf(file,"\t%lu\n", ttl);
	X		break;
	X	}
	X    }
	X    return(SUCCESS);
	X}
	X
	X
	X/*
	X *******************************************************************************
	X *
	X *  ViewList --
	X *
	X *	A hack to view the output of the ls command in sorted
	X *	order using more.
	X *
	X *******************************************************************************
	X */
	X
	XViewList(string)
	X    char *string;
	X{
	X    char file[NAME_LEN];
	X    char command[NAME_LEN];
	X
	X    sscanf(string, " view %s", file);
	X    (void)sprintf(command, "grep \"^ \" %s | sort | more", file);
	X    system(command);
	X}
	X
	X/*
	X *******************************************************************************
	X *
	X *   Finger --
	X *
	X *	Connects with the finger server for the current host
	X *	to request info on the specified person (long form)
	X *	who is on the system (short form).
	X *
	X *  Results:
	X *	SUCCESS		the finger server was contacted.
	X *	ERROR		the server could not be contacted because 
	X *			a socket could not be obtained or connected 
	X *			to or the service could not be found.
	X *
	X *******************************************************************************
	X */
	X
	XFinger(string, putToFile)
	X    char *string;
	X    int  putToFile;
	X{
	X	struct servent 		*sp;
	X	struct sockaddr_in 	sin;
	X	register FILE 		*f;
	X	register int 		c;
	X	register int 		lastc;
	X	char 			name[NAME_LEN];
	X	char 			file[NAME_LEN];
	X
	X	/*
	X	 *  We need a valid current host info to get an inet address.
	X	 */
	X	if (!curHostValid) {
	X	    fprintf(stderr, "Finger: no current host defined.\n");
	X	    return (ERROR);
	X	}
	X
	X	if (sscanf(string, " finger %s", name) == 1) {
	X	    if (putToFile && (name[0] == '>')) {
	X		name[0] = '\0';
	X	    }
	X	} else {
	X	    name[0] = '\0';
	X	}
	X
	X#ifdef SYS5
	X	memset((char *)&sin, '\0', sizeof(sin));
	X#else
	X	bzero((char *)&sin, sizeof(sin));
	X#endif
	X	sin.sin_family	= curHostInfo.addrType;
	X#ifdef SYS5
	X	(void)memcpy((char *)&sin.sin_addr, curHostInfo.addrList[0],
	X#else
	X	bcopy(curHostInfo.addrList[0], (char *)&sin.sin_addr, 
	X#endif
	X		curHostInfo.addrLen);
	X#ifdef EXOS
	X	sin.sin_port = IPPORT_FINGER;
	X	sockFD = socket(SOCK_STREAM, 0, (struct sockproto *) 0, 0);
	X	if (sockFD < 0) {
	X	    fflush(stdout);
	X	    perror("Finger");
	X	    return (ERROR);
	X	}
	X
	X	if (connect(sockFD, (char *)&sin) < 0) {
	X	    fflush(stdout);
	X	    perror("Finger");
	X	    close(sockFD);
	X	    sockFD = -1;
	X	    return (ERROR);
	X	}
	X#else
	X	sp = getservbyname("finger", "tcp");
	X	if (sp == 0) {
	X	    fprintf(stderr, "Finger: unknown service\n");
	X	    return (ERROR);
	X	}
	X	sin.sin_port	= sp->s_port;
	X	/*
	X	 *  Set up a virtual circuit to the host.
	X	 */
	X
	X#ifdef EXOS
	X	sockFD = socket(SOCK_STREAM, 0, 0, 0);
	X#else
	X	sockFD = socket(curHostInfo.addrType, SOCK_STREAM, 0);
	X#endif
	X
	X	if (sockFD < 0) {
	X	    fflush(stdout);
	X	    perror("Finger");
	X	    return (ERROR);
	X	}
	X
	X#ifdef EXOS
	X	if (connect(sockFD, (char *)&sin)) < 0) {
	X#else
	X	if (connect(sockFD, (char *)&sin, sizeof (sin)) < 0) {
	X#endif
	X	    fflush(stdout);
	X	    perror("Finger");
	X	    close(sockFD);
	X	    sockFD = -1;
	X	    return (ERROR);
	X	}
	X#endif
	X	if (!putToFile) {
	X	    filePtr = stdout;
	X	} else {
	X	    filePtr = OpenFile(string, file);
	X	    if (filePtr == NULL) {
	X		fprintf(stderr, "*** Can't open %s for writing\n", file);
	X		close(sockFD);
	X		sockFD = -1;
	X		return(ERROR);
	X	    }
	X	    fprintf(filePtr,"> %s\n", string);
	X	}
	X	fprintf(filePtr, "[%s]\n", curHostInfo.name);
	X
	X	if (name[0] != '\0') {
	X	    write(sockFD, "/W ", 3);
	X	}
	X	write(sockFD, name, strlen(name));
	X	write(sockFD, "\r\n", 2);
	X	f = fdopen(sockFD, "r");
	X	while ((c = getc(f)) != EOF) {
	X	    switch(c) {
	X		case 0210:
	X		case 0211:
	X		case 0212:
	X		case 0214:
	X			c -= 0200;
	X			break;
	X		case 0215:
	X			c = '\n';
	X			break;
	X	    }
	X	    putc(lastc = c, filePtr);
	X	}
	X	if (lastc != '\n') {
	X	    putc('\n', filePtr);
	X	}
	X	putc('\n', filePtr);
	X
	X	close(sockFD);
	X	sockFD = -1;
	X
	X	if (putToFile) {
	X	    fclose(filePtr);
	X	    filePtr = NULL;
	X	}
	X	return (SUCCESS);
	X}
SHAR_EOF
if test 20445 -ne "`wc -c < 'list.c'`"
then
	echo shar: "error transmitting 'list.c'" '(should have been 20445 characters)'
fi
fi
echo shar: "extracting 'main.c'" '(24577 characters)'
if test -f 'main.c'
then
	echo shar: "will not over-write existing file 'main.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'main.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#ifndef lint
	Xchar copyright[] =
	X"@(#) Copyright (c) 1985 Regents of the University of California.\n\
	X All rights reserved.\n";
	X#endif /* not lint */
	X
	X#ifndef lint
	Xstatic char sccsid[] = "@(#)main.c	5.15 (Berkeley) 3/26/88";
	X#endif /* not lint */
	X
	X/*
	X *******************************************************************************
	X *  
	X *   main.c --
	X *  
	X *  	Main routine and some action routines for the name server
	X *	lookup program.
	X *
	X *  	Andrew Cherenson 	CS298-26  Fall 1985
	X *  
	X *******************************************************************************
	X */
	X
	X#include <stdio.h>
	X#ifdef SYS5
	X#include <string.h>
	X#else
	X#include <strings.h>
	X#endif
	X#include <sys/param.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#endif
	X#include <netdb.h>
	X#include <sys/socket.h>
	X#include <netinet/in.h>
	X#include <arpa/nameser.h>
	X#include <resolv.h>
	X#include <signal.h>
	X#include <setjmp.h>
	X#include "res.h"
	X
	X/*
	X *  Location of the help file.
	X */
	X
	X#define HELPFILE "/usr1/local/lib/nslookup.help"
	X
	X
	X#if BSD < 43
	X/*
	X *  Internet address of the current host.
	X */
	X
	X#define LOCALHOST "127.0.0.1"
	X#endif
	X
	X
	X/*
	X * Name of a top-level name server. Can be changed with 
	X * the "set root" command.
	X */
	X
	X#define 	ROOT_SERVER "sri-nic.arpa."
	Xchar 		rootServerName[NAME_LEN];
	X
	X
	X/*
	X *  Import the state information from the resolver library.
	X */
	X
	Xextern struct state _res;
	X
	X
	X/*
	X *  Info about the most recently queried host.
	X */
	X
	XHostInfo	curHostInfo;
	Xint		curHostValid = FALSE;
	X
	X
	X/*
	X *  Info about the default name server.
	X */
	X
	XHostInfo 	*defaultPtr = NULL;
	Xchar 		defaultServer[NAME_LEN];
	Xstruct in_addr	defaultAddr;
	X
	X
	X/*
	X *  Initial name server query type is Address.
	X */
	X
	Xint 		queryType = T_A;
	Xint 		queryClass = C_IN;
	X
	X/*
	X * Stuff for Interrupt (control-C) signal handler.
	X *  SockFD is the file descriptor for sockets used to
	X *  connect with the name servers. It has to be global to
	X *  allow the interrupt handler can close open sockets.
	X */
	X
	Xextern int 	IntrHandler();
	Xint 		sockFD = -1;
	XFILE 		*filePtr;
	Xjmp_buf 	env;
	X
	X
	X
	X/*
	X *******************************************************************************
	X *
	X *  main --
	X *
	X *	Initializes the resolver library and determines the address
	X *	of the initial name server. The yylex routine is used to
	X *	read and perform commands.
	X *
	X *******************************************************************************
	X */
	X
	Xmain(argc, argv)
	X    int argc;
	X    char **argv;
	X{
	X    int 	result;
	X    char	hostName[NAME_LEN];
	X    char	*wantedHost = NULL;
	X    int		useLocalServer;
	X    int		i;
	X    struct hostent	*hp;
	X    extern int	h_errno;
	X
	X    /*
	X     *  Initialize the resolver library routines.
	X     */
	X
	X    if (res_init() == -1) {
	X	fprintf(stderr,"*** Can't initialize resolver.\n");
	X	exit(1);
	X    }
	X
	X    /*
	X     *  Allocate space for the default server's host info and
	X     *  find the server's address and name. If the resolver library
	X     *  already has some addresses for a potential name server,
	X     *  then use them. Otherwise, see if the current host has a server.
	X     *  Command line arguments may override the choice of initial server. 
	X     */
	X
	X    defaultPtr = (HostInfo *) Calloc(1, sizeof(HostInfo));
	X
	X    /*
	X     * Parse the arguments:
	X     *  no args =  go into interactive mode, use default host as server
	X     *	1 arg	=  use as host name to be looked up, default host will be server
	X     *		   non-interactive mode
	X     *  2 args	=  1st arg: 
	X     *		     if it is '-', then 
	X     *		        ignore but go into interactive mode
	X     *	 	     else 
	X     *		         use as host name to be looked up, 
	X     *			 go into non-interactive mode
	X     *  	   2nd arg: name or inet address of server
	X     *
	X     */
	X
	X    useLocalServer = FALSE;
	X    if (argc > 1) {
	X	if (argc > 3) {
	X	    Usage();
	X	} 
	X	argv++;		/* skip prog name */
	X
	X	if (*argv[0] != '-') {
	X	    wantedHost = *argv;	/* name of host to be looked up */
	X	}
	X	if (argc == 3) {
	X
	X            /*
	X             *	Set explicit name server address.
	X             */ 
	X
	X	    _res.nscount = 1;
	X	    _res.nsaddr.sin_addr.s_addr = inet_addr(*++argv);
	X	    if (_res.nsaddr.sin_addr.s_addr == (unsigned)-1) {
	X		hp = gethostbyname(*argv);
	X		if (hp == NULL){
	X		    herror(h_errno);
	X	            _res.nscount = 0;
	X                    useLocalServer = TRUE;
	X		} else {
	X#if BSD > 42
	X#ifdef SYS5
	X		    (void)memcpy( &_res.nsaddr.sin_addr, hp->h_addr_list[0],
	X#else
	X		    bcopy(hp->h_addr_list[0], &_res.nsaddr.sin_addr,
	X#endif
	X		       hp->h_length);
	X#else
	X#ifdef SYS5
	X		    (void)memcpy( &_res.nsaddr.sin_addr,hp->h_addr,
	X#else
	X		    bcopy(hp->h_addr, &_res.nsaddr.sin_addr,
	X#endif
	X		       hp->h_length);
	X#endif
	X	            useLocalServer = FALSE;
	X		} 
	X	    }
	X        }
	X    }
	X
	X
	X    if (_res.nscount > 0 && !useLocalServer) {
	X	for (i = 0; i < _res.nscount; i++) {
	X	    if (_res.nsaddr_list[i].sin_addr.s_addr == INADDR_ANY) {
	X	        useLocalServer = TRUE;
	X		break;
	X	    } else {
	X		result = FindHostInfo(&(_res.nsaddr_list[i].sin_addr), 
	X				    &(_res.nsaddr_list[i].sin_addr), 
	X				    sizeof(struct in_addr),
	X				    defaultPtr);
	X		if (result != SUCCESS) {
	X		    fprintf(stderr,
	X		    "*** Can't find server name for address %s: %s\n", 
	X		       inet_ntoa(_res.nsaddr_list[i].sin_addr), 
	X		       DecodeError(result));
	X		} else {
	X		    defaultAddr = _res.nsaddr_list[i].sin_addr;
	X		    break;
	X		}
	X	    }
	X	}
	X
	X	/*
	X	 *  If we have exhausted the list, tell the user about the
	X	 *  command line argument to specify an address.
	X	 */
	X
	X	if (i == _res.nscount) {
	X	    fprintf(stderr, 
	X	    "*** Default servers are not available\n");
	X	    exit(1);
	X	}
	X
	X    }
	X    gethostname(hostName, sizeof(hostName));
	X#if BSD >= 43
	X    strcpy(defaultServer, hostName);
	X    (void) GetHostInfo(&defaultAddr, C_IN, T_A, "0.0.0.0", defaultPtr, 1);
	X    defaultPtr->name = hostName;
	X#else
	X    if (useLocalServer) {
	X	defaultAddr.s_addr = inet_addr(LOCALHOST);
	X	result = GetHostInfo(&defaultAddr, C_IN, T_A, hostName, defaultPtr, 1);
	X	if (result != SUCCESS) {
	X	    fprintf(stderr,
	X		"*** Can't find initialize address for server %s: %s\n", 
	X			    defaultServer, DecodeError(result));
	X	    exit(1);
	X	}
	X    }
	X    strcpy(defaultServer, defaultPtr->name);
	X#endif
	X
	X    strcpy(rootServerName, ROOT_SERVER);
	X
	X
	X#ifdef DEBUG
	X#ifdef DEBUG2
	X    _res.options |= RES_DEBUG2;
	X#endif
	X    _res.options |= RES_DEBUG;
	X    _res.retry    = 2;
	X#endif DEBUG
	X
	X    /*
	X     * If we're in non-interactive mode, look up the wanted host and quit.
	X     * Otherwise, print the initial server's name and continue with
	X     * the initialization.
	X     */
	X
	X    if (wantedHost != (char *) NULL) {
	X	LookupHost(wantedHost, 0);
	X	exit(0);
	X    } else {
	X	PrintHostInfo(stdout, "Default Server:", defaultPtr);
	X    }
	X
	X    /*
	X     * Setup the environment to allow the interrupt handler to return here.
	X     */
	X
	X    (void) setjmp(env);
	X
	X    /* 
	X     * Return here after a longjmp.
	X     */
	X
	X    signal(SIGINT, IntrHandler);
	X
	X    /*
	X     * Read and evaluate commands. The commands are described in commands.l
	X     * Yylex returns 0 when ^D or 'exit' is typed. 
	X     */
	X
	X    printf("> ");
	X    while(yylex()) {
	X	printf("> ");
	X    }
	X}
	X
	X
	X/*
	X *******************************************************************************
	X *
	X *  Usage --
	X *
	X *	Lists the proper methods to run the program and exits.
	X *
	X *******************************************************************************
	X */
	X
	XUsage()
	X{
	X    fprintf(sised 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 1351 -ne "`wc -c < 'README'`"
then
	echo shar: "error transmitting 'README'" '(should have been 1351 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'" '(6838 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 (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 6838 -ne "`wc -c < 'nameser.h'`"
then
	echo shar: "error transmitting 'nameser.h'" '(should have been 6838 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 ..
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: "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

 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

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

If you are on the internet and want your Masscomp to understand the Domain
Name Service, here is the first step. This is the resolver library.
This code is based on BIND 4.8 with all patches to date.

Enjoy.

#! /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/Makefile.libc
#	res/Makefile.resol
#	res/makefile
#	res/res_debug.c
#	res/res_comp.c
#	res/res_compat.c
#	res/herror.c
#	res/strcasecmp.c
# This archive created: Mon Jul  4 20:32:08 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 'Makefile.libc'" '(4950 characters)'
if test -f 'Makefile.libc'
then
	echo shar: "will not over-write existing file 'Makefile.libc'"
else
sed 's/^	X//' << \SHAR_EOF > 'Makefile.libc'
	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#	@(#)Makefile	5.16 (Berkeley) 3/14/88
	X#
	XSRCS=	getnetbyaddr.c getnetent.c getnetbyname.c getproto.c getprotoent.c \
	X	getprotoname.c getservent.c getservbyport.c getservbyname.c \
	X	herror.c rcmd.c rexec.c ruserpass.c res_comp.c res_debug.c \
	X	res_init.c res_mkquery.c res_query.c res_send.c
	XOBJS=	getnetbyaddr.o getnetent.o getnetbyname.o getproto.o getprotoent.o \
	X	getprotoname.o getservent.o getservbyport.o getservbyname.o \
	X	herror.o rcmd.o rexec.o ruserpass.o res_comp.o res_debug.o \
	X	res_init.o res_mkquery.o res_query.o res_send.o
	X
	XCFLAGS=	-O ${DEFS} -I../include		# Craig Finset, MSC, April 1988
	XTAGSFILE=tags
	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
	Xnetlib netlib_p: ${OBJS}
	X	@echo "building profiled netlib"
	X	@cd profiled; ar cru ../netlib_p ${OBJS}
	X	@echo "building normal netlib"
	X	@ar cru netlib ${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 profiled/*.o errs a.out core netlib netlib_p 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
	Xgetnetbyaddr.o: getnetbyaddr.c /usr/include/netdb.h
	Xgetnetent.o: getnetent.c /usr/include/stdio.h /usr/include/sys/types.h
	Xgetnetent.o: /usr/include/sys/socket.h /usr/include/netdb.h
	Xgetnetent.o: /usr/include/ctype.h
	Xgetnetbyname.o: getnetbyname.c /usr/include/netdb.h
	Xgetproto.o: getproto.c /usr/include/netdb.h
	Xgetprotoent.o: getprotoent.c /usr/include/stdio.h /usr/include/sys/types.h
	Xgetprotoent.o: /usr/include/sys/socket.h /usr/include/netdb.h
	Xgetprotoent.o: /usr/include/ctype.h
	Xgetprotoname.o: getprotoname.c /usr/include/netdb.h
	Xgetservent.o: getservent.c /usr/include/stdio.h /usr/include/sys/param.h
	Xgetservent.o: /usr/include/sys/types.h /usr/include/signal.h
	Xgetservent.o: /usr/include/machine/trap.h /usr/include/sys/types.h
	Xgetservent.o: /usr/include/sys/socket.h /usr/include/netdb.h
	Xgetservent.o: /usr/include/ctype.h
	Xgetservbyport.o: getservbyport.c /usr/include/netdb.h
	Xgetservbyname.o: getservbyname.c /usr/include/netdb.h
	Xherror.o: herror.c /usr/include/sys/types.h /usr/include/sys/uio.h
	Xrcmd.o: rcmd.c /usr/include/stdio.h /usr/include/ctype.h /usr/include/pwd.h
	Xrcmd.o: /usr/include/sys/param.h /usr/include/sys/types.h /usr/include/signal.h
	Xrcmd.o: /usr/include/machine/trap.h /usr/include/sys/file.h
	Xrcmd.o: /usr/include/sys/signal.h /usr/include/sys/socket.h
	Xrcmd.o: /usr/include/sys/stat.h /usr/include/netinet/in.h /usr/include/netdb.h
	Xrcmd.o: /usr/include/errno.h
	Xrexec.o: rexec.c /usr/include/sys/types.h /usr/include/sys/socket.h
	Xrexec.o: /usr/include/netinet/in.h /usr/include/stdio.h /usr/include/netdb.h
	Xrexec.o: /usr/include/errno.h
	Xruserpass.o: ruserpass.c /usr/include/stdio.h /usr/include/utmp.h
	Xruserpass.o: /usr/include/ctype.h /usr/include/sys/types.h
	Xruserpass.o: /usr/include/sys/stat.h /usr/include/errno.h
	Xres_comp.o: res_comp.c /usr/include/sys/types.h /usr/include/stdio.h
	Xres_comp.o: /usr/include/arpa/nameser.h
	Xres_debug.o: res_debug.c /usr/include/sys/types.h /usr/include/netinet/in.h
	Xres_debug.o: /usr/include/stdio.h /usr/include/arpa/nameser.h
	Xres_init.o: res_init.c /usr/include/sys/types.h /usr/include/sys/socket.h
	Xres_init.o: /usr/include/netinet/in.h /usr/include/stdio.h
	Xres_init.o: /usr/include/arpa/nameser.h /usr/include/resolv.h
	Xres_mkquery.o: res_mkquery.c /usr/include/stdio.h /usr/include/sys/types.h
	Xres_mkquery.o: /usr/include/netinet/in.h /usr/include/arpa/nameser.h
	Xres_mkquery.o: /usr/include/resolv.h
	Xres_query.o: res_query.c /usr/include/sys/param.h /usr/include/sys/types.h
	Xres_query.o: /usr/include/signal.h /usr/include/machine/trap.h
	Xres_query.o: /usr/include/sys/socket.h /usr/include/netinet/in.h
	Xres_query.o: /usr/include/ctype.h /usr/include/netdb.h /usr/include/stdio.h
	Xres_query.o: /usr/include/errno.h /usr/include/strings.h
	Xres_query.o: /usr/include/arpa/inet.h /usr/include/arpa/nameser.h
	Xres_query.o: /usr/include/resolv.h
	Xres_send.o: res_send.c /usr/include/sys/param.h /usr/include/sys/types.h
	Xres_send.o: /usr/include/signal.h /usr/include/machine/trap.h
	Xres_send.o: /usr/include/sys/time.h /usr/include/time.h
	Xres_send.o: /usr/include/sys/socket.h /usr/include/sys/uio.h
	Xres_send.o: /usr/include/netinet/in.h /usr/include/stdio.h /usr/include/errno.h
	Xres_send.o: /usr/include/arpa/nameser.h /usr/include/resolv.h
	X
	X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
SHAR_EOF
if test 4950 -ne "`wc -c < 'Makefile.libc'`"
then
	echo shar: "error transmitting 'Makefile.libc'" '(should have been 4950 characters)'
fi
fi
echo shar: "extracting 'Makefile.resol'" '(2051 characters)'
if test -f 'Makefile.resol'
then
	echo shar: "will not over-write existing file 'Makefile.resol'"
else
sed 's/^	X//' << \SHAR_EOF > 'Makefile.resol'
	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#	from @(#)Makefile	5.16 (Berkeley) 3/14/88
	X#
	XSHELL=	/bin/sh
	XSRCS=	herror.c res_comp.c res_debug.c res_init.c res_mkquery.c res_query.c \
	X	res_send.c strcasecmp.c named/gethnamadr.c named/sethostent.c \
	X	res_compat.c
	XOBJS=	herror.o res_comp.o res_debug.o res_init.o res_mkquery.o res_query.o \
	X	res_send.o strcasecmp.o gethnamadr.o sethostent.o res_compat.o
	X#	add -DDEBUG if you want the debugging code included
	X#	add -DSYS5 if you are compiling under System V
	X#	add -DEXOS if your computer has an EXCELAN board in it and you
	X#	are using the EXCELAN host software
	X#
	XDEFS=	-DSYS5 -DEXOS -DDEBUG
	XCFLAGS=	-O ${DEFS} -I../include -I/usr/include/NET-5000
	X# use echo is SYSTEM V, ranlib if 4.XBSD
	XRANLIB= echo
	X
	Xlibresolv.a: ${OBJS}
	X	ar cru libresolv.a ${OBJS}
	X
	Xinstall: libresolv.a
	X	cp libresolv.a ${DESTDIR}/usr/lib
	X	chown bin ${DESTDIR}/usr/lib/libresolv.a
	X	chgrp bin ${DESTDIR}/usr/lib/libresolv.a
	X	chmod 644 ${DESTDIR}/usr/lib/libresolv.a
	X	${RANLIB} ${DESTDIR}/usr/lib/libresolv.a
	X
	X.c.o:
	X	${CC} ${CFLAGS} -c $*.c
	X	-ld -x -r $*.o
	X	mv a.out $*.o
	X
	Xgethnamadr.o: named/gethnamadr.c
	X	${CC} -c ${CFLAGS} named/gethnamadr.c
	X	-ld -x -r gethnamadr.o
	X	mv a.out gethnamadr.o
	X
	Xsethostent.o: named/sethostent.c
	X	${CC} -c ${CFLAGS} named/sethostent.c
	X	-ld -x -r sethostent.o
	X	mv a.out sethostent.o
	X
	Xclean: FRC
	X	rm -f *.o errs a.out core libresolv.a tags
	X
	Xdepend: FRC
	X	../tools/mkdep -f Makfile.resolv ${CFLAGS} ${SRCS}
	X
	XFRC:
	X
	X# DO NOT DELETE THIS LINE -- mkdep uses it.
	X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
	X
	X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
SHAR_EOF
if test 2051 -ne "`wc -c < 'Makefile.resol'`"
then
	echo shar: "error transmitting 'Makefile.resol'" '(should have been 2051 characters)'
fi
fi
echo shar: "extracting 'makefile'" '(2094 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) 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#	from @(#)Makefile	5.16 (Berkeley) 3/14/88
	X#
	XSHELL=	/bin/sh
	XSRCS=	herror.c res_comp.c res_debug.c res_init.c res_mkquery.c res_query.c \
	X	res_send.c strcasecmp.c named/gethnamadr.c named/sethostent.c \
	X	res_compat.c
	XOBJS=	herror.o res_comp.o res_debug.o res_init.o res_mkquery.o res_query.o \
	X	res_send.o strcasecmp.o gethnamadr.o sethostent.o res_compat.o
	X#	add -DDEBUG if you want the debugging code included
	X#	add -DSYS5 if you are compiling under System V
	X#	add -DEXOS if your computer has an EXCELAN board in it and you
	X#	are using the EXCELAN host software
	X#	add -DMASSCOMP is your computer is a MASSCOMP
	X#
	XDEFS=	-DSYS5 -DMASSCOMP -DDEBUG
	XCFLAGS=	-O ${DEFS} -I../include 
	X# use echo is SYSTEM V, ranlib if 4.XBSD or MASSCOMP
	XRANLIB= ranlib
	X
	Xlibresolv.a: ${OBJS}
	X	ar cru libresolv.a ${OBJS}
	X
	Xinstall: libresolv.a
	X	cp libresolv.a ${DESTDIR}/usr/lib
	X	chown bin ${DESTDIR}/usr/lib/libresolv.a
	X	chgrp bin ${DESTDIR}/usr/lib/libresolv.a
	X	chmod 644 ${DESTDIR}/usr/lib/libresolv.a
	X	${RANLIB} ${DESTDIR}/usr/lib/libresolv.a
	X
	X.c.o:
	X	${CC} ${CFLAGS} -c $*.c
	X	-ld -x -r $*.o
	X	mv a.out $*.o
	X
	Xgethnamadr.o: named/gethnamadr.c
	X	${CC} -c ${CFLAGS} named/gethnamadr.c
	X	-ld -x -r gethnamadr.o
	X	mv a.out gethnamadr.o
	X
	Xsethostent.o: named/sethostent.c
	X	${CC} -c ${CFLAGS} named/sethostent.c
	X	-ld -x -r sethostent.o
	X	mv a.out sethostent.o
	X
	Xclean: FRC
	X	rm -f *.o errs a.out core libresolv.a tags
	X
	Xdepend: FRC
	X	../tools/mkdep -f Makfile.resolv ${CFLAGS} ${SRCS}
	X
	XFRC:
	X
	X# DO NOT DELETE THIS LINE -- mkdep uses it.
	X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
	X
	X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
SHAR_EOF
if test 2094 -ne "`wc -c < 'makefile'`"
then
	echo shar: "error transmitting 'makefile'" '(should have been 2094 characters)'
fi
fi
echo shar: "extracting 'res_debug.c'" '(12802 characters)'
if test -f 'res_debug.c'
then
	echo shar: "will not over-write existing file 'res_debug.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'res_debug.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_debug.c	5.22 (Berkeley) 3/7/88";
	X#endif /* LIBC_SCCS and not lint */
	X
	X#if defined(lint) && !defined(DEBUG)
	X#define DEBUG
	X#endif
	X
	X#include <sys/types.h>
	X#ifdef EXOS
	X#include <exos/misc.h>
	X#undef XFER
	X#endif
	X#include <netinet/in.h>
	X#include <stdio.h>
	X#include <arpa/nameser.h>
	X#ifdef XFER
	X#include <syslog.h>
	X#include <netdb.h>
	Xextern char *malloc();
	X#endif /* XFER */
	X
	Xextern char *p_cdname(), *p_rr(), *p_type(), *p_class(), *p_time();
	Xextern char *inet_ntoa();
	X
	Xchar *_res_opcodes[] = {
	X	"QUERY",
	X	"IQUERY",
	X	"CQUERYM",
	X	"CQUERYU",
	X	"4",
	X	"5",
	X	"6",
	X	"7",
	X	"8",
	X	"UPDATEA",
	X	"UPDATED",
	X	"UPDATEDA",
	X	"UPDATEM",
	X	"UPDATEMA",
	X	"ZONEINIT",
	X	"ZONEREF",
	X};
	X
	Xchar *_res_resultcodes[] = {
	X	"NOERROR",
	X	"FORMERR",
	X	"SERVFAIL",
	X	"NXDOMAIN",
	X	"NOTIMP",
	X	"REFUSED",
	X	"6",
	X	"7",
	X	"8",
	X	"9",
	X	"10",
	X	"11",
	X	"12",
	X	"13",
	X	"14",
	X	"NOCHANGE",
	X};
	X
	Xp_query(msg)
	X	char *msg;
	X{
	X#ifdef DEBUG
	X	fp_query(msg,stdout);
	X#endif
	X}
	X
	X/*
	X * Print the contents of a query.
	X * This is intended to be primarily a debugging routine.
	X */
	Xfp_query(msg,file)
	X	char *msg;
	X	FILE *file;
	X{
	X#ifdef DEBUG
	X	register char *cp;
	X	register HEADER *hp;
	X	register int n;
	X
	X	/*
	X	 * Print header fields.
	X	 */
	X	hp = (HEADER *)msg;
	X	cp = msg + sizeof(HEADER);
	X	fprintf(file,"HEADER:\n");
	X	fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
	X	fprintf(file,", id = %d", ntohs(hp->id));
	X	fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
	X	fprintf(file,"\theader flags: ");
	X	if (hp->qr)
	X		fprintf(file," qr");
	X	if (hp->aa)
	X		fprintf(file," aa");
	X	if (hp->tc)
	X		fprintf(file," tc");
	X	if (hp->rd)
	X		fprintf(file," rd");
	X	if (hp->ra)
	X		fprintf(file," ra");
	X	if (hp->pr)
	X		fprintf(file," pr");
	X	fprintf(file,"\n\tqdcount = %d", ntohs(hp->qdcount));
	X	fprintf(file,", ancount = %d", ntohs(hp->ancount));
	X	fprintf(file,", nscount = %d", ntohs(hp->nscount));
	X	fprintf(file,", arcount = %d\n\n", ntohs(hp->arcount));
	X	/*
	X	 * Print question records.
	X	 */
	X	if (n = ntohs(hp->qdcount)) {
	X		fprintf(file,"QUESTIONS:\n");
	X		while (--n >= 0) {
	X			fprintf(file,"\t");
	X			cp = p_cdname(cp, msg, file);
	X			if (cp == NULL)
	X				return;
	X			fprintf(file,", type = %s", p_type(_getshort(cp)));
	X			cp += sizeof(u_short);
	X			fprintf(file,", class = %s\n\n", p_class(_getshort(cp)));
	X			cp += sizeof(u_short);
	X		}
	X	}
	X	/*
	X	 * Print authoritative answer records
	X	 */
	X	if (n = ntohs(hp->ancount)) {
	X		fprintf(file,"ANSWERS:\n");
	X		while (--n >= 0) {
	X			fprintf(file,"\t");
	X			cp = p_rr(cp, msg, file);
	X			if (cp == NULL)
	X				return;
	X		}
	X	}
	X	/*
	X	 * print name server records
	X	 */
	X	if (n = ntohs(hp->nscount)) {
	X		fprintf(file,"NAME SERVERS:\n");
	X		while (--n >= 0) {
	X			fprintf(file,"\t");
	X			cp = p_rr(cp, msg, file);
	X			if (cp == NULL)
	X				return;
	X		}
	X	}
	X	/*
	X	 * print additional records
	X	 */
	X	if (n = ntohs(hp->arcount)) {
	X		fprintf(file,"ADDITIONAL RECORDS:\n");
	X		while (--n >= 0) {
	X			fprintf(file,"\t");
	X			cp = p_rr(cp, msg, file);
	X			if (cp == NULL)
	X				return;
	X		}
	X	}
	X#endif
	X}
	X
	Xchar *
	Xp_cdname(cp, msg, file)
	X	char *cp, *msg;
	X	FILE *file;
	X{
	X#ifdef DEBUG
	X	char name[MAXDNAME];
	X	int n;
	X
	X	if ((n = dn_expand(msg, msg + 512, cp, name, sizeof(name))) < 0)
	X		return (NULL);
	X	if (name[0] == '\0') {
	X		name[0] = '.';
	X		name[1] = '\0';
	X	}
	X	fputs(name, file);
	X	return (cp + n);
	X#endif
	X}
	X
	X/*
	X * Print resource record fields in human readable form.
	X */
	Xchar *
	Xp_rr(cp, msg, file)
	X	char *cp, *msg;
	X	FILE *file;
	X{
	X#ifdef DEBUG
	X	int type, class, dlen, n, c;
	X	struct in_addr inaddr;
	X	char *cp1;
	X
	X	if ((cp = p_cdname(cp, msg, file)) == NULL)
	X		return (NULL);			/* compression error */
	X	fprintf(file,"\n\ttype = %s", p_type(type = _getshort(cp)));
	X	cp += sizeof(u_short);
	X	fprintf(file,", class = %s", p_class(class = _getshort(cp)));
	X	cp += sizeof(u_short);
	X	fprintf(file,", ttl = %s", p_time(_getlong(cp)));
	X	cp += sizeof(u_long);
	X	fprintf(file,", dlen = %d\n", dlen = _getshort(cp));
	X	cp += sizeof(u_short);
	X	cp1 = cp;
	X	/*
	X	 * Print type specific data, if appropriate
	X	 */
	X	switch (type) {
	X	case T_A:
	X		switch (class) {
	X		case C_IN:
	X#ifdef SYS5
	X			(void)memcpy((char *)&inaddr, cp, sizeof(inaddr));
	X#else
	X			bcopy(cp, (char *)&inaddr, sizeof(inaddr));
	X#endif
	X			if (dlen == 4) {
	X				fprintf(file,"\tinternet address = %s\n",
	X					inet_ntoa(inaddr));
	X				cp += dlen;
	X			} else if (dlen == 7) {
	X				fprintf(file,"\tinternet address = %s",
	X					inet_ntoa(inaddr));
	X				fprintf(file,", protocol = %d", cp[4]);
	X				fprintf(file,", port = %d\n",
	X					(cp[5] << 8) + cp[6]);
	X				cp += dlen;
	X			}
	X			break;
	X		default:
	X			cp += dlen;
	X		}
	X		break;
	X	case T_CNAME:
	X	case T_MB:
	X#ifdef OLDRR
	X	case T_MD:
	X	case T_MF:
	X#endif /* OLDRR */
	X	case T_MG:
	X	case T_MR:
	X	case T_NS:
	X	case T_PTR:
	X		fprintf(file,"\tdomain name = ");
	X		cp = p_cdname(cp, msg, file);
	X		fprintf(file,"\n");
	X		break;
	X
	X	case T_HINFO:
	X		if (n = *cp++) {
	X			fprintf(file,"\tCPU=%.*s\n", n, cp);
	X			cp += n;
	X		}
	X		if (n = *cp++) {
	X			fprintf(file,"\tOS=%.*s\n", n, cp);
	X			cp += n;
	X		}
	X		break;
	X
	X	case T_SOA:
	X		fprintf(file,"\torigin = ");
	X		cp = p_cdname(cp, msg, file);
	X		fprintf(file,"\n\tmail addr = ");
	X		cp = p_cdname(cp, msg, file);
	X		fprintf(file,"\n\tserial=%ld", _getlong(cp));
	X		cp += sizeof(u_long);
	X		fprintf(file,", refresh=%s", p_time(_getlong(cp)));
	X		cp += sizeof(u_long);
	X		fprintf(file,", retry=%s", p_time(_getlong(cp)));
	X		cp += sizeof(u_long);
	X		fprintf(file,", expire=%s", p_time(_getlong(cp)));
	X		cp += sizeof(u_long);
	X		fprintf(file,", min=%s\n", p_time(_getlong(cp)));
	X		cp += sizeof(u_long);
	X		break;
	X
	X	case T_MX:
	X		fprintf(file,"\tpreference = %ld,",_getshort(cp));
	X		cp += sizeof(u_short);
	X		fprintf(file," name = ");
	X		cp = p_cdname(cp, msg, file);
	X		break;
	X
	X	case T_MINFO:
	X		fprintf(file,"\trequests = ");
	X		cp = p_cdname(cp, msg, file);
	X		fprintf(file,"\n\terrors = ");
	X		cp = p_cdname(cp, msg, file);
	X		break;
	X
	X	case T_UINFO:
	X		fprintf(file,"\t%s\n", cp);
	X		cp += dlen;
	X		break;
	X
	X	case T_UID:
	X	case T_GID:
	X		if (dlen == 4) {
	X			fprintf(file,"\t%ld\n", _getlong(cp));
	X			cp += sizeof(int);
	X		}
	X		break;
	X
	X	case T_WKS:
	X		if (dlen < sizeof(u_long) + 1)
	X			break;
	X#ifdef SYS5
	X		(void)memcpy ((char *)&inaddr, cp, sizeof(inaddr));
	X#else
	X		bcopy(cp, (char *)&inaddr, sizeof(inaddr));
	X#endif
	X		cp += sizeof(u_long);
	X		fprintf(file,"\tinternet address = %s, protocol = %d\n\t",
	X			inet_ntoa(inaddr), *cp++);
	X		n = 0;
	X		while (cp < cp1 + dlen) {
	X			c = *cp++;
	X			do {
	X 				if (c & 0200)
	X					fprintf(file," %d", n);
	X 				c <<= 1;
	X			} while (++n & 07);
	X		}
	X		putc('\n',file);
	X		break;
	X
	X#ifdef ALLOW_T_UNSPEC
	X	case T_UNSPEC:
	X		{
	X			int NumBytes = 8;
	X			char *DataPtr;
	X			int i;
	X
	X			if (dlen < NumBytes) NumBytes = dlen;
	X			fprintf(file, "\tFirst %d bytes of hex data:",
	X				NumBytes);
	X			for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
	X				fprintf(file, " %x", *DataPtr);
	X			fputs("\n", file);
	X			cp += dlen;
	X		}
	X		break;
	X#endif /* ALLOW_T_UNSPEC */
	X
	X	default:
	X		fprintf(file,"\t???\n");
	X		cp += dlen;
	X	}
	X	if (cp != cp1 + dlen)
	X		fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen);
	X	fprintf(file,"\n");
	X	return (cp);
	X#endif
	X}
	X
	Xstatic	char nbuf[20];
	X
	X/*
	X * Return a string for the type
	X */
	Xchar *
	Xp_type(type)
	X	int type;
	X{
	X	switch (type) {
	X	case T_A:
	X		return("A");
	X	case T_NS:		/* authoritative server */
	X		return("NS");
	X#ifdef OLDRR
	X	case T_MD:		/* mail destination */
	X		return("MD");
	X	case T_MF:		/* mail forwarder */
	X		return("MF");
	X#endif /* OLDRR */
	X	case T_CNAME:		/* connonical name */
	X		return("CNAME");
	X	case T_SOA:		/* start of authority zone */
	X		return("SOA");
	X	case T_MB:		/* mailbox domain name */
	X		return("MB");
	X	case T_MG:		/* mail group member */
	X		return("MG");
	X	case T_MX:		/* mail routing info */
	X		return("MX");
	X	case T_MR:		/* mail rename name */
	X		return("MR");
	X	case T_NULL:		/* null resource record */
	X		return("NULL");
	X	case T_WKS:		/* well known service */
	X		return("WKS");
	X	case T_PTR:		/* domain name pointer */
	X		return("PTR");
	X	case T_HINFO:		/* host information */
	X		return("HINFO");
	X	case T_MINFO:		/* mailbox information */
	X		return("MINFO");
	X	case T_AXFR:		/* zone transfer */
	X		return("AXFR");
	X	case T_MAILB:		/* mail box */
	X		return("MAILB");
	X	case T_MAILA:		/* mail address */
	X		return("MAILA");
	X	case T_ANY:		/* matches any type */
	X		return("ANY");
	X	case T_UINFO:
	X		return("UINFO");
	X	case T_UID:
	X		return("UID");
	X	case T_GID:
	X		return("GID");
	X#ifdef ALLOW_T_UNSPEC
	X	case T_UNSPEC:
	X		return("UNSPEC");
	X#endif /* ALLOW_T_UNSPEC */
	X	default:
	X		(void)sprintf(nbuf, "%d", type);
	X		return(nbuf);
	X	}
	X}
	X
	X/*
	X * Return a mnemonic for class
	X */
	Xchar *
	Xp_class(class)
	X	int class;
	X{
	X
	X	switch (class) {
	X	case C_IN:		/* internet class */
	X		return("IN");
	X	case C_ANY:		/* matches any class */
	X		return("ANY");
	X	default:
	X		(void)sprintf(nbuf, "%d", class);
	X		return(nbuf);
	X	}
	X}
	X
	X#ifdef XFER
	X/*
	X * Make a copy of a string and return a pointer to it.
	X */
	Xstatic char *
	Xsavestr(str)
	X	char *str;
	X{
	X	char *cp;
	X 
	X	cp = malloc((unsigned)strlen(str) + 1);
	X	if (cp == NULL) {
	X		syslog(LOG_ERR, "savestr: %m");
	X		exit(1);
	X	}
	X	(void) strcpy(cp, str);
	X	return (cp);
	X}
	X
	Xchar *
	Xp_protocal(num)
	X    	int num;
	X{
	X	static	char number[8];
	X	struct protoent *pp;
	X	extern struct protoent *cgetprotobynumber();
	X 
	X	pp = cgetprotobynumber(num);
	X	if(pp == 0)  {
	X		(void) sprintf(number, "%d", num);
	X		return(number);
	X	}
	X	return(pp->p_name);
	X}
	X 
	Xchar *
	Xp_service(port, proto)
	X	u_short port;
	X	char *proto;
	X{
	X	static	char number[8];
	X	struct servent *ss;
	X	extern struct servent *cgetservbyport();
	X 
	X	ss = cgetservbyport((int)htons(port), proto);
	X	if(ss == 0)  {
	X		(void) sprintf(number, "%d", port);
	X		return(number);
	X	}
	X	return(ss->s_name);
	X}
	X
	X
	Xstruct valuelist {
	X	struct valuelist *next, *prev;
	X	char	*name;
	X	char	*proto;
	X	short	port;
	X} *servicelist, *protolist;
	X
	Xbuildservicelist()
	X{
	X	struct servent *sp;
	X	struct valuelist *slp;
	X
	X	setservent(1);
	X	while (sp = getservent()) {
	X		slp = (struct valuelist *)malloc(sizeof(struct valuelist));
	X		slp->name = savestr(sp->s_name);
	X		slp->proto = savestr(sp->s_proto);
	X		slp->port = ntohs(sp->s_port);
	X		slp->next = servicelist;
	X		slp->prev = NULL;
	X		if (servicelist) {
	X			servicelist->prev = slp;
	X		}
	X		servicelist = slp;
	X	}
	X	endservent();
	X}
	X
	Xbuildprotolist()
	X{
	X	struct protoent *pp;
	X	struct valuelist *slp;
	X
	X	setprotoent(1);
	X	while (pp = getprotoent()) {
	X		slp = (struct valuelist *)malloc(sizeof(struct valuelist));
	X		slp->name = savestr(pp->p_name);
	X		slp->port = pp->p_proto;
	X		slp->next = protolist;
	X		slp->prev = NULL;
	X		if (protolist) {
	X			protolist->prev = slp;
	X		}
	X		protolist = slp;
	X	}
	X	endprotoent();
	X}
	X
	Xstruct servent *
	Xcgetservbyport(port, proto)
	X	u_short port;
	X	char *proto;
	X{
	X	register struct valuelist **list = &servicelist;
	X	register struct valuelist *lp = *list;
	X	static struct servent serv;
	X
	X	port = htons(port);
	X	for (; lp != NULL; lp = lp->next) {
	X		if (port != lp->port)
	X			continue;
	X		if (strcasecmp(lp->proto, proto) == 0) {
	X			if (lp != *list) {
	X				lp->prev->next = lp->next;
	X				if (lp->next)
	X					lp->next->prev = lp->prev;
	X				(*list)->prev = lp;
	X				lp->next = *list;
	X				*list = lp;
	X			}
	X			serv.s_name = lp->name;
	X			serv.s_port = htons(lp->port);
	X			serv.s_proto = lp->proto;
	X			return(&serv);
	X		}
	X	}
	X	return(0);
	X}
	X
	Xstruct protoent *
	Xcgetprotobynumber(proto)
	X    	register int proto;
	X{
	X
	X	register struct valuelist **list = &protolist;
	X	register struct valuelist *lp = *list;
	X	static struct protoent prot;
	X
	X	for (; lp != NULL; lp = lp->next)
	X		if (lp->port == proto) {
	X			if (lp != *list) {
	X				lp->prev->next = lp->next;
	X				if (lp->next)
	X					lp->next->prev = lp->prev;
	X				(*list)->prev = lp;
	X				lp->next = *list;
	X				*list = lp;
	X			}
	X			prot.p_name = lp->name;
	X			prot.p_proto = lp->port;
	X			return(&prot);
	X		}
	X	return(0);
	X}
	X
	X#endif /* XFER */
	X
	X/*
	X * Return a mnemonic for a time to live
	X */
	Xchar *
	Xp_time(value)
	X	unsigned long value;
	X{
	X	int secs, mins, hours;
	X	static char buf[128];
	X
	X	secs = value % 60;
	X	value /= 60;
	X	mins = value % 60;
	X	value /= 60;
	X	hours = value % 24;
	X	value /= 24;
	X
	X# define PLURALIZE(x) x, (x==1)?"":"s"
	X	if (value)
	X		(void) sprintf(buf, "%d day%s", PLURALIZE(value));
	X	else
	X		strcpy(buf, "");
	X	if (hours) {
	X		(void) sprintf(nbuf, " %d hour%s", PLURALIZE(hours));
	X		(void) strcat(buf, nbuf);
	X	}
	X	if (mins) {
	X		(void) sprintf(nbuf, " %d min%s", PLURALIZE(mins));
	X		(void) strcat(buf, nbuf);
	X	}
	X	if (secs) {
	X		(void) sprintf(nbuf, " %d sec%s", PLURALIZE(secs));
	X		(void) strcat(buf, nbuf);
	X	}
	X	return (buf);
	X}
	X
SHAR_EOF
if test 12802 -ne "`wc -c < 'res_debug.c'`"
then
	echo shar: "error transmitting 'res_debug.c'" '(should have been 12802 characters)'
fi
fi
echo shar: "extracting 'res_comp.c'" '(6673 characters)'
if test -f 'res_comp.c'
then
	echo shar: "will not over-write existing file 'res_comp.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'res_comp.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_comp.c	6.13 (Berkeley) 3/13/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 <stdio.h>
	X#include <arpa/nameser.h>
	X
	X
	X/*
	X * Expand compressed domain name 'comp_dn' to full domain name.
	X * 'msg' is a pointer to the begining of the message,
	X * 'eomorig' points to the first location after the message,
	X * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
	X * Return size of compressed name or -1 if there was an error.
	X */
	Xdn_expand(msg, eomorig, comp_dn, exp_dn, length)
	X	u_char *msg, *eomorig, *comp_dn, *exp_dn;
	X	int length;
	X{
	X	register u_char *cp, *dn;
	X	register int n, c;
	X	u_char *eom;
	X	int len = -1, checked = 0;
	X
	X	dn = exp_dn;
	X	cp = comp_dn;
	X	eom = exp_dn + length - 1;
	X	/*
	X	 * fetch next label in domain name
	X	 */
	X	while (n = *cp++) {
	X		/*
	X		 * Check for indirection
	X		 */
	X		switch (n & INDIR_MASK) {
	X		case 0:
	X			if (dn != exp_dn) {
	X				if (dn >= eom)
	X					return (-1);
	X				*dn++ = '.';
	X			}
	X			if (dn+n >= eom)
	X				return (-1);
	X			checked += n + 1;
	X			while (--n >= 0) {
	X				if ((c = *cp++) == '.') {
	X					if (dn+n+1 >= eom)
	X						return (-1);
	X					*dn++ = '\\';
	X				}
	X				*dn++ = c;
	X				if (cp >= eomorig)	/* out of range */
	X					return(-1);
	X			}
	X			break;
	X
	X		case INDIR_MASK:
	X			if (len < 0)
	X				len = cp - comp_dn + 1;
	X			cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
	X			if (cp < msg || cp >= eomorig)	/* out of range */
	X				return(-1);
	X			checked += 2;
	X			/*
	X			 * Check for loops in the compressed name;
	X			 * if we've looked at the whole message,
	X			 * there must be a loop.
	X			 */
	X			if (checked >= eomorig - msg)
	X				return (-1);
	X			break;
	X
	X		default:
	X			return (-1);			/* flag error */
	X		}
	X	}
	X	*dn = '\0';
	X	if (len < 0)
	X		len = cp - comp_dn;
	X	return (len);
	X}
	X
	X/*
	X * Compress domain name 'exp_dn' into 'comp_dn'.
	X * Return the size of the compressed name or -1.
	X * 'length' is the size of the array pointed to by 'comp_dn'.
	X * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
	X * is a pointer to the beginning of the message. The list ends with NULL.
	X * 'lastdnptr' is a pointer to the end of the arrary pointed to
	X * by 'dnptrs'. Side effect is to update the list of pointers for
	X * labels inserted into the message as we compress the name.
	X * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
	X * is NULL, we don't update the list.
	X */
	Xdn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
	X	u_char *exp_dn, *comp_dn;
	X	int length;
	X	u_char **dnptrs, **lastdnptr;
	X{
	X	register u_char *cp, *dn;
	X	register int c, l;
	X	u_char **cpp, **lpp, *sp, *eob;
	X	u_char *msg;
	X
	X	dn = exp_dn;
	X	cp = comp_dn;
	X	eob = cp + length;
	X	if (dnptrs != NULL) {
	X		if ((msg = *dnptrs++) != NULL) {
	X			for (cpp = dnptrs; *cpp != NULL; cpp++)
	X				;
	X			lpp = cpp;	/* end of list to search */
	X		}
	X	} else
	X		msg = NULL;
	X	for (c = *dn++; c != '\0'; ) {
	X		/* look to see if we can use pointers */
	X		if (msg != NULL) {
	X			if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
	X				if (cp+1 >= eob)
	X					return (-1);
	X				*cp++ = (l >> 8) | INDIR_MASK;
	X				*cp++ = l % 256;
	X				return (cp - comp_dn);
	X			}
	X			/* not found, save it */
	X			if (lastdnptr != NULL && cpp < lastdnptr-1) {
	X				*cpp++ = cp;
	X				*cpp = NULL;
	X			}
	X		}
	X		sp = cp++;	/* save ptr to length byte */
	X		do {
	X			if (c == '.') {
	X				c = *dn++;
	X				break;
	X			}
	X			if (c == '\\') {
	X				if ((c = *dn++) == '\0')
	X					break;
	X			}
	X			if (cp >= eob)
	X				return (-1);
	X			*cp++ = c;
	X		} while ((c = *dn++) != '\0');
	X		/* catch trailing '.'s but not '..' */
	X		if ((l = cp - sp - 1) == 0 && c == '\0') {
	X			cp--;
	X			break;
	X		}
	X		if (l <= 0 || l > MAXLABEL)
	X			return (-1);
	X		*sp = l;
	X	}
	X	if (cp >= eob)
	X		return (-1);
	X	*cp++ = '\0';
	X	return (cp - comp_dn);
	X}
	X
	X/*
	X * Skip over a compressed domain name. Return the size or -1.
	X */
	Xdn_skipname(comp_dn, eom)
	X	u_char *comp_dn, *eom;
	X{
	X	register u_char *cp;
	X	register int n;
	X
	X	cp = comp_dn;
	X	while (cp < eom && (n = *cp++)) {
	X		/*
	X		 * check for indirection
	X		 */
	X		switch (n & INDIR_MASK) {
	X		case 0:		/* normal case, n == len */
	X			cp += n;
	X			continue;
	X		default:	/* illegal type */
	X			return (-1);
	X		case INDIR_MASK:	/* indirection */
	X			cp++;
	X		}
	X		break;
	X	}
	X	return (cp - comp_dn);
	X}
	X
	X/*
	X * Search for expanded name from a list of previously compressed names.
	X * Return the offset from msg if found or -1.
	X * dnptrs is the pointer to the first name on the list,
	X * not the pointer to the start of the message.
	X */
	Xstatic
	Xdn_find(exp_dn, msg, dnptrs, lastdnptr)
	X	u_char *exp_dn, *msg;
	X	u_char **dnptrs, **lastdnptr;
	X{
	X	register u_char *dn, *cp, **cpp;
	X	register int n;
	X	u_char *sp;
	X
	X	for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
	X		dn = exp_dn;
	X		sp = cp = *cpp;
	X		while (n = *cp++) {
	X			/*
	X			 * check for indirection
	X			 */
	X			switch (n & INDIR_MASK) {
	X			case 0:		/* normal case, n == len */
	X				while (--n >= 0) {
	X					if (*dn == '\\')
	X						dn++;
	X					if (*dn++ != *cp++)
	X						goto next;
	X				}
	X				if ((n = *dn++) == '\0' && *cp == '\0')
	X					return (sp - msg);
	X				if (n == '.')
	X					continue;
	X				goto next;
	X
	X			default:	/* illegal type */
	X				return (-1);
	X
	X			case INDIR_MASK:	/* indirection */
	X				cp = msg + (((n & 0x3f) << 8) | *cp);
	X			}
	X		}
	X		if (*dn == '\0')
	X			return (sp - msg);
	X	next:	;
	X	}
	X	return (-1);
	X}
	X
	X/*
	X * Routines to insert/extract short/long's. Must account for byte
	X * order and non-alignment problems. This code at least has the
	X * advantage of being portable.
	X *
	X * used by sendmail.
	X */
	X
	Xu_short
	X_getshort(msgp)
	X	u_char *msgp;
	X{
	X	register u_char *p = (u_char *) msgp;
	X#ifdef vax
	X	/*
	X	 * vax compiler doesn't put shorts in registers
	X	 */
	X	register u_long u;
	X#else
	X	register u_short u;
	X#endif
	X
	X	u = *p++ << 8;
	X	return ((u_short)(u | *p));
	X}
	X
	Xu_long
	X_getlong(msgp)
	X	u_char *msgp;
	X{
	X	register u_char *p = (u_char *) msgp;
	X	register u_long u;
	X
	X	u = *p++; u <<= 8;
	X	u |= *p++; u <<= 8;
	X	u |= *p++; u <<= 8;
	X	return (u | *p);
	X}
	X
	X
	Xputshort(s, msgp)
	X	register u_short s;
	X	register u_char *msgp;
	X{
	X
	X	msgp[1] = s;
	X	msgp[0] = s >> 8;
	X}
	X
	Xputlong(l, msgp)
	X	register u_long l;
	X	register u_char *msgp;
	X{
	X
	X	msgp[3] = l;
	X	msgp[2] = (l >>= 8);
	X	msgp[1] = (l >>= 8);
	X	msgp[0] = l >> 8;
	X}
SHAR_EOF
if test 6673 -ne "`wc -c < 'res_comp.c'`"
then
	echo shar: "error transmitting 'res_comp.c'" '(should have been 6673 characters)'
fi
fi
echo shar: "extracting 'res_compat.c'" '(2469 characters)'
if test -f 'res_compat.c'
then
	echo shar: "will not over-write existing file 'res_compat.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'res_compat.c'
	X/*
	X * This file contains routines that will resolve compatibilities between
	X * System V and BSD versions of Unix.
	X */
	X
	X#if defined(LIBC_SCCS) && !defined(lint)
	Xstatic char sccsid[] = "@(#)res_compat 1.0 (Baylor College of Medicine)";
	X#endif /* LIBC_SCCS and not lint */
	X
	X#ifdef SYS5
	X#include <sys/types.h>
	X#include <stdio.h>
	X#include <string.h>
	X#include <ctype.h>
	X#ifdef EXOS
	X#include <netinet/in.h>
	X
	X/*
	X * inet_ntoa() returns a character string representing the address
	X * passed in the arguement.
	X */
	X
	Xchar *
	Xinet_ntoa(in)
	Xstruct in_addr in;
	X{
	X	static char address[20];
	X
	X	sprintf(address, "%u.%u.%u.%u",
	X			 (in.s_addr>>24)&0xff,
	X			 (in.s_addr>>16)&0xff,
	X			 (in.s_addr>>8 )&0xff,
	X			 (in.s_addr    )&0xff);
	X	return(address);
	X}
	X
	X#endif EXOS
	X
	X/*
	X * inet_addr() returns a long given a string representation of
	X * an internet address
	X */
	Xunsigned long
	Xinet_addr(cp)
	Xregister char * cp;
	X{
	X	unsigned long val, base, n;
	X	register char c;
	X 	unsigned long octet[4], *octetptr = octet;
	X#ifndef	htonl
	X	extern	unsigned long	htonl();
	X#endif	htonl
	Xagain:
	X	/*
	X	 * Collect number up to ``.''.
	X	 * Values are specified as for C:
	X	 * 0x=hex, 0=octal, other=decimal.
	X	 */
	X	val = 0; base = 10;
	X	if (*cp == '0')
	X		base = 8, cp++;
	X	if (*cp == 'x' || *cp == 'X')
	X		base = 16, cp++;
	X	while (c = *cp) {
	X		if (isdigit(c)) {
	X			val = (val * base) + (c - '0');
	X			cp++;
	X			continue;
	X		}
	X		if (base == 16 && isxdigit(c)) {
	X			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
	X			cp++;
	X			continue;
	X		}
	X		break;
	X	}
	X	if (*cp == '.') {
	X		/*
	X		 * Internet format:
	X		 *	a.b.c.d
	X		 *	a.b.c	(with c treated as 16-bits)
	X		 *	a.b	(with b treated as 24 bits)
	X		 */
	X		if (octetptr >= octet + 4)
	X			return (-1);
	X		*octetptr++ = val, cp++;
	X		goto again;
	X	}
	X	/*
	X	 * Check for trailing characters.
	X	 */
	X	if (*cp && !isspace(*cp))
	X		return (-1);
	X	*octetptr++ = val;
	X	/*
	X	 * Concoct the address according to
	X	 * the number of octet specified.
	X	 */
	X	n = octetptr - octet;
	X	switch (n) {
	X
	X	case 1:				/* a -- 32 bits */
	X		val = octet[0];
	X		break;
	X
	X	case 2:				/* a.b -- 8.24 bits */
	X		val = (octet[0] << 24) | (octet[1] & 0xffffff);
	X		break;
	X
	X	case 3:				/* a.b.c -- 8.8.16 bits */
	X		val = (octet[0] << 24) | ((octet[1] & 0xff) << 16) |
	X			(octet[2] & 0xffff);
	X		break;
	X
	X	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
	X		val = (octet[0] << 24) | ((octet[1] & 0xff) << 16) |
	X		      ((octet[2] & 0xff) << 8) | (octet[3] & 0xff);
	X		break;
	X
	X	default:
	X		return (-1);
	X	}
	X	val = htonl(val);
	X	return (val);
	X}
	X#endif	SYS5
SHAR_EOF
if test 2469 -ne "`wc -c < 'res_compat.c'`"
then
	echo shar: "error transmitting 'res_compat.c'" '(should have been 2469 characters)'
fi
fi
echo shar: "extracting 'herror.c'" '(1599 characters)'
if test -f 'herror.c'
then
	echo shar: "will not over-write existing file 'herror.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'herror.c'
	X/*
	X * Copyright (c) 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
	X#if defined(LIBC_SCCS) && !defined(lint)
	Xstatic char sccsid[] = "@(#)herror.c	6.1 (Berkeley) 12/4/87";
	X#endif LIBC_SCCS and not lint
	X
	X#include <sys/types.h>
	X#ifndef SYS5
	X#include <sys/uio.h>
	X#endif
	X
	Xchar	*h_errlist[] = {
	X	"Error 0",
	X	"Unknown host",				/* 1 HOST_NOT_FOUND */
	X	"Host name lookup failure",		/* 2 TRY_AGAIN */
	X	"Unknown server error",			/* 3 NO_RECOVERY */
	X	"No address associated with name",	/* 4 NO_ADDRESS */
	X};
	Xint	h_nerr = { sizeof(h_errlist)/sizeof(h_errlist[0]) };
	X
	Xextern int	h_errno;
	X
	X/*
	X * herror --
	X *	print the error indicated by the h_errno value.
	X */
	Xherror(s)
	X	char *s;
	X{
	X#ifdef SYS5
	X	int len;
	X	char * hmsg;
	X	if (s == (char * ) h_errno) len = 0;
	X		/* 
	X		 * compensate for persons who
	X		 * don't read instructions!
	X		 */
	X	else len = strlen(s);
	X	if (len > 0){
	X		if (write(2,s, (unsigned) len) != len)
	X			return;
	X		if (write(2, ": ",2) != 2)
	X			return;
	X	}
	X	hmsg = "Unknown error";
	X	if (h_errno < h_nerr && h_errno > 0)
	X		hmsg =  h_errlist[h_errno];
	X	write(2,hmsg,(unsigned)strlen(hmsg));
	X	write(2,"\n",1);	
	X#else
	X	struct iovec iov[4];
	X	register struct iovec *v = iov;
	X
	X	if (s && *s) {
	X		v->iov_base = s;
	X		v->iov_len = strlen(s);
	X		v++;
	X		v->iov_base = ": ";
	X		v->iov_len = 2;
	X		v++;
	X	}
	X	v->iov_base = h_errno < h_nerr ? h_errlist[h_errno] : "Unknown error";
	X	v->iov_len = strlen(v->iov_base);
	X	v++;
	X	v->iov_base = "\n";
	X	v->iov_len = 1;
	X	writev(2, iov, (v - iov) + 1);
	X#endif
	X}
SHAR_EOF
if test 1599 -ne "`wc -c < 'herror.c'`"
then
	echo shar: "error transmitting 'herror.c'" '(should have been 1599 characters)'
fi
fi
echo shar: "extracting 'strcasecmp.c'" '(3014 characters)'
if test -f 'strcasecmp.c'
then
	echo shar: "will not over-write existing file 'strcasecmp.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'strcasecmp.c'
	X/*
	X * Copyright (c) 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
	X#if defined(LIBC_SCCS) && !defined(lint)
	Xstatic char sccsid[] = "@(#)strcasecmp.c	1.3 (Berkeley) 8/3/87";
	X#endif LIBC_SCCS and not lint
	X
	X/*
	X * This array is designed for mapping upper and lower case letter
	X * together for a case independent comparison.  The mappings are
	X * based upon ascii character sequences.
	X */
	Xstatic char charmap[] = {
	X	'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
	X	'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
	X	'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
	X	'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
	X	'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
	X	'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
	X	'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
	X	'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
	X	'\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
	X	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
	X	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
	X	'\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
	X	'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
	X	'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
	X	'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
	X	'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
	X	'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
	X	'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
	X	'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
	X	'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
	X	'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
	X	'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
	X	'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
	X	'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
	X	'\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
	X	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
	X	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
	X	'\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
	X	'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
	X	'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
	X	'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
	X	'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
	X};
	X
	Xstrcasecmp(s1, s2)
	X	register char *s1, *s2;
	X{
	X	register char *cm = charmap;
	X
	X	while (cm[*s1] == cm[*s2++])
	X		if (*s1++ == '\0')
	X			return(0);
	X	return(cm[*s1] - cm[*--s2]);
	X}
	X
	Xstrncasecmp(s1, s2, n)
	X	register char *s1, *s2;
	X	register int n;
	X{
	X	register char *cm = charmap;
	X
	X	while (--n >= 0 && cm[*s1] == cm[*s2++])
	X		if (*s1++ == '\0')
	X			return(0);
	X	return(n < 0 ? 0 : cm[*s1] - cm[*--s2]);
	X}
SHAR_EOF
if test 3014 -ne "`wc -c < 'strcasecmp.c'`"
then
	echo shar: "error transmitting 'strcasecmp.c'" '(should have been 3014 characters)'
fi
fi
exit 0
#	End of shell archive