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/e0e62fa11578
branches: trunk
changeset: 342429:e0e62fa11578
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 b1bec78f5e62 -r e0e62fa11578 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 b1bec78f5e62 -r e0e62fa11578 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