feisty meow concerns codebase 2.140
UnpackTar.java
Go to the documentation of this file.
1package org.gffs.compression;
2
3import java.io.BufferedOutputStream;
4import java.io.File;
5import java.io.FileInputStream;
6import java.io.FileOutputStream;
7import java.io.IOException;
8import java.nio.file.Files;
9import java.nio.file.Paths;
10import java.nio.file.attribute.PosixFilePermission;
11import java.util.HashSet;
12import org.apache.commons.compress.archivers.ArchiveEntry;
13import org.apache.commons.compress.archivers.ArchiveInputStream;
14import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
15import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
16import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
17import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
18import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
19import org.apache.commons.logging.Log;
20import org.apache.commons.logging.LogFactory;
21
22public class UnpackTar
23{
24 static private Log _logger = LogFactory.getLog(UnpackTar.class);
25
30 public enum archiveType {
33 TGZ
34 };
35
36 public static void uncompressArchive(ArchiveInputStream tarIn, File dest, archiveType archType, boolean grantUserPermsToGroup)
37 throws IOException
38 {
39
40 if (dest.exists()) {
41 // Don't unpack into an existing directory
42 throw new IOException("Directory " + dest.getAbsolutePath() + " already exists. Unpacking exiting");
43 }
44 dest.mkdir();
45
46 ArchiveEntry tarEntry = tarIn.getNextEntry();
47 while (tarEntry != null) {
48 // New code by ASG 2016-02-21. Added extracting user permission bits and OR ing them with group permissions
49 int mode = 0;
50 int defaultMode = 0750; // assume somewhat standard executable permissions if we cannot get the mode.
51 switch (archType) {
52 case TAR:
53 case TGZ:
54 mode = ((TarArchiveEntry) tarEntry).getMode();
55 break;
56 case ZIP:
57 mode = ((ZipArchiveEntry) tarEntry).getUnixMode();
58 break;
59 }
60 if (mode == 0) {
61 mode = defaultMode;
62 }
63 if (_logger.isTraceEnabled())
64 _logger.debug("The mode on '" + tarEntry.getName() + "' is " + Integer.toOctalString(mode));
65 if (grantUserPermsToGroup) {
66 int temp = mode & 0700;
67 temp = temp / 8; // Shift it right 3 bit positions
68 mode = mode | temp;
69 if (_logger.isTraceEnabled())
70 _logger.debug("Now mode on '" + tarEntry.getName() + "' is " + Integer.toOctalString(mode));
71 }
72 // End of extracting and Or ing the permission bits.
73
74 // create a file with the same name as the tarEntry
75 File destPath = new File(dest, tarEntry.getName());
76 if (_logger.isTraceEnabled())
77 _logger.debug("working on: " + destPath.getCanonicalPath());
78 if (tarEntry.isDirectory()) {
79 destPath.mkdirs();
80 } else {
81 destPath.createNewFile();
82
83 // byte [] btoRead = new byte[(int)tarEntry.getSize()];
84 byte[] btoRead = new byte[8192];
85 BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(destPath));
86 int len = 0;
87 boolean wroteAnything = false;
88 while ((len = tarIn.read(btoRead)) != -1) {
89 if (_logger.isTraceEnabled())
90 _logger.debug("read " + len + " bytes");
91 wroteAnything = true;
92 bout.write(btoRead, 0, len);
93 }
94 if (!wroteAnything) {
95 _logger.error("zero bytes read from: " + destPath.getCanonicalPath());
96 }
97
98 bout.close();
99 }
100 // using PosixFilePermission to set file permissions that we extracted earlier.
101 HashSet<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
102 // add owners permission
103 if ((mode & 0400) != 0)
104 perms.add(PosixFilePermission.OWNER_READ);
105 if ((mode & 0200) != 0)
106 perms.add(PosixFilePermission.OWNER_WRITE);
107 if ((mode & 0100) != 0)
108 perms.add(PosixFilePermission.OWNER_EXECUTE);
109 // add group permissions
110 if ((mode & 0040) != 0)
111 perms.add(PosixFilePermission.GROUP_READ);
112 if ((mode & 0020) != 0)
113 perms.add(PosixFilePermission.GROUP_WRITE);
114 if ((mode & 0010) != 0)
115 perms.add(PosixFilePermission.GROUP_EXECUTE);
116 // add others permissions
117 if ((mode & 0004) != 0)
118 perms.add(PosixFilePermission.OTHERS_READ);
119 if ((mode & 0002) != 0)
120 perms.add(PosixFilePermission.OTHERS_WRITE);
121 if ((mode & 0001) != 0)
122 perms.add(PosixFilePermission.OTHERS_EXECUTE);
123
124 Files.setPosixFilePermissions(Paths.get(destPath.getCanonicalPath()), perms);
125 tarEntry = tarIn.getNextEntry();
126 }
127 tarIn.close();
128 }
129
130 public synchronized static void uncompressTarGZ(File tarFile, File dest, boolean grantUserPermsToGroup) throws IOException
131 {
132 TarArchiveInputStream tarIn = new TarArchiveInputStream(new GzipCompressorInputStream(new FileInputStream(tarFile)));
133
134 uncompressArchive(tarIn, dest, archiveType.TGZ, grantUserPermsToGroup);
135 }
136
137 public synchronized static void uncompressTar(File tarFile, File dest, boolean grantUserPermsToGroup) throws IOException
138 {
139 TarArchiveInputStream tarIn = new TarArchiveInputStream(new FileInputStream(tarFile));
140
141 uncompressArchive(tarIn, dest, archiveType.TAR, grantUserPermsToGroup);
142 }
143
144 public synchronized static void uncompressZip(File zipFile, File dest, boolean grantUserPermsToGroup) throws IOException
145 {
146 ZipArchiveInputStream tarIn = new ZipArchiveInputStream(new FileInputStream(zipFile));
147
148 uncompressArchive(tarIn, dest, archiveType.ZIP, grantUserPermsToGroup);
149 }
150
151 static public void main(String[] args) throws Throwable
152 {
153 if (args.length != 2) {
154 System.err.println("USAGE: UnpackTar {tar.gz file} {output location}");
155 System.exit(1);
156 }
157
158 try {
159 UnpackTar.uncompressTarGZ(new File(args[0]), new File(args[1]), false);
160 } catch (Throwable t) {
161 _logger.error("failed to uncompress tar file " + args[0] + " into " + args[1]);
162 System.exit(1);
163 }
164
165 System.out.println("successfully uncompressed tar file " + args[0] + " into " + args[1]);
166 }
167
168}
static synchronized void uncompressTarGZ(File tarFile, File dest, boolean grantUserPermsToGroup)
static synchronized void uncompressZip(File zipFile, File dest, boolean grantUserPermsToGroup)
static synchronized void uncompressTar(File tarFile, File dest, boolean grantUserPermsToGroup)
static void main(String[] args)
static void uncompressArchive(ArchiveInputStream tarIn, File dest, archiveType archType, boolean grantUserPermsToGroup)