[alt.sources] resolv+ -- improved resolver library -- part01/02

wisner@ims.alaska.edu (Bill Wisner) (04/23/91)

It really pains me to admit that there's anything good in Ultrix, but I'm
afraid I have to: they've added a facility that allows the administrator to
choose what facility is to be used for looking up hostname (and address)
queries -- BIND, the host table, or YP.

I've long wanted to be able to do something similar, so today in a fit of
envy (or something similar) I hacked up the standard resolver library from
the BIND 4.8.3 distribution and made it possible to choose between BIND and
/etc/hosts lookups.  I didn't bother with YP, since if it's set up properly
it'll use both methods anyway.

Here it is.

Note: Yellow Pages is a registered trademark of British Telecom plc, but I
don't care.

Bill Wisner <wisner@ims.alaska.edu> Gryphon Gang Fairbanks AK 99775
/* you are not expected to understand this */

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 2)."
# Contents:  MANIFEST Makefile README SUN4.1 herror.c include
#   include/arpa include/arpa/inet.h include/netdb.h include/resolv.h
#   mktemp.c named named/sethostent.c res_comp.c res_init.c
#   res_mkquery.c strcasecmp.c strerror.c strpbrk.c
# Wrapped by wisner@hayes on Mon Apr 22 18:43:57 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(0 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(1639 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
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.1 (Berkeley) 3/14/88
X#
XSRCS=	herror.c res_comp.c res_debug.c res_init.c res_mkquery.c res_query.c \
X	res_send.c named/gethostnamadr.c named/sethostent.c \
X	mktemp.c strcasecmp.c strpbrk.c strerror.c
XOBJS=	herror.o res_comp.o res_debug.o res_init.o res_mkquery.o res_query.o \
X	res_send.o gethostnamadr.o sethostent.o \
X	mktemp.o strcasecmp.o strpbrk.o strerror.o
XDEFS=	-DDEBUG
XCFLAGS=	-O ${DEFS} -Iinclude
X
Xlibresolv.a: ${OBJS}
X	ar cru libresolv.a ${OBJS}
X	ranlib libresolv.a
X
Xinstall: libresolv.a
X	install -o bin -g bin -m 644 libresolv.a ${DESTDIR}/usr/lib
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
Xgethostnamadr.o: named/gethostnamadr.c
X	${CC} -c ${CFLAGS} named/gethostnamadr.c
X	-ld -x -r gethostnamadr.o
X	mv a.out gethostnamadr.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	mkdep ${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.
END_OF_FILE
if test 1639 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2480 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XThis is a modified version of the resolver library from BIND 4.8.3.
XIn this version, you can configure whether hostname lookups are done
Xwith BIND, the host table, or both, and in what order.  This is an
Xidea that I stole shamelessly from Ultrix.
X
XTo configure hostname lookups, edit /etc/resolv.conf.  Add an "order"
Xline to the file.  The order line should contain "bind" and/or "local"
Xseperated by commas.  The methods listed will be used in their given order.
X
Xorder		bind		- Use BIND only.  This is the default.
Xorder		bind,local	- If BIND lookup fails, resort to the host
X				  table.
Xorder		local,bind	- Look at the host table before trying BIND.
Xorder		local		- If you run your system like Fred Flintstone.
X
XOther than this change, this resolver library functions exactly like that
Xin BIND 4.8.3.
X
XNo site-specific configuration should be necessary before compiling; just
Xrun make.  Once the library is compiled it can be installed in a few
Xdifferent ways.
X
XYou can copy libresolv.a into /usr/lib/libresolv.a and compile all your
Xnetworking programs with -lresolv.  This is the low-impact method, though
Xit does require a bit of extra work when compiling things later.
X
XYou can incorporate the modules in libresolv.a into your system's C library.
XHow to do this is left as an exercise for the reader.  (If you're clever
Xenough to do this you don't need me to tell you how.  If you're not, you're
Xbetter off not mucking about with things you don't understand.)
X
XIf you're running SunOS 4.1, you can incorporate this resolver library into
Xyour system's shared library.  If you do this, all of your networking
Xprograms will be able to use the resolver library without having to be
Xrecompiled.  This is especially handy if you don't use NIS.  Instructions
Xfor this method are in the file SUN4.1.  If you choose this method you must
Xadd -pic to CFLAGFS before compiling.
X
XUnless you've chosen the last installation method, you will have to recompile
Xyour networking programs before you see much of a benefit in using this
Xpackage.  If you don't have a source code license, don't feel bad: you're
Xexactly like most of the rest of us.  Fortunately, the source code for the
XBerkeley networking software is publically available from many anonymous FTP
Xsites.
X
XIf your system runs a particularly crummy version of UNIX, you may have
Xto copy some of the headers in the include subdirectory into /usr/include,
Xparticularly netdb.h.
X
XBill Wisner <wisner@ims.alaska.edu>
X22 April 1991
END_OF_FILE
if test 2480 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'SUN4.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'SUN4.1'\"
else
echo shar: Extracting \"'SUN4.1'\" \(2342 characters\)
sed "s/^X//" >'SUN4.1' <<'END_OF_FILE'
XTo build a resolver library suitable for inclusion in a SunOS 4.1 shared
Xlibrary, edit the Makefile before compiling.  It contains three "ld"
Xcommands, each of which is followed by a "mv" command.  Remove all three
X"ld"s and all three "mv"s.
X
XThe following instructions for incorporating a resolver library into the
Xstandard SunOS 4.1 shared library were originally posted to USENET by Greg
XEarle of Sun (if memory serves -- unfortunately, I didn't save the headers).
X
XTo get complete instructions, append the remainder of this file to
X/usr/lib/shlib.etc/README.  Then, color by numbers.
X
X(I shouldn't have to point out that instead of /usr/lib/libresolv.a, you
Xshould use the libresolv.a built from this package.)
X
X----------------------------------------------------------------------
X
XSupplemental instructions for building a shared libc.so that uses the resolver
Xfor hostname/addr resolution:
X
X10. Extract the contents of libc_pic.a and /usr/lib/libresolv.a into the
X    tmp directory:
X	% cd tmp
X	% ar x ../libc_pic.a
X	% ar x /usr/lib/libresolv.a
X
X    The libresolv.a (apparently) contains object modules that are position
X    independant, so they can be added to the libc_pic modules without fear.
X
X11. Remove the old routine to do the hostname/addr resolution:
X	% rm gethostent.o
X
X12. Remove the libresolv module that contains `strncasecmp' (which is now
X    in the main C library, so it is redundant):
X	% rm strcasecmp.o
X
X13. Remove the libresolv module that contains mktemp and mkstemp, since
X    the SunOS versions will do just as well.
X	% rm mktemp.o
X
X14. Now put the SunOS version of mktemp back into place.
X	% ar x ../libc_pic.a mktemp.o
X
X15. As mentioned in step 5 above, edit the file `lorder-sparc' in the ..
X    directory.  Remove the reference to `gethostent.o' and add the
X    references to the resolver library routines by applying this patch:
X
X	% diff -rc2 lorder-sparc.orig lorder-sparc
X	*** lorder-sparc.orig   Thu Feb  8 05:27:46 1990
X	--- lorder-sparc	Mon Apr  9 12:58:59 1990
X	***************
X	*** 150,154 ****
X	  getwd.o
X	  getnetgrent.o
X	! gethostent.o
X	  ypxdr.o
X	  ttyname.o
X	--- 150,161 ----
X	  getwd.o
X	  getnetgrent.o
X	! gethostnamadr.o
X	! sethostent.o
X	! res_query.o
X	! res_mkquery.o
X	! res_send.o
X	! res_debug.o
X	! res_comp.o
X	! res_init.o
X	  ypxdr.o
X	  ttyname.o
X
X14. Continue as above, from steps 6 to 9.
X
END_OF_FILE
if test 2342 -ne `wc -c <'SUN4.1'`; then
    echo shar: \"'SUN4.1'\" unpacked with wrong size!
fi
# end of 'SUN4.1'
fi
if test -f 'herror.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'herror.c'\"
else
echo shar: Extracting \"'herror.c'\" \(1961 characters\)
sed "s/^X//" >'herror.c' <<'END_OF_FILE'
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: (1) source distributions retain this entire copyright
X * notice and comment, and (2) distributions including binaries display
X * the following acknowledgement:  ``This product includes software
X * developed by the University of California, Berkeley and its contributors''
X * in the documentation or other materials provided with the distribution
X * and in all advertising materials mentioning features or use of this
X * software. Neither the name of the University nor the names of its
X * contributors may be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)herror.c	6.5 (Berkeley) 6/1/90";
X#endif /* LIBC_SCCS and not lint */
X
X#include <sys/types.h>
X#include <sys/uio.h>
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	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 = (u_int)h_errno < h_nerr ?
X	    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}
END_OF_FILE
if test 1961 -ne `wc -c <'herror.c'`; then
    echo shar: \"'herror.c'\" unpacked with wrong size!
fi
# end of 'herror.c'
fi
if test ! -d 'include' ; then
    echo shar: Creating directory \"'include'\"
    mkdir 'include'
fi
if test ! -d 'include/arpa' ; then
    echo shar: Creating directory \"'include/arpa'\"
    mkdir 'include/arpa'
fi
if test -f 'include/arpa/inet.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'include/arpa/inet.h'\"
else
echo shar: Extracting \"'include/arpa/inet.h'\" \(1612 characters\)
sed "s/^X//" >'include/arpa/inet.h' <<'END_OF_FILE'
X/*
X * Copyright (c) 1983 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: (1) source distributions retain this entire copyright
X * notice and comment, and (2) distributions including binaries display
X * the following acknowledgement:  ``This product includes software
X * developed by the University of California, Berkeley and its contributors''
X * in the documentation or other materials provided with the distribution
X * and in all advertising materials mentioning features or use of this
X * software. Neither the name of the University nor the names of its
X * contributors may be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X *	@(#)inet.h	5.4 (Berkeley) 6/1/90
X */
X
X/* External definitions for functions in inet(3) */
X
X#ifdef __STDC__
Xextern unsigned long inet_addr(const char *);
Xextern char *inet_ntoa(struct in_addr);
Xextern struct in_addr inet_makeaddr(int , int);
Xextern unsigned long inet_network(const char *);
Xextern unsigned long inet_lnaof(struct in_addr);
Xextern unsigned long inet_netof(struct in_addr);
X#else
Xextern unsigned long inet_addr();
Xextern char *inet_ntoa();
Xextern struct in_addr inet_makeaddr();
Xextern unsigned long inet_network();
Xextern unsigned long inet_lnaof();
Xextern unsigned long inet_netof();
X#endif
END_OF_FILE
if test 1612 -ne `wc -c <'include/arpa/inet.h'`; then
    echo shar: \"'include/arpa/inet.h'\" unpacked with wrong size!
fi
# end of 'include/arpa/inet.h'
fi
if test -f 'include/netdb.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'include/netdb.h'\"
else
echo shar: Extracting \"'include/netdb.h'\" \(3034 characters\)
sed "s/^X//" >'include/netdb.h' <<'END_OF_FILE'
X/*-
X * Copyright (c) 1980, 1983, 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: (1) source distributions retain this entire copyright
X * notice and comment, and (2) distributions including binaries display
X * the following acknowledgement:  ``This product includes software
X * developed by the University of California, Berkeley and its contributors''
X * in the documentation or other materials provided with the distribution
X * and in all advertising materials mentioning features or use of this
X * software. Neither the name of the University nor the names of its
X * contributors may be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X *	@(#)netdb.h	5.11 (Berkeley) 5/21/90
X */
X
X#define	_PATH_HEQUIV	"/etc/hosts.equiv"
X#define	_PATH_HOSTS	"/etc/hosts"
X#define	_PATH_NETWORKS	"/etc/networks"
X#define	_PATH_PROTOCOLS	"/etc/protocols"
X#define	_PATH_SERVICES	"/etc/services"
X
X/*
X * Structures returned by network data base library.  All addresses are
X * supplied in host order, and returned in network order (suitable for
X * 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_list;	/* list of addresses from name server */
X#define	h_addr	h_addr_list[0]	/* address, for backward compatiblity */
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 */
END_OF_FILE
if test 3034 -ne `wc -c <'include/netdb.h'`; then
    echo shar: \"'include/netdb.h'\" unpacked with wrong size!
fi
# end of 'include/netdb.h'
fi
if test -f 'include/resolv.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'include/resolv.h'\"
else
echo shar: Extracting \"'include/resolv.h'\" \(3099 characters\)
sed "s/^X//" >'include/resolv.h' <<'END_OF_FILE'
X/*
X * Copyright (c) 1983, 1987, 1989 The 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: (1) source distributions retain this entire copyright
X * notice and comment, and (2) distributions including binaries display
X * the following acknowledgement:  ``This product includes software
X * developed by the University of California, Berkeley and its contributors''
X * in the documentation or other materials provided with the distribution
X * and in all advertising materials mentioning features or use of this
X * software. Neither the name of the University nor the names of its
X * contributors may be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X *	@(#)resolv.h	5.10.1 (Berkeley) 6/1/90
X */
X
X/*
X * Resolver configuration file.
X * Normally not present, but may contain the address of the
X * inital name server(s) to query and the domain search list.
X */
X
X#ifndef _PATH_RESCONF
X#define _PATH_RESCONF        "/etc/resolv.conf"
X#endif
X
X/*
X * Global defines and variables for resolver stub.
X */
X#define	MAXNS		3		/* max # name servers we'll track */
X#define	MAXDFLSRCH	3		/* # default domain levels to try */
X#define	MAXDNSRCH	6		/* max # domains in search path */
X#define	LOCALDOMAINPARTS 2		/* min levels in name that is "local" */
X#define MAXSERVICES	2		/* max # of services to search */
X
X#define	RES_TIMEOUT	5		/* min. 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	u_short	order[MAXSERVICES+1];	/* search service order */
X};
X
X#define RES_SERVICE_NONE	0
X#define RES_SERVICE_BIND	1
X#define RES_SERVICE_LOCAL	2
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(), *p_time();
END_OF_FILE
if test 3099 -ne `wc -c <'include/resolv.h'`; then
    echo shar: \"'include/resolv.h'\" unpacked with wrong size!
fi
# end of 'include/resolv.h'
fi
if test -f 'mktemp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mktemp.c'\"
else
echo shar: Extracting \"'mktemp.c'\" \(2503 characters\)
sed "s/^X//" >'mktemp.c' <<'END_OF_FILE'
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 the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)mktemp.c	5.8 (Berkeley - modified) 10/16/89";
X#endif /* LIBC_SCCS and not lint */
X
X#include <sys/types.h>
X#include <sys/file.h>
X#include <sys/stat.h>
X#include <errno.h>
X#include <stdio.h>
X#include <ctype.h>
X
X#ifndef S_ISDIR
X#define S_ISDIR(m)	((m & 0170000) == 0040000)
X#endif
X
Xmkstemp(path)
X	char *path;
X{
X	int fd;
X
X	return (_gettemp(path, &fd) ? fd : -1);
X}
X
Xchar *
Xmktemp(path)
X	char *path;
X{
X	return(_gettemp(path, (int *)NULL) ? path : (char *)NULL);
X}
X
Xstatic
X_gettemp(path, doopen)
X	char *path;
X	register int *doopen;
X{
X	extern int errno;
X	register char *start, *trv;
X	struct stat sbuf;
X	u_int pid;
X
X	pid = getpid();
X	for (trv = path; *trv; ++trv);		/* extra X's get set to 0's */
X	while (*--trv == 'X') {
X		*trv = (pid % 10) + '0';
X		pid /= 10;
X	}
X
X	/*
X	 * check the target directory; if you have six X's and it
X	 * doesn't exist this runs for a *very* long time.
X	 */
X	for (start = trv + 1;; --trv) {
X		if (trv <= path)
X			break;
X		if (*trv == '/') {
X			*trv = '\0';
X			if (stat(path, &sbuf))
X				return(0);
X			if (!S_ISDIR(sbuf.st_mode)) {
X				errno = ENOTDIR;
X				return(0);
X			}
X			*trv = '/';
X			break;
X		}
X	}
X
X	for (;;) {
X		if (doopen) {
X			if ((*doopen =
X			    open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
X				return(1);
X			if (errno != EEXIST)
X				return(0);
X		}
X		else if (stat(path, &sbuf))
X			return(errno == ENOENT ? 1 : 0);
X
X		/* tricky little algorithm for backward compatibility */
X		for (trv = start;;) {
X			if (!*trv)
X				return(0);
X			if (*trv == 'z')
X				*trv++ = 'a';
X			else {
X				if (isdigit(*trv))
X					*trv = 'a';
X				else
X					++*trv;
X				break;
X			}
X		}
X	}
X	/*NOTREACHED*/
X}
END_OF_FILE
if test 2503 -ne `wc -c <'mktemp.c'`; then
    echo shar: \"'mktemp.c'\" unpacked with wrong size!
fi
# end of 'mktemp.c'
fi
if test ! -d 'named' ; then
    echo shar: Creating directory \"'named'\"
    mkdir 'named'
fi
if test -f 'named/sethostent.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'named/sethostent.c'\"
else
echo shar: Extracting \"'named/sethostent.c'\" \(1290 characters\)
sed "s/^X//" >'named/sethostent.c' <<'END_OF_FILE'
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 the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)sethostent.c	6.5 (Berkeley) 6/27/88";
X#endif /* LIBC_SCCS and not lint */
X
X#include <sys/types.h>
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}
END_OF_FILE
if test 1290 -ne `wc -c <'named/sethostent.c'`; then
    echo shar: \"'named/sethostent.c'\" unpacked with wrong size!
fi
# end of 'named/sethostent.c'
fi
if test -f 'res_comp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'res_comp.c'\"
else
echo shar: Extracting \"'res_comp.c'\" \(7310 characters\)
sed "s/^X//" >'res_comp.c' <<'END_OF_FILE'
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 provided
X * that: (1) source distributions retain this entire copyright notice and
X * comment, and (2) distributions including binaries display the following
X * acknowledgement:  ``This product includes software developed by the
X * University of California, Berkeley and its contributors'' in the
X * documentation or other materials provided with the distribution and in
X * all advertising materials mentioning features or use of this software.
X * Neither the name of the University nor the names of its contributors may
X * be used to endorse or promote products derived from this software without
X * specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)res_comp.c	6.18 (Berkeley) 6/27/90";
X#endif /* LIBC_SCCS and not lint */
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <arpa/nameser.h>
X
Xstatic dn_find();
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;
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 + 2 >= 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				if (msg != NULL)
X					*lpp = NULL;
X				return (-1);
X			}
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			if (msg != NULL)
X				*lpp = NULL;
X			return (-1);
X		}
X		*sp = l;
X	}
X	if (cp >= eob) {
X		if (msg != NULL)
X			*lpp = NULL;
X		return (-1);
X	}
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						goto next;
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}
END_OF_FILE
if test 7310 -ne `wc -c <'res_comp.c'`; then
    echo shar: \"'res_comp.c'\" unpacked with wrong size!
fi
# end of 'res_comp.c'
fi
if test -f 'res_init.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'res_init.c'\"
else
echo shar: Extracting \"'res_init.c'\" \(6340 characters\)
sed "s/^X//" >'res_init.c' <<'END_OF_FILE'
X/*-
X * Copyright (c) 1985, 1989 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted provided
X * that: (1) source distributions retain this entire copyright notice and
X * comment, and (2) distributions including binaries display the following
X * acknowledgement:  ``This product includes software developed by the
X * University of California, Berkeley and its contributors'' in the
X * documentation or other materials provided with the distribution and in
X * all advertising materials mentioning features or use of this software.
X * Neither the name of the University nor the names of its contributors may
X * be used to endorse or promote products derived from this software without
X * specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)res_init.c	6.14.1 (Berkeley) 6/27/90";
X#endif /* LIBC_SCCS and not lint */
X
X#include <sys/types.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
X/*
X * Resolver state default settings
X */
X
Xstruct state _res = {
X	RES_TIMEOUT,               	/* retransmition time interval */
X	4,                         	/* number of times to retransmit */
X	RES_DEFAULT,			/* options flags */
X	1,                         	/* number of name servers */
X};
X
X/*
X * Set up default settings.  If the configuration file exist, the values
X * there will have precedence.  Otherwise, the server address is set to
X * INADDR_ANY and the default domain name comes from the gethostname().
X *
X * The configuration file should only be used if you want to redefine your
X * domain or run without a server on your machine.
X *
X * Return 0 if completes successfully, -1 on error
X */
Xres_init()
X{
X	register FILE *fp;
X	register char *cp, *dp, **pp;
X	register int n;
X	char buf[BUFSIZ];
X	extern u_long inet_addr();
X	extern char *index();
X	extern char *strcpy(), *strncpy();
X	extern char *getenv();
X	int nserv = 0;    /* number of nameserver records read from file */
X	int norder = 0;
X	int haveenv = 0;
X	int havesearch = 0;
X
X	_res.nsaddr.sin_addr.s_addr = INADDR_ANY;
X	_res.nsaddr.sin_family = AF_INET;
X	_res.nsaddr.sin_port = htons(NAMESERVER_PORT);
X	_res.nscount = 1;
X
X	/* Allow user to override the local domain definition */
X	if ((cp = getenv("LOCALDOMAIN")) != NULL) {
X		(void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
X		haveenv++;
X	}
X
X	if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
X	    /* read the config file */
X	    while (fgets(buf, sizeof(buf), fp) != NULL) {
X		/* read default domain name */
X		if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
X		    if (haveenv)	/* skip if have from environ */
X			    continue;
X		    cp = buf + sizeof("domain") - 1;
X		    while (*cp == ' ' || *cp == '\t')
X			    cp++;
X		    if ((*cp == '\0') || (*cp == '\n'))
X			    continue;
X		    (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
X		    if ((cp = index(_res.defdname, '\n')) != NULL)
X			    *cp = '\0';
X		    havesearch = 0;
X		    continue;
X		}
X		/* set search list */
X		if (!strncmp(buf, "search", sizeof("search") - 1)) {
X		    if (haveenv)	/* skip if have from environ */
X			    continue;
X		    cp = buf + sizeof("search") - 1;
X		    while (*cp == ' ' || *cp == '\t')
X			    cp++;
X		    if ((*cp == '\0') || (*cp == '\n'))
X			    continue;
X		    (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
X		    if ((cp = index(_res.defdname, '\n')) != NULL)
X			    *cp = '\0';
X		    /*
X		     * Set search list to be blank-separated strings
X		     * on rest of line.
X		     */
X		    cp = _res.defdname;
X		    pp = _res.dnsrch;
X		    *pp++ = cp;
X		    for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
X			    if (*cp == ' ' || *cp == '\t') {
X				    *cp = 0;
X				    n = 1;
X			    } else if (n) {
X				    *pp++ = cp;
X				    n = 0;
X			    }
X		    }
X		    /* null terminate last domain if there are excess */
X		    while (*cp != '\0' && *cp != ' ' && *cp != '\t')
X			    cp++;
X		    *cp = '\0';
X		    *pp++ = 0;
X		    havesearch = 1;
X		    continue;
X		}
X		/* read nameservers to query */
X		if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) &&
X		   nserv < MAXNS) {
X		    cp = buf + sizeof("nameserver") - 1;
X		    while (*cp == ' ' || *cp == '\t')
X			    cp++;
X		    if ((*cp == '\0') || (*cp == '\n'))
X			    continue;
X		    if ((_res.nsaddr_list[nserv].sin_addr.s_addr =
X			inet_addr(cp)) == (unsigned)-1) {
X			    _res.nsaddr_list[nserv].sin_addr.s_addr
X				= INADDR_ANY;
X			    continue;
X		    }
X		    _res.nsaddr_list[nserv].sin_family = AF_INET;
X		    _res.nsaddr_list[nserv].sin_port = htons(NAMESERVER_PORT);
X		    nserv++;
X		    continue;
X		}
X		/* read service order */
X		if (!strncmp(buf, "order", sizeof("order") - 1)) {
X			cp = buf + sizeof("order") - 1;
X		    while (*cp == ' ' || *cp == '\t')
X			cp++;
X		    if ((*cp == '\0') || (*cp == '\n'))
X			continue;
X		    norder = 0;
X		    do {
X			if ((dp = index(cp, ',')) != NULL)
X			    *dp = '\0';
X			if (norder >= MAXSERVICES)
X			    continue;
X			if (!strncmp(cp, "bind", sizeof("bind") - 1))
X			    _res.order[norder++] = RES_SERVICE_BIND;
X			else if (!strncmp(cp, "local", sizeof("local") - 1))
X			    _res.order[norder++] = RES_SERVICE_LOCAL;
X			cp = dp + 1;
X		    } while (dp != NULL);
X		    _res.order[norder] = RES_SERVICE_NONE;
X		    continue;
X		}
X	    }
X	    if (nserv > 1) 
X		_res.nscount = nserv;
X	    (void) fclose(fp);
X	}
X	if (_res.defdname[0] == 0) {
X		if (gethostname(buf, sizeof(_res.defdname)) == 0 &&
X		   (cp = index(buf, '.')))
X			(void)strcpy(_res.defdname, cp + 1);
X	}
X
X	/* find components of local domain that might be searched */
X	if (havesearch == 0) {
X		pp = _res.dnsrch;
X		*pp++ = _res.defdname;
X		for (cp = _res.defdname, n = 0; *cp; cp++)
X			if (*cp == '.')
X				n++;
X		cp = _res.defdname;
X		for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH;
X		    n--) {
X			cp = index(cp, '.');
X			*pp++ = ++cp;
X		}
X		*pp++ = 0;
X	}
X	/* default search order to bind only */
X	if (norder == 0) {
X		_res.order[0] = RES_SERVICE_BIND;
X		_res.order[1] = RES_SERVICE_NONE;
X	}
X	_res.options |= RES_INIT;
X	return (0);
X}
END_OF_FILE
if test 6340 -ne `wc -c <'res_init.c'`; then
    echo shar: \"'res_init.c'\" unpacked with wrong size!
fi
# end of 'res_init.c'
fi
if test -f 'res_mkquery.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'res_mkquery.c'\"
else
echo shar: Extracting \"'res_mkquery.c'\" \(5295 characters\)
sed "s/^X//" >'res_mkquery.c' <<'END_OF_FILE'
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: (1) source distributions retain this entire copyright
X * notice and comment, and (2) distributions including binaries display
X * the following acknowledgement:  ``This product includes software
X * developed by the University of California, Berkeley and its contributors''
X * in the documentation or other materials provided with the distribution
X * and in all advertising materials mentioning features or use of this
X * software. Neither the name of the University nor the names of its
X * contributors may be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)res_mkquery.c	6.12 (Berkeley) 6/1/90";
X#endif /* LIBC_SCCS and not lint */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <netinet/in.h>
X#include <arpa/nameser.h>
X#include <resolv.h>
X
X/*
X * Form all types of queries.
X * Returns the size of the result or -1.
X */
Xres_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen)
X	int op;			/* opcode of query */
X	char *dname;		/* domain name */
X	int class, type;	/* class and type of query */
X	char *data;		/* resource record data */
X	int datalen;		/* length of data */
X	struct rrec *newrr;	/* new rr for modify or append */
X	char *buf;		/* buffer to put query */
X	int buflen;		/* size of buffer */
X{
X	register HEADER *hp;
X	register char *cp;
X	register int n;
X	char *dnptrs[10], **dpp, **lastdnptr;
X	extern char *index();
X
X#ifdef DEBUG
X	if (_res.options & RES_DEBUG)
X		printf("res_mkquery(%d, %s, %d, %d)\n", op, dname, class, type);
X#endif DEBUG
X	/*
X	 * Initialize header fields.
X	 */
X	if ((buf == NULL) || (buflen < sizeof(HEADER)))
X		return(-1);
X	bzero(buf, sizeof(HEADER));
X	hp = (HEADER *) buf;
X	hp->id = htons(++_res.id);
X	hp->opcode = op;
X	hp->pr = (_res.options & RES_PRIMARY) != 0;
X	hp->rd = (_res.options & RES_RECURSE) != 0;
X	hp->rcode = NOERROR;
X	cp = buf + sizeof(HEADER);
X	buflen -= sizeof(HEADER);
X	dpp = dnptrs;
X	*dpp++ = buf;
X	*dpp++ = NULL;
X	lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
X	/*
X	 * perform opcode specific processing
X	 */
X	switch (op) {
X	case QUERY:
X		if ((buflen -= QFIXEDSZ) < 0)
X			return(-1);
X		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
X			return (-1);
X		cp += n;
X		buflen -= n;
X		putshort(type, cp);
X		cp += sizeof(u_short);
X		putshort(class, cp);
X		cp += sizeof(u_short);
X		hp->qdcount = htons(1);
X		if (op == QUERY || data == NULL)
X			break;
X		/*
X		 * Make an additional record for completion domain.
X		 */
X		buflen -= RRFIXEDSZ;
X		if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0)
X			return (-1);
X		cp += n;
X		buflen -= n;
X		putshort(T_NULL, cp);
X		cp += sizeof(u_short);
X		putshort(class, cp);
X		cp += sizeof(u_short);
X		putlong(0, cp);
X		cp += sizeof(u_long);
X		putshort(0, cp);
X		cp += sizeof(u_short);
X		hp->arcount = htons(1);
X		break;
X
X	case IQUERY:
X		/*
X		 * Initialize answer section
X		 */
X		if (buflen < 1 + RRFIXEDSZ + datalen)
X			return (-1);
X		*cp++ = '\0';	/* no domain name */
X		putshort(type, cp);
X		cp += sizeof(u_short);
X		putshort(class, cp);
X		cp += sizeof(u_short);
X		putlong(0, cp);
X		cp += sizeof(u_long);
X		putshort(datalen, cp);
X		cp += sizeof(u_short);
X		if (datalen) {
X			bcopy(data, cp, datalen);
X			cp += datalen;
X		}
X		hp->ancount = htons(1);
X		break;
X
X#ifdef ALLOW_UPDATES
X	/*
X	 * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
X	 * (Record to be modified is followed by its replacement in msg.)
X	 */
X	case UPDATEM:
X	case UPDATEMA:
X
X	case UPDATED:
X		/*
X		 * The res code for UPDATED and UPDATEDA is the same; user
X		 * calls them differently: specifies data for UPDATED; server
X		 * ignores data if specified for UPDATEDA.
X		 */
X	case UPDATEDA:
X		buflen -= RRFIXEDSZ + datalen;
X		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
X			return (-1);
X		cp += n;
X		putshort(type, cp);
X                cp += sizeof(u_short);
X                putshort(class, cp);
X                cp += sizeof(u_short);
X		putlong(0, cp);
X		cp += sizeof(u_long);
X		putshort(datalen, cp);
X                cp += sizeof(u_short);
X		if (datalen) {
X			bcopy(data, cp, datalen);
X			cp += datalen;
X		}
X		if ( (op == UPDATED) || (op == UPDATEDA) ) {
X			hp->ancount = htons(0);
X			break;
X		}
X		/* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
X
X	case UPDATEA:	/* Add new resource record */
X		buflen -= RRFIXEDSZ + datalen;
X		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
X			return (-1);
X		cp += n;
X		putshort(newrr->r_type, cp);
X                cp += sizeof(u_short);
X                putshort(newrr->r_class, cp);
X                cp += sizeof(u_short);
X		putlong(0, cp);
X		cp += sizeof(u_long);
X		putshort(newrr->r_size, cp);
X                cp += sizeof(u_short);
X		if (newrr->r_size) {
X			bcopy(newrr->r_data, cp, newrr->r_size);
X			cp += newrr->r_size;
X		}
X		hp->ancount = htons(0);
X		break;
X
X#endif ALLOW_UPDATES
X	}
X	return (cp - buf);
X}
END_OF_FILE
if test 5295 -ne `wc -c <'res_mkquery.c'`; then
    echo shar: \"'res_mkquery.c'\" unpacked with wrong size!
fi
# end of 'res_mkquery.c'
fi
if test -f 'strcasecmp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'strcasecmp.c'\"
else
echo shar: Extracting \"'strcasecmp.c'\" \(3766 characters\)
sed "s/^X//" >'strcasecmp.c' <<'END_OF_FILE'
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 the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)strcasecmp.c	5.7 (Berkeley) 2/7/89";
X#endif /* LIBC_SCCS and not lint */
X
X#include <sys/types.h>
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 u_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', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
X	'\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
X	'\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
X	'\330', '\331', '\332', '\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	char *s1, *s2;
X{
X	register u_char	*cm = charmap,
X			*us1 = (u_char *)s1,
X			*us2 = (u_char *)s2;
X
X	while (cm[*us1] == cm[*us2++])
X		if (*us1++ == '\0')
X			return(0);
X	return(cm[*us1] - cm[*--us2]);
X}
X
Xstrncasecmp(s1, s2, n)
X	char *s1, *s2;
X	register int n;
X{
X	register u_char	*cm = charmap,
X			*us1 = (u_char *)s1,
X			*us2 = (u_char *)s2;
X
X	while (--n >= 0 && cm[*us1] == cm[*us2++])
X		if (*us1++ == '\0')
X			return(0);
X	return(n < 0 ? 0 : cm[*us1] - cm[*--us2]);
X}
END_OF_FILE
if test 3766 -ne `wc -c <'strcasecmp.c'`; then
    echo shar: \"'strcasecmp.c'\" unpacked with wrong size!
fi
# end of 'strcasecmp.c'
fi
if test -f 'strerror.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'strerror.c'\"
else
echo shar: Extracting \"'strerror.c'\" \(1446 characters\)
sed "s/^X//" >'strerror.c' <<'END_OF_FILE'
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 provided
X * that: (1) source distributions retain this entire copyright notice and
X * comment, and (2) distributions including binaries display the following
X * acknowledgement:  ``This product includes software developed by the
X * University of California, Berkeley and its contributors'' in the
X * documentation or other materials provided with the distribution and in
X * all advertising materials mentioning features or use of this software.
X * Neither the name of the University nor the names of its contributors may
X * be used to endorse or promote products derived from this software without
X * specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
X * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
X * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)strerror.c	5.4 (Berkeley) 6/24/90";
X#endif /* LIBC_SCCS and not lint */
X
X#include <string.h>
X
Xchar *
Xstrerror(errnum)
X	int errnum;
X{
X	extern int sys_nerr;
X	extern char *sys_errlist[];
X	static char ebuf[40];		/* 64-bit number + slop */
X
X	if ((unsigned int)errnum < sys_nerr)
X		return(sys_errlist[errnum]);
X	(void)sprintf(ebuf, "Unknown error: %d", errnum);
X	return(ebuf);
X}
END_OF_FILE
if test 1446 -ne `wc -c <'strerror.c'`; then
    echo shar: \"'strerror.c'\" unpacked with wrong size!
fi
# end of 'strerror.c'
fi
if test -f 'strpbrk.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'strpbrk.c'\"
else
echo shar: Extracting \"'strpbrk.c'\" \(1162 characters\)
sed "s/^X//" >'strpbrk.c' <<'END_OF_FILE'
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 the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X#if defined(LIBC_SCCS) && !defined(lint)
Xstatic char sccsid[] = "@(#)strpbrk.c	5.5 (Berkeley) 5/10/89";
X#endif /* LIBC_SCCS and not lint */
X
Xchar *
Xstrpbrk(s1, s2)
X	register char *s1, *s2;
X{
X	register int c, sc;
X	register char *scanp;
X
X	for (; c = *s1; ++s1)
X		for (scanp = s2; sc = *scanp++;)
X			if (sc == c)
X				return(s1);
X	return(0);
X}
END_OF_FILE
if test 1162 -ne `wc -c <'strpbrk.c'`; then
    echo shar: \"'strpbrk.c'\" unpacked with wrong size!
fi
# end of 'strpbrk.c'
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0