Java Code Examples for org.apache.commons.compress.archivers.tar.TarArchiveEntry#isSymbolicLink()

The following examples show how to use org.apache.commons.compress.archivers.tar.TarArchiveEntry#isSymbolicLink() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Untar.java    From buck with Apache License 2.0 6 votes vote down vote up
/** Sets the modification time and the execution bit on a file */
private void setAttributes(ProjectFilesystem filesystem, Path path, TarArchiveEntry entry)
    throws IOException {
  AbsPath filePath = filesystem.getRootPath().resolve(path);
  File file = filePath.toFile();
  file.setLastModified(entry.getModTime().getTime());
  Set<PosixFilePermission> posixPermissions = MorePosixFilePermissions.fromMode(entry.getMode());
  if (posixPermissions.contains(PosixFilePermission.OWNER_EXECUTE)) {
    // setting posix file permissions on a symlink does not work, so use File API instead
    if (entry.isSymbolicLink()) {
      file.setExecutable(true, true);
    } else {
      MostFiles.makeExecutable(filePath.getPath());
    }
  }
}
 
Example 2
Source File: FileUtil.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
private static void unpackEntries(TarArchiveInputStream tis,
                                  TarArchiveEntry entry, File outputDir) throws IOException {
  String targetDirPath = outputDir.getCanonicalPath() + File.separator;
  File outputFile = new File(outputDir, entry.getName());
  if (!outputFile.getCanonicalPath().startsWith(targetDirPath)) {
    throw new IOException("expanding " + entry.getName()
        + " would create entry outside of " + outputDir);
  }

  if (entry.isDirectory()) {
    File subDir = new File(outputDir, entry.getName());
    if (!subDir.mkdirs() && !subDir.isDirectory()) {
      throw new IOException("Mkdirs failed to create tar internal dir "
          + outputDir);
    }

    for (TarArchiveEntry e : entry.getDirectoryEntries()) {
      unpackEntries(tis, e, subDir);
    }

    return;
  }

  if (entry.isSymbolicLink()) {
    // Create symbolic link relative to tar parent dir
    Files.createSymbolicLink(FileSystems.getDefault()
            .getPath(outputDir.getPath(), entry.getName()),
        FileSystems.getDefault().getPath(entry.getLinkName()));
    return;
  }

  if (!outputFile.getParentFile().exists()) {
    if (!outputFile.getParentFile().mkdirs()) {
      throw new IOException("Mkdirs failed to create tar internal dir "
          + outputDir);
    }
  }

  if (entry.isLink()) {
    File src = new File(outputDir, entry.getLinkName());
    HardLink.createHardLink(src, outputFile);
    return;
  }

  int count;
  byte data[] = new byte[2048];
  try (BufferedOutputStream outputStream = new BufferedOutputStream(
      new FileOutputStream(outputFile));) {

    while ((count = tis.read(data)) != -1) {
      outputStream.write(data, 0, count);
    }

    outputStream.flush();
  }
}
 
Example 3
Source File: Tar.java    From phoenicis with GNU Lesser General Public License v3.0 4 votes vote down vote up
/**
 * Uncompress a tar
 *
 * @param countingInputStream
 *            to count the number of byte extracted
 * @param outputDir
 *            The directory where files should be extracted
 * @return A list of extracted files
 * @throws ArchiveException
 *             if the process fails
 */
private List<File> uncompress(final InputStream inputStream, CountingInputStream countingInputStream,
        final File outputDir, long finalSize, Consumer<ProgressEntity> stateCallback) {
    final List<File> uncompressedFiles = new LinkedList<>();
    try (ArchiveInputStream debInputStream = new ArchiveStreamFactory().createArchiveInputStream("tar",
            inputStream)) {
        TarArchiveEntry entry;
        while ((entry = (TarArchiveEntry) debInputStream.getNextEntry()) != null) {
            final File outputFile = new File(outputDir, entry.getName());
            if (entry.isDirectory()) {
                LOGGER.info(
                        String.format("Attempting to write output directory %s.", outputFile.getAbsolutePath()));

                if (!outputFile.exists()) {
                    LOGGER.info(String.format("Attempting to createPrefix output directory %s.",
                            outputFile.getAbsolutePath()));
                    Files.createDirectories(outputFile.toPath());
                }
            } else {
                LOGGER.info(String.format("Creating output file %s (%s).", outputFile.getAbsolutePath(),
                        entry.getMode()));

                if (entry.isSymbolicLink()) {
                    Files.createSymbolicLink(Paths.get(outputFile.getAbsolutePath()),
                            Paths.get(entry.getLinkName()));
                } else {
                    try (final OutputStream outputFileStream = new FileOutputStream(outputFile)) {
                        IOUtils.copy(debInputStream, outputFileStream);

                        Files.setPosixFilePermissions(Paths.get(outputFile.getPath()),
                                fileUtilities.octToPosixFilePermission(entry.getMode()));
                    }
                }

            }
            uncompressedFiles.add(outputFile);

            stateCallback
                    .accept(new ProgressEntity.Builder()
                            .withPercent(
                                    (double) countingInputStream.getCount() / (double) finalSize * (double) 100)
                            .withProgressText("Extracting " + outputFile.getName()).build());

        }
        return uncompressedFiles;
    } catch (IOException | org.apache.commons.compress.archivers.ArchiveException e) {
        throw new ArchiveException("Unable to extract the file", e);
    }
}
 
Example 4
Source File: ProjectArchives.java    From digdag with Apache License 2.0 4 votes vote down vote up
private static void extractArchive(Path destDir, TarArchiveInputStream archive, ExtractListener listener)
      throws IOException
  {
      String prefix = destDir.toString();
      TarArchiveEntry entry;
      while (true) {
          entry = archive.getNextTarEntry();
          if (entry == null) {
              break;
          }
          Path path = destDir.resolve(entry.getName()).normalize();
          if (!path.toString().startsWith(prefix)) {
              throw new RuntimeException("Archive includes an invalid entry: " + entry.getName());
          }
          if (entry.isDirectory()) {
              Files.createDirectories(path);
          }
          else if (entry.isSymbolicLink()) {
              Files.createDirectories(path.getParent());
              String dest = entry.getLinkName();
              Path destAbsPath = path.getParent().resolve(dest).normalize();
              if (!destAbsPath.normalize().toString().startsWith(prefix)) {
                  throw new RuntimeException("Archive includes an invalid symlink: " + entry.getName() + " -> " + dest);
              }
              if (listener != null) {
                  listener.symlink(destDir.relativize(path), dest);
              }
              Files.createSymbolicLink(path, Paths.get(dest));
          }
          else {
              Files.createDirectories(path.getParent());
              if (listener != null) {
                  listener.file(destDir.relativize(path));
              }
              try (OutputStream out = Files.newOutputStream(path)) {
                  ByteStreams.copy(archive, out);
              }
          }
          if (!Files.isSymbolicLink(path) && isPosixCompliant()) {
// Files.setPosixFilePermissions doesn't work on Windows: java.lang.UnsupportedOperationException
              Files.setPosixFilePermissions(path, getPosixFilePermissions(entry));
          }
      }
  }
 
Example 5
Source File: CompressedTarFunction.java    From bazel with Apache License 2.0 4 votes vote down vote up
@Override
public Path decompress(DecompressorDescriptor descriptor)
    throws InterruptedException, IOException {
  if (Thread.interrupted()) {
    throw new InterruptedException();
  }
  Optional<String> prefix = descriptor.prefix();
  boolean foundPrefix = false;
  Set<String> availablePrefixes = new HashSet<>();

  try (InputStream decompressorStream = getDecompressorStream(descriptor)) {
    TarArchiveInputStream tarStream = new TarArchiveInputStream(decompressorStream);
    TarArchiveEntry entry;
    while ((entry = tarStream.getNextTarEntry()) != null) {
      StripPrefixedPath entryPath = StripPrefixedPath.maybeDeprefix(entry.getName(), prefix);
      foundPrefix = foundPrefix || entryPath.foundPrefix();

      if (prefix.isPresent() && !foundPrefix) {
        Optional<String> suggestion =
            CouldNotFindPrefixException.maybeMakePrefixSuggestion(entryPath.getPathFragment());
        if (suggestion.isPresent()) {
          availablePrefixes.add(suggestion.get());
        }
      }

      if (entryPath.skip()) {
        continue;
      }

      Path filePath = descriptor.repositoryPath().getRelative(entryPath.getPathFragment());
      FileSystemUtils.createDirectoryAndParents(filePath.getParentDirectory());
      if (entry.isDirectory()) {
        FileSystemUtils.createDirectoryAndParents(filePath);
      } else {
        if (entry.isSymbolicLink() || entry.isLink()) {
          PathFragment targetName = PathFragment.create(entry.getLinkName());
          targetName = maybeDeprefixSymlink(targetName, prefix, descriptor.repositoryPath());
          if (entry.isSymbolicLink()) {
            if (filePath.exists()) {
              filePath.delete();
            }
            FileSystemUtils.ensureSymbolicLink(filePath, targetName);
          } else {
            Path targetPath = descriptor.repositoryPath().getRelative(targetName);
            if (filePath.equals(targetPath)) {
              // The behavior here is semantically different, depending on whether the underlying
              // filesystem is case-sensitive or case-insensitive. However, it is effectively the
              // same: we drop the link entry.
              // * On a case-sensitive filesystem, this is a hardlink to itself, such as GNU tar
              //   creates when given repeated files. We do nothing since the link already exists.
              // * On a case-insensitive filesystem, we may be extracting a differently-cased
              //   hardlink to the same file (such as when extracting an archive created on a
              //   case-sensitive filesystem). GNU tar, for example, will drop the new link entry.
              //   BSD tar on MacOS X (by default case-insensitive) errors and aborts extraction.
            } else {
              if (filePath.exists()) {
                filePath.delete();
              }
              FileSystemUtils.createHardLink(filePath, targetPath);
            }
          }
        } else {
          try (OutputStream out = filePath.getOutputStream()) {
            ByteStreams.copy(tarStream, out);
          }
          filePath.chmod(entry.getMode());

          // This can only be done on real files, not links, or it will skip the reader to
          // the next "real" file to try to find the mod time info.
          Date lastModified = entry.getLastModifiedDate();
          filePath.setLastModifiedTime(lastModified.getTime());
        }
      }
      if (Thread.interrupted()) {
        throw new InterruptedException();
      }
    }

    if (prefix.isPresent() && !foundPrefix) {
      throw new CouldNotFindPrefixException(prefix.get(), availablePrefixes);
    }
  }

  return descriptor.repositoryPath();
}
 
Example 6
Source File: Untar.java    From buck with Apache License 2.0 4 votes vote down vote up
@VisibleForTesting
ImmutableSet<Path> extractArchive(
    Path archiveFile,
    ProjectFilesystem filesystem,
    Path filesystemRelativePath,
    Optional<Path> stripPath,
    ExistingFileMode existingFileMode,
    PatternsMatcher entriesToExclude,
    boolean writeSymlinksAfterCreatingFiles)
    throws IOException {

  ImmutableSet.Builder<Path> paths = ImmutableSet.builder();
  HashSet<Path> dirsToTidy = new HashSet<>();
  TreeMap<Path, Long> dirCreationTimes = new TreeMap<>();
  DirectoryCreator creator = new DirectoryCreator(filesystem);

  // On windows, we create hard links instead of symlinks. This is fine, but the
  // destination file may not exist yet, which is an error. So, just hold onto the paths until
  // all files are extracted, and /then/ try to do the links
  Map<Path, Path> windowsSymlinkMap = new HashMap<>();

  try (TarArchiveInputStream archiveStream = getArchiveInputStream(archiveFile)) {
    TarArchiveEntry entry;
    while ((entry = archiveStream.getNextTarEntry()) != null) {
      String entryName = entry.getName();
      if (entriesToExclude.matches(entryName)) {
        continue;
      }
      Path destFile = Paths.get(entryName);
      Path destPath;
      if (stripPath.isPresent()) {
        if (!destFile.startsWith(stripPath.get())) {
          continue;
        }
        destPath =
            filesystemRelativePath.resolve(stripPath.get().relativize(destFile)).normalize();
      } else {
        destPath = filesystemRelativePath.resolve(destFile).normalize();
      }

      if (entry.isDirectory()) {
        dirsToTidy.add(destPath);
        mkdirs(creator, destPath);
        dirCreationTimes.put(destPath, entry.getModTime().getTime());
      } else if (entry.isSymbolicLink()) {
        if (writeSymlinksAfterCreatingFiles) {
          recordSymbolicLinkForWindows(creator, destPath, entry, windowsSymlinkMap);
        } else {
          writeSymbolicLink(creator, destPath, entry);
        }
        paths.add(destPath);
        setAttributes(filesystem, destPath, entry);
      } else if (entry.isFile()) {
        writeFile(creator, archiveStream, destPath);
        paths.add(destPath);
        setAttributes(filesystem, destPath, entry);
      }
    }

    writeWindowsSymlinks(creator, windowsSymlinkMap);
  } catch (CompressorException e) {
    throw new IOException(
        String.format("Could not get decompressor for archive at %s", archiveFile), e);
  }

  setDirectoryModificationTimes(filesystem, dirCreationTimes);

  ImmutableSet<Path> filePaths = paths.build();
  if (existingFileMode == ExistingFileMode.OVERWRITE_AND_CLEAN_DIRECTORIES) {
    // Clean out directories of files that were not in the archive
    tidyDirectories(filesystem, dirsToTidy, filePaths);
  }
  return filePaths;
}
 
Example 7
Source File: SymbolicLinkPreservingUntarTask.java    From crate with Apache License 2.0 4 votes vote down vote up
@TaskAction
final void execute() {
    // ensure the target extraction path is empty
    getProject().delete(extractPath);
    try (
        TarArchiveInputStream tar = new TarArchiveInputStream(
            new GzipCompressorInputStream(new FileInputStream(tarFile.getAsFile().get()))
        )
    ) {
        final Path destinationPath = extractPath.get().getAsFile().toPath();
        TarArchiveEntry entry = tar.getNextTarEntry();
        while (entry != null) {
            final Path relativePath = transform.apply(entry.getName());
            if (relativePath == null) {
                entry = tar.getNextTarEntry();
                continue;
            }

            final Path destination = destinationPath.resolve(relativePath);
            final Path parent = destination.getParent();
            if (Files.exists(parent) == false) {
                Files.createDirectories(parent);
            }
            if (entry.isDirectory()) {
                Files.createDirectory(destination);
            } else if (entry.isSymbolicLink()) {
                Files.createSymbolicLink(destination, Paths.get(entry.getLinkName()));
            } else {
                // copy the file from the archive using a small buffer to avoid heaping
                Files.createFile(destination);
                try (FileOutputStream fos = new FileOutputStream(destination.toFile())) {
                    tar.transferTo(fos);
                }
            }
            if (entry.isSymbolicLink() == false) {
                // check if the underlying file system supports POSIX permissions
                final PosixFileAttributeView view = Files.getFileAttributeView(destination, PosixFileAttributeView.class);
                if (view != null) {
                    final Set<PosixFilePermission> permissions = PosixFilePermissions.fromString(
                        permissions((entry.getMode() >> 6) & 07) + permissions((entry.getMode() >> 3) & 07) + permissions(
                            (entry.getMode() >> 0) & 07
                        )
                    );
                    Files.setPosixFilePermissions(destination, permissions);
                }
            }
            entry = tar.getNextTarEntry();
        }
    } catch (final IOException e) {
        throw new GradleException("unable to extract tar [" + tarFile.getAsFile().get().toPath() + "]", e);
    }
}