Merge "unzip: fix Mac build." am: 2ea7c7d39f
am: 5a5ad6106d
Change-Id: I8e94dfef723cd7c2f798b8fc11a529a01d03b7a9
diff --git a/libziparchive/unzip.cpp b/libziparchive/unzip.cpp
index af70f1d..7332b41 100644
--- a/libziparchive/unzip.cpp
+++ b/libziparchive/unzip.cpp
@@ -15,11 +15,11 @@
*/
#include <errno.h>
-#include <error.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <getopt.h>
#include <inttypes.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
@@ -64,6 +64,20 @@
static uint64_t total_compressed_length = 0;
static size_t file_count = 0;
+static const char* g_progname;
+
+static void die(int error, const char* fmt, ...) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(stderr, "%s: ", g_progname);
+ vfprintf(stderr, fmt, ap);
+ if (error != 0) fprintf(stderr, ": %s", strerror(error));
+ fprintf(stderr, "\n");
+ va_end(ap);
+ exit(1);
+}
+
static bool ShouldInclude(const std::string& name) {
// Explicitly excluded?
if (!excludes.empty()) {
@@ -155,7 +169,7 @@
char* line = nullptr;
size_t n;
if (getline(&line, &n, stdin) == -1) {
- error(1, 0, "(EOF/read error; assuming [N]one...)");
+ die(0, "(EOF/read error; assuming [N]one...)");
overwrite_mode = kNever;
return false;
}
@@ -183,10 +197,10 @@
uint8_t* buffer = new uint8_t[entry.uncompressed_length];
int err = ExtractToMemory(zah, &entry, buffer, entry.uncompressed_length);
if (err < 0) {
- error(1, 0, "failed to extract %s: %s", name.c_str(), ErrorCodeString(err));
+ die(0, "failed to extract %s: %s", name.c_str(), ErrorCodeString(err));
}
if (!android::base::WriteFully(1, buffer, entry.uncompressed_length)) {
- error(1, errno, "failed to write %s to stdout", name.c_str());
+ die(errno, "failed to write %s to stdout", name.c_str());
}
delete[] buffer;
}
@@ -194,7 +208,7 @@
static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string& name) {
// Bad filename?
if (StartsWith(name, "/") || StartsWith(name, "../") || name.find("/../") != std::string::npos) {
- error(1, 0, "bad filename %s", name.c_str());
+ die(0, "bad filename %s", name.c_str());
}
// Where are we actually extracting to (for human-readable output)?
@@ -207,7 +221,7 @@
// Ensure the directory hierarchy exists.
if (!MakeDirectoryHierarchy(android::base::Dirname(name))) {
- error(1, errno, "couldn't create directory hierarchy for %s", dst.c_str());
+ die(errno, "couldn't create directory hierarchy for %s", dst.c_str());
}
// An entry in a zip file can just be a directory itself.
@@ -218,7 +232,7 @@
struct stat sb;
if (stat(name.c_str(), &sb) != -1 && S_ISDIR(sb.st_mode)) return;
}
- error(1, errno, "couldn't extract directory %s", dst.c_str());
+ die(errno, "couldn't extract directory %s", dst.c_str());
}
return;
}
@@ -231,12 +245,12 @@
// Either overwrite_mode is kAlways or the user consented to this specific case.
fd = open(name.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, entry.unix_mode);
}
- if (fd == -1) error(1, errno, "couldn't create file %s", dst.c_str());
+ if (fd == -1) die(errno, "couldn't create file %s", dst.c_str());
// Actually extract into the file.
if (!flag_q) printf(" inflating: %s\n", dst.c_str());
int err = ExtractEntryToFile(zah, &entry, fd);
- if (err < 0) error(1, 0, "failed to extract %s: %s", dst.c_str(), ErrorCodeString(err));
+ if (err < 0) die(0, "failed to extract %s: %s", dst.c_str(), ErrorCodeString(err));
close(fd);
}
@@ -345,7 +359,7 @@
void* cookie;
int err = StartIteration(zah, &cookie);
if (err != 0) {
- error(1, 0, "couldn't iterate %s: %s", archive_name, ErrorCodeString(err));
+ die(0, "couldn't iterate %s: %s", archive_name, ErrorCodeString(err));
}
ZipEntry entry;
@@ -354,7 +368,7 @@
if (ShouldInclude(name)) ProcessOne(zah, entry, name);
}
- if (err < -1) error(1, 0, "failed iterating %s: %s", archive_name, ErrorCodeString(err));
+ if (err < -1) die(0, "failed iterating %s: %s", archive_name, ErrorCodeString(err));
EndIteration(cookie);
MaybeShowFooter();
@@ -420,14 +434,14 @@
int main(int argc, char* argv[]) {
// Who am I, and what am I doing?
- const char* base = basename(argv[0]);
- if (!strcmp(base, "ziptool") && argc > 1) return main(argc - 1, argv + 1);
- if (!strcmp(base, "unzip")) {
+ g_progname = basename(argv[0]);
+ if (!strcmp(g_progname, "ziptool") && argc > 1) return main(argc - 1, argv + 1);
+ if (!strcmp(g_progname, "unzip")) {
role = kUnzip;
- } else if (!strcmp(base, "zipinfo")) {
+ } else if (!strcmp(g_progname, "zipinfo")) {
role = kZipinfo;
} else {
- error(1, 0, "run as ziptool with unzip or zipinfo as the first argument, or symlink");
+ die(0, "run as ziptool with unzip or zipinfo as the first argument, or symlink");
}
static const struct option opts[] = {
@@ -484,19 +498,19 @@
}
}
- if (!archive_name) error(1, 0, "missing archive filename");
+ if (!archive_name) die(0, "missing archive filename");
// We can't support "-" to unzip from stdin because libziparchive relies on mmap.
ZipArchiveHandle zah;
int32_t err;
if ((err = OpenArchive(archive_name, &zah)) != 0) {
- error(1, 0, "couldn't open %s: %s", archive_name, ErrorCodeString(err));
+ die(0, "couldn't open %s: %s", archive_name, ErrorCodeString(err));
}
// Implement -d by changing into that directory.
// We'll create implicit directories based on paths in the zip file, but we
// require that the -d directory already exists.
- if (flag_d && chdir(flag_d) == -1) error(1, errno, "couldn't chdir to %s", flag_d);
+ if (flag_d && chdir(flag_d) == -1) die(errno, "couldn't chdir to %s", flag_d);
ProcessAll(zah);