0

I am trying to add an Run Script to install4j that handles the unzipping and untarring of tarballs for things like like mysql and tomcat that are getting embedded in my installer. I realize that I could explode these tars as part of the build process in ant, but for at least one use case I can't do that.

I have included the code below in my Run Script action, using the org.apache.tools.tar.TarEntry and TarInputStream classes. This is working reasonably well, with one bug.

Using this implementation, file paths that are longer than 99 characters are being truncated and the resulting files are being exploded into the top-level directory.

I'm trying to figure out if this is a bug in my implementation or a problem with the apache tools classes. It seems tarEntry.getName() isn't returning the entire path when it's over 99 characters. Is there an easy way work around this without having to rewrite what TarInputStream does? Tar.Entry has a isGNULongNameEntry method, but I can't seem to figure out a reliable way to account for where to put the file when this returns true.

Any suggestions?

import java.io.*;
import java.util.zip.*;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;

String outputDirectory = "mysql";
File tgzFile = new File(context.getInstallationDirectory(), outputDirectory + File.separator + "mysql-5.5.17-linux2.6-i686.tar.gz");

// Create the Tar input stream.
FileInputStream fin = new FileInputStream(tgzFile);
GZIPInputStream gin = new GZIPInputStream(fin);
TarInputStream tin = new TarInputStream(gin);

// Create the destination directory.
File outputDir = new File(outputDirectory);
outputDir.mkdir();

// Extract files.
TarEntry tarEntry = tin.getNextEntry();
while (tarEntry != null) {
    File destPath = new File(context.getInstallationDirectory(), outputDirectory + File.separator + tarEntry.getName());

tarEntry.isGNULongNameEntry()

    if (tarEntry.isDirectory()) {
        destPath.mkdirs();
    } else {
        // If the parent directory of a file doesn't exist, create it.
        if (!destPath.getParentFile().exists())
            destPath.getParentFile().mkdirs();

        FileOutputStream fout = new FileOutputStream(destPath);
        tin.copyEntryContents(fout);
        fout.close();
    // Presserve the last modified date of the tar'd files.
        destPath.setLastModified(tarEntry.getModTime().getTime());
    }
    tarEntry = tin.getNextEntry();
}
tin.close();

return true;
Frank
  • 165
  • 1
  • 13

2 Answers2

1

Feel free to look at my proposed patch for this ant untar issue It might give you some pointers at least.

Peter Svensson
  • 6,105
  • 1
  • 31
  • 31
  • Thanks Peter, at least that helps me to know I"m not the only one dealing with similar issues. Wow, you submitted that quite awhile ago. I'm surprised they haven't picked up the patch. – Frank Feb 09 '12 at 15:26
0

While long file names in POSIX tar files are not handled by the apache tar library, you could use GNU tar to create the tar files. In that case there will be no problem with long file names.

Ingo Kegel
  • 46,523
  • 10
  • 71
  • 102
  • Yea problem with that is I have no control over the tar files I'm dealing with, they're distributed by third parties. I could untar and retart them but that's not a great workaround. – Frank Feb 10 '12 at 15:46