package org.ovirt.engine.core.utils.archivers.tar;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
/**
* A simple recursive tar based on javatar.
*/
public class Tar {
private static void recurse(
TarArchiveOutputStream archive,
File file,
String base
) throws SecurityException, IOException {
TarArchiveEntry entry = (TarArchiveEntry)archive.createArchiveEntry(
file,
base
);
if (entry.getFile().isDirectory()) {
entry.setMode(0700);
archive.putArchiveEntry(entry);
archive.closeArchiveEntry();
String[] names = entry.getFile().list();
if (names != null) {
for (String f : names) {
recurse(
archive,
new File(entry.getFile(), f),
new File(entry.getName(), f).getPath()
);
}
}
}
else if (entry.getFile().isFile()) {
if (entry.getFile().canExecute()) {
entry.setMode(0700);
}
else {
entry.setMode(0600);
}
archive.putArchiveEntry(entry);
try (InputStream is = new FileInputStream(entry.getFile())) {
byte[] buffer = new byte[8192];
int n;
while ((n = is.read(buffer)) != -1) {
archive.write(buffer, 0, n);
}
}
archive.closeArchiveEntry();
}
}
/**
* Crete tar.
* @param os output stream to write into.
* @param base base directory.
*
* Only regular files and directories are supported.
* Files will be owner rw and optional execute bit.
*/
public static void doTar(
OutputStream os,
File base
) throws SecurityException, IOException {
if (!base.exists()) {
throw new FileNotFoundException(
String.format(
"File or directory %1$s not found",
base
)
);
}
try (TarArchiveOutputStream archive = new TarArchiveOutputStream(os)) {
// TODO: use LONGFILE_POSIX in newer version of commons-compress
archive.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
recurse(archive, base, "./");
}
}
public static void main(String[] args) throws Exception {
try (OutputStream os = new FileOutputStream(args[0])) {
Tar.doTar(os, new File(args[1]));
}
}
}