package com.threerings.getdown.util;
import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.*;
import java.util.jar.*;
import java.util.zip.GZIPInputStream;
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveInputStream;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+
+import com.threerings.getdown.util.StreamUtil;
import com.threerings.getdown.Log;
import static com.threerings.getdown.Log.log;
}
try (BufferedOutputStream fout = new BufferedOutputStream(new FileOutputStream(efile));
- InputStream jin = jar.getInputStream(entry)) {
+ InputStream jin = jar.getInputStream(entry)) {
StreamUtil.copy(jin, fout);
} catch (Exception e) {
throw new IOException(
}
/**
+ * Unpacks the specified tgz file into the specified target directory.
+ * @param cleanExistingDirs if true, all files in all directories contained in {@code tgz} will
+ * be deleted prior to unpacking the tgz.
+ */
+ public static void unpackTgz (TarArchiveInputStream tgz, File target, boolean cleanExistingDirs)
+ throws IOException
+ {
+ TarArchiveEntry entry;
+ while ((entry = tgz.getNextTarEntry()) != null) {
+ // sanitize the entry name
+ String entryName = entry.getName();
+ if (entryName.startsWith(File.separator))
+ {
+ entryName = entryName.substring(File.separator.length());
+ }
+ File efile = new File(target, entryName);
+
+ // if we're unpacking a normal tgz file, it will have special path
+ // entries that allow us to create our directories first
+ if (entry.isDirectory()) {
+
+ if (cleanExistingDirs) {
+ if (efile.exists()) {
+ for (File f : efile.listFiles()) {
+ if (!f.isDirectory())
+ f.delete();
+ }
+ }
+ }
+
+ if (!efile.exists() && !efile.mkdir()) {
+ log.warning("Failed to create tgz entry path", "tgz", tgz, "entry", entry);
+ }
+ continue;
+ }
+
+ // but some do not, so we want to ensure that our directories exist
+ // prior to getting down and funky
+ File parent = new File(efile.getParent());
+ if (!parent.exists() && !parent.mkdirs()) {
+ log.warning("Failed to create tgz entry parent", "tgz", tgz, "parent", parent);
+ continue;
+ }
+
+ if (entry.isLink())
+ {
+ System.out.println("Creating hard link "+efile.getName()+" -> "+entry.getLinkName());
+ Files.createLink(efile.toPath(), Paths.get(entry.getLinkName()));
+ continue;
+ }
+
+ if (entry.isSymbolicLink())
+ {
+ System.out.println("Creating symbolic link "+efile.getName()+" -> "+entry.getLinkName());
+ Files.createSymbolicLink(efile.toPath(), Paths.get(entry.getLinkName()));
+ continue;
+ }
+
+ try (BufferedOutputStream fout = new BufferedOutputStream(new FileOutputStream(efile));
+ InputStream tin = tgz;) {
+ StreamUtil.copy(tin, fout);
+ } catch (Exception e) {
+ throw new IOException(
+ Log.format("Failure unpacking", "tgz", tgz, "entry", efile), e);
+ }
+ }
+ }
+
+ /**
* Unpacks a pack200 packed jar file from {@code packedJar} into {@code target}. If {@code
* packedJar} has a {@code .gz} extension, it will be gunzipped first.
*/