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, ×);
#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