PERFORCE change 118181 for review

Matt Jacob mjacob at FreeBSD.org
Sun Apr 15 17:15:12 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=118181

Change 118181 by mjacob at mjexp on 2007/04/15 17:14:35

	IFC

Affected files ...

.. //depot/projects/mjexp/lib/libarchive/Makefile#9 integrate
.. //depot/projects/mjexp/lib/libarchive/archive.h.in#10 integrate
.. //depot/projects/mjexp/lib/libarchive/archive_platform.h#6 integrate
.. //depot/projects/mjexp/lib/libarchive/archive_read_extract.c#8 integrate
.. //depot/projects/mjexp/lib/libarchive/archive_read_support_format_ar.c#3 integrate
.. //depot/projects/mjexp/lib/libarchive/archive_read_support_format_tar.c#9 integrate
.. //depot/projects/mjexp/lib/libarchive/archive_read_support_format_zip.c#5 integrate
.. //depot/projects/mjexp/lib/libarchive/archive_write_disk.c#6 integrate
.. //depot/projects/mjexp/lib/libarchive/archive_write_set_compression_none.c#6 integrate
.. //depot/projects/mjexp/lib/libarchive/archive_write_set_format_ar.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/archive_write_set_format_by_name.c#4 integrate
.. //depot/projects/mjexp/lib/libarchive/config_freebsd.h#4 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_acl_basic.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_acl_pax.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_read_data_large.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_read_extract.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_read_format_ar.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_read_large.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_read_position.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_read_truncated.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_tar_filenames.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_write_disk_perms.c#3 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_write_disk_secure.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_write_format_ar.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_write_format_tar.c#2 integrate
.. //depot/projects/mjexp/lib/libarchive/test/test_write_open_memory.c#2 integrate
.. //depot/projects/mjexp/sys/cam/cam_ccb.h#4 integrate
.. //depot/projects/mjexp/sys/cam/cam_periph.c#4 integrate
.. //depot/projects/mjexp/sys/cam/cam_periph.h#2 integrate
.. //depot/projects/mjexp/sys/cam/cam_sim.c#2 integrate
.. //depot/projects/mjexp/sys/cam/cam_sim.h#2 integrate
.. //depot/projects/mjexp/sys/cam/cam_xpt.c#8 integrate
.. //depot/projects/mjexp/sys/cam/cam_xpt.h#5 integrate
.. //depot/projects/mjexp/sys/cam/cam_xpt_periph.h#2 integrate
.. //depot/projects/mjexp/sys/cam/scsi/scsi_cd.c#3 integrate
.. //depot/projects/mjexp/sys/cam/scsi/scsi_ch.c#3 integrate
.. //depot/projects/mjexp/sys/cam/scsi/scsi_da.c#7 integrate
.. //depot/projects/mjexp/sys/cam/scsi/scsi_low.c#4 integrate
.. //depot/projects/mjexp/sys/cam/scsi/scsi_pass.c#3 integrate
.. //depot/projects/mjexp/sys/cam/scsi/scsi_pt.c#3 integrate
.. //depot/projects/mjexp/sys/cam/scsi/scsi_sa.c#3 integrate
.. //depot/projects/mjexp/sys/cam/scsi/scsi_ses.c#3 integrate
.. //depot/projects/mjexp/sys/cam/scsi/scsi_sg.c#3 integrate
.. //depot/projects/mjexp/sys/cam/scsi/scsi_targ_bh.c#3 integrate
.. //depot/projects/mjexp/sys/cam/scsi/scsi_target.c#4 integrate
.. //depot/projects/mjexp/sys/compat/linprocfs/linprocfs.c#10 integrate
.. //depot/projects/mjexp/sys/contrib/opensolaris/uts/common/fs/dnlc.c#3 integrate
.. //depot/projects/mjexp/sys/dev/aac/aac_cam.c#5 integrate
.. //depot/projects/mjexp/sys/dev/advansys/advansys.c#5 integrate
.. //depot/projects/mjexp/sys/dev/advansys/adwcam.c#6 integrate
.. //depot/projects/mjexp/sys/dev/aha/aha.c#5 integrate
.. //depot/projects/mjexp/sys/dev/ahb/ahb.c#7 integrate
.. //depot/projects/mjexp/sys/dev/aic/aic.c#4 integrate
.. //depot/projects/mjexp/sys/dev/aic7xxx/aic79xx_osm.c#4 integrate
.. //depot/projects/mjexp/sys/dev/aic7xxx/aic7xxx_osm.c#4 integrate
.. //depot/projects/mjexp/sys/dev/amd/amd.c#6 integrate
.. //depot/projects/mjexp/sys/dev/amr/amr_cam.c#4 integrate
.. //depot/projects/mjexp/sys/dev/arcmsr/arcmsr.c#10 integrate
.. //depot/projects/mjexp/sys/dev/asr/asr.c#6 integrate
.. //depot/projects/mjexp/sys/dev/ata/atapi-cam.c#6 integrate
.. //depot/projects/mjexp/sys/dev/buslogic/bt.c#5 integrate
.. //depot/projects/mjexp/sys/dev/ciss/ciss.c#6 integrate
.. //depot/projects/mjexp/sys/dev/cxgb/sys/uipc_mvec.c#4 integrate
.. //depot/projects/mjexp/sys/dev/dpt/dpt_scsi.c#5 integrate
.. //depot/projects/mjexp/sys/dev/esp/ncr53c9x.c#4 integrate
.. //depot/projects/mjexp/sys/dev/firewire/sbp.c#6 integrate
.. //depot/projects/mjexp/sys/dev/firewire/sbp_targ.c#3 integrate
.. //depot/projects/mjexp/sys/dev/hptmv/entry.c#5 integrate
.. //depot/projects/mjexp/sys/dev/iir/iir.c#4 integrate
.. //depot/projects/mjexp/sys/dev/isp/isp_freebsd.c#16 integrate
.. //depot/projects/mjexp/sys/dev/mly/mly.c#6 integrate
.. //depot/projects/mjexp/sys/dev/mpt/mpt_cam.c#16 integrate
.. //depot/projects/mjexp/sys/dev/ppbus/vpo.c#3 integrate
.. //depot/projects/mjexp/sys/dev/rr232x/osm_bsd.c#3 integrate
.. //depot/projects/mjexp/sys/dev/sym/sym_hipd.c#6 integrate
.. //depot/projects/mjexp/sys/dev/trm/trm.c#6 integrate
.. //depot/projects/mjexp/sys/dev/twa/tw_osl_cam.c#4 integrate
.. //depot/projects/mjexp/sys/dev/usb/umass.c#7 integrate
.. //depot/projects/mjexp/sys/dev/wds/wd7000.c#4 integrate
.. //depot/projects/mjexp/sys/fs/procfs/procfs_dbregs.c#2 integrate
.. //depot/projects/mjexp/sys/fs/procfs/procfs_fpregs.c#2 integrate
.. //depot/projects/mjexp/sys/fs/procfs/procfs_regs.c#2 integrate
.. //depot/projects/mjexp/sys/netinet/sctp_output.c#9 integrate
.. //depot/projects/mjexp/sys/netinet/sctp_structs.h#8 integrate
.. //depot/projects/mjexp/sys/netinet/sctp_uio.h#8 integrate
.. //depot/projects/mjexp/sys/netinet/sctp_var.h#7 integrate
.. //depot/projects/mjexp/sys/netinet/sctputil.h#6 integrate
.. //depot/projects/mjexp/sys/nfsserver/nfs_srvsock.c#4 integrate
.. //depot/projects/mjexp/sys/pci/ncr.c#5 integrate
.. //depot/projects/mjexp/sys/sys/proc.h#12 integrate

Differences ...

==== //depot/projects/mjexp/lib/libarchive/Makefile#9 (text+ko) ====

@@ -1,4 +1,4 @@
-# $FreeBSD: src/lib/libarchive/Makefile,v 1.68 2007/04/14 18:24:42 kientzle Exp $
+# $FreeBSD: src/lib/libarchive/Makefile,v 1.70 2007/04/15 00:53:38 kientzle Exp $
 
 LIB=	archive
 DPADD=	${LIBBZ2} ${LIBZ}
@@ -9,7 +9,7 @@
 #  Major: Bumped ONLY when API/ABI breakage happens (see SHLIB_MAJOR)
 #  Minor: Bumped when significant new features are added
 #  Revision: Bumped on any notable change
-VERSION= 2.0.30
+VERSION= 2.0.31
 
 ARCHIVE_API_MAJOR!=	echo ${VERSION} | sed -e 's/[^0-9]/./g' -e 's/\..*//'
 ARCHIVE_API_MINOR!=	echo ${VERSION} | sed -e 's/[^0-9]/./g' -e 's/[0-9]*\.//' -e 's/\..*//'
@@ -59,6 +59,7 @@
 	archive_read_support_compression_gzip.c		\
 	archive_read_support_compression_none.c		\
 	archive_read_support_format_all.c		\
+	archive_read_support_format_ar.c		\
 	archive_read_support_format_cpio.c		\
 	archive_read_support_format_empty.c		\
 	archive_read_support_format_iso9660.c		\

==== //depot/projects/mjexp/lib/libarchive/archive.h.in#10 (text+ko) ====

@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libarchive/archive.h.in,v 1.41 2007/04/03 05:34:36 kientzle Exp $
+ * $FreeBSD: src/lib/libarchive/archive.h.in,v 1.42 2007/04/14 22:34:10 kientzle Exp $
  */
 
 #ifndef ARCHIVE_H_INCLUDED
@@ -178,7 +178,7 @@
 #define	ARCHIVE_FORMAT_ZIP			0x50000
 #define	ARCHIVE_FORMAT_EMPTY			0x60000
 #define	ARCHIVE_FORMAT_AR			0x70000
-#define	ARCHIVE_FORMAT_AR_SVR4			(ARCHIVE_FORMAT_AR | 1)
+#define	ARCHIVE_FORMAT_AR_GNU			(ARCHIVE_FORMAT_AR | 1)
 #define	ARCHIVE_FORMAT_AR_BSD			(ARCHIVE_FORMAT_AR | 2)
 
 /*-

==== //depot/projects/mjexp/lib/libarchive/archive_platform.h#6 (text+ko) ====

@@ -22,7 +22,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libarchive/archive_platform.h,v 1.25 2007/04/12 04:44:21 kientzle Exp $
+ * $FreeBSD: src/lib/libarchive/archive_platform.h,v 1.26 2007/04/15 00:53:38 kientzle Exp $
  */
 
 /*
@@ -67,6 +67,23 @@
 #include <stdint.h>
 #endif
 
+/* Some platforms lack the standard *_MAX definitions. */
+#if !HAVE_DECL_SIZE_MAX
+#define	SIZE_MAX (~(size_t)0)
+#endif
+#if !HAVE_DECL_UINT32_MAX
+#define	UINT32_MAX (~(uint32_t)0)
+#endif
+#if !HAVE_DECL_UINT64_MAX
+#define	UINT64_MAX (~(uint64_t)0)
+#endif
+#if !HAVE_DECL_INT64_MAX
+#define	INT64_MAX ((int64_t)(UINT64_MAX >> 1))
+#endif
+#if !HAVE_DECL_INT64_MIN
+#define	INT64_MIN ((int64_t)(~INT64_MAX))
+#endif
+
 /*
  * If this platform has <sys/acl.h>, acl_create(), acl_init(),
  * acl_set_file(), and ACL_USER, we assume it has the rest of the

==== //depot/projects/mjexp/lib/libarchive/archive_read_extract.c#8 (text+ko) ====

@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.55 2007/04/07 03:37:59 cperciva Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_extract.c,v 1.57 2007/04/15 01:01:20 kientzle Exp $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -95,8 +95,13 @@
 	archive_write_disk_set_skip_file(a->extract->ad,
 	    a->skip_file_dev, a->skip_file_ino);
 	r = archive_write_header(a->extract->ad, entry);
-	if (r == ARCHIVE_OK)
-		/* If there's an FD, pour data into it. */
+	if (r != ARCHIVE_OK)
+		/* If _write_header failed, copy the error. */
+		archive_set_error(&a->archive,
+		    archive_errno(extract->ad),
+		    "%s", archive_error_string(extract->ad));
+	else
+		/* Otherwise, pour data into the entry. */
 		r = copy_data(_a, a->extract->ad);
 	r2 = archive_write_finish_entry(a->extract->ad);
 	/* Use the first message. */

==== //depot/projects/mjexp/lib/libarchive/archive_read_support_format_ar.c#3 (text+ko) ====

@@ -26,8 +26,11 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_ar.c,v 1.3 2007/04/14 08:42:50 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_ar.c,v 1.5 2007/04/15 00:53:38 kientzle Exp $");
 
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
 #endif
@@ -70,16 +73,6 @@
 #define AR_fmag_offset 58
 #define AR_fmag_size 2
 
-/*
- * "ar" magic numbers.
- */
-#define	ARMAG		"!<arch>\n"
-#define	SARMAG		8		/* strlen(ARMAG); */
-#define	AR_EFMT1	"#1/"
-#define	SAR_EFMT1	3		/* strlen(AR_EFMT1); */
-#define	ARFMAG		"`\n"
-#define	SARFMAG		2		/* strlen(ARFMAG); */
-
 #define isdigit(x)	(x) >= '0' && (x) <= '9'
 
 static int	archive_read_format_ar_bid(struct archive_read *a);
@@ -89,32 +82,12 @@
 static int	archive_read_format_ar_skip(struct archive_read *a);
 static int	archive_read_format_ar_read_header(struct archive_read *a,
 		    struct archive_entry *e);
-static int64_t	ar_atol8(const char *p, unsigned char_cnt);
-static int64_t	ar_atol10(const char *p, unsigned char_cnt);
-static int	ar_parse_string_table(struct archive_read *, struct ar *,
+static uint64_t	ar_atol8(const char *p, unsigned char_cnt);
+static uint64_t	ar_atol10(const char *p, unsigned char_cnt);
+static int	ar_parse_gnu_filename_table(struct archive_read *, struct ar *,
 		    const void *, size_t);
-
-/*
- * ANSI C99 defines constants for these, but not everyone supports
- * those constants, so I define a couple of static variables here and
- * compute the values.  These calculations should be portable to any
- * 2s-complement architecture.
- */
-#ifdef UINT64_MAX
-static const uint64_t max_uint64 = UINT64_MAX;
-#else
-static const uint64_t max_uint64 = ~(uint64_t)0;
-#endif
-#ifdef INT64_MAX
-static const int64_t max_int64 = INT64_MAX;
-#else
-static const int64_t max_int64 = (int64_t)((~(uint64_t)0) >> 1);
-#endif
-#ifdef INT64_MIN
-static const int64_t min_int64 = INT64_MIN;
-#else
-static const int64_t min_int64 = (int64_t)(~((~(uint64_t)0) >> 1));
-#endif
+static int	ar_parse_common_header(struct ar *ar, struct archive_entry *,
+		    const char *h);
 
 int
 archive_read_support_format_ar(struct archive *_a)
@@ -177,16 +150,15 @@
 	if (ar->bid > 0)
 		return (ar->bid);
 
-	bytes_read = (a->compression_read_ahead)(a, &h, SARMAG);
-	if (bytes_read < SARMAG)
-		return (-1);
-
 	/*
-	 * Verify the global header.
+	 * Verify the 8-byte file signature.
 	 * TODO: Do we need to check more than this?
 	 */
-	if (strncmp((const char*)h, ARMAG, SARMAG) == 0) {
-		ar->bid = SARMAG;
+	bytes_read = (a->compression_read_ahead)(a, &h, 8);
+	if (bytes_read < 8)
+		return (-1);
+	if (strncmp((const char*)h, "!<arch>\n", 8) == 0) {
+		ar->bid = 64;
 		return (ar->bid);
 	}
 	return (-1);
@@ -196,199 +168,247 @@
 archive_read_format_ar_read_header(struct archive_read *a,
     struct archive_entry *entry)
 {
-	int r;
-	size_t bsd_append;
-	ssize_t bytes;
-	int64_t nval;
-	size_t tab_size;
-	char *fname, *p;
+	char filename[AR_name_size + 1];
 	struct ar *ar;
+	uint64_t number; /* Used to hold parsed numbers before validation. */
+	ssize_t bytes_read;
+	size_t bsd_name_length, entry_size;
+	char *p;
 	const void *b;
 	const char *h;
+	int r;
 
-	bsd_append = 0;
+	ar = (struct ar*)*(a->pformat_data);
 
-	if (!a->archive.archive_format) {
-		a->archive.archive_format = ARCHIVE_FORMAT_AR;
-		a->archive.archive_format_name = "Unix Archiver";
-	}
-
 	if (a->archive.file_position == 0) {
 		/*
 		 * We are now at the beginning of the archive,
 		 * so we need first consume the ar global header.
 		 */
-		(a->compression_read_consume)(a, SARMAG);
+		(a->compression_read_consume)(a, 8);
+		/* Set a default format code for now. */
+		a->archive.archive_format = ARCHIVE_FORMAT_AR;
 	}
 
-	/* Read 60-byte header */
-	bytes = (a->compression_read_ahead)(a, &b, 60);
-	if (bytes < 60) {
-		/*
-		 * We just encountered an incomplete ar file,
-		 * though the _bid function accepted it.
-		 */
+	/* Read the header for the next file entry. */
+	bytes_read = (a->compression_read_ahead)(a, &b, 60);
+	if (bytes_read < 60) {
+		/* Broken header. */
 		return (ARCHIVE_EOF);
 	}
 	(a->compression_read_consume)(a, 60);
-
 	h = (const char *)b;
 
-	/* Consistency check */
-	if (strncmp(h + AR_fmag_offset, ARFMAG, SARFMAG) != 0) {
+	/* Verify the magic signature on the file header. */
+	if (strncmp(h + AR_fmag_offset, "`\n", 2) != 0) {
 		archive_set_error(&a->archive, EINVAL,
 		    "Consistency check failed");
 		return (ARCHIVE_WARN);
 	}
 
-	ar = (struct ar*)*(a->pformat_data);
+	/* Copy filename into work buffer. */
+	strncpy(filename, h + AR_name_offset, AR_name_size);
+	filename[AR_name_size] = '\0';
 
-	if (strncmp(h + AR_name_offset, "//", 2) == 0) {
+	/*
+	 * Guess the format variant based on the filename.
+	 */
+	if (a->archive.archive_format == ARCHIVE_FORMAT_AR) {
+		/* We don't already know the variant, so let's guess. */
+		/*
+		 * Biggest clue is presence of '/': GNU starts special
+		 * filenames with '/', appends '/' as terminator to
+		 * non-special names, so anything with '/' should be
+		 * GNU except for BSD long filenames.
+		 */
+		if (strncmp(filename, "#1/", 3) == 0)
+			a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD;
+		else if (strchr(filename, '/') != NULL)
+			a->archive.archive_format = ARCHIVE_FORMAT_AR_GNU;
+		else if (strncmp(filename, "__.SYMDEF", 9) == 0)
+			a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD;
 		/*
-		 * An archive member with ar_name "//" is an archive
-		 * string table.
+		 * XXX Do GNU/SVR4 'ar' programs ever omit trailing '/'
+		 * if name exactly fills 16-byte field?  If so, we
+		 * can't assume entries without '/' are BSD. XXX
 		 */
-		nval = ar_atol10(h + AR_size_offset, AR_size_size);
-		if (nval < 0 || nval > SIZE_MAX) {
+	}
+
+	/* Update format name from the code. */
+	if (a->archive.archive_format == ARCHIVE_FORMAT_AR_GNU)
+		a->archive.archive_format_name = "ar (GNU/SVR4)";
+	else if (a->archive.archive_format == ARCHIVE_FORMAT_AR_BSD)
+		a->archive.archive_format_name = "ar (BSD)";
+	else
+		a->archive.archive_format_name = "ar";
+
+	/*
+	 * Remove trailing spaces from the filename.  GNU and BSD
+	 * variants both pad filename area out with spaces.
+	 * This will only be wrong if GNU/SVR4 'ar' implementations
+	 * omit trailing '/' for 16-char filenames and we have
+	 * a 16-char filename that ends in ' '.
+	 */
+	p = filename + AR_name_size - 1;
+	while (p >= filename && *p == ' ') {
+		*p = '\0';
+		p--;
+	}
+
+	/*
+	 * Remove trailing slash unless first character is '/'.
+	 * (BSD entries never end in '/', so this will only trim
+	 * GNU-format entries.  GNU special entries start with '/'
+	 * and are not terminated in '/', so we don't trim anything
+	 * that starts with '/'.)
+	 */
+	if (filename[0] != '/' && *p == '/')
+		*p = '\0';
+
+	/*
+	 * '//' is the GNU filename table.
+	 * Later entries can refer to names in this table.
+	 */
+	if (strcmp(filename, "//") == 0) {
+		/* This must come before any call to _read_ahead. */
+		ar_parse_common_header(ar, entry, h);
+		archive_entry_copy_pathname(entry, filename);
+		archive_entry_set_mode(entry,
+		    S_IFREG | (archive_entry_mode(entry) & 0777));
+		/* Get the size of the filename table. */
+		number = ar_atol10(h + AR_size_offset, AR_size_size);
+		if (number > SIZE_MAX) {
 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-			    "String table too large");
+			    "Filename table too large");
 			return (ARCHIVE_FATAL);
 		}
-		tab_size = (size_t)nval;
-		bytes = (a->compression_read_ahead)(a, &b, tab_size);
-		if (bytes <= 0)
+		entry_size = (size_t)number;
+		/* Read the filename table into memory. */
+		bytes_read = (a->compression_read_ahead)(a, &b, entry_size);
+		if (bytes_read <= 0)
 			return (ARCHIVE_FATAL);
-		if (bytes < nval) {
+		if ((size_t)bytes_read < entry_size) {
 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 			    "Truncated input file");
 			return (ARCHIVE_FATAL);
 		}
+		/*
+		 * Don't consume the contents, so the client will
+		 * also get a shot at reading it.
+		 */
 
-		r = ar_parse_string_table(a, ar, b, tab_size);
-		if (r == ARCHIVE_OK) {
-			/*
-			 * Archive string table only have ar_name and ar_size fileds
-			 * in its header.
-			 */
-			archive_entry_copy_pathname(entry, "//");
-			h = (const char *)b;
-			nval = ar_atol10(h + AR_size_offset, AR_size_size);
-			archive_entry_set_size(entry, nval);
-
-			ar->entry_offset = 0;
-			ar->entry_bytes_remaining = nval;
-			ar->entry_padding = ar->entry_bytes_remaining % 2;
-		}
-		return (r);
+		/* Parse the filename table. */
+		return (ar_parse_gnu_filename_table(a, ar, b, entry_size));
 	}
 
-	if (h[AR_name_offset] == '/' && isdigit(h[AR_name_offset + 1])) {
+	/*
+	 * GNU variant handles long filenames by storing /<number>
+	 * to indicate a name stored in the filename table.
+	 */
+	if (filename[0] == '/' && isdigit(filename[1])) {
+		number = ar_atol10(h + AR_name_offset + 1, AR_name_size - 1);
 		/*
-		 * Archive member is common format with SVR4/GNU variant.
-		 * "/" followed by one or more digit(s) in the ar_name
-		 * filed indicates an index to the string table.
+		 * If we can't look up the real name, warn and return
+		 * the entry with the wrong name.
 		 */
-		if (ar->strtab == NULL) {
+		if (ar->strtab == NULL || number > ar->strtab_size) {
 			archive_set_error(&a->archive, EINVAL,
-			    "String table does not exist");
+			    "Can't find long filename for entry");
+			archive_entry_copy_pathname(entry, filename);
+			/* Parse the time, owner, mode, size fields. */
+			ar_parse_common_header(ar, entry, h);
 			return (ARCHIVE_WARN);
 		}
 
-		nval = ar_atol10(h + AR_name_offset + 1, AR_name_size - 1);
-		if (nval < 0 || nval > ar->strtab_size) {
-			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-			    "String table overflow");
-			return (ARCHIVE_FATAL);
-		}
-		archive_entry_copy_pathname(entry, &ar->strtab[(size_t)nval]);
-		goto remain;
+		archive_entry_copy_pathname(entry, &ar->strtab[(size_t)number]);
+		/* Parse the time, owner, mode, size fields. */
+		return (ar_parse_common_header(ar, entry, h));
 	}
 
-	if (strncmp(h + AR_name_offset, AR_EFMT1, SAR_EFMT1) == 0) {
-		/*
-		 * Archive member is common format with BSD variant.
-		 * AR_EFMT1 is followed by one or more digit(s) indicating
-		 * the length of the real filename which is appended
-		 * to the header.
-		 */
-		nval = ar_atol10(h + AR_name_offset + SAR_EFMT1,
-		    AR_name_size - SAR_EFMT1);
-		if (nval < 0 || nval >= SIZE_MAX) {
+	/*
+	 * BSD handles long filenames by storing "#1/" followed by the
+	 * length of filename as a decimal number, then prepends the
+	 * the filename to the file contents.
+	 */
+	if (strncmp(filename, "#1/", 3) == 0) {
+		/* Parse the time, owner, mode, size fields. */
+		/* This must occur before _read_ahead is called again. */
+		ar_parse_common_header(ar, entry, h);
+
+		/* Parse the size of the name, adjust the file size. */
+		number = ar_atol10(h + AR_name_offset + 3, AR_name_size - 3);
+		if ((off_t)number > ar->entry_bytes_remaining) {
 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 			    "Bad input file size");
 			return (ARCHIVE_FATAL);
 		}
-		bsd_append = (size_t)nval;
-		bytes = (a->compression_read_ahead)(a, &b, bsd_append);
-		if (bytes <= 0)
+		bsd_name_length = (size_t)number;
+		ar->entry_bytes_remaining -= bsd_name_length;
+		/* Adjust file size reported to client. */
+		archive_entry_set_size(entry, ar->entry_bytes_remaining);
+
+		/* Read the long name into memory. */
+		bytes_read = (a->compression_read_ahead)(a, &b, bsd_name_length);
+		if (bytes_read <= 0)
 			return (ARCHIVE_FATAL);
-		if (bytes < nval) {
+		if ((size_t)bytes_read < bsd_name_length) {
 			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 			    "Truncated input file");
 			return (ARCHIVE_FATAL);
 		}
+		(a->compression_read_consume)(a, bsd_name_length);
 
-		(a->compression_read_consume)(a, bsd_append);
-
-		fname = (char *)malloc(bsd_append + 1);
-		if (fname == NULL) {
+		/* Store it in the entry. */
+		p = (char *)malloc(bsd_name_length + 1);
+		if (p == NULL) {
 			archive_set_error(&a->archive, ENOMEM,
 			    "Can't allocate fname buffer");
 			return (ARCHIVE_FATAL);
 		}
-		strncpy(fname, b, bsd_append);
-		fname[bsd_append] = '\0';
-		archive_entry_copy_pathname(entry, fname);
-		free(fname);
-		fname = NULL;
-
-		goto remain;
+		strncpy(p, b, bsd_name_length);
+		p[bsd_name_length] = '\0';
+		archive_entry_copy_pathname(entry, p);
+		free(p);
+		return (ARCHIVE_OK);
 	}
 
 	/*
-	 * "/" followed by one or more spaces indicate a
-	 * SVR4/GNU archive symbol table.
-	 *
+	 * "/" is the SVR4/GNU archive symbol table.
 	 */
-	if (strncmp(h + AR_name_offset, "/ ", 2) == 0) {
+	if (strcmp(filename, "/") == 0) {
 		archive_entry_copy_pathname(entry, "/");
-		goto remain;
+		/* Parse the time, owner, mode, size fields. */
+		r = ar_parse_common_header(ar, entry, h);
+		/* Force the file type to a regular file. */
+		archive_entry_set_mode(entry,
+		    S_IFREG | (archive_entry_mode(entry) & 0777));
+		return (r);
 	}
+
 	/*
-	 * "__.SYMDEF" indicates a BSD archive symbol table.
+	 * "__.SYMDEF" is a BSD archive symbol table.
 	 */
-	if (strncmp(h + AR_name_offset, "__.SYMDEF", 9) == 0) {
-		archive_entry_copy_pathname(entry, "__.SYMDEF");
-		goto remain;
+	if (strcmp(filename, "__.SYMDEF") == 0) {
+		archive_entry_copy_pathname(entry, filename);
+		/* Parse the time, owner, mode, size fields. */
+		return (ar_parse_common_header(ar, entry, h));
 	}
 
 	/*
-	 * Otherwise, the ar_name fields stores the real
-	 * filename.
-	 * SVR4/GNU variant append a '/' to mark the end of
-	 * filename, while BSD variant use a space.
+	 * Otherwise, this is a standard entry.  The filename
+	 * has already been trimmed as much as possible, based
+	 * on our current knowledge of the format.
 	 */
-	fname = (char *)malloc(AR_name_size + 1);
-	strncpy(fname, h + AR_name_offset, AR_name_size);
-	fname[AR_name_size] = '\0';
+	archive_entry_copy_pathname(entry, filename);
+	return (ar_parse_common_header(ar, entry, h));
+}
 
-	if ((p = strchr(fname, '/')) != NULL) {
-		/* SVR4/GNU format */
-		*p = '\0';
-		archive_entry_copy_pathname(entry, fname);
-		free(fname);
-		fname = NULL;
-		goto remain;
-	}
-
-	/* BSD format */
-	if ((p = strchr(fname, ' ')) != NULL)
-		*p = '\0';
-	archive_entry_copy_pathname(entry, fname);
-	free(fname);
-	fname = NULL;
+static int
+ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
+    const char *h)
+{
+	uint64_t n;
 
-remain:
 	/* Copy remaining header */
 	archive_entry_set_mtime(entry,
 	    (time_t)ar_atol10(h + AR_date_offset, AR_date_size), 0L);
@@ -398,28 +418,12 @@
 	    (gid_t)ar_atol10(h + AR_gid_offset, AR_gid_size));
 	archive_entry_set_mode(entry,
 	    (mode_t)ar_atol8(h + AR_mode_offset, AR_mode_size));
-	nval = ar_atol10(h + AR_size_offset, AR_size_size);
+	n = ar_atol10(h + AR_size_offset, AR_size_size);
 
 	ar->entry_offset = 0;
-	ar->entry_padding = nval % 2;
-
-	/*
-	 * For BSD variant, we should subtract the length of
-	 * the appended filename string from ar_size to get the
-	 * real file size. But remember we should do this only
-	 * after we had calculated the padding.
-	 */
-	if (bsd_append > nval) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Truncated input file");
-		return (ARCHIVE_FATAL);
-	}
-	if (bsd_append > 0)
-		nval -= bsd_append;
-
-	archive_entry_set_size(entry, nval);
-	ar->entry_bytes_remaining = nval;
-
+	ar->entry_padding = n % 2;
+	archive_entry_set_size(entry, n);
+	ar->entry_bytes_remaining = n;
 	return (ARCHIVE_OK);
 }
 
@@ -441,7 +445,6 @@
 		}
 		if (bytes_read < 0)
 			return (ARCHIVE_FATAL);
-		/* XXX I don't get this. */
 		if (bytes_read > ar->entry_bytes_remaining)
 			bytes_read = (ssize_t)ar->entry_bytes_remaining;
 		*size = bytes_read;
@@ -496,7 +499,7 @@
 }
 
 static int
-ar_parse_string_table(struct archive_read *a, struct ar *ar,
+ar_parse_gnu_filename_table(struct archive_read *a, struct ar *ar,
     const void *h, size_t size)
 {
 	char *p;
@@ -550,68 +553,53 @@
 	return (ARCHIVE_WARN);
 }
 
-static int64_t
+static uint64_t
 ar_atol8(const char *p, unsigned char_cnt)
 {
-	int64_t	l, limit, last_digit_limit;
-	int digit, sign, base;
+	uint64_t l, limit, last_digit_limit;
+	unsigned int digit, base;
 
 	base = 8;
-	limit = max_int64 / base;
-	last_digit_limit = max_int64 % base;
+	limit = UINT64_MAX / base;
+	last_digit_limit = UINT64_MAX % base;
 
-	while (*p == ' ' || *p == '\t')
+	while ((*p == ' ' || *p == '\t') && char_cnt-- > 0)
 		p++;
-	if (*p == '-') {
-		sign = -1;
-		p++;
-	} else
-		sign = 1;
 
 	l = 0;
 	digit = *p - '0';
-	while (digit >= 0 && digit < base  && char_cnt-- > 0) {
+	while (*p >= '0' && digit < base  && char_cnt-- > 0) {
 		if (l>limit || (l == limit && digit > last_digit_limit)) {
-			l = max_uint64; /* Truncate on overflow. */
+			l = UINT64_MAX; /* Truncate on overflow. */
 			break;
 		}
 		l = (l * base) + digit;
 		digit = *++p - '0';
 	}
-	return (sign < 0) ? -l : l;
+	return (l);
 }
 
-/*
- * XXX This is not really correct for negative numbers,
- * as min_int64_t can never be returned. That one is unused BTW.
- */
-static int64_t
+static uint64_t
 ar_atol10(const char *p, unsigned char_cnt)
 {
-	int64_t l, limit, last_digit_limit;
-	int base, digit, sign;
+	uint64_t l, limit, last_digit_limit;
+	unsigned int base, digit;
 
 	base = 10;
-	limit = max_int64 / base;
-	last_digit_limit = max_int64 % base;
+	limit = UINT64_MAX / base;
+	last_digit_limit = UINT64_MAX % base;
 
-	while (*p == ' ' || *p == '\t')
-		p++;
-	if (*p == '-') {
-		sign = -1;
+	while ((*p == ' ' || *p == '\t') && char_cnt-- > 0)
 		p++;
-	} else
-		sign = 1;
-
 	l = 0;
 	digit = *p - '0';
-	while (digit >= 0 && digit < base  && char_cnt-- > 0) {
+	while (*p >= '0' && digit < base  && char_cnt-- > 0) {
 		if (l > limit || (l == limit && digit > last_digit_limit)) {
-			l = max_uint64; /* Truncate on overflow. */
+			l = UINT64_MAX; /* Truncate on overflow. */
 			break;
 		}
 		l = (l * base) + digit;
 		digit = *++p - '0';
 	}
-	return (sign < 0) ? -l : l;
+	return (l);
 }

==== //depot/projects/mjexp/lib/libarchive/archive_read_support_format_tar.c#9 (text+ko) ====

@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_tar.c,v 1.53 2007/04/12 04:42:57 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_tar.c,v 1.54 2007/04/15 00:53:38 kientzle Exp $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -225,28 +225,6 @@
 static int	utf8_decode(wchar_t *, const char *, size_t length);
 static char	*wide_to_narrow(const wchar_t *wval);
 
-/*
- * ANSI C99 defines constants for these, but not everyone supports
- * those constants, so I define a couple of static variables here and
- * compute the values.  These calculations should be portable to any
- * 2s-complement architecture.
- */
-#ifdef UINT64_MAX
-static const uint64_t max_uint64 = UINT64_MAX;
-#else
-static const uint64_t max_uint64 = ~(uint64_t)0;
-#endif
-#ifdef INT64_MAX
-static const int64_t max_int64 = INT64_MAX;
-#else
-static const int64_t max_int64 = (int64_t)((~(uint64_t)0) >> 1);
-#endif
-#ifdef INT64_MIN
-static const int64_t min_int64 = INT64_MIN;
-#else
-static const int64_t min_int64 = (int64_t)(~((~(uint64_t)0) >> 1));
-#endif
-
 int
 archive_read_support_format_gnutar(struct archive *a)
 {
@@ -1379,8 +1357,8 @@
 	int sign;
 	int64_t limit, last_digit_limit;
 
-	limit = max_int64 / 10;
-	last_digit_limit = max_int64 % 10;
+	limit = INT64_MAX / 10;
+	last_digit_limit = INT64_MAX % 10;
 
 	s = 0;
 	sign = 1;
@@ -1392,7 +1370,7 @@
 		digit = *p - '0';
 		if (s > limit ||
 		    (s == limit && digit > last_digit_limit)) {
-			s = max_uint64;
+			s = UINT64_MAX;
 			break;
 		}
 		s = (s * 10) + digit;
@@ -1593,8 +1571,8 @@
 	int digit, sign, base;
 
 	base = 8;
-	limit = max_int64 / base;
-	last_digit_limit = max_int64 % base;
+	limit = INT64_MAX / base;
+	last_digit_limit = INT64_MAX % base;
 
 	while (*p == ' ' || *p == '\t')
 		p++;
@@ -1608,7 +1586,7 @@
 	digit = *p - '0';
 	while (digit >= 0 && digit < base  && char_cnt-- > 0) {
 		if (l>limit || (l == limit && digit > last_digit_limit)) {
-			l = max_uint64; /* Truncate on overflow. */
+			l = UINT64_MAX; /* Truncate on overflow. */
 			break;
 		}
 		l = (l * base) + digit;
@@ -1630,8 +1608,8 @@
 	int base, digit, sign;
 
 	base = 10;
-	limit = max_int64 / base;
-	last_digit_limit = max_int64 % base;
+	limit = INT64_MAX / base;
+	last_digit_limit = INT64_MAX % base;
 
 	while (*p == ' ' || *p == '\t')
 		p++;
@@ -1645,7 +1623,7 @@
 	digit = *p - '0';
 	while (digit >= 0 && digit < base  && char_cnt-- > 0) {
 		if (l > limit || (l == limit && digit > last_digit_limit)) {
-			l = max_uint64; /* Truncate on overflow. */
+			l = UINT64_MAX; /* Truncate on overflow. */
 			break;
 		}
 		l = (l * base) + digit;
@@ -1668,8 +1646,8 @@
 	int64_t	l, upper_limit, lower_limit;
 	const unsigned char *p = (const unsigned char *)_p;
 
-	upper_limit = max_int64 / 256;
-	lower_limit = min_int64 / 256;
+	upper_limit = INT64_MAX / 256;
+	lower_limit = INT64_MIN / 256;
 
 	/* Pad with 1 or 0 bits, depending on sign. */
 	if ((0x40 & *p) == 0x40)
@@ -1679,10 +1657,10 @@
 	l = (l << 6) | (0x3f & *p++);
 	while (--char_cnt > 0) {
 		if (l > upper_limit) {
-			l = max_int64; /* Truncate on overflow */
+			l = INT64_MAX; /* Truncate on overflow */
 			break;
 		} else if (l < lower_limit) {
-			l = min_int64;
+			l = INT64_MIN;
 			break;
 		}
 		l = (l << 8) | (0xff & (int64_t)*p++);

==== //depot/projects/mjexp/lib/libarchive/archive_read_support_format_zip.c#5 (text+ko) ====

@@ -24,7 +24,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_zip.c,v 1.11 2007/03/03 07:37:36 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_format_zip.c,v 1.12 2007/04/15 00:53:38 kientzle Exp $");
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -137,9 +137,6 @@
 static time_t	zip_time(const char *);
 static void process_extra(const void* extra, struct zip* zip);
 
-/* Largest 32-bit unsigned value, stored in a 64-bit constant. */
-static const uint64_t max_uint32 = (((uint64_t)1) << 32) - 1;
-
 int
 archive_read_support_format_zip(struct archive *_a)
 {
@@ -412,8 +409,8 @@
 				return (ARCHIVE_WARN);
 			}
 			/* Size field only stores the lower 32 bits of the actual size. */
-			if ((zip->uncompressed_size & max_uint32)
-			    != (zip->entry_uncompressed_bytes_read & max_uint32)) {
+			if ((zip->uncompressed_size & UINT32_MAX)
+			    != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) {
 				archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 				    "ZIP uncompressed data is wrong size");
 				return (ARCHIVE_WARN);

==== //depot/projects/mjexp/lib/libarchive/archive_write_disk.c#6 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.8 2007/04/14 02:37:22 kientzle Exp $");
+__FBSDID("$FreeBSD: src/lib/libarchive/archive_write_disk.c,v 1.10 2007/04/15 04:43:12 kientzle Exp $");
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -897,7 +897,7 @@
 			times.modtime = p->mtime;
 			times.actime = p->atime;
 
-			utime(p->name, times);
+			utime(p->name, &times);
 #endif
 		}
 		if (p->fixup & TODO_MODE_BASE)
@@ -922,6 +922,10 @@
 	struct archive_write_disk *a = (struct archive_write_disk *)_a;
 	int ret;
 	ret = _archive_write_close(&a->archive);
+	if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
+		(a->cleanup_gid)(a->lookup_gid_data);
+	if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
+		(a->cleanup_uid)(a->lookup_uid_data);
 	archive_string_free(&a->_name_data);
 	archive_string_free(&a->archive.error_string);
 	archive_string_free(&a->path_safe);
@@ -1452,7 +1456,7 @@

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list