Info-Zip way. PR: 6492 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@273629 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -132,6 +132,9 @@ Other changes: | |||
| * <tarfileset> has a new dirmode attribute to specify the permissions | |||
| for directories. | |||
| * <zip> can now store Unix permissions in a way that can be | |||
| reconstructed by Info-Zip's unzip command. | |||
| Changes from Ant 1.5.1Beta1 to 1.5.1 | |||
| ==================================== | |||
| @@ -1183,9 +1183,21 @@ | |||
| <antcall inheritAll="false" target="internal_dist"> | |||
| <param name="dist.dir" value="${dist.name}"/> | |||
| </antcall> | |||
| <zip destfile="${dist.base}/bin/${dist.name}-bin.zip" | |||
| basedir="${dist.name}/.." | |||
| includes="${dist.name}/**"/> | |||
| <zip destfile="${dist.base}/bin/${dist.name}-bin.zip"> | |||
| <zipfileset dir="${dist.name}/.." filemode="755"> | |||
| <include name="${dist.name}/bin/ant"/> | |||
| <include name="${dist.name}/bin/antRun"/> | |||
| <include name="${dist.name}/bin/*.pl"/> | |||
| <include name="${dist.name}/bin/*.py"/> | |||
| </zipfileset> | |||
| <fileset dir="${dist.name}/.."> | |||
| <include name="${dist.name}/**"/> | |||
| <exclude name="${dist.name}/bin/ant"/> | |||
| <exclude name="${dist.name}/bin/antRun"/> | |||
| <exclude name="${dist.name}/bin/*.pl"/> | |||
| <exclude name="${dist.name}/bin/*.py"/> | |||
| </fileset> | |||
| </zip> | |||
| <tar longfile="gnu" | |||
| destfile="${dist.base}/bin/${dist.name}-bin.tar"> | |||
| <tarfileset dir="${dist.name}/.." mode="755" username="ant" group="ant"> | |||
| @@ -1219,9 +1231,17 @@ | |||
| <antcall inheritAll="false" target="src-dist"> | |||
| <param name="src.dist.dir" value="${dist.name}"/> | |||
| </antcall> | |||
| <zip destfile="${dist.base}/src/${dist.name}-src.zip" | |||
| basedir="${dist.name}/.." | |||
| includes="${dist.name}/**"/> | |||
| <zip destfile="${dist.base}/src/${dist.name}-src.zip"> | |||
| <zipfileset dir="${dist.name}/.." filemode="755"> | |||
| <include name="${dist.name}/bootstrap.sh"/> | |||
| <include name="${dist.name}/build.sh"/> | |||
| </zipfileset> | |||
| <fileset dir="${dist.name}/.."> | |||
| <include name="${dist.name}/**"/> | |||
| <exclude name="${dist.name}/bootstrap.sh"/> | |||
| <exclude name="${dist.name}/build.sh"/> | |||
| </fileset> | |||
| </zip> | |||
| <tar longfile="gnu" | |||
| destfile="${dist.base}/src/${dist.name}-src.tar" > | |||
| <tarfileset dir="${dist.name}/.." mode="755" username="ant" group="ant"> | |||
| @@ -52,6 +52,15 @@ but causes problems if you try to open them from within Java and your | |||
| filenames contain non US-ASCII characters. Use the encoding attribute | |||
| and set it to UTF8 to create zip files that can safely be read by | |||
| Java.</p> | |||
| <p>Starting with Ant 1.6, <zip> can store Unix permissions | |||
| inside the archive (see description of the filemode and dirmode | |||
| attributes for <a href="#zipfileset"><zipfileset></a>). | |||
| Unfortunately there is no portable way to store these permissions. | |||
| Ant uses the algorithm used by <a href="http://www.info-zip.org">Info-Zip's</a> | |||
| implementation of the zip and unzip commands - these are the default | |||
| versions of zip and unzip for many Unix and Unix-like systems.</p> | |||
| <h3>Parameters</h3> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| @@ -144,15 +153,64 @@ Java.</p> | |||
| <p>The zip task supports any number of nested <a | |||
| href="../CoreTypes/fileset.html"><code><fileset></code></a> elements to specify | |||
| the files to be included in the archive.</p> | |||
| <h4>zipfileset</h4> | |||
| <p>A <code><zipfileset></code> has three additional attributes: <i>prefix</i>, <i>fullpath</i>, and <i>src</i>. The | |||
| <i>prefix</i> and <i>fullpath</i> attributes modify the location of the files when they are placed | |||
| inside the archive. If the <i>prefix</i> attribute is set, all files in the fileset are prefixed | |||
| with that path in the archive. If the <i>fullpath</i> attribute is set, the file described by the fileset is placed at that | |||
| exact location in the archive. (The <i>fullpath</i> attribute can only be set for filesets that represent a single file. The <i>prefix</i> and <i>fullpath</i> attributes cannot both be set on the same fileset.) The <i>src</i> attribute | |||
| may be used in place of the <i>dir</i> attribute to specify a zip file whose | |||
| contents will be extracted and included in the archive. As with directories, include and exclude patterns may be used to specify a subset of the zip file | |||
| for inclusion in the archive.</p> | |||
| <h4><a name="zipfileset">zipfileset</a></h4> | |||
| <p>A <code><zipfileset></code> is a special form of a | |||
| <code><fileset></code> that adds some extra functionality. It | |||
| supports all attributes of <code><fileset></code> in addition to | |||
| those listed below.</p> | |||
| <h3>Parameters</h3> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| <td valign="top"><b>Attribute</b></td> | |||
| <td valign="top"><b>Description</b></td> | |||
| <td valign="top" align="center"><b>Required</b></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">prefix</td> | |||
| <td valign="top">all files in the fileset are prefixed with that | |||
| path in the archive.</td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">fullpath</td> | |||
| <td valign="top">the file described by the fileset is placed at | |||
| that exact location in the archive.</td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">src</td> | |||
| <td valign="top">may be used in place of the <i>dir</i> attribute | |||
| to specify a zip file whose contents will be extracted and | |||
| included in the archive.</td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">filemode</td> | |||
| <td valign="top">A 3 digit octal string, specify the user, group | |||
| and other modes in the standard Unix fashion. Only applies to | |||
| plain files. Default is 644. <em>since Ant 1.6</em>.</td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">dirmode</td> | |||
| <td valign="top">A 3 digit octal string, specify the user, group | |||
| and other modes in the standard Unix fashion. Only applies to | |||
| directories. Default is 755. <em>since Ant 1.6</em>.</td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| </table> | |||
| <p>The <i>fullpath</i> attribute can only be set for filesets that | |||
| represent a single file. The <i>prefix</i> and <i>fullpath</i> | |||
| attributes cannot both be set on the same fileset.</p> | |||
| <p>When using the <i>src</i> attribute, include and exclude patterns | |||
| may be used to specify a subset of the zip file for inclusion in the | |||
| archive as with the <i>dir</i> attribute.</p> | |||
| <h4>zipgroupfileset</h4> | |||
| <p>A <code><zipgroupfileset></code> allows for multiple zip files to be | |||
| merged into the archive. Each file found in this fileset is added to the archive | |||
| @@ -134,7 +134,8 @@ public class Ear extends Jar { | |||
| super.initZipOutputStream(zOut); | |||
| } | |||
| protected void zipFile(File file, ZipOutputStream zOut, String vPath) | |||
| protected void zipFile(File file, ZipOutputStream zOut, String vPath, | |||
| int mode) | |||
| throws IOException { | |||
| // If the file being added is META-INF/application.xml, we | |||
| // warn if it's not the one specified in the "appxml" | |||
| @@ -150,11 +151,11 @@ public class Ear extends Jar { | |||
| + " be ignored (please use appxml attribute to " | |||
| + archiveType + " task)", Project.MSG_WARN); | |||
| } else { | |||
| super.zipFile(file, zOut, vPath); | |||
| super.zipFile(file, zOut, vPath, mode); | |||
| descriptorAdded = true; | |||
| } | |||
| } else { | |||
| super.zipFile(file, zOut, vPath); | |||
| super.zipFile(file, zOut, vPath, mode); | |||
| } | |||
| } | |||
| @@ -314,7 +314,7 @@ public class Jar extends Zip { | |||
| Project.MSG_WARN); | |||
| } | |||
| zipDir(null, zOut, "META-INF/"); | |||
| zipDir(null, zOut, "META-INF/", ZipFileSet.DEFAULT_DIR_MODE); | |||
| // time to write the manifest | |||
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |||
| PrintWriter writer = new PrintWriter(baos); | |||
| @@ -324,7 +324,8 @@ public class Jar extends Zip { | |||
| ByteArrayInputStream bais = | |||
| new ByteArrayInputStream(baos.toByteArray()); | |||
| super.zipFile(bais, zOut, "META-INF/MANIFEST.MF", | |||
| System.currentTimeMillis(), null); | |||
| System.currentTimeMillis(), null, | |||
| ZipFileSet.DEFAULT_FILE_MODE); | |||
| super.initZipOutputStream(zOut); | |||
| } | |||
| @@ -387,20 +388,22 @@ public class Jar extends Zip { | |||
| writer.flush(); | |||
| ByteArrayInputStream bais = | |||
| new ByteArrayInputStream(baos.toByteArray()); | |||
| super.zipFile(bais, zOut, INDEX_NAME, System.currentTimeMillis(), null); | |||
| super.zipFile(bais, zOut, INDEX_NAME, System.currentTimeMillis(), null, | |||
| ZipFileSet.DEFAULT_FILE_MODE); | |||
| } | |||
| /** | |||
| * Overriden from Zip class to deal with manifests | |||
| */ | |||
| protected void zipFile(File file, ZipOutputStream zOut, String vPath) | |||
| protected void zipFile(File file, ZipOutputStream zOut, String vPath, | |||
| int mode) | |||
| throws IOException { | |||
| if ("META-INF/MANIFEST.MF".equalsIgnoreCase(vPath)) { | |||
| if (! doubleFilePass || (doubleFilePass && skipWriting)) { | |||
| filesetManifest(file, null); | |||
| } | |||
| } else { | |||
| super.zipFile(file, zOut, vPath); | |||
| super.zipFile(file, zOut, vPath, mode); | |||
| } | |||
| } | |||
| @@ -408,14 +411,14 @@ public class Jar extends Zip { | |||
| * Overriden from Zip class to deal with manifests | |||
| */ | |||
| protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath, | |||
| long lastModified, File file) | |||
| long lastModified, File file, int mode) | |||
| throws IOException { | |||
| if ("META-INF/MANIFEST.MF".equalsIgnoreCase(vPath)) { | |||
| if (! doubleFilePass || (doubleFilePass && skipWriting)) { | |||
| filesetManifest(file, is); | |||
| } | |||
| } else { | |||
| super.zipFile(is, zOut, vPath, lastModified, null); | |||
| super.zipFile(is, zOut, vPath, lastModified, null, mode); | |||
| } | |||
| } | |||
| @@ -172,7 +172,8 @@ public class War extends Jar { | |||
| /** | |||
| * add another file to the stream | |||
| */ | |||
| protected void zipFile(File file, ZipOutputStream zOut, String vPath) | |||
| protected void zipFile(File file, ZipOutputStream zOut, String vPath, | |||
| int mode) | |||
| throws IOException { | |||
| // If the file being added is WEB-INF/web.xml, we warn if it's | |||
| // not the one specified in the "webxml" attribute - or if | |||
| @@ -187,11 +188,11 @@ public class War extends Jar { | |||
| + "(please use webxml attribute to " | |||
| + archiveType + " task)", Project.MSG_WARN); | |||
| } else { | |||
| super.zipFile(file, zOut, vPath); | |||
| super.zipFile(file, zOut, vPath, mode); | |||
| descriptorAdded = true; | |||
| } | |||
| } else { | |||
| super.zipFile(file, zOut, vPath); | |||
| super.zipFile(file, zOut, vPath, mode); | |||
| } | |||
| } | |||
| @@ -388,7 +388,9 @@ public class Zip extends MatchingTask { | |||
| // Add the implicit fileset to the archive. | |||
| if (baseDir != null) { | |||
| addFiles(getDirectoryScanner(baseDir), zOut, "", ""); | |||
| addFiles(getDirectoryScanner(baseDir), zOut, "", "", | |||
| ZipFileSet.DEFAULT_DIR_MODE, | |||
| ZipFileSet.DEFAULT_FILE_MODE); | |||
| } | |||
| // Add the explicit filesets to the archive. | |||
| addFiles(filesets, zOut); | |||
| @@ -473,10 +475,28 @@ public class Zip extends MatchingTask { | |||
| * prependig the given prefix to each filename. | |||
| * | |||
| * <p>Ensure parent directories have been added as well. | |||
| * | |||
| * @deprecated use six-arg version instead. | |||
| */ | |||
| protected void addFiles(FileScanner scanner, ZipOutputStream zOut, | |||
| String prefix, String fullpath) | |||
| throws IOException { | |||
| addFiles(scanner, zOut, prefix, fullpath, ZipFileSet.DEFAULT_DIR_MODE, | |||
| ZipFileSet.DEFAULT_FILE_MODE); | |||
| } | |||
| /** | |||
| * Add all files of the given FileScanner to the ZipOutputStream | |||
| * prependig the given prefix to each filename. | |||
| * | |||
| * <p>Ensure parent directories have been added as well. | |||
| * | |||
| * @since Ant 1.6 | |||
| */ | |||
| protected void addFiles(FileScanner scanner, ZipOutputStream zOut, | |||
| String prefix, String fullpath, int dirMode, | |||
| int fileMode) | |||
| throws IOException { | |||
| if (prefix.length() > 0 && fullpath.length() > 0) { | |||
| throw new BuildException("Both prefix and fullpath attributes must" | |||
| @@ -500,7 +520,7 @@ public class Zip extends MatchingTask { | |||
| if (!name.endsWith("/")) { | |||
| name += "/"; | |||
| } | |||
| addParentDirs(thisBaseDir, name, zOut, prefix); | |||
| addParentDirs(thisBaseDir, name, zOut, prefix, dirMode); | |||
| } | |||
| // files that matched include patterns | |||
| @@ -514,13 +534,13 @@ public class Zip extends MatchingTask { | |||
| File f = new File(thisBaseDir, files[i]); | |||
| if (fullpath.length() > 0) { | |||
| // Add this file at the specified location. | |||
| addParentDirs(null, fullpath, zOut, ""); | |||
| zipFile(f, zOut, fullpath); | |||
| addParentDirs(null, fullpath, zOut, "", dirMode); | |||
| zipFile(f, zOut, fullpath, fileMode); | |||
| } else { | |||
| // Add this file with the specified prefix. | |||
| String name = files[i].replace(File.separatorChar, '/'); | |||
| addParentDirs(thisBaseDir, name, zOut, prefix); | |||
| zipFile(f, zOut, prefix + name); | |||
| addParentDirs(thisBaseDir, name, zOut, prefix, dirMode); | |||
| zipFile(f, zOut, prefix + name, fileMode); | |||
| } | |||
| } | |||
| } | |||
| @@ -550,13 +570,16 @@ public class Zip extends MatchingTask { | |||
| String vPath = entry.getName(); | |||
| if (zipScanner.match(vPath)) { | |||
| if (fullpath.length() > 0) { | |||
| addParentDirs(null, fullpath, zOut, ""); | |||
| zipFile(in, zOut, fullpath, entry.getTime(), zipSrc); | |||
| addParentDirs(null, fullpath, zOut, "", | |||
| fs.getDirMode()); | |||
| zipFile(in, zOut, fullpath, entry.getTime(), zipSrc, | |||
| fs.getFileMode()); | |||
| } else { | |||
| addParentDirs(null, vPath, zOut, prefix); | |||
| addParentDirs(null, vPath, zOut, prefix, | |||
| fs.getDirMode()); | |||
| if (!entry.isDirectory()) { | |||
| zipFile(in, zOut, prefix + vPath, entry.getTime(), | |||
| zipSrc); | |||
| zipSrc, fs.getFileMode()); | |||
| } | |||
| } | |||
| } | |||
| @@ -701,8 +724,20 @@ public class Zip extends MatchingTask { | |||
| return result; | |||
| } | |||
| /** | |||
| * @deprecated use four-arg version instead. | |||
| */ | |||
| protected void zipDir(File dir, ZipOutputStream zOut, String vPath) | |||
| throws IOException { | |||
| zipDir(dir, zOut, vPath, ZipFileSet.DEFAULT_DIR_MODE); | |||
| } | |||
| /** | |||
| * @since Ant 1.6 | |||
| */ | |||
| protected void zipDir(File dir, ZipOutputStream zOut, String vPath, | |||
| int mode) | |||
| throws IOException { | |||
| if (addedDirs.get(vPath) != null) { | |||
| // don't add directories we've already added. | |||
| // no warning if we try, it is harmless in and of itself | |||
| @@ -723,17 +758,28 @@ public class Zip extends MatchingTask { | |||
| ze.setMethod (ZipEntry.STORED); | |||
| // This is faintly ridiculous: | |||
| ze.setCrc (EMPTY_CRC); | |||
| // this is 040775 | MS-DOS directory flag in reverse byte order | |||
| ze.setExternalAttributes(0x41FD0010L); | |||
| ze.setUnixMode(mode); | |||
| zOut.putNextEntry (ze); | |||
| } | |||
| } | |||
| /** | |||
| * @deprecated use six-arg version instead. | |||
| */ | |||
| protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath, | |||
| long lastModified, File file) | |||
| throws IOException { | |||
| zipFile(in, zOut, vPath, lastModified, file, | |||
| ZipFileSet.DEFAULT_FILE_MODE); | |||
| } | |||
| /** | |||
| * @since Ant 1.6 | |||
| */ | |||
| protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath, | |||
| long lastModified, File file, int mode) | |||
| throws IOException { | |||
| if (entries.contains(vPath)) { | |||
| if (duplicate.equals("preserve")) { | |||
| @@ -759,14 +805,15 @@ public class Zip extends MatchingTask { | |||
| ze.setTime(lastModified); | |||
| /* | |||
| * XXX ZipOutputStream.putEntry expects the ZipEntry to know its | |||
| * size and the CRC sum before you start writing the data when using | |||
| * STORED mode. | |||
| * ZipOutputStream.putNextEntry expects the ZipEntry to | |||
| * know its size and the CRC sum before you start writing | |||
| * the data when using STORED mode. | |||
| * | |||
| * This forces us to process the data twice. | |||
| * | |||
| * I couldn't find any documentation on this, just found out by try | |||
| * and error. | |||
| * In DEFLATED mode, it will take advantage of a Zip | |||
| * Version 2 feature where size can be stored after the | |||
| * data (as the data itself signals end of data). | |||
| */ | |||
| if (!doCompress) { | |||
| long size = 0; | |||
| @@ -800,6 +847,7 @@ public class Zip extends MatchingTask { | |||
| ze.setCrc(cal.getValue()); | |||
| } | |||
| ze.setUnixMode(mode); | |||
| zOut.putNextEntry(ze); | |||
| byte[] buffer = new byte[8 * 1024]; | |||
| @@ -814,8 +862,20 @@ public class Zip extends MatchingTask { | |||
| addedFiles.addElement(vPath); | |||
| } | |||
| /** | |||
| * @deprecated use six-arg version instead. | |||
| */ | |||
| protected void zipFile(File file, ZipOutputStream zOut, String vPath) | |||
| throws IOException { | |||
| zipFile(file, zOut, vPath, ZipFileSet.DEFAULT_FILE_MODE); | |||
| } | |||
| /** | |||
| * @since Ant 1.6 | |||
| */ | |||
| protected void zipFile(File file, ZipOutputStream zOut, String vPath, | |||
| int mode) | |||
| throws IOException { | |||
| if (file.equals(zipFile)) { | |||
| throw new BuildException("A zip file cannot include itself", | |||
| getLocation()); | |||
| @@ -823,18 +883,31 @@ public class Zip extends MatchingTask { | |||
| FileInputStream fIn = new FileInputStream(file); | |||
| try { | |||
| zipFile(fIn, zOut, vPath, file.lastModified(), null); | |||
| zipFile(fIn, zOut, vPath, file.lastModified(), null, mode); | |||
| } finally { | |||
| fIn.close(); | |||
| } | |||
| } | |||
| /** | |||
| * Ensure all parent dirs of a given entry have been added. | |||
| * @deprecated use five-arg version instead. | |||
| */ | |||
| protected void addParentDirs(File baseDir, String entry, | |||
| ZipOutputStream zOut, String prefix) | |||
| throws IOException { | |||
| addParentDirs(baseDir, entry, zOut, prefix, | |||
| ZipFileSet.DEFAULT_DIR_MODE); | |||
| } | |||
| /** | |||
| * Ensure all parent dirs of a given entry have been added. | |||
| * | |||
| * @since Ant 1.6 | |||
| */ | |||
| protected void addParentDirs(File baseDir, String entry, | |||
| ZipOutputStream zOut, String prefix, | |||
| int dirMode) | |||
| throws IOException { | |||
| if (!doFilesonly) { | |||
| Stack directories = new Stack(); | |||
| int slashPos = entry.length(); | |||
| @@ -855,7 +928,7 @@ public class Zip extends MatchingTask { | |||
| } else { | |||
| f = new File(dir); | |||
| } | |||
| zipDir(f, zOut, prefix + dir); | |||
| zipDir(f, zOut, prefix + dir, dirMode); | |||
| } | |||
| } | |||
| } | |||
| @@ -874,10 +947,14 @@ public class Zip extends MatchingTask { | |||
| String prefix = ""; | |||
| String fullpath = ""; | |||
| int fileMode = ZipFileSet.DEFAULT_FILE_MODE; | |||
| int dirMode = ZipFileSet.DEFAULT_DIR_MODE; | |||
| if (fs instanceof ZipFileSet) { | |||
| ZipFileSet zfs = (ZipFileSet) fs; | |||
| prefix = zfs.getPrefix(); | |||
| fullpath = zfs.getFullpath(); | |||
| fileMode = zfs.getFileMode(); | |||
| dirMode = zfs.getDirMode(); | |||
| } | |||
| if (prefix.length() > 0 | |||
| @@ -889,10 +966,10 @@ public class Zip extends MatchingTask { | |||
| // Need to manually add either fullpath's parent directory, or | |||
| // the prefix directory, to the archive. | |||
| if (prefix.length() > 0) { | |||
| addParentDirs(null, prefix, zOut, ""); | |||
| zipDir(null, zOut, prefix); | |||
| addParentDirs(null, prefix, zOut, "", dirMode); | |||
| zipDir(null, zOut, prefix, dirMode); | |||
| } else if (fullpath.length() > 0) { | |||
| addParentDirs(null, fullpath, zOut, ""); | |||
| addParentDirs(null, fullpath, zOut, "", dirMode); | |||
| } | |||
| if (fs instanceof ZipFileSet | |||
| @@ -900,7 +977,7 @@ public class Zip extends MatchingTask { | |||
| addZipEntries((ZipFileSet) fs, ds, zOut, prefix, fullpath); | |||
| } else { | |||
| // Add the fileset. | |||
| addFiles(ds, zOut, prefix, fullpath); | |||
| addFiles(ds, zOut, prefix, fullpath, dirMode, fileMode); | |||
| } | |||
| } | |||
| } | |||
| @@ -80,12 +80,28 @@ import org.apache.tools.zip.UnixStat; | |||
| */ | |||
| public class ZipFileSet extends FileSet { | |||
| /** | |||
| * Default value for the dirmode attribute. | |||
| * | |||
| * @since Ant 1.6 | |||
| */ | |||
| public static final int DEFAULT_DIR_MODE = | |||
| UnixStat.DIR_FLAG | UnixStat.DEFAULT_DIR_PERM; | |||
| /** | |||
| * Default value for the filemode attribute. | |||
| * | |||
| * @since Ant 1.6 | |||
| */ | |||
| public static final int DEFAULT_FILE_MODE = | |||
| UnixStat.FILE_FLAG | UnixStat.DEFAULT_FILE_PERM; | |||
| private File srcFile = null; | |||
| private String prefix = ""; | |||
| private String fullpath = ""; | |||
| private boolean hasDir = false; | |||
| private int fileMode = UnixStat.FILE_FLAG | UnixStat.DEFAULT_FILE_PERM; | |||
| private int dirMode = UnixStat.DIR_FLAG | UnixStat.DEFAULT_DIR_PERM; | |||
| private int fileMode = DEFAULT_FILE_MODE; | |||
| private int dirMode = DEFAULT_DIR_MODE; | |||
| public ZipFileSet() { | |||
| super(); | |||
| @@ -198,6 +198,8 @@ public class ZipEntry extends java.util.zip.ZipEntry { | |||
| */ | |||
| public void setUnixMode(int mode) { | |||
| setExternalAttributes((mode << 16) | |||
| // MS-DOS read-only attribute | |||
| | ((mode & 0200) == 0 ? 1 : 0) | |||
| // MS-DOS directory flag | |||
| | (isDirectory() ? 0x10 : 0)); | |||
| platform = PLATFORM_UNIX; | |||
| @@ -131,12 +131,25 @@ public class ZipEntryTest extends TestCase { | |||
| (ze.getExternalAttributes() >> 16) & 0xFFFF); | |||
| assertEquals(0, ze.getExternalAttributes() & 0xFFFF); | |||
| ze.setUnixMode(0444); | |||
| assertEquals(3, ze.getPlatform()); | |||
| assertEquals(0444, | |||
| (ze.getExternalAttributes() >> 16) & 0xFFFF); | |||
| assertEquals(1, ze.getExternalAttributes() & 0xFFFF); | |||
| ze = new ZipEntry("foo/"); | |||
| assertEquals(0, ze.getPlatform()); | |||
| ze.setUnixMode(0777); | |||
| assertEquals(3, ze.getPlatform()); | |||
| assertEquals(0777, | |||
| (ze.getExternalAttributes() >> 16) & 0xFFFF); | |||
| assertEquals(0x10, ze.getExternalAttributes() & 0xFFFF); | |||
| ze.setUnixMode(0577); | |||
| assertEquals(3, ze.getPlatform()); | |||
| assertEquals(0577, | |||
| (ze.getExternalAttributes() >> 16) & 0xFFFF); | |||
| assertEquals(0x10, ze.getExternalAttributes() & 0xFFFF); | |||
| assertEquals(0x11, ze.getExternalAttributes() & 0xFFFF); | |||
| } | |||
| } | |||