From dc3e224063ae8fbb295566b678d5eb71d6f88887 Mon Sep 17 00:00:00 2001 From: fidox Date: Wed, 3 Sep 2014 17:19:34 +0100 Subject: [PATCH 1/2] In most simple usage of the task you will want to preserve file permissions but override the user to root. Seems that is not supported, with this modification the DirectoryProducer will preserve the permissions of files and directories. Requieres jdk1.7 --- .../org/vafer/jdeb/mapping/PermMapper.java | 2 +- .../jdeb/producers/DataProducerDirectory.java | 196 +++++++++++------- 2 files changed, 127 insertions(+), 71 deletions(-) diff --git a/src/main/java/org/vafer/jdeb/mapping/PermMapper.java b/src/main/java/org/vafer/jdeb/mapping/PermMapper.java index 66b858362..28821094d 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()); } - + System.out.println(entry.getName() + " ---> " + entry.getMode()); // 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); + } + +} From 70fc925d54af1c198a479bc310bd758e2e41c5b7 Mon Sep 17 00:00:00 2001 From: fidox Date: Wed, 3 Sep 2014 17:25:25 +0100 Subject: [PATCH 2/2] remove println --- src/main/java/org/vafer/jdeb/mapping/PermMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/vafer/jdeb/mapping/PermMapper.java b/src/main/java/org/vafer/jdeb/mapping/PermMapper.java index 28821094d..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()); } - System.out.println(entry.getName() + " ---> " + entry.getMode()); + // Set permissions if (newEntry.isDirectory()) { if (dirMode > -1) {