| @@ -203,4 +203,12 @@ | |||
| <untar src="${output}/testout/test.tar" dest="${output}/untar"/> | |||
| </target> | |||
| <target name="testTarFilesetWithSymlinks"> | |||
| <gunzip src="../testtarwithsymlinks.tar.gz" dest="${output}/source.tar"/> | |||
| <tar destfile="${output}/result.tar"> | |||
| <tarfileset prefix="pre" src="${output}/source.tar"/> | |||
| </tar> | |||
| <echo message="asd ${output}"/> | |||
| </target> | |||
| </project> | |||
| @@ -405,12 +405,7 @@ public class Tar extends MatchingTask { | |||
| return; | |||
| } | |||
| String prefix = tarFileSet.getPrefix(this.getProject()); | |||
| // '/' is appended for compatibility with the zip task. | |||
| if (!prefix.isEmpty() && !prefix.endsWith("/")) { | |||
| prefix += "/"; | |||
| } | |||
| vPath = prefix + vPath; | |||
| vPath = getCanonicalPrefix(tarFileSet, this.getProject()) + vPath; | |||
| } else { | |||
| vPath = fullpath; | |||
| } | |||
| @@ -464,6 +459,14 @@ public class Tar extends MatchingTask { | |||
| te.setUserId(tr.getLongUid()); | |||
| te.setGroupName(tr.getGroup()); | |||
| te.setGroupId(tr.getLongGid()); | |||
| String linkName = tr.getLinkName(); | |||
| byte linkFlag = tr.getLinkFlag(); | |||
| if (linkFlag == TarConstants.LF_LINK && | |||
| linkName != null && linkName.length() > 0 && !linkName.startsWith("/")) { | |||
| linkName = getCanonicalPrefix(tarFileSet, this.getProject()) + linkName; | |||
| } | |||
| te.setLinkName(linkName); | |||
| te.setLinkFlag(linkFlag); | |||
| } | |||
| } | |||
| @@ -785,6 +788,15 @@ public class Tar extends MatchingTask { | |||
| return tfs; | |||
| } | |||
| private static String getCanonicalPrefix(TarFileSet tarFileSet, Project project) { | |||
| String prefix = tarFileSet.getPrefix(project); | |||
| // '/' is appended for compatibility with the zip task. | |||
| if (prefix.isEmpty() || prefix.endsWith("/")) { | |||
| return prefix; | |||
| } | |||
| return prefix += "/"; | |||
| } | |||
| /** | |||
| * This is a FileSet with the option to specify permissions | |||
| * and other attributes. | |||
| @@ -26,6 +26,7 @@ import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.types.Resource; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| import org.apache.tools.tar.TarConstants; | |||
| import org.apache.tools.tar.TarEntry; | |||
| import org.apache.tools.tar.TarInputStream; | |||
| @@ -39,6 +40,8 @@ public class TarResource extends ArchiveResource { | |||
| private String groupName = ""; | |||
| private long uid; | |||
| private long gid; | |||
| private byte linkFlag = TarConstants.LF_NORMAL; | |||
| private String linkName = ""; | |||
| /** | |||
| * Default constructor. | |||
| @@ -172,6 +175,22 @@ public class TarResource extends ArchiveResource { | |||
| return (int) getLongGid(); | |||
| } | |||
| /** | |||
| * @return the link "name" (=path) of this entry; an empty string if this is no link | |||
| * @since 1.10.10 | |||
| */ | |||
| public String getLinkName() { | |||
| return linkName; | |||
| } | |||
| /** | |||
| * @return the link "flag" (=type) of this entry | |||
| * @since 1.10.10 | |||
| */ | |||
| public byte getLinkFlag() { | |||
| return linkFlag; | |||
| } | |||
| /** | |||
| * fetches information from the named entry inside the archive. | |||
| */ | |||
| @@ -213,6 +232,8 @@ public class TarResource extends ArchiveResource { | |||
| groupName = e.getGroupName(); | |||
| uid = e.getLongUserId(); | |||
| gid = e.getLongGroupId(); | |||
| linkName = e.getLinkName(); | |||
| linkFlag = e.getLinkFlag(); | |||
| } | |||
| } | |||
| @@ -395,6 +395,24 @@ public class TarEntry implements TarConstants { | |||
| this.mode = mode; | |||
| } | |||
| /** | |||
| * Get this entry's link flag. | |||
| * | |||
| * @return This entry's link flag. | |||
| */ | |||
| public byte getLinkFlag() { | |||
| return linkFlag; | |||
| } | |||
| /** | |||
| * Set this entry's link flag. | |||
| * | |||
| * @param link the link flag to use. | |||
| */ | |||
| public void setLinkFlag(byte linkFlag) { | |||
| this.linkFlag = linkFlag; | |||
| } | |||
| /** | |||
| * Get this entry's link name. | |||
| * | |||
| @@ -19,16 +19,21 @@ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.FileNotFoundException; | |||
| import java.io.IOException; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.BuildFileRule; | |||
| import org.apache.tools.ant.FileUtilities; | |||
| import org.apache.tools.tar.TarEntry; | |||
| import org.apache.tools.tar.TarInputStream; | |||
| import org.junit.Before; | |||
| import org.junit.Rule; | |||
| import org.junit.Test; | |||
| import static org.junit.Assert.assertEquals; | |||
| import static org.junit.Assert.assertNull; | |||
| import static org.junit.Assert.assertTrue; | |||
| public class TarTest { | |||
| @@ -186,4 +191,27 @@ public class TarTest { | |||
| public void testtestTarFilesetWithReference() { | |||
| buildRule.executeTarget("testTarFilesetWithReference"); | |||
| } | |||
| @Test | |||
| public void testTarFilesetWithSymlinks() throws IOException { | |||
| buildRule.executeTarget("testTarFilesetWithSymlinks"); | |||
| final File f = new File(buildRule.getProject().getProperty("output"), "result.tar"); | |||
| final TarInputStream tis = new TarInputStream(new FileInputStream(f)); | |||
| try { | |||
| final TarEntry e1 = tis.getNextEntry(); | |||
| assertEquals("pre/dir/file", e1.getName()); | |||
| assertEquals("", e1.getLinkName()); | |||
| assertEquals(48, e1.getLinkFlag()); | |||
| final TarEntry e2 = tis.getNextEntry(); | |||
| assertEquals("pre/sub/file", e2.getName()); | |||
| assertEquals("../dir/file", e2.getLinkName()); | |||
| assertEquals(50, e2.getLinkFlag()); | |||
| assertNull(tis.getNextEntry()); | |||
| } | |||
| finally { | |||
| tis.close(); | |||
| } | |||
| } | |||
| } | |||