/* * Uncompress an entry, in its entirety, to an open file descriptor. * * TODO: this doesn't verify the data's CRC, but probably should (especially * for uncompressed data). */ bool dexZipExtractEntryToFile(const ZipArchive* pArchive, const ZipEntry entry, int fd) { bool result = false; int ent = entryToIndex(pArchive, entry); if (ent < 0) return -1; const unsigned char* basePtr = (const unsigned char*)pArchive->mMap.addr; int method; long uncompLen, compLen; off_t offset; if (!dexZipGetEntryInfo(pArchive, entry, &method, &uncompLen, &compLen, &offset, NULL, NULL)) { goto bail; } if (method == kCompressStored) { ssize_t actual; actual = write(fd, basePtr + offset, uncompLen); if (actual < 0) { LOGE("Write failed: %s\n", strerror(errno)); goto bail; } else if (actual != uncompLen) { LOGE("Partial write during uncompress (%d of %ld)\n", (int) actual, uncompLen); goto bail; } else { LOGI("+++ successful write\n"); } } else { if (!inflateToFile(fd, basePtr+offset, uncompLen, compLen)) goto bail; } result = true; bail: return result; }
/* * Uncompress an entry, in its entirety, to an open file descriptor. * * TODO: this doesn't verify the data's CRC, but probably should (especially * for uncompressed data). */ int dexZipExtractEntryToFile(const ZipArchive* pArchive, const ZipEntry entry, int fd) { int result = -1; int ent = entryToIndex(pArchive, entry); if (ent < 0) { LOGW("Zip: extract can't find entry %p\n", entry); goto bail; } int method; size_t uncompLen, compLen; off_t dataOffset; if (dexZipGetEntryInfo(pArchive, entry, &method, &uncompLen, &compLen, &dataOffset, NULL, NULL) != 0) { goto bail; } if (lseek(pArchive->mFd, dataOffset, SEEK_SET) != dataOffset) { LOGW("Zip: lseek to data at %ld failed\n", (long) dataOffset); goto bail; } if (method == kCompressStored) { if (copyFileToFile(pArchive->mFd, fd, uncompLen) != 0) goto bail; } else { if (inflateToFile(pArchive->mFd, fd, uncompLen, compLen) != 0) goto bail; } result = 0; bail: return result; }