diff --git a/build.xml b/build.xml
index aa06b0f5b..89ac6c475 100644
--- a/build.xml
+++ b/build.xml
@@ -384,14 +384,14 @@
basedir="${dist.name}/.."
includes="${dist.name}/**"
excludes="${dist.name}/lib/optional.jar"/>
-
+
@@ -402,13 +402,13 @@
-
+
diff --git a/src/main/org/apache/tools/ant/taskdefs/Tar.java b/src/main/org/apache/tools/ant/taskdefs/Tar.java
index ae80c097f..06adde55b 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Tar.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Tar.java
@@ -68,9 +68,14 @@ import org.apache.tools.tar.*;
public class Tar extends MatchingTask {
+ static public final String TRUNCATE = "truncate";
+ static public final String GNU = "gnu";
+
File tarFile;
File baseDir;
+ String longFileMode = null;
+
/**
* This is the name/location of where to create the tar file.
*/
@@ -84,6 +89,17 @@ public class Tar extends MatchingTask {
public void setBasedir(File baseDir) {
this.baseDir = baseDir;
}
+
+ /**
+ * Set how to handle long files.
+ *
+ * Allowable values are
+ * truncate
+ * gnu
+ */
+ public void setLongfile(String method) {
+ this.longFileMode = method;
+ }
public void execute() throws BuildException {
if (tarFile == null) {
@@ -115,6 +131,15 @@ public class Tar extends MatchingTask {
try {
tOut = new TarOutputStream(new FileOutputStream(tarFile));
tOut.setDebug(true);
+ if (longFileMode == null) {
+ tOut.setLongFileMode(TarOutputStream.LONGFILE_ERROR);
+ }
+ else if (longFileMode.equalsIgnoreCase(TRUNCATE)) {
+ tOut.setLongFileMode(TarOutputStream.LONGFILE_TRUNCATE);
+ }
+ else if (longFileMode.equalsIgnoreCase(GNU)) {
+ tOut.setLongFileMode(TarOutputStream.LONGFILE_GNU);
+ }
for (int i = 0; i < files.length; i++) {
File f = new File(baseDir,files[i]);
diff --git a/src/main/org/apache/tools/tar/TarConstants.java b/src/main/org/apache/tools/tar/TarConstants.java
index 37372590c..fe4a69959 100644
--- a/src/main/org/apache/tools/tar/TarConstants.java
+++ b/src/main/org/apache/tools/tar/TarConstants.java
@@ -179,4 +179,13 @@ public interface TarConstants {
*/
public static final String GNU_TMAGIC = "ustar ";
+ /**
+ * The namr of the GNU tar entry which contains a long name.
+ */
+ public static final String GNU_LONGLINK = "././@LongLink";
+
+ /**
+ * Identifies the *next* file on the tape as having a long name.
+ */
+ public static final byte LF_GNUTYPE_LONGNAME = (byte) 'L';
}
diff --git a/src/main/org/apache/tools/tar/TarEntry.java b/src/main/org/apache/tools/tar/TarEntry.java
index ef670417c..bc8cdc878 100644
--- a/src/main/org/apache/tools/tar/TarEntry.java
+++ b/src/main/org/apache/tools/tar/TarEntry.java
@@ -178,11 +178,14 @@ public class TarEntry implements TarConstants {
this.devMajor = 0;
this.devMinor = 0;
- if (this.name.length() > NAMELEN) {
- throw new RuntimeException("file name '" + this.name
- + "' is too long ( > "
- + NAMELEN + " bytes)");
- }
+ }
+
+ /**
+ * Construct an entry with a name an a link flag.
+ */
+ public TarEntry(String name, byte linkFlag) {
+ this(name);
+ this.linkFlag = linkFlag;
}
/**
@@ -244,14 +247,6 @@ public class TarEntry implements TarConstants {
this.linkFlag = LF_NORMAL;
}
- if (this.name.length() > NAMELEN) {
- throw new RuntimeException("file name '" + this.name
- + "' is too long ( > "
- + NAMELEN + " bytes)");
-
- // UNDONE When File lets us get the userName, use it!
- }
-
this.size = file.length();
this.modTime = file.lastModified() / 1000;
this.checkSum = 0;
diff --git a/src/main/org/apache/tools/tar/TarOutputStream.java b/src/main/org/apache/tools/tar/TarOutputStream.java
index 8d6f31d30..0d554fb00 100644
--- a/src/main/org/apache/tools/tar/TarOutputStream.java
+++ b/src/main/org/apache/tools/tar/TarOutputStream.java
@@ -69,6 +69,10 @@ import java.io.*;
* @author Timothy Gerard Endres time@ice.com
*/
public class TarOutputStream extends FilterOutputStream {
+ static public final int LONGFILE_ERROR = 0;
+ static public final int LONGFILE_TRUNCATE = 1;
+ static public final int LONGFILE_GNU = 2;
+
protected boolean debug;
protected int currSize;
protected int currBytes;
@@ -77,6 +81,7 @@ public class TarOutputStream extends FilterOutputStream {
protected int assemLen;
protected byte[] assemBuf;
protected TarBuffer buffer;
+ protected int longFileMode = LONGFILE_ERROR;
public TarOutputStream(OutputStream os) {
this(os, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE);
@@ -97,6 +102,11 @@ public class TarOutputStream extends FilterOutputStream {
this.oneBuf = new byte[1];
}
+ public void setLongFileMode(int longFileMode) {
+ this.longFileMode = longFileMode;
+ }
+
+
/**
* Sets the debugging flag.
*
@@ -154,6 +164,27 @@ public class TarOutputStream extends FilterOutputStream {
* @param entry The TarEntry to be written to the archive.
*/
public void putNextEntry(TarEntry entry) throws IOException {
+ if (entry.getName().length() > TarConstants.NAMELEN) {
+
+ if (longFileMode == LONGFILE_GNU) {
+ // create a TarEntry for the LongLink, the contents
+ // of which are the entry's name
+ TarEntry longLinkEntry = new TarEntry(TarConstants.GNU_LONGLINK,
+ TarConstants.LF_GNUTYPE_LONGNAME);
+
+ longLinkEntry.setSize(entry.getName().length() + 1);
+ putNextEntry(longLinkEntry);
+ write(entry.getName().getBytes());
+ write(0);
+ closeEntry();
+ }
+ else if (longFileMode != LONGFILE_TRUNCATE) {
+ throw new RuntimeException("file name '" + entry.getName()
+ + "' is too long ( > "
+ + TarConstants.NAMELEN + " bytes)");
+ }
+ }
+
entry.writeEntryHeader(this.recordBuf);
this.buffer.writeRecord(this.recordBuf);
@@ -210,7 +241,7 @@ public class TarOutputStream extends FilterOutputStream {
/**
* Writes bytes to the current tar archive entry.
*
- * This method simply calls read( byte[], int, int ).
+ * This method simply calls write( byte[], int, int ).
*
* @param wBuf The buffer to write to the archive.
* @return The number of bytes read, or -1 at EOF.
@@ -228,8 +259,6 @@ public class TarOutputStream extends FilterOutputStream {
* that are not a multiple of recordsize in length, including
* assembling records from small buffers.
*
- * This method simply calls read( byte[], int, int ).
- *
* @param wBuf The buffer to write to the archive.
* @param wOffset The offset in the buffer from which to get bytes.
* @param numToWrite The number of bytes to write.