Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/unzip From FreeBSD:



details:   https://anonhg.NetBSD.org/src/rev/c6d1fd880986
branches:  trunk
changeset: 812571:c6d1fd880986
user:      christos <christos%NetBSD.org@localhost>
date:      Mon Dec 21 17:17:02 2015 +0000

description:
>From FreeBSD:
- Whitespace cleanup
- Pass a filename rather than fd to libarchive (should work with 2.8+)
- Accept zipfiles from stdin
- Extract common code from extract()/extract_stdout() to extract2fd() (pending)

diffstat:

 usr.bin/unzip/unzip.1 |    8 +-
 usr.bin/unzip/unzip.c |  256 +++++++++++++++++++------------------------------
 2 files changed, 103 insertions(+), 161 deletions(-)

diffs (truncated from 373 to 300 lines):

diff -r 99098e2b5fc4 -r c6d1fd880986 usr.bin/unzip/unzip.1
--- a/usr.bin/unzip/unzip.1     Mon Dec 21 17:02:32 2015 +0000
+++ b/usr.bin/unzip/unzip.1     Mon Dec 21 17:17:02 2015 +0000
@@ -25,9 +25,9 @@
 .\" SUCH DAMAGE.
 .\"
 .\" $FreeBSD: revision 180125$
-.\" $NetBSD: unzip.1,v 1.10 2014/03/18 18:20:45 riastradh Exp $
+.\" $NetBSD: unzip.1,v 1.11 2015/12/21 17:17:02 christos Exp $
 .\"
-.Dd August 18, 2011
+.Dd December 21, 2015
 .Dt UNZIP 1
 .Os
 .Sh NAME
@@ -142,8 +142,8 @@
 zipfile's central directory.
 Since the
 .Xr archive 3
-library reads zipfiles sequentially, and does not use the central
-directory, that information is not available to the
+library does not provide access to that information, it is not available
+to the
 .Nm
 utility.
 Instead, the
diff -r 99098e2b5fc4 -r c6d1fd880986 usr.bin/unzip/unzip.c
--- a/usr.bin/unzip/unzip.c     Mon Dec 21 17:02:32 2015 +0000
+++ b/usr.bin/unzip/unzip.c     Mon Dec 21 17:17:02 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: unzip.c,v 1.21 2015/12/03 20:01:19 christos Exp $ */
+/* $NetBSD: unzip.c,v 1.22 2015/12/21 17:17:02 christos Exp $ */
 
 /*-
  * Copyright (c) 2009, 2010 Joerg Sonnenberger <joerg%NetBSD.org@localhost>
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: unzip.c,v 1.21 2015/12/03 20:01:19 christos Exp $");
+__RCSID("$NetBSD: unzip.c,v 1.22 2015/12/21 17:17:02 christos Exp $");
 
 #include <sys/queue.h>
 #include <sys/stat.h>
@@ -436,7 +436,7 @@
                        (void)unlink(*path);
                        return 1;
                case 'N':
-                       n_opt = 1;                      
+                       n_opt = 1;
                        /* FALL THROUGH */
                case 'n':
                        return -1;
@@ -486,6 +486,92 @@
 }
 
 /*
+ * Extract to a file descriptor
+ */
+static int
+extract2fd(struct archive *a, char *pathname, int fd)
+{
+       int cr, text, warn;
+       ssize_t len;
+       unsigned char *p, *q, *end;
+
+       text = a_opt;
+       warn = 0;
+       cr = 0;
+
+       /* loop over file contents and write to fd */
+       for (int n = 0; ; n++) {
+               if (fd != STDOUT_FILENO)
+                       if (tty && (n % 4) == 0)
+                               info(" %c\b\b", spinner[(n / 4) % sizeof spinner]);
+
+               len = archive_read_data(a, buffer, sizeof buffer);
+
+               if (len < 0)
+                       ac(len);
+
+               /* left over CR from previous buffer */
+               if (a_opt && cr) {
+                       if (len == 0 || buffer[0] != '\n')
+                               if (write(fd, "\r", 1) != 1)
+                                       error("write('%s')", pathname);
+                       cr = 0;
+               }
+
+               /* EOF */
+               if (len == 0)
+                       break;
+               end = buffer + len;
+
+               /*
+                * Detect whether this is a text file.  The correct way to
+                * do this is to check the least significant bit of the
+                * "internal file attributes" field of the corresponding
+                * file header in the central directory, but libarchive
+                * does not provide access to this field, so we have to
+                * guess by looking for non-ASCII characters in the
+                * buffer.  Hopefully we won't guess wrong.  If we do
+                * guess wrong, we print a warning message later.
+                */
+               if (a_opt && n == 0) {
+                       if (check_binary(buffer, len))
+                               text = 0;
+               }
+
+               /* simple case */
+               if (!a_opt || !text) {
+                       if (write(fd, buffer, len) != len)
+                               error("write('%s')", pathname);
+                       continue;
+               }
+
+               /* hard case: convert \r\n to \n (sigh...) */
+               for (p = buffer; p < end; p = q + 1) {
+                       for (q = p; q < end; q++) {
+                               if (!warn && BYTE_IS_BINARY(*q)) {
+                                       warningx("%s may be corrupted due"
+                                           " to weak text file detection"
+                                           " heuristic", pathname);
+                                       warn = 1;
+                               }
+                               if (q[0] != '\r')
+                                       continue;
+                               if (&q[1] == end) {
+                                       cr = 1;
+                                       break;
+                               }
+                               if (q[1] == '\n')
+                                       break;
+                       }
+                       if (write(fd, p, q - p) != q - p)
+                               error("write('%s')", pathname);
+               }
+       }
+
+       return text;
+}
+
+/*
  * Extract a regular file.
  */
 static void
@@ -495,9 +581,7 @@
        time_t mtime;
        struct stat sb;
        struct timeval tv[2];
-       int cr, fd, text, warn, check;
-       ssize_t len;
-       unsigned char *p, *q, *end;
+       int fd, check, text;
        const char *linkname;
 
        mode = archive_entry_mode(e) & 0777;
@@ -561,77 +645,10 @@
        if ((fd = open(*path, O_RDWR|O_CREAT|O_TRUNC, mode)) < 0)
                error("open('%s')", *path);
 
-       /* loop over file contents and write to disk */
        info(" extracting: %s", *path);
-       text = a_opt;
-       warn = 0;
-       cr = 0;
-       for (int n = 0; ; n++) {
-               if (tty && (n % 4) == 0)
-                       info(" %c\b\b", spinner[(n / 4) % sizeof spinner]);
-
-               len = archive_read_data(a, buffer, sizeof buffer);
-
-               if (len < 0)
-                       ac(len);
-
-               /* left over CR from previous buffer */
-               if (a_opt && cr) {
-                       if (len == 0 || buffer[0] != '\n')
-                               if (write(fd, "\r", 1) != 1)
-                                       error("write('%s')", *path);
-                       cr = 0;
-               }
-
-               /* EOF */
-               if (len == 0)
-                       break;
-               end = buffer + len;
 
-               /*
-                * Detect whether this is a text file.  The correct way to
-                * do this is to check the least significant bit of the
-                * "internal file attributes" field of the corresponding
-                * file header in the central directory, but libarchive
-                * does not read the central directory, so we have to
-                * guess by looking for non-ASCII characters in the
-                * buffer.  Hopefully we won't guess wrong.  If we do
-                * guess wrong, we print a warning message later.
-                */
-               if (a_opt && n == 0) {
-                       if (check_binary(buffer, len))
-                               text = 0;
-               }
-
-               /* simple case */
-               if (!a_opt || !text) {
-                       if (write(fd, buffer, len) != len)
-                               error("write('%s')", *path);
-                       continue;
-               }
+       text = extract2fd(a, *path, fd);
 
-               /* hard case: convert \r\n to \n (sigh...) */
-               for (p = buffer; p < end; p = q + 1) {
-                       for (q = p; q < end; q++) {
-                               if (!warn && BYTE_IS_BINARY(*q)) {
-                                       warningx("%s may be corrupted due"
-                                           " to weak text file detection"
-                                           " heuristic", *path);
-                                       warn = 1;
-                               }
-                               if (q[0] != '\r')
-                                       continue;
-                               if (&q[1] == end) {
-                                       cr = 1;
-                                       break;
-                               }
-                               if (q[1] == '\n')
-                                       break;
-                       }
-                       if (write(fd, p, q - p) != q - p)
-                               error("write('%s')", *path);
-               }
-       }
        if (tty)
                info("  \b\b");
        if (text)
@@ -729,9 +746,6 @@
 {
        char *pathname;
        mode_t filetype;
-       int cr, text, warn;
-       ssize_t len;
-       unsigned char *p, *q, *end;
 
        pathname = pathdup(archive_entry_pathname(e));
        filetype = archive_entry_filetype(e);
@@ -761,77 +775,7 @@
        if (c_opt)
                info("x %s\n", pathname);
 
-       text = a_opt;
-       warn = 0;
-       cr = 0;
-       for (int n = 0; ; n++) {
-               len = archive_read_data(a, buffer, sizeof buffer);
-
-               if (len < 0)
-                       ac(len);
-
-               /* left over CR from previous buffer */
-               if (a_opt && cr) {
-                       if (len == 0 || buffer[0] != '\n') {
-                               if (fwrite("\r", 1, 1, stderr) != 1)
-                                       error("write('%s')", pathname);
-                       }
-                       cr = 0;
-               }
-
-               /* EOF */
-               if (len == 0)
-                       break;
-               end = buffer + len;
-
-               /*
-                * Detect whether this is a text file.  The correct way to
-                * do this is to check the least significant bit of the
-                * "internal file attributes" field of the corresponding
-                * file header in the central directory, but libarchive
-                * does not read the central directory, so we have to
-                * guess by looking for non-ASCII characters in the
-                * buffer.  Hopefully we won't guess wrong.  If we do
-                * guess wrong, we print a warning message later.
-                */
-               if (a_opt && n == 0) {
-                       for (p = buffer; p < end; ++p) {
-                               if (!isascii((unsigned char)*p)) {
-                                       text = 0;
-                                       break;
-                               }
-                       }
-               }
-
-               /* simple case */
-               if (!a_opt || !text) {
-                       if (fwrite(buffer, 1, len, stdout) != (size_t)len)
-                               error("write('%s')", pathname);
-                       continue;
-               }
-
-               /* hard case: convert \r\n to \n (sigh...) */



Home | Main Index | Thread Index | Old Index