static void* unzip_file(ZipArchiveHandle zip, const char* entry_name, unsigned* sz) { ZipEntryName zip_entry_name(entry_name); ZipEntry zip_entry; if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) { fprintf(stderr, "archive does not contain '%s'\n", entry_name); return 0; } *sz = zip_entry.uncompressed_length; uint8_t* data = reinterpret_cast<uint8_t*>(malloc(zip_entry.uncompressed_length)); if (data == NULL) { fprintf(stderr, "failed to allocate %u bytes for '%s'\n", *sz, entry_name); return 0; } int error = ExtractToMemory(zip, &zip_entry, data, zip_entry.uncompressed_length); if (error != 0) { fprintf(stderr, "failed to extract '%s': %s\n", entry_name, ErrorCodeString(error)); free(data); return 0; } return data; }
static int unzip_to_file(ZipArchiveHandle zip, char* entry_name) { FILE* fp = tmpfile(); if (fp == NULL) { fprintf(stderr, "failed to create temporary file for '%s': %s\n", entry_name, strerror(errno)); return -1; } ZipEntryName zip_entry_name(entry_name); ZipEntry zip_entry; if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) { fprintf(stderr, "archive does not contain '%s'\n", entry_name); return -1; } int fd = fileno(fp); int error = ExtractEntryToFile(zip, &zip_entry, fd); if (error != 0) { fprintf(stderr, "failed to extract '%s': %s\n", entry_name, ErrorCodeString(error)); return -1; } lseek(fd, 0, SEEK_SET); return fd; }
std::unique_ptr<ZipFileCollection> ZipFileCollection::create(const StringPiece& path, std::string* outError) { constexpr static const int32_t kEmptyArchive = -6; std::unique_ptr<ZipFileCollection> collection = std::unique_ptr<ZipFileCollection>( new ZipFileCollection()); int32_t result = OpenArchive(path.data(), &collection->mHandle); if (result != 0) { // If a zip is empty, result will be an error code. This is fine and we should // return an empty ZipFileCollection. if (result == kEmptyArchive) { return collection; } if (outError) *outError = ErrorCodeString(result); return {}; } void* cookie = nullptr; result = StartIteration(collection->mHandle, &cookie, nullptr, nullptr); if (result != 0) { if (outError) *outError = ErrorCodeString(result); return {}; } using IterationEnder = std::unique_ptr<void, decltype(EndIteration)*>; IterationEnder iterationEnder(cookie, EndIteration); ZipString zipEntryName; ZipEntry zipData; while ((result = Next(cookie, &zipData, &zipEntryName)) == 0) { std::string zipEntryPath = std::string(reinterpret_cast<const char*>(zipEntryName.name), zipEntryName.name_length); std::string nestedPath = path.toString() + "@" + zipEntryPath; collection->mFiles[zipEntryPath] = util::make_unique<ZipFile>(collection->mHandle, zipData, Source(nestedPath)); } if (result != -1) { if (outError) *outError = ErrorCodeString(result); return {}; } return collection; }
static void ExtractToPipe(ZipArchiveHandle zah, ZipEntry& entry, const std::string& name) { // We need to extract to memory because ExtractEntryToFile insists on // being able to seek and truncate, and you can't do that with stdout. 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)); } if (!android::base::WriteFully(1, buffer, entry.uncompressed_length)) { error(1, errno, "failed to write %s to stdout", name.c_str()); } delete[] buffer; }
static void ProcessAll(ZipArchiveHandle zah) { MaybeShowHeader(); // libziparchive iteration order doesn't match the central directory. // We could sort, but that would cost extra and wouldn't match either. void* cookie; int err = StartIteration(zah, &cookie); if (err != 0) { error(1, 0, "couldn't iterate %s: %s", archive_name, ErrorCodeString(err)); } ZipEntry entry; ZipString string; while ((err = Next(cookie, &entry, &string)) >= 0) { std::string name(string.name, string.name + string.name_length); if (ShouldInclude(name)) ProcessOne(zah, entry, name); } if (err < -1) error(1, 0, "failed iterating %s: %s", archive_name, ErrorCodeString(err)); EndIteration(cookie); MaybeShowFooter(); }
static void ExtractOne(ZipArchiveHandle zah, ZipEntry& entry, const std::string& name) { // Bad filename? if (android::base::StartsWith(name, "/") || android::base::StartsWith(name, "../") || name.find("/../") != std::string::npos) { error(1, 0, "bad filename %s", name.c_str()); } // Where are we actually extracting to (for human-readable output)? std::string dst; if (flag_d) { dst = flag_d; if (!android::base::EndsWith(dst, "/")) dst += '/'; } dst += name; // Ensure the directory hierarchy exists. if (!MakeDirectoryHierarchy(android::base::Dirname(name))) { error(1, errno, "couldn't create directory hierarchy for %s", dst.c_str()); } // An entry in a zip file can just be a directory itself. if (android::base::EndsWith(name, "/")) { if (mkdir(name.c_str(), entry.unix_mode) == -1) { // If the directory already exists, that's fine. if (errno == EEXIST) { 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()); } return; } // Create the file. int fd = open(name.c_str(), O_CREAT | O_WRONLY | O_CLOEXEC | O_EXCL, entry.unix_mode); if (fd == -1 && errno == EEXIST) { if (overwrite_mode == kNever) return; if (overwrite_mode == kPrompt && !PromptOverwrite(dst)) return; // 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()); // 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)); close(fd); }
void do_update(usb_handle *usb, const char *filename, int erase_first) { queue_info_dump(); fb_queue_query_save("product", cur_product, sizeof(cur_product)); ZipArchiveHandle zip; int error = OpenArchive(filename, &zip); if (error != 0) { CloseArchive(zip); die("failed to open zip file '%s': %s", filename, ErrorCodeString(error)); } unsigned sz; void* data = unzip_file(zip, "android-info.txt", &sz); if (data == 0) { CloseArchive(zip); die("update package '%s' has no android-info.txt", filename); } setup_requirements(reinterpret_cast<char*>(data), sz); for (size_t i = 0; i < ARRAY_SIZE(images); ++i) { int fd = unzip_to_file(zip, images[i].img_name); if (fd == -1) { if (images[i].is_optional) { continue; } CloseArchive(zip); exit(1); // unzip_to_file already explained why. } fastboot_buffer buf; int rc = load_buf_fd(usb, fd, &buf); if (rc) die("cannot load %s from flash", images[i].img_name); do_update_signature(zip, images[i].sig_name); if (erase_first && needs_erase(usb, images[i].part_name)) { fb_queue_erase(images[i].part_name); } flash_buf(images[i].part_name, &buf); /* not closing the fd here since the sparse code keeps the fd around * but hasn't mmaped data yet. The tmpfile will get cleaned up when the * program exits. */ } CloseArchive(zip); }
int main(int argc, char* argv[]) { static struct option opts[] = { {"help", no_argument, 0, 'h'}, }; bool saw_x = false; int opt; while ((opt = getopt_long(argc, argv, "-d:hlnopqvx", opts, nullptr)) != -1) { switch (opt) { case 'd': flag_d = optarg; break; case 'h': ShowHelp(true); break; case 'l': flag_l = true; break; case 'n': overwrite_mode = kNever; break; case 'o': overwrite_mode = kAlways; break; case 'p': flag_p = flag_q = true; break; case 'q': flag_q = true; break; case 'v': flag_v = true; break; case 'x': saw_x = true; break; case 1: // -x swallows all following arguments, so we use '-' in the getopt // string and collect files here. if (!archive_name) { archive_name = optarg; } else if (saw_x) { excludes.insert(optarg); } else { includes.insert(optarg); } break; default: ShowHelp(false); } } if (!archive_name) error(1, 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)); } // 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); ProcessAll(zah); CloseArchive(zah); return 0; }
static void throwIoException(JNIEnv* env, const int32_t errorCode) { jniThrowException(env, "java/io/IOException", ErrorCodeString(errorCode)); }
// ----------------------------------------------------------------------------- // CSifUiTest::SetResult() // ----------------------------------------------------------------------------- // void CSifUiTest::SetResult( TTestResult& aResult, const TInt aReturnCode ) const { aResult.SetResult( aReturnCode, ErrorCodeString( aReturnCode ) ); }