List of usage examples for org.apache.commons.compress.archivers.zip ZipArchiveEntry getSize
public long getSize()
From source file:at.spardat.xma.xdelta.JarDelta.java
/** * Compute delta./*from w ww. j a va2 s . c o m*/ * * @param source the source * @param target the target * @param output the output * @param list the list * @param prefix the prefix * @throws IOException Signals that an I/O exception has occurred. */ public void computeDelta(ZipFile source, ZipFile target, ZipArchiveOutputStream output, PrintWriter list, String prefix) throws IOException { try { for (Enumeration<ZipArchiveEntry> enumer = target.getEntries(); enumer.hasMoreElements();) { calculatedDelta = null; ZipArchiveEntry targetEntry = enumer.nextElement(); ZipArchiveEntry sourceEntry = findBestSource(source, target, targetEntry); String nextEntryName = prefix + targetEntry.getName(); if (sourceEntry != null && zipFilesPattern.matcher(sourceEntry.getName()).matches() && !equal(sourceEntry, targetEntry)) { nextEntryName += "!"; } nextEntryName += "|" + Long.toHexString(targetEntry.getCrc()); if (sourceEntry != null) { nextEntryName += ":" + Long.toHexString(sourceEntry.getCrc()); } else { nextEntryName += ":0"; } list.println(nextEntryName); if (targetEntry.isDirectory()) { if (sourceEntry == null) { ZipArchiveEntry outputEntry = entryToNewName(targetEntry, prefix + targetEntry.getName()); output.putArchiveEntry(outputEntry); output.closeArchiveEntry(); } } else { if (sourceEntry == null || sourceEntry.getSize() <= Delta.DEFAULT_CHUNK_SIZE || targetEntry.getSize() <= Delta.DEFAULT_CHUNK_SIZE) { // new Entry od. alter Eintrag od. neuer Eintrag leer ZipArchiveEntry outputEntry = entryToNewName(targetEntry, prefix + targetEntry.getName()); output.putArchiveEntry(outputEntry); try (InputStream in = target.getInputStream(targetEntry)) { int read = 0; while (-1 < (read = in.read(buffer))) { output.write(buffer, 0, read); } output.flush(); } output.closeArchiveEntry(); } else { if (!equal(sourceEntry, targetEntry)) { if (zipFilesPattern.matcher(sourceEntry.getName()).matches()) { File embeddedTarget = File.createTempFile("jardelta-tmp", ".zip"); File embeddedSource = File.createTempFile("jardelta-tmp", ".zip"); try (FileOutputStream out = new FileOutputStream(embeddedSource); InputStream in = source.getInputStream(sourceEntry); FileOutputStream out2 = new FileOutputStream(embeddedTarget); InputStream in2 = target.getInputStream(targetEntry)) { int read = 0; while (-1 < (read = in.read(buffer))) { out.write(buffer, 0, read); } out.flush(); read = 0; while (-1 < (read = in2.read(buffer))) { out2.write(buffer, 0, read); } out2.flush(); computeDelta(new ZipFile(embeddedSource), new ZipFile(embeddedTarget), output, list, prefix + sourceEntry.getName() + "!"); } finally { embeddedSource.delete(); embeddedTarget.delete(); } } else { ZipArchiveEntry outputEntry = new ZipArchiveEntry( prefix + targetEntry.getName() + ".gdiff"); outputEntry.setTime(targetEntry.getTime()); outputEntry.setComment("" + targetEntry.getCrc()); output.putArchiveEntry(outputEntry); if (calculatedDelta != null) { output.write(calculatedDelta); output.flush(); } else { try (ByteArrayOutputStream outbytes = new ByteArrayOutputStream()) { Delta d = new Delta(); DiffWriter diffWriter = new GDiffWriter(new DataOutputStream(outbytes)); int sourceSize = (int) sourceEntry.getSize(); byte[] sourceBytes = new byte[sourceSize]; try (InputStream sourceStream = source.getInputStream(sourceEntry)) { for (int erg = sourceStream.read( sourceBytes); erg < sourceBytes.length; erg += sourceStream .read(sourceBytes, erg, sourceBytes.length - erg)) ; } d.compute(sourceBytes, target.getInputStream(targetEntry), diffWriter); output.write(outbytes.toByteArray()); } } output.closeArchiveEntry(); } } } } } } finally { source.close(); target.close(); } }
From source file:at.spardat.xma.xdelta.JarPatcher.java
/** * Apply delta./*from w w w .j a v a2 s. c o m*/ * * @param patch the patch * @param source the source * @param output the output * @param list the list * @param prefix the prefix * @throws IOException Signals that an I/O exception has occurred. */ public void applyDelta(ZipFile patch, ZipFile source, ZipArchiveOutputStream output, BufferedReader list, String prefix) throws IOException { String fileName = null; try { for (fileName = (next == null ? list.readLine() : next); fileName != null; fileName = (next == null ? list.readLine() : next)) { if (next != null) next = null; if (!fileName.startsWith(prefix)) { next = fileName; return; } int crcDelim = fileName.lastIndexOf(':'); int crcStart = fileName.lastIndexOf('|'); long crc = Long.valueOf(fileName.substring(crcStart + 1, crcDelim), 16); long crcSrc = Long.valueOf(fileName.substring(crcDelim + 1), 16); fileName = fileName.substring(prefix.length(), crcStart); if ("META-INF/file.list".equalsIgnoreCase(fileName)) continue; if (fileName.contains("!")) { String[] embeds = fileName.split("\\!"); ZipArchiveEntry original = getEntry(source, embeds[0], crcSrc); File originalFile = File.createTempFile("jardelta-tmp-origin-", ".zip"); File outputFile = File.createTempFile("jardelta-tmp-output-", ".zip"); Exception thrown = null; try (FileOutputStream out = new FileOutputStream(originalFile); InputStream in = source.getInputStream(original)) { int read = 0; while (-1 < (read = in.read(buffer))) { out.write(buffer, 0, read); } out.flush(); applyDelta(patch, new ZipFile(originalFile), new ZipArchiveOutputStream(outputFile), list, prefix + embeds[0] + "!"); } catch (Exception e) { thrown = e; throw e; } finally { originalFile.delete(); try (FileInputStream in = new FileInputStream(outputFile)) { if (thrown == null) { ZipArchiveEntry outEntry = copyEntry(original); output.putArchiveEntry(outEntry); int read = 0; while (-1 < (read = in.read(buffer))) { output.write(buffer, 0, read); } output.flush(); output.closeArchiveEntry(); } } finally { outputFile.delete(); } } } else { try { ZipArchiveEntry patchEntry = getEntry(patch, prefix + fileName, crc); if (patchEntry != null) { // new Entry ZipArchiveEntry outputEntry = JarDelta.entryToNewName(patchEntry, fileName); output.putArchiveEntry(outputEntry); if (!patchEntry.isDirectory()) { try (InputStream in = patch.getInputStream(patchEntry)) { int read = 0; while (-1 < (read = in.read(buffer))) { output.write(buffer, 0, read); } } } closeEntry(output, outputEntry, crc); } else { ZipArchiveEntry sourceEntry = getEntry(source, fileName, crcSrc); if (sourceEntry == null) { throw new FileNotFoundException( fileName + " not found in " + sourceName + " or " + patchName); } if (sourceEntry.isDirectory()) { ZipArchiveEntry outputEntry = new ZipArchiveEntry(sourceEntry); output.putArchiveEntry(outputEntry); closeEntry(output, outputEntry, crc); continue; } patchEntry = getPatchEntry(patch, prefix + fileName + ".gdiff", crc); if (patchEntry != null) { // changed Entry ZipArchiveEntry outputEntry = new ZipArchiveEntry(sourceEntry); outputEntry.setTime(patchEntry.getTime()); output.putArchiveEntry(outputEntry); byte[] sourceBytes = new byte[(int) sourceEntry.getSize()]; try (InputStream sourceStream = source.getInputStream(sourceEntry)) { for (int erg = sourceStream .read(sourceBytes); erg < sourceBytes.length; erg += sourceStream .read(sourceBytes, erg, sourceBytes.length - erg)) ; } InputStream patchStream = patch.getInputStream(patchEntry); GDiffPatcher diffPatcher = new GDiffPatcher(); diffPatcher.patch(sourceBytes, patchStream, output); patchStream.close(); outputEntry.setCrc(crc); closeEntry(output, outputEntry, crc); } else { // unchanged Entry ZipArchiveEntry outputEntry = new ZipArchiveEntry(sourceEntry); output.putArchiveEntry(outputEntry); try (InputStream in = source.getInputStream(sourceEntry)) { int read = 0; while (-1 < (read = in.read(buffer))) { output.write(buffer, 0, read); } } output.flush(); closeEntry(output, outputEntry, crc); } } } catch (PatchException pe) { IOException ioe = new IOException(); ioe.initCause(pe); throw ioe; } } } } catch (Exception e) { System.err.println(prefix + fileName); throw e; } finally { source.close(); output.close(); } }
From source file:adams.core.io.ZipUtils.java
/** * Unzips the specified file from a ZIP file. * * @param input the ZIP file to unzip// www . jav a2s . com * @param archiveFile the file from the archive to extract * @param output the name of the output file * @param createDirs whether to create the directory structure represented * by output file * @param bufferSize the buffer size to use * @param errors for storing potential errors * @return whether file was successfully extracted */ public static boolean decompress(File input, String archiveFile, File output, boolean createDirs, int bufferSize, StringBuilder errors) { boolean result; ZipFile zipfile; Enumeration<ZipArchiveEntry> enm; ZipArchiveEntry entry; File outFile; String outName; byte[] buffer; BufferedInputStream in; BufferedOutputStream out; FileOutputStream fos; int len; String error; long read; result = false; zipfile = null; try { // unzip archive buffer = new byte[bufferSize]; zipfile = new ZipFile(input.getAbsoluteFile()); enm = zipfile.getEntries(); while (enm.hasMoreElements()) { entry = enm.nextElement(); if (entry.isDirectory()) continue; if (!entry.getName().equals(archiveFile)) continue; in = null; out = null; fos = null; outName = null; try { // output name outName = output.getAbsolutePath(); // create directory, if necessary outFile = new File(outName).getParentFile(); if (!outFile.exists()) { if (!createDirs) { error = "Output directory '" + outFile.getAbsolutePath() + " does not exist', " + "skipping extraction of '" + outName + "'!"; System.err.println(error); errors.append(error + "\n"); break; } else { if (!outFile.mkdirs()) { error = "Failed to create directory '" + outFile.getAbsolutePath() + "', " + "skipping extraction of '" + outName + "'!"; System.err.println(error); errors.append(error + "\n"); break; } } } // extract data in = new BufferedInputStream(zipfile.getInputStream(entry)); fos = new FileOutputStream(outName); out = new BufferedOutputStream(fos, bufferSize); read = 0; while (read < entry.getSize()) { len = in.read(buffer); read += len; out.write(buffer, 0, len); } result = true; break; } catch (Exception e) { result = false; error = "Error extracting '" + entry.getName() + "' to '" + outName + "': " + e; System.err.println(error); errors.append(error + "\n"); } finally { FileUtils.closeQuietly(in); FileUtils.closeQuietly(out); FileUtils.closeQuietly(fos); } } } catch (Exception e) { result = false; e.printStackTrace(); errors.append("Error occurred: " + e + "\n"); } finally { if (zipfile != null) { try { zipfile.close(); } catch (Exception e) { // ignored } } } return result; }
From source file:adams.core.io.ZipUtils.java
/** * Unzips the files in a ZIP file. Files can be filtered based on their * filename, using a regular expression (the matching sense can be inverted). * * @param input the ZIP file to unzip//from w w w. j a va 2 s . co m * @param outputDir the directory where to store the extracted files * @param createDirs whether to re-create the directory structure from the * ZIP file * @param match the regular expression that the files are matched against * @param invertMatch whether to invert the matching sense * @param bufferSize the buffer size to use * @param errors for storing potential errors * @return the successfully extracted files */ @MixedCopyright(copyright = "Apache compress commons", license = License.APACHE2, url = "http://commons.apache.org/compress/examples.html") public static List<File> decompress(File input, File outputDir, boolean createDirs, BaseRegExp match, boolean invertMatch, int bufferSize, StringBuilder errors) { List<File> result; ZipFile archive; Enumeration<ZipArchiveEntry> enm; ZipArchiveEntry entry; File outFile; String outName; byte[] buffer; BufferedInputStream in; BufferedOutputStream out; FileOutputStream fos; int len; String error; long read; result = new ArrayList<>(); archive = null; try { // unzip archive buffer = new byte[bufferSize]; archive = new ZipFile(input.getAbsoluteFile()); enm = archive.getEntries(); while (enm.hasMoreElements()) { entry = enm.nextElement(); if (entry.isDirectory() && !createDirs) continue; // does name match? if (!match.isMatchAll() && !match.isEmpty()) { if (invertMatch && match.isMatch(entry.getName())) continue; else if (!invertMatch && !match.isMatch(entry.getName())) continue; } // extract if (entry.isDirectory() && createDirs) { outFile = new File(outputDir.getAbsolutePath() + File.separator + entry.getName()); if (!outFile.mkdirs()) { error = "Failed to create directory '" + outFile.getAbsolutePath() + "'!"; System.err.println(error); errors.append(error + "\n"); } } else { in = null; out = null; fos = null; outName = null; try { // assemble output name outName = outputDir.getAbsolutePath() + File.separator; if (createDirs) outName += entry.getName(); else outName += new File(entry.getName()).getName(); // create directory, if necessary outFile = new File(outName).getParentFile(); if (!outFile.exists()) { if (!outFile.mkdirs()) { error = "Failed to create directory '" + outFile.getAbsolutePath() + "', " + "skipping extraction of '" + outName + "'!"; System.err.println(error); errors.append(error + "\n"); continue; } } // extract data in = new BufferedInputStream(archive.getInputStream(entry)); fos = new FileOutputStream(outName); out = new BufferedOutputStream(fos, bufferSize); read = 0; while (read < entry.getSize()) { len = in.read(buffer); read += len; out.write(buffer, 0, len); } result.add(new File(outName)); } catch (Exception e) { error = "Error extracting '" + entry.getName() + "' to '" + outName + "': " + e; System.err.println(error); errors.append(error + "\n"); } finally { FileUtils.closeQuietly(in); FileUtils.closeQuietly(out); FileUtils.closeQuietly(fos); } } } } catch (Exception e) { e.printStackTrace(); errors.append("Error occurred: " + e + "\n"); } finally { if (archive != null) { try { archive.close(); } catch (Exception e) { // ignored } } } return result; }
From source file:io.personium.core.bar.BarFileReadRunner.java
/** * bar???.// w w w .j a va 2 s . com */ public void run() { boolean isSuccess = true; String path = "/" + this.cell.getName() + "/" + boxName + "/"; log.debug("install target: " + path); try { List<String> doneKeys = new ArrayList<String>(); try { this.zipArchiveInputStream = new ZipArchiveInputStream(new FileInputStream(barFile)); } catch (IOException e) { throw PersoniumCoreException.Server.FILE_SYSTEM_ERROR.params(e.getMessage()); } // ("bar/")?? if (!isRootDir()) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", ROOT_DIR, message); isSuccess = false; return; } // 00_meta?? if (!isMetadataDir()) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", META_DIR, message); isSuccess = false; return; } // 00_meta??? ZipArchiveEntry zae = null; try { long maxBarEntryFileSize = getMaxBarEntryFileSize(); Set<String> keyList = barFileOrder.keySet(); while ((zae = this.zipArchiveInputStream.getNextZipEntry()) != null) { String entryName = zae.getName(); log.debug("Entry Name: " + entryName); log.debug("Entry Size: " + zae.getSize()); log.debug("Entry Compressed Size: " + zae.getCompressedSize()); if (!zae.isDirectory()) { this.progressInfo.addDelta(1L); } // bar?? isSuccess = createMetadata(zae, entryName, maxBarEntryFileSize, keyList, doneKeys); if (!isSuccess) { break; } // 90_contents?????? if (isContentsDir(zae)) { if (davCmpMap.isEmpty()) { writeOutputStream(true, "PL-BI-1004", zae.getName()); isSuccess = false; } else { writeOutputStream(false, "PL-BI-1003", zae.getName()); } doneKeys.add(zae.getName()); break; } } } catch (IOException ex) { isSuccess = false; log.info("IOException: " + ex.getMessage(), ex.fillInStackTrace()); } // 90_contents()??? if (isSuccess && isContentsDir(zae)) { isSuccess = createContents(); } // ?????????? // ??????? if (isSuccess) { Set<String> filenameList = barFileOrder.keySet(); for (String filename : filenameList) { Boolean isNecessary = barFileOrder.get(filename); if (isNecessary && !doneKeys.contains(filename)) { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", filename, message); isSuccess = false; } } } } catch (Throwable ex) { isSuccess = false; String message = getErrorMessage(ex); log.info("Exception: " + message, ex.fillInStackTrace()); writeOutputStream(true, "PL-BI-1005", "", message); } finally { if (isSuccess) { writeOutputStream(false, CODE_BAR_INSTALL_COMPLETED, this.cell.getUrl() + boxName, ""); this.progressInfo.setStatus(ProgressInfo.STATUS.COMPLETED); } else { String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(false, CODE_BAR_INSTALL_FAILED, this.cell.getUrl() + boxName, message); this.progressInfo.setStatus(ProgressInfo.STATUS.FAILED); } this.progressInfo.setEndTime(); writeToProgressCache(true); IOUtils.closeQuietly(this.zipArchiveInputStream); if (this.barFile.exists() && !this.barFile.delete()) { log.warn("Failed to remove bar file. [" + this.barFile.getAbsolutePath() + "]."); } } }
From source file:com.fujitsu.dc.core.bar.BarFileReadRunner.java
/** * bar???.//from www. ja v a 2s . co m */ public void run() { boolean isSuccess = true; String path = "/" + this.cell.getName() + "/" + boxName + "/"; log.debug("install target: " + path); try { List<String> doneKeys = new ArrayList<String>(); try { this.zipArchiveInputStream = new ZipArchiveInputStream(new FileInputStream(barFile)); } catch (IOException e) { throw DcCoreException.Server.FILE_SYSTEM_ERROR.params(e.getMessage()); } // ("bar/")?? if (!isRootDir()) { String message = DcCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", ROOT_DIR, message); isSuccess = false; return; } // 00_meta?? if (!isMetadataDir()) { String message = DcCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", META_DIR, message); isSuccess = false; return; } // 00_meta??? ZipArchiveEntry zae = null; try { long maxBarEntryFileSize = getMaxBarEntryFileSize(); Set<String> keyList = barFileOrder.keySet(); while ((zae = this.zipArchiveInputStream.getNextZipEntry()) != null) { String entryName = zae.getName(); log.debug("Entry Name: " + entryName); log.debug("Entry Size: " + zae.getSize()); log.debug("Entry Compressed Size: " + zae.getCompressedSize()); if (!zae.isDirectory()) { this.progressInfo.addDelta(1L); } // bar?? isSuccess = createMetadata(zae, entryName, maxBarEntryFileSize, keyList, doneKeys); if (!isSuccess) { break; } // 90_contents?????? if (isContentsDir(zae)) { if (davCmpMap.isEmpty()) { writeOutputStream(true, "PL-BI-1004", zae.getName()); isSuccess = false; } else { writeOutputStream(false, "PL-BI-1003", zae.getName()); } doneKeys.add(zae.getName()); break; } } } catch (IOException ex) { isSuccess = false; log.info("IOException: " + ex.getMessage(), ex.fillInStackTrace()); } // 90_contents()??? if (isSuccess && isContentsDir(zae)) { isSuccess = createContents(); } // ?????????? // ??????? if (isSuccess) { Set<String> filenameList = barFileOrder.keySet(); for (String filename : filenameList) { Boolean isNecessary = barFileOrder.get(filename); if (isNecessary && !doneKeys.contains(filename)) { String message = DcCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(true, "PL-BI-1004", filename, message); isSuccess = false; } } } } catch (Throwable ex) { isSuccess = false; String message = getErrorMessage(ex); log.info("Exception: " + message, ex.fillInStackTrace()); writeOutputStream(true, "PL-BI-1005", "", message); } finally { if (isSuccess) { writeOutputStream(false, CODE_BAR_INSTALL_COMPLETED, this.cell.getUrl() + boxName, ""); this.progressInfo.setStatus(ProgressInfo.STATUS.COMPLETED); } else { String message = DcCoreMessageUtils.getMessage("PL-BI-2001"); writeOutputStream(false, CODE_BAR_INSTALL_FAILED, this.cell.getUrl() + boxName, message); this.progressInfo.setStatus(ProgressInfo.STATUS.FAILED); } this.progressInfo.setEndTime(); writeToProgressCache(true); IOUtils.closeQuietly(this.zipArchiveInputStream); if (this.barFile.exists() && !this.barFile.delete()) { log.warn("Failed to remove bar file. [" + this.barFile.getAbsolutePath() + "]."); } } }
From source file:cz.muni.fi.xklinec.zipstream.Mallory.java
/** * Entry point. /* w ww. j ava2s. co m*/ * * @param args * @throws FileNotFoundException * @throws IOException * @throws NoSuchFieldException * @throws ClassNotFoundException * @throws NoSuchMethodException * @throws java.lang.InterruptedException * @throws java.lang.CloneNotSupportedException */ public void doMain(String[] args) throws FileNotFoundException, IOException, NoSuchFieldException, ClassNotFoundException, NoSuchMethodException, InterruptedException, CloneNotSupportedException { // command line argument parser CmdLineParser parser = new CmdLineParser(this); // if you have a wider console, you could increase the value; // here 80 is also the default parser.setUsageWidth(80); try { // parse the arguments. parser.parseArgument(args); } catch (CmdLineException e) { // if there's a problem in the command line, // you'll get this exception. this will report // an error message. System.err.println(e.getMessage()); System.err.println("java Mallory [options...] arguments..."); // print the list of available options parser.printUsage(System.err); System.err.println(); // print option sample. This is useful some time System.err.println(" Example: java Mallory " + parser.printExample(ExampleMode.ALL)); return; } if (arguments.size() == 2) { final String a0 = arguments.get(0); final String a1 = arguments.get(1); if (!quiet) System.err .println(String.format("Will use file [%s] as input file and [%s] as output file", a0, a1)); fis = new FileInputStream(a0); fos = new FileOutputStream(a1); } else if (arguments.isEmpty()) { if (!quiet) System.err .println(String.format("Will use file [STDIN] as input file and [STDOUT] as output file")); fis = System.in; fos = System.out; } else { if (!quiet) System.err.println("I do not understand the usage."); return; } if (zipAlign) { System.err.println("WARNING: ZIP Align feature not implemented yet..."); return; } // Deflater to re-compress uncompressed data read from ZIP stream. def = new Deflater(9, true); sentFiles = new HashSet<String>(); // Buffer input stream so input stream is read in chunks bis = new BufferedInputStream(fis); bos = new BufferedOutputStream(fos); // Effective temporary dir - if separate is required if (separateTempDir) { effectiveTempDir = File.createTempFile("temp_apk_dir_", "", new File(TEMP_DIR)); effectiveTempDir.delete(); effectiveTempDir.mkdir(); } else { effectiveTempDir = new File(TEMP_DIR); } // Generate temporary APK filename tempApk = File.createTempFile("temp_apk_", ".apk", effectiveTempDir); if (tempApk.canWrite() == false) { throw new IOException("Temp file is not writable!"); } FileOutputStream tos = new FileOutputStream(tempApk); // What we want here is to read input stream from the socket/pipe // whatever, process it in ZIP logic and simultaneously to copy // all read data to the temporary file - this reminds tee command // logic. This functionality can be found in TeeInputStream. TeeInputStream tis = new TeeInputStream(bis, tos); // Providing tis to ZipArchiveInputStream will copy all read data // to temporary tos file. zip = new ZipArchiveInputStream(tis); // List of all sent files, with data and hashes alMap = new HashMap<String, PostponedEntry>(); // Output stream // If there is defined slow down stream, it is used for user output to // mitigate tampering time gap. OutputStream osToUse = bos; SlowDownStream sdStream = null; if (slowDownStream) { // New slow down output stream with internal pipe buffer 15MB. sdStream = new SlowDownStream(osToUse, 15 * 1024 * 1024); // If size of the APK is known, use it to set slow down parameters correctly. if (apkSize > 0) { setSlowDownParams(); } if (!quiet) { System.err.println(String.format("Slown down stream will be used; apkSize=%d buffer=%d timeout=%d", apkSize, slowDownBuffer, slowDownTimeout)); } sdStream.setFlushBufferSize(slowDownBuffer); sdStream.setFlushBufferTimeout(slowDownTimeout); sdStream.start(); osToUse = sdStream; } zop = new ZipArchiveOutputStream(osToUse); zop.setLevel(9); if (!quiet) { System.err.println("Patterns that will be excluded:"); for (String regex : exclude) { System.err.println(" '" + regex + "'"); } System.err.println(); } // Read the archive ZipArchiveEntry ze = zip.getNextZipEntry(); while (ze != null) { ZipExtraField[] extra = ze.getExtraFields(true); byte[] lextra = ze.getLocalFileDataExtra(); UnparseableExtraFieldData uextra = ze.getUnparseableExtraFieldData(); byte[] uextrab = uextra != null ? uextra.getLocalFileDataData() : null; byte[] ex = ze.getExtra(); // ZipArchiveOutputStream.DEFLATED // // Data for entry byte[] byteData = Utils.readAll(zip); byte[] deflData = new byte[0]; int infl = byteData.length; int defl = 0; // If method is deflated, get the raw data (compress again). // Since ZIPStream automatically decompresses deflated files in read(). if (ze.getMethod() == ZipArchiveOutputStream.DEFLATED) { def.reset(); def.setInput(byteData); def.finish(); byte[] deflDataTmp = new byte[byteData.length * 2]; defl = def.deflate(deflDataTmp); deflData = new byte[defl]; System.arraycopy(deflDataTmp, 0, deflData, 0, defl); } if (!quiet) System.err.println(String.format( "ZipEntry: meth=%d " + "size=%010d isDir=%5s " + "compressed=%07d extra=%d lextra=%d uextra=%d ex=%d " + "comment=[%s] " + "dataDesc=%s " + "UTF8=%s " + "infl=%07d defl=%07d " + "name [%s]", ze.getMethod(), ze.getSize(), ze.isDirectory(), ze.getCompressedSize(), extra != null ? extra.length : -1, lextra != null ? lextra.length : -1, uextrab != null ? uextrab.length : -1, ex != null ? ex.length : -1, ze.getComment(), ze.getGeneralPurposeBit().usesDataDescriptor(), ze.getGeneralPurposeBit().usesUTF8ForNames(), infl, defl, ze.getName())); final String curName = ze.getName(); // Store zip entry to the map for later check after the APK is recompiled. // Hashes will be compared with the modified APK files after the process. PostponedEntry al = new PostponedEntry(ze, byteData, deflData); alMap.put(curName, al); // META-INF files should be always on the end of the archive, // thus add postponed files right before them if (isPostponed(ze)) { // Capturing interesting files for us and store for later. // If the file is not interesting, send directly to the stream. if (!quiet) System.err.println(" Interesting file, postpone sending!!!"); } else { // recompute CRC? if (recomputeCrc) { crc.reset(); crc.update(byteData); final long newCrc = crc.getValue(); if (!quiet && ze.getCrc() != newCrc && ze.getCrc() != -1) { System.err.println(" Warning: file CRC mismatch!!! Original: [" + ze.getCrc() + "] real: [" + newCrc + "]"); } ze.setCrc(newCrc); } // Write ZIP entry to the archive zop.putArchiveEntry(ze); // Add file data to the stream zop.write(byteData, 0, infl); zop.closeArchiveEntry(); zop.flush(); // Mark file as sent. addSent(curName); } ze = zip.getNextZipEntry(); } // Flush buffers zop.flush(); fos.flush(); // Cleaning up stuff, all reading streams can be closed now. zip.close(); bis.close(); fis.close(); tis.close(); tos.close(); // // APK is finished here, all non-interesting files were sent to the // zop strem (socket to the victim). Now APK transformation will // be performed, diff, sending rest of the files to zop. // boolean doPadding = paddExtra > 0 || outBytes > 0; long flen = tempApk.length(); if (outBytes <= 0) { outBytes = flen + paddExtra; } if (!quiet) { System.err.println("\nAPK reading finished, going to tamper downloaded " + " APK file [" + tempApk.toString() + "]; filezise=[" + flen + "]"); System.err.println(String.format("Sent so far: %d kB in %f %% after adding padding it is %f %%", zop.getWritten() / 1024, 100.0 * (double) zop.getWritten() / (double) flen, 100.0 * (double) zop.getWritten() / ((double) (outBytes > 0 ? outBytes : flen)))); } // New APK was generated, new filename = "tempApk_tampered" newApk = new File(outFile == null ? getFileName(tempApk.getAbsolutePath()) : outFile); if (cmd == null) { // Simulation of doing some evil stuff on the temporary apk Thread.sleep(3000); if (!quiet) System.err.println( "Tampered APK file: " + " [" + newApk.toString() + "]; filezise=[" + newApk.length() + "]"); // // Since no tampering was performed right now we will simulate it by just simple // copying the APK file // FileUtils.copyFile(tempApk, newApk); } else { try { // Execute command String cmd2exec; switch (cmdFormat) { case 0: cmd2exec = cmd + " " + tempApk.getAbsolutePath(); break; case 1: cmd2exec = cmd.replaceAll(INPUT_APK_PLACEHOLDER, tempApk.getAbsolutePath()); break; case 2: cmd2exec = cmd.replaceAll(INPUT_APK_PLACEHOLDER, tempApk.getAbsolutePath()); cmd2exec = cmd2exec.replaceAll(OUTPUT_APK_PLACEHOLDER, newApk.getAbsolutePath()); break; default: throw new IllegalArgumentException("Unknown command format number"); } if (!quiet) { System.err.println("Command to be executed: " + cmd2exec); System.err.println("\n<CMDOUTPUT>"); } long cmdStartTime = System.currentTimeMillis(); CmdExecutionResult resExec = execute(cmd2exec, OutputOpt.EXECUTE_STD_COMBINE, null, quiet ? null : System.err); long cmdStopTime = System.currentTimeMillis(); if (!quiet) { System.err.println("</CMDOUTPUT>\n"); System.err.println("Command executed. Return value: " + resExec.exitValue + "; tamperingTime=" + (cmdStopTime - cmdStartTime)); } } catch (IOException e) { if (!quiet) e.printStackTrace(System.err); } } // // Now read new APK file with ZipInputStream and push new/modified files to the ZOP. // fis = new FileInputStream(newApk); bis = new BufferedInputStream(fis); zip = new ZipArchiveInputStream(bis); // Merge tampered APK to the final, but in this first time // do it to the external buffer in order to get final apk size. // Backup ZOP state to the clonned instance. zop.flush(); long writtenBeforeDiff = zop.getWritten(); ZipArchiveOutputStream zop_back = zop; zop = zop.cloneThis(); // Set temporary byte array output stream, so original output stream is not // touched in this phase. ByteArrayOutputStream bbos = new ByteArrayOutputStream(); zop.setOut(bbos); mergeTamperedApk(false, false); zop.flush(); // Now output stream almost contains APK file, central directory is not written yet. long writtenAfterDiff = zop.getWritten(); if (!quiet) System.err.println(String.format("Tampered apk size yet; writtenBeforeDiff=%d writtenAfterDiff=%d", writtenBeforeDiff, writtenAfterDiff)); // Write central directory header to temporary buffer to discover its size. zop.writeFinish(); zop.flush(); bbos.flush(); // Read new values long writtenAfterCentralDir = zop.getWritten(); long centralDirLen = zop.getCdLength(); byte[] buffAfterMerge = bbos.toByteArray(); //int endOfCentralDir = (int) (buffAfterMerge.length - (writtenAfterCentralDir-writtenBeforeDiff)); long endOfCentralDir = END_OF_CENTRAL_DIR_SIZE; // Determine number of bytes to add to APK. // padlen is number of bytes missing in APK to meet desired size in bytes. padlen = doPadding ? (outBytes - (writtenAfterCentralDir + endOfCentralDir)) : 0; // Compute number of files needed for padding. int padfiles = (int) Math.ceil((double) padlen / (double) (PAD_BLOCK_MAX)); if (!quiet) System.err.println(String.format("Remaining to pad=%d, padfiles=%d " + "writtenAfterCentralDir=%d " + "centralDir=%d endOfCentralDir=%d centralDirOffset=%d " + "buffSize=%d total=%d desired=%d ", padlen, padfiles, writtenAfterCentralDir, centralDirLen, endOfCentralDir, zop.getCdOffset(), buffAfterMerge.length, writtenAfterCentralDir + endOfCentralDir, outBytes)); if (padlen < 0) { throw new IllegalStateException("Padlen cannot be negative, please increase padding size"); } // Close input streams for tampered APK try { zip.close(); bis.close(); fis.close(); } catch (Exception e) { if (!quiet) e.printStackTrace(System.err); } // Merge again, now with pre-defined padding size. fis = new FileInputStream(newApk); bis = new BufferedInputStream(fis); zip = new ZipArchiveInputStream(bis); // Revert changes - use clonned writer stream. zop = zop_back; long writtenBeforeDiff2 = zop.getWritten(); // Merge tampered APK, now for real, now with computed padding. mergeTamperedApk(true, true); zop.flush(); long writtenAfterMerge2 = zop.getWritten(); // Finish really zop.finish(); zop.flush(); long writtenReally = zop.getWritten(); long centralDirLen2 = zop.getCdLength(); if (!quiet) System.err.println(String.format( "Write stats; " + "writtenBeforeDiff=%d writtenAfterDiff=%d " + "writtenAfterCentralDir=%d centralDir=%d endOfCd=%d centralDirOffset=%d " + "padlen=%d total=%d desired=%d", writtenBeforeDiff2, writtenAfterMerge2, writtenReally, centralDirLen2, endOfCentralDir, zop.getCdOffset(), padlen, writtenReally + endOfCentralDir, outBytes)); // Will definitelly close (and finish if not yet) ZOP stream // and close underlying stream. zop.close(); if (sdStream != null) { if (!quiet) { System.err.println("Waiting for sdStream to finish..."); } // Wait for stream to finish dumping with pre-set speed, if it takes // too long (1 minute) switch slown down stream to dumping mode // without any waiting. long startedDump = System.currentTimeMillis(); while (sdStream.isRunning()) { long curTime = System.currentTimeMillis(); if (startedDump != -1 && (curTime - startedDump) > 1000 * 120) { startedDump = -1; sdStream.flushPipes(); } Thread.sleep(10); } if (!quiet) { System.err.println("SD stream finished, terminating..."); } } // Should always be same if (!quiet && doPadding && writtenBeforeDiff != writtenBeforeDiff2) { System.err.println(String.format("Warning! Size before merge from pass1 and pass2 does not match.")); } // If size is different, something went wrong. if (!quiet && doPadding && ((writtenReally + endOfCentralDir) != outBytes)) { System.err.println(String.format("Warning! Output size differs from desired size.")); } bos.close(); fos.close(); // Delete temporary files if required if (deleteArtefacts) { try { if (newApk.exists()) { newApk.delete(); if (!quiet) System.err.println("Tampered APK removed. " + newApk.getAbsolutePath()); } if (tempApk.exists()) { tempApk.delete(); if (!quiet) System.err.println("Original APK removed. " + tempApk.getAbsolutePath()); } if (separateTempDir && effectiveTempDir.exists()) { FileUtils.deleteDirectory(effectiveTempDir); if (!quiet) System.err.println("Temporary directory removed. " + effectiveTempDir.getAbsolutePath()); } if (!quiet) System.err.println("Temporary files were removed."); } catch (IOException e) { if (!quiet) e.printStackTrace(System.err); } } if (!quiet) System.err.println("THE END!"); }
From source file:io.personium.core.bar.BarFileReadRunner.java
/** * bar?(bar/90_contents)1????.//from w w w .ja v a 2s . co m * @return boolean ???? */ protected boolean createContents() { boolean isSuccess = true; // Collection???Map?????? Map<String, DavCmp> odataCols = getCollections(DavCmp.TYPE_COL_ODATA); Map<String, DavCmp> webdavCols = getCollections(DavCmp.TYPE_COL_WEBDAV); Map<String, DavCmp> serviceCols = getCollections(DavCmp.TYPE_COL_SVC); DavCmp davCmp = null; List<String> doneKeys = new ArrayList<String>(); try { ZipArchiveEntry zae = null; String currentPath = null; int userDataCount = 0; List<JSONMappedObject> userDataLinks = new ArrayList<JSONMappedObject>(); LinkedHashMap<String, BulkRequest> bulkRequests = new LinkedHashMap<String, BulkRequest>(); Map<String, String> fileNameMap = new HashMap<String, String>(); PersoniumODataProducer producer = null; while ((zae = this.zipArchiveInputStream.getNextZipEntry()) != null) { String entryName = zae.getName(); log.debug("Entry Name: " + entryName); log.debug("Entry Size: " + zae.getSize()); log.debug("Entry Compressed Size: " + zae.getCompressedSize()); if (!zae.isDirectory()) { this.progressInfo.addDelta(1L); } writeOutputStream(false, CODE_BAR_INSTALL_STARTED, entryName); // ODataCollection?Dav/ServiceCollection/ODataCollection????????? // ?????????? if (currentPath != null && !entryName.startsWith(currentPath)) { if (!execBulkRequest(davCmp.getCell().getId(), bulkRequests, fileNameMap, producer)) { return false; } if (!createUserdataLinks(producer, userDataLinks)) { return false; } userDataLinks = new ArrayList<JSONMappedObject>(); currentPath = null; } int entryType = getEntryType(entryName, odataCols, webdavCols, serviceCols, this.davFileMap); switch (entryType) { case TYPE_ODATA_COLLECTION: // OData? if (!odataCols.isEmpty()) { if (!isValidODataContents(entryName, odataCols, doneKeys)) { return false; } Pattern formatPattern = Pattern.compile(CONTENTS_DIR + ".+/90_data/"); Matcher formatMatcher = formatPattern.matcher(entryName); if (formatMatcher.matches()) { currentPath = entryName; } Pattern userodataDirPattern = Pattern.compile(CONTENTS_DIR + ".+/90_data/.+"); Matcher userodataDirMatcher = userodataDirPattern.matcher(entryName); if (getFileExtension(entryName).equals(".xml")) { // 00_$metadata.xml?? davCmp = getCollection(entryName, odataCols); // OData???????? producer = davCmp.getODataProducer(); if (!registUserSchema(entryName, this.zipArchiveInputStream, davCmp)) { doneKeys.add(entryName); return false; } writeOutputStream(false, "PL-BI-1003", entryName); doneKeys.add(entryName); continue; } else if (entryName.endsWith(USERDATA_LINKS_JSON)) { userDataLinks = registJsonLinksUserdata(entryName, this.zipArchiveInputStream); if (userDataLinks == null) { doneKeys.add(entryName); return false; } writeOutputStream(false, "PL-BI-1003", entryName); doneKeys.add(entryName); continue; } else if (userodataDirMatcher.matches() && getFileExtension(entryName).equals(".json")) { userDataCount++; if (!setBulkRequests(entryName, producer, bulkRequests, fileNameMap)) { return false; } doneKeys.add(entryName); if ((userDataCount % bulkSize) == 0 && !execBulkRequest(davCmp.getCell().getId(), bulkRequests, fileNameMap, producer)) { return false; } continue; } else if (!entryName.endsWith("/")) { // xml,json????????? String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2001"); log.info(message + " [" + entryName + "]"); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } } break; case TYPE_DAV_FILE: // WebDAV? // bar/90_contents/{davcol_name}??1???? if (!registWebDavFile(entryName, this.zipArchiveInputStream, webdavCols)) { return false; } break; case TYPE_SVC_FILE: // Service? if (!installSvcCollection(webdavCols, entryName)) { return false; } break; case TYPE_MISMATCH: // OData??????????rootprops?????? String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2006"); log.info(message + " [" + entryName + "]"); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; default: break; } writeOutputStream(false, "PL-BI-1003", entryName); doneKeys.add(entryName); } // ODataCollection?????????????????? if (currentPath != null) { if (!execBulkRequest(davCmp.getCell().getId(), bulkRequests, fileNameMap, producer)) { return false; } if (!createUserdataLinks(producer, userDataLinks)) { return false; } userDataLinks = null; } } catch (IOException ex) { isSuccess = false; log.info("IOException: " + ex.getMessage(), ex.fillInStackTrace()); String message = PersoniumCoreMessageUtils.getMessage("PL-BI-2000"); writeOutputStream(true, CODE_BAR_INSTALL_FAILED, "", message); } // bar/90_contents/{odatacol_name}/00_$metadata.xml)?? isSuccess = checkNecessaryFile(isSuccess, odataCols, doneKeys); return isSuccess; }
From source file:com.fujitsu.dc.core.bar.BarFileReadRunner.java
/** * bar?(bar/90_contents)1????.//from ww w . j ava 2 s .c o m * @return boolean ???? */ protected boolean createContents() { boolean isSuccess = true; // Collection???Map?????? Map<String, DavCmpEsImpl> odataCols = getCollections(DavCmp.TYPE_COL_ODATA); Map<String, DavCmpEsImpl> webdavCols = getCollections(DavCmp.TYPE_COL_WEBDAV); Map<String, DavCmpEsImpl> serviceCols = getCollections(DavCmp.TYPE_COL_SVC); DavCmpEsImpl davCmp = null; List<String> doneKeys = new ArrayList<String>(); try { ZipArchiveEntry zae = null; String currentPath = null; int userDataCount = 0; List<JSONMappedObject> userDataLinks = new ArrayList<JSONMappedObject>(); LinkedHashMap<String, BulkRequest> bulkRequests = new LinkedHashMap<String, BulkRequest>(); Map<String, String> fileNameMap = new HashMap<String, String>(); DcODataProducer producer = null; while ((zae = this.zipArchiveInputStream.getNextZipEntry()) != null) { String entryName = zae.getName(); log.debug("Entry Name: " + entryName); log.debug("Entry Size: " + zae.getSize()); log.debug("Entry Compressed Size: " + zae.getCompressedSize()); if (!zae.isDirectory()) { this.progressInfo.addDelta(1L); } writeOutputStream(false, CODE_BAR_INSTALL_STARTED, entryName); // ODataCollection?Dav/ServiceCollection/ODataCollection????????? // ?????????? if (currentPath != null && !entryName.startsWith(currentPath)) { if (!execBulkRequest(davCmp.getCellId(), bulkRequests, fileNameMap, producer)) { return false; } if (!createUserdataLinks(producer, userDataLinks)) { return false; } userDataLinks = new ArrayList<JSONMappedObject>(); currentPath = null; } int entryType = getEntryType(entryName, odataCols, webdavCols, serviceCols, this.davFileMap); switch (entryType) { case TYPE_ODATA_COLLECTION: // OData? if (!odataCols.isEmpty()) { if (!isValidODataContents(entryName, odataCols, doneKeys)) { return false; } Pattern formatPattern = Pattern.compile(CONTENTS_DIR + ".+/90_data/"); Matcher formatMatcher = formatPattern.matcher(entryName); if (formatMatcher.matches()) { currentPath = entryName; } Pattern userodataDirPattern = Pattern.compile(CONTENTS_DIR + ".+/90_data/.+"); Matcher userodataDirMatcher = userodataDirPattern.matcher(entryName); if (getFileExtension(entryName).equals(".xml")) { // 00_$metadata.xml?? davCmp = getCollection(entryName, odataCols); // OData???????? producer = davCmp.getODataProducer(); if (!registUserSchema(entryName, this.zipArchiveInputStream, davCmp)) { doneKeys.add(entryName); return false; } writeOutputStream(false, "PL-BI-1003", entryName); doneKeys.add(entryName); continue; } else if (entryName.endsWith(USERDATA_LINKS_JSON)) { userDataLinks = registJsonLinksUserdata(entryName, this.zipArchiveInputStream); if (userDataLinks == null) { doneKeys.add(entryName); return false; } writeOutputStream(false, "PL-BI-1003", entryName); doneKeys.add(entryName); continue; } else if (userodataDirMatcher.matches() && getFileExtension(entryName).equals(".json")) { userDataCount++; if (!setBulkRequests(entryName, producer, bulkRequests, fileNameMap)) { return false; } doneKeys.add(entryName); if ((userDataCount % bulkSize) == 0 && !execBulkRequest(davCmp.getCellId(), bulkRequests, fileNameMap, producer)) { return false; } continue; } else if (!entryName.endsWith("/")) { // xml,json????????? String message = DcCoreMessageUtils.getMessage("PL-BI-2001"); log.info(message + " [" + entryName + "]"); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; } } break; case TYPE_DAV_FILE: // WebDAV? // bar/90_contents/{davcol_name}??1???? if (!registWebDavFile(entryName, this.zipArchiveInputStream, webdavCols)) { return false; } break; case TYPE_SVC_FILE: // Service? if (!installSvcCollection(webdavCols, entryName)) { return false; } break; case TYPE_MISMATCH: // OData??????????rootprops?????? String message = DcCoreMessageUtils.getMessage("PL-BI-2006"); log.info(message + " [" + entryName + "]"); writeOutputStream(true, "PL-BI-1004", entryName, message); return false; default: break; } writeOutputStream(false, "PL-BI-1003", entryName); doneKeys.add(entryName); } // ODataCollection?????????????????? if (currentPath != null) { if (!execBulkRequest(davCmp.getCellId(), bulkRequests, fileNameMap, producer)) { return false; } if (!createUserdataLinks(producer, userDataLinks)) { return false; } userDataLinks = null; } } catch (IOException ex) { isSuccess = false; log.info("IOException: " + ex.getMessage(), ex.fillInStackTrace()); String message = DcCoreMessageUtils.getMessage("PL-BI-2000"); writeOutputStream(true, CODE_BAR_INSTALL_FAILED, "", message); } // bar/90_contents/{odatacol_name}/00_$metadata.xml)?? isSuccess = checkNecessaryFile(isSuccess, odataCols, doneKeys); return isSuccess; }
From source file:com.android.tools.idea.sdk.remote.internal.archives.ArchiveInstaller.java
/** * Unzips a zip file into the given destination directory. * <p/>/*from w w w . java 2 s . c o m*/ * The archive file MUST have a unique "root" folder. * This root folder is skipped when unarchiving. */ @SuppressWarnings("unchecked") @VisibleForTesting(visibility = Visibility.PRIVATE) protected boolean unzipFolder(ArchiveReplacement archiveInfo, File archiveFile, File unzipDestFolder, ITaskMonitor monitor) { Archive newArchive = archiveInfo.getNewArchive(); RemotePkgInfo pkg = newArchive.getParentPackage(); String pkgName = pkg.getShortDescription(); long compressedSize = newArchive.getSize(); ZipFile zipFile = null; try { zipFile = new ZipFile(archiveFile); // To advance the percent and the progress bar, we don't know the number of // items left to unzip. However we know the size of the archive and the size of // each uncompressed item. The zip file format overhead is negligible so that's // a good approximation. long incStep = compressedSize / NUM_MONITOR_INC; long incTotal = 0; long incCurr = 0; int lastPercent = 0; byte[] buf = new byte[65536]; Enumeration<ZipArchiveEntry> entries = zipFile.getEntries(); while (entries.hasMoreElements()) { ZipArchiveEntry entry = entries.nextElement(); String name = entry.getName(); // ZipFile entries should have forward slashes, but not all Zip // implementations can be expected to do that. name = name.replace('\\', '/'); // Zip entries are always packages in a top-level directory (e.g. docs/index.html). int pos = name.indexOf('/'); if (pos == -1) { // All zip entries should have a root folder. // This zip entry seems located at the root of the zip. // Rather than ignore the file, just place it at the root. } else if (pos == name.length() - 1) { // This is a zip *directory* entry in the form dir/, so essentially // it's the root directory of the SDK. It's safe to ignore that one // since we want to use our own root directory and we'll recreate // root directories as needed. // A direct consequence is that if a malformed archive has multiple // root directories, their content will all be merged together. continue; } else { // This is the expected behavior: the zip entry is in the form root/file // or root/dir/. We want to use our top-level directory so we drop the // first segment of the path name. name = name.substring(pos + 1); } File destFile = new File(unzipDestFolder, name); if (name.endsWith("/")) { //$NON-NLS-1$ // Create directory if it doesn't exist yet. This allows us to create // empty directories. if (!mFileOp.isDirectory(destFile) && !mFileOp.mkdirs(destFile)) { monitor.logError("Failed to create directory %1$s", destFile.getPath()); return false; } continue; } else if (name.indexOf('/') != -1) { // Otherwise it's a file in a sub-directory. // Sanity check: since we're always unzipping in a fresh temp folder // the destination file shouldn't already exist. if (mFileOp.exists(destFile)) { monitor.logVerbose("Duplicate file found: %1$s", name); } // Make sure the parent directory has been created. File parentDir = destFile.getParentFile(); if (!mFileOp.isDirectory(parentDir)) { if (!mFileOp.mkdirs(parentDir)) { monitor.logError("Failed to create directory %1$s", parentDir.getPath()); return false; } } } FileOutputStream fos = null; long remains = entry.getSize(); try { fos = new FileOutputStream(destFile); // Java bug 4040920: do not rely on the input stream EOF and don't // try to read more than the entry's size. InputStream entryContent = zipFile.getInputStream(entry); int n; while (remains > 0 && (n = entryContent.read(buf, 0, (int) Math.min(remains, buf.length))) != -1) { remains -= n; if (n > 0) { fos.write(buf, 0, n); } } } catch (EOFException e) { monitor.logError("Error uncompressing file %s. Size: %d bytes, Unwritten: %d bytes.", entry.getName(), entry.getSize(), remains); throw e; } finally { if (fos != null) { fos.close(); } } pkg.postUnzipFileHook(newArchive, monitor, mFileOp, destFile, entry); // Increment progress bar to match. We update only between files. for (incTotal += entry.getCompressedSize(); incCurr < incTotal; incCurr += incStep) { monitor.incProgress(1); } int percent = (int) (100 * incTotal / compressedSize); if (percent != lastPercent) { monitor.setDescription("Unzipping %1$s (%2$d%%)", pkgName, percent); lastPercent = percent; } if (monitor.isCancelRequested()) { return false; } } return true; } catch (IOException e) { monitor.logError("Unzip failed: %1$s", e.getMessage()); } finally { if (zipFile != null) { try { zipFile.close(); } catch (IOException e) { // pass } } } return false; }