From: <chr...@us...> - 2009-04-15 14:42:12
|
Revision: 5284 http://jnode.svn.sourceforge.net/jnode/?rev=5284&view=rev Author: chrisboertien Date: 2009-04-15 14:41:53 +0000 (Wed, 15 Apr 2009) Log Message: ----------- Implemented zip/unzip commands. This is just a start, not many options are actually supported yet. zip can create a new archive, and is able to recurse unzip can list and extract the contents of an archive Signed-off-by: Chris <chr...@gm...> Modified Paths: -------------- trunk/fs/descriptors/org.apache.tools.archive.xml trunk/fs/descriptors/org.jnode.fs.command.archive.xml trunk/fs/src/fs/org/jnode/fs/command/archive/UnzipCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java Added Paths: ----------- trunk/fs/src/fs/org/jnode/fs/command/archive/BZCatCommand.java Modified: trunk/fs/descriptors/org.apache.tools.archive.xml =================================================================== --- trunk/fs/descriptors/org.apache.tools.archive.xml 2009-04-15 14:41:09 UTC (rev 5283) +++ trunk/fs/descriptors/org.apache.tools.archive.xml 2009-04-15 14:41:53 UTC (rev 5284) @@ -21,7 +21,7 @@ <permission class="java.lang.RuntimePermission" name="setSecurityManager" actions="*" /> <permission class="java.lang.RuntimePermission" name="setIO" actions="*" /> <permission class="java.lang.RuntimePermission" name="exitVM" actions="*" /> - <permission class="java.lang.RuntimePermission" name="createClassLoader" actions="*" /> + <permission class="java.lang.RuntimePermission" name="createClassLoader" actions="*" /> <permission class="org.jnode.security.JNodePermission" name="getVmClass" actions="*" /> <permission class="java.util.PropertyPermission" name="*" actions="read,write"/> </extension> Modified: trunk/fs/descriptors/org.jnode.fs.command.archive.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.command.archive.xml 2009-04-15 14:41:09 UTC (rev 5283) +++ trunk/fs/descriptors/org.jnode.fs.command.archive.xml 2009-04-15 14:41:53 UTC (rev 5284) @@ -31,76 +31,67 @@ </extension> <extension point="org.jnode.shell.syntaxes"> - <syntax alias="tar"> - <sequence> - <optionSet description="tar options"> - <!-- Tar Operations --> - <option argLabel="doAppend" shortName="r" longName="append" /> - <option argLabel="doCreate" shortName="c" longName="create" /> - <option argLabel="doConcat" shortName="A" longName="concatenate" /> - <option argLabel="doDelete" longName="delete" /> - <option argLabel="doDiff" shortName="d" longName="diff" /> - <option argLabel="doExtract" shortName="x" longName="extract" /> - <option argLabel="doList" shortName="t" longName="list" /> - <option argLabel="doUpdate" shortName="u" longName="update" /> - <!-- Tar Global Options --> - <option argLabel="archive" shortName="f" longName="file" /> - <option argLabel="backup" longName="backup" /> - <option argLabel="bzip" shortName="j" longName="bzip2" /> - <option argLabel="fileList" shortName="T" longName="files-from"/> - <option argLabel="gzip" shortName="z" longName="gzip" /> - <option argLabel="interact" shortName="w" longName="interactive" /> - <option argLabel="keep_old" shortName="k" longName="keep-old-files" /> - <option argLabel="keep_new" longName="keep-newer-files" /> - <option argLabel="removeFiles" longName="remove-files" /> - <option argLabel="showTotals" longName="totals" /> - <option argLabel="suffix" longName="suffix" /> - <option argLabel="unlink" longName="unlink" /> - <option argLabel="verify" shortName="W" longName="verify" /> - <option argLabel="xfile" shortName="X" longName="exclude-from"/> - <!-- Tar Path Parser Options --> - <!-- These need to be changed out of here once the syntax allows for specifying positional arguments. --> - <option argLabel="exclude" longName="exclude" label="pattern" /> - <option argLabel="noRecurse" longName="no-recursion" /> - <option argLabel="recurse" longName="recursion" /> - <option argLabel="dir" shortName="C" longName="directory" /> + <syntax alias="bunzip2"> + <empty description="decompress stdin to stdout" /> + <sequence description="decompress files"> + <optionSet> + <!-- BZip --> + <option argLabel="compress" shortName="z" longName="compress"/> + <option argLabel="decompress" shortName="d" longName="decompress"/> + <option argLabel="test" shortName="t" longName="test" /> + <option argLabel="keep" shortName="k" longName="keep" /> + <option argLabel="small" shortName="s" longName="small" /> <!-- ArchiveCommand --> + <option argLabel="stdout" shortName="c" longName="stdout" /> + <option argLabel="force" shortName="f" longName="force" /> <option argLabel="verbose" shortName="v" longName="verbose" /> + <option argLabel="quiet" shortName="q" longName="quiet" /> <option argLabel="debug" longName="debug" /> - <option argLabel="stdout" shortName="O" longName="to-stdout" /> - <!-- - <option argLabel="minDate" shortName="N" longName="newer" /> - <option argLabel="minMTime" longName="newer-mtime" /> - --> </optionSet> - <repeat minCount="0"> - <argument argLabel="paths"/> + <repeat> + <argument argLabel="files" /> </repeat> </sequence> </syntax> - <syntax alias="gzip"> - <empty description="compress standard input to standard output" /> + <syntax alias="bzcat"> + <empty description="decompress stdin to stdout" /> + <sequence description="decompress files to stdout"> + <optionSet> + <option argLabel="small" shortName="s" longName="small" /> + </optionSet> + <repeat> + <argument argLabel="files" /> + </repeat> + </sequence> + </syntax> + <syntax alias="bzip2"> + <empty description="compress stdin to stdout" /> <sequence description="compress files"> <optionSet> - <!-- GZipCommand --> + <!-- BZipCommand --> <option argLabel="c1" shortName="1" longName="fast" /> + <option argLabel="c2" shortName="2" /> + <option argLabel="c3" shortName="3" /> + <option argLabel="c4" shortName="4" /> + <option argLabel="c5" shortName="5" /> + <option argLabel="c6" shortName="6" /> + <option argLabel="c7" shortName="7" /> + <option argLabel="c8" shortName="8" /> <option argLabel="c9" shortName="9" longName="best" /> + <!-- BZip --> <option argLabel="decompress" shortName="d" longName="decompress" /> - <!-- GZip --> + <option argLabel="compress" shortName="z" longName="compress" /> <option argLabel="test" shortName="t" longName="test" /> - <option argLabel="list" shortName="l" longName="list" /> - <option argLabel="recurse" shortName="r" longName="recursive" /> - <option argLabel="noname" shortName="n" longName="no-name" /> - <option argLabel="name" shortName="N" longName="name" /> + <option argLabel="keep" shortName="k" longName="keep" /> + <option argLabel="small" shortName="s" longName="small" /> <!-- ArchiveCommand --> <option argLabel="stdout" shortName="c" longName="stdout" /> <option argLabel="force" shortName="f" longName="force" /> + <option argLabel="verbose" shortName="v" longName="verbose" /> <option argLabel="quiet" shortName="q" longName="quiet" /> - <option argLabel="verbose" shortName="v" longName="verbose" /> <option argLabel="debug" longName="debug" /> </optionSet> - <optional eager="true"><option argLabel="suffix" shortName="S" longName="suffix" /></optional> - <repeat minCount="1"> + <repeat> <argument argLabel="files" /> </repeat> </sequence> @@ -128,81 +119,156 @@ </repeat> </sequence> </syntax> - <syntax alias="zcat"> - <empty description="decompress standard input to standard output" /> - <repeat minCount="1"> - <argument argLabel="files" /> - </repeat> - </syntax> - <syntax alias="zip"> - </syntax> - <syntax alias="unzip"> - </syntax> - <syntax alias="bzip2"> - <empty description="compress stdin to stdout" /> + <syntax alias="gzip"> + <empty description="compress standard input to standard output" /> <sequence description="compress files"> <optionSet> - <!-- BZipCommand --> + <!-- GZipCommand --> <option argLabel="c1" shortName="1" longName="fast" /> - <option argLabel="c2" shortName="2" /> - <option argLabel="c3" shortName="3" /> - <option argLabel="c4" shortName="4" /> - <option argLabel="c5" shortName="5" /> - <option argLabel="c6" shortName="6" /> - <option argLabel="c7" shortName="7" /> - <option argLabel="c8" shortName="8" /> <option argLabel="c9" shortName="9" longName="best" /> - <!-- BZip --> <option argLabel="decompress" shortName="d" longName="decompress" /> - <option argLabel="compress" shortName="z" longName="compress" /> + <!-- GZip --> <option argLabel="test" shortName="t" longName="test" /> - <option argLabel="keep" shortName="k" longName="keep" /> - <option argLabel="small" shortName="s" longName="small" /> + <option argLabel="list" shortName="l" longName="list" /> + <option argLabel="recurse" shortName="r" longName="recursive" /> + <option argLabel="noname" shortName="n" longName="no-name" /> + <option argLabel="name" shortName="N" longName="name" /> <!-- ArchiveCommand --> <option argLabel="stdout" shortName="c" longName="stdout" /> <option argLabel="force" shortName="f" longName="force" /> + <option argLabel="quiet" shortName="q" longName="quiet" /> <option argLabel="verbose" shortName="v" longName="verbose" /> - <option argLabel="quiet" shortName="q" longName="quiet" /> <option argLabel="debug" longName="debug" /> </optionSet> - <repeat> + <optional eager="true"><option argLabel="suffix" shortName="S" longName="suffix" /></optional> + <repeat minCount="1"> <argument argLabel="files" /> </repeat> </sequence> </syntax> - <syntax alias="bunzip2"> - <empty description="decompress stdin to stdout" /> - <sequence description="decompress files"> - <optionSet> - <!-- BZip --> - <option argLabel="compress" shortName="z" longName="compress"/> - <option argLabel="decompress" shortName="d" longName="decompress"/> - <option argLabel="test" shortName="t" longName="test" /> - <option argLabel="keep" shortName="k" longName="keep" /> - <option argLabel="small" shortName="s" longName="small" /> + <syntax alias="tar"> + <sequence> + <optionSet description="tar options"> + <!-- Tar Operations --> + <option argLabel="doAppend" shortName="r" longName="append" /> + <option argLabel="doCreate" shortName="c" longName="create" /> + <option argLabel="doConcat" shortName="A" longName="concatenate" /> + <option argLabel="doDelete" longName="delete" /> + <option argLabel="doDiff" shortName="d" longName="diff" /> + <option argLabel="doExtract" shortName="x" longName="extract" /> + <option argLabel="doList" shortName="t" longName="list" /> + <option argLabel="doUpdate" shortName="u" longName="update" /> + <!-- Tar Global Options --> + <option argLabel="archive" shortName="f" longName="file" /> + <option argLabel="backup" longName="backup" /> + <option argLabel="bzip" shortName="j" longName="bzip2" /> + <option argLabel="fileList" shortName="T" longName="files-from"/> + <option argLabel="gzip" shortName="z" longName="gzip" /> + <option argLabel="interact" shortName="w" longName="interactive" /> + <option argLabel="keep_old" shortName="k" longName="keep-old-files" /> + <option argLabel="keep_new" longName="keep-newer-files" /> + <option argLabel="removeFiles" longName="remove-files" /> + <option argLabel="showTotals" longName="totals" /> + <option argLabel="suffix" longName="suffix" /> + <option argLabel="unlink" longName="unlink" /> + <option argLabel="verify" shortName="W" longName="verify" /> + <option argLabel="xfile" shortName="X" longName="exclude-from"/> + <!-- Tar Path Parser Options --> + <option argLabel="exclude" longName="exclude" label="pattern" /> + <option argLabel="noRecurse" longName="no-recursion" /> + <option argLabel="recurse" longName="recursion" /> + <option argLabel="dir" shortName="C" longName="directory" /> <!-- ArchiveCommand --> - <option argLabel="stdout" shortName="c" longName="stdout" /> - <option argLabel="force" shortName="f" longName="force" /> <option argLabel="verbose" shortName="v" longName="verbose" /> - <option argLabel="quiet" shortName="q" longName="quiet" /> <option argLabel="debug" longName="debug" /> + <option argLabel="stdout" shortName="O" longName="to-stdout" /> + <!-- + <option argLabel="minDate" shortName="N" longName="newer" /> + <option argLabel="minMTime" longName="newer-mtime" /> + --> </optionSet> <repeat> - <argument argLabel="files" /> + <argument argLabel="paths"/> </repeat> </sequence> </syntax> - <syntax alias="bzcat"> - <empty description="decompress stdin to stdout" /> - <sequence description="decompress files to stdout"> + <syntax alias="unzip"> + <sequence> <optionSet> - <option argLabel="small" shortName="s" longName="small" /> + <!-- UnzipCommand --> + <option argLabel="backup" shortName="B"/> + <option argLabel="ignore-case" shortName="C"/> + <option argLabel="keep" shortName="n"/> + <option argLabel="overwrite" shortName="o"/> + <!-- Zip --> + <option argLabel="no-path" shortName="j"/> + <!-- Zip Operations --> + <option argLabel="freshen" shortName="f"/> + <option argLabel="list" shortName="l"/> + <option argLabel="test" shortName="t"/> + <option argLabel="update" shortName="u"/> + <!-- ArchiveCommand --> + <option argLabel="stdout" shortName="p"/> + <option argLabel="verbose" shortName="v"/> + <option argLabel="quiet" shortName="q"/> + <option argLabel="debug" longName="debug"/> </optionSet> + <argument argLabel="archive"/> <repeat> - <argument argLabel="files" /> + <argument argLabel="patterns"/> </repeat> + <!-- TODO + <repeat> + <option argLabel="exclude" shortName="x"/> + </repeat> + <optional> + <option argLabel="extract-dir" shortName="d"/> + </optional> + --> </sequence> </syntax> + <syntax alias="zcat"> + <empty description="decompress standard input to standard output" /> + <repeat minCount="1"> + <argument argLabel="files" /> + </repeat> + </syntax> + <syntax alias="zip"> + <sequence> + <optionSet> + <!-- ZipCommand --> + <option argLabel="files-stdin" shortName="@"/> + <option argLabel="tmp-dir" shortName="b"/> + <option argLabel="no-dirs" shortName="D"/> + <option argLabel="no-compress" shortName="n"/> + <option argLabel="recurse" shortName="r"/> + <!--<option argLabel="recurse-cd" shortName="R"/>--> + <option argLabel="newer" shortName="t"/> + <!--<option argLabel="older" shortName="tt"/>--> + <!-- Zip --> + <option argLabel="no-path" shortName="j"/> + <!-- Zip Operations --> + <option argLabel="delete" shortName="d"/> + <option argLabel="freshen" shortName="f"/> + <option argLabel="move" shortName="m"/> + <option argLabel="update" shortName="u"/> + <!-- ArchiveCommand --> + <option argLabel="quiet" shortName="q"/> + <option argLabel="verbose" shortName="v"/> + <option argLabel="debug" longName="debug"/> + </optionSet> + <argument argLabel="archive"/> + <repeat> + <argument argLabel="patterns"/> + </repeat> + <!-- TODO + <repeat> + <option argLabel="include" shortName="i"/> + <option argLabel="exclude" shortName="x"/> + </repeat> + --> + </sequence> + </syntax> </extension> <extension point="org.jnode.security.permissions"> Copied: trunk/fs/src/fs/org/jnode/fs/command/archive/BZCatCommand.java (from rev 5283, trunk/fs/src/fs/org/jnode/fs/command/archive/UnzipCommand.java) =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/BZCatCommand.java (rev 0) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/BZCatCommand.java 2009-04-15 14:41:53 UTC (rev 5284) @@ -0,0 +1,33 @@ +/* + * $Id$ + * + * Copyright (C) 2003-2009 JNode.org + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; If not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +package org.jnode.fs.command.archive; + +public class BZCatCommand extends BZip { + + public BZCatCommand() { + super("extract files to stdout"); + // from BZip + registerArguments(Files, Small); + } + + public void execute() { + super.execute("bzcat"); + } +} Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/UnzipCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/UnzipCommand.java 2009-04-15 14:41:09 UTC (rev 5283) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/UnzipCommand.java 2009-04-15 14:41:53 UTC (rev 5284) @@ -20,17 +20,45 @@ package org.jnode.fs.command.archive; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FlagArgument; + /** * @author chris boertien */ public class UnzipCommand extends Zip { + private static final String help_ignore_case = "Use case-insensitive matching for include/exclude"; + private static final String help_backup = "Backup existing files when extracting, appending a ~ to the name"; + private static final String help_keep = "Skip extracting entries if the file exists"; + private static final String help_overwrite = "Overwrite existing files if they exist"; + + private final FlagArgument IgnoreCase; + private final FlagArgument Backup; + private final FlagArgument Keep; + private final FlagArgument Overwrite; + public UnzipCommand() { super("extracts entries from zip archives"); - //registerArguments(ZipfileArg,PatternsArg); + // from ArchiveCommand + registerArguments(Verbose, Quiet, Debug, Stdout); + // from Zip + registerArguments(Archive, Patterns, NoPath, Freshen, List, Test, Update); + + IgnoreCase = new FlagArgument("ignore-case", Argument.OPTIONAL, help_ignore_case); + Backup = new FlagArgument("backup", Argument.OPTIONAL, help_backup); + Keep = new FlagArgument("keep", Argument.OPTIONAL, help_keep); + Overwrite = new FlagArgument("overwrite", Argument.OPTIONAL, help_overwrite); + registerArguments(IgnoreCase, Backup, Keep, Overwrite); } + @Override public void execute() { + ignore_case = IgnoreCase.isSet(); + backup = Backup.isSet(); + keep = Keep.isSet(); + overwrite = Overwrite.isSet(); + super.execute("unzip"); } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java 2009-04-15 14:41:09 UTC (rev 5283) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java 2009-04-15 14:41:53 UTC (rev 5284) @@ -20,42 +20,468 @@ package org.jnode.fs.command.archive; +import org.jnode.shell.PathnamePattern; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FlagArgument; +import org.jnode.shell.syntax.FileArgument; +import org.jnode.shell.syntax.StringArgument; + import java.io.File; -//import java.io.FileInputStream; -//import java.io.FileOutputStream; -//import java.io.InputStream; -//import java.io.OutputStream; -//import java.io.Reader; -//import java.io.PrintWriter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.PrintWriter; import java.io.IOException; -//import java.util.Enumeration; -//import java.util.zip.ZipFile; -//import java.util.zip.ZipEntry; -//import java.util.zip.ZipOutputStream; -//import java.util.zip.ZipException; +import java.util.Enumeration; +import java.util.List; +import java.util.ArrayList; + +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import org.apache.tools.zip.AsiExtraField; +import org.apache.tools.zip.ZipExtraField; +import org.apache.tools.zip.ZipFile; +import org.apache.tools.zip.ZipEntry; +import org.apache.tools.zip.ZipOutputStream; + +/** + * @author chris boeriten + */ public class Zip extends ArchiveCommand { - private static final int ZIP_DELETE = 1; - private static final int ZIP_REFRESH = 2; - private static final int ZIP_MOVE = 3; - private static final int ZIP_ADD = 4; - private static final int ZIP_UPDATE = 5; - private static final int ZIP_EXTRACT = 6; + private static final String help_delete = "remove the list of entries from the archive"; + private static final String help_freshen = "[zip] Replaces entries in the archive with files from the file " + + "system if they exist and are newer than the entry.\n[unzip] Replaces " + + "files on the file system with entries from the archive if they exist " + + "and are newer than the file."; + private static final String help_update = "Like freshen, except it will also add files if they do not exist"; + private static final String help_test = "[zip] Tests the archive before finishing. If the archive is corrupt " + + "then the original archive is restored, if any. This will also skip " + + "deleting files in a move operation.\n[unzip] Tests the archive, " + + "reporting wether the archive is corrupt or not."; + private static final String help_move = "add the list of files to the archive, removing them from the file system"; + private static final String help_list = "list the contents of the archive"; + private static final String help_no_path = "store/extract the file with only its file name and no path prefix"; + private static final String help_archive = "the zip archive to use"; + private static final String help_patterns = "file matching patterns(wildcards)"; + protected final StringArgument Patterns; + protected final FileArgument Archive; + protected final FlagArgument Delete; + protected final FlagArgument Freshen; + protected final FlagArgument Update; + protected final FlagArgument Test; + protected final FlagArgument Move; + protected final FlagArgument List; + protected final FlagArgument NoPath; + + private static final int ZIP_ADD = 0x01; + private static final int ZIP_MOVE = 0x02; + private static final int ZIP_EXTRACT = 0x04; + private static final int ZIP_DELETE = 0x08; + private static final int ZIP_LIST = 0x10; + private static final int ZIP_TEST = 0x20; + private static final int ZIP_FRESHEN = 0x40; + private static final int ZIP_UPDATE = 0x80; + private static final int ZIP_ALL = 0x3F; + private static final int ZIP_INSERT = ZIP_ADD | ZIP_MOVE; + private static final int ZIP_REQ_ARCH = ZIP_ALL & ~ZIP_INSERT; + + private List<Pattern> patterns; + private List<Pattern> includes; + private List<Pattern> excludes; + private List<File> files; + private List<ZipEntry> fileEntries; + private List<ZipEntry> dirEntries; + + protected long newer; + protected long older; private File archive; + private ZipFile zarchive; + protected File tmpDir; + protected String noCompress; + protected int mode; + protected boolean ignore_case; + protected boolean keep; + protected boolean overwrite; + protected boolean backup; + protected boolean noDirEntry; + protected boolean recurse; + protected boolean filesStdin; + protected boolean useStdout; - private int mode; - public Zip(String s) { super(s); + Delete = new FlagArgument("delete", Argument.OPTIONAL, help_delete); + Freshen = new FlagArgument("freshen", Argument.OPTIONAL, help_freshen); + Update = new FlagArgument("update", Argument.OPTIONAL, help_update); + Test = new FlagArgument("test", Argument.OPTIONAL, help_test); + Move = new FlagArgument("move", Argument.OPTIONAL, help_move); + List = new FlagArgument("list", Argument.OPTIONAL, help_list); + NoPath = new FlagArgument("no-path", Argument.OPTIONAL, help_no_path); + Patterns = new StringArgument("patterns", Argument.OPTIONAL | Argument.MULTIPLE, help_patterns); + Archive = new FileArgument("archive", Argument.MANDATORY, help_archive); } public void execute(String command) { - super.execute(command); + super.execute("zcat"); + parseOptions(command); + + try { + if (mode == ZIP_ADD) { + insert(); + return; + } + + if (mode == ZIP_EXTRACT) { + extract(); + return; + } + + if (mode == ZIP_LIST) { + list(); + return; + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (zarchive != null) { + try { + zarchive.close(); + } catch (IOException _) { + // ignore + } + } + exit(0); + } } - void extract() throws IOException { + private void insert() throws IOException { + ZipOutputStream zout = null; + ZipEntry entry; + InputStream in; + try { + zout = new ZipOutputStream(new FileOutputStream(archive)); + for (File file : files) { + in = null; + try { + entry = createEntry(file); + if (!file.isDirectory()) { + if ((in = openFileRead(file)) == null) { + continue; + } + zout.putNextEntry(entry); + processStream(in, zout); + } else { + zout.putNextEntry(entry); + } + zout.closeEntry(); + } catch (IOException e) { + debug(e.getMessage()); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + // ignore + } + } + } + } + } finally { + if (zout != null) { + try { + zout.finish(); + } catch (IOException e) { + // + } + } + } } + + private void list() throws IOException { + Enumeration<ZipEntry> entries; + ZipEntry entry; + int size = 0; + int csize = 0; + int count = 0; + + printListHeader(); + entries = zarchive.getEntries(); + while (entries.hasMoreElements()) { + entry = entries.nextElement(); + //debug(entry); + printListEntry(entry); + count++; + size += entry.getSize(); + csize += entry.getCompressedSize(); + } + printListFooter(size, csize, count); + } + + private void extract() throws IOException { + InputStream in = null; + OutputStream out = null; + File file; + + out("Archive: " + archive.getName()); + for (ZipEntry entry : dirEntries) { + out(String.format("%11s: %s", "creating", entry.getName())); + file = new File(entry.getName()); + file.mkdirs(); + } + + for (ZipEntry entry : fileEntries) { + out(String.format("%11s: %s", "inflating", entry.getName())); + file = new File(entry.getName()); + try { + file.createNewFile(); + in = zarchive.getInputStream(entry); + out = new FileOutputStream(file); + processStream(in, out); + } catch (IOException e) { + debug(e.getMessage()); + } finally { + if (in != null) { + try { + in.close(); + in = null; + } catch (IOException _) { + // ignore; + } + } + if (out != null) { + try { + out.close(); + out = null; + } catch (IOException _) { + // ignore; + } + } + } + } + } + + private ZipEntry createEntry(File file) { + String name = file.getPath(); + ZipEntry entry; + if (file.isDirectory()) { + if (!name.endsWith(File.separator)) { + name = name + File.separator; + } + entry = new ZipEntry(name); + entry.setMethod(ZipEntry.STORED); + entry.setCrc(0); + entry.setSize(0); + } else { + entry = new ZipEntry(name); + entry.setMethod(ZipEntry.DEFLATED); + } + return entry; + } + + private void printListHeader() { + out(" Size CSize Date Time Name"); + out(" -------- -------- -------- ----- ----"); + } + + private void printListEntry(ZipEntry entry) { + out(String.format(" %8d %8d %s", entry.getSize(), entry.getCompressedSize(), entry.getName())); + } + + private void printListFooter(int size, int csize, int numFiles) { + out(" -------- -------- -------"); + out(String.format(" %8d %8d %d files", size, csize, numFiles)); + } + + private void printName(String s) { + if (outMode != 0) { + out(s); + } + } + + private void parseOptions(String command) { + outMode |= OUT_DEBUG; + if (command.equals("zip")) { + if (Delete.isSet()) { + mode = ZIP_DELETE; + } else if (Freshen.isSet()) { + mode = ZIP_FRESHEN | ZIP_ADD; + } else if (Update.isSet()) { + mode = ZIP_UPDATE | ZIP_ADD; + } else if (Move.isSet()) { + mode = ZIP_MOVE; + } else { + mode = ZIP_ADD; + } + } else if (command.equals("unzip")) { + if (Freshen.isSet()) { + mode = ZIP_FRESHEN | ZIP_EXTRACT; + } else if (Update.isSet()) { + mode = ZIP_UPDATE | ZIP_EXTRACT; + } else if (List.isSet()) { + mode = ZIP_LIST; + } else if (Test.isSet()) { + mode = ZIP_TEST; + } else { + mode = ZIP_EXTRACT; + } + } + assert mode != 0 : "Invalid mode"; + + switch (mode) { + case ZIP_ADD : + parseFiles(); + getArchive(true, false); + break; + case ZIP_EXTRACT : + getArchive(false, true); + parseEntries(); + break; + case ZIP_LIST : + getArchive(false, true); + break; + default : + throw new UnsupportedOperationException("This mode is not implemented."); + } + } + + private void getArchive(boolean create, boolean zipfile) { + archive = Archive.getValue(); + + if (archive.getName().equals("-")) { + // pipe to stdout + } + + if (!archive.exists()) { + if (create) { + try { + archive.createNewFile(); + } catch (IOException e) { + fatal("Could not create archive: " + archive, 1); + } + } else { + fatal("Archive required but not found: " + archive, 1); + } + } else { + if (create) { + fatal("Archive exists, refused to overwrite: " + archive, 1); + } + } + + if (zipfile) { + try { + zarchive = new ZipFile(archive); + } catch (IOException e) { + debug(e.getMessage()); + fatal("Unable to open archive as ZipFile: " + archive, 1); + } + assert zarchive != null : "null zarchive"; + } + + assert archive != null : "null archive after getArchive()"; + assert archive.exists() : "archive does not exist, or was not created"; + } + + private void parseFiles() { + files = new ArrayList<File>(); + + if (Patterns.isSet()) { + for (String pattern : Patterns.getValues()) { + if (!PathnamePattern.isPattern(pattern)) { + File file = new File(pattern); + if (!file.exists()) { + debug("File or Directory does not exist: " + file); + continue; + } + if (file.isDirectory()) { + addDirectory(file); + } else { + addFile(file); + } + } else { + PathnamePattern pat = PathnamePattern.compilePathPattern(pattern); + List<String> list = pat.expand(new File(".")); + for (String name : list) { + File file = new File(name); + if (file.isDirectory()) { + addDirectory(file); + } else { + addFile(file); + } + } + } + } + } + } + + private void parseEntries() { + assert zarchive != null : "null archive in parseEntries"; + int count = 0; + + ZipEntry entry; + Enumeration<ZipEntry> entries = zarchive.getEntries(); + fileEntries = new ArrayList<ZipEntry>(); + dirEntries = new ArrayList<ZipEntry>(); + + while (entries.hasMoreElements()) { + count++; + entry = entries.nextElement(); + if (entry.isDirectory()) { + dirEntries.add(entry); + } else { + fileEntries.add(entry); + } + } + + assert count == (fileEntries.size() + dirEntries.size()); + } + + private void addDirectory(File dir) { + if (!recurse) { + return; + } + files.add(dir); + + for (File file : dir.listFiles()) { + if (file.isDirectory()) { + addDirectory(file); + } else { + + addFile(file); + } + } + } + + private void addFile(File file) { + files.add(file); + } + + private void debug(ZipEntry entry) { + debug("Name: " + entry.getName()); + debug("Directory: " + entry.isDirectory()); + debug("Platform: " + entry.getPlatform()); + debug("Mode: " + entry.getUnixMode()); + debug("IAttr: " + entry.getInternalAttributes()); + debug("EAttr: " + entry.getExternalAttributes()); + debug("CSize: " + entry.getCompressedSize()); + debug("Size: " + entry.getSize()); + debug("MTime: " + entry.getTime()); + debug("Method: " + entry.getMethod()); + debug("CRC: " + entry.getCrc()); + debug("Comment: " + entry.getComment()); + ZipExtraField[] extra = entry.getExtraFields(); + if (extra != null && extra.length > 0) { + debug("--Extra--"); + for (ZipExtraField field : extra) { + debug("CDL: " + field.getCentralDirectoryLength().getValue() + " FDL: " + + field.getLocalFileDataLength().getValue()); + } + } + } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java 2009-04-15 14:41:09 UTC (rev 5283) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java 2009-04-15 14:41:53 UTC (rev 5284) @@ -20,32 +20,57 @@ package org.jnode.fs.command.archive; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FlagArgument; +import org.jnode.shell.syntax.FileArgument; +import org.jnode.shell.syntax.StringArgument; + /** * @author chris boertien */ public class ZipCommand extends Zip { -/* - private static final String help_refresh = "freshen: only changed files"; - private static final String help_delete = "delete entries in zip file"; - private static final String help_move = "move into zipfile (delete files)"; - private static final String help_recurse = "recurse into directories"; - private static final String help_zfile = "zip file to oeprate on"; - private static final String help_patterns = "search patterns"; + + private static final String help_files_stdin = "Read files from stdin"; + private static final String help_tmpdir = "Use this directory for storing the tmp archive"; + private static final String help_no_dir = "Do not add entries for directories"; + private static final String help_no_compress = "Comma delimited list of suffixes that should be stored"; + private static final String help_recurse = "recurse into directories"; + private static final String help_newer_than = "only include files newer than the specified time"; + private static final String help_older_than = "only include files older than the specified time"; - private final FileArgument ArgZipfile = new FileArgument("zipFile" , Argument.OPTIONAL , help_zfile); - private final StringArgument ArgPatterns - = new StringArgument("patterns" , Argument.OPTIONAL | Argument.MULTIPLE , help_patterns); - private final FlagArgument ArgDelete = new FlagArgument("doDelete" , Argument.OPTIONAL , help_delete); - private final FlagArgument ArgRefresh = new FlagArgument("doRefresh" , Argument.OPTIONAL , help_refresh); - private final FlagArgument ArgMove = new FlagArgument("doMove" , Argument.OPTIONAL , help_move); - private final FlagArgument ArgRecurse = new FlagArgument("recurse" , Argument.OPTIONAL , help_recurse); - */ + private final FlagArgument FilesStdin; + private final FlagArgument NoDirEntry; + private final FlagArgument Recurse; + private final FileArgument TmpDir; + private final StringArgument NoCompress; + private final StringArgument NewerThan; + private final StringArgument OlderThan; + public ZipCommand() { super("compress files into a zip archive"); - //registerArguments(ArgZipfile, ArgPatterns, ArgDelete, ArgRefresh, ArgMove, ArgRecurse); + // from ArchiveCommand + registerArguments(Verbose, Quiet, Debug); + // from Zip + registerArguments(Archive, Patterns, NoPath, Delete, Freshen, Move, Update); + + FilesStdin = new FlagArgument("files-stdin", Argument.OPTIONAL, help_files_stdin); + NoDirEntry = new FlagArgument("no-dirs", Argument.OPTIONAL, help_no_dir); + Recurse = new FlagArgument("recurse", Argument.OPTIONAL, help_recurse); + TmpDir = new FileArgument("tmp-dir", Argument.OPTIONAL, help_tmpdir); + NoCompress = new StringArgument("no-compress", Argument.OPTIONAL, help_no_compress); + NewerThan = new StringArgument("newer", Argument.OPTIONAL, help_newer_than); + OlderThan = new StringArgument("older", Argument.OPTIONAL, help_older_than); + registerArguments(FilesStdin, TmpDir, NoDirEntry, NoCompress, Recurse, NewerThan, OlderThan); } + @Override public void execute() { + recurse = Recurse.isSet(); + noDirEntry = NoDirEntry.isSet(); + filesStdin = FilesStdin.isSet(); + if (NoCompress.isSet()) noCompress = NoCompress.getValue(); + if (TmpDir.isSet()) tmpDir = TmpDir.getValue(); + super.execute("zip"); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |