@SuppressWarnings("ResultOfMethodCallIgnored")
 public void testSymlinkFileSet() throws Exception {
   final File zipFile = getTestFile("target/output/pasymlinks-fileset.zip");
   final ZipArchiver zipArchiver = getZipArchiver(zipFile);
   final DefaultFileSet fs = new DefaultFileSet();
   fs.setPrefix("bzz/");
   fs.setDirectory(new File("src/test/resources/symlinks/src"));
   zipArchiver.addFileSet(fs);
   zipArchiver.createArchive();
   final File output = getTestFile("target/output/unzipped/symlFs");
   output.mkdirs();
   final ZipUnArchiver zipUnArchiver = getZipUnArchiver(zipFile);
   zipUnArchiver.setDestFile(output);
   zipUnArchiver.extract();
   File symDir = new File(output, "bzz/symDir");
   PlexusIoResourceAttributes fa = Java7FileAttributes.uncached(symDir);
   assertTrue(fa.isSymbolicLink());
 }
 public void testSymlinkZip() throws Exception {
   final File zipFile = getTestFile("target/output/pasymlinks.zip");
   final ZipArchiver zipArchiver = getZipArchiver(zipFile);
   PlexusIoFileResourceCollection files = new PlexusIoFileResourceCollection();
   files.setFollowingSymLinks(false);
   files.setBaseDir(new File("src/test/resources/symlinks"));
   files.setPrefix("plexus/");
   zipArchiver.addResources(files);
   zipArchiver.createArchive();
   final File output = getTestFile("target/output/unzipped");
   output.mkdirs();
   final ZipUnArchiver zipUnArchiver = getZipUnArchiver(zipFile);
   zipUnArchiver.setDestFile(output);
   zipUnArchiver.extract();
   File symDir = new File("target/output/unzipped/plexus/src/symDir");
   PlexusIoResourceAttributes fa = Java7FileAttributes.uncached(symDir);
   assertTrue(fa.isSymbolicLink());
 }
  /**
   * tar a file
   *
   * @param entry the file to tar
   * @param tOut the output stream
   * @param vPath the path name of the file to tar
   * @throws IOException on error
   */
  protected void tarFile(ArchiveEntry entry, TarOutputStream tOut, String vPath)
      throws ArchiverException, IOException {
    InputStream fIn = null;

    // don't add "" to the archive
    if (vPath.length() <= 0) {
      return;
    }

    if (entry.getResource().isDirectory() && !vPath.endsWith("/")) {
      vPath += "/";
    }

    if (vPath.startsWith("/") && !options.getPreserveLeadingSlashes()) {
      int l = vPath.length();
      if (l <= 1) {
        // we would end up adding "" to the archive
        return;
      }
      vPath = vPath.substring(1, l);
    }

    int pathLength = vPath.length();
    try {
      final TarEntry te;
      if (!longFileMode.isGnuMode() && pathLength >= TarConstants.NAMELEN) {
        int maxPosixPathLen = TarConstants.NAMELEN + TarConstants.POSIX_PREFIXLEN;
        if (longFileMode.isPosixMode()) {
          if (pathLength > maxPosixPathLen) {
            te = new TarEntry(vPath);
          } else {
            te = new PosixTarEntry(vPath);
          }
        } else if (longFileMode.isPosixWarnMode()) {
          if (pathLength > maxPosixPathLen) {
            getLogger()
                .warn("Entry: " + vPath + " longer than " + maxPosixPathLen + " characters.");
            if (!longWarningGiven) {
              getLogger()
                  .warn(
                      "Resulting tar file can only be processed "
                          + "successfully by GNU compatible tar commands");
              longWarningGiven = true;
            }
            te = new TarEntry(vPath);
          } else {
            te = new PosixTarEntry(vPath);
          }
        } else if (longFileMode.isOmitMode()) {
          getLogger().info("Omitting: " + vPath);
          return;
        } else if (longFileMode.isWarnMode()) {
          getLogger()
              .warn("Entry: " + vPath + " longer than " + TarConstants.NAMELEN + " characters.");
          if (!longWarningGiven) {
            getLogger()
                .warn(
                    "Resulting tar file can only be processed "
                        + "successfully by GNU compatible tar commands");
            longWarningGiven = true;
          }
          te = new TarEntry(vPath);
        } else if (longFileMode.isFailMode()) {
          throw new ArchiverException(
              "Entry: " + vPath + " longer than " + TarConstants.NAMELEN + " characters.");
        } else {
          throw new IllegalStateException("Non gnu mode should never get here?");
        }
      } else {
        /* Did not touch it, because this would change the following default tar format, however
         * GNU tar can untar POSIX tar, so I think we should us PosixTarEntry here instead. */
        te = new TarEntry(vPath);
      }

      long teLastModified = entry.getResource().getLastModified();
      te.setModTime(
          teLastModified == PlexusIoResource.UNKNOWN_MODIFICATION_DATE
              ? System.currentTimeMillis()
              : teLastModified);

      if (!entry.getResource().isDirectory()) {
        final long size = entry.getResource().getSize();
        te.setSize(size == PlexusIoResource.UNKNOWN_RESOURCE_SIZE ? 0 : size);

        te.setMode(entry.getMode());
      } else {
        te.setMode(entry.getMode());
      }

      PlexusIoResourceAttributes attributes = entry.getResourceAttributes();

      te.setUserName(
          (attributes != null && attributes.getUserName() != null)
              ? attributes.getUserName()
              : options.getUserName());
      te.setGroupName(
          (attributes != null && attributes.getGroupName() != null)
              ? attributes.getGroupName()
              : options.getGroup());

      final int userId =
          (attributes != null && attributes.getUserId() != null)
              ? attributes.getUserId()
              : options.getUid();
      if (userId > 0) {
        te.setUserId(userId);
      }

      final int groupId =
          (attributes != null && attributes.getGroupId() != null)
              ? attributes.getGroupId()
              : options.getGid();
      if (groupId > 0) {
        te.setGroupId(groupId);
      }

      tOut.putNextEntry(te);

      if (!entry.getResource().isDirectory()) {
        fIn = entry.getInputStream();

        byte[] buffer = new byte[8 * 1024];
        int count = 0;
        do {
          tOut.write(buffer, 0, count);
          count = fIn.read(buffer, 0, buffer.length);
        } while (count != -1);
      }

      tOut.closeEntry();
    } finally {
      IOUtil.close(fIn);
    }
  }
  public void testCreateArchiveWithDetectedModes() throws Exception {

    String[] executablePaths = {"path/to/executable", "path/to/executable.bat"};

    String[] confPaths = {"path/to/etc/file", "path/to/etc/file2"};

    String[] logPaths = {"path/to/logs/log.txt"};

    int exeMode = 0777;
    int confMode = 0600;
    int logMode = 0640;

    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
      StackTraceElement e = new Throwable().getStackTrace()[0];
      System.out.println(
          "Cannot execute test: " + e.getMethodName() + " on " + System.getProperty("os.name"));
      return;
    }

    File tmpDir = null;
    try {
      tmpDir = File.createTempFile("zip-with-chmod.", ".dir");
      tmpDir.delete();

      tmpDir.mkdirs();

      for (String executablePath : executablePaths) {
        writeFile(tmpDir, executablePath, exeMode);
      }

      for (String confPath : confPaths) {
        writeFile(tmpDir, confPath, confMode);
      }

      for (String logPath : logPaths) {
        writeFile(tmpDir, logPath, logMode);
      }

      {
        Map<String, PlexusIoResourceAttributes> attributesByPath =
            PlexusIoResourceAttributeUtils.getFileAttributesByPath(tmpDir);
        for (String path : executablePaths) {
          PlexusIoResourceAttributes attrs = attributesByPath.get(path);
          if (attrs == null) {
            attrs = attributesByPath.get(new File(tmpDir, path).getAbsolutePath());
          }

          assertNotNull(attrs);
          assertEquals(
              "Wrong mode for: " + path + "; expected: " + exeMode, exeMode, attrs.getOctalMode());
        }

        for (String path : confPaths) {
          PlexusIoResourceAttributes attrs = attributesByPath.get(path);
          if (attrs == null) {
            attrs = attributesByPath.get(new File(tmpDir, path).getAbsolutePath());
          }

          assertNotNull(attrs);
          assertEquals(
              "Wrong mode for: " + path + "; expected: " + confMode,
              confMode,
              attrs.getOctalMode());
        }

        for (String path : logPaths) {
          PlexusIoResourceAttributes attrs = attributesByPath.get(path);
          if (attrs == null) {
            attrs = attributesByPath.get(new File(tmpDir, path).getAbsolutePath());
          }

          assertNotNull(attrs);
          assertEquals(
              "Wrong mode for: " + path + "; expected: " + logMode, logMode, attrs.getOctalMode());
        }
      }

      File zipFile = getTestFile("target/output/zip-with-modes.zip");

      ZipArchiver archiver = getZipArchiver(zipFile);

      archiver.addDirectory(tmpDir);
      archiver.createArchive();

      assertTrue(zipFile.exists());

      File zipFile2 = getTestFile("target/output/zip-with-modes-L2.zip");

      archiver = getZipArchiver();
      archiver.setDestFile(zipFile2);

      archiver.addArchivedFileSet(zipFile);
      archiver.createArchive();

      ZipFile zf = new ZipFile(zipFile2);

      for (String path : executablePaths) {
        ZipArchiveEntry ze = zf.getEntry(path);

        int mode = ze.getUnixMode() & UnixStat.PERM_MASK;

        assertEquals("Wrong mode for: " + path + "; expected: " + exeMode, exeMode, mode);
      }

      for (String path : confPaths) {
        ZipArchiveEntry ze = zf.getEntry(path);

        int mode = ze.getUnixMode() & UnixStat.PERM_MASK;

        assertEquals("Wrong mode for: " + path + "; expected: " + confMode, confMode, mode);
      }

      for (String path : logPaths) {
        ZipArchiveEntry ze = zf.getEntry(path);

        int mode = ze.getUnixMode() & UnixStat.PERM_MASK;

        assertEquals("Wrong mode for: " + path + "; expected: " + logMode, logMode, mode);
      }
    } finally {
      if (tmpDir != null && tmpDir.exists()) {
        try {
          FileUtils.forceDelete(tmpDir);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
  /**
   * tar a file
   *
   * @param entry the file to tar
   * @param tOut the output stream
   * @param vPath the path name of the file to tar
   * @throws IOException on error
   */
  protected void tarFile(ArchiveEntry entry, TarArchiveOutputStream tOut, String vPath)
      throws ArchiverException, IOException {

    // don't add "" to the archive
    if (vPath.length() <= 0) {
      return;
    }

    if (entry.getResource().isDirectory() && !vPath.endsWith("/")) {
      vPath += "/";
    }

    if (vPath.startsWith("/") && !options.getPreserveLeadingSlashes()) {
      int l = vPath.length();
      if (l <= 1) {
        // we would end up adding "" to the archive
        return;
      }
      vPath = vPath.substring(1, l);
    }

    int pathLength = vPath.length();
    InputStream fIn = null;

    try {
      TarArchiveEntry te;
      if (!longFileMode.isGnuMode()
          && pathLength >= org.apache.commons.compress.archivers.tar.TarConstants.NAMELEN) {
        int maxPosixPathLen =
            org.apache.commons.compress.archivers.tar.TarConstants.NAMELEN
                + org.apache.commons.compress.archivers.tar.TarConstants.PREFIXLEN;
        if (longFileMode.isPosixMode()) {
        } else if (longFileMode.isPosixWarnMode()) {
          if (pathLength > maxPosixPathLen) {
            getLogger()
                .warn("Entry: " + vPath + " longer than " + maxPosixPathLen + " characters.");
            if (!longWarningGiven) {
              getLogger()
                  .warn(
                      "Resulting tar file can only be processed "
                          + "successfully by GNU compatible tar commands");
              longWarningGiven = true;
            }
          }
        } else if (longFileMode.isOmitMode()) {
          getLogger().info("Omitting: " + vPath);
          return;
        } else if (longFileMode.isWarnMode()) {
          getLogger()
              .warn(
                  "Entry: "
                      + vPath
                      + " longer than "
                      + org.apache.commons.compress.archivers.tar.TarConstants.NAMELEN
                      + " characters.");
          if (!longWarningGiven) {
            getLogger()
                .warn(
                    "Resulting tar file can only be processed "
                        + "successfully by GNU compatible tar commands");
            longWarningGiven = true;
          }
        } else if (longFileMode.isFailMode()) {
          throw new ArchiverException(
              "Entry: "
                  + vPath
                  + " longer than "
                  + org.apache.commons.compress.archivers.tar.TarConstants.NAMELEN
                  + " characters.");
        } else {
          throw new IllegalStateException("Non gnu mode should never get here?");
        }
      }

      if (entry.getType() == ArchiveEntry.SYMLINK) {
        final SymlinkDestinationSupplier plexusIoSymlinkResource =
            (SymlinkDestinationSupplier) entry.getResource();
        te = new TarArchiveEntry(vPath, TarArchiveEntry.LF_SYMLINK);
        te.setLinkName(plexusIoSymlinkResource.getSymlinkDestination());
      } else {
        te = new TarArchiveEntry(vPath);
      }

      long teLastModified = entry.getResource().getLastModified();
      te.setModTime(
          teLastModified == PlexusIoResource.UNKNOWN_MODIFICATION_DATE
              ? System.currentTimeMillis()
              : teLastModified);

      if (entry.getType() == ArchiveEntry.SYMLINK) {
        te.setSize(0);

      } else if (!entry.getResource().isDirectory()) {
        final long size = entry.getResource().getSize();
        te.setSize(size == PlexusIoResource.UNKNOWN_RESOURCE_SIZE ? 0 : size);
      }
      te.setMode(entry.getMode());

      PlexusIoResourceAttributes attributes = entry.getResourceAttributes();

      te.setUserName(
          (attributes != null && attributes.getUserName() != null)
              ? attributes.getUserName()
              : options.getUserName());
      te.setGroupName(
          (attributes != null && attributes.getGroupName() != null)
              ? attributes.getGroupName()
              : options.getGroup());

      final int userId =
          (attributes != null && attributes.getUserId() != null)
              ? attributes.getUserId()
              : options.getUid();
      if (userId >= 0) {
        te.setUserId(userId);
      }

      final int groupId =
          (attributes != null && attributes.getGroupId() != null)
              ? attributes.getGroupId()
              : options.getGid();
      if (groupId >= 0) {
        te.setGroupId(groupId);
      }

      tOut.putArchiveEntry(te);

      try {
        if (entry.getResource().isFile() && !(entry.getType() == ArchiveEntry.SYMLINK)) {
          fIn = entry.getInputStream();

          Streams.copyFullyDontCloseOutput(fIn, tOut, "xAR");
        }

      } catch (Throwable e) {
        getLogger().warn("When creating tar entry", e);
      } finally {
        tOut.closeArchiveEntry();
      }
    } finally {
      IOUtil.close(fIn);
    }
  }