diff --git a/src/main/java/org/vafer/jdeb/mapping/PermMapper.java b/src/main/java/org/vafer/jdeb/mapping/PermMapper.java index 66b858362..1150003d2 100644 --- a/src/main/java/org/vafer/jdeb/mapping/PermMapper.java +++ b/src/main/java/org/vafer/jdeb/mapping/PermMapper.java @@ -83,7 +83,7 @@ public TarArchiveEntry map( final TarArchiveEntry entry ) { } else { newEntry.setGroupName(entry.getGroupName()); } - + // Set permissions if (newEntry.isDirectory()) { if (dirMode > -1) { diff --git a/src/main/java/org/vafer/jdeb/producers/DataProducerDirectory.java b/src/main/java/org/vafer/jdeb/producers/DataProducerDirectory.java index 8bece1282..8ea7d56ad 100644 --- a/src/main/java/org/vafer/jdeb/producers/DataProducerDirectory.java +++ b/src/main/java/org/vafer/jdeb/producers/DataProducerDirectory.java @@ -18,7 +18,13 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.PosixFilePermission; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.tools.ant.DirectoryScanner; @@ -28,75 +34,125 @@ import org.vafer.jdeb.utils.Utils; /** - * DataProducer iterating over a directory. - * For cross-platform permissions and ownerships you probably want to use a Mapper, too. + * DataProducer iterating over a directory. For cross-platform permissions and + * ownerships you probably want to use a Mapper, too. * * @author Torsten Curdt */ -public final class DataProducerDirectory extends AbstractDataProducer implements DataProducer { - - private final DirectoryScanner scanner = new DirectoryScanner(); - - public DataProducerDirectory( final File pDir, final String[] pIncludes, final String[] pExcludes, final Mapper[] pMappers ) { - super(pIncludes, pExcludes, pMappers); - scanner.setBasedir(pDir); - scanner.setIncludes(pIncludes); - scanner.setExcludes(pExcludes); - scanner.setCaseSensitive(true); - scanner.setFollowSymlinks(true); - } - - public void produce( final DataConsumer pReceiver ) throws IOException { - - scanner.scan(); - - final File baseDir = scanner.getBasedir(); - - for (String dir : scanner.getIncludedDirectories()) { - final File file = new File(baseDir, dir); - String dirname = getFilename(baseDir, file); - - if ("".equals(dirname)) { - continue; - } - - if ('/' != File.separatorChar) { - dirname = dirname.replace(File.separatorChar, '/'); - } - - if (!isIncluded(dirname)) { - continue; - } - - if (!dirname.endsWith("/")) { - dirname += "/"; - } - - produceDir(pReceiver, dirname); - } - - - for (String f : scanner.getIncludedFiles()) { - final File file = new File(baseDir, f); - String filename = getFilename(baseDir, file); - - if ('/' != File.separatorChar) { - filename = filename.replace(File.separatorChar, '/'); - } - - if (!isIncluded(filename)) { - continue; - } - - produceFile(pReceiver, file, filename); - } - } - - private String getFilename( File root, File file ) { - - final String relativeFilename = file.getAbsolutePath().substring(root.getAbsolutePath().length()); - - return Utils.stripLeadingSlash(relativeFilename); - } - -} \ No newline at end of file +public final class DataProducerDirectory extends AbstractDataProducer implements + DataProducer { + public static final Map ORDINAL_MASK = new HashMap(); + static { + ORDINAL_MASK.put("OTHERS_READ", 4); + ORDINAL_MASK.put("OTHERS_WRITE", 2); + ORDINAL_MASK.put("OTHERS_EXECUTE", 1); + ORDINAL_MASK.put("GROUP_READ", 32); + ORDINAL_MASK.put("GROUP_WRITE", 16); + ORDINAL_MASK.put("GROUP_EXECUTE", 8); + ORDINAL_MASK.put("OWNER_READ", 256); + ORDINAL_MASK.put("OWNER_WRITE", 128); + ORDINAL_MASK.put("OWNER_EXECUTE", 64); + } + private final DirectoryScanner scanner = new DirectoryScanner(); + + public DataProducerDirectory(final File pDir, final String[] pIncludes, + final String[] pExcludes, final Mapper[] pMappers) { + super(pIncludes, pExcludes, pMappers); + scanner.setBasedir(pDir); + scanner.setIncludes(pIncludes); + scanner.setExcludes(pExcludes); + scanner.setCaseSensitive(true); + scanner.setFollowSymlinks(true); + } + + public void produce(final DataConsumer pReceiver) throws IOException { + + scanner.scan(); + + final File baseDir = scanner.getBasedir(); + + for (String dir : scanner.getIncludedDirectories()) { + final File file = new File(baseDir, dir); + String dirname = getFilename(baseDir, file); + + if ("".equals(dirname)) { + continue; + } + + if ('/' != File.separatorChar) { + dirname = dirname.replace(File.separatorChar, '/'); + } + + if (!isIncluded(dirname)) { + continue; + } + + if (!dirname.endsWith("/")) { + dirname += "/"; + } + + produceDir(pReceiver, dirname); + } + + for (String f : scanner.getIncludedFiles()) { + final File file = new File(baseDir, f); + String filename = getFilename(baseDir, file); + + if ('/' != File.separatorChar) { + filename = filename.replace(File.separatorChar, '/'); + } + + if (!isIncluded(filename)) { + continue; + } + + produceFile(pReceiver, file, filename); + } + } + + @Override + public void produceFile(final DataConsumer consumer, final File file, + final String entryName) throws IOException { + TarArchiveEntry entry = new TarArchiveEntry(entryName, true); + entry.setUserId(Producers.ROOT_UID); + entry.setUserName(Producers.ROOT_NAME); + entry.setGroupId(Producers.ROOT_UID); + entry.setGroupName(Producers.ROOT_NAME); + entry.setMode(getOrdinalPermissions(file)); + entry.setSize(file.length()); + entry = map(entry); + Producers.produceInputStreamWithEntry(consumer, + new FileInputStream(file), entry); + } + + public static final int S_IFREG = 0100000; + public static final int S_IFDIR = 0040000; + + public int getOrdinalPermissions(File file) { + try { + Path p = Paths.get(file.getAbsolutePath()); + Set perms = Files.getPosixFilePermissions(p); + int mode = 0; + if (file.isDirectory()) { + mode |= S_IFDIR; + } else { + mode |= S_IFREG; + } + for (PosixFilePermission perm : perms) { + mode |= ORDINAL_MASK.get(perm.name()); + } + return mode; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private String getFilename(File root, File file) { + + final String relativeFilename = file.getAbsolutePath().substring( + root.getAbsolutePath().length()); + + return Utils.stripLeadingSlash(relativeFilename); + } + +}