Merge "unzip: fix Mac build."

This commit is contained in:
Elliott Hughes 2019-11-04 05:23:39 +00:00 committed by Gerrit Code Review
commit 2ea7c7d39f

View file

@ -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_uncompressed_length = 0;
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 @@ static bool PromptOverwrite(const std::string& dst) {
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 @@ static void ExtractToPipe(ZipArchiveHandle zah, ZipEntry& entry, const std::stri
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 ExtractToPipe(ZipArchiveHandle zah, ZipEntry& entry, const std::stri
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 @@ static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string&
// 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 @@ static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string&
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 @@ static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string&
// 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 @@ static void ProcessAll(ZipArchiveHandle zah) {
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 @@ static void ProcessAll(ZipArchiveHandle zah) {
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 @@ static void HandleCommonOption(int opt) {
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 @@ int main(int argc, char* argv[]) {
}
}
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);