From 6ff2c8367d444eefd444295b032a36805baa617d Mon Sep 17 00:00:00 2001 From: Conor MacNeill Date: Thu, 1 Feb 2001 15:46:32 +0000 Subject: [PATCH] Add support for long filenames in tar task. The tar task now takes an attribute "longfile" which can take either the value "truncate" or the value "gnu". If the attribute is omitted, an exception is thrown (the current behaviour). Truncation is currently silent but willbe fixed to give a warning. Restored building of tar files in the distribution target. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268555 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 20 +++++------ .../org/apache/tools/ant/taskdefs/Tar.java | 25 +++++++++++++ .../org/apache/tools/tar/TarConstants.java | 9 +++++ src/main/org/apache/tools/tar/TarEntry.java | 21 +++++------ .../org/apache/tools/tar/TarOutputStream.java | 35 +++++++++++++++++-- 5 files changed, 84 insertions(+), 26 deletions(-) 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.