*** 8.27	1996/01/09 20:23:45
--- CHANGES	1996/03/03 01:47:28
***************
*** 1,4 ****
--- 1,42 ----
  $Id: CHANGES,v 8.27 1996/01/09 20:23:45 vixie Exp vixie $
  
+ 	--- 4.9.3-p2 released ---
+ 
+ 593. [security]	db_load() will allow invalid SOA ANAMEs, for now.
+ 
+ 592. [bug]	dig and nslookup needed code from 4.9.4-T1A for AXFR (#589).
+ 
+ 591. [bug]	dig and nslookup both dumped core if dn_expand() failed.
+ 
+ 590. [port]	changed __RES to 19960229 due to dn_isvalid() API addition.
+ 
+ 589. [bug]	named-xfer was unable to handle some compliant AXFR streams.
+ 
+ 588. [security]	call dn_isvalid() from db_load() to catch zone naming errors.
+ 
+ 587. [security]	added function dn_isvalid(), called from dn_expand(), per CERT.
+ 
+ 586. [bug]	dangling NS RR's (no A RR's in cache) weren't recoverable.
+ 
+ 585. [bug]	named was ignoring the cache for "." even after priming.
+ 
+ 584. [bug]	ns_resp() could dump core during some kinds of query restarts.
+ 
+ 583. [bug]	default logging priority for lame delegations now LOG_DEBUG.
+ 
+ 582. [doc]	removed RFC 1537, replaced with RFC 1912 which obsoletes it.
+ 
+ 581. [port]	BSD really does not have SIGIOT any more, stop using it.
+ 
+ 580. [bug]	getnetent() could mangle /etc/networks input lines.
+ 
+ 579. [bug]	db_dump was printing -1 for TTL wherever default TTL was used.
+ 
+ 578. [port]	many scanf/printf patterns misused %lu, DEC AXP didn't like it.
+ 
+ 577. [bug]	named-xfer and res_debug were mishandling "\\" in TXT/HINFO.
+ 
+ 576. [bug]	"limit" directive was setting current but not max system limit.
+ 
  	--- 4.9.3-p1 released ---
  
*** 8.28	1996/01/09 20:23:45
--- Makefile	1996/03/01 08:21:04
***************
*** 57,61 ****
  ## --Copyright--
  
! VER = 4.9.3-P1
  SHELL = /bin/sh
  MAKE = make
--- 57,61 ----
  ## --Copyright--
  
! VER = 4.9.3-P2
  SHELL = /bin/sh
  MAKE = make
*** 8.3	1995/12/31 23:28:00
--- BSD/Makefile.inc	1996/03/01 08:20:20
***************
*** 14,18 ****
  PS=		ps
  DESTSBIN=	/usr/sbin
! IOT=		IOT
  
  CONFIG?=	-DUSE_OPTIONS_H
--- 14,18 ----
  PS=		ps
  DESTSBIN=	/usr/sbin
! IOT=		ABRT
  
  CONFIG?=	-DUSE_OPTIONS_H
*** 8.7	1995/12/29 21:08:13
--- conf/options.h	1996/03/01 08:28:53
***************
*** 110,114 ****
  #define DATUMREFCNT	/* use reference counts on datums (mpa) */
  #define LAME_DELEGATION	/* lame delegations (original-del,reworked-bb&del)*/
! #define LAME_LOGGING LOG_WARNING /* log lame delegations, set log level */
  #define GETSER_LOGGING LOG_INFO /* log errors/timeouts getting serial number */
  /*#define RETURNSOA	/* good code that the world isn't ready for yet */
--- 110,114 ----
  #define DATUMREFCNT	/* use reference counts on datums (mpa) */
  #define LAME_DELEGATION	/* lame delegations (original-del,reworked-bb&del)*/
! #define LAME_LOGGING LOG_DEBUG /* log lame delegations, set log level */
  #define GETSER_LOGGING LOG_INFO /* log errors/timeouts getting serial number */
  /*#define RETURNSOA	/* good code that the world isn't ready for yet */
*** 8.5	1995/12/22 10:20:27
--- include/resolv.h	1996/03/02 08:09:53
***************
*** 79,83 ****
   */
  
! #define	__RES	19951031
  
  /*
--- 79,83 ----
   */
  
! #define	__RES	19960229
  
  /*
***************
*** 185,188 ****
--- 185,189 ----
  
  /* Private routines shared between libc/net, named, nslookup and others. */
+ #define	dn_isvalid	__dn_isvalid
  #define	dn_skipname	__dn_skipname
  #define	fp_query	__fp_query
***************
*** 204,207 ****
--- 205,209 ----
  #define	res_queriesmatch __res_queriesmatch
  __BEGIN_DECLS
+ int	 __dn_isvalid __P((const char *));
  int	 __dn_skipname __P((const u_char *, const u_char *));
  void	 __fp_resstat __P((struct __res_state *, FILE *));
*** 8.8	1995/12/06 20:34:38
--- named/db_dump.c	1996/03/01 08:01:50
***************
*** 315,325 ****
  			zp->z_type, zp->z_class,
  			zp->z_source ? zp->z_source : "Nil");
! 		fprintf(fp, ";\ttime=%ld, lastupdate=%ld, serial=%u,\n",
! 			zp->z_time, zp->z_lastupdate, zp->z_serial);
  		fprintf(fp, ";\trefresh=%u, retry=%u, expire=%u, minimum=%u\n",
  			zp->z_refresh, zp->z_retry,
  			zp->z_expire, zp->z_minimum);
! 		fprintf(fp, ";\tftime=%ld, xaddr=[%s], state=%04x, pid=%d\n",
! 			zp->z_ftime, inet_ntoa(zp->z_xaddr),
  			zp->z_flags, (int)zp->z_xferpid);
  		sprintf(buf, ";\tz_addr[%d]: ", zp->z_addrcnt);
--- 315,326 ----
  			zp->z_type, zp->z_class,
  			zp->z_source ? zp->z_source : "Nil");
! 		fprintf(fp, ";\ttime=%lu, lastupdate=%lu, serial=%u,\n",
! 			(u_long)zp->z_time, (u_long)zp->z_lastupdate,
! 			zp->z_serial);
  		fprintf(fp, ";\trefresh=%u, retry=%u, expire=%u, minimum=%u\n",
  			zp->z_refresh, zp->z_retry,
  			zp->z_expire, zp->z_minimum);
! 		fprintf(fp, ";\tftime=%lu, xaddr=[%s], state=%04x, pid=%d\n",
! 			(u_long)zp->z_ftime, inet_ntoa(zp->z_xaddr),
  			zp->z_flags, (int)zp->z_xferpid);
  		sprintf(buf, ";\tz_addr[%d]: ", zp->z_addrcnt);
***************
*** 420,424 ****
  				    fprintf(fp, "%d\t",
  				        (int)(dp->d_ttl - tt.tv_sec));
! 			} else if (dp->d_ttl != 0 &&
  			    dp->d_ttl != zones[dp->d_zone].z_minimum)
  				fprintf(fp, "%d\t", (int)dp->d_ttl);
--- 421,425 ----
  				    fprintf(fp, "%d\t",
  				        (int)(dp->d_ttl - tt.tv_sec));
! 			} else if (dp->d_ttl != USE_MINIMUM &&
  			    dp->d_ttl != zones[dp->d_zone].z_minimum)
  				fprintf(fp, "%d\t", (int)dp->d_ttl);
***************
*** 810,814 ****
  
  	/* Get byte count and checksum information from end of buffer */
! 	if(sscanf(inp, "%ld %lx %lx %lx", numbytes, &oeor, &osum, &orot) != 4)
  		return(CONV_BADFMT);
  	if ((oeor != Ceor) || (osum != Csum) || (orot != Crot))
--- 811,815 ----
  
  	/* Get byte count and checksum information from end of buffer */
! 	if (sscanf(inp, "%d %lx %lx %lx", numbytes, &oeor, &osum, &orot) != 4)
  		return(CONV_BADFMT);
  	if ((oeor != Ceor) || (osum != Csum) || (orot != Crot))
***************
*** 900,904 ****
  	/* Put byte count and checksum information at end of buffer, delimited
  	   by 'x' */
! 	(void) sprintf(outp, "x %ld %lx %lx %lx", inbuflen, Ceor, Csum, Crot);
  	if (&outp[strlen(outp) - 1] >= endoutp)
  		return(CONV_OVERFLOW);
--- 901,905 ----
  	/* Put byte count and checksum information at end of buffer, delimited
  	   by 'x' */
! 	(void) sprintf(outp, "x %d %lx %lx %lx", inbuflen, Ceor, Csum, Crot);
  	if (&outp[strlen(outp) - 1] >= endoutp)
  		return(CONV_OVERFLOW);
*** 8.15	1995/12/31 23:28:17
--- named/db_load.c	1996/03/03 02:23:34
***************
*** 81,85 ****
  			getprotocol __P((FILE *, const char *)),
  			getservices __P((int, char *, FILE *, const char *));
! static void		makename __P((char *, const char *));
  static int		empty_token = 0;
  int	getnum_error;
--- 81,85 ----
  			getprotocol __P((FILE *, const char *)),
  			getservices __P((int, char *, FILE *, const char *));
! static int		makename __P((char *, const char *));
  static int		empty_token = 0;
  int	getnum_error;
***************
*** 247,251 ****
  				strcpy(tmporigin, origin);
  			else {
! 				makename(tmporigin, origin);
  				endline(fp);
  			}
--- 247,251 ----
  				strcpy(tmporigin, origin);
  			else {
! 				errs += makename(tmporigin, origin);
  				endline(fp);
  			}
***************
*** 260,264 ****
  			dprintf(3, (ddt, "db_load: origin %s, buf %s\n",
  				    origin, buf));
! 			makename(origin, buf);
  			dprintf(3, (ddt, "db_load: origin now %s\n", origin));
  			continue;
--- 260,264 ----
  			dprintf(3, (ddt, "db_load: origin %s, buf %s\n",
  				    origin, buf));
! 			errs += makename(origin, buf);
  			dprintf(3, (ddt, "db_load: origin now %s\n", origin));
  			continue;
***************
*** 285,288 ****
--- 285,292 ----
  		case CURRENT:
  		gotdomain:
+ 			if (!dn_isvalid(domain)) {
+ 				strcpy(buf, domain);
+ 				goto err;
+ 			}
  			if (!getword((char *)buf, sizeof(buf), fp, 0)) {
  				if (c == CURRENT)
***************
*** 432,436 ****
  			case T_RP:
  				(void) strcpy((char *)data, (char *)buf);
! 				makename(data, origin);
  				cp = data + strlen((char *)data) + 1;
  				if (!getword((char *)cp,
--- 436,441 ----
  			case T_RP:
  				(void) strcpy((char *)data, (char *)buf);
! 				if (makename(data, origin) != 0)
! 					goto err;
  				cp = data + strlen((char *)data) + 1;
  				if (!getword((char *)cp,
***************
*** 438,442 ****
  					     fp, 1))
  					goto err;
! 				makename(cp, origin);
  				cp += strlen((char *)cp) + 1;
  				if (type != T_SOA) {
--- 443,457 ----
  					     fp, 1))
  					goto err;
! 				if (makename(cp, origin) != 0) {
! 					if (type == T_SOA) {
! 						syslog(LOG_INFO, "%s:%d: %s",
! 						       filename, lineno,
! 					        "SOA ANAME not valid (warning)"
! 						       );
! 					} else {
! 						strcpy(buf, cp);
! 						goto err;
! 					}
! 				}
  				cp += strlen((char *)cp) + 1;
  				if (type != T_SOA) {
***************
*** 479,483 ****
  			"%s:%d: WARNING: new serial number < old (%lu < %lu)",
  						filename , lineno,
! 						zp->z_serial, serial);
  				}
  #endif
--- 494,499 ----
  			"%s:%d: WARNING: new serial number < old (%lu < %lu)",
  						filename , lineno,
! 						(u_long)zp->z_serial,
! 						(u_long)serial);
  				}
  #endif
***************
*** 531,535 ****
  				    syslog(LOG_WARNING,
      "%s: WARNING SOA expire value is less then SOA refresh (%lu < %lu)",
! 				    filename, zp->z_expire, zp->z_refresh);
  				}
  				endline(fp);
--- 547,552 ----
  				    syslog(LOG_WARNING,
      "%s: WARNING SOA expire value is less then SOA refresh (%lu < %lu)",
! 				    filename, (u_long)zp->z_expire,
! 				    (u_long)zp->z_refresh);
  				}
  				endline(fp);
***************
*** 573,577 ****
  			case T_PTR:
  				(void) strcpy((char *)data, (char *)buf);
! 				makename(data, origin);
  				n = strlen((char *)data) + 1;
  				break;
--- 590,595 ----
  			case T_PTR:
  				(void) strcpy((char *)data, (char *)buf);
! 				if (makename(data, origin) != 0)
! 					goto err;
  				n = strlen((char *)data) + 1;
  				break;
***************
*** 614,618 ****
  					goto err;
  				(void) strcpy((char *)cp, (char *)buf);
! 				makename(cp, origin);
  				/* advance pointer to end of data */
  				cp += strlen((char *)cp) +1;
--- 632,637 ----
  					goto err;
  				(void) strcpy((char *)cp, (char *)buf);
! 				if (makename(cp, origin) != 0)
! 					goto err;
  				/* advance pointer to end of data */
  				cp += strlen((char *)cp) +1;
***************
*** 637,641 ****
  					goto err;
  				(void) strcpy((char *)cp, (char *)buf);
! 				makename(cp, origin);
  				/* advance pointer to next field */
  				cp += strlen((char *)cp) +1;
--- 656,661 ----
  					goto err;
  				(void) strcpy((char *)cp, (char *)buf);
! 				if (makename(cp, origin) != 0)
! 					goto err;
  				/* advance pointer to next field */
  				cp += strlen((char *)cp) +1;
***************
*** 643,647 ****
  					goto err;
  				(void) strcpy((char *)cp, (char *)buf);
! 				makename(cp, origin);
  				/* advance pointer to end of data */
  				cp += strlen((char *)cp) + 1;
--- 663,668 ----
  					goto err;
  				(void) strcpy((char *)cp, (char *)buf);
! 				if (makename(cp, origin) != 0)
! 					goto err;
  				/* advance pointer to end of data */
  				cp += strlen((char *)cp) + 1;
***************
*** 1152,1156 ****
   * "name" means append origin.
   */
! static void
  makename(name, origin)
  	char *name;
--- 1173,1177 ----
   * "name" means append origin.
   */
! static int
  makename(name, origin)
  	char *name;
***************
*** 1165,1173 ****
  		if (name[0] == '.') {
  			name[0] = '\0';
! 			return;
  		}
  		if (name[0] == '@') {
  			(void) strcpy(name, origin);
! 			return;
  		}
  	}
--- 1186,1194 ----
  		if (name[0] == '.') {
  			name[0] = '\0';
! 			goto done;
  		}
  		if (name[0] == '@') {
  			(void) strcpy(name, origin);
! 			goto done;
  		}
  	}
***************
*** 1180,1183 ****
--- 1201,1206 ----
  		}
  	}
+  done:
+ 	return (!dn_isvalid(name));	/* number of errors */
  }
  
*** 8.10	1995/12/06 20:34:38
--- named/named-xfer.c	1996/03/02 09:05:36
***************
*** 888,896 ****
  			} else {
  #endif /*STUBS*/
! 				n = print_output(buf, bufsize, cp);
! 				if (cp + n != eom) {
  					syslog(LOG_INFO,
  				"print_output: short answer (%d, %d), zone %s",
! 					       cp - buf, n, zp->z_origin);
  					error++;
  					break;
--- 888,901 ----
  			} else {
  #endif /*STUBS*/
! 				ancount = ntohs(hp->ancount);
! 				for (cnt = 0; cnt < ancount; cnt++) {
! 					n = print_output(buf, bufsize, cp);
! 					cp += n;
! 				}
! 				if (cp != eom) {
  					syslog(LOG_INFO,
  				"print_output: short answer (%d, %d), zone %s",
! 					       cp - buf, eom - buf,
! 					       zp->z_origin);
  					error++;
  					break;
***************
*** 1474,1480 ****
  					break;
  				}
! 				if ((*cp == '\n') || (*cp == '"')) {
  					(void) putc('\\', dbfp);
- 				}
  				(void) putc(*cp++, dbfp);
  				j++;
--- 1479,1484 ----
  					break;
  				}
! 				if (strchr("\n\"\\", *cp))
  					(void) putc('\\', dbfp);
  				(void) putc(*cp++, dbfp);
  				j++;
***************
*** 1526,1533 ****
  		while (cp < cp1) {
  			if (i = *cp++) {
! 				for (j = i ; j > 0 && cp < cp1 ; j--) {
! 					if ((*cp == '\n') || (*cp == '"')) {
  						(void) putc('\\', dbfp);
- 					}
  					(void) putc(*cp++, dbfp);
  				}
--- 1530,1536 ----
  		while (cp < cp1) {
  			if (i = *cp++) {
! 				for (j = i; j > 0 && cp < cp1; j--) {
! 					if (strchr("\n\"\\", *cp))
  						(void) putc('\\', dbfp);
  					(void) putc(*cp++, dbfp);
  				}
*** 8.9	1995/12/22 10:20:30
--- named/ns_forw.c	1996/03/01 08:36:54
***************
*** 358,361 ****
--- 358,362 ----
  	int oldn, naddr, class, found_arr;
  	time_t curtime;
+ 	int pass;
  
  	dprintf(3, (ddt, "nslookup(nsp=0x%lx, qp=0x%lx, \"%s\")\n",
***************
*** 381,385 ****
  		}
  
! 		tmphtp = ((nsdp->d_flags & DB_F_HINT) ?fcachetab :hashtab);
  		np = nlookup(dname, &tmphtp, &fname, 1);
  		if (np == NULL || fname != dname) {
--- 382,388 ----
  		}
  
! 		tmphtp = hashtab;
! 		pass = 1;
! again:
  		np = nlookup(dname, &tmphtp, &fname, 1);
  		if (np == NULL || fname != dname) {
***************
*** 539,542 ****
--- 542,550 ----
  			NULL;
  		}
+ 		if ((found_arr == 0) && (pass == 1)) {
+ 			tmphtp = fcachetab;
+ 			pass++;
+ 			goto again;
+ 		}
  		dprintf(8, (ddt, "nslookup: %d ns addrs\n", n));
   need_sysquery:
*** 8.12	1995/12/29 07:16:18
--- named/ns_init.c	1996/02/19 21:21:59
***************
*** 927,931 ****
  		return;
  	}
! 	limits.rlim_cur = value;
  	if (setrlimit(rlimit, &limits) < 0) {
  		syslog(LOG_WARNING, "setrlimit(%s, %ld): %m", name, value);
--- 927,931 ----
  		return;
  	}
! 	limits.rlim_cur = limits.rlim_max = value;
  	if (setrlimit(rlimit, &limits) < 0) {
  		syslog(LOG_WARNING, "setrlimit(%s, %ld): %m", name, value);
*** 8.13	1996/01/09 20:23:55
--- named/ns_main.c	1996/03/01 07:58:04
***************
*** 1049,1053 ****
  				netloop.addr = ntp->my_addr.s_addr;
  				dprintf(1, (ddt, "loopback address: x%lx\n",
! 					    netloop.my_addr.s_addr));
  			}
  			continue;
--- 1049,1053 ----
  				netloop.addr = ntp->my_addr.s_addr;
  				dprintf(1, (ddt, "loopback address: x%lx\n",
! 					    (u_long)netloop.my_addr.s_addr));
  			}
  			continue;
*** 8.11	1995/12/22 10:20:30
--- named/ns_maint.c	1996/03/01 07:58:44
***************
*** 332,338 ****
  			syslog(LOG_NOTICE,
     "Zone \"%s\" (class %d) SOA serial# (%lu) rcvd from [%s] is < ours (%lu)\n",
! 			       zp->z_origin, zp->z_class, serial,
  			       inet_ntoa(from_addr.sin_addr),
! 			       zp->z_serial);
  		}
  	} else {
--- 332,338 ----
  			syslog(LOG_NOTICE,
     "Zone \"%s\" (class %d) SOA serial# (%lu) rcvd from [%s] is < ours (%lu)\n",
! 			       zp->z_origin, zp->z_class, (u_long)serial,
  			       inet_ntoa(from_addr.sin_addr),
! 			       (u_long)zp->z_serial);
  		}
  	} else {
***************
*** 573,577 ****
  		fprintf(ddt, ", now time : %lu sec", (u_long)tt.tv_sec);
  		fprintf(ddt, ", time left: %lu sec",
! 			(long)(zp->z_time - tt.tv_sec));
  	}
  	fprintf(ddt, "; flags %lx\n", (u_long)zp->z_flags);
--- 573,577 ----
  		fprintf(ddt, ", now time : %lu sec", (u_long)tt.tv_sec);
  		fprintf(ddt, ", time left: %lu sec",
! 			(u_long)(zp->z_time - tt.tv_sec));
  	}
  	fprintf(ddt, "; flags %lx\n", (u_long)zp->z_flags);
*** 8.15	1995/12/29 07:16:18
--- named/ns_req.c	1996/03/02 08:08:41
***************
*** 1231,1235 ****
  	dprintf(5, (ddt, "make_rr(%s, %lx, %lx, %d, %d) %d zone %d ttl %lu\n",
  		    name, (u_long)dp, (u_long)buf,
! 		    buflen, doadd, dp->d_size, dp->d_zone, dp->d_ttl));
  
  #ifdef	NCACHE
--- 1231,1235 ----
  	dprintf(5, (ddt, "make_rr(%s, %lx, %lx, %d, %d) %d zone %d ttl %lu\n",
  		    name, (u_long)dp, (u_long)buf,
! 		    buflen, doadd, dp->d_size, dp->d_zone, (u_long)dp->d_ttl));
  
  #ifdef	NCACHE
***************
*** 1547,1551 ****
  			if (!haveComplained((char*)nhash(ap->a_dname),
  					    (char*)nhash(ap->a_rname))) {
! 				syslog(LOG_INFO,
  				       "\"%s %s %s\" points to a CNAME (%s)",
  				       ap->a_rname, p_class(ap->a_class),
--- 1547,1551 ----
  			if (!haveComplained((char*)nhash(ap->a_dname),
  					    (char*)nhash(ap->a_rname))) {
! 				syslog(LOG_DEBUG,
  				       "\"%s %s %s\" points to a CNAME (%s)",
  				       ap->a_rname, p_class(ap->a_class),
***************
*** 2010,2015 ****
  		(u_long)cp, cp);
  	cp += strlen(cp) + 1; /* skip in-charge string */
! 	fprintf(ddt, "printSOAdata: serial(%lx)=%d\n",
! 		cp, (u_long)_getlong(cp));
  }
  #endif
--- 2010,2015 ----
  		(u_long)cp, cp);
  	cp += strlen(cp) + 1; /* skip in-charge string */
! 	fprintf(ddt, "printSOAdata: serial(%lx)=%lu\n",
! 		(u_long)cp, (u_long)_getlong(cp));
  }
  #endif
***************
*** 2055,2059 ****
  		/* parent */
  		syslog(LOG_DEBUG, "zone transfer of \"%s\" to %s (pid %lu)",
! 		       dname, sin_ntoa(&qsp->s_from), pid);
  		return;
  	}
--- 2055,2059 ----
  		/* parent */
  		syslog(LOG_DEBUG, "zone transfer of \"%s\" to %s (pid %lu)",
! 		       dname, sin_ntoa(&qsp->s_from), (u_long)pid);
  		return;
  	}
*** 8.19	1996/01/09 20:23:55
--- named/ns_resp.c	1996/03/01 08:44:51
***************
*** 1237,1241 ****
   servfail:
  	nameserIncr(qp->q_from.sin_addr, nssSentFail);
! 	hp = (HEADER *)(cname ? qp->q_cmsg : qp->q_msg);
  	hp->rcode = SERVFAIL;
  	hp->qr = 1;
--- 1237,1241 ----
   servfail:
  	nameserIncr(qp->q_from.sin_addr, nssSentFail);
! 	hp = (HEADER *)(qp->q_cmsglen ? qp->q_cmsg : qp->q_msg);
  	hp->rcode = SERVFAIL;
  	hp->qr = 1;
***************
*** 1243,1247 ****
  	hp->rd = 1;
  	hp->ra = (NoRecurse == 0);
! 	(void) send_msg((u_char *)hp, (cname ? qp->q_cmsglen : qp->q_msglen),
  			qp);
  	qremove(qp);
--- 1243,1247 ----
  	hp->rd = 1;
  	hp->ra = (NoRecurse == 0);
! 	(void) send_msg((u_char *)hp, (qp->q_cmsglen ? qp->q_cmsglen : qp->q_msglen),
  			qp);
  	qremove(qp);
***************
*** 1890,1893 ****
--- 1890,1894 ----
  	struct namebuf *np;
  	struct databuf *nsp[NSMAX];
+ 	struct databuf *dp;
  	struct hashbuf *htp;
  	struct sockaddr_in *nsa;
***************
*** 1997,2011 ****
  		qp->q_naddr = nsc;
  	} else {
  		count = nslookup(nsp, qp, dname, "sysquery");
  		if (count <= 0) {
! 			if (count < 0)
  				syslog(LOG_INFO,
  				      "sysquery: nslookup reports danger (%s)",
  				       dname);
! 			else
! 				/* "." domain gets LOG_WARNING here. */
! 				syslog(dname[0] ? LOG_INFO : LOG_WARNING,
! 				       "sysquery: no addrs found for NS (%s)",
  				       dname);
  			goto err2;
  		}
--- 1998,2040 ----
  		qp->q_naddr = nsc;
  	} else {
+  fetch_a:
  		count = nslookup(nsp, qp, dname, "sysquery");
  		if (count <= 0) {
! 			if (count < 0) {
  				syslog(LOG_INFO,
  				      "sysquery: nslookup reports danger (%s)",
  				       dname);
! 				goto err2;
! 			} else if (np && np->n_dname[0] == '\0') {
! 				syslog(LOG_WARNING,
! 				   "sysquery: no addrs found for root NS (%s)",
  				       dname);
+ 				goto err2;
+ 			}
+ 			if (np) {
+ 				for (dp = np->n_data; dp ; dp = dp->d_next)
+ 					if (dp->d_zone &&
+ 					    match(dp, class, T_NS)) {
+ 						syslog(LOG_INFO,
+ 					"sysquery: no addrs found for NS (%s)",
+ 						       dname);
+ 						goto err2;
+ 					}
+ #ifdef DATUMREFCNT
+ 				free_nsp(nsp);
+ 				nsp[0] = NULL;
+ #endif
+ 				np = np->n_parent;
+ 				n = findns(&np, class, nsp, &count, 0);
+ 				switch (n) {
+ 				case NXDOMAIN: /*FALLTHROUGH*/
+ 				case SERVFAIL:
+ 					syslog(LOG_DEBUG,
+ 					  "sysquery: findns error (%d) on %s?",
+ 					       n, dname);
+ 					goto err2;
+ 				}
+ 				goto fetch_a;
+ 			}
  			goto err2;
  		}
***************
*** 2021,2025 ****
  		    sin_ntoa(nsa), qp->q_dfd, 
  		    ntohs(qp->q_nsid), ntohs(qp->q_id),
! 		    qp->q_time));
  #ifdef DEBUG
  	if (debug >= 10)
--- 2050,2054 ----
  		    sin_ntoa(nsa), qp->q_dfd, 
  		    ntohs(qp->q_nsid), ntohs(qp->q_id),
! 		    (long)qp->q_time));
  #ifdef DEBUG
  	if (debug >= 10)
***************
*** 2190,2196 ****
  			    htp == hashtab ? "cache" : "hints"));
  		for (np = htp->h_tab[0]; np != NULL; np = np->n_next)
! 			if (np->n_dname[0] == '\0')
  				break;
! 		htp = (htp == hashtab ? fcachetab : NULL);	/* Fallback */
  	}
  	while (np != NULL) {
--- 2219,2241 ----
  			    htp == hashtab ? "cache" : "hints"));
  		for (np = htp->h_tab[0]; np != NULL; np = np->n_next)
! 			if (np->n_dname[0] == '\0') {
! 			    /*
! 			     * do we have a root NS for this class?
! 			     */
! 			    for (dp = np->n_data; dp != NULL;
! 						dp = dp->d_next) {
! 				    if (!match(dp, class, T_NS))
! 					continue;
! #ifdef NCACHE
! 				    if (dp->d_rcode)
! 					continue;
! #endif
! 				    break;
! 			    }
! 			    if (dp)
  				break;
! 			}
! 		if (!np)	/* Fallback */
! 			htp = (htp == hashtab ? fcachetab : NULL);
  	}
  	while (np != NULL) {
*** 8.4	1995/06/29 09:26:17
--- named/ns_stats.c	1996/03/01 08:00:16
***************
*** 358,366 ****
  		tv_float(usage.ru_utime), tv_float(usage.ru_stime),
  		tv_float(childu.ru_utime), tv_float(childu.ru_stime));
! 	syslog(LOG_INFO, "USAGE %lu %lu %s", timenow, boottime, buffer);
  # undef tv_float
  #endif
  
! 	sprintf(header, "NSTATS %lu %lu", timenow, boottime);
  	strcpy(buffer, header);
  
--- 358,367 ----
  		tv_float(usage.ru_utime), tv_float(usage.ru_stime),
  		tv_float(childu.ru_utime), tv_float(childu.ru_stime));
! 	syslog(LOG_INFO, "USAGE %lu %lu %s", (u_long)timenow, (u_long)boottime,
! 		buffer);
  # undef tv_float
  #endif
  
! 	sprintf(header, "NSTATS %lu %lu", (u_long)timenow, (u_long)boottime);
  	strcpy(buffer, header);
  
*** 8.1	1994/12/15 06:24:24
--- res/getnetent.c	1996/03/01 08:04:37
***************
*** 144,159 ****
  	net.n_addrtype = AF_INET;
  	q = net.n_aliases = net_aliases;
! 	if (p != NULL) 
  		cp = p;
! 	while (cp && *cp) {
! 		if (*cp == ' ' || *cp == '\t') {
! 			cp++;
! 			continue;
  		}
- 		if (q < &net_aliases[MAXALIASES - 1])
- 			*q++ = cp;
- 		cp = strpbrk(cp, " \t");
- 		if (cp != NULL)
- 			*cp++ = '\0';
  	}
  	*q = NULL;
--- 144,160 ----
  	net.n_addrtype = AF_INET;
  	q = net.n_aliases = net_aliases;
! 	if (p != NULL) {
  		cp = p;
! 		while (cp && *cp) {
! 			if (*cp == ' ' || *cp == '\t') {
! 				cp++;
! 				continue;
! 			}
! 			if (q < &net_aliases[MAXALIASES - 1])
! 				*q++ = cp;
! 			cp = strpbrk(cp, " \t");
! 			if (cp != NULL)
! 				*cp++ = '\0';
  		}
  	}
  	*q = NULL;
*** 8.3	1995/12/06 20:34:50
--- res/res_comp.c	1996/03/02 07:46:50
***************
*** 149,155 ****
  	}
  	*dn = '\0';
! 	for (dn = exp_dn; (c = *dn) != '\0'; dn++)
! 		if (isascii(c) && isspace(c))
! 			return (-1);
  	if (len < 0)
  		len = cp - comp_dn;
--- 149,154 ----
  	}
  	*dn = '\0';
! 	if (!dn_isvalid(exp_dn))
! 		return (-1);
  	if (len < 0)
  		len = cp - comp_dn;
***************
*** 341,344 ****
--- 340,406 ----
  
  /*
+  * Verify that a domain name uses an acceptable character set.
+  */
+ 
+ /****
+ To: "Lawrence R. Rogers" <lrr@cert.org>
+ cc: cert@cert.org, pvm@home.net
+ Subject: Re: VU#14542 
+ In-reply-to: Your message of "Mon, 19 Feb 1996 17:16:27 PST."
+ Date: Tue, 20 Feb 1996 22:37:21 -0800
+ From: Paul A Vixie <vixie@wisdom.home.vix.com>
+ 
+ in retrospect,
+ 
+ 	hostname = firstlabel ( "." otherlabel )+
+ 	firstchar = [a-zA-Z0-9_]
+ 	otherchar = [a-zA-Z0-9_-/]
+ 	firstlabel = firstchar otherchar*
+ 	otherlabel = otherchar+
+ 
+ should have been
+ 
+ 	hostname = label ( "." label )+
+ 	firstchar = [a-zA-Z0-9_]
+ 	otherchar = [a-zA-Z0-9_-/]
+ 	label = firstchar otherchar*
+ 
+ i know of no example of a real host name that needs the looser rule i sent
+ earlier.  since i'm only trying to bend the spec to fit actual known uses,
+ i should not have widened the rules as far as i did earlier.
+ 
+ sorry for the confusion.  this is exactly the confusion which has delayed P2.
+ ****/
+ 
+ #define firstchar(c) ((isascii(c) && isalnum(c)) || c == '_')
+ #define otherchar(c) (firstchar(c) || c == '-' || c == '/')
+ #define	wildlabel(firstlabel, ch, nch) \
+ 	((firstlabel) && (ch) == '*' && ((nch) == '.' || (nch) == '\0'))
+ 
+ int
+ dn_isvalid(dn)
+ 	const char *dn;
+ {
+ 	int ppch = '\0', pch = '.', ch = *dn++, firstlabel = 1;
+ 
+ 	while (ch != '\0') {
+ 		int nch = *dn++;
+ 
+ 		if (ch == '.' || (ch == '\\' && nch == '.')) {
+ 			NULL;
+ 		} else if (pch == '.' && ppch != '\\') {
+ 			if (!firstchar(ch) && !wildlabel(firstlabel, ch, nch))
+ 				return (0);
+ 		} else {
+ 			if (!otherchar(ch))
+ 				return (0);
+ 		}
+ 		ppch = pch, pch = ch, ch = nch;
+ 		firstlabel = 0;
+ 	}
+ 	return (1);
+ }
+ 
+ /*
   * Routines to insert/extract short/long's.
   */
*** 8.7	1995/12/22 10:20:39
--- res/res_debug.c	1996/03/01 07:53:47
***************
*** 503,516 ****
  	case T_HINFO:
  	case T_ISDN:
  		cp2 = cp + dlen;
! 		if (n = *cp++) {
! 			fprintf(file, "\t%.*s", n, cp);
! 			cp += n;
  		}
! 		if ((cp < cp2) && (n = *cp++)) {
! 			fprintf(file, "\t%.*s", n, cp);
! 			cp += n;
! 		} else if (type == T_HINFO)
  			fprintf(file, "\n;; *** Warning *** OS-type missing");
  		break;
  
--- 503,528 ----
  	case T_HINFO:
  	case T_ISDN:
+ 		(void) fputs("\t\"", file);
  		cp2 = cp + dlen;
! 		if ((n = (unsigned char) *cp++) != 0) {
! 			for (c = n; c > 0 && cp < cp2; c--) {
! 				if (strchr("\n\"\\", *cp))
! 					(void) putc('\\', file);
! 				(void) putc(*cp++, file);
! 			}
! 			putc('"', file);
  		}
! 		if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
! 			(void) fputs ("\t\"", file);
! 			for (c = n; c > 0 && cp < cp2; c--) {
! 				if (strchr("\n\"\\", *cp))
! 					(void) putc('\\', file);
! 				(void) putc(*cp++, file);
! 			}
! 			putc('"', file);
! 		} else if (type == T_HINFO) {
! 			(void) fputs("\"?\"", file);
  			fprintf(file, "\n;; *** Warning *** OS-type missing");
+ 		}
  		break;
  
***************
*** 564,573 ****
  		while (cp < cp2) {
  			if (n = (unsigned char) *cp++) {
! 				for (c = n; c > 0 && cp < cp2; c--)
! 					if ((*cp == '\n') || (*cp == '"')) {
! 					    (void) putc('\\', file);
! 					    (void) putc(*cp++, file);
! 					} else
! 					    (void) putc(*cp++, file);
  			}
  		}
--- 576,584 ----
  		while (cp < cp2) {
  			if (n = (unsigned char) *cp++) {
! 				for (c = n; c > 0 && cp < cp2; c--) {
! 					if (strchr("\n\"\\", *cp))
! 						(void) putc('\\', file);
! 					(void) putc(*cp++, file);
! 				}
  			}
  		}
*** 8.6	1995/12/29 21:08:13
--- tools/dig.c	1996/03/03 01:33:22
***************
*** 985,993 ****
  	int			numRead;
  	int			numAnswers = 0;
  	int			result;
  	int			soacnt = 0;
  	int			sockFD;
  	u_short			len;
! 	u_char			*cp, *nmp;
  	char			dname[2][NAME_LEN];
  	char			file[NAME_LEN];
--- 985,995 ----
  	int			numRead;
  	int			numAnswers = 0;
+ 	int			numRecords = 0;
  	int			result;
  	int			soacnt = 0;
  	int			sockFD;
+ 	int			count, type, class, rlen, done, n;
  	u_short			len;
! 	u_char			*cp;
  	char			dname[2][NAME_LEN];
  	char			file[NAME_LEN];
***************
*** 1045,1049 ****
  
  	dname[0][0] = '\0';
! 	while (1) {
  	    u_int16_t tmp;
  
--- 1047,1051 ----
  
  	dname[0][0] = '\0';
! 	for (done = 0; !done; NULL) {
  	    u_int16_t tmp;
  
***************
*** 1099,1123 ****
  		break;
  	    }
! 
  	    numAnswers++;
  	    cp = answer + HFIXEDSZ;
! 	    if (ntohs(((HEADER *)answer)->qdcount) > 0)
! 		cp += dn_skipname((u_char *)cp,
! 		    (u_char *)answer + len) + QFIXEDSZ;
! 	    nmp = cp;
! 	    cp += dn_skipname((u_char *)cp, (u_char *)answer + len);
! 	    if ((_getshort((u_char*)cp) == T_SOA)) {
! 		(void) dn_expand(answer, answer + len, nmp,
! 				 dname[soacnt], sizeof dname[0]);
! 	        if (soacnt) {
! 		    if (strcmp(dname[0], dname[1]) == 0)
! 			break;
! 		} else
! 		    soacnt++;
  	    }
  	}
  
! 	fprintf(stdout, ";; Received %d record%s.\n",
! 		numAnswers, (numAnswers != 1) ? "s" : "");
  
  	(void) close(sockFD);
--- 1101,1142 ----
  		break;
  	    }
! 	    numRecords += htons(((HEADER *)answer)->ancount);
  	    numAnswers++;
+ 
+ 	    /* Header. */
  	    cp = answer + HFIXEDSZ;
! 	    /* Question. */
! 	    for (count = ntohs(((HEADER *)answer)->qdcount);	
! 		 count > 0;
! 		 count--)
! 		cp += dn_skipname(cp, answer + len) + QFIXEDSZ;
! 	    /* Answer. */
! 	    for (count = ntohs(((HEADER *)answer)->ancount);
! 		 count > 0;
! 		 count--) {
! 		n = dn_expand(answer, answer + len, cp,
! 			      dname[soacnt], sizeof dname[0]);
! 		if (n < 0) {
! 		    error = ERR_PRINTING;
! 		    done++;
! 		    break;
! 		}
! 		cp += n;
! 		GETSHORT(type, cp);
! 		GETSHORT(class, cp);
! 		cp += INT32SZ;	/* ttl */
! 		GETSHORT(rlen, cp);
! 		cp += rlen;
! 		if (type == T_SOA && soacnt++ &&
! 		    !strcasecmp(dname[0], dname[1])) {
! 		    done++;
! 		    break;
! 		}
  	    }
  	}
  
! 	printf(";; Received %d answer%s (%d record%s).\n",
! 	       numAnswers, (numAnswers != 1) ? "s" : "",
! 	       numRecords, (numRecords != 1) ? "s" : "");
  
  	(void) close(sockFD);
***************
*** 1174,1186 ****
      if (ntohs(headerPtr->ancount) == 0) {
  	return(NO_INFO);
!     } else {
! 	if (ntohs(headerPtr->qdcount) > 0) {
! 	    nameLen = dn_skipname(cp, eom);
! 	    if (nameLen < 0)
! 		return (ERROR);
! 	    cp += nameLen + QFIXEDSZ;
! 	}
! 	cp = (u_char*) p_rr(cp, msg, stdout);
      }
      return(SUCCESS);
  }
--- 1193,1209 ----
      if (ntohs(headerPtr->ancount) == 0) {
  	return(NO_INFO);
!     }
!     for (n = ntohs(headerPtr->qdcount); n > 0; n--) {
! 	nameLen = dn_skipname(cp, eom);
! 	if (nameLen < 0)
! 	    return (ERROR);
! 	cp += nameLen + QFIXEDSZ;
      }
+ #ifdef PROTOCOLDEBUG
+     printf(";;; (message of %d octets has %d answers)\n",
+ 	   eom - msg, ntohs(headerPtr->ancount));
+ #endif
+     for (n = ntohs(headerPtr->ancount); n > 0; n--)
+ 	cp = (u_char*) p_rr(cp, msg, stdout);
      return(SUCCESS);
  }
*** 8.2	1995/06/29 09:26:34
--- tools/nslookup/debug.c	1996/03/02 20:53:13
***************
*** 338,343 ****
--- 338,351 ----
                  fprintf(file,", RFC 822 = ");
                  cp = Print_cdname(cp, msg, eom, file);
+ 		if (cp == NULL) {
+ 			fprintf(file, "(name truncated?)\n");
+ 			return (NULL);			/* compression error */
+ 		}
                  fprintf(file,"\nX.400 = ");
                  cp = Print_cdname(cp, msg, eom, file);
+ 		if (cp == NULL) {
+ 			fprintf(file, "(name truncated?)\n");
+ 			return (NULL);			/* compression error */
+ 		}
                  (void) putc('\n', file);
                  break;
***************
*** 359,362 ****
--- 367,374 ----
  doname:
  		cp = Print_cdname(cp, msg, eom, file);
+ 		if (cp == NULL) {
+ 			fprintf(file, "(name truncated?)\n");
+ 			return (NULL);			/* compression error */
+ 		}
  		(void) putc('\n', file);
  		break;
***************
*** 392,397 ****
--- 404,417 ----
  		fprintf(file,"\torigin = ");
  		cp = Print_cdname(cp, msg, eom, file);
+ 		if (cp == NULL) {
+ 			fprintf(file, "(name truncated?)\n");
+ 			return (NULL);			/* compression error */
+ 		}
  		fprintf(file,"\n\tmail addr = ");
  		cp = Print_cdname(cp, msg, eom, file);
+ 		if (cp == NULL) {
+ 			fprintf(file, "(name truncated?)\n");
+ 			return (NULL);			/* compression error */
+ 		}
  		fprintf(file,"\n\tserial = %lu", _getlong((u_char*)cp));
  		cp += INT32SZ;
***************
*** 416,421 ****
--- 436,449 ----
  		fprintf(file,"\trequests = ");
  		cp = Print_cdname(cp, msg, eom, file);
+ 		if (cp == NULL) {
+ 			fprintf(file, "(name truncated?)\n");
+ 			return (NULL);			/* compression error */
+ 		}
  		fprintf(file,"\n\terrors = ");
  		cp = Print_cdname(cp, msg, eom, file);
+ 		if (cp == NULL) {
+ 			fprintf(file, "(name truncated?)\n");
+ 			return (NULL);			/* compression error */
+ 		}
  		(void) putc('\n', file);
  		break;
***************
*** 425,430 ****
--- 453,466 ----
  		fprintf(file,"\tmailbox = ");
  		cp = Print_cdname(cp, msg, eom, file);
+ 		if (cp == NULL) {
+ 			fprintf(file, "(name truncated?)\n");
+ 			return (NULL);			/* compression error */
+ 		}
  		fprintf(file,"\n\ttext = ");
  		cp = Print_cdname(cp, msg, eom, file);
+ 		if (cp == NULL) {
+ 			fprintf(file, "(name truncated?)\n");
+ 			return (NULL);			/* compression error */
+ 		}
  		(void) putc('\n', file);
  		break;
*** 8.3	1994/12/19 08:35:16
--- tools/nslookup/list.c	1996/03/03 01:35:19
***************
*** 238,247 ****
  	int			msglen;
  	int			amtToRead;
! 	int			numRead;
  	int			numAnswers = 0;
  	int			result;
  	int			soacnt = 0;
  	u_short			len;
! 	u_char			*cp, *nmp;
  	char			dname[2][NAME_LEN];
  	char			file[NAME_LEN];
--- 238,249 ----
  	int			msglen;
  	int			amtToRead;
! 	int			numRead, n;
  	int			numAnswers = 0;
+ 	int			numRecords = 0;
  	int			result;
  	int			soacnt = 0;
+ 	int			count, done;
  	u_short			len;
! 	u_char			*cp;
  	char			dname[2][NAME_LEN];
  	char			file[NAME_LEN];
***************
*** 427,431 ****
  
  	dname[0][0] = '\0';
! 	while (1) {
  	    unsigned short tmp;
  
--- 429,433 ----
  
  	dname[0][0] = '\0';
! 	for (done = 0; !done; NULL) {
  	    unsigned short tmp;
  
***************
*** 482,486 ****
  		break;
  	    }
! 
  	    numAnswers++;
  	    if (cmd != NULL && ((numAnswers % HASH_SIZE) == 0)) {
--- 484,488 ----
  		break;
  	    }
! 	    numRecords += htons(((HEADER *)answer)->ancount);
  	    numAnswers++;
  	    if (cmd != NULL && ((numAnswers % HASH_SIZE) == 0)) {
***************
*** 488,505 ****
  		fflush(stdout);
  	    }
  	    cp = answer + HFIXEDSZ;
! 	    if (ntohs(((HEADER* )answer)->qdcount) > 0)
! 		cp += dn_skipname((u_char *)cp,
! 		    (u_char *)answer + len) + QFIXEDSZ;
! 	    nmp = cp;
! 	    cp += dn_skipname((u_char *)cp, (u_char *)answer + len);
! 	    if ((_getshort((u_char*)cp) == T_SOA)) {
! 		(void) dn_expand(answer, answer + len, nmp,
! 				 dname[soacnt], sizeof dname[0]);
! 	        if (soacnt) {
! 		    if (strcmp(dname[0], dname[1]) == 0)
! 			break;
! 		} else
! 		    soacnt++;
  	    }
  	}
--- 490,524 ----
  		fflush(stdout);
  	    }
+ 	    /* Header. */
  	    cp = answer + HFIXEDSZ;
! 	    /* Question. */
! 	    for (count = ntohs(((HEADER* )answer)->qdcount);
! 		 count > 0;
! 		 count--)
! 		    cp += dn_skipname(cp, answer + len) + QFIXEDSZ;
! 	    /* Answer. */
! 	    for (count = ntohs(((HEADER* )answer)->ancount);
! 		 count > 0;
! 		 count--) {
! 		int type, class, rlen;
! 
! 		n = dn_expand(answer, answer + len, cp,
! 			      dname[soacnt], sizeof dname[0]);
! 		if (n < 0) {
! 		    error = ERR_PRINTING;
! 		    done++;
! 		    break;
! 		}
! 		cp += n;
! 		GETSHORT(type, cp);
! 		GETSHORT(class, cp);
! 		cp += INT32SZ;	/* ttl */
! 		GETSHORT(rlen, cp);
! 		cp += rlen;
! 		if (type == T_SOA && soacnt++ &&
! 		    !strcasecmp(dname[0], dname[1])) {
! 		    done++;
! 		    break;
! 		}
  	    }
  	}
***************
*** 506,513 ****
  
  	if (cmd != NULL) {
! 	    fprintf(stdout, "%sReceived %d record%s.\n",
  		(numAnswers >= HASH_SIZE) ? "\n" : "",
! 		numAnswers,
! 		(numAnswers != 1) ? "s" : "");
  	}
  
--- 525,532 ----
  
  	if (cmd != NULL) {
! 	    fprintf(stdout, "%sReceived %d answer%s (%d record%s).\n",
  		(numAnswers >= HASH_SIZE) ? "\n" : "",
! 		numAnswers, (numAnswers != 1) ? "s" : "",
! 		numRecords, (numRecords != 1) ? "s" : "");
  	}
  
***************
*** 593,597 ****
      int			type, class, dlen, nameLen;
      u_int32_t		ttl;
!     int			n, pref;
      struct in_addr	inaddr;
      char		name[NAME_LEN];
--- 612,616 ----
      int			type, class, dlen, nameLen;
      u_int32_t		ttl;
!     int			n, pref, count;
      struct in_addr	inaddr;
      char		name[NAME_LEN];
***************
*** 616,626 ****
      if (ntohs(headerPtr->ancount) == 0) {
  	return(NO_INFO);
!     } else {
! 	if (ntohs(headerPtr->qdcount) > 0) {
! 	    nameLen = dn_skipname(cp, eom);
! 	    if (nameLen < 0)
! 		return (ERROR);
! 	    cp += nameLen + QFIXEDSZ;
! 	}
  	nameLen = dn_expand(msg, eom, cp, name, sizeof name);
  	if (nameLen < 0)
--- 635,646 ----
      if (ntohs(headerPtr->ancount) == 0) {
  	return(NO_INFO);
!     }
!     for (n = ntohs(headerPtr->qdcount); n > 0; n--) {
! 	nameLen = dn_skipname(cp, eom);
! 	if (nameLen < 0)
! 	    return (ERROR);
! 	cp += nameLen + QFIXEDSZ;
!     }
!     for (count = ntohs(headerPtr->ancount); count > 0; count--) {
  	nameLen = dn_expand(msg, eom, cp, name, sizeof name);
  	if (nameLen < 0)
***************
*** 679,682 ****
--- 699,703 ----
  			fprintf(file, " (dlen = %d?)", dlen);
  		}
+ 		cp += dlen;
  		break;
  
***************
*** 691,694 ****
--- 712,716 ----
  		}
  		fprintf(file, " %s", name2);
+ 		cp += nameLen;
  		break;
  
***************
*** 700,707 ****
  		    fprintf(file,"%s = ", type == T_PTR ? "host" : "server");
  		cp = (u_char *)Print_cdname2(cp, msg, eom, file);
  		break;
  
  	    case T_HINFO:
! 		case T_ISDN:
  		{
  		    u_char *cp2 = cp + dlen;
--- 722,733 ----
  		    fprintf(file,"%s = ", type == T_PTR ? "host" : "server");
  		cp = (u_char *)Print_cdname2(cp, msg, eom, file);
+ 		if (!cp) {
+ 		    fprintf(file, " ***\n");
+ 		    return (ERROR);
+ 		}
  		break;
  
  	    case T_HINFO:
! 	    case T_ISDN:
  		{
  		    u_char *cp2 = cp + dlen;
***************
*** 759,762 ****
--- 785,789 ----
  		}
  		fprintf(file, " %s", name2);
+ 		cp += nameLen;
  		break;
  
***************
*** 771,785 ****
  		}
  		fprintf(file, " %s", name2);
! 		cp += strlen((char *)cp) + 1;
  		nameLen = dn_expand(msg, eom, cp, name2, sizeof name2);
  		if (nameLen < 0) {
!               	fprintf(file, " ***\n");
!               	return (ERROR);
!               }
  		fprintf(file, " %s", name2);
  		break;
  
  	    case T_TXT:
! 		case T_X25:
  		{
  		    u_char *cp2 = cp + dlen;
--- 798,813 ----
  		}
  		fprintf(file, " %s", name2);
! 		cp += nameLen;
  		nameLen = dn_expand(msg, eom, cp, name2, sizeof name2);
  		if (nameLen < 0) {
! 		    fprintf(file, " ***\n");
! 		    return (ERROR);
! 		}
  		fprintf(file, " %s", name2);
+ 		cp += nameLen;
  		break;
  
  	    case T_TXT:
! 	    case T_X25:
  		{
  		    u_char *cp2 = cp + dlen;
***************
*** 787,800 ****
  
  		    (void) fputs(" \"", file);
! 		    while (cp < cp2) {
! 			    if (n = (unsigned char) *cp++) {
! 				    for (c = n; c > 0 && cp < cp2; c--)
! 					    if ((*cp == '\n') || (*cp == '"')) {
! 						(void) putc('\\', file);
! 						(void) putc(*cp++, file);
! 					    } else
! 						(void) putc(*cp++, file);
! 			    }
! 		    }
  		    (void) putc('"', file);
  		}
--- 815,826 ----
  
  		    (void) fputs(" \"", file);
! 		    while (cp < cp2)
! 			if (n = (unsigned char) *cp++)
! 			    for (c = n; c > 0 && cp < cp2; c--)
! 				if (strchr("\n\"\\", *cp)) {
! 				    (void) putc('\\', file);
! 				    (void) putc(*cp++, file);
! 				} else
! 				    (void) putc(*cp++, file);
  		    (void) putc('"', file);
  		}
***************
*** 803,806 ****
--- 829,833 ----
  	    case T_NSAP:
  		fprintf(file, " %s", inet_nsap_ntoa(dlen, cp, NULL));
+ 		cp += dlen;
  		break;
  
***************
*** 809,814 ****
--- 836,849 ----
  		(void) putc(' ', file);
  		cp = (u_char *)Print_cdname(cp, msg, eom, file);
+ 		if (!cp) {
+ 		    fprintf(file, " ***\n");
+ 		    return (ERROR);
+ 		}
  		fprintf(file, "  ");
  		cp = (u_char *)Print_cdname(cp, msg, eom, file);
+ 		if (!cp) {
+ 		    fprintf(file, " ***\n");
+ 		    return (ERROR);
+ 		}
  		break;
  
***************
*** 815,818 ****
--- 850,854 ----
  	    case T_UINFO:
  		fprintf(file, " %s", cp);
+ 		cp += dlen;
  		break;
  
***************
*** 820,823 ****
--- 856,860 ----
  	    case T_GID:
  		fprintf(file, " %lu", _getlong((u_char*)cp));
+ 		cp += dlen;
  		break;
  
