Import libarchive-2.7.1.
authorPeter Avalos <pavalos@dragonflybsd.org>
Thu, 1 Oct 2009 19:02:36 +0000 (19:02 +0000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Thu, 1 Oct 2009 19:02:36 +0000 (19:02 +0000)
* Suppress bogus warning about unxz
* Support lzma/xz files compressed with larger buffer sizes.
* Handle gzip files signed with OpenBSD "gzsig" program.
* Avoid false failures when reading from pipe.

17 files changed:
contrib/libarchive/NEWS
contrib/libarchive/README.DELETED [deleted file]
contrib/libarchive/build/version
contrib/libarchive/cpio/cmdline.c
contrib/libarchive/cpio/cpio.c
contrib/libarchive/libarchive/archive.h
contrib/libarchive/libarchive/archive_private.h
contrib/libarchive/libarchive/archive_read.c
contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
contrib/libarchive/libarchive/archive_read_open_filename.c
contrib/libarchive/libarchive/archive_read_support_compression_all.c
contrib/libarchive/libarchive/archive_read_support_compression_gzip.c
contrib/libarchive/libarchive/archive_read_support_compression_xz.c
contrib/libarchive/libarchive/archive_read_support_format_iso9660.c
contrib/libarchive/libarchive/archive_read_support_format_mtree.c
contrib/libarchive/libarchive/archive_read_support_format_tar.c
contrib/libarchive/libarchive/archive_write_set_format_cpio.c

index de617c3..68700b7 100644 (file)
@@ -1,4 +1,12 @@
 
+Aug 04, 2009: libarchive 2.7.1 released
+
+Jul 20, 2009: Suppress bogus warning about unxz
+Jul 19, 2009: Support Cygwin 1.7
+Jun 11, 2009: Support lzma/xz files compressed with larger buffer sizes.
+May 24, 2009: Handle gzip files signed with OpenBSD "gzsig" program.
+May 07, 2009: Avoid false failures when reading from pipe.
+
 Apr 16, 2009: libarchive 2.7.0 released
 
 Apr 10, 2009: libarchive 2.6.992a released
diff --git a/contrib/libarchive/README.DELETED b/contrib/libarchive/README.DELETED
deleted file mode 100644 (file)
index 409636e..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-CMakeLists.txt
-INSTALL
-Makefile.am
-Makefile.in
-PROJECTS
-aclocal.m4
-build/autoconf/
-build/autogen.sh
-build/cmake/
-build/release.sh
-build/windows/
-config.h.in
-configure
-configure.ac
-contrib/
-cpio/CMakeLists.txt
-cpio/config_freebsd.h
-cpio/cpio_cygwin.c
-cpio/cpio_cygwin.h
-cpio/cpio_windows.c
-cpio/cpio_windows.h
-cpio/test/
-doc/
-examples/
-libarchive/CMakeLists.txt
-libarchive/archive_windows.c
-libarchive/archive_windows.h
-libarchive/config_freebsd.h
-libarchive/config_windows.h
-libarchive/filter_fork_windows.c
-libarchive/test/
-tar/CMakeLists.txt
-tar/bsdtar_cygwin.c
-tar/bsdtar_cygwin.h
-tar/bsdtar_windows.c
-tar/bsdtar_windows.h
-tar/config_freebsd.h
-tar/test/
index f0033e9..edcd8ba 100644 (file)
@@ -50,7 +50,7 @@ __FBSDID("$FreeBSD: src/usr.bin/cpio/cmdline.c,v 1.5 2008/12/06 07:30:40 kientzl
 /*
  * Short options for cpio.  Please keep this sorted.
  */
-static const char *short_options = "0AaBC:F:O:cdE:f:H:hijLlmnopR:rtuvW:yZz";
+static const char *short_options = "0AaBC:F:O:cdE:f:H:hI:ijLlmnopR:rtuvW:yZz";
 
 /*
  * Long options for cpio.  Please keep this sorted.
index c62ed11..e5b40c9 100644 (file)
@@ -969,11 +969,11 @@ list_item_verbose(struct cpio *cpio, struct archive_entry *entry)
 
        if (cpio->option_numeric_uid_gid) {
                /* Format numeric uid/gid for display. */
-               snprintf(uids, sizeof(uids), "%jd",
-                   (intmax_t)archive_entry_uid(entry));
+               snprintf(uids, sizeof(uids), "%d",
+                   (int)archive_entry_uid(entry));
                uname = uids;
-               snprintf(gids, sizeof(gids), "%jd",
-                   (intmax_t)archive_entry_gid(entry));
+               snprintf(gids, sizeof(gids), "%d",
+                   (int)archive_entry_gid(entry));
                gname = gids;
        } else {
                /* Use uname if it's present, else lookup name from uid. */
index 0b3f8e1..917c19a 100644 (file)
@@ -118,13 +118,13 @@ extern "C" {
  *             (ARCHIVE_API_VERSION * 1000000 + ARCHIVE_API_FEATURE * 1000)
  * #endif
  */
-#define        ARCHIVE_VERSION_NUMBER 2007000
+#define        ARCHIVE_VERSION_NUMBER 2007001
 __LA_DECL int          archive_version_number(void);
 
 /*
  * Textual name/version of the library, useful for version displays.
  */
-#define        ARCHIVE_VERSION_STRING "libarchive 2.7.0"
+#define        ARCHIVE_VERSION_STRING "libarchive 2.7.1"
 __LA_DECL const char * archive_version_string(void);
 
 #if ARCHIVE_VERSION_NUMBER < 3000000
index a25dd22..698ad22 100644 (file)
@@ -87,9 +87,9 @@ struct archive {
        const char *compression_name;
 
        /* Position in UNCOMPRESSED data stream. */
-       off_t             file_position;
+       int64_t           file_position;
        /* Position in COMPRESSED data stream. */
-       off_t             raw_position;
+       int64_t           raw_position;
 
        int               archive_error_number;
        const char       *error;
index d4233c9..e88b90f 100644 (file)
@@ -117,6 +117,7 @@ archive_read_set_format_options(struct archive *_a, const char *s)
        struct archive_read *a;
        struct archive_format_descriptor *format;
        char key[64], val[64];
+       char *valp;
        size_t i;
        int len, r;
 
@@ -135,10 +136,10 @@ archive_read_set_format_options(struct archive *_a, const char *s)
 
                while ((len = __archive_parse_options(s, format->name,
                    sizeof(key), key, sizeof(val), val)) > 0) {
-                       if (val[0] == '\0')
-                               r = format->options(a, key, NULL);
-                       else
-                               r = format->options(a, key, val);
+                       valp = val[0] == '\0' ? NULL : val;
+                       a->format = format;
+                       r = format->options(a, key, valp);
+                       a->format = NULL;
                        if (r == ARCHIVE_FATAL)
                                return (r);
                        s += len;
@@ -241,13 +242,26 @@ client_read_proxy(struct archive_read_filter *self, const void **buff)
 static int64_t
 client_skip_proxy(struct archive_read_filter *self, int64_t request)
 {
-       int64_t r;
+       int64_t ask, get, total;
+       /* Limit our maximum seek request to 1GB on platforms
+       * with 32-bit off_t (such as Windows). */
+       int64_t skip_limit = ((int64_t)1) << (sizeof(off_t) * 8 - 2);
+
        if (self->archive->client.skipper == NULL)
                return (0);
-       r = (self->archive->client.skipper)(&self->archive->archive,
-           self->data, request);
-       self->archive->archive.raw_position += r;
-       return (r);
+       total = 0;
+       for (;;) {
+               ask = request;
+               if (ask > skip_limit)
+                       ask = skip_limit;
+               get = (self->archive->client.skipper)(&self->archive->archive,
+                       self->data, ask);
+               if (get == 0)
+                       return (total);
+               request -= get;
+               self->archive->archive.raw_position += get;
+               total += get;
+       }
 }
 
 static int
@@ -1118,7 +1132,7 @@ __archive_read_skip(struct archive_read *a, int64_t request)
 int64_t
 __archive_read_filter_skip(struct archive_read_filter *filter, int64_t request)
 {
-       off_t bytes_skipped, total_bytes_skipped = 0;
+       int64_t bytes_skipped, total_bytes_skipped = 0;
        size_t min;
 
        if (filter->fatal)
@@ -1133,7 +1147,7 @@ __archive_read_filter_skip(struct archive_read_filter *filter, int64_t request)
                total_bytes_skipped += bytes_skipped;
        }
        if (filter->client_avail > 0) {
-               min = minimum(request, (off_t)filter->client_avail);
+               min = minimum(request, (int64_t)filter->client_avail);
                bytes_skipped = __archive_read_consume(filter->archive, min);
                request -= bytes_skipped;
                total_bytes_skipped += bytes_skipped;
index 6e12517..8f90191 100644 (file)
@@ -92,6 +92,7 @@ archive_read_disk_entry_from_file(struct archive *_a,
        int initial_fd = fd;
        int r, r1;
 
+       archive_clear_error(_a);
        path = archive_entry_sourcepath(entry);
        if (path == NULL)
                path = archive_entry_pathname(entry);
index 04efb0f..deac47b 100644 (file)
@@ -84,20 +84,32 @@ archive_read_open_filename(struct archive *a, const char *filename,
        void *b;
        int fd;
 
-       if (filename == NULL || filename[0] == '\0')
-               return (archive_read_open_fd(a, 0, block_size));
-
-       fd = open(filename, O_RDONLY | O_BINARY);
-       if (fd < 0) {
-               archive_set_error(a, errno, "Failed to open '%s'", filename);
-               return (ARCHIVE_FATAL);
+       if (filename == NULL || filename[0] == '\0') {
+               /* We used to invoke archive_read_open_fd(a,0,block_size)
+                * here, but that doesn't (and shouldn't) handle the
+                * end-of-file flush when reading stdout from a pipe.
+                * Basically, read_open_fd() is intended for folks who
+                * are willing to handle such details themselves.  This
+                * API is intended to be a little smarter for folks who
+                * want easy handling of the common case.
+                */
+               filename = ""; /* Normalize NULL to "" */
+               fd = 0;
+       } else {
+               fd = open(filename, O_RDONLY | O_BINARY);
+               if (fd < 0) {
+                       archive_set_error(a, errno,
+                           "Failed to open '%s'", filename);
+                       return (ARCHIVE_FATAL);
+               }
        }
        if (fstat(fd, &st) != 0) {
                archive_set_error(a, errno, "Can't stat '%s'", filename);
                return (ARCHIVE_FATAL);
        }
 
-       mine = (struct read_file_data *)malloc(sizeof(*mine) + strlen(filename));
+       mine = (struct read_file_data *)calloc(1,
+           sizeof(*mine) + strlen(filename));
        b = malloc(block_size);
        if (mine == NULL || b == NULL) {
                archive_set_error(a, ENOMEM, "No memory");
@@ -116,15 +128,20 @@ archive_read_open_filename(struct archive *a, const char *filename,
        if (S_ISREG(st.st_mode)) {
                archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
                /*
-                * Skip is a performance optimization for anything
-                * that supports lseek().  Generally, that only
-                * includes regular files and possibly raw disk
-                * devices, but there's no good portable way to detect
-                * raw disks.
+                * Enabling skip here is a performance optimization
+                * for anything that supports lseek().  On FreeBSD
+                * (and probably many other systems), only regular
+                * files and raw disk devices support lseek() (on
+                * other input types, lseek() returns success but
+                * doesn't actually change the file pointer, which
+                * just completely screws up the position-tracking
+                * logic).  In addition, I've yet to find a portable
+                * way to determine if a device is a raw disk device.
+                * So I don't see a way to do much better than to only
+                * enable this optimization for regular files.
                 */
                mine->can_skip = 1;
-       } else
-               mine->can_skip = 0;
+       }
        return (archive_read_open2(a, mine,
                NULL, file_read, file_skip, file_close));
 }
@@ -138,8 +155,11 @@ file_read(struct archive *a, void *client_data, const void **buff)
        *buff = mine->buffer;
        bytes_read = read(mine->fd, mine->buffer, mine->block_size);
        if (bytes_read < 0) {
-               archive_set_error(a, errno, "Error reading '%s'",
-                   mine->filename);
+               if (mine->filename[0] == '\0')
+                       archive_set_error(a, errno, "Error reading stdin");
+               else
+                       archive_set_error(a, errno, "Error reading '%s'",
+                           mine->filename);
        }
        return (bytes_read);
 }
@@ -189,8 +209,15 @@ file_skip(struct archive *a, void *client_data, off_t request)
                 * likely caused by a programmer error (too large request)
                 * or a corrupted archive file.
                 */
-               archive_set_error(a, errno, "Error seeking in '%s'",
-                   mine->filename);
+               if (mine->filename[0] == '\0')
+                       /*
+                        * Should never get here, since lseek() on stdin ought
+                        * to return an ESPIPE error.
+                        */
+                       archive_set_error(a, errno, "Error seeking in stdin");
+               else
+                       archive_set_error(a, errno, "Error seeking in '%s'",
+                           mine->filename);
                return (-1);
        }
        return (new_offset - old_offset);
@@ -224,7 +251,9 @@ file_close(struct archive *a, void *client_data)
                                    mine->block_size);
                        } while (bytesRead > 0);
                }
-               close(mine->fd);
+               /* If a named file was opened, then it needs to be closed. */
+               if (mine->filename[0] != '\0')
+                       close(mine->fd);
        }
        free(mine->buffer);
        free(mine);
index 063c288..dcd6a31 100644 (file)
@@ -50,5 +50,7 @@ archive_read_support_compression_all(struct archive *a)
         * "as much as possible."  Clients who need specific
         * compression should enable those individually so they can
         * verify the level of support. */
+       /* Clear any warning messages set by the above functions. */
+       archive_clear_error(a);
        return (ARCHIVE_OK);
 }
index 2222478..cd21c61 100644 (file)
@@ -148,6 +148,7 @@ peek_at_header(struct archive_read_filter *filter, int *pbits)
                if (p == NULL)
                        return (0);
                len += ((int)p[len + 1] << 8) | (int)p[len];
+               len += 2;
        }
 
        /* Null-terminated optional filename. */
index a3c9553..61d9d0c 100644 (file)
@@ -302,11 +302,11 @@ xz_lzma_bidder_init(struct archive_read_filter *self)
         */
        if (self->code == ARCHIVE_COMPRESSION_XZ)
                ret = lzma_stream_decoder(&(state->stream),
-                   (1U << 23) + (1U << 21),/* memlimit */
+                   (1U << 30),/* memlimit */
                    LZMA_CONCATENATED);
        else
                ret = lzma_alone_decoder(&(state->stream),
-                   (1U << 23) + (1U << 21));/* memlimit */
+                   (1U << 30));/* memlimit */
 
        if (ret == LZMA_OK)
                return (ARCHIVE_OK);
index c45872a..1921c58 100644 (file)
@@ -683,7 +683,7 @@ archive_read_format_iso9660_read_data(struct archive_read *a,
        if (bytes_read == 0)
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
                    "Truncated input file");
-       if (buff == NULL)
+       if (*buff == NULL)
                return (ARCHIVE_FATAL);
        if (bytes_read > iso9660->entry_bytes_remaining)
                bytes_read = iso9660->entry_bytes_remaining;
index 0f0e116..3496e0b 100644 (file)
@@ -990,8 +990,8 @@ read_data(struct archive_read *a, const void **buff, size_t *size, off_t *offset
                if (mtree->buff == NULL) {
                        archive_set_error(&a->archive, ENOMEM,
                            "Can't allocate memory");
+                       return (ARCHIVE_FATAL);
                }
-               return (ARCHIVE_FATAL);
        }
 
        *buff = mtree->buff;
index 60ad814..bc82878 100644 (file)
@@ -159,10 +159,10 @@ struct tar {
        wchar_t                 *pax_entry;
        size_t                   pax_entry_length;
        int                      header_recursion_depth;
-       off_t                    entry_bytes_remaining;
-       off_t                    entry_offset;
-       off_t                    entry_padding;
-       off_t                    realsize;
+       int64_t                  entry_bytes_remaining;
+       int64_t                  entry_offset;
+       int64_t                  entry_padding;
+       int64_t                  realsize;
        struct sparse_block     *sparse_list;
        struct sparse_block     *sparse_last;
        int64_t                  sparse_offset;
@@ -509,7 +509,7 @@ archive_read_format_tar_read_data(struct archive_read *a,
 static int
 archive_read_format_tar_skip(struct archive_read *a)
 {
-       off_t bytes_skipped;
+       int64_t bytes_skipped;
        struct tar* tar;
 
        tar = (struct tar *)(a->format->data);
index 3026b6c..c20abf8 100644 (file)
@@ -125,8 +125,9 @@ archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry)
         * re-using the ones off the disk.  That way, the 18-bit c_ino
         * field only limits the number of files in the archive.
         */
-       if (archive_entry_ino(entry) > 0777777) {
-               archive_set_error(&a->archive, ERANGE, "large inode number truncated");
+       if ((int)archive_entry_ino(entry) > 0777777) {
+               archive_set_error(&a->archive, ERANGE,
+                   "large inode number truncated");
                ret = ARCHIVE_WARN;
        }