--- old/usr/src/cmd/tar/tar.c	Sun Aug 16 13:00:01 2015
+++ new/usr/src/cmd/tar/tar.c	Sun Aug 16 13:00:01 2015
@@ -21,7 +21,7 @@
 /*
  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012 Milan Jurik. All rights reserved.
- * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright 2015 Joyent, Inc.
  */
 
 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
@@ -124,13 +124,6 @@
 #define	min(a, b)  ((a) < (b) ? (a) : (b))
 #define	max(a, b)  ((a) > (b) ? (a) : (b))
 
-/* -DDEBUG	ONLY for debugging */
-#ifdef	DEBUG
-#undef	DEBUG
-#define	DEBUG(a, b, c)\
-	(void) fprintf(stderr, "DEBUG - "), (void) fprintf(stderr, a, b, c)
-#endif
-
 #define	TBLOCK	512	/* tape block size--should be universal */
 
 #ifdef	BSIZE
@@ -482,7 +475,7 @@
 static int checkw(char c, char *name);
 static int cmp(char *b, char *s, int n);
 static int defset(char *arch);
-static int endtape(void);
+static boolean_t endtape(void);
 static int is_in_table(file_list_t *table[], char *str);
 static int notsame(void);
 static int is_prefix(char *s1, char *s2);
@@ -558,6 +551,8 @@
 static void wait_pid(pid_t);
 static void verify_compress_opt(const char *t);
 static void detect_compress(void);
+static void dlog(const char *, ...);
+static boolean_t should_enable_debug(void);
 
 static	struct stat stbuf;
 
@@ -633,7 +628,7 @@
 static	int	extotal;	/* total extents in this file */
 static	off_t	extsize;	/* size of current extent during extraction */
 static	ushort_t	Oumask = 0;	/* old umask value */
-static 	int is_posix;	/* true if archive we're reading is POSIX-conformant */
+static 	boolean_t is_posix;	/* true if archive is POSIX-conformant */
 static	const	char	*magic_type = "ustar";
 static	size_t	xrec_size = 8 * PATH_MAX;	/* extended rec initial size */
 static	char	*xrec_ptr;
@@ -645,6 +640,8 @@
 					/*   need to be in extended header. */
 static	pid_t	comp_pid = 0;
 
+static boolean_t debug_output = B_FALSE;
+
 #define	_X_DEVMAJOR	0x1
 #define	_X_DEVMINOR	0x2
 #define	_X_GID		0x4
@@ -736,6 +733,8 @@
 	if (argc < 2)
 		usage();
 
+	debug_output = should_enable_debug();
+
 	tfile = NULL;
 	if ((myname = strdup(argv[0])) == NULL) {
 		(void) fprintf(stderr, gettext(
@@ -1193,7 +1192,50 @@
 	return (1);
 }
 
+static boolean_t
+should_enable_debug(void)
+{
+	const char *val;
+	const char *truth[] = {
+		"true",
+		"1",
+		"yes",
+		"y",
+		"please",
+		NULL
+	};
+	unsigned int i;
+
+	if ((val = getenv("DEBUG_TAR")) == NULL) {
+		return (B_FALSE);
+	}
+
+	for (i = 0; truth[i] != NULL; i++) {
+		if (strcmp(val, truth[i]) == 0) {
+			return (B_TRUE);
+		}
+	}
+
+	return (B_FALSE);
+}
+
+/*PRINTFLIKE1*/
 static void
+dlog(const char *format, ...)
+{
+	va_list ap;
+
+	if (!debug_output) {
+		return;
+	}
+
+	va_start(ap, format);
+	(void) fprintf(stderr, "tar: DEBUG: ");
+	(void) vfprintf(stderr, format, ap);
+	va_end(ap);
+}
+
+static void
 usage(void)
 {
 	(void) fprintf(stderr, gettext(
@@ -1427,13 +1469,26 @@
  *			1 if	 EOT, tape position unaffected
  */
 
-static int
+static boolean_t
 endtape(void)
 {
-	if (dblock.dbuf.name[0] == '\0') {	/* null header = EOT */
-		return (1);
-	} else
-		return (0);
+	if (dblock.dbuf.name[0] != '\0') {
+		/*
+		 * The name field is populated.
+		 */
+		return (B_FALSE);
+	}
+
+	if (is_posix && dblock.dbuf.prefix[0] != '\0') {
+		/*
+		 * This is a ustar/POSIX archive, and although the name
+		 * field is empty the prefix field is not.
+		 */
+		return (B_FALSE);
+	}
+
+	dlog("endtape(): found null header; EOT\n");
+	return (B_TRUE);
 }
 
 /*
@@ -1471,9 +1526,11 @@
 	is_posix = (strcmp(dblock.dbuf.magic, magic_type) == 0);
 
 	sp->st_mode = Gen.g_mode;
-	if (is_posix && (sp->st_mode & S_IFMT) == 0)
+	if (is_posix && (sp->st_mode & S_IFMT) == 0) {
 		switch (dblock.dbuf.typeflag) {
-		case '0': case 0: case _XATTR_HDRTYPE:
+		case '0':
+		case 0:
+		case _XATTR_HDRTYPE:
 			sp->st_mode |= S_IFREG;
 			break;
 		case '1':	/* hard link */
@@ -1498,6 +1555,7 @@
 				sp->st_mode |= S_IFREG;
 			break;
 		}
+	}
 
 	if ((dblock.dbuf.typeflag == 'X') || (dblock.dbuf.typeflag == 'L')) {
 		Xhdrflag = 1;	/* Currently processing extended header */
@@ -1605,7 +1663,7 @@
  *	The tape directory entry must be in dblock.dbuf. This
  *	routine just eats the number of blocks computed from the
  *	directory size entry; the tape must be (logically) positioned
- *	right after thee directory info.
+ *	right after the directory info.
  */
 
 static void
@@ -1615,6 +1673,18 @@
 	char buf[TBLOCK];
 
 	/*
+	 * Print some debugging information about the directory entry
+	 * we are skipping over:
+	 */
+	dlog("passtape: typeflag \"%c\"\n", dblock.dbuf.typeflag);
+	if (dblock.dbuf.name[0] != '\0') {
+		dlog("passtape: name \"%s\"\n", dblock.dbuf.name);
+	}
+	if (is_posix && dblock.dbuf.prefix[0] != '\0') {
+		dlog("passtape: prefix \"%s\"\n", dblock.dbuf.prefix);
+	}
+
+	/*
 	 * Types link(1), sym-link(2), char special(3), blk special(4),
 	 *  directory(5), and FIFO(6) do not have data blocks associated
 	 *  with them so just skip reading the data block.
@@ -1625,6 +1695,8 @@
 		return;
 	blocks = TBLOCKS(stbuf.st_size);
 
+	dlog("passtape: block count %" FMT_blkcnt_t "\n", blocks);
+
 	/* if operating on disk, seek instead of reading */
 	if (NotTape)
 		seekdisk(blocks);
@@ -2070,11 +2142,9 @@
 			(void) writetbuf((char *)&dblock, 1);
 		}
 		if (vflag) {
-#ifdef DEBUG
-			if (NotTape)
-				DEBUG("seek = %" FMT_blkcnt_t "K\t", K(tapepos),
-				    0);
-#endif
+			if (NotTape) {
+				dlog("seek = %" FMT_blkcnt_t "K\n", K(tapepos));
+			}
 			if (filetype == XATTR_FILE && Hiddendir) {
 				(void) fprintf(vfile,
 				    gettext("a %s attribute %s "),
@@ -2083,12 +2153,13 @@
 			} else {
 				(void) fprintf(vfile, "a %s/ ", longname);
 			}
-			if (NotTape)
+			if (NotTape) {
 				(void) fprintf(vfile, "%" FMT_blkcnt_t "K\n",
 				    K(blocks));
-			else
+			} else {
 				(void) fprintf(vfile, gettext("%" FMT_blkcnt_t
 				    " tape blocks\n"), blocks);
+			}
 		}
 
 		/*
@@ -2270,20 +2341,16 @@
 			}
 			newvol();	/* not worth it--just get new volume */
 		}
-#ifdef DEBUG
-		DEBUG("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
+		dlog("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
 		    blocks);
-#endif
 		if (build_dblock(name, tchar, '0', filetype,
 		    &stbuf, stbuf.st_dev, prefix) != 0) {
 			goto out;
 		}
 		if (vflag) {
-#ifdef DEBUG
-			if (NotTape)
-				DEBUG("seek = %" FMT_blkcnt_t "K\t", K(tapepos),
-				    0);
-#endif
+			if (NotTape) {
+				dlog("seek = %" FMT_blkcnt_t "K\n", K(tapepos));
+			}
 			(void) fprintf(vfile, "a %s%s%s%s ", longname,
 			    rw_sysattr ? gettext(" system") : "",
 			    (filetype == XATTR_FILE) ? gettext(
@@ -2367,23 +2434,19 @@
 			}
 			newvol();
 		}
-#ifdef DEBUG
-		DEBUG("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
+		dlog("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
 		    blocks);
-#endif
 		if (vflag) {
-#ifdef DEBUG
-			if (NotTape)
-				DEBUG("seek = %" FMT_blkcnt_t "K\t", K(tapepos),
-				    0);
-#endif
-			if (NotTape)
+			if (NotTape) {
+				dlog("seek = %" FMT_blkcnt_t "K\n", K(tapepos));
+
 				(void) fprintf(vfile, gettext("a %s %"
 				    FMT_blkcnt_t "K\n "), longname, K(blocks));
-			else
+			} else {
 				(void) fprintf(vfile, gettext(
 				    "a %s %" FMT_blkcnt_t " tape blocks\n"),
 				    longname, blocks);
+			}
 		}
 		if (build_dblock(name, tchar, '6', filetype,
 		    &stbuf, stbuf.st_dev, prefix) != 0)
@@ -2418,23 +2481,19 @@
 			}
 			newvol();
 		}
-#ifdef DEBUG
-		DEBUG("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
+		dlog("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
 		    blocks);
-#endif
 		if (vflag) {
-#ifdef DEBUG
-			if (NotTape)
-				DEBUG("seek = %" FMT_blkcnt_t "K\t", K(tapepos),
-				    0);
-#endif
-			if (NotTape)
+			if (NotTape) {
+				dlog("seek = %" FMT_blkcnt_t "K\t", K(tapepos));
+
 				(void) fprintf(vfile, gettext("a %s %"
 				    FMT_blkcnt_t "K\n"), longname, K(blocks));
-			else
+			} else {
 				(void) fprintf(vfile, gettext("a %s %"
 				    FMT_blkcnt_t " tape blocks\n"), longname,
 				    blocks);
+			}
 		}
 		if (build_dblock(name, tchar, '3',
 		    filetype, &stbuf, stbuf.st_rdev, prefix) != 0)
@@ -2469,16 +2528,13 @@
 			}
 			newvol();
 		}
-#ifdef DEBUG
-		DEBUG("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
+		dlog("putfile: %s wants %" FMT_blkcnt_t " blocks\n", longname,
 		    blocks);
-#endif
 		if (vflag) {
-#ifdef DEBUG
-			if (NotTape)
-				DEBUG("seek = %" FMT_blkcnt_t "K\t", K(tapepos),
-				    0);
-#endif
+			if (NotTape) {
+				dlog("seek = %" FMT_blkcnt_t "K\n", K(tapepos));
+			}
+
 			(void) fprintf(vfile, "a %s ", longname);
 			if (NotTape)
 				(void) fprintf(vfile, "%" FMT_blkcnt_t "K\n",
@@ -4790,9 +4846,7 @@
 	int c;
 
 	if (dumping) {
-#ifdef DEBUG
-		DEBUG("newvol called with 'dumping' set\n", 0, 0);
-#endif
+		dlog("newvol called with 'dumping' set\n");
 		putempty((blkcnt_t)2);	/* 2 EOT marks */
 		closevol();
 		flushtape();
@@ -4825,10 +4879,8 @@
 		    "tar: cannot reopen %s (%s)\n"),
 		    dumping ? gettext("output") : gettext("input"), usefile);
 
-#ifdef DEBUG
-		DEBUG("update=%d, usefile=%s ", update, usefile);
-		DEBUG("mt=%d, [%s]\n", mt, strerror(errno));
-#endif
+		dlog("update=%d, usefile=%s ", update, usefile);
+		dlog("mt=%d, [%s]\n", mt, strerror(errno));
 
 		done(2);
 	}
@@ -5013,9 +5065,7 @@
 #endif
 
 	tapepos += blocks;
-#ifdef DEBUG
-	DEBUG("seekdisk(%" FMT_blkcnt_t ") called\n", blocks, 0);
-#endif
+	dlog("seekdisk(%" FMT_blkcnt_t ") called\n", blocks);
 	if (recno + blocks <= nblock) {
 		recno += blocks;
 		return;
@@ -5026,10 +5076,8 @@
 	recno = nblock;	/* so readtape() reads next time through */
 #if SYS_BLOCK > TBLOCK
 	nxb = (blkcnt_t)(seekval % (off_t)(SYS_BLOCK / TBLOCK));
-#ifdef DEBUG
-	DEBUG("xtrablks=%" FMT_blkcnt_t " seekval=%" FMT_blkcnt_t " blks\n",
+	dlog("xtrablks=%" FMT_blkcnt_t " seekval=%" FMT_blkcnt_t " blks\n",
 	    nxb, seekval);
-#endif
 	if (nxb && nxb > seekval) /* don't seek--we'll read */
 		goto noseek;
 	seekval -=  nxb;	/* don't seek quite so far */
@@ -5043,9 +5091,7 @@
 	/* read those extra blocks */
 noseek:
 	if (nxb) {
-#ifdef DEBUG
-		DEBUG("reading extra blocks\n", 0, 0);
-#endif
+		dlog("reading extra blocks\n", 0, 0);
 		if (read(mt, tbuf, TBLOCK*nblock) < 0) {
 			(void) fprintf(stderr, gettext(
 			    "tar: read error while skipping file\n"));
@@ -5217,10 +5263,8 @@
 backtape(void)
 {
 	struct mtop mtcmd;
-#ifdef DEBUG
-	DEBUG("backtape() called, recno=%" FMT_blkcnt_t " nblock=%d\n", recno,
+	dlog("backtape() called, recno=%" FMT_blkcnt_t " nblock=%d\n", recno,
 	    nblock);
-#endif
 	/*
 	 * Backup to the position in the archive where the record
 	 * currently sitting in the tbuf buffer is situated.
@@ -5278,9 +5322,7 @@
 static void
 flushtape(void)
 {
-#ifdef DEBUG
-	DEBUG("flushtape() called, recno=%" FMT_blkcnt_t "\n", recno, 0);
-#endif
+	dlog("flushtape() called, recno=%" FMT_blkcnt_t "\n", recno);
 	if (recno > 0) {	/* anything buffered? */
 		if (NotTape) {
 #if SYS_BLOCK > TBLOCK
@@ -5293,9 +5335,7 @@
 			 * boundary.
 			 */
 			if ((i = recno % (SYS_BLOCK / TBLOCK)) != 0) {
-#ifdef DEBUG
-				DEBUG("flushtape() %d rounding blocks\n", i, 0);
-#endif
+				dlog("flushtape() %d rounding blocks\n", i);
 				recno += i;	/* round up to even SYS_BLOCK */
 			}
 #endif
@@ -5302,11 +5342,9 @@
 			if (recno > nblock)
 				recno = nblock;
 		}
-#ifdef DEBUG
-		DEBUG("writing out %" FMT_blkcnt_t " blocks of %" FMT_blkcnt_t
+		dlog("writing out %" FMT_blkcnt_t " blocks of %" FMT_blkcnt_t
 		    " bytes\n", (blkcnt_t)(NotTape ? recno : nblock),
 		    (blkcnt_t)(NotTape ? recno : nblock) * TBLOCK);
-#endif
 		if (write(mt, tbuf,
 		    (size_t)(NotTape ? recno : nblock) * TBLOCK) < 0) {
 			(void) fprintf(stderr, gettext(
@@ -5436,12 +5474,10 @@
 	else
 		NotTape = (blocklim != 0);
 	(void) defopen(NULL);
-#ifdef DEBUG
-	DEBUG("defset: archive='%s'; usefile='%s'\n", arch, usefile);
-	DEBUG("defset: nblock='%d'; blocklim='%" FMT_blkcnt_t "'\n",
+	dlog("defset: archive='%s'; usefile='%s'\n", arch, usefile);
+	dlog("defset: nblock='%d'; blocklim='%" FMT_blkcnt_t "'\n",
 	    nblock, blocklim);
-	DEBUG("defset: not tape = %d\n", NotTape, 0);
-#endif
+	dlog("defset: not tape = %d\n", NotTape);
 	return (TRUE);
 }
 
@@ -5752,6 +5788,9 @@
 
 	if (endtape()) {
 		if (Bflag) {
+			ssize_t sz;
+			size_t extra_blocks = 0;
+
 			/*
 			 * Logically at EOT - consume any extra blocks
 			 * so that write to our stdin won't fail and
@@ -5760,10 +5799,13 @@
 			 * will produce a bogus error message from "dd".
 			 */
 
-			while (read(mt, tbuf, TBLOCK*nblock) > 0) {
-				/* empty body */
+			while ((sz = read(mt, tbuf, TBLOCK*nblock)) > 0) {
+				extra_blocks += sz;
 			}
+			dlog("wantit(): %d bytes of extra blocks\n",
+			    extra_blocks);
 		}
+		dlog("wantit(): at end of tape.\n");
 		return (-1);
 	}
 
@@ -8016,11 +8058,9 @@
 			 */
 
 			if (vflag) {
-#ifdef DEBUG
 				if (NotTape)
-					DEBUG("seek = %" FMT_blkcnt_t
-					    "K\t", K(tapepos), 0);
-#endif
+					dlog("seek = %" FMT_blkcnt_t
+					    "K\n", K(tapepos));
 				if (filetype == XATTR_FILE) {
 					(void) fprintf(vfile, gettext(
 					    "a %s attribute %s link to "
