Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!bcm!soma!masscomp-request
From: sob@cortex.neuro.bcm.tmc.edu (Stan Barber)
Newsgroups: comp.sys.masscomp
Subject: name server resolver library for MASSCOMP (part 3 of 7)
Message-ID: <3471@soma.bcm.tmc.edu>
Date: 5 Jul 88 01:00:22 GMT
Sender: masscomp@soma.bcm.tmc.edu
Lines: 1383
Approved: masscomp@soma.bcm.tmc.edu

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 
	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 
	X#ifdef EXOS
	X#include 
	X#endif
	X#include 
	X#include 
	X#include 
	X#include 
	X#include 
	X#include 
	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 
	X#ifdef EXOS
	X#include 
	X#endif
	X#include 
	X#include 
	X#include 
	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 
	X#ifdef SYS5
	X#include 
	X#else
	X#include 
	X#endif
	X#include 
	X#ifdef EXOS
	X#include 
	X#endif
	X#include 
	X#include 
	X#include 
	X#include 
	X#include 
	X#include 
	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