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 fromX * 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