Search in sources :

Example 21 with PosixFilePermission

use of java.nio.file.attribute.PosixFilePermission in project buck by facebook.

the class Unzip method extractZipFile.

/**
   * Unzips a file to a destination and returns the paths of the written files.
   */
public static ImmutableList<Path> extractZipFile(Path zipFile, ProjectFilesystem filesystem, Path relativePath, ExistingFileMode existingFileMode) throws IOException {
    // if requested, clean before extracting
    if (existingFileMode == ExistingFileMode.OVERWRITE_AND_CLEAN_DIRECTORIES) {
        try (ZipFile zip = new ZipFile(zipFile.toFile())) {
            Enumeration<ZipArchiveEntry> entries = zip.getEntries();
            while (entries.hasMoreElements()) {
                ZipArchiveEntry entry = entries.nextElement();
                filesystem.deleteRecursivelyIfExists(relativePath.resolve(entry.getName()));
            }
        }
    }
    ImmutableList.Builder<Path> filesWritten = ImmutableList.builder();
    try (ZipFile zip = new ZipFile(zipFile.toFile())) {
        Enumeration<ZipArchiveEntry> entries = zip.getEntries();
        while (entries.hasMoreElements()) {
            ZipArchiveEntry entry = entries.nextElement();
            String fileName = entry.getName();
            Path target = relativePath.resolve(fileName);
            if (entry.isDirectory()) {
                // Create the directory and all its parent directories
                filesystem.mkdirs(target);
            } else {
                // Create parent folder
                filesystem.createParentDirs(target);
                filesWritten.add(target);
                // Write file
                try (InputStream is = zip.getInputStream(entry)) {
                    if (entry.isUnixSymlink()) {
                        filesystem.createSymLink(target, filesystem.getPath(new String(ByteStreams.toByteArray(is), Charsets.UTF_8)), /* force */
                        true);
                    } else {
                        try (OutputStream out = filesystem.newFileOutputStream(target)) {
                            ByteStreams.copy(is, out);
                        }
                    }
                }
                // restore mtime for the file
                filesystem.resolve(target).toFile().setLastModified(entry.getTime());
                // TODO(shs96c): Implement what the comment below says we should do.
                //
                // Sets the file permissions of the output file given the information in {@code entry}'s
                // extra data field. According to the docs at
                // http://www.opensource.apple.com/source/zip/zip-6/unzip/unzip/proginfo/extra.fld there
                // are two extensions that might support file permissions: Acorn and ASi UNIX. We shall
                // assume that inputs are not from an Acorn SparkFS. The relevant section from the docs:
                //
                // <pre>
                //    The following is the layout of the ASi extra block for Unix.  The
                //    local-header and central-header versions are identical.
                //    (Last Revision 19960916)
                //
                //    Value         Size        Description
                //    -----         ----        -----------
                //   (Unix3) 0x756e        Short       tag for this extra block type ("nu")
                //   TSize         Short       total data size for this block
                //   CRC           Long        CRC-32 of the remaining data
                //   Mode          Short       file permissions
                //   SizDev        Long        symlink'd size OR major/minor dev num
                //   UID           Short       user ID
                //   GID           Short       group ID
                //   (var.)        variable    symbolic link filename
                //
                //   Mode is the standard Unix st_mode field from struct stat, containing
                //   user/group/other permissions, setuid/setgid and symlink info, etc.
                // </pre>
                //
                // From the stat man page, we see that the following mask values are defined for the file
                // permissions component of the st_mode field:
                //
                // <pre>
                //   S_ISUID   0004000   set-user-ID bit
                //   S_ISGID   0002000   set-group-ID bit (see below)
                //   S_ISVTX   0001000   sticky bit (see below)
                //
                //   S_IRWXU     00700   mask for file owner permissions
                //
                //   S_IRUSR     00400   owner has read permission
                //   S_IWUSR     00200   owner has write permission
                //   S_IXUSR     00100   owner has execute permission
                //
                //   S_IRWXG     00070   mask for group permissions
                //   S_IRGRP     00040   group has read permission
                //   S_IWGRP     00020   group has write permission
                //   S_IXGRP     00010   group has execute permission
                //
                //   S_IRWXO     00007   mask for permissions for others
                //   (not in group)
                //   S_IROTH     00004   others have read permission
                //   S_IWOTH     00002   others have write permission
                //   S_IXOTH     00001   others have execute permission
                // </pre>
                //
                // For the sake of our own sanity, we're going to assume that no-one is using symlinks,
                // but we'll check and throw if they are.
                //
                // Before we do anything, we should check the header ID. Pfft!
                //
                // Having jumped through all these hoops, it turns out that InfoZIP's "unzip" store the
                // values in the external file attributes of a zip entry (found in the zip's central
                // directory) assuming that the OS creating the zip was one of an enormous list that
                // includes UNIX but not Windows, it first searches for the extra fields, and if not found
                // falls through to a code path that supports MS-DOS and which stores the UNIX file
                // attributes in the upper 16 bits of the external attributes field.
                //
                // We'll support neither approach fully, but we encode whether this file was executable
                // via storing 0100 in the fields that are typically used by zip implementations to store
                // POSIX permissions. If we find it was executable, use the platform independent java
                // interface to make this unpacked file executable.
                Set<PosixFilePermission> permissions = MorePosixFilePermissions.fromMode(entry.getExternalAttributes() >> 16);
                if (permissions.contains(PosixFilePermission.OWNER_EXECUTE)) {
                    MoreFiles.makeExecutable(filesystem.resolve(target));
                }
            }
        }
    }
    return filesWritten.build();
}
Also used : Path(java.nio.file.Path) ZipFile(org.apache.commons.compress.archivers.zip.ZipFile) ImmutableList(com.google.common.collect.ImmutableList) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) ZipArchiveEntry(org.apache.commons.compress.archivers.zip.ZipArchiveEntry) PosixFilePermission(java.nio.file.attribute.PosixFilePermission)

Example 22 with PosixFilePermission

use of java.nio.file.attribute.PosixFilePermission in project buck by facebook.

the class ProjectFilesystemTest method testCreateZipPreservesExecutablePermissions.

@Test
public void testCreateZipPreservesExecutablePermissions() throws IOException {
    // Create a empty executable file.
    Path exe = tmp.newFile("test.exe");
    MoreFiles.makeExecutable(exe);
    // Archive it into a zipfile using `ProjectFileSystem.createZip`.
    Path zipFile = tmp.getRoot().resolve("test.zip");
    filesystem.createZip(ImmutableList.of(exe), zipFile);
    // permissions.
    try (ZipFile zip = new ZipFile(zipFile.toFile())) {
        Enumeration<ZipArchiveEntry> entries = zip.getEntries();
        assertTrue(entries.hasMoreElements());
        ZipArchiveEntry entry = entries.nextElement();
        Set<PosixFilePermission> permissions = MorePosixFilePermissions.fromMode(entry.getExternalAttributes() >> 16);
        assertTrue(permissions.contains(PosixFilePermission.OWNER_EXECUTE));
        assertFalse(entries.hasMoreElements());
    }
}
Also used : Path(java.nio.file.Path) ZipFile(org.apache.commons.compress.archivers.zip.ZipFile) ZipArchiveEntry(org.apache.commons.compress.archivers.zip.ZipArchiveEntry) PosixFilePermission(java.nio.file.attribute.PosixFilePermission) Test(org.junit.Test)

Example 23 with PosixFilePermission

use of java.nio.file.attribute.PosixFilePermission in project buck by facebook.

the class ZipStepTest method zipMaintainsExecutablePermissions.

@Test
public void zipMaintainsExecutablePermissions() throws IOException {
    assumeTrue(Platform.detect() != Platform.WINDOWS);
    Path parent = tmp.newFolder("zipstep");
    Path toZip = tmp.newFolder("zipdir");
    Path file = toZip.resolve("foo.sh");
    ImmutableSet<PosixFilePermission> filePermissions = ImmutableSet.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.GROUP_READ, PosixFilePermission.OTHERS_READ);
    Files.createFile(file, PosixFilePermissions.asFileAttribute(filePermissions));
    Path outputZip = parent.resolve("output.zip");
    ZipStep step = new ZipStep(filesystem, outputZip, ImmutableSet.of(), false, ZipCompressionLevel.MIN_COMPRESSION_LEVEL, Paths.get("zipdir"));
    assertEquals(0, step.execute(TestExecutionContext.newInstance()).getExitCode());
    Path destination = tmp.newFolder("output");
    Unzip.extractZipFile(outputZip, destination, Unzip.ExistingFileMode.OVERWRITE);
    assertTrue(Files.isExecutable(destination.resolve("foo.sh")));
}
Also used : Path(java.nio.file.Path) PosixFilePermission(java.nio.file.attribute.PosixFilePermission) Test(org.junit.Test)

Example 24 with PosixFilePermission

use of java.nio.file.attribute.PosixFilePermission in project jimfs by google.

the class PosixAttributeProvider method defaultValues.

@SuppressWarnings("unchecked")
@Override
public ImmutableMap<String, ?> defaultValues(Map<String, ?> userProvidedDefaults) {
    Object userProvidedGroup = userProvidedDefaults.get("posix:group");
    UserPrincipal group = DEFAULT_GROUP;
    if (userProvidedGroup != null) {
        if (userProvidedGroup instanceof String) {
            group = createGroupPrincipal((String) userProvidedGroup);
        } else {
            throw new IllegalArgumentException("invalid type " + userProvidedGroup.getClass().getName() + " for attribute 'posix:group': should be one of " + String.class + " or " + GroupPrincipal.class);
        }
    }
    Object userProvidedPermissions = userProvidedDefaults.get("posix:permissions");
    Set<PosixFilePermission> permissions = DEFAULT_PERMISSIONS;
    if (userProvidedPermissions != null) {
        if (userProvidedPermissions instanceof String) {
            permissions = Sets.immutableEnumSet(PosixFilePermissions.fromString((String) userProvidedPermissions));
        } else if (userProvidedPermissions instanceof Set) {
            permissions = toPermissions((Set<?>) userProvidedPermissions);
        } else {
            throw new IllegalArgumentException("invalid type " + userProvidedPermissions.getClass().getName() + " for attribute 'posix:permissions': should be one of " + String.class + " or " + Set.class);
        }
    }
    return ImmutableMap.of("posix:group", group, "posix:permissions", permissions);
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) UserLookupService.createGroupPrincipal(com.google.common.jimfs.UserLookupService.createGroupPrincipal) GroupPrincipal(java.nio.file.attribute.GroupPrincipal) PosixFilePermission(java.nio.file.attribute.PosixFilePermission) UserPrincipal(java.nio.file.attribute.UserPrincipal)

Example 25 with PosixFilePermission

use of java.nio.file.attribute.PosixFilePermission in project camel by apache.

the class FileOperations method storeFile.

public boolean storeFile(String fileName, Exchange exchange) throws GenericFileOperationFailedException {
    ObjectHelper.notNull(endpoint, "endpoint");
    File file = new File(fileName);
    // if an existing file already exists what should we do?
    if (file.exists()) {
        if (endpoint.getFileExist() == GenericFileExist.Ignore) {
            // ignore but indicate that the file was written
            LOG.trace("An existing file already exists: {}. Ignore and do not override it.", file);
            return true;
        } else if (endpoint.getFileExist() == GenericFileExist.Fail) {
            throw new GenericFileOperationFailedException("File already exist: " + file + ". Cannot write new file.");
        } else if (endpoint.getFileExist() == GenericFileExist.Move) {
            // move any existing file first
            doMoveExistingFile(fileName);
        }
    }
    // Do an explicit test for a null body and decide what to do
    if (exchange.getIn().getBody() == null) {
        if (endpoint.isAllowNullBody()) {
            LOG.trace("Writing empty file.");
            try {
                writeFileEmptyBody(file);
                return true;
            } catch (IOException e) {
                throw new GenericFileOperationFailedException("Cannot store file: " + file, e);
            }
        } else {
            throw new GenericFileOperationFailedException("Cannot write null body to file: " + file);
        }
    }
    // 3. write stream to file
    try {
        // is there an explicit charset configured we must write the file as
        String charset = endpoint.getCharset();
        // we can optimize and use file based if no charset must be used, and the input body is a file
        File source = null;
        boolean fileBased = false;
        if (charset == null) {
            // if no charset, then we can try using file directly (optimized)
            Object body = exchange.getIn().getBody();
            if (body instanceof WrappedFile) {
                body = ((WrappedFile<?>) body).getFile();
            }
            if (body instanceof File) {
                source = (File) body;
                fileBased = true;
            }
        }
        if (fileBased) {
            // okay we know the body is a file based
            // so try to see if we can optimize by renaming the local work path file instead of doing
            // a full file to file copy, as the local work copy is to be deleted afterwards anyway
            // local work path
            File local = exchange.getIn().getHeader(Exchange.FILE_LOCAL_WORK_PATH, File.class);
            if (local != null && local.exists()) {
                boolean renamed = writeFileByLocalWorkPath(local, file);
                if (renamed) {
                    // try to keep last modified timestamp if configured to do so
                    keepLastModified(exchange, file);
                    // set permissions if the chmod option was set
                    if (ObjectHelper.isNotEmpty(endpoint.getChmod())) {
                        Set<PosixFilePermission> permissions = endpoint.getPermissions();
                        if (!permissions.isEmpty()) {
                            if (LOG.isTraceEnabled()) {
                                LOG.trace("Setting chmod: {} on file: {} ", PosixFilePermissions.toString(permissions), file);
                            }
                            Files.setPosixFilePermissions(file.toPath(), permissions);
                        }
                    }
                    // clear header as we have renamed the file
                    exchange.getIn().setHeader(Exchange.FILE_LOCAL_WORK_PATH, null);
                    // to the target.
                    return true;
                }
            } else if (source != null && source.exists()) {
                // no there is no local work file so use file to file copy if the source exists
                writeFileByFile(source, file);
                // try to keep last modified timestamp if configured to do so
                keepLastModified(exchange, file);
                // set permissions if the chmod option was set
                if (ObjectHelper.isNotEmpty(endpoint.getChmod())) {
                    Set<PosixFilePermission> permissions = endpoint.getPermissions();
                    if (!permissions.isEmpty()) {
                        if (LOG.isTraceEnabled()) {
                            LOG.trace("Setting chmod: {} on file: {} ", PosixFilePermissions.toString(permissions), file);
                        }
                        Files.setPosixFilePermissions(file.toPath(), permissions);
                    }
                }
                return true;
            }
        }
        if (charset != null) {
            // charset configured so we must use a reader so we can write with encoding
            Reader in = exchange.getContext().getTypeConverter().tryConvertTo(Reader.class, exchange, exchange.getIn().getBody());
            if (in == null) {
                // okay no direct reader conversion, so use an input stream (which a lot can be converted as)
                InputStream is = exchange.getIn().getMandatoryBody(InputStream.class);
                in = new InputStreamReader(is);
            }
            // buffer the reader
            in = IOHelper.buffered(in);
            writeFileByReaderWithCharset(in, file, charset);
        } else {
            // fallback and use stream based
            InputStream in = exchange.getIn().getMandatoryBody(InputStream.class);
            writeFileByStream(in, file);
        }
        // try to keep last modified timestamp if configured to do so
        keepLastModified(exchange, file);
        // set permissions if the chmod option was set
        if (ObjectHelper.isNotEmpty(endpoint.getChmod())) {
            Set<PosixFilePermission> permissions = endpoint.getPermissions();
            if (!permissions.isEmpty()) {
                if (LOG.isTraceEnabled()) {
                    LOG.trace("Setting chmod: {} on file: {} ", PosixFilePermissions.toString(permissions), file);
                }
                Files.setPosixFilePermissions(file.toPath(), permissions);
            }
        }
        return true;
    } catch (IOException e) {
        throw new GenericFileOperationFailedException("Cannot store file: " + file, e);
    } catch (InvalidPayloadException e) {
        throw new GenericFileOperationFailedException("Cannot store file: " + file, e);
    }
}
Also used : Set(java.util.Set) InputStreamReader(java.io.InputStreamReader) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) IOException(java.io.IOException) PosixFilePermission(java.nio.file.attribute.PosixFilePermission) InvalidPayloadException(org.apache.camel.InvalidPayloadException) WrappedFile(org.apache.camel.WrappedFile) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) WrappedFile(org.apache.camel.WrappedFile)

Aggregations

PosixFilePermission (java.nio.file.attribute.PosixFilePermission)33 Path (java.nio.file.Path)18 IOException (java.io.IOException)10 Test (org.junit.Test)7 File (java.io.File)6 HashSet (java.util.HashSet)6 PosixFileAttributes (java.nio.file.attribute.PosixFileAttributes)5 Set (java.util.Set)4 GroupPrincipal (java.nio.file.attribute.GroupPrincipal)3 PosixFileAttributeView (java.nio.file.attribute.PosixFileAttributeView)3 TransferSettings (org.syncany.plugins.transfer.TransferSettings)3 TestClient (org.syncany.tests.util.TestClient)3 ImmutableSet (com.google.common.collect.ImmutableSet)2 FileOutputStream (java.io.FileOutputStream)2 InputStream (java.io.InputStream)2 RandomAccessFile (java.io.RandomAccessFile)2 UserPrincipal (java.nio.file.attribute.UserPrincipal)2 Date (java.util.Date)2 MockEndpoint (org.apache.camel.component.mock.MockEndpoint)2 ZipArchiveEntry (org.apache.commons.compress.archivers.zip.ZipArchiveEntry)2