Module Name:    src
Committed By:   christos
Date:           Thu Aug  9 08:09:22 UTC 2012

Modified Files:
        src/bin/pax: cpio.c extern.h gen_subs.c pax.h tar.c

Log Message:
PR/46786: Simon Burge: After conversion to 64 bit time_t, tar/pax/cpio
erroneously think that negative time_t's never fit in 32 bits. Rework
conversion code to always use uintmax_t, and detect negative values.
XXX[1]: Perhaps we should do the same (use a signed conversion) for all
fields not just for time_t
XXX[2]: pullup for 6


To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/bin/pax/cpio.c
cvs rdiff -u -r1.58 -r1.59 src/bin/pax/extern.h
cvs rdiff -u -r1.35 -r1.36 src/bin/pax/gen_subs.c
cvs rdiff -u -r1.30 -r1.31 src/bin/pax/pax.h
cvs rdiff -u -r1.69 -r1.70 src/bin/pax/tar.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/bin/pax/cpio.c
diff -u src/bin/pax/cpio.c:1.21 src/bin/pax/cpio.c:1.22
--- src/bin/pax/cpio.c:1.21	Sat Mar 26 08:01:06 2011
+++ src/bin/pax/cpio.c	Thu Aug  9 04:09:21 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpio.c,v 1.21 2011/03/26 12:01:06 martin Exp $	*/
+/*	$NetBSD: cpio.c,v 1.22 2012/08/09 08:09:21 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)cpio.c	8.1 (Berkeley) 5/31/93";
 #else
-__RCSID("$NetBSD: cpio.c,v 1.21 2011/03/26 12:01:06 martin Exp $");
+__RCSID("$NetBSD: cpio.c,v 1.22 2012/08/09 08:09:21 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -297,15 +297,15 @@ cpio_rd(ARCHD *arcn, char *buf)
 	 * ascii fields from the header
 	 */
 	arcn->pad = 0L;
-	arcn->sb.st_dev = (dev_t)asc_ul(hd->c_dev, sizeof(hd->c_dev), OCT);
-	arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), OCT);
-	arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), OCT);
-	arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), OCT);
-	arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), OCT);
-	arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
+	arcn->sb.st_dev = (dev_t)asc_u32(hd->c_dev, sizeof(hd->c_dev), OCT);
+	arcn->sb.st_ino = (ino_t)asc_u32(hd->c_ino, sizeof(hd->c_ino), OCT);
+	arcn->sb.st_mode = (mode_t)asc_u32(hd->c_mode, sizeof(hd->c_mode), OCT);
+	arcn->sb.st_uid = (uid_t)asc_u32(hd->c_uid, sizeof(hd->c_uid), OCT);
+	arcn->sb.st_gid = (gid_t)asc_u32(hd->c_gid, sizeof(hd->c_gid), OCT);
+	arcn->sb.st_nlink = (nlink_t)asc_u32(hd->c_nlink, sizeof(hd->c_nlink),
 	    OCT);
-	arcn->sb.st_rdev = (dev_t)asc_ul(hd->c_rdev, sizeof(hd->c_rdev), OCT);
-	arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime, sizeof(hd->c_mtime),
+	arcn->sb.st_rdev = (dev_t)asc_u32(hd->c_rdev, sizeof(hd->c_rdev), OCT);
+	arcn->sb.st_mtime = (time_t)(int32_t)asc_u32(hd->c_mtime, sizeof(hd->c_mtime),
 	    OCT);
 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
 	arcn->sb.st_size = (off_t)ASC_OFFT(hd->c_filesize,
@@ -315,7 +315,7 @@ cpio_rd(ARCHD *arcn, char *buf)
 	 * check name size and if valid, read in the name of this entry (name
 	 * follows header in the archive)
 	 */
-	if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2)
+	if ((nsz = (int)asc_u32(hd->c_namesize,sizeof(hd->c_namesize),OCT)) < 2)
 		return -1;
 	arcn->nlen = nsz - 1;
 	if (rd_nm(arcn, nsz) < 0)
@@ -415,7 +415,7 @@ cpio_wr(ARCHD *arcn)
 		/*
 		 * set data size to hold link name
 		 */
-		if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
+		if (u32_asc((uintmax_t)arcn->ln_nlen, hd->c_filesize,
 		    sizeof(hd->c_filesize), OCT))
 			goto out;
 		break;
@@ -423,7 +423,7 @@ cpio_wr(ARCHD *arcn)
 		/*
 		 * all other file types have no file data
 		 */
-		if (ul_asc((u_long)0, hd->c_filesize, sizeof(hd->c_filesize),
+		if (u32_asc((uintmax_t)0, hd->c_filesize, sizeof(hd->c_filesize),
 		     OCT))
 			goto out;
 		break;
@@ -432,24 +432,24 @@ cpio_wr(ARCHD *arcn)
 	/*
 	 * copy the values to the header using octal ascii
 	 */
-	if (ul_asc((u_long)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) ||
-	    ul_asc((u_long)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev),
+	if (u32_asc((uintmax_t)MAGIC, hd->c_magic, sizeof(hd->c_magic), OCT) ||
+	    u32_asc((uintmax_t)arcn->sb.st_dev, hd->c_dev, sizeof(hd->c_dev),
 		OCT) ||
-	    ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
+	    u32_asc((uintmax_t)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
 		OCT) ||
-	    ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
+	    u32_asc((uintmax_t)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
 		OCT) ||
-	    ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
+	    u32_asc((uintmax_t)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
 		OCT) ||
-	    ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
+	    u32_asc((uintmax_t)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
 		OCT) ||
-	    ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
+	    u32_asc((uintmax_t)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
 		 OCT) ||
-	    ul_asc((u_long)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev),
+	    u32_asc((uintmax_t)arcn->sb.st_rdev, hd->c_rdev, sizeof(hd->c_rdev),
 		OCT) ||
-	    ul_asc((u_long)arcn->sb.st_mtime,hd->c_mtime,sizeof(hd->c_mtime),
+	    u32_asc((uintmax_t)arcn->sb.st_mtime,hd->c_mtime,sizeof(hd->c_mtime),
 		OCT) ||
-	    ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT))
+	    u32_asc((uintmax_t)nsz, hd->c_namesize, sizeof(hd->c_namesize), OCT))
 		goto out;
 
 	/*
@@ -578,29 +578,29 @@ vcpio_rd(ARCHD *arcn, char *buf)
 	/*
 	 * extract the hex ascii fields from the header
 	 */
-	arcn->sb.st_ino = (ino_t)asc_ul(hd->c_ino, sizeof(hd->c_ino), HEX);
-	arcn->sb.st_mode = (mode_t)asc_ul(hd->c_mode, sizeof(hd->c_mode), HEX);
-	arcn->sb.st_uid = (uid_t)asc_ul(hd->c_uid, sizeof(hd->c_uid), HEX);
-	arcn->sb.st_gid = (gid_t)asc_ul(hd->c_gid, sizeof(hd->c_gid), HEX);
-	arcn->sb.st_mtime = (time_t)asc_ul(hd->c_mtime,sizeof(hd->c_mtime),HEX);
+	arcn->sb.st_ino = (ino_t)asc_u32(hd->c_ino, sizeof(hd->c_ino), HEX);
+	arcn->sb.st_mode = (mode_t)asc_u32(hd->c_mode, sizeof(hd->c_mode), HEX);
+	arcn->sb.st_uid = (uid_t)asc_u32(hd->c_uid, sizeof(hd->c_uid), HEX);
+	arcn->sb.st_gid = (gid_t)asc_u32(hd->c_gid, sizeof(hd->c_gid), HEX);
+	arcn->sb.st_mtime = (time_t)(int32_t)asc_u32(hd->c_mtime,sizeof(hd->c_mtime),HEX);
 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
 	arcn->sb.st_size = (off_t)ASC_OFFT(hd->c_filesize,
 	    sizeof(hd->c_filesize), HEX);
-	arcn->sb.st_nlink = (nlink_t)asc_ul(hd->c_nlink, sizeof(hd->c_nlink),
+	arcn->sb.st_nlink = (nlink_t)asc_u32(hd->c_nlink, sizeof(hd->c_nlink),
 	    HEX);
-	devmajor = (dev_t)asc_ul(hd->c_maj, sizeof(hd->c_maj), HEX);
-	devminor = (dev_t)asc_ul(hd->c_min, sizeof(hd->c_min), HEX);
+	devmajor = (dev_t)asc_u32(hd->c_maj, sizeof(hd->c_maj), HEX);
+	devminor = (dev_t)asc_u32(hd->c_min, sizeof(hd->c_min), HEX);
 	arcn->sb.st_dev = TODEV(devmajor, devminor);
-	devmajor = (dev_t)asc_ul(hd->c_rmaj, sizeof(hd->c_maj), HEX);
-	devminor = (dev_t)asc_ul(hd->c_rmin, sizeof(hd->c_min), HEX);
+	devmajor = (dev_t)asc_u32(hd->c_rmaj, sizeof(hd->c_maj), HEX);
+	devminor = (dev_t)asc_u32(hd->c_rmin, sizeof(hd->c_min), HEX);
 	arcn->sb.st_rdev = TODEV(devmajor, devminor);
-	arcn->crc = asc_ul(hd->c_chksum, sizeof(hd->c_chksum), HEX);
+	arcn->crc = asc_u32(hd->c_chksum, sizeof(hd->c_chksum), HEX);
 
 	/*
 	 * check the length of the file name, if ok read it in, return -1 if
 	 * bogus
 	 */
-	if ((nsz = (int)asc_ul(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2)
+	if ((nsz = (int)asc_u32(hd->c_namesize,sizeof(hd->c_namesize),HEX)) < 2)
 		return -1;
 	arcn->nlen = nsz - 1;
 	if (rd_nm(arcn, nsz) < 0)
@@ -699,15 +699,15 @@ vcpio_wr(ARCHD *arcn)
 	 * file data crc's, and the crc if needed.
 	 */
 	if (docrc) {
-		if (ul_asc((u_long)VCMAGIC, hd->c_magic, sizeof(hd->c_magic),
+		if (u32_asc((uintmax_t)VCMAGIC, hd->c_magic, sizeof(hd->c_magic),
 			OCT) ||
-		    ul_asc((u_long)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum),
+		    u32_asc((uintmax_t)arcn->crc,hd->c_chksum,sizeof(hd->c_chksum),
 			HEX))
 			goto out;
 	} else {
-		if (ul_asc((u_long)VMAGIC, hd->c_magic, sizeof(hd->c_magic),
+		if (u32_asc((uintmax_t)VMAGIC, hd->c_magic, sizeof(hd->c_magic),
 			OCT) ||
-		    ul_asc((u_long)0L, hd->c_chksum, sizeof(hd->c_chksum),HEX))
+		    u32_asc((uintmax_t)0, hd->c_chksum, sizeof(hd->c_chksum),HEX))
 			goto out;
 	}
 
@@ -733,7 +733,7 @@ vcpio_wr(ARCHD *arcn)
 		 * the size of the link
 		 */
 		arcn->pad = 0L;
-		if (ul_asc((u_long)arcn->ln_nlen, hd->c_filesize,
+		if (u32_asc((uintmax_t)arcn->ln_nlen, hd->c_filesize,
 		    sizeof(hd->c_filesize), HEX))
 			goto out;
 		break;
@@ -742,7 +742,7 @@ vcpio_wr(ARCHD *arcn)
 		 * no file data for the caller to process
 		 */
 		arcn->pad = 0L;
-		if (ul_asc((u_long)0L, hd->c_filesize, sizeof(hd->c_filesize),
+		if (u32_asc((uintmax_t)0, hd->c_filesize, sizeof(hd->c_filesize),
 		    HEX))
 			goto out;
 		break;
@@ -751,27 +751,27 @@ vcpio_wr(ARCHD *arcn)
 	/*
 	 * set the other fields in the header
 	 */
-	if (ul_asc((u_long)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
+	if (u32_asc((uintmax_t)arcn->sb.st_ino, hd->c_ino, sizeof(hd->c_ino),
 		HEX) ||
-	    ul_asc((u_long)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
+	    u32_asc((uintmax_t)arcn->sb.st_mode, hd->c_mode, sizeof(hd->c_mode),
 		HEX) ||
-	    ul_asc((u_long)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
+	    u32_asc((uintmax_t)arcn->sb.st_uid, hd->c_uid, sizeof(hd->c_uid),
 		HEX) ||
-	    ul_asc((u_long)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
+	    u32_asc((uintmax_t)arcn->sb.st_gid, hd->c_gid, sizeof(hd->c_gid),
 		HEX) ||
-	    ul_asc((u_long)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime),
+	    u32_asc((uintmax_t)arcn->sb.st_mtime, hd->c_mtime, sizeof(hd->c_mtime),
 		HEX) ||
-	    ul_asc((u_long)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
+	    u32_asc((uintmax_t)arcn->sb.st_nlink, hd->c_nlink, sizeof(hd->c_nlink),
 		HEX) ||
-	    ul_asc((u_long)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj),
+	    u32_asc((uintmax_t)MAJOR(arcn->sb.st_dev),hd->c_maj, sizeof(hd->c_maj),
 		HEX) ||
-	    ul_asc((u_long)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min),
+	    u32_asc((uintmax_t)MINOR(arcn->sb.st_dev),hd->c_min, sizeof(hd->c_min),
 		HEX) ||
-	    ul_asc((u_long)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj),
+	    u32_asc((uintmax_t)MAJOR(arcn->sb.st_rdev),hd->c_rmaj,sizeof(hd->c_maj),
 		HEX) ||
-	    ul_asc((u_long)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min),
+	    u32_asc((uintmax_t)MINOR(arcn->sb.st_rdev),hd->c_rmin,sizeof(hd->c_min),
 		HEX) ||
-	    ul_asc((u_long)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX))
+	    u32_asc((uintmax_t)nsz, hd->c_namesize, sizeof(hd->c_namesize), HEX))
 		goto out;
 
 	/*

Index: src/bin/pax/extern.h
diff -u src/bin/pax/extern.h:1.58 src/bin/pax/extern.h:1.59
--- src/bin/pax/extern.h:1.58	Mon Aug 29 10:47:47 2011
+++ src/bin/pax/extern.h	Thu Aug  9 04:09:21 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: extern.h,v 1.58 2011/08/29 14:47:47 joerg Exp $	*/
+/*	$NetBSD: extern.h,v 1.59 2012/08/09 08:09:21 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -181,12 +181,10 @@ int next_file(ARCHD *);
 void ls_list(ARCHD *, time_t, FILE *);
 void ls_tty(ARCHD *);
 void safe_print(const char *, FILE *);
-u_long asc_ul(char *, int, int);
-int ul_asc(u_long, char *, int, int);
-#if !defined(_LP64)
-unsigned long long asc_ull(char *, int, int);
-int ull_asc(unsigned long long, char *, int, int);
-#endif
+uint32_t asc_u32(char *, int, int);
+int u32_asc(uintmax_t, char *, int, int);
+uintmax_t asc_umax(char *, int, int);
+int umax_asc(uintmax_t, char *, int, int);
 int check_Aflag(void);
 
 /*

Index: src/bin/pax/gen_subs.c
diff -u src/bin/pax/gen_subs.c:1.35 src/bin/pax/gen_subs.c:1.36
--- src/bin/pax/gen_subs.c:1.35	Sun Aug 14 06:49:58 2011
+++ src/bin/pax/gen_subs.c	Thu Aug  9 04:09:21 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: gen_subs.c,v 1.35 2011/08/14 10:49:58 christos Exp $	*/
+/*	$NetBSD: gen_subs.c,v 1.36 2012/08/09 08:09:21 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)gen_subs.c	8.1 (Berkeley) 5/31/93";
 #else
-__RCSID("$NetBSD: gen_subs.c,v 1.35 2011/08/14 10:49:58 christos Exp $");
+__RCSID("$NetBSD: gen_subs.c,v 1.36 2012/08/09 08:09:21 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -202,20 +202,20 @@ safe_print(const char *str, FILE *fp)
 }
 
 /*
- * asc_ul()
- *	convert hex/octal character string into a u_long. We do not have to
+ * asc_u32()
+ *	convert hex/octal character string into a uint32_t. We do not have to
  *	check for overflow! (the headers in all supported formats are not large
  *	enough to create an overflow).
  *	NOTE: strings passed to us are NOT TERMINATED.
  * Return:
- *	unsigned long value
+ *	uint32_t value
  */
 
-u_long
-asc_ul(char *str, int len, int base)
+uint32_t
+asc_u32(char *str, int len, int base)
 {
 	char *stop;
-	u_long tval = 0;
+	uint32_t tval = 0;
 
 	stop = str + len;
 
@@ -248,17 +248,24 @@ asc_ul(char *str, int len, int base)
 }
 
 /*
- * ul_asc()
- *	convert an unsigned long into an hex/oct ascii string. pads with LEADING
+ * u32_asc()
+ *	convert an uintmax_t into an hex/oct ascii string. pads with LEADING
  *	ascii 0's to fill string completely
  *	NOTE: the string created is NOT TERMINATED.
  */
 
 int
-ul_asc(u_long val, char *str, int len, int base)
+u32_asc(uintmax_t val, char *str, int len, int base)
 {
 	char *pt;
-	u_long digit;
+	uint32_t digit;
+	uintmax_t p;
+
+	p = val & TOP_HALF;
+	if (p && p != TOP_HALF)
+		return -1;
+
+	val &= BOTTOM_HALF;
 
 	/*
 	 * WARNING str is not '\0' terminated by this routine
@@ -282,7 +289,7 @@ ul_asc(u_long val, char *str, int len, i
 	} else {
 		while (pt >= str) {
 			*pt-- = '0' + (char)(val & 0x7);
-			if ((val = (val >> 3)) == (u_long)0)
+			if ((val = (val >> 3)) == 0)
 				break;
 		}
 	}
@@ -292,27 +299,26 @@ ul_asc(u_long val, char *str, int len, i
 	 */
 	while (pt >= str)
 		*pt-- = '0';
-	if (val != (u_long)0)
+	if (val != 0)
 		return -1;
 	return 0;
 }
 
-#if !defined(_LP64)
 /*
- * asc_ull()
- *	convert hex/octal character string into a unsigned long long. We do
+ * asc_umax()
+ *	convert hex/octal character string into a uintmax. We do
  *	not have to to check for overflow! (the headers in all supported
  *	formats are not large enough to create an overflow).
  *	NOTE: strings passed to us are NOT TERMINATED.
  * Return:
- *	unsigned long long value
+ *	uintmax_t value
  */
 
-unsigned long long
-asc_ull(char *str, int len, int base)
+uintmax_t
+asc_umax(char *str, int len, int base)
 {
 	char *stop;
-	unsigned long long tval = 0;
+	uintmax_t tval = 0;
 
 	stop = str + len;
 
@@ -345,17 +351,17 @@ asc_ull(char *str, int len, int base)
 }
 
 /*
- * ull_asc()
- *	convert an unsigned long long into a hex/oct ascii string. pads with
+ * umax_asc()
+ *	convert an uintmax_t into a hex/oct ascii string. pads with
  *	LEADING ascii 0's to fill string completely
  *	NOTE: the string created is NOT TERMINATED.
  */
 
 int
-ull_asc(unsigned long long val, char *str, int len, int base)
+umax_asc(uintmax_t val, char *str, int len, int base)
 {
 	char *pt;
-	unsigned long long digit;
+	uintmax_t digit;
 
 	/*
 	 * WARNING str is not '\0' terminated by this routine
@@ -373,13 +379,13 @@ ull_asc(unsigned long long val, char *st
 				*pt-- = '0' + (char)digit;
 			else
 				*pt-- = 'a' + (char)(digit - 10);
-			if ((val = (val >> 4)) == (unsigned long long)0)
+			if ((val = (val >> 4)) == 0)
 				break;
 		}
 	} else {
 		while (pt >= str) {
 			*pt-- = '0' + (char)(val & 0x7);
-			if ((val = (val >> 3)) == (unsigned long long)0)
+			if ((val = (val >> 3)) == 0)
 				break;
 		}
 	}
@@ -389,11 +395,10 @@ ull_asc(unsigned long long val, char *st
 	 */
 	while (pt >= str)
 		*pt-- = '0';
-	if (val != (unsigned long long)0)
+	if (val != 0)
 		return -1;
 	return 0;
 }
-#endif
 
 int
 check_Aflag(void)

Index: src/bin/pax/pax.h
diff -u src/bin/pax/pax.h:1.30 src/bin/pax/pax.h:1.31
--- src/bin/pax/pax.h:1.30	Tue Apr  7 15:52:35 2009
+++ src/bin/pax/pax.h	Thu Aug  9 04:09:21 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: pax.h,v 1.30 2009/04/07 19:52:35 perry Exp $	*/
+/*	$NetBSD: pax.h,v 1.31 2012/08/09 08:09:21 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -267,24 +267,17 @@ typedef struct oplist {
 #define _TFILE_BASE	"paxXXXXXXXXXX"
 
 /*
- * Macros to manipulate off_t as a unsigned long or unsigned long long
+ * Macros to manipulate off_t as uintmax_t
  */
-#if defined(_LP64)
-#define	OFFT_F			"%lu"
-#define	OFFT_FP(x)		"%" x "lu"
-#define	OFFT_T			u_long
-#define	ASC_OFFT(x,y,z)		asc_ul(x,y,z)
-#define	OFFT_ASC(w,x,y,z)	ul_asc((u_long)w,x,y,z)
-#define	OFFT_OCT(w,x,y,z)	ul_oct((u_long)w,x,y,z)
-#define	STRTOOFFT(x,y,z)	strtol(x,y,z)
-#define	OFFT_MAX		LONG_MAX
-#else
-#define	OFFT_F			"%llu"
-#define	OFFT_FP(x)		"%" x "llu"
-#define	OFFT_T			unsigned long long
-#define	ASC_OFFT(x,y,z)		asc_ull(x,y,z)
-#define	OFFT_ASC(w,x,y,z)	ull_asc((unsigned long long)w,x,y,z)
-#define	OFFT_OCT(w,x,y,z)	ull_oct((unsigned long long)w,x,y,z)
-#define	STRTOOFFT(x,y,z)	strtoll(x,y,z)
-#define	OFFT_MAX		LLONG_MAX
-#endif
+#define	OFFT_F			"%" PRIuMAX
+#define	OFFT_FP(x)		"%" x PRIuMAX
+#define	OFFT_T			uintmax_t
+#define	ASC_OFFT(x,y,z)		asc_umax(x,y,z)
+#define	OFFT_ASC(w,x,y,z)	umax_asc((uintmax_t)w,x,y,z)
+#define	OFFT_OCT(w,x,y,z)	umax_oct((uintmax_t)w,x,y,z)
+#define	STRTOOFFT(x,y,z)	strtoimax(x,y,z)
+#define	OFFT_MAX		INTMAX_MAX
+
+#define TOP_HALF	0xffffffff00000000ULL
+#define BOTTOM_HALF	0x00000000ffffffffULL
+

Index: src/bin/pax/tar.c
diff -u src/bin/pax/tar.c:1.69 src/bin/pax/tar.c:1.70
--- src/bin/pax/tar.c:1.69	Tue Mar 20 14:42:28 2012
+++ src/bin/pax/tar.c	Thu Aug  9 04:09:22 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: tar.c,v 1.69 2012/03/20 18:42:28 matt Exp $	*/
+/*	$NetBSD: tar.c,v 1.70 2012/08/09 08:09:22 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)tar.c	8.2 (Berkeley) 4/18/94";
 #else
-__RCSID("$NetBSD: tar.c,v 1.69 2012/03/20 18:42:28 matt Exp $");
+__RCSID("$NetBSD: tar.c,v 1.70 2012/08/09 08:09:22 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -70,12 +70,10 @@ __RCSID("$NetBSD: tar.c,v 1.69 2012/03/2
 
 static int expandname(char *, size_t,  char **, size_t *, const char *, size_t);
 static void longlink(ARCHD *, int);
-static u_long tar_chksm(char *, int);
+static uint32_t tar_chksm(char *, int);
 static char *name_split(char *, int);
-static int ul_oct(u_long, char *, int, int);
-#if !defined(_LP64)
-static int ull_oct(unsigned long long, char *, int, int);
-#endif
+static int u32_oct(uintmax_t, char *, int, int);
+static int umax_oct(uintmax_t, char *, int, int);
 static int tar_gnutar_exclude_one(const char *, size_t);
 static int check_sum(char *, size_t, char *, size_t, int);
 
@@ -111,14 +109,14 @@ char DEV_8[] = "/dev/rst8";
 static int
 check_sum(char *hd, size_t hdlen, char *bl, size_t bllen, int quiet)
 {
-	u_long hdck, blck;
+	uint32_t hdck, blck;
 
-	hdck = asc_ul(hd, hdlen, OCT);
+	hdck = asc_u32(hd, hdlen, OCT);
 	blck = tar_chksm(bl, bllen);
 
 	if (hdck != blck) {
 		if (!quiet)
-			tty_warn(0, "Header checksum %lo does not match %lo",
+			tty_warn(0, "Header checksum %o does not match %o",
 			    hdck, blck);
 		return -1;
 	}
@@ -208,8 +206,8 @@ tar_trail(char *buf, int in_resync, int 
 }
 
 /*
- * ul_oct()
- *	convert an unsigned long to an octal string. many oddball field
+ * u32_oct()
+ *	convert an uintmax_t to an octal string. many oddball field
  *	termination characters are used by the various versions of tar in the
  *	different fields. term selects which kind to use. str is '0' padded
  *	at the front to len. we are unable to use only one format as many old
@@ -219,9 +217,16 @@ tar_trail(char *buf, int in_resync, int 
  */
 
 static int
-ul_oct(u_long val, char *str, int len, int term)
+u32_oct(uintmax_t val, char *str, int len, int term)
 {
 	char *pt;
+	uint64_t p;
+
+	p = val & TOP_HALF;
+	if (p && p != TOP_HALF)
+		return -1;
+
+	val &= BOTTOM_HALF;
 
 	/*
 	 * term selects the appropriate character(s) for the end of the string
@@ -250,20 +255,19 @@ ul_oct(u_long val, char *str, int len, i
 	 */
 	while (pt >= str) {
 		*pt-- = '0' + (char)(val & 0x7);
-		if ((val = val >> 3) == (u_long)0)
+		if ((val = val >> 3) == 0)
 			break;
 	}
 
 	while (pt >= str)
 		*pt-- = '0';
-	if (val != (u_long)0)
+	if (val != 0)
 		return -1;
 	return 0;
 }
 
-#if !defined(_LP64)
 /*
- * ull_oct()
+ * umax_oct()
  *	convert an unsigned long long to an octal string. one of many oddball
  *	field termination characters are used by the various versions of tar
  *	in the different fields. term selects which kind to use. str is '0'
@@ -274,7 +278,7 @@ ul_oct(u_long val, char *str, int len, i
  */
 
 static int
-ull_oct(unsigned long long val, char *str, int len, int term)
+umax_oct(uintmax_t val, char *str, int len, int term)
 {
 	char *pt;
 
@@ -311,11 +315,10 @@ ull_oct(unsigned long long val, char *st
 
 	while (pt >= str)
 		*pt-- = '0';
-	if (val != (unsigned long long)0)
+	if (val != 0)
 		return -1;
 	return 0;
 }
-#endif
 
 /*
  * tar_chksm()
@@ -327,12 +330,12 @@ ull_oct(unsigned long long val, char *st
  *	unsigned long checksum
  */
 
-static u_long
+static uint32_t
 tar_chksm(char *blk, int len)
 {
 	char *stop;
 	char *pt;
-	u_long chksm = BLNKSUM;	/* initial value is checksum field sum */
+	uint32_t chksm = BLNKSUM;	/* initial value is checksum field sum */
 
 	/*
 	 * add the part of the block before the checksum field
@@ -340,7 +343,7 @@ tar_chksm(char *blk, int len)
 	pt = blk;
 	stop = blk + CHK_OFFSET;
 	while (pt < stop)
-		chksm += (u_long)(*pt++ & 0xff);
+		chksm += (uint32_t)(*pt++ & 0xff);
 	/*
 	 * move past the checksum field and keep going, spec counts the
 	 * checksum field as the sum of 8 blanks (which is pre-computed as
@@ -351,7 +354,7 @@ tar_chksm(char *blk, int len)
 	pt += CHK_LEN;
 	stop = blk + len;
 	while (pt < stop)
-		chksm += (u_long)(*pt++ & 0xff);
+		chksm += (uint32_t)(*pt++ & 0xff);
 	return chksm;
 }
 
@@ -476,12 +479,12 @@ tar_rd(ARCHD *arcn, char *buf)
 		    &gnu_link_string, &gnu_link_length, hd->linkname,
 		    sizeof(hd->linkname));
 	}
-	arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode,sizeof(hd->mode),OCT) &
+	arcn->sb.st_mode = (mode_t)(asc_u32(hd->mode,sizeof(hd->mode),OCT) &
 	    0xfff);
-	arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT);
-	arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT);
+	arcn->sb.st_uid = (uid_t)asc_u32(hd->uid, sizeof(hd->uid), OCT);
+	arcn->sb.st_gid = (gid_t)asc_u32(hd->gid, sizeof(hd->gid), OCT);
 	arcn->sb.st_size = (off_t)ASC_OFFT(hd->size, sizeof(hd->size), OCT);
-	arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT);
+	arcn->sb.st_mtime = (time_t)(int32_t)asc_u32(hd->mtime, sizeof(hd->mtime), OCT);
 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
 
 	/*
@@ -571,7 +574,7 @@ tar_rd(ARCHD *arcn, char *buf)
  * tar_wr()
  *	write a tar header for the file specified in the ARCHD to the archive.
  *	Have to check for file types that cannot be stored and file names that
- *	are too long. Be careful of the term (last arg) to ul_oct, each field
+ *	are too long. Be careful of the term (last arg) to u32_oct, each field
  *	of tar has it own spec for the termination character(s).
  *	ASSUMED: space after header in header block is zero filled
  * Return:
@@ -658,7 +661,7 @@ tar_wr(ARCHD *arcn)
 		 */
 		hd->linkflag = AREGTYPE;
 		hd->name[len-1] = '/';
-		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
+		if (u32_oct((uintmax_t)0L, hd->size, sizeof(hd->size), 1))
 			goto out;
 	} else if (arcn->type == PAX_SLK) {
 		/*
@@ -666,7 +669,7 @@ tar_wr(ARCHD *arcn)
 		 */
 		hd->linkflag = SYMTYPE;
 		strlcpy(hd->linkname, arcn->ln_name, sizeof(hd->linkname));
-		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
+		if (u32_oct((uintmax_t)0L, hd->size, sizeof(hd->size), 1))
 			goto out;
 	} else if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) {
 		/*
@@ -674,7 +677,7 @@ tar_wr(ARCHD *arcn)
 		 */
 		hd->linkflag = LNKTYPE;
 		strlcpy(hd->linkname, arcn->ln_name, sizeof(hd->linkname));
-		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1))
+		if (u32_oct((uintmax_t)0L, hd->size, sizeof(hd->size), 1))
 			goto out;
 	} else {
 		/*
@@ -692,10 +695,10 @@ tar_wr(ARCHD *arcn)
 	/*
 	 * copy those fields that are independent of the type
 	 */
-	if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 0) ||
-	    ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 0) ||
-	    ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 0) ||
-	    ul_oct((u_long)arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 1))
+	if (u32_oct((uintmax_t)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 0) ||
+	    u32_oct((uintmax_t)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 0) ||
+	    u32_oct((uintmax_t)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 0) ||
+	    u32_oct((uintmax_t)arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 1))
 		goto out;
 
 	/*
@@ -703,7 +706,7 @@ tar_wr(ARCHD *arcn)
 	 * 0 tells the caller to now write the file data, 1 says no data needs
 	 * to be written
 	 */
-	if (ul_oct(tar_chksm(hdblk, sizeof(HD_TAR)), hd->chksum,
+	if (u32_oct(tar_chksm(hdblk, sizeof(HD_TAR)), hd->chksum,
 	    sizeof(hd->chksum), 3))
 		goto out;			/* XXX Something's wrong here
 						 * because a zero-byte file can
@@ -850,10 +853,10 @@ ustar_rd(ARCHD *arcn, char *buf)
 	 * follow the spec to the letter. we should only have mode bits, strip
 	 * off all other crud we may be passed.
 	 */
-	arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode, sizeof(hd->mode), OCT) &
+	arcn->sb.st_mode = (mode_t)(asc_u32(hd->mode, sizeof(hd->mode), OCT) &
 	    0xfff);
 	arcn->sb.st_size = (off_t)ASC_OFFT(hd->size, sizeof(hd->size), OCT);
-	arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT);
+	arcn->sb.st_mtime = (time_t)(int32_t)asc_u32(hd->mtime, sizeof(hd->mtime), OCT);
 	arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime;
 
 	/*
@@ -864,10 +867,10 @@ ustar_rd(ARCHD *arcn, char *buf)
 	 */
 	hd->gname[sizeof(hd->gname) - 1] = '\0';
 	if (gid_from_group(hd->gname, &(arcn->sb.st_gid)) < 0)
-		arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT);
+		arcn->sb.st_gid = (gid_t)asc_u32(hd->gid, sizeof(hd->gid), OCT);
 	hd->uname[sizeof(hd->uname) - 1] = '\0';
 	if (uid_from_user(hd->uname, &(arcn->sb.st_uid)) < 0)
-		arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT);
+		arcn->sb.st_uid = (uid_t)asc_u32(hd->uid, sizeof(hd->uid), OCT);
 
 	/*
 	 * set the defaults, these may be changed depending on the file type
@@ -909,8 +912,8 @@ ustar_rd(ARCHD *arcn, char *buf)
 			arcn->type = PAX_CHR;
 			arcn->sb.st_mode |= S_IFCHR;
 		}
-		devmajor = (dev_t)asc_ul(hd->devmajor,sizeof(hd->devmajor),OCT);
-		devminor = (dev_t)asc_ul(hd->devminor,sizeof(hd->devminor),OCT);
+		devmajor = (dev_t)asc_u32(hd->devmajor,sizeof(hd->devmajor),OCT);
+		devminor = (dev_t)asc_u32(hd->devminor,sizeof(hd->devminor),OCT);
 		arcn->sb.st_rdev = TODEV(devmajor, devminor);
 		break;
 	case SYMTYPE:
@@ -1012,7 +1015,7 @@ longlink(ARCHD *arcn, int type)
  * ustar_wr()
  *	write a ustar header for the file specified in the ARCHD to the archive
  *	Have to check for file types that cannot be stored and file names that
- *	are too long. Be careful of the term (last arg) to ul_oct, we only use
+ *	are too long. Be careful of the term (last arg) to u32_oct, we only use
  *	'\0' for the termination character (this is different than picky tar)
  *	ASSUMED: space after header in header block is zero filled
  * Return:
@@ -1116,7 +1119,7 @@ ustar_wr(ARCHD *arcn)
 	switch(arcn->type) {
 	case PAX_DIR:
 		hd->typeflag = DIRTYPE;
-		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
+		if (u32_oct((uintmax_t)0L, hd->size, sizeof(hd->size), 3))
 			return size_err("DIRTYPE", arcn);
 		break;
 	case PAX_CHR:
@@ -1125,16 +1128,16 @@ ustar_wr(ARCHD *arcn)
 			hd->typeflag = CHRTYPE;
 		else
 			hd->typeflag = BLKTYPE;
-		if (ul_oct((u_long)MAJOR(arcn->sb.st_rdev), hd->devmajor,
+		if (u32_oct((uintmax_t)MAJOR(arcn->sb.st_rdev), hd->devmajor,
 		   sizeof(hd->devmajor), 3) ||
-		   ul_oct((u_long)MINOR(arcn->sb.st_rdev), hd->devminor,
+		   u32_oct((uintmax_t)MINOR(arcn->sb.st_rdev), hd->devminor,
 		   sizeof(hd->devminor), 3) ||
-		   ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
+		   u32_oct((uintmax_t)0L, hd->size, sizeof(hd->size), 3))
 			return size_err("DEVTYPE", arcn);
 		break;
 	case PAX_FIF:
 		hd->typeflag = FIFOTYPE;
-		if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3))
+		if (u32_oct((uintmax_t)0L, hd->size, sizeof(hd->size), 3))
 			return size_err("FIFOTYPE", arcn);
 		break;
 	case PAX_GLL:
@@ -1148,7 +1151,7 @@ ustar_wr(ARCHD *arcn)
 		else
 			hd->typeflag = LNKTYPE;
 		strlcpy(hd->linkname, arcn->ln_name, sizeof(hd->linkname));
-		if (ul_oct((u_long)gnu_hack_len, hd->size,
+		if (u32_oct((uintmax_t)gnu_hack_len, hd->size,
 		    sizeof(hd->size), 3))
 			return size_err("LINKTYPE", arcn);
 		break;
@@ -1162,7 +1165,7 @@ ustar_wr(ARCHD *arcn)
 		if (arcn->type == PAX_GLF) {
 			hd->typeflag = LONGNAMETYPE;
 			arcn->pad = TAR_PAD(gnu_hack_len);
-			if (OFFT_OCT((u_long)gnu_hack_len, hd->size,
+			if (OFFT_OCT((uint32_t)gnu_hack_len, hd->size,
 			    sizeof(hd->size), 3)) {
 				tty_warn(1,"File is too long for ustar %s",
 				    arcn->org_name);
@@ -1194,13 +1197,13 @@ ustar_wr(ARCHD *arcn)
 	 * set the remaining fields. Some versions want all 16 bits of mode
 	 * we better humor them (they really do not meet spec though)....
 	 */
-	if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3))
+	if (u32_oct((uintmax_t)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 3))
 		return size_err("MODE", arcn);
-	if (ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3))
+	if (u32_oct((uintmax_t)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 3))
 		return size_err("UID", arcn);
-	if (ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3))
+	if (u32_oct((uintmax_t)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 3))
 		return size_err("GID", arcn);
-	if (ul_oct((u_long)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3))
+	if (u32_oct((uintmax_t)arcn->sb.st_mtime,hd->mtime,sizeof(hd->mtime),3))
 		return size_err("MTIME", arcn);
 	user = user_from_uid(arcn->sb.st_uid, 1);
 	group = group_from_gid(arcn->sb.st_gid, 1);
@@ -1212,7 +1215,7 @@ ustar_wr(ARCHD *arcn)
 	 * return 0 tells the caller to now write the file data, 1 says no data
 	 * needs to be written
 	 */
-	if (ul_oct(tar_chksm(hdblk, sizeof(HD_USTAR)), hd->chksum,
+	if (u32_oct(tar_chksm(hdblk, sizeof(HD_USTAR)), hd->chksum,
 	   sizeof(hd->chksum), 3))
 		return size_err("CHKSUM", arcn);
 	if (wr_rdbuf(hdblk, sizeof(HD_USTAR)) < 0)

Reply via email to