diff options
author | Narayan Kamath <narayan@google.com> | 2015-02-23 15:09:31 +0100 |
---|---|---|
committer | Narayan Kamath <narayan@google.com> | 2015-02-27 15:19:59 +0100 |
commit | e57c62a007002577ee2339f53f9767af8a6b2877 (patch) | |
tree | e9faaa34a12fcfe6cc9581338193bf0dc2346f14 /minzip/Zip.c | |
parent | Merge "Add tests for read_block_adb." (diff) | |
download | android_bootable_recovery-e57c62a007002577ee2339f53f9767af8a6b2877.tar android_bootable_recovery-e57c62a007002577ee2339f53f9767af8a6b2877.tar.gz android_bootable_recovery-e57c62a007002577ee2339f53f9767af8a6b2877.tar.bz2 android_bootable_recovery-e57c62a007002577ee2339f53f9767af8a6b2877.tar.lz android_bootable_recovery-e57c62a007002577ee2339f53f9767af8a6b2877.tar.xz android_bootable_recovery-e57c62a007002577ee2339f53f9767af8a6b2877.tar.zst android_bootable_recovery-e57c62a007002577ee2339f53f9767af8a6b2877.zip |
Diffstat (limited to 'minzip/Zip.c')
-rw-r--r-- | minzip/Zip.c | 152 |
1 files changed, 53 insertions, 99 deletions
diff --git a/minzip/Zip.c b/minzip/Zip.c index fb462f45c..b5e446716 100644 --- a/minzip/Zip.c +++ b/minzip/Zip.c @@ -828,7 +828,7 @@ static const char *targetEntryPath(MzPathHelper *helper, ZipEntry *pEntry) */ bool mzExtractRecursive(const ZipArchive *pArchive, const char *zipDir, const char *targetDir, - int flags, const struct utimbuf *timestamp, + const struct utimbuf *timestamp, void (*callback)(const char *fn, void *), void *cookie, struct selabel_handle *sehnd) { @@ -932,30 +932,19 @@ bool mzExtractRecursive(const ZipArchive *pArchive, break; } - /* With DRY_RUN set, invoke the callback but don't do anything else. - */ - if (flags & MZ_EXTRACT_DRY_RUN) { - if (callback != NULL) callback(targetFile, cookie); - continue; - } - - /* Create the file or directory. - */ #define UNZIP_DIRMODE 0755 #define UNZIP_FILEMODE 0644 - if (pEntry->fileName[pEntry->fileNameLen-1] == '/') { - if (!(flags & MZ_EXTRACT_FILES_ONLY)) { - int ret = dirCreateHierarchy( - targetFile, UNZIP_DIRMODE, timestamp, false, sehnd); - if (ret != 0) { - LOGE("Can't create containing directory for \"%s\": %s\n", - targetFile, strerror(errno)); - ok = false; - break; - } - LOGD("Extracted dir \"%s\"\n", targetFile); - } - } else { + /* + * Create the file or directory. We ignore directory entries + * because we recursively create paths to each file entry we encounter + * in the zip archive anyway. + * + * NOTE: A "directory entry" in a zip archive is just a zero length + * entry that ends in a "/". They're not mandatory and many tools get + * rid of them. We need to process them only if we want to preserve + * empty directories from the archive. + */ + if (pEntry->fileName[pEntry->fileNameLen-1] != '/') { /* This is not a directory. First, make sure that * the containing directory exists. */ @@ -968,91 +957,56 @@ bool mzExtractRecursive(const ZipArchive *pArchive, break; } - /* With FILES_ONLY set, we need to ignore metadata entirely, - * so treat symlinks as regular files. + /* + * The entry is a regular file or a symlink. Open the target for writing. + * + * TODO: This behavior for symlinks seems rather bizarre. For a + * symlink foo/bar/baz -> foo/tar/taz, we will create a file called + * "foo/bar/baz" whose contents are the literal "foo/tar/taz". We + * warn about this for now and preserve older behavior. */ - if (!(flags & MZ_EXTRACT_FILES_ONLY) && mzIsZipEntrySymlink(pEntry)) { - /* The entry is a symbolic link. - * The relative target of the symlink is in the - * data section of this entry. - */ - if (pEntry->uncompLen == 0) { - LOGE("Symlink entry \"%s\" has no target\n", - targetFile); - ok = false; - break; - } - char *linkTarget = malloc(pEntry->uncompLen + 1); - if (linkTarget == NULL) { - ok = false; - break; - } - ok = mzReadZipEntry(pArchive, pEntry, linkTarget, - pEntry->uncompLen); - if (!ok) { - LOGE("Can't read symlink target for \"%s\"\n", - targetFile); - free(linkTarget); - break; - } - linkTarget[pEntry->uncompLen] = '\0'; - - /* Make the link. - */ - ret = symlink(linkTarget, targetFile); - if (ret != 0) { - LOGE("Can't symlink \"%s\" to \"%s\": %s\n", - targetFile, linkTarget, strerror(errno)); - free(linkTarget); - ok = false; - break; - } - LOGD("Extracted symlink \"%s\" -> \"%s\"\n", - targetFile, linkTarget); - free(linkTarget); - } else { - /* The entry is a regular file. - * Open the target for writing. - */ - - char *secontext = NULL; + if (mzIsZipEntrySymlink(pEntry)) { + LOGE("Symlink entry \"%.*s\" will be output as a regular file.", + pEntry->fileNameLen, pEntry->fileName); + } - if (sehnd) { - selabel_lookup(sehnd, &secontext, targetFile, UNZIP_FILEMODE); - setfscreatecon(secontext); - } + char *secontext = NULL; - int fd = creat(targetFile, UNZIP_FILEMODE); + if (sehnd) { + selabel_lookup(sehnd, &secontext, targetFile, UNZIP_FILEMODE); + setfscreatecon(secontext); + } - if (secontext) { - freecon(secontext); - setfscreatecon(NULL); - } + int fd = creat(targetFile, UNZIP_FILEMODE); - if (fd < 0) { - LOGE("Can't create target file \"%s\": %s\n", - targetFile, strerror(errno)); - ok = false; - break; - } + if (secontext) { + freecon(secontext); + setfscreatecon(NULL); + } - bool ok = mzExtractZipEntryToFile(pArchive, pEntry, fd); - close(fd); - if (!ok) { - LOGE("Error extracting \"%s\"\n", targetFile); - ok = false; - break; - } + if (fd < 0) { + LOGE("Can't create target file \"%s\": %s\n", + targetFile, strerror(errno)); + ok = false; + break; + } - if (timestamp != NULL && utime(targetFile, timestamp)) { - LOGE("Error touching \"%s\"\n", targetFile); - ok = false; - break; - } + bool ok = mzExtractZipEntryToFile(pArchive, pEntry, fd); + close(fd); + if (!ok) { + LOGE("Error extracting \"%s\"\n", targetFile); + ok = false; + break; + } - LOGV("Extracted file \"%s\"\n", targetFile); - ++extractCount; + if (timestamp != NULL && utime(targetFile, timestamp)) { + LOGE("Error touching \"%s\"\n", targetFile); + ok = false; + break; } + + LOGV("Extracted file \"%s\"\n", targetFile); + ++extractCount; } if (callback != NULL) callback(targetFile, cookie); |