[comp.sys.ibm.pc.rt] Fix for libc, part 3 of 3, IBM/4.3

brunner@bullhead.uucp (12/05/89)

Subject: Fix for libc (part 3)
Index: /usr/src/lib/libc IBM/4.3

Description:
	The C library name resolver code distributed in the December
	release does not contain all of the routines in the post-4.3
	Berkeley release. Compilation of Tahoe-release versions of
	sendmail (5.61) and named (4.8) fail. This kit adds files to
	and patches existing files in the include and libc source trees.

	When this kit is installed and the library has been rebuilt and
	reinstalled replacement of named and sendmail only requires the
	usual make install sequence. (See /usr/src/Makefile, and
	/usr/src/lib/libc/Makefile)

	Sendmail version 5.61 and named (aka "BIND") version 4.8 are
	available via anonymous ftp at numerous sites on the Internet.
	For the benefit of sites without Internet access, compressed tar
	images of each are available via uucp from ibmsupt, the sizes
	are:

		314397 named4.8.tar.Z
		473205 sendmail5.61.tar.Z

	It is strongly recommended that the versions of sendmail and
	named shipped with the December 88 release be replaced with
	these versions.

	This is part 3 of a 3 part patch installation kit. The contents
	of the kit are:

part 1  patchs to the following files in /usr/src/include:
	netdb.h, resolve and arpa/nameser.h

part 2  shar file containing the following files in /usr/src/lib/libc:
	gen/{setenv.c, strcasecmp.c}
	net/{herror.c, res_query.c}
        
part 3  patchs to the following files in /usr/src/lib/libc:
	gen/{Makefile, getenv.c}
	net/{Makefile, res_comp.c, res_debug.c, res_init.c, res_mkquery.c,
	and res_send.c}

Fix:	Change directories to /usr/src/lib/libc and apply the following
	patch, e.g.,

		patch -p1 < this_file

	This is the last part of the 3 part kit.

Installation Instructions (libc, named and sendmail only):

		cd /usr/src/include; make install
		cd /usr/src/lib/libc; make depend
		cd /usr/src; make lib
		cd /usr/src/lib/libc; make install
		cd /usr/src/etc/named; make depend; make; make install
		cd /usr/src/usr.lib/sendmail; make depend; make; make install

	The `make install' in the include directory will install the
	patched include files. The `make depend' will rebuild the explicit
	dependency lines in the libc makefiles. The `make lib' in the src
	directory will compile everything in libc and the Portable C
	Compiler (cc) without installing anything. This line in the
	Makefile may be commented out when using the MetaWare C Compiler.
	The `make install' will then install the new C library.

	The remaining steps for the installation of named and sendmail
	are self explanitory. See the Installation Recommendations, below.


Installation Recommendations:
	It is recommended that `make -n name' be run prior to each
	step (see make.1) to ensure that each step is understood, and
	that stdout and stderr be redirected to a logfile during all
	phases of the build for examination.

	Makefiles with read-only permissions and un-made symbolic links
	are two common causes of failure during the `make depend' and
	`make' phases.


diff -r -c libc.dist/gen/Makefile libc.fix/gen/Makefile
*** libc.dist/gen/Makefile	Fri Dec  9 11:33:39 1988
--- libc.fix/gen/Makefile	Thu Nov 16 10:26:40 1989
***************
*** 34,40 ****
  	random.c readdir.c regex.c \
  	scandir.c seekdir.c setegid.c seteuid.c setgid.c setrgid.c setruid.c \
  	setuid.c siginterrupt.c siglist.c signal.c sleep.c strncat.c strncpy.c \
! 	swab.c syslog.c system.c \
  	telldir.c time.c timezone.c ttyname.c ttyslot.c \
  	ualarm.c usleep.c \
  	valloc.c \
--- 34,40 ----
  	random.c readdir.c regex.c \
  	scandir.c seekdir.c setegid.c seteuid.c setgid.c setrgid.c setruid.c \
  	setuid.c siginterrupt.c siglist.c signal.c sleep.c strncat.c strncpy.c \
! 	strcasecmp.c swab.c syslog.c system.c setenv.c \
  	telldir.c time.c timezone.c ttyname.c ttyslot.c \
  	ualarm.c usleep.c \
  	valloc.c \
***************
*** 56,62 ****
  #        random.c readdir.c regex.c \
  #        scandir.c seekdir.c setegid.c seteuid.c setgid.c setrgid.c setruid.c \
  #        setuid.c siginterrupt.c siglist.c signal.c sleep.c strncat.c strncpy.c \
! #        swab.c syslog.c system.c \
  #        telldir.c time.c timezone.c ttyname.c ttyslot.c \
  #        ualarm.c usleep.c \
  #        valloc.c
--- 56,62 ----
  #        random.c readdir.c regex.c \
  #        scandir.c seekdir.c setegid.c seteuid.c setgid.c setrgid.c setruid.c \
  #        setuid.c siginterrupt.c siglist.c signal.c sleep.c strncat.c strncpy.c \
! #        strcasecmp.c swab.c syslog.c system.c setenv.c \
  #        telldir.c time.c timezone.c ttyname.c ttyslot.c \
  #        ualarm.c usleep.c \
  #        valloc.c
***************
*** 79,85 ****
  	random.o readdir.o regex.o \
  	scandir.o seekdir.o setegid.o seteuid.o setgid.o setrgid.o setruid.o \
  	setuid.o siginterrupt.o siglist.o signal.o sleep.o strncat.o strncpy.o \
! 	swab.o syslog.o system.o \
  	telldir.o time.o timezone.o ttyname.o ttyslot.o \
  	ualarm.o usleep.o \
  	valloc.o \
--- 79,85 ----
  	random.o readdir.o regex.o \
  	scandir.o seekdir.o setegid.o seteuid.o setgid.o setrgid.o setruid.o \
  	setuid.o siginterrupt.o siglist.o signal.o sleep.o strncat.o strncpy.o \
! 	strcasecmp.o swab.o syslog.o system.o setenv.o \
  	telldir.o time.o timezone.o ttyname.o ttyslot.o \
  	ualarm.o usleep.o \
  	valloc.o \
***************
*** 101,107 ****
  #        random.o readdir.o regex.o \
  #        scandir.o seekdir.o setegid.o seteuid.o setgid.o setrgid.o setruid.o \
  #        setuid.o siginterrupt.o siglist.o signal.o sleep.o strncat.o strncpy.o \
! #        swab.o syslog.o system.o \
  #        telldir.o time.o timezone.o ttyname.o ttyslot.o \
  #        ualarm.o usleep.o \
  #        valloc.o
--- 101,107 ----
  #        random.o readdir.o regex.o \
  #        scandir.o seekdir.o setegid.o seteuid.o setgid.o setrgid.o setruid.o \
  #        setuid.o siginterrupt.o siglist.o signal.o sleep.o strncat.o strncpy.o \
! #        strcasecmp.o swab.o syslog.o system.o setenv.o \
  #        telldir.o time.o timezone.o ttyname.o ttyslot.o \
  #        ualarm.o usleep.o \
  #        valloc.o
diff -r -c libc.dist/gen/getenv.c libc.fix/gen/getenv.c
*** libc.dist/gen/getenv.c	Fri Dec  9 11:33:58 1988
--- libc.fix/gen/getenv.c	Wed Nov 29 15:23:41 1989
***************
*** 54,56 ****
--- 54,85 ----
  		return(s2);
  	return(NULL);
  }
+ 
+ 
+ /*
+  * _findenv --
+  *      Returns pointer to value associated with name, if any, else NULL.
+  *      Sets offset to be the offset of the name/value combination in the
+  *      environmental array, for use by setenv(3) and unsetenv(3).
+  *      Explicitly removes '=' in argument name.
+  *
+  *      This routine *should* be a static; don't use it.
+  */
+ char *
+ _findenv(name, offset)
+         register char *name;
+         int *offset;
+ {
+         extern char **environ;
+         register int len;
+         register char **P, *C;
+ 
+         for (C = name, len = 0; *C && *C != '='; ++C, ++len);
+         for (P = environ; *P; ++P)
+                 if (!strncmp(*P, name, len))
+                         if (*(C = *P + len) == '=') {
+                                 *offset = P - environ;
+                                 return(++C);
+                         }
+         return(NULL);
+ }
diff -r -c libc.dist/net/Makefile libc.fix/net/Makefile
*** libc.dist/net/Makefile	Fri Dec  9 11:35:56 1988
--- libc.fix/net/Makefile	Thu Nov 16 10:27:11 1989
***************
*** 20,32 ****
  # VFS version
  SRCS=	getnetgrent.c \
  	innetgr.c \
! 	rcmd.c rexec.c ruserpass.c \
! 	res_comp.c res_debug.c res_init.c res_mkquery.c res_send.c
  
  OBJS=	getnetgrent.o \
  	innetgr.o \
! 	rcmd.o rexec.o ruserpass.o \
! 	res_comp.o res_debug.o res_init.o res_mkquery.o res_send.o
  CFLAGS=	-O ${DEFS} -I/usr/include
  
  # non-VFS version
--- 20,32 ----
  # VFS version
  SRCS=	getnetgrent.c \
  	innetgr.c \
! 	herror.c rcmd.c rexec.c ruserpass.c res_comp.c res_debug.c \
! 	res_init.c res_mkquery.c res_query.c res_send.c
  
  OBJS=	getnetgrent.o \
  	innetgr.o \
! 	herror.o rcmd.o rexec.o ruserpass.o res_comp.o res_debug.o \
! 	res_init.o res_mkquery.o res_query.o res_send.o
  CFLAGS=	-O ${DEFS} -I/usr/include
  
  # non-VFS version
diff -r -c libc.dist/net/res_comp.c libc.fix/net/res_comp.c
*** libc.dist/net/res_comp.c	Fri Dec  9 11:37:07 1988
--- libc.fix/net/res_comp.c	Fri Dec  1 10:41:51 1989
***************
*** 12,30 ****
  
  /*
   * Copyright (c) 1985 Regents of the University of California.
!  * All rights reserved.  The Berkeley software License Agreement
!  * specifies the terms and conditions for redistribution.
   */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char sccsid[] = "@(#)res_comp.c	6.7 (Berkeley) 3/11/86";
! #endif LIBC_SCCS and not lint
  
  #include <sys/types.h>
  #include <stdio.h>
  #include <arpa/nameser.h>
  
- 
  /*
   * Expand compressed domain name 'comp_dn' to full domain name.
   * 'msg' is a pointer to the begining of the message,
--- 12,40 ----
  
  /*
   * Copyright (c) 1985 Regents of the University of California.
!  * All rights reserved.
!  *
!  * Redistribution and use in source and binary forms are permitted
!  * provided that the above copyright notice and this paragraph are
!  * duplicated in all such forms and that any documentation,
!  * advertising materials, and other materials related to such
!  * distribution and use acknowledge that the software was developed
!  * by the University of California, Berkeley.  The name of the
!  * University may not be used to endorse or promote products derived
!  * from this software without specific prior written permission.
!  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
!  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
!  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char sccsid[] = "@(#)res_comp.c	6.14 (Berkeley) 6/27/88";
! #endif /* LIBC_SCCS and not lint */
  
  #include <sys/types.h>
  #include <stdio.h>
  #include <arpa/nameser.h>
  
  /*
   * Expand compressed domain name 'comp_dn' to full domain name.
   * 'msg' is a pointer to the begining of the message,
***************
*** 33,45 ****
   * Return size of compressed name or -1 if there was an error.
   */
  dn_expand(msg, eomorig, comp_dn, exp_dn, length)
! 	char *msg, *eomorig, *comp_dn, *exp_dn;
  	int length;
  {
! 	register char *cp, *dn;
  	register int n, c;
! 	char *eom;
! 	int len = -1;
  
  	dn = exp_dn;
  	cp = comp_dn;
--- 43,55 ----
   * Return size of compressed name or -1 if there was an error.
   */
  dn_expand(msg, eomorig, comp_dn, exp_dn, length)
! 	u_char *msg, *eomorig, *comp_dn, *exp_dn;
  	int length;
  {
! 	register u_char *cp, *dn;
  	register int n, c;
! 	u_char *eom;
! 	int len = -1, checked = 0;
  
  	dn = exp_dn;
  	cp = comp_dn;
***************
*** 60,65 ****
--- 70,76 ----
  			}
  			if (dn+n >= eom)
  				return (-1);
+ 			checked += n + 1;
  			while (--n >= 0) {
  				if ((c = *cp++) == '.') {
  					if (dn+n+1 >= eom)
***************
*** 78,83 ****
--- 89,102 ----
  			cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
  			if (cp < msg || cp >= eomorig)	/* out of range */
  				return(-1);
+ 			checked += 2;
+ 			/*
+ 			 * Check for loops in the compressed name;
+ 			 * if we've looked at the whole message,
+ 			 * there must be a loop.
+ 			 */
+ 			if (checked >= eomorig - msg)
+ 				return (-1);
  			break;
  
  		default:
***************
*** 103,116 ****
   * is NULL, we don't update the list.
   */
  dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
! 	char *exp_dn, *comp_dn;
  	int length;
! 	char **dnptrs, **lastdnptr;
  {
! 	register char *cp, *dn;
  	register int c, l;
! 	char **cpp, **lpp, *sp, *eob;
! 	char *msg;
  
  	dn = exp_dn;
  	cp = comp_dn;
--- 122,135 ----
   * is NULL, we don't update the list.
   */
  dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
! 	u_char *exp_dn, *comp_dn;
  	int length;
! 	u_char **dnptrs, **lastdnptr;
  {
! 	register u_char *cp, *dn;
  	register int c, l;
! 	u_char **cpp, **lpp, *sp, *eob;
! 	u_char *msg;
  
  	dn = exp_dn;
  	cp = comp_dn;
***************
*** 171,184 ****
  /*
   * Skip over a compressed domain name. Return the size or -1.
   */
! dn_skip(comp_dn)
! 	char *comp_dn;
  {
! 	register char *cp;
  	register int n;
  
  	cp = comp_dn;
! 	while (n = *cp++) {
  		/*
  		 * check for indirection
  		 */
--- 190,203 ----
  /*
   * Skip over a compressed domain name. Return the size or -1.
   */
! dn_skipname(comp_dn, eom)
! 	u_char *comp_dn, *eom;
  {
! 	register u_char *cp;
  	register int n;
  
  	cp = comp_dn;
! 	while (cp < eom && (n = *cp++)) {
  		/*
  		 * check for indirection
  		 */
***************
*** 199,214 ****
  /*
   * Search for expanded name from a list of previously compressed names.
   * Return the offset from msg if found or -1.
   */
  dn_find(exp_dn, msg, dnptrs, lastdnptr)
! 	char *exp_dn, *msg;
! 	char **dnptrs, **lastdnptr;
  {
! 	register char *dn, *cp, **cpp;
  	register int n;
! 	char *sp;
  
! 	for (cpp = dnptrs + 1; cpp < lastdnptr; cpp++) {
  		dn = exp_dn;
  		sp = cp = *cpp;
  		while (n = *cp++) {
--- 218,236 ----
  /*
   * Search for expanded name from a list of previously compressed names.
   * Return the offset from msg if found or -1.
+  * dnptrs is the pointer to the first name on the list,
+  * not the pointer to the start of the message.
   */
+ static
  dn_find(exp_dn, msg, dnptrs, lastdnptr)
! 	u_char *exp_dn, *msg;
! 	u_char **dnptrs, **lastdnptr;
  {
! 	register u_char *dn, *cp, **cpp;
  	register int n;
! 	u_char *sp;
  
! 	for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
  		dn = exp_dn;
  		sp = cp = *cpp;
  		while (n = *cp++) {
***************
*** 233,239 ****
  				return (-1);
  
  			case INDIR_MASK:	/* indirection */
! 				cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
  			}
  		}
  		if (*dn == '\0')
--- 255,261 ----
  				return (-1);
  
  			case INDIR_MASK:	/* indirection */
! 				cp = msg + (((n & 0x3f) << 8) | *cp);
  			}
  		}
  		if (*dn == '\0')
***************
*** 247,257 ****
   * Routines to insert/extract short/long's. Must account for byte
   * order and non-alignment problems. This code at least has the
   * advantage of being portable.
   */
  
  u_short
! getshort(msgp)
! 	char *msgp;
  {
  	register u_char *p = (u_char *) msgp;
  #ifdef vax
--- 269,281 ----
   * Routines to insert/extract short/long's. Must account for byte
   * order and non-alignment problems. This code at least has the
   * advantage of being portable.
+  *
+  * used by sendmail.
   */
  
  u_short
! _getshort(msgp)
! 	u_char *msgp;
  {
  	register u_char *p = (u_char *) msgp;
  #ifdef vax
***************
*** 268,275 ****
  }
  
  u_long
! getlong(msgp)
! 	char *msgp;
  {
  	register u_char *p = (u_char *) msgp;
  	register u_long u;
--- 292,299 ----
  }
  
  u_long
! _getlong(msgp)
! 	u_char *msgp;
  {
  	register u_char *p = (u_char *) msgp;
  	register u_long u;
***************
*** 283,289 ****
  
  putshort(s, msgp)
  	register u_short s;
! 	register char *msgp;
  {
  
  	msgp[1] = s;
--- 307,313 ----
  
  putshort(s, msgp)
  	register u_short s;
! 	register u_char *msgp;
  {
  
  	msgp[1] = s;
***************
*** 292,298 ****
  
  putlong(l, msgp)
  	register u_long l;
! 	register char *msgp;
  {
  
  	msgp[3] = l;
--- 316,322 ----
  
  putlong(l, msgp)
  	register u_long l;
! 	register u_char *msgp;
  {
  
  	msgp[3] = l;
***************
*** 300,302 ****
--- 324,401 ----
  	msgp[1] = (l >>= 8);
  	msgp[0] = l >> 8;
  }
+ 
+ /*
+  * Compatibility with pre-tahoe release
+  * dn_skip, getlong and getshort
+  *
+  */
+ 
+ 
+ 
+ /*
+  * Skip over a compressed domain name. Return the size or -1.
+  */
+ dn_skip(comp_dn)
+ 	char *comp_dn;
+ {
+ 	register char *cp;
+ 	register int n;
+ 
+ 	cp = comp_dn;
+ 	while (n = *cp++) {
+ 		/*
+ 		 * check for indirection
+ 		 */
+ 		switch (n & INDIR_MASK) {
+ 		case 0:		/* normal case, n == len */
+ 			cp += n;
+ 			continue;
+ 		default:	/* illegal type */
+ 			return (-1);
+ 		case INDIR_MASK:	/* indirection */
+ 			cp++;
+ 		}
+ 		break;
+ 	}
+ 	return (cp - comp_dn);
+ }
+ 
+ 
+ /*
+  * Routines to insert/extract short/long's. Must account for byte
+  * order and non-alignment problems. This code at least has the
+  * advantage of being portable.
+  */
+ 
+ u_short
+ getshort(msgp)
+ 	char *msgp;
+ {
+ 	register u_char *p = (u_char *) msgp;
+ #ifdef vax
+ 	/*
+ 	 * vax compiler doesn't put shorts in registers
+ 	 */
+ 	register u_long u;
+ #else
+ 	register u_short u;
+ #endif
+ 
+ 	u = *p++ << 8;
+ 	return ((u_short)(u | *p));
+ }
+ 
+ u_long
+ getlong(msgp)
+ 	char *msgp;
+ {
+ 	register u_char *p = (u_char *) msgp;
+ 	register u_long u;
+ 
+ 	u = *p++; u <<= 8;
+ 	u |= *p++; u <<= 8;
+ 	u |= *p++; u <<= 8;
+ 	return (u | *p);
+ }
+ 
diff -r -c libc.dist/net/res_debug.c libc.fix/net/res_debug.c
*** libc.dist/net/res_debug.c	Fri Dec  9 11:37:10 1988
--- libc.fix/net/res_debug.c	Tue Oct 31 12:44:52 1989
***************
*** 12,24 ****
  
  /*
   * Copyright (c) 1985 Regents of the University of California.
!  * All rights reserved.  The Berkeley software License Agreement
!  * specifies the terms and conditions for redistribution.
   */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char sccsid[] = "@(#)res_debug.c	5.13 (Berkeley) 3/9/86";
! #endif LIBC_SCCS and not lint
  
  #if defined(lint) && !defined(DEBUG)
  #define DEBUG
--- 12,35 ----
  
  /*
   * Copyright (c) 1985 Regents of the University of California.
!  * All rights reserved.
!  *
!  * Redistribution and use in source and binary forms are permitted
!  * provided that the above copyright notice and this paragraph are
!  * duplicated in all such forms and that any documentation,
!  * advertising materials, and other materials related to such
!  * distribution and use acknowledge that the software was developed
!  * by the University of California, Berkeley.  The name of the
!  * University may not be used to endorse or promote products derived
!  * from this software without specific prior written permission.
!  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
!  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
!  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char sccsid[] = "@(#)res_debug.c	5.24 (Berkeley) 6/27/88";
! #endif /* LIBC_SCCS and not lint */
  
  #if defined(lint) && !defined(DEBUG)
  #define DEBUG
***************
*** 29,38 ****
  #include <stdio.h>
  #include <arpa/nameser.h>
  
! extern char *p_cdname(), *p_rr(), *p_type(), *p_class();
  extern char *inet_ntoa();
  
! char *opcodes[] = {
  	"QUERY",
  	"IQUERY",
  	"CQUERYM",
--- 40,49 ----
  #include <stdio.h>
  #include <arpa/nameser.h>
  
! extern char *p_cdname(), *p_rr(), *p_type(), *p_class(), *p_time();
  extern char *inet_ntoa();
  
! char *_res_opcodes[] = {
  	"QUERY",
  	"IQUERY",
  	"CQUERYM",
***************
*** 42,57 ****
  	"6",
  	"7",
  	"8",
- 	"9",
- 	"10",
  	"UPDATEA",
  	"UPDATED",
  	"UPDATEM",
  	"ZONEINIT",
  	"ZONEREF",
  };
  
! char *rcodes[] = {
  	"NOERROR",
  	"FORMERR",
  	"SERVFAIL",
--- 53,68 ----
  	"6",
  	"7",
  	"8",
  	"UPDATEA",
  	"UPDATED",
+ 	"UPDATEDA",
  	"UPDATEM",
+ 	"UPDATEMA",
  	"ZONEINIT",
  	"ZONEREF",
  };
  
! char *_res_resultcodes[] = {
  	"NOERROR",
  	"FORMERR",
  	"SERVFAIL",
***************
*** 97,105 ****
  	hp = (HEADER *)msg;
  	cp = msg + sizeof(HEADER);
  	fprintf(file,"HEADER:\n");
! 	fprintf(file,"\topcode = %s", opcodes[hp->opcode]);
  	fprintf(file,", id = %d", ntohs(hp->id));
! 	fprintf(file,", rcode = %s\n", rcodes[hp->rcode]);
  	fprintf(file,"\theader flags: ");
  	if (hp->qr)
  		fprintf(file," qr");
--- 108,116 ----
  	hp = (HEADER *)msg;
  	cp = msg + sizeof(HEADER);
  	fprintf(file,"HEADER:\n");
! 	fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
  	fprintf(file,", id = %d", ntohs(hp->id));
! 	fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
  	fprintf(file,"\theader flags: ");
  	if (hp->qr)
  		fprintf(file," qr");
***************
*** 127,135 ****
  			cp = p_cdname(cp, msg, file);
  			if (cp == NULL)
  				return;
! 			fprintf(file,", type = %s", p_type(getshort(cp)));
  			cp += sizeof(u_short);
! 			fprintf(file,", class = %s\n\n", p_class(getshort(cp)));
  			cp += sizeof(u_short);
  		}
  	}
--- 138,146 ----
  			cp = p_cdname(cp, msg, file);
  			if (cp == NULL)
  				return;
! 			fprintf(file,", type = %s", p_type(_getshort(cp)));
  			cp += sizeof(u_short);
! 			fprintf(file,", class = %s\n\n", p_class(_getshort(cp)));
  			cp += sizeof(u_short);
  		}
  	}
***************
*** 207,219 ****
  
  	if ((cp = p_cdname(cp, msg, file)) == NULL)
  		return (NULL);			/* compression error */
! 	fprintf(file,"\n\ttype = %s", p_type(type = getshort(cp)));
  	cp += sizeof(u_short);
! 	fprintf(file,", class = %s", p_class(class = getshort(cp)));
  	cp += sizeof(u_short);
! 	fprintf(file,", ttl = %u", getlong(cp));
  	cp += sizeof(u_long);
! 	fprintf(file,", dlen = %d\n", dlen = getshort(cp));
  	cp += sizeof(u_short);
  	cp1 = cp;
  	/*
--- 218,230 ----
  
  	if ((cp = p_cdname(cp, msg, file)) == NULL)
  		return (NULL);			/* compression error */
! 	fprintf(file,"\n\ttype = %s", p_type(type = _getshort(cp)));
  	cp += sizeof(u_short);
! 	fprintf(file,", class = %s", p_class(class = _getshort(cp)));
  	cp += sizeof(u_short);
! 	fprintf(file,", ttl = %s", p_time(cp));
  	cp += sizeof(u_long);
! 	fprintf(file,", dlen = %d\n", dlen = _getshort(cp));
  	cp += sizeof(u_short);
  	cp1 = cp;
  	/*
***************
*** 237,242 ****
--- 248,255 ----
  				cp += dlen;
  			}
  			break;
+ 		default:
+ 			cp += dlen;
  		}
  		break;
  	case T_CNAME:
***************
*** 270,289 ****
  		cp = p_cdname(cp, msg, file);
  		fprintf(file,"\n\tmail addr = ");
  		cp = p_cdname(cp, msg, file);
! 		fprintf(file,"\n\tserial=%ld", getlong(cp));
  		cp += sizeof(u_long);
! 		fprintf(file,", refresh=%ld", getlong(cp));
  		cp += sizeof(u_long);
! 		fprintf(file,", retry=%ld", getlong(cp));
  		cp += sizeof(u_long);
! 		fprintf(file,", expire=%ld", getlong(cp));
  		cp += sizeof(u_long);
! 		fprintf(file,", min=%ld\n", getlong(cp));
  		cp += sizeof(u_long);
  		break;
  
  	case T_MX:
! 		fprintf(file,"\tpreference = %ld,",getshort(cp));
  		cp += sizeof(u_short);
  		fprintf(file," name = ");
  		cp = p_cdname(cp, msg, file);
--- 283,302 ----
  		cp = p_cdname(cp, msg, file);
  		fprintf(file,"\n\tmail addr = ");
  		cp = p_cdname(cp, msg, file);
! 		fprintf(file,"\n\tserial=%ld", _getlong(cp));
  		cp += sizeof(u_long);
! 		fprintf(file,", refresh=%s", p_time(cp));
  		cp += sizeof(u_long);
! 		fprintf(file,", retry=%s", p_time(cp));
  		cp += sizeof(u_long);
! 		fprintf(file,", expire=%s", p_time(cp));
  		cp += sizeof(u_long);
! 		fprintf(file,", min=%s\n", p_time(cp));
  		cp += sizeof(u_long);
  		break;
  
  	case T_MX:
! 		fprintf(file,"\tpreference = %ld,",_getshort(cp));
  		cp += sizeof(u_short);
  		fprintf(file," name = ");
  		cp = p_cdname(cp, msg, file);
***************
*** 304,310 ****
  	case T_UID:
  	case T_GID:
  		if (dlen == 4) {
! 			fprintf(file,"\t%ld\n", getlong(cp));
  			cp += sizeof(int);
  		}
  		break;
--- 317,323 ----
  	case T_UID:
  	case T_GID:
  		if (dlen == 4) {
! 			fprintf(file,"\t%ld\n", _getlong(cp));
  			cp += sizeof(int);
  		}
  		break;
***************
*** 328,333 ****
--- 341,364 ----
  		putc('\n',file);
  		break;
  
+ #ifdef ALLOW_T_UNSPEC
+ 	case T_UNSPEC:
+ 		{
+ 			int NumBytes = 8;
+ 			char *DataPtr;
+ 			int i;
+ 
+ 			if (dlen < NumBytes) NumBytes = dlen;
+ 			fprintf(file, "\tFirst %d bytes of hex data:",
+ 				NumBytes);
+ 			for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
+ 				fprintf(file, " %x", *DataPtr);
+ 			fputs("\n", file);
+ 			cp += dlen;
+ 		}
+ 		break;
+ #endif /* ALLOW_T_UNSPEC */
+ 
  	default:
  		fprintf(file,"\t???\n");
  		cp += dlen;
***************
*** 339,346 ****
  #endif
  }
  
! static	char nbuf[20];
! extern	char *sprintf();
  
  /*
   * Return a string for the type
--- 370,376 ----
  #endif
  }
  
! static	char nbuf[40];
  
  /*
   * Return a string for the type
***************
*** 396,403 ****
  		return("UID");
  	case T_GID:
  		return("GID");
  	default:
! 		return (sprintf(nbuf, "%d", type));
  	}
  }
  
--- 426,438 ----
  		return("UID");
  	case T_GID:
  		return("GID");
+ #ifdef ALLOW_T_UNSPEC
+ 	case T_UNSPEC:
+ 		return("UNSPEC");
+ #endif /* ALLOW_T_UNSPEC */
  	default:
! 		(void)sprintf(nbuf, "%d", type);
! 		return(nbuf);
  	}
  }
  
***************
*** 415,420 ****
  	case C_ANY:		/* matches any class */
  		return("ANY");
  	default:
! 		return (sprintf(nbuf, "%d", class));
  	}
  }
--- 450,500 ----
  	case C_ANY:		/* matches any class */
  		return("ANY");
  	default:
! 		(void)sprintf(nbuf, "%d", class);
! 		return(nbuf);
  	}
+ }
+ 
+ /*
+  * Return a mnemonic for a time to live
+  */
+ char
+ *p_time(value)
+ 	u_long value;
+ {
+ 	int secs, mins, hours;
+ 	register char *p;
+ 
+ 	secs = value % 60;
+ 	value /= 60;
+ 	mins = value % 60;
+ 	value /= 60;
+ 	hours = value % 24;
+ 	value /= 24;
+ 
+ #define	PLURALIZE(x)	x, (x == 1) ? "" : "s"
+ 	p = nbuf;
+ 	if (value) {
+ 		(void)sprintf(p, "%d day%s", PLURALIZE(value));
+ 		while (*++p);
+ 	}
+ 	if (hours) {
+ 		if (p != nbuf)
+ 			*p++ = ' ';
+ 		(void)sprintf(p, "%d hour%s", PLURALIZE(hours));
+ 		while (*++p);
+ 	}
+ 	if (mins) {
+ 		if (p != nbuf)
+ 			*p++ = ' ';
+ 		(void)sprintf(p, "%d min%s", PLURALIZE(mins));
+ 		while (*++p);
+ 	}
+ 	if (secs) {
+ 		if (p != nbuf)
+ 			*p++ = ' ';
+ 		(void)sprintf(p, "%d sec%s", PLURALIZE(secs));
+ 		while (*++p);
+ 	}
+ 	return(nbuf);
  }
diff -r -c libc.dist/net/res_init.c libc.fix/net/res_init.c
*** libc.dist/net/res_init.c	Fri Dec  9 11:37:13 1988
--- libc.fix/net/res_init.c	Tue Oct 31 13:22:00 1989
***************
*** 12,24 ****
  
  /*
   * Copyright (c) 1985 Regents of the University of California.
!  * All rights reserved.  The Berkeley software License Agreement
!  * specifies the terms and conditions for redistribution.
   */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char sccsid[] = "@(#)res_init.c	6.5 (Berkeley) 4/11/86";
! #endif LIBC_SCCS and not lint
  
  #include <sys/types.h>
  #include <sys/socket.h>
--- 12,35 ----
  
  /*
   * Copyright (c) 1985 Regents of the University of California.
!  * All rights reserved.
!  *
!  * Redistribution and use in source and binary forms are permitted
!  * provided that the above copyright notice and this paragraph are
!  * duplicated in all such forms and that any documentation,
!  * advertising materials, and other materials related to such
!  * distribution and use acknowledge that the software was developed
!  * by the University of California, Berkeley.  The name of the
!  * University may not be used to endorse or promote products derived
!  * from this software without specific prior written permission.
!  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
!  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
!  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char sccsid[] = "@(#)res_init.c	6.9 (Berkeley) 6/27/88";
! #endif /* LIBC_SCCS and not lint */
  
  #include <sys/types.h>
  #include <sys/socket.h>
***************
*** 33,42 ****
   * non fully qualified domain names.
   */
  
! #ifdef CONFFILE
! char    *conffile = CONFFILE;
! #else
! char    *conffile = "/etc/resolv.conf";
  #endif
  
  /*
--- 44,51 ----
   * non fully qualified domain names.
   */
  
! #ifndef	CONFFILE
! #define	CONFFILE	"/etc/resolv.conf"
  #endif
  
  /*
***************
*** 43,57 ****
   * Resolver state default settings
   */
  
- #ifndef RES_TIMEOUT
- #define RES_TIMEOUT 4
- #endif
- 
  struct state _res = {
!     RES_TIMEOUT,                 /* retransmition time interval */
!     4,                           /* number of times to retransmit */
!     RES_RECURSE|RES_DEFNAMES,    /* options flags */
!     1,                           /* number of name servers */
  };
  
  /*
--- 52,62 ----
   * Resolver state default settings
   */
  
  struct state _res = {
!     RES_TIMEOUT,               	/* retransmition time interval */
!     4,                         	/* number of times to retransmit */
!     RES_DEFAULT,		/* options flags */
!     1,                         	/* number of name servers */
  };
  
  /*
***************
*** 67,79 ****
  res_init()
  {
      register FILE *fp;
!     char buf[BUFSIZ], *cp;
      extern u_long inet_addr();
      extern char *index();
      extern char *strcpy(), *strncpy();
- #ifdef DEBUG
      extern char *getenv();
- #endif DEBUG
      int n = 0;    /* number of nameserver records read from file */
  
      _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
--- 72,83 ----
  res_init()
  {
      register FILE *fp;
!     register char *cp, **pp;
!     char buf[BUFSIZ];
      extern u_long inet_addr();
      extern char *index();
      extern char *strcpy(), *strncpy();
      extern char *getenv();
      int n = 0;    /* number of nameserver records read from file */
  
      _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
***************
*** 82,88 ****
      _res.nscount = 1;
      _res.defdname[0] = '\0';
  
!     if ((fp = fopen(conffile, "r")) != NULL) {
          /* read the config file */
          while (fgets(buf, sizeof(buf), fp) != NULL) {
              /* read default domain name */
--- 86,92 ----
      _res.nscount = 1;
      _res.defdname[0] = '\0';
  
!     if ((fp = fopen(CONFFILE, "r")) != NULL) {
          /* read the config file */
          while (fgets(buf, sizeof(buf), fp) != NULL) {
              /* read default domain name */
***************
*** 131,141 ****
               (void)strcpy(_res.defdname, cp + 1);
      }
  
- #ifdef DEBUG
      /* Allow user to override the local domain definition */
      if ((cp = getenv("LOCALDOMAIN")) != NULL)
          (void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
! #endif DEBUG
      _res.options |= RES_INIT;
      return(0);
  }
--- 135,155 ----
               (void)strcpy(_res.defdname, cp + 1);
      }
  
      /* Allow user to override the local domain definition */
      if ((cp = getenv("LOCALDOMAIN")) != NULL)
          (void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
! 
!     /* find components of local domain that might be searched */
!     pp = _res.dnsrch;
!     *pp++ = _res.defdname;
!     for (cp = _res.defdname, n = 0; *cp; cp++)
! 	if (*cp == '.')
! 	    n++;
!     cp = _res.defdname;
!     for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDNSRCH; n--) {
! 	cp = index(cp, '.');
! 	*pp++ = ++cp;
!     }
      _res.options |= RES_INIT;
      return(0);
  }
diff -r -c libc.dist/net/res_mkquery.c libc.fix/net/res_mkquery.c
*** libc.dist/net/res_mkquery.c	Fri Dec  9 11:37:16 1988
--- libc.fix/net/res_mkquery.c	Tue Oct 31 13:47:14 1989
***************
*** 12,24 ****
  
  /*
   * Copyright (c) 1985 Regents of the University of California.
!  * All rights reserved.  The Berkeley software License Agreement
!  * specifies the terms and conditions for redistribution.
   */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char sccsid[] = "@(#)res_mkquery.c	6.3 (Berkeley) 3/17/86";
! #endif LIBC_SCCS and not lint
  
  #include <stdio.h>
  #include <sys/types.h>
--- 12,30 ----
  
  /*
   * Copyright (c) 1985 Regents of the University of California.
!  * All rights reserved.
!  *
!  * Redistribution and use in source and binary forms are permitted
!  * provided that this notice is preserved and that due credit is given
!  * to the University of California at Berkeley. The name of the University
!  * may not be used to endorse or promote products derived from this
!  * software without specific prior written permission. This software
!  * is provided ``as is'' without express or implied warranty.
   */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char sccsid[] = "@(#)res_mkquery.c	6.7 (Berkeley) 3/7/88";
! #endif /* LIBC_SCCS and not lint */
  
  #include <stdio.h>
  #include <sys/types.h>
***************
*** 26,33 ****
  #include <arpa/nameser.h>
  #include <resolv.h>
  
- extern	char *sprintf();
- 
  /*
   * Form all types of queries.
   * Returns the size of the result or -1.
--- 32,37 ----
***************
*** 82,89 ****
  		if (!(_res.options & RES_INIT))
  			if (res_init() == -1)
  				return(-1);
! 		if (_res.defdname[0] != '\0')
! 			dname = sprintf(dnbuf, "%s.%s", dname, _res.defdname);
  	}
  	/*
  	 * perform opcode specific processing
--- 86,95 ----
  		if (!(_res.options & RES_INIT))
  			if (res_init() == -1)
  				return(-1);
! 		if (_res.defdname[0] != '\0') {
! 			(void)sprintf(dnbuf, "%s.%s", dname, _res.defdname);
! 			dname = dnbuf;
! 		}
  	}
  	/*
  	 * perform opcode specific processing
***************
*** 90,97 ****
  	 */
  	switch (op) {
  	case QUERY:
- 	case CQUERYM:
- 	case CQUERYU:
  		buflen -= QFIXEDSZ;
  		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  			return (-1);
--- 96,101 ----
***************
*** 145,213 ****
  		hp->ancount = htons(1);
  		break;
  
! #ifdef notdef
  	case UPDATED:
  		/*
! 		 * Put record to be added or deleted in additional section
  		 */
  		buflen -= RRFIXEDSZ + datalen;
! 		if ((n = dn_comp(dname, cp, buflen, NULL, NULL)) < 0)
  			return (-1);
  		cp += n;
! 		*((u_short *)cp) = htons(type);
! 		cp += sizeof(u_short);
! 		*((u_short *)cp) = htons(class);
! 		cp += sizeof(u_short);
! 		*((u_long *)cp) = 0;
  		cp += sizeof(u_long);
! 		*((u_short *)cp) = htons(datalen);
! 		cp += sizeof(u_short);
  		if (datalen) {
  			bcopy(data, cp, datalen);
  			cp += datalen;
  		}
! 		break;
  
! 	case UPDATEM:
! 		/*
! 		 * Record to be modified followed by its replacement
! 		 */
  		buflen -= RRFIXEDSZ + datalen;
  		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  			return (-1);
  		cp += n;
! 		*((u_short *)cp) = htons(type);
! 		cp += sizeof(u_short);
! 		*((u_short *)cp) = htons(class);
! 		cp += sizeof(u_short);
! 		*((u_long *)cp) = 0;
  		cp += sizeof(u_long);
! 		*((u_short *)cp) = htons(datalen);
! 		cp += sizeof(u_short);
! 		if (datalen) {
! 			bcopy(data, cp, datalen);
! 			cp += datalen;
! 		}
! 
! 	case UPDATEA:
! 		buflen -= RRFIXEDSZ + newrr->r_size;
! 		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
! 			return (-1);
! 		cp += n;
! 		*((u_short *)cp) = htons(newrr->r_type);
! 		cp += sizeof(u_short);
! 		*((u_short *)cp) = htons(newrr->r_type);
! 		cp += sizeof(u_short);
! 		*((u_long *)cp) = htonl(newrr->r_ttl);
! 		cp += sizeof(u_long);
! 		*((u_short *)cp) = htons(newrr->r_size);
! 		cp += sizeof(u_short);
  		if (newrr->r_size) {
  			bcopy(newrr->r_data, cp, newrr->r_size);
  			cp += newrr->r_size;
  		}
  		break;
! #endif
  	}
  	return (cp - buf);
  }
--- 149,212 ----
  		hp->ancount = htons(1);
  		break;
  
! #ifdef ALLOW_UPDATES
! 	/*
! 	 * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
! 	 * (Record to be modified is followed by its replacement in msg.)
! 	 */
! 	case UPDATEM:
! 	case UPDATEMA:
! 
  	case UPDATED:
  		/*
! 		 * The res code for UPDATED and UPDATEDA is the same; user
! 		 * calls them differently: specifies data for UPDATED; server
! 		 * ignores data if specified for UPDATEDA.
  		 */
+ 	case UPDATEDA:
  		buflen -= RRFIXEDSZ + datalen;
! 		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  			return (-1);
  		cp += n;
! 		putshort(type, cp);
!                 cp += sizeof(u_short);
!                 putshort(class, cp);
!                 cp += sizeof(u_short);
! 		putlong(0, cp);
  		cp += sizeof(u_long);
! 		putshort(datalen, cp);
!                 cp += sizeof(u_short);
  		if (datalen) {
  			bcopy(data, cp, datalen);
  			cp += datalen;
  		}
! 		if ( (op == UPDATED) || (op == UPDATEDA) ) {
! 			hp->ancount = htons(0);
! 			break;
! 		}
! 		/* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
  
! 	case UPDATEA:	/* Add new resource record */
  		buflen -= RRFIXEDSZ + datalen;
  		if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  			return (-1);
  		cp += n;
! 		putshort(newrr->r_type, cp);
!                 cp += sizeof(u_short);
!                 putshort(newrr->r_class, cp);
!                 cp += sizeof(u_short);
! 		putlong(0, cp);
  		cp += sizeof(u_long);
! 		putshort(newrr->r_size, cp);
!                 cp += sizeof(u_short);
  		if (newrr->r_size) {
  			bcopy(newrr->r_data, cp, newrr->r_size);
  			cp += newrr->r_size;
  		}
+ 		hp->ancount = htons(0);
  		break;
! 
! #endif ALLOW_UPDATES
  	}
  	return (cp - buf);
  }
diff -r -c libc.dist/net/res_send.c libc.fix/net/res_send.c
*** libc.dist/net/res_send.c	Fri Dec  9 11:37:19 1988
--- libc.fix/net/res_send.c	Tue Oct 31 13:49:19 1989
***************
*** 13,25 ****
  
  /*
   * Copyright (c) 1985 Regents of the University of California.
!  * All rights reserved.  The Berkeley software License Agreement
!  * specifies the terms and conditions for redistribution.
   */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char sccsid[] = "@(#)res_send.c	6.14 (Berkeley) 5/7/86";
! #endif LIBC_SCCS and not lint
  
  /*
   * Send query to name server and wait for reply.
--- 13,36 ----
  
  /*
   * Copyright (c) 1985 Regents of the University of California.
!  * All rights reserved.
!  *
!  * Redistribution and use in source and binary forms are permitted
!  * provided that the above copyright notice and this paragraph are
!  * duplicated in all such forms and that any documentation,
!  * advertising materials, and other materials related to such
!  * distribution and use acknowledge that the software was developed
!  * by the University of California, Berkeley.  The name of the
!  * University may not be used to endorse or promote products derived
!  * from this software without specific prior written permission.
!  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
!  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
!  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   */
  
  #if defined(LIBC_SCCS) && !defined(lint)
! static char sccsid[] = "@(#)res_send.c	6.21 (Berkeley) 6/27/88";
! #endif /* LIBC_SCCS and not lint */
  
  /*
   * Send query to name server and wait for reply.
***************
*** 38,44 ****
--- 49,66 ----
  extern int errno;
  
  static int s = -1;	/* socket used for communications */
+ static struct sockaddr no_addr;
+   
  
+ #ifndef FD_SET
+ #define	NFDBITS		32
+ #define	FD_SETSIZE	32
+ #define	FD_SET(n, p)	((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+ #define	FD_CLR(n, p)	((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+ #define	FD_ISSET(n, p)	((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+ #define FD_ZERO(p)	bzero((char *)(p), sizeof(*(p)))
+ #endif
+ 
  #define KEEPOPEN (RES_USEVC|RES_STAYOPEN)
  
  res_send(buf, buflen, answer, anslen)
***************
*** 49,55 ****
  {
  	register int n;
  	int retry, v_circuit, resplen, ns;
! 	int gotsomewhere = 0;
  	u_short id, len;
  	char *cp;
  	fd_set dsmask;
--- 71,77 ----
  {
  	register int n;
  	int retry, v_circuit, resplen, ns;
! 	int gotsomewhere = 0, connected = 0;
  	u_short id, len;
  	char *cp;
  	fd_set dsmask;
***************
*** 58,63 ****
--- 80,86 ----
  	HEADER *anhp = (HEADER *) answer;
  	struct iovec iov[2];
  	int terrno = ETIMEDOUT;
+ 	char junk[512];
  
  #ifdef DEBUG
  	if (_res.options & RES_DEBUG) {
***************
*** 79,87 ****
  #ifdef DEBUG
  		if (_res.options & RES_DEBUG)
  			printf("Querying server (# %d) address = %s\n", ns+1,
! 			      inet_ntoa(_res.nsaddr_list[ns].sin_addr.s_addr));
  #endif DEBUG
  		if (v_circuit) {
  			/*
  			 * Use virtual circuit.
  			 */
--- 102,112 ----
  #ifdef DEBUG
  		if (_res.options & RES_DEBUG)
  			printf("Querying server (# %d) address = %s\n", ns+1,
! 			      inet_ntoa(_res.nsaddr_list[ns].sin_addr));
  #endif DEBUG
  		if (v_circuit) {
+ 			int truncated = 0;
+ 
  			/*
  			 * Use virtual circuit.
  			 */
***************
*** 146,152 ****
  				continue;
  			}
  			cp = answer;
! 			resplen = len = ntohs(*(u_short *)cp);
  			while (len != 0 &&
  			   (n = read(s, (char *)cp, (int)len)) > 0) {
  				cp += n;
--- 171,185 ----
  				continue;
  			}
  			cp = answer;
! 			if ((resplen = ntohs(*(u_short *)cp)) > anslen) {
! #ifdef DEBUG
! 				if (_res.options & RES_DEBUG)
! 					fprintf(stderr, "response truncated\n");
! #endif DEBUG
! 				len = anslen;
! 				truncated = 1;
! 			} else
! 				len = resplen;
  			while (len != 0 &&
  			   (n = read(s, (char *)cp, (int)len)) > 0) {
  				cp += n;
***************
*** 162,167 ****
--- 195,216 ----
  				s = -1;
  				continue;
  			}
+ 			if (truncated) {
+ 				/*
+ 				 * Flush rest of answer
+ 				 * so connection stays in synch.
+ 				 */
+ 				anhp->tc = 1;
+ 				len = resplen - anslen;
+ 				while (len != 0) {
+ 					n = (len > sizeof(junk) ?
+ 					    sizeof(junk) : len);
+ 					if ((n = read(s, junk, n)) > 0)
+ 						len -= n;
+ 					else
+ 						break;
+ 				}
+ 			}
  		} else {
  			/*
  			 * Use datagrams.
***************
*** 169,193 ****
  			if (s < 0)
  				s = socket(AF_INET, SOCK_DGRAM, 0);
  #if	BSD >= 43
! 			if (connect(s, &_res.nsaddr_list[ns],
! 			    sizeof(struct sockaddr)) < 0 ||
! 			    send(s, buf, buflen, 0) != buflen) {
  #ifdef DEBUG
! 				if (_res.options & RES_DEBUG)
! 					perror("connect");
  #endif DEBUG
! 				continue;
! 			}
! #else BSD
! 			if (sendto(s, buf, buflen, 0, &_res.nsaddr_list[ns],
! 			    sizeof(struct sockaddr)) != buflen) {
  #ifdef DEBUG
! 				if (_res.options & RES_DEBUG)
! 					perror("sendto");
  #endif DEBUG
! 				continue;
! 			}
  #endif BSD
  			/*
  			 * Wait for reply
  			 */
--- 218,271 ----
  			if (s < 0)
  				s = socket(AF_INET, SOCK_DGRAM, 0);
  #if	BSD >= 43
! 			if (_res.nscount == 1 || retry == _res.retry) {
! 				/*
! 				 * Don't use connect if we might
! 				 * still receive a response
! 				 * from another server.
! 				 */
! 				if (connected == 0) {
! 					if (connect(s, &_res.nsaddr_list[ns],
! 					    sizeof(struct sockaddr)) < 0) {
  #ifdef DEBUG
! 						if (_res.options & RES_DEBUG)
! 							perror("connect");
  #endif DEBUG
! 						continue;
! 					}
! 					connected = 1;
! 				}
! 				if (send(s, buf, buflen, 0) != buflen) {
  #ifdef DEBUG
! 					if (_res.options & RES_DEBUG)
! 						perror("send");
  #endif DEBUG
! 					continue;
! 				}
! 			} else {
! 				/*
! 				 * Disconnect if we want to listen
! 				 * for responses from more than one server.
! 				 */
! 				if (connected) {
! 					(void) connect(s, &no_addr,
! 					    sizeof(no_addr));
! 					connected = 0;
! 				}
  #endif BSD
+ 				if (sendto(s, buf, buflen, 0,
+ 				    &_res.nsaddr_list[ns],
+ 				    sizeof(struct sockaddr)) != buflen) {
+ #ifdef DEBUG
+ 					if (_res.options & RES_DEBUG)
+ 						perror("sendto");
+ #endif DEBUG
+ 					continue;
+ 				}
+ #if	BSD >= 43
+ 			}
+ #endif
+ 
  			/*
  			 * Wait for reply
  			 */
***************
*** 269,281 ****
  		 * over the rest (i.e. it is on the local machine) and only
  		 * keep that one open.
  		 */
! 		if ((_res.options & KEEPOPEN) == KEEPOPEN && ns == 0) {
! 			return (resplen);
! 		} else {
  			(void) close(s);
  			s = -1;
- 			return (resplen);
  		}
  	   }
  	}
  	if (s >= 0) {
--- 347,357 ----
  		 * over the rest (i.e. it is on the local machine) and only
  		 * keep that one open.
  		 */
! 		if ((_res.options & KEEPOPEN) == 0 || ns != 0) {
  			(void) close(s);
  			s = -1;
  		}
+ 		return (resplen);
  	   }
  	}
  	if (s >= 0) {
***************
*** 283,289 ****
  		s = -1;
  	}
  	if (v_circuit == 0)
! 		if(gotsomewhere == 0)
  			errno = ECONNREFUSED;
  		else
  			errno = ETIMEDOUT;
--- 359,365 ----
  		s = -1;
  	}
  	if (v_circuit == 0)
! 		if (gotsomewhere == 0)
  			errno = ECONNREFUSED;
  		else
  			errno = ETIMEDOUT;




diff -r -c include.dist/netdb.h include.fix/netdb.h
*** include.dist/netdb.h	Fri Dec  9 11:27:48 1988
--- include.fix/netdb.h	Wed Nov 22 14:41:26 1989
***************
*** 2,23 ****
   * 5799-WZQ (C) COPYRIGHT = NONE
   * LICENSED MATERIALS - PROPERTY OF IBM
   */
! /* $Header:netdb.h 12.0$ */
  /* $ACIS:netdb.h 12.0$ */
! /* $Source: /ibm/acis/usr/src/include/RCS/netdb.h,v $ */
  
  #if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
! static char *rcsidnetdb = "$Header:netdb.h 12.0$";
  #endif
  
  #include <sys/nfs_defines.h>
  
  /*
!  * Copyright (c) 1980 Regents of the University of California.
!  * All rights reserved.  The Berkeley software License Agreement
!  * specifies the terms and conditions for redistribution.
   *
!  *	@(#)netdb.h	5.7 (Berkeley) 5/12/86
   */
  
  #ifdef NFS
--- 2,34 ----
   * 5799-WZQ (C) COPYRIGHT = NONE
   * LICENSED MATERIALS - PROPERTY OF IBM
   */
! /* $Header: netdb.h,v 12.2 89/11/22 14:41:24 root Locked $ */
  /* $ACIS:netdb.h 12.0$ */
! /* $Source: /fish/src/include/RCS/netdb.h,v $ */
  
  #if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
! static char *rcsidnetdb = "$Header: netdb.h,v 12.2 89/11/22 14:41:24 root Locked $";
  #endif
  
  #include <sys/nfs_defines.h>
  
  /*
!  * Copyright (c) 1980, 1983, 1988 Regents of the University of California.
!  * All rights reserved.
   *
!  * Redistribution and use in source and binary forms are permitted
!  * provided that the above copyright notice and this paragraph are
!  * duplicated in all such forms and that any documentation,
!  * advertising materials, and other materials related to such
!  * distribution and use acknowledge that the software was developed
!  * by the University of California, Berkeley.  The name of the
!  * University may not be used to endorse or promote products derived
!  * from this software without specific prior written permission.
!  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
!  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
!  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
!  *
!  *	@(#)netdb.h	5.10 (Berkeley) 6/27/88
   */
  
  #ifdef NFS
***************
*** 80,90 ****
  
  /*
   * Error return codes from gethostbyname() and gethostbyaddr()
   */
  
! extern  int h_errno;	
  
! #define	HOST_NOT_FOUND	1 /* Authoritive Answer Host not found */
  #define	TRY_AGAIN	2 /* Non-Authoritive Host not found, or SERVERFAIL */
  #define	NO_RECOVERY	3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
! #define NO_ADDRESS	4 /* Valid host name, no address, look for MX record */
--- 91,103 ----
  
  /*
   * Error return codes from gethostbyname() and gethostbyaddr()
+  * (left in extern int h_errno).
   */
  
! extern  int h_errno;
  
! #define	HOST_NOT_FOUND	1 /* Authoritative Answer Host not found */
  #define	TRY_AGAIN	2 /* Non-Authoritive Host not found, or SERVERFAIL */
  #define	NO_RECOVERY	3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
! #define	NO_DATA		4 /* Valid name, no data record of requested type */
! #define	NO_ADDRESS	NO_DATA		/* no address, look for MX record */
diff -r -c include.dist/resolv.h include.fix/resolv.h
*** include.dist/resolv.h	Fri Dec  9 11:27:57 1988
--- include.fix/resolv.h	Mon Nov 20 14:07:53 1989
***************
*** 2,22 ****
   * 5799-WZQ (C) COPYRIGHT = NONE
   * LICENSED MATERIALS - PROPERTY OF IBM
   */
! /* $Header:resolv.h 12.0$ */
  /* $ACIS:resolv.h 12.0$ */
! /* $Source: /ibm/acis/usr/src/include/RCS/resolv.h,v $ */
  
  #if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
! static char *rcsidresolv = "$Header:resolv.h 12.0$";
  #endif
  
- 
  /*
!  * Copyright (c) 1983 Regents of the University of California.
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)resolv.h	5.4 (Berkeley) 2/22/86
   */
  
  /*
--- 2,21 ----
   * 5799-WZQ (C) COPYRIGHT = NONE
   * LICENSED MATERIALS - PROPERTY OF IBM
   */
! /* $Header: resolv.h,v 12.1 89/11/20 14:07:52 root Locked $ */
  /* $ACIS:resolv.h 12.0$ */
! /* $Source: /fish/src/include/RCS/resolv.h,v $ */
  
  #if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
! static char *rcsidresolv = "$Header: resolv.h,v 12.1 89/11/20 14:07:52 root Locked $";
  #endif
  
  /*
!  * Copyright (c) 1983, 1987 Regents of the University of California.
   * All rights reserved.  The Berkeley software License Agreement
   * specifies the terms and conditions for redistribution.
   *
!  *	@(#)resolv.h	5.5 (Berkeley) 5/12/87
   */
  
  /*
***************
*** 25,31 ****
--- 24,33 ----
  
  
  #define	MAXNS		3		/* max # name servers we'll track */
+ #define	MAXDNSRCH	3		/* max # default domain levels to try */
+ #define	LOCALDOMAINPARTS 2		/* min levels in name that is "local" */
  
+ #define	RES_TIMEOUT	4		/* seconds between retries */
  
  struct state {
  	int	retrans;	 	/* retransmition time interval */
***************
*** 36,41 ****
--- 38,44 ----
  #define	nsaddr	nsaddr_list[0]		/* for backward compatibility */
  	u_short	id;			/* current packet id */
  	char	defdname[MAXDNAME];	/* default domain */
+ 	char	*dnsrch[MAXDNSRCH+1];	/* components of domain to search */
  };
  
  /*
***************
*** 50,55 ****
--- 53,61 ----
  #define RES_RECURSE	0x0040		/* recursion desired */
  #define RES_DEFNAMES	0x0080		/* use default domain name */
  #define RES_STAYOPEN	0x0100		/* Keep TCP socket open */
+ #define RES_DNSRCH	0x0200		/* search up local domain tree */
+ 
+ #define RES_DEFAULT	(RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
  
  extern struct state _res;
  extern char *p_cdname(), *p_rr(), *p_type(), *p_class();
diff -r -c include.dist/arpa/nameser.h include.fix/arpa/nameser.h
*** include.dist/arpa/nameser.h	Fri Dec  9 11:27:11 1988
--- include.fix/arpa/nameser.h	Mon Nov 20 14:08:18 1989
***************
*** 2,21 ****
   * 5799-WZQ (C) COPYRIGHT = NONE
   * LICENSED MATERIALS - PROPERTY OF IBM
   */
! /* $Header:nameser.h 12.0$ */
  /* $ACIS:nameser.h 12.0$ */
! /* $Source: /ibm/acis/usr/src/include/arpa/RCS/nameser.h,v $ */
  
  #if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
! static char *rcsidnameser = "$Header:nameser.h 12.0$";
  #endif
  
  /*
   * Copyright (c) 1983 Regents of the University of California.
!  * All rights reserved.  The Berkeley software License Agreement
!  * specifies the terms and conditions for redistribution.
   *
!  *	@(#)nameser.h	5.11 (Berkeley) 2/14/86
   */
  
  /*
--- 2,32 ----
   * 5799-WZQ (C) COPYRIGHT = NONE
   * LICENSED MATERIALS - PROPERTY OF IBM
   */
! /* $Header: nameser.h,v 12.1 89/11/20 14:08:17 root Locked $ */
  /* $ACIS:nameser.h 12.0$ */
! /* $Source: /fish/src/include/arpa/RCS/nameser.h,v $ */
  
  #if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
! static char *rcsidnameser = "$Header: nameser.h,v 12.1 89/11/20 14:08:17 root Locked $";
  #endif
  
  /*
   * Copyright (c) 1983 Regents of the University of California.
!  * All rights reserved.
   *
!  * Redistribution and use in source and binary forms are permitted
!  * provided that the above copyright notice and this paragraph are
!  * duplicated in all such forms and that any documentation,
!  * advertising materials, and other materials related to such
!  * distribution and use acknowledge that the software was developed
!  * by the University of California, Berkeley.  The name of the
!  * University may not be used to endorse or promote products derived
!  * from this software without specific prior written permission.
!  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
!  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
!  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
!  *
!  *	@(#)nameser.h	5.18 (Berkeley) 6/27/88
   */
  
  /*
***************
*** 38,54 ****
  /*
   * Currently defined opcodes
   */
! #define QUERY		0		/* standard query */
! #define IQUERY		1		/* inverse query */
! #define CQUERYM		2		/* completion query (multiple) */
! #define CQUERYU		3		/* completion query (unique) */
  	/* non standard */
! #define UPDATEA		100		/* add resource record */
! #define UPDATED		101		/* delete resource record */
! #define UPDATEM		102		/* modify resource record */
! #define ZONEINIT	103		/* initial zone transfer */
! #define ZONEREF		104		/* incremental zone referesh */
  
  /*
   * Currently defined response codes
   */
--- 49,68 ----
  /*
   * Currently defined opcodes
   */
! #define QUERY		0x0		/* standard query */
! #define IQUERY		0x1		/* inverse query */
! #define STATUS		0x2		/* nameserver status query */
! /*#define xxx		0x3		/* 0x3 reserved */
  	/* non standard */
! #define UPDATEA		0x9		/* add resource record */
! #define UPDATED		0xa		/* delete a specific resource record */
! #define UPDATEDA	0xb		/* delete all nemed resource record */
! #define UPDATEM		0xc		/* modify a specific resource record */
! #define UPDATEMA	0xd		/* modify all named resource record */
  
+ #define ZONEINIT	0xe		/* initial zone transfer */
+ #define ZONEREF		0xf		/* incremental zone referesh */
+ 
  /*
   * Currently defined response codes
   */
***************
*** 59,65 ****
  #define NOTIMP		4		/* not implemented */
  #define REFUSED		5		/* query refused */
  	/* non standard */
! #define NOCHANGE	100		/* update failed to change db */
  
  /*
   * Type values for resources and queries
--- 73,79 ----
  #define NOTIMP		4		/* not implemented */
  #define REFUSED		5		/* query refused */
  	/* non standard */
! #define NOCHANGE	0xf		/* update failed to change db */
  
  /*
   * Type values for resources and queries
***************
*** 83,88 ****
--- 97,103 ----
  #define T_UINFO		100		/* user (finger) information */
  #define T_UID		101		/* user ID */
  #define T_GID		102		/* group ID */
+ #define T_UNSPEC	103		/* Unspecified format (binary data) */
  	/* Query type values which do not appear in resource records */
  #define T_AXFR		252		/* transfer zone of authority */
  #define T_MAILB		253		/* transfer mailbox records */
***************
*** 99,104 ****
--- 114,128 ----
  #define C_ANY		255		/* wildcard match */
  
  /*
+  * Status return codes for T_UNSPEC conversion routines
+  */
+ #define CONV_SUCCESS 0
+ #define CONV_OVERFLOW -1
+ #define CONV_BADFMT -2
+ #define CONV_BADCKSUM -3
+ #define CONV_BADBUFLEN -4
+ 
+ /*
   * Structure for query header, the order of the fields is machine and
   * compiler dependent, in our case, the bits within a byte are assignd 
   * least significant first, while the order of transmition is most 
***************
*** 108,115 ****
  typedef struct {
  	u_short	id;		/* query identification number */
  #if defined (sun) || defined (sel) || defined (pyr) || defined (is68k) \
! || defined (tahoe) || defined (ibm032) || defined (ibm370) \
! || defined (BIT_ZERO_ON_LEFT)
  	/* Bit zero on left:  Gould and similar architectures */
  			/* fields in third byte */
  	u_char	qr:1;		/* response flag */
--- 132,138 ----
  typedef struct {
  	u_short	id;		/* query identification number */
  #if defined (sun) || defined (sel) || defined (pyr) || defined (is68k) \
! || defined (tahoe)  || defined (ibm032) || defined (BIT_ZERO_ON_LEFT)
  	/* Bit zero on left:  Gould and similar architectures */
  			/* fields in third byte */
  	u_char	qr:1;		/* response flag */
***************
*** 123,129 ****
  	u_char	unused:2;	/* unused bits */
  	u_char	rcode:4;	/* response code */
  #else
! #if defined (vax) || defined (BIT_ZERO_ON_RIGHT)
  	/* Bit zero on right:  VAX */
  			/* fields in third byte */
  	u_char	rd:1;		/* recursion desired */
--- 146,152 ----
  	u_char	unused:2;	/* unused bits */
  	u_char	rcode:4;	/* response code */
  #else
! #if defined (vax) || defined(ns32000) || defined (BIT_ZERO_ON_RIGHT)
  	/* Bit zero on right:  VAX */
  			/* fields in third byte */
  	u_char	rd:1;		/* recursion desired */
***************
*** 165,169 ****
  	char	*r_data;		/* pointer to data */
  };
  
! extern	u_short	getshort();
! extern	u_long	getlong();
--- 188,227 ----
  	char	*r_data;		/* pointer to data */
  };
  
! extern	u_short	_getshort();
! extern	u_long	_getlong();
! 
! /*
!  * Inline versions of get/put short/long.
!  * Pointer is advanced; we assume that both arguments
!  * are lvalues and will already be in registers.
!  * cp MUST be u_char *.
!  */
! #define GETSHORT(s, cp) { \
! 	(s) = *(cp)++ << 8; \
! 	(s) |= *(cp)++; \
! }
! 
! #define GETLONG(l, cp) { \
! 	(l) = *(cp)++ << 8; \
! 	(l) |= *(cp)++; (l) <<= 8; \
! 	(l) |= *(cp)++; (l) <<= 8; \
! 	(l) |= *(cp)++; \
! }
! 
! 
! #define PUTSHORT(s, cp) { \
! 	*(cp)++ = (s) >> 8; \
! 	*(cp)++ = (s); \
! }
! 
! /*
!  * Warning: PUTLONG destroys its first argument.
!  */
! #define PUTLONG(l, cp) { \
! 	(cp)[3] = l; \
! 	(cp)[2] = (l >>= 8); \
! 	(cp)[1] = (l >>= 8); \
! 	(cp)[0] = l >> 8; \
! 	(cp) += sizeof(u_long); \
! }

Eric Brunner, Consultant, IBM AWD Palo Alto	(415) 855-4486
inet: brunner@monet.berkeley.edu
uucp: uunet!ibmsupt!brunner