From: <ls...@us...> - 2008-10-28 09:13:08
|
Revision: 4657 http://jnode.svn.sourceforge.net/jnode/?rev=4657&view=rev Author: lsantha Date: 2008-10-28 09:10:23 +0000 (Tue, 28 Oct 2008) Log Message: ----------- Integrated the md5sum command contributed by Tim Sparg. Modified Paths: -------------- trunk/fs/descriptors/org.jnode.fs.command.xml Added Paths: ----------- trunk/fs/src/fs/org/jnode/fs/command/Md5SumCommand.java Modified: trunk/fs/descriptors/org.jnode.fs.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.command.xml 2008-10-26 21:54:35 UTC (rev 4656) +++ trunk/fs/descriptors/org.jnode.fs.command.xml 2008-10-28 09:10:23 UTC (rev 4657) @@ -33,6 +33,7 @@ <alias name="pwd" class="org.jnode.fs.command.PwdCommand"/> <alias name="touch" class="org.jnode.fs.command.TouchCommand"/> <alias name="hexdump" class="org.jnode.fs.command.HexdumpCommand"/> + <alias name="md5sum" class="org.jnode.fs.command.Md5SumCommand"/> </extension> <extension point="org.jnode.shell.syntaxes"> @@ -110,6 +111,18 @@ <syntax alias="touch"> <argument argLabel="file" description="touch the given file"/> </syntax> + <syntax alias="md5sum"> + <sequence description="Cecks md5 sums agains a file"> + <option argLabel="check" shortName="c" longName="check"/> + <argument argLabel="checkfile" description="md5sum file to check against"/> + </sequence> + <sequence description="Calculates the md5sum for files or folders of files"> + <optionSet> + <option argLabel="recursive" shortName="r" longName="recursive"/> + </optionSet> + <repeat minCount="1"><argument argLabel="paths"/></repeat> + </sequence> + </syntax> </extension> Added: trunk/fs/src/fs/org/jnode/fs/command/Md5SumCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/Md5SumCommand.java (rev 0) +++ trunk/fs/src/fs/org/jnode/fs/command/Md5SumCommand.java 2008-10-28 09:10:23 UTC (rev 4657) @@ -0,0 +1,233 @@ +package org.jnode.fs.command; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import org.jnode.shell.AbstractCommand; +import org.jnode.shell.CommandLine; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FileArgument; +import org.jnode.shell.syntax.FlagArgument; + +public class Md5SumCommand extends AbstractCommand { + + private final FileArgument ARG_PATHS = new FileArgument( + "paths", Argument.OPTIONAL | Argument.MULTIPLE, + "the files or directories to be md5summed"); + private final FlagArgument FLAG_RECURSIVE = new FlagArgument( + "recursive", Argument.OPTIONAL, + "if set, will recursively go through all folders, md5summing all files"); + private final FlagArgument ARG_CHECK = new FlagArgument( + "check", Argument.OPTIONAL, + "if set, will check all md5sums against a file "); + private final FileArgument ARG_CHECKFILE = new FileArgument( + "checkfile", Argument.OPTIONAL | Argument.SINGLE, + "the md5sum file to check against "); + + + private static final int MEGABYTE = 1048576; + static final byte[] HEX_CHAR_TABLE = { + (byte) '0', (byte) '1', (byte) '2', (byte) '3', + (byte) '4', (byte) '5', (byte) '6', (byte) '7', + (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', + (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' + }; + + private boolean recursive; + private File[] paths; + private PrintStream err; + private MessageDigest msgDigest; + private PrintStream out; + private File checkFile; + private String hexOutputString; + + public Md5SumCommand() { + super("Calculate a md5sum against a file or Folder of Files"); + registerArguments(ARG_PATHS, FLAG_RECURSIVE, ARG_CHECK, ARG_CHECKFILE); + } + + + public void execute(CommandLine commandLine, InputStream in, + PrintStream out, PrintStream err) throws Exception { + + recursive = FLAG_RECURSIVE.isSet(); + paths = ARG_PATHS.getValues(); + checkFile = ARG_CHECKFILE.getValue(); + + this.err = err; + this.out = out; + + if (ARG_CHECK.isSet()) { + calculatemd5sumAgainstFile(); + } else { + boolean ok = true; + for (File file : paths) { + ok &= calculatemd5sum(file); + } + } + + + } + + private void calculatemd5sumAgainstFile() { + boolean md5Ok = true; + if (!checkFile.exists()) { + err.println(checkFile); + md5Ok = false; + } + + BufferedReader reader = null; + if (md5Ok) { + try { + reader = new BufferedReader(new FileReader(checkFile)); + } catch (FileNotFoundException e) { + //have just checked against this, so this shouldnt occour + } + } + + if (md5Ok) { + String readLine; + try { + int failCount = 0; + while ((readLine = reader.readLine()) != null) { + boolean passed = true; + String[] line = readLine.split("[ ]+"); + if (calculatemd5sum(new File(line[1].trim()))) { + if (!hexOutputString.equals(line[0].trim())) { + passed = false; + } + } else { + passed = false; + } + + if (passed) { + out.println(line[1] + " : OK"); + } else { + out.println(line[1] + " : FAILED"); + failCount++; + } + } + if (failCount > 0) { + out.println(failCount + " file(s) failed"); + } + } catch (IOException e) { + out.println("md5sum could not be checked against " + checkFile); + } + } + } + + + private boolean calculatemd5sum(File file) { + if (!file.exists()) { + err.println(file + " does not exist"); + return false; + } + boolean md5sumOk = true; + + if (file.isDirectory()) { + if (recursive) { + for (File f : file.listFiles()) { + final String name = f.getName(); + if (!name.equals(".") && !name.equals("..")) { + md5sumOk &= calculatemd5sum(f); + } + } + } else { + err.println("Cannot calculate md5sum on folder: " + file); + md5sumOk = false; + } + } else { + if (md5sumOk) { + if (msgDigest == null) { + try { + msgDigest = MessageDigest.getInstance("md5"); + } catch (NoSuchAlgorithmException e) { + err.println("md5sum algorithm Could not be found"); + md5sumOk = false; + } + } else { + msgDigest.reset(); + } + } + + BufferedInputStream bis = null; + byte[] buffer = null; + int maxBytesToRead = 0; + long fileSize = file.length(); + if (md5sumOk) { + if (fileSize >= MEGABYTE) { + maxBytesToRead = MEGABYTE; + buffer = new byte[maxBytesToRead]; + } else { + maxBytesToRead = (int) fileSize; + buffer = new byte[maxBytesToRead]; + } + try { + bis = new BufferedInputStream(new FileInputStream(file)); + } catch (FileNotFoundException e) { + md5sumOk = false; + } + + } + + + if (md5sumOk) { + int bytesRead = 0; + try { + bytesRead = bis.read(buffer, 0, maxBytesToRead); + do { + msgDigest.update(buffer); + bytesRead = bis.read(buffer, 0, maxBytesToRead); + } while (bytesRead > 0); + bis.close(); + hexOutputString = convertOutputToHexString(msgDigest.digest()); + } catch (IOException e) { + md5sumOk = false; + } + + } + + if (md5sumOk) { + out.println(hexOutputString + " " + file); + } else { + err.println(file + " was not md5summed"); + } + + } + + return md5sumOk; + } + + + private String convertOutputToHexString(byte[] bs) throws UnsupportedEncodingException { + byte[] hex = new byte[2 * bs.length]; + int index = 0; + + for (byte b : bs) { + int v = b & 0xFF; + hex[index++] = HEX_CHAR_TABLE[v >>> 4]; + hex[index++] = HEX_CHAR_TABLE[v & 0xF]; + } + + return new String(hex, "ASCII"); + } + + + /** + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + new Md5SumCommand().execute(args); + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cr...@us...> - 2008-11-03 14:22:34
|
Revision: 4665 http://jnode.svn.sourceforge.net/jnode/?rev=4665&view=rev Author: crawley Date: 2008-11-03 14:22:31 +0000 (Mon, 03 Nov 2008) Log Message: ----------- Fixed the syntax and argument parsing for 'md5sum' to work as intended. Added support for md5summing the input stream. Improved documentation strings, and generally tidied up the code. Modified Paths: -------------- trunk/fs/descriptors/org.jnode.fs.command.xml trunk/fs/src/fs/org/jnode/fs/command/Md5SumCommand.java Modified: trunk/fs/descriptors/org.jnode.fs.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.command.xml 2008-11-03 14:05:07 UTC (rev 4664) +++ trunk/fs/descriptors/org.jnode.fs.command.xml 2008-11-03 14:22:31 UTC (rev 4665) @@ -94,6 +94,17 @@ <empty description="list the current directory"/> <repeat><argument argLabel="path" description="list files or directories"/></repeat> </syntax> + <syntax alias="md5sum"> + <option description="Checks MD5 digests recorded in a file" + argLabel="checkfile" shortName="c" longName="check"/> + <sequence description="Calculates the MD5 digests for files"> + <optional eager="true"> + <option argLabel="recursive" shortName="r" longName="recursive"/> + </optional> + <repeat minCount="1"><argument argLabel="paths"/></repeat> + </sequence> + <empty description="Calculates the MD5 digest for standard input"/> + </syntax> <syntax alias="mkdir"> <argument argLabel="directory" description="create a new directory"/> </syntax> @@ -111,21 +122,8 @@ <syntax alias="touch"> <argument argLabel="file" description="touch the given file"/> </syntax> - <syntax alias="md5sum"> - <sequence description="Cecks md5 sums agains a file"> - <option argLabel="check" shortName="c" longName="check"/> - <argument argLabel="checkfile" description="md5sum file to check against"/> - </sequence> - <sequence description="Calculates the md5sum for files or folders of files"> - <optionSet> - <option argLabel="recursive" shortName="r" longName="recursive"/> - </optionSet> - <repeat minCount="1"><argument argLabel="paths"/></repeat> - </sequence> - </syntax> </extension> - <extension point="org.jnode.security.permissions"> <permission class="java.io.FilePermission" name="<<ALL FILES>>" actions="read,write,delete"/> <permission class="java.net.SocketPermission" name="*:0-" actions="connect,resolve"/> Modified: trunk/fs/src/fs/org/jnode/fs/command/Md5SumCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/Md5SumCommand.java 2008-11-03 14:05:07 UTC (rev 4664) +++ trunk/fs/src/fs/org/jnode/fs/command/Md5SumCommand.java 2008-11-03 14:22:31 UTC (rev 4665) @@ -1,6 +1,25 @@ +/* + * $Id: FormatCommand.java 3585 2007-11-13 13:31:18Z galatnm $ + * + * JNode.org + * Copyright (C) 2003-2006 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; -import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; @@ -8,221 +27,233 @@ import java.io.FileReader; import java.io.IOException; import java.io.InputStream; -import java.io.PrintStream; -import java.io.UnsupportedEncodingException; +import java.io.PrintWriter; import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; + import org.jnode.shell.AbstractCommand; -import org.jnode.shell.CommandLine; import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.FileArgument; import org.jnode.shell.syntax.FlagArgument; +/** + * This command class calculates MD5 digests for files. If the 'check' flag is + * given, it reads a file containing digests and filenames and checks that the + * named files digests batch the supplied digests. Otherwise, it simply calculates + * and outputs the digests as filenames in a format compatible with 'check' processing. + * <p> + * The command is based on the GNU 'md5sum' command, with some differences in the + * 'check' file format. + * + * @author Tim Sparg + * @author cr...@jn... + */ public class Md5SumCommand extends AbstractCommand { private final FileArgument ARG_PATHS = new FileArgument( "paths", Argument.OPTIONAL | Argument.MULTIPLE, - "the files or directories to be md5summed"); + "the files (or directories) to be calculate MD5 digests for"); private final FlagArgument FLAG_RECURSIVE = new FlagArgument( "recursive", Argument.OPTIONAL, - "if set, will recursively go through all folders, md5summing all files"); - private final FlagArgument ARG_CHECK = new FlagArgument( - "check", Argument.OPTIONAL, - "if set, will check all md5sums against a file "); + "if set, recursively calculate MD5 digests for the contents of any directory"); private final FileArgument ARG_CHECKFILE = new FileArgument( "checkfile", Argument.OPTIONAL | Argument.SINGLE, - "the md5sum file to check against "); + "check MD5 digests for files listed in this file"); - private static final int MEGABYTE = 1048576; - static final byte[] HEX_CHAR_TABLE = { - (byte) '0', (byte) '1', (byte) '2', (byte) '3', - (byte) '4', (byte) '5', (byte) '6', (byte) '7', - (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', - (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' - }; + private static final int BUFFER_SIZE = 1048576; // 1Mb - private boolean recursive; - private File[] paths; - private PrintStream err; - private MessageDigest msgDigest; - private PrintStream out; - private File checkFile; - private String hexOutputString; - + private PrintWriter out; + private PrintWriter err; + private MessageDigest digestEngine; + + public Md5SumCommand() { - super("Calculate a md5sum against a file or Folder of Files"); - registerArguments(ARG_PATHS, FLAG_RECURSIVE, ARG_CHECK, ARG_CHECKFILE); + super("Calculate or check MD5 digests"); + registerArguments(ARG_PATHS, FLAG_RECURSIVE, ARG_CHECKFILE); } + public void execute() throws Exception { + this.err = getError().getPrintWriter(); + this.out = getOutput().getPrintWriter(); - public void execute(CommandLine commandLine, InputStream in, - PrintStream out, PrintStream err) throws Exception { + // If this throws an exception, we want it to propagate ,,, + digestEngine = MessageDigest.getInstance("md5"); - recursive = FLAG_RECURSIVE.isSet(); - paths = ARG_PATHS.getValues(); - checkFile = ARG_CHECKFILE.getValue(); - - this.err = err; - this.out = out; - - if (ARG_CHECK.isSet()) { - calculatemd5sumAgainstFile(); - } else { - boolean ok = true; + boolean ok = true; + if (ARG_CHECKFILE.isSet()) { + ok = checkFile(ARG_CHECKFILE.getValue()); + } else if (ARG_PATHS.isSet()) { + boolean recursive = FLAG_RECURSIVE.isSet(); + File[] paths = ARG_PATHS.getValues(); for (File file : paths) { - ok &= calculatemd5sum(file); + ok &= processFile(file, recursive); } + } else { + ok = processInput(); } - - + if (!ok) { + exit(1); + } } - private void calculatemd5sumAgainstFile() { - boolean md5Ok = true; - if (!checkFile.exists()) { - err.println(checkFile); - md5Ok = false; - } - - BufferedReader reader = null; - if (md5Ok) { + /** + * Read a check file containing a list of filenames and the expected MD5 digests + * of the corresponding files. We calculate the actual digests, compare with + * the expected digests and report any differences and other problems to stdout + * and/or stderr. + * + * @param checkFile the file listing the files to be checked and their + * expected digests. + * @return <code>true</code> if the check file was opened successfully, all + * named files were found and their digests were as expected. + */ + private boolean checkFile(File checkFile) { + BufferedReader br = null; + try { try { - reader = new BufferedReader(new FileReader(checkFile)); - } catch (FileNotFoundException e) { - //have just checked against this, so this shouldnt occour + br = new BufferedReader(new FileReader(checkFile)); + } catch (FileNotFoundException ex) { + err.println("Cannot open " + checkFile + ": " + ex.getMessage()); + return false; } - } - - if (md5Ok) { String readLine; - try { - int failCount = 0; - while ((readLine = reader.readLine()) != null) { - boolean passed = true; - String[] line = readLine.split("[ ]+"); - if (calculatemd5sum(new File(line[1].trim()))) { - if (!hexOutputString.equals(line[0].trim())) { - passed = false; + int failCount = 0; + while ((readLine = br.readLine()) != null) { + String[] line = readLine.split("\\s+"); + if (line.length == 2) { + try { + byte[] digest = computeDigest(new File(line[1])); + boolean passed = toHexString(digest).equalsIgnoreCase(line[0]); + if (passed) { + out.println(line[1] + " : OK"); + } else { + out.println(line[1] + " : FAILED"); + failCount++; } - } else { - passed = false; - } - - if (passed) { - out.println(line[1] + " : OK"); - } else { - out.println(line[1] + " : FAILED"); + } catch (IOException ex) { + out.println(line[1] + " : IO EXCEPTION - " + ex.getMessage()); failCount++; } } - if (failCount > 0) { - out.println(failCount + " file(s) failed"); + } + if (failCount > 0) { + err.println(failCount + " file(s) failed"); + return false; + } + } catch (IOException ex) { + err.println("problem reading file " + checkFile + ": " + ex.getMessage()); + return false; + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException ex) { + // squash ... } - } catch (IOException e) { - out.println("md5sum could not be checked against " + checkFile); } } + return true; } - - private boolean calculatemd5sum(File file) { - if (!file.exists()) { - err.println(file + " does not exist"); - return false; - } - boolean md5sumOk = true; - + /** + * Calculate the digest for a file and output it in a format compatible + * with the 'check' option. If the supplied file is a directory and + * 'recursive' is <code>true</code>, recursively process the directory + * contents. + * + * @param file the file (or directory) to be processed. + * @param recursive if <code>true</code> process directory contents recursively. + * @return <code>true</code> if all file digests were computed and output. + */ + private boolean processFile(File file, boolean recursive) { + boolean res = true; if (file.isDirectory()) { if (recursive) { for (File f : file.listFiles()) { final String name = f.getName(); if (!name.equals(".") && !name.equals("..")) { - md5sumOk &= calculatemd5sum(f); + res &= processFile(f, recursive); } } } else { err.println("Cannot calculate md5sum on folder: " + file); - md5sumOk = false; + res = false; } } else { - if (md5sumOk) { - if (msgDigest == null) { - try { - msgDigest = MessageDigest.getInstance("md5"); - } catch (NoSuchAlgorithmException e) { - err.println("md5sum algorithm Could not be found"); - md5sumOk = false; - } - } else { - msgDigest.reset(); - } + try { + out.println(toHexString(computeDigest(file)) + " " + file); } - - BufferedInputStream bis = null; - byte[] buffer = null; - int maxBytesToRead = 0; - long fileSize = file.length(); - if (md5sumOk) { - if (fileSize >= MEGABYTE) { - maxBytesToRead = MEGABYTE; - buffer = new byte[maxBytesToRead]; - } else { - maxBytesToRead = (int) fileSize; - buffer = new byte[maxBytesToRead]; - } - try { - bis = new BufferedInputStream(new FileInputStream(file)); - } catch (FileNotFoundException e) { - md5sumOk = false; - } - + catch (IOException ex) { + err.println(file + " was not md5summed: " + ex.getMessage()); } + } + return res; + } + + /** + * Compute digest for the command's input stream. + * @return <code>true</code> if all is well; + */ + private boolean processInput() { + try { + out.println(toHexString(computeDigest(null))); + return true; + } + catch (IOException ex) { + err.println("Input was not md5summed: " + ex.getMessage()); + return false; + } + } - - if (md5sumOk) { - int bytesRead = 0; - try { - bytesRead = bis.read(buffer, 0, maxBytesToRead); - do { - msgDigest.update(buffer); - bytesRead = bis.read(buffer, 0, maxBytesToRead); - } while (bytesRead > 0); - bis.close(); - hexOutputString = convertOutputToHexString(msgDigest.digest()); - } catch (IOException e) { - md5sumOk = false; - } - + /** + * Compute the digest of a file. + * @param file the file. If this is <code>null</code>, we calculate the digest + * for the command's input stream. + * @return the digest. + * @throws IOException + */ + private byte[] computeDigest(File file) throws IOException { + InputStream is = null; + byte[] buffer = new byte[BUFFER_SIZE]; + try { + digestEngine.reset(); + is = (file != null) ? new FileInputStream(file) : getInput().getInputStream(); + int bytesRead; + while ((bytesRead = is.read(buffer, 0, BUFFER_SIZE)) > 0 ) { + digestEngine.update(buffer, 0, bytesRead); } - - if (md5sumOk) { - out.println(hexOutputString + " " + file); - } else { - err.println(file + " was not md5summed"); + return digestEngine.digest(); + } finally { + if (file != null && is != null) { + is.close(); } - } - - return md5sumOk; } - - private String convertOutputToHexString(byte[] bs) throws UnsupportedEncodingException { - byte[] hex = new byte[2 * bs.length]; + /** + * Turn a digest represented as a byte array into a hexadecimal string. + * + * @param digest the digest as bytes + * @return the corresponding hex string. + */ + private String toHexString(byte[] digest) { + char[] hex = new char[digest.length * 2]; int index = 0; - for (byte b : bs) { - int v = b & 0xFF; - hex[index++] = HEX_CHAR_TABLE[v >>> 4]; - hex[index++] = HEX_CHAR_TABLE[v & 0xF]; + for (byte b : digest) { + hex[index++] = hexChar(b >> 4); + hex[index++] = hexChar(b); } - - return new String(hex, "ASCII"); + return new String(hex); } + + private char hexChar(int i) { + i = i & 0xf; + return (char) ((i > 9 ? ('a' - 10) : '0') + i); + } - /** + * The classic Java entry point. * @param args * @throws Exception */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-03-30 23:26:56
|
Revision: 5194 http://jnode.svn.sourceforge.net/jnode/?rev=5194&view=rev Author: chrisboertien Date: 2009-03-30 23:26:53 +0000 (Mon, 30 Mar 2009) Log Message: ----------- implemented verbose/interactive commands into del Modified Paths: -------------- trunk/fs/descriptors/org.jnode.fs.command.xml trunk/fs/src/fs/org/jnode/fs/command/DeleteCommand.java Modified: trunk/fs/descriptors/org.jnode.fs.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.command.xml 2009-03-30 18:23:13 UTC (rev 5193) +++ trunk/fs/descriptors/org.jnode.fs.command.xml 2009-03-30 23:26:53 UTC (rev 5194) @@ -57,6 +57,9 @@ <sequence description="delete files and directories"> <optionSet> <option argLabel="recursive" shortName="r" longName="recursive"/> + <option argLabel="force" shortName="f" longName="force" /> + <option argLabel="interactive" shortName="i" longName="interactive" /> + <option argLabel="verbose" shortName="v" longName="verbose" /> </optionSet> <repeat minCount="1"><argument argLabel="paths"/></repeat> </sequence> Modified: trunk/fs/src/fs/org/jnode/fs/command/DeleteCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/DeleteCommand.java 2009-03-30 18:23:13 UTC (rev 5193) +++ trunk/fs/src/fs/org/jnode/fs/command/DeleteCommand.java 2009-03-30 23:26:53 UTC (rev 5194) @@ -22,6 +22,8 @@ import java.io.File; import java.io.PrintWriter; +import java.io.Reader; +import java.io.IOException; import javax.naming.NameNotFoundException; @@ -42,22 +44,32 @@ * @author cr...@jn... */ public class DeleteCommand extends AbstractCommand { + + private static final String help_file = "the files or directories to be deleted"; + private static final String help_recurse = "if set, any directories are deleted recursively"; + private static final String help_force = "ignore non-existant files, never prompt"; + private static final String help_interact = "prompt before every delete"; + private static final String help_verbose = "give information on what is happening"; - private final FileArgument ARG_PATHS = new FileArgument( - "paths", Argument.MANDATORY | Argument.MULTIPLE | Argument.EXISTING, - "the files or directories to be deleted"); - private final FlagArgument FLAG_RECURSIVE = new FlagArgument( - "recursive", Argument.OPTIONAL, - "if set, any directories are deleted recursively"); + private final FileArgument ArgPaths + = new FileArgument("paths", Argument.MANDATORY | Argument.MULTIPLE | Argument.EXISTING, help_file); + private final FlagArgument FlagRecurse = new FlagArgument("recursive", Argument.OPTIONAL, help_recurse); + private final FlagArgument FlagForce = new FlagArgument("force", Argument.OPTIONAL, help_force); + private final FlagArgument FlagInteract = new FlagArgument("interactive", Argument.OPTIONAL, help_interact); + private final FlagArgument FlagVerbose = new FlagArgument("verbose", Argument.OPTIONAL, help_verbose); private FileSystemService fss; private boolean recursive; + private boolean force; + private boolean interactive; + private boolean verbose; private PrintWriter err; - + private PrintWriter out; + private Reader in; public DeleteCommand() { super("delete files or directories"); - registerArguments(ARG_PATHS, FLAG_RECURSIVE); + registerArguments(ArgPaths, FlagRecurse, FlagForce, FlagInteract, FlagVerbose); } public static void main(String[] args) throws Exception { @@ -67,9 +79,17 @@ public void execute() throws NameNotFoundException { // Lookup the Filesystem service fss = InitialNaming.lookup(FileSystemService.NAME); - recursive = FLAG_RECURSIVE.isSet(); - File[] paths = ARG_PATHS.getValues(); - this.err = getError().getPrintWriter(); + + recursive = FlagRecurse.isSet(); + force = FlagForce.isSet(); + interactive = FlagInteract.isSet(); + verbose = FlagVerbose.isSet(); + File[] paths = ArgPaths.getValues(); + + err = getError().getPrintWriter(); + out = getOutput().getPrintWriter(); + in = getInput().getReader(); + boolean ok = true; for (File file : paths) { ok &= deleteFile(file); @@ -81,9 +101,19 @@ private boolean deleteFile(File file) { if (!file.exists()) { - err.println(file + " does not exist"); + if (!force) { + err.println(file + " does not exist"); + } return false; } + if (file.isDirectory() && !recursive) { + err.println("cannot remove " + file + ": Is a directory"); + return false; + } + if (file.isFile() && interactive && !prompt_yn("remove regular file " + file.getAbsolutePath() + "?")) { + return false; + } + boolean deleteOk = true; // FIXME the following doesn't handle mounted filesystems correctly (I think). @@ -91,26 +121,30 @@ // give an error message and then refuse to delete the parent directory because // it cannot be emptied. if (file.isDirectory() && !fss.isMount(file.getAbsolutePath())) { + if (interactive && !prompt_yn("descend into directory " + file.getAbsolutePath() + "?")) { + return false; + } for (File f : file.listFiles()) { final String name = f.getName(); if (!name.equals(".") && !name.equals("..")) { - if (!recursive) { - err.println("Directory is not empty " + file); - deleteOk = false; - break; - } else { - deleteOk &= deleteFile(f); - } + deleteOk &= deleteFile(f); } } + if (deleteOk && interactive && !prompt_yn("remove directory " + file.getAbsolutePath() + "?")) { + return false; + } } - + if (deleteOk) { // FIXME ... this is going to attempt to delete "directories" that are // mounted filesystems. Is this right? What will it do? // FIXME ... this does not report the reason that the delete failed. // How should we do that? + if (verbose) { + if (file.isFile()) out.println("removed " + file.getAbsolutePath()); + if (file.isDirectory()) out.println("removed directory " + file.getAbsolutePath()); + } deleteOk = file.delete(); if (!deleteOk) { err.println(file + " was not deleted"); @@ -118,4 +152,20 @@ } return deleteOk; } + + private boolean prompt_yn(String s) { + int choice; + for (;;) { + out.print(s + " [y/n]"); + try { + choice = in.read(); + } catch (IOException _) { + choice = 0; + } + out.println(); + if (choice == 'y' || choice == 'n') break; + } + + return choice == 'y'; + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2009-03-31 20:12:57
|
Revision: 5199 http://jnode.svn.sourceforge.net/jnode/?rev=5199&view=rev Author: lsantha Date: 2009-03-31 19:57:24 +0000 (Tue, 31 Mar 2009) Log Message: ----------- Integrated patch by Stefan Anzinger: "Changes done: 1. Removed usage JFuncSuite for defining TestSuites this blocks Eclipse JUnit testrunner to execute tests (i don't know why but it doesn't work). Now it is also feasible to run FSTestSuite in Eclipse with "Run-As -> Junit Test". 2. Added report generation in the fs/build.xml to generate HTML-report of testrun in fs/build/report/" Modified Paths: -------------- trunk/fs/build.xml trunk/fs/src/test/org/jnode/test/fs/filesystem/AbstractFSTest.java trunk/fs/src/test/org/jnode/test/fs/filesystem/FSTestSuite.java trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/BasicFSTest.java trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/ConcurrentAccessFSTest.java trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/FileFSTest.java trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/TreeFSTest.java Modified: trunk/fs/build.xml =================================================================== --- trunk/fs/build.xml 2009-03-31 19:02:47 UTC (rev 5198) +++ trunk/fs/build.xml 2009-03-31 19:57:24 UTC (rev 5199) @@ -6,6 +6,7 @@ <property name="my-classes.dir" value="${my-build.dir}/classes"/> <property name="my-src.dir" value="${basedir}/src"/> <property name="my.jar" value="${jnode-fs.jar}"/> + <property name="my-report.dir" value="${my-build.dir}/report"/> <!-- Subproject specific classpath --> <path id="my-cp"> @@ -71,12 +72,19 @@ <!-- tests FileSystems --> <target name="tests" depends="compile" description="Run FS tests with JUnit"> + <mkdir dir="${my-report.dir}"/> <junit fork="yes" haltonerror="false" haltonfailure="false" printsummary="on" includeantruntime="true"> <classpath refid="cp-jnode" /> - - <formatter type="plain" usefile="false" /> - <test name="org.jnode.test.fs.filesystem.FSTestSuite" /> + <formatter type="xml" /> + <test name="org.jnode.test.fs.filesystem.FSTestSuite" outfile="${my-report.dir}/TEST-fs"/> </junit> + <junitreport todir="${my-report.dir}"> + <fileset dir="${my-report.dir}"> + <include name="TEST*.xml"/> + </fileset> + <report todir="${my-report.dir}" format="frames"/> + </junitreport> + <echo message="HTML report: ${my-report.dir}/index.html" /> </target> </project> Modified: trunk/fs/src/test/org/jnode/test/fs/filesystem/AbstractFSTest.java =================================================================== --- trunk/fs/src/test/org/jnode/test/fs/filesystem/AbstractFSTest.java 2009-03-31 19:02:47 UTC (rev 5198) +++ trunk/fs/src/test/org/jnode/test/fs/filesystem/AbstractFSTest.java 2009-03-31 19:57:24 UTC (rev 5199) @@ -26,8 +26,11 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; + import javax.naming.NameNotFoundException; -import junit.extensions.jfunc.JFuncTestCase; + +import junit.framework.TestCase; + import org.apache.log4j.Logger; import org.jnode.driver.Device; import org.jnode.fs.FSDirectory; @@ -41,18 +44,19 @@ /** * @author Fabien DUMINY */ -public abstract class AbstractFSTest extends JFuncTestCase { +public abstract class AbstractFSTest extends TestCase { protected final Logger log = Logger.getLogger(getClass()); //public static final int FILE_SIZE_IN_WORDS = 256 * 1024; // 512 Ko = 256 K Words public static final int FILE_SIZE_IN_WORDS = 128; // 512 Ko = 128 K Words private FileSystem fs; - private FSTestConfig config; + protected FSTestConfig config; private Device device; - public AbstractFSTest() { + public AbstractFSTest(FSTestConfig config) { super(); + this.config = config; } /** @@ -62,10 +66,9 @@ super(name); } - protected final void setUp(FSTestConfig config) throws NameNotFoundException, FileSystemException, IOException, + public final void setUp() throws NameNotFoundException, FileSystemException, IOException, InstantiationException, IllegalAccessException, Exception { super.setUp(); - this.config = config; this.device = config.getDeviceParam().createDevice(); this.fs = config.getFileSystem().format(this.device); this.fs = config.getFileSystem().mount(this.device); @@ -141,9 +144,9 @@ // return (FSContext) ContextManager.getInstance().getContext(); // } - protected void assertFalse(String message, boolean condition) { - assertTrue(message, !condition); - } +// protected void assertFalse(String message, boolean condition) { +// assertTrue(message, !condition); +// } protected void assertContainsOnly(String errorMessage, Iterator<? extends FSEntry> it, String[] requiredNames) { boolean ok = true; Modified: trunk/fs/src/test/org/jnode/test/fs/filesystem/FSTestSuite.java =================================================================== --- trunk/fs/src/test/org/jnode/test/fs/filesystem/FSTestSuite.java 2009-03-31 19:02:47 UTC (rev 5198) +++ trunk/fs/src/test/org/jnode/test/fs/filesystem/FSTestSuite.java 2009-03-31 19:57:24 UTC (rev 5199) @@ -20,8 +20,12 @@ package org.jnode.test.fs.filesystem; +import javax.naming.NamingException; + import junit.extensions.jfunc.JFuncSuite; import junit.extensions.jfunc.textui.JFuncRunner; +import junit.framework.TestCase; +import junit.framework.TestSuite; import org.jnode.emu.naming.BasicNameSpace; import org.jnode.emu.plugin.model.DummyConfigurationElement; @@ -38,7 +42,6 @@ import org.jnode.test.fs.filesystem.tests.FileFSTest; import org.jnode.test.fs.filesystem.tests.TreeFSTest; import org.jnode.util.OsUtils; -import javax.naming.NamingException; /** * This class runs a suite of functional tests on the JNode file system @@ -84,36 +87,40 @@ setup = true; } - public static JFuncSuite suite() throws Throwable { + public static TestSuite suite() throws Throwable { setUp(); - JFuncSuite suite = new JFuncSuite(); - + TestSuite allTestsSuite = new TestSuite("All FS Tests"); + for (FSTestConfig config : new FSConfigurations()) { - BasicFSTest basicTest = (BasicFSTest) suite.getTestProxy(new BasicFSTest()); - basicTest.testAddDirectory(config); - basicTest.testAddFile(config); - basicTest.testAddFileThenRemountFSAndGetFile(config); - basicTest.testGetRootEntry(config); - basicTest.testListRootEntries(config); - basicTest.testRemoveThenRemountFSAndGetEntry(config); + TestSuite tests = new TestSuite(); + tests.setName(config.getFileSystem().toString()); + addTest(tests, new BasicFSTest(config), "testAddDirectory"); + addTest(tests, new BasicFSTest(config), "testAddFile"); + addTest(tests, new BasicFSTest(config), "testAddFileThenRemountFSAndGetFile"); + addTest(tests, new BasicFSTest(config), "testGetRootEntry"); + addTest(tests, new BasicFSTest(config), "testListRootEntries"); + addTest(tests, new BasicFSTest(config), "testRemoveThenRemountFSAndGetEntry"); - FileFSTest fileTest = (FileFSTest) suite.getTestProxy(new FileFSTest()); - fileTest.testSetLength(config); - fileTest.testWriteFileInReadOnlyMode(config); - fileTest.testWriteFileThenRemountFSAndRead(config); + addTest(tests, new FileFSTest(config), "testSetLength"); + addTest(tests, new FileFSTest(config), "testWriteFileInReadOnlyMode"); + addTest(tests, new FileFSTest(config), "testWriteFileThenRemountFSAndRead"); + + addTest(tests, new TreeFSTest(config), "testFSTree"); + addTest(tests, new TreeFSTest(config), "testFSTreeWithRemountAndLongName"); + addTest(tests, new TreeFSTest(config), "testFSTreeWithRemountAndShortName"); - TreeFSTest treeTest = (TreeFSTest) suite.getTestProxy(new TreeFSTest()); - treeTest.testFSTree(config); - treeTest.testFSTreeWithRemountAndLongName(config); - treeTest.testFSTreeWithRemountAndShortName(config); + addTest(tests, new ConcurrentAccessFSTest(config), "testRead"); + addTest(tests, new ConcurrentAccessFSTest(config), "testWrite"); + addTest(tests, new ConcurrentAccessFSTest(config), "testReadWrite"); - ConcurrentAccessFSTest threadTest = (ConcurrentAccessFSTest) - suite.getTestProxy(new ConcurrentAccessFSTest()); - threadTest.testRead(config); - threadTest.testWrite(config); - threadTest.testReadWrite(config); + allTestsSuite.addTest(tests); } - - return suite; + + return allTestsSuite; } + + private static void addTest(TestSuite suite, TestCase test, String name) { + test.setName(name); + suite.addTest(test); + } } Modified: trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/BasicFSTest.java =================================================================== --- trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/BasicFSTest.java 2009-03-31 19:02:47 UTC (rev 5198) +++ trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/BasicFSTest.java 2009-03-31 19:57:24 UTC (rev 5199) @@ -20,8 +20,8 @@ package org.jnode.test.fs.filesystem.tests; -import java.io.IOException; import java.util.Iterator; + import org.jnode.fs.FSDirectory; import org.jnode.fs.FSEntry; import org.jnode.fs.ReadOnlyFileSystemException; @@ -34,30 +34,30 @@ * @author Fabien DUMINY */ public class BasicFSTest extends AbstractFSTest { - public BasicFSTest() { - super(); + public BasicFSTest(FSTestConfig config) { + super(config); } public BasicFSTest(String name) { super(name); } - - public void testGetRootEntry(FSTestConfig config) throws Exception { - setUp(config); + + public void testGetRootEntry() throws Exception { + setUp(); FSEntry rootEntry = getFs().getRootEntry(); log.debug(FSUtils.toString(rootEntry, false)); } - public void testListRootEntries(FSTestConfig config) throws Exception { - setUp(config); + public void testListRootEntries() throws Exception { + setUp(); Iterator<? extends FSEntry> iterator = getFs().getRootEntry().getDirectory().iterator(); TestUtils.listEntries(iterator); } - public void testAddDirectory(FSTestConfig config) throws Exception { - setUp(config); + public void testAddDirectory() throws Exception { + setUp(); FSDirectory rootDir = getFs().getRootEntry().getDirectory(); String dirName = "A new directory.text"; @@ -89,8 +89,8 @@ TestUtils.listEntries(rootDir.iterator()); } - public void testAddFile(FSTestConfig config) throws Exception { - setUp(config); + public void testAddFile() throws Exception { + setUp(); FSDirectory rootDir = getFs().getRootEntry().getDirectory(); String fileName = "A new file.text"; @@ -124,9 +124,9 @@ TestUtils.listEntries(rootDir.iterator()); } - public void testAddFileThenRemountFSAndGetFile(FSTestConfig config) throws IOException, Exception { + public void testAddFileThenRemountFSAndGetFile() throws Exception { if (!config.isReadOnly()) { - setUp(config); + setUp(); String filename = "a file to test.text"; FSDirectory rootDir = getFs().getRootEntry().getDirectory(); @@ -149,10 +149,10 @@ } } - public void testRemoveThenRemountFSAndGetEntry(FSTestConfig config) throws Exception { + public void testRemoveThenRemountFSAndGetEntry() throws Exception { if (!config.isReadOnly()) { - setUp(config); + setUp(); String filename = "a file to test.text"; FSDirectory rootDir = getFs().getRootEntry().getDirectory(); Modified: trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/ConcurrentAccessFSTest.java =================================================================== --- trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/ConcurrentAccessFSTest.java 2009-03-31 19:02:47 UTC (rev 5198) +++ trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/ConcurrentAccessFSTest.java 2009-03-31 19:57:24 UTC (rev 5199) @@ -41,16 +41,16 @@ protected static final int NB_WRITERS = 10; - public ConcurrentAccessFSTest() { - super(); + public ConcurrentAccessFSTest(FSTestConfig config) { + super(config); } public ConcurrentAccessFSTest(String name) { super(name); } - public void testRead(FSTestConfig config) throws Throwable { - setUp(config); + public void testRead() throws Throwable { + setUp(); FSFile file = prepareFile(config); @@ -61,9 +61,9 @@ monitor.waitAll(); } - public void testWrite(FSTestConfig config) throws Throwable { + public void testWrite() throws Throwable { if (!config.isReadOnly()) { - setUp(config); + setUp(); FSFile file = prepareFile(config); Monitor monitor = new Monitor("testWrite"); @@ -73,8 +73,8 @@ } } - public void testReadWrite(FSTestConfig config) throws Throwable { - setUp(config); + public void testReadWrite() throws Throwable { + setUp(); FSFile file = prepareFile(config); Monitor monitor = new Monitor("testReadWrite"); Modified: trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/FileFSTest.java =================================================================== --- trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/FileFSTest.java 2009-03-31 19:02:47 UTC (rev 5198) +++ trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/FileFSTest.java 2009-03-31 19:57:24 UTC (rev 5199) @@ -33,16 +33,16 @@ * @author Fabien DUMINY */ public class FileFSTest extends AbstractFSTest { - public FileFSTest() { - super(); + public FileFSTest(FSTestConfig config) { + super(config); } public FileFSTest(String name) { super(name); } - public void testWriteFileThenRemountFSAndRead(FSTestConfig config) throws Exception { - setUp(config); + public void testWriteFileThenRemountFSAndRead() throws Exception { + setUp(); final String fileName = "RWTest"; @@ -82,9 +82,9 @@ } } - public void testWriteFileInReadOnlyMode(FSTestConfig config) throws Exception { + public void testWriteFileInReadOnlyMode() throws Exception { if (config.isReadOnly()) { - setUp(config); + setUp(); final String fileName = "RWTest"; @@ -104,8 +104,8 @@ } } - public void testSetLength(FSTestConfig config) throws Exception { - setUp(config); + public void testSetLength() throws Exception { + setUp(); final int newSize = 128; final String fileName = "RWTest"; Modified: trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/TreeFSTest.java =================================================================== --- trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/TreeFSTest.java 2009-03-31 19:02:47 UTC (rev 5198) +++ trunk/fs/src/test/org/jnode/test/fs/filesystem/tests/TreeFSTest.java 2009-03-31 19:57:24 UTC (rev 5199) @@ -31,17 +31,17 @@ * @author Fabien DUMINY */ public class TreeFSTest extends AbstractFSTest { - public TreeFSTest() { - super(); + public TreeFSTest(FSTestConfig config) { + super(config); } public TreeFSTest(String name) { super(name); } - public void testFSTree(FSTestConfig config) throws IOException, Exception { + public void testFSTree() throws IOException, Exception { if (!config.isReadOnly()) { - setUp(config); + setUp(); FSDirectory rootDir = getFs().getRootEntry().getDirectory(); FSEntry dir1 = rootDir.addDirectory("dir1"); @@ -62,17 +62,17 @@ } } - public void testFSTreeWithRemountAndShortName(FSTestConfig config) throws Exception { + public void testFSTreeWithRemountAndShortName() throws Exception { doTestFSTreeWithRemount(config, "dir1"); } - public void testFSTreeWithRemountAndLongName(FSTestConfig config) throws Exception { + public void testFSTreeWithRemountAndLongName() throws Exception { doTestFSTreeWithRemount(config, "This is a Long FileName.extension"); } private void doTestFSTreeWithRemount(FSTestConfig config, String fileName) throws Exception { if (!config.isReadOnly()) { - setUp(config); + setUp(); FSDirectory rootDir = getFs().getRootEntry().getDirectory(); log.debug("### testFSTreeWithRemount: rootDir=\n" + FSUtils.toString(rootDir, true)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-04-01 04:24:07
|
Revision: 5202 http://jnode.svn.sourceforge.net/jnode/?rev=5202&view=rev Author: chrisboertien Date: 2009-04-01 04:23:57 +0000 (Wed, 01 Apr 2009) Log Message: ----------- More fs-archive command implementation Signed-off-by: Chris Boertien <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/ArchiveCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/BUnzipCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/BZip.java trunk/fs/src/fs/org/jnode/fs/command/archive/BZipCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/GUnzipCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/GZip.java trunk/fs/src/fs/org/jnode/fs/command/archive/GZipCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/TarCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/ZCatCommand.java Modified: trunk/fs/descriptors/org.apache.tools.archive.xml =================================================================== --- trunk/fs/descriptors/org.apache.tools.archive.xml 2009-03-31 20:21:47 UTC (rev 5201) +++ trunk/fs/descriptors/org.apache.tools.archive.xml 2009-04-01 04:23:57 UTC (rev 5202) @@ -12,7 +12,7 @@ <library name="ant.jar"> <export name="org.apache.tools.tar.*" /> <export name="org.apache.tools.zip.*" /> - <export name="org.apache.tools.bzip.*" /> + <export name="org.apache.tools.bzip2.*" /> </library> </runtime> Modified: trunk/fs/descriptors/org.jnode.fs.command.archive.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.command.archive.xml 2009-03-31 20:21:47 UTC (rev 5201) +++ trunk/fs/descriptors/org.jnode.fs.command.archive.xml 2009-04-01 04:23:57 UTC (rev 5202) @@ -54,13 +54,13 @@ <option argLabel="fileList" shortName="T" longName="files-from"/> <option argLabel="gzip" shortName="z" longName="gzip" /> <option argLabel="interact" shortName="w" longName="interactive" /> - <option argLabel="keepFiles" shortName="k" longName="keep-old-files" /> + <option argLabel="keep" shortName="k" longName="keep-old-files" /> <option argLabel="noRecurse" longName="no-recursion" /> <option argLabel="recurse" longName="recursion" /> <option argLabel="removeFiles" longName="remove-files" /> <option argLabel="showTotals" longName="totals" /> <option argLabel="suffix" longName="suffix" /> - <option argLabel="useStdout" shortName="O" longName="to-stdout" /> + <option argLabel="stdout" shortName="O" longName="to-stdout" /> <option argLabel="verbose" shortName="v" longName="verbose" /> <option argLabel="verify" shortName="W" longName="verify" /> <option argLabel="xfile" shortName="X" longName="exclude-from"/> @@ -70,7 +70,7 @@ --> </optionSet> <repeat minCount="0"> - <argument argLabel="paths" label="file/dir"/> + <argument argLabel="paths"/> </repeat> </sequence> </syntax> @@ -85,16 +85,16 @@ <option argLabel="force" shortName="f" longName="force" /> <option argLabel="quiet" shortName="q" longName="quiet" /> <option argLabel="verbose" shortName="v" longName="verbose" /> - <option argLabel="lvl1" shortName="1" longName="fast" /> + <option argLabel="c1" shortName="1" longName="fast" /> <option argLabel="debug" longName="debug" /> - <option argLabel="recursive" shortName="r" longName="recursive" /> + <option argLabel="recurse" shortName="r" longName="recursive" /> <option argLabel="test" shortName="t" longName="test" /> <option argLabel="list" shortName="l" longName="list" /> - <option argLabel="lvl9" shortName="9" longName="best" /> + <option argLabel="c9" shortName="9" longName="best" /> </optionSet> <optional eager="true"><option argLabel="suffix" shortName="S" longName="suffix" /></optional> <repeat minCount="1"> - <argument argLabel="file" /> + <argument argLabel="files" /> </repeat> </sequence> </syntax> @@ -103,7 +103,7 @@ <sequence description="decompress files"> <optionSet> <option argLabel="debug" longName="debug" /> - <option argLabel="recursive" shortName="r" longName="recursive" /> + <option argLabel="recurse" shortName="r" longName="recursive" /> <option argLabel="test" shortName="t" longName="test" /> <option argLabel="list" shortName="l" longName="list" /> <option argLabel="noname" shortName="n" longName="no-name" /> @@ -115,7 +115,7 @@ </optionSet> <optional eager="true"><option argLabel="suffix" shortName="S" longName="suffix" /></optional> <repeat minCount="1"> - <argument argLabel="file" /> + <argument argLabel="files" /> </repeat> </sequence> </syntax> @@ -128,7 +128,7 @@ <option argLabel="debug" longName="debug" /> </optionSet> <repeat minCount="1"> - <argument argLabel="file" /> + <argument argLabel="files" /> </repeat> </sequence> </syntax> @@ -137,10 +137,62 @@ <syntax alias="unzip"> </syntax> <syntax alias="bzip2"> + <empty description="compress stdin to stdout" /> + <sequence description="compress files"> + <optionSet> + <option argLabel="stdout" shortName="c" longName="stdout" /> + <option argLabel="decompress" shortName="d" longName="decompress" /> + <option argLabel="compress" shortName="z" longName="compress" /> + <option argLabel="test" shortName="t" longName="test" /> + <option argLabel="force" shortName="f" longName="force" /> + <option argLabel="keep" shortName="k" longName="keep" /> + <option argLabel="small" shortName="s" longName="small" /> + <option argLabel="verbose" shortName="v" longName="verbose" /> + <option argLabel="quiet" shortName="q" longName="quiet" /> + <option argLabel="debug" longName="debug" /> + <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" /> + </optionSet> + <repeat> + <argument argLabel="files" /> + </repeat> + </sequence> </syntax> <syntax alias="bunzip2"> + <empty description="decompress stdin to stdout" /> + <sequence description="decompress files"> + <optionSet> + <option argLabel="stdout" shortName="c" longName="stdout" /> + <option argLabel="test" shortName="t" longName="test" /> + <option argLabel="force" shortName="f" longName="force" /> + <option argLabel="keep" shortName="k" longName="keep" /> + <option argLabel="small" shortName="s" longName="small" /> + <option argLabel="verbose" shortName="v" longName="verbose" /> + <option argLabel="quiet" shortName="q" longName="quiet" /> + <option argLabel="debug" longName="debug" /> + </optionSet> + <repeat> + <argument argLabel="files" /> + </repeat> + </sequence> </syntax> <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> </extension> Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java 2009-03-31 20:21:47 UTC (rev 5201) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java 2009-04-01 04:23:57 UTC (rev 5202) @@ -21,6 +21,8 @@ package org.jnode.fs.command.archive; import org.jnode.shell.AbstractCommand; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FlagArgument; import java.io.File; import java.io.FileInputStream; @@ -31,35 +33,133 @@ import java.io.Reader; import java.io.IOException; +import java.util.ArrayList; + public class ArchiveCommand extends AbstractCommand { - protected static final int OUT_ERROR = 0x01; - protected static final int OUT_WARN = 0x02; - protected static final int OUT_NOTICE = 0x04; + private static final String help_verbose = "show the compression ratio for each file compressed"; + private static final String help_debug = "internal debug output"; + private static final String help_quiet = "supress non-essential warning messages"; + private static final String help_stdout = "pipe data to stdout"; + private static final String help_force = "force overwrite of output files"; + protected static final String help_decompress = "force decompression"; + + protected static final String prompt_overwrite = " already exists. Do you wish to overwrite? [Y/n]: "; + + protected static final String err_exception_uncaught = "Unhandled Exception thrown"; + protected static final String err_file_create = "Could not create file: "; + protected static final String err_file_not_exist = "Could not find file: "; + protected static final String err_stream_create = "Could not create stream: "; + + protected static final String fmt_size_diff = "%s:\t%f.2%% -- replaced with %s"; + + protected final FlagArgument Quiet = new FlagArgument("quiet", Argument.OPTIONAL, help_quiet); + protected final FlagArgument Verbose = new FlagArgument("verbose", Argument.OPTIONAL, help_verbose); + protected final FlagArgument Debug = new FlagArgument("debug", Argument.OPTIONAL, help_debug); + protected final FlagArgument Stdout = new FlagArgument("stdout", Argument.OPTIONAL, help_stdout); + protected final FlagArgument Force = new FlagArgument("force", Argument.OPTIONAL, help_force); + + protected static final int OUT_FATAL = 0x01; + protected static final int OUT_ERROR = 0x02; + protected static final int OUT_WARN = 0x04; + protected static final int OUT_NOTICE = 0x08; protected static final int OUT_DEBUG = 0x80; + protected static final int BUFFER_SIZE = 4096; + protected int outMode = OUT_ERROR | OUT_WARN; protected PrintWriter stdoutWriter; protected PrintWriter stderrWriter; protected Reader stdinReader; + protected InputStream stdin; + protected OutputStream stdout; + protected String commandName; + protected boolean use_stdout; + protected boolean force; + protected boolean compress; + private byte[] buffer; + private ArchiveCommand() {} + protected ArchiveCommand(String s) { super(s); + registerArguments(Quiet, Verbose, Debug, Stdout, Force); } - protected void setup() { + public void execute() { stdoutWriter = getOutput().getPrintWriter(); stderrWriter = getError().getPrintWriter(); stdinReader = getInput().getReader(); + stdin = getInput().getInputStream(); + stdout = getOutput().getOutputStream(); + + if (Quiet.isSet()) { + outMode = 0; + } else { + if (Verbose.isSet()) { + outMode |= OUT_NOTICE; + } + if (Debug.isSet()) { + outMode |= OUT_DEBUG; + } + } + + if (!use_stdout) use_stdout = Stdout.isSet(); + force = Force.isSet(); } protected void createStreamBuffer(int size) { buffer = new byte[size]; } + protected File[] processFileList(File[] files, boolean recurse) { + if (files == null || files.length == 0) return null; + + if (files.length == 1 && !files[0].isDirectory()) { + if (files[0].getName().equals("-")) return null; + return files; + } + + ArrayList<File> _files = new ArrayList<File>(); + + for (File file : files) { + debug(file.getName()); + if (file.getName().equals("-")) { + if (use_stdout) { + // A special case where '-' is found amongst a list of files and are + // being piped to stdout. The idea is that the content from - should + // be concated amongst the list of files. Its more of an error if the + // destination is not stdout. + _files.add(file); + } else { + fatal("Found stdin in file list.", 1); + } + } + if (!file.exists()) { + error(err_file_not_exist + file); + continue; + } + if (file.isDirectory() && recurse) { + File[] dirList = file.listFiles(); + for (File subFile : dirList) { + if (subFile.isFile()) { + _files.add(subFile); + } + } + } else { + if (file.isFile()) { + _files.add(file); + } + } + } + + if (_files.size() == 0) return null; + return _files.toArray(files); + } + /** * Pipes the contents of the InputStream into the OutputStream. * @@ -93,12 +193,17 @@ protected OutputStream openFileWrite(File file , boolean delete , boolean forced) { try { boolean createNew = true; + if (file == null) { + error(err_file_create + "null"); + return null; + } + if (file.exists()) { if (delete) { if (forced) { file.delete(); } else { - if (prompt_yn(file + "exists. Overwrite? ")) { + if (prompt_yn(file + prompt_overwrite, true)) { file.delete(); } else { notice("Skipping " + file); @@ -110,12 +215,12 @@ } } if (createNew && !file.createNewFile()) { - error("Could not create file: " + file); + error(err_file_create + file); return null; } return new FileOutputStream(file); } catch (IOException ioe) { - error("Could not open stream: " + file + " : " + ioe.getLocalizedMessage()); + error(err_stream_create + file); return null; } } @@ -131,9 +236,13 @@ */ protected InputStream openFileRead(File file) { try { + if (file == null || !file.exists()) { + error(err_file_not_exist + file); + return null; + } return new FileInputStream(file); } catch (IOException ioe) { - error("Cannot open stream: " + file + " : " + ioe.getLocalizedMessage()); + error(err_stream_create + file); return null; } } @@ -144,26 +253,30 @@ * @param String the question to ask the user * @return true if the user said yes, false if the user said no */ - protected boolean prompt_yn(String s) { + protected boolean prompt_yn(String s, boolean defaultY) { int choice; for (;;) { - stdoutWriter.print(s + " [y/n]"); + stdoutWriter.print(s); try { choice = stdinReader.read(); } catch (IOException _) { - choice = 0; + throw new RuntimeException("Problem with stdin"); } stdoutWriter.println(); - if (choice == 'y' || choice == 'n') break; + if (choice == 'y') return true; + if (choice == 'n') return false; + if (choice == '\n') return defaultY; } - - return choice == 'y'; } protected void out(String s) { stdoutWriter.println(s); } + protected void err(String s) { + stderrWriter.println(s); + } + protected void debug(String s) { if ((outMode & OUT_DEBUG) == OUT_DEBUG) { stderrWriter.print("debug: "); @@ -182,4 +295,9 @@ protected void error(String s) { if ((outMode & OUT_ERROR) == OUT_ERROR) stderrWriter.println(s); } + + protected void fatal(String s, int exit_code) { + stderrWriter.println("Fatal error: " + s); + exit(exit_code); + } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/BUnzipCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/BUnzipCommand.java 2009-03-31 20:21:47 UTC (rev 5201) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/BUnzipCommand.java 2009-04-01 04:23:57 UTC (rev 5202) @@ -28,6 +28,7 @@ } public void execute() { - setup(); + compress = false; + super.execute(); } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/BZip.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/BZip.java 2009-03-31 20:21:47 UTC (rev 5201) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/BZip.java 2009-04-01 04:23:57 UTC (rev 5202) @@ -20,9 +20,203 @@ package org.jnode.fs.command.archive; +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; + +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FileArgument; +import org.jnode.shell.syntax.FlagArgument; + +import org.apache.tools.bzip2.CBZip2InputStream; +import org.apache.tools.bzip2.CBZip2OutputStream; + +/** + * + * @author chris boertien + */ public class BZip extends ArchiveCommand { + private static final String help_compress = "forces compression; regardless of invocation name"; + private static final String help_files = "space seperated list of files to compress"; + private static final String help_keep = "Keep input files"; + private static final String help_small = "(ignored)"; + private static final String help_test = "test the file integrity"; + + private static final String fmt_suffix_bad = "Can't guess original name for %s -- using %s.out"; + + protected final FlagArgument Compress = new FlagArgument("compress", Argument.OPTIONAL, help_compress); + protected final FlagArgument Decompress = new FlagArgument("decompress", Argument.OPTIONAL, help_decompress); + protected final FileArgument Files = new FileArgument("files", Argument.OPTIONAL | Argument.MULTIPLE, help_files); + protected final FlagArgument Keep = new FlagArgument("keep", Argument.OPTIONAL, help_keep); + protected final FlagArgument Small = new FlagArgument("small", Argument.OPTIONAL, help_small); + protected final FlagArgument Test = new FlagArgument("test", Argument.OPTIONAL, help_test); + + protected int clevel = 9; + protected boolean keep; + public BZip(String s) { super(s); + registerArguments(Compress, Decompress, Files, Keep, Small, Test); + createStreamBuffer(4096); } + + public void execute() { + super.execute(); + + if (compress && Decompress.isSet()) { + compress = false; + } + if (!compress && Compress.isSet()) { + compress = true; + } + + keep = Keep.isSet(); + + if (!keep && use_stdout) { + keep = true; + } + + try { + if (compress) { + compress(processFileList(Files.getValues(), true)); + } else { + decompress(processFileList(Files.getValues(), true)); + } + } catch (IOException e) { + e.printStackTrace(); + fatal(err_exception_uncaught, 1); + } + } + + private void compress(File[] files) throws IOException { + InputStream in; + OutputStream out = null; + CBZip2OutputStream bzout = null; + File bzfile = null; + float sizeDiff; + + if (files == null) { + processStream(stdin, new CBZip2OutputStream(stdout, clevel)); + return; + } + + if (use_stdout) { + bzout = new CBZip2OutputStream(stdout, clevel); + } + + for (File file : files) { + if (!use_stdout) { + bzfile = new File(file.getAbsolutePath() + ".bz2"); + if ((out = openFileWrite(bzfile, true, force)) == null) continue; + bzout = new CBZip2OutputStream(out, clevel); + } + + if (file.getName().equals("-")) { + processStream(stdin, bzout); + continue; + } + + if ((in = openFileRead(file)) == null) { + if (!use_stdout) bzout.close(); + continue; + } + processStream(in, bzout); + in.close(); + + if (!use_stdout) { + bzout.close(); + sizeDiff = ((float) bzfile.length() / (float) file.length()) * 100; + notice(String.format(fmt_size_diff, file, sizeDiff, bzfile)); + if (!keep) file.delete(); + } + } + + if (use_stdout) { + bzout.close(); + } + } + + private void decompress(File[] files) throws IOException { + InputStream in; + OutputStream out = null; + File file = null; + float sizeDiff; + + if (files == null) { + processStream(new CBZip2InputStream(stdin), stdout); + return; + } + + if (use_stdout) { + out = stdout; + } + + for (File bzfile : files) { + if (!use_stdout) { + file = stripSuffix(bzfile); + if ((out = openFileWrite(file, true, force)) == null) continue; + } + + if (bzfile.getName().equals("-")) { + processStream(new CBZip2InputStream(stdin), out); + continue; + } + + if ((in = new CBZip2InputStream(openFileRead(bzfile))) == null) { + if (!use_stdout) out.close(); + continue; + } + processStream(in, out); + in.close(); + + if (!use_stdout) { + out.close(); + sizeDiff = ((float) bzfile.length() / (float) file.length()) * 100; + notice(String.format(fmt_size_diff, bzfile, sizeDiff, file)); + if (!keep) bzfile.delete(); + } + } + } + + private void test(File[] files) { + // requires patch to apache ant to have CBZip2InputStream fail with an + // exception, instead it just prints to stderr and doesn't tell us if + // it failed. + // + // Otherwise we would have to read and compute the crc ourself. + } + + private File stripSuffix(File bzfile) { + String name = bzfile.getName(); + int len = 0; + String newSuffix = null; + + if (name.endsWith(".bz")) { + len = 3; + } else if (name.endsWith(".bz2")) { + len = 4; + } else if (name.endsWith(".tbz")) { + len = 4; + newSuffix = ".tar"; + } else if (name.endsWith(".tbz2")) { + len = 5; + newSuffix = ".tar"; + } else { + notice(String.format(fmt_suffix_bad, bzfile, bzfile)); + notice("Can't guess original name for " + bzfile + " -- using " + bzfile + ".out"); + return new File(name + ".out"); + } + + if (len > 0) { + name = name.substring(0, name.length() - len); + } + + if (newSuffix != null) { + name = name + newSuffix; + } + + return new File(name); + } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/BZipCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/BZipCommand.java 2009-03-31 20:21:47 UTC (rev 5201) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/BZipCommand.java 2009-04-01 04:23:57 UTC (rev 5202) @@ -20,13 +20,31 @@ package org.jnode.fs.command.archive; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FlagArgument; + public class BZipCommand extends BZip { + private static final String help_fast = "compress faster"; + private static final String help_best = "compress better"; + + private final FlagArgument C1 = new FlagArgument("c1", Argument.OPTIONAL, help_fast); + private final FlagArgument C2 = new FlagArgument("c2", Argument.OPTIONAL, " "); + private final FlagArgument C3 = new FlagArgument("c3", Argument.OPTIONAL, " "); + private final FlagArgument C4 = new FlagArgument("c4", Argument.OPTIONAL, " "); + private final FlagArgument C5 = new FlagArgument("c5", Argument.OPTIONAL, " "); + private final FlagArgument C6 = new FlagArgument("c6", Argument.OPTIONAL, " "); + private final FlagArgument C7 = new FlagArgument("c7", Argument.OPTIONAL, " "); + private final FlagArgument C8 = new FlagArgument("c8", Argument.OPTIONAL, " "); + private final FlagArgument C9 = new FlagArgument("c9", Argument.OPTIONAL, help_best); + public BZipCommand() { super("compresses data with bzip2"); + registerArguments(C1, C2, C3, C4, C5, C6, C7, C8, C9); } public void execute() { - setup(); + compress = true; + super.execute(); } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/GUnzipCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/GUnzipCommand.java 2009-03-31 20:21:47 UTC (rev 5201) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/GUnzipCommand.java 2009-04-01 04:23:57 UTC (rev 5202) @@ -20,11 +20,6 @@ package org.jnode.fs.command.archive; -import org.jnode.shell.syntax.Argument; -import org.jnode.shell.syntax.FileArgument; -import org.jnode.shell.syntax.FlagArgument; -import org.jnode.shell.syntax.StringArgument; - /** * Decompresses data in the gzip format. * @@ -38,60 +33,13 @@ */ public class GUnzipCommand extends GZip { - - private static final String msg_stdout = "Write output on standard output, keep original files"; - private static final String msg_force = "force overwrite of output files and compress links"; - private static final String msg_list = "list compressed file contents"; - private static final String msg_noname = "do not save or restore the original name and time stamp"; - private static final String msg_name = "save or restore the original name and time stamp"; - private static final String msg_quiet = "suppress all warning"; - private static final String msg_recurse = "operate recursively on directories"; - private static final String msg_suffix = "use suffix SUF on compressed files"; - private static final String msg_test = "test compressed file integrity"; - private static final String msg_verbose = "verbose mode"; - private static final String msg_file = "the files to compress, use stdin if FILE is '-' or no files are listed"; - private final FileArgument ArgFile = new FileArgument("file", Argument.OPTIONAL | Argument.MULTIPLE, msg_file); - private final StringArgument ArgSuffix = new StringArgument("suffix", Argument.OPTIONAL, msg_suffix); - private final FlagArgument ArgStdout = new FlagArgument("stdout", Argument.OPTIONAL, msg_stdout); - private final FlagArgument ArgForce = new FlagArgument("force", Argument.OPTIONAL, msg_force); - private final FlagArgument ArgList = new FlagArgument("list", Argument.OPTIONAL, msg_list); - private final FlagArgument ArgNoname = new FlagArgument("noname", Argument.OPTIONAL, msg_noname); - private final FlagArgument ArgName = new FlagArgument("name", Argument.OPTIONAL, msg_name); - private final FlagArgument ArgQuiet = new FlagArgument("quiet", Argument.OPTIONAL, msg_quiet); - private final FlagArgument ArgRecurse = new FlagArgument("recursive", Argument.OPTIONAL, msg_recurse); - private final FlagArgument ArgTest = new FlagArgument("test", Argument.OPTIONAL, msg_test); - private final FlagArgument ArgVerbose = new FlagArgument("verbose", Argument.OPTIONAL, msg_verbose); - private final FlagArgument ArgDebug = new FlagArgument("debug", Argument.OPTIONAL, " "); - public GUnzipCommand() { super("decompresses files/data"); - registerArguments(ArgFile, ArgSuffix, ArgStdout, ArgForce, ArgList, ArgNoname, ArgName, ArgQuiet, ArgRecurse, - ArgTest, ArgVerbose, ArgDebug); } public void execute() { - if (ArgQuiet.isSet()) { - outMode = 0; - } else { - if (ArgDebug.isSet()) { - outMode |= OUT_DEBUG; - } - if (ArgVerbose.isSet()) { - outMode |= OUT_NOTICE; - } - } - - if (ArgSuffix.isSet()) suffix = ArgSuffix.getValue(); - - if (ArgList.isSet()) mode = GZIP_LIST; - else if (ArgTest.isSet()) mode = GZIP_TEST; - else mode = GZIP_DECOMPRESS; - - try { - execute(ArgFile.getValues(), ArgForce.isSet(), ArgStdout.isSet(), ArgRecurse.isSet()); - } catch (Exception e) { - e.printStackTrace(); - } + compress = false; + super.execute(); } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/GZip.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/GZip.java 2009-03-31 20:21:47 UTC (rev 5201) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/GZip.java 2009-04-01 04:23:57 UTC (rev 5202) @@ -24,10 +24,14 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; -import java.util.ArrayList; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FlagArgument; +import org.jnode.shell.syntax.FileArgument; +import org.jnode.shell.syntax.StringArgument; + /** * * TODO implement test/list @@ -37,140 +41,139 @@ */ public class GZip extends ArchiveCommand { - private static final String msg_exists_prompt = " already exists; do you wish to overwrite (y or n)? "; - private static final String msg_exists_skip = "gzip: skipping file: "; - private static final String msg_err_open = "gzip: Cannot open file: "; - private static final String msg_err_create = "gzip: Cannot create file: "; - private static final String msg_err_bad_suffix = "gzip: Invalid suffix, expecting "; - - private static final int BUFFER_SIZE = 4096; + private static final String help_suffix = "append <suffix> on compressed files"; + private static final String help_list = "list compressed file contents"; + private static final String help_noname = "do not save or restore the original name and time stamp"; + private static final String help_name = "save or restore the original name and time stamp"; + private static final String help_recurse = "operate recursively on directories"; + private static final String help_test = "test compressed file integrity"; + private static final String help_file = "the files to compress, use stdin if FILE is '-' or no files are listed"; - private File[] files; - private InputStream stdinStream; - private OutputStream stdoutStream; + private final FileArgument Files = new FileArgument("files", Argument.OPTIONAL | Argument.MULTIPLE, help_file); + private final FlagArgument List = new FlagArgument("list", Argument.OPTIONAL, help_list); + private final FlagArgument NoName = new FlagArgument("noname", Argument.OPTIONAL, help_noname); + private final FlagArgument Name = new FlagArgument("name", Argument.OPTIONAL, help_name); + private final FlagArgument Recurse = new FlagArgument("recurse", Argument.OPTIONAL, help_recurse); + private final FlagArgument Test = new FlagArgument("test", Argument.OPTIONAL, help_test); + private final StringArgument Suffix = new StringArgument("suffix", Argument.OPTIONAL, help_suffix); - protected static final int GZIP_LIST = 1; - protected static final int GZIP_TEST = 2; - protected static final int GZIP_DECOMPRESS = 3; - protected static final int GZIP_COMPRESS = 4; - protected String suffix = ".gz"; - protected int mode; + protected boolean recurse; protected GZip(String s) { super(s); - createStreamBuffer(BUFFER_SIZE); + registerArguments(Files, List, NoName, Name, Recurse, Test, Suffix); + createStreamBuffer(4096); } - public void execute(File[] files , boolean forced , boolean use_stdout , boolean recurse) throws IOException { - setup(); - stdinStream = getInput().getInputStream(); - stdoutStream = getOutput().getOutputStream(); + public void execute() { + super.execute(); - switch(mode) { - case GZIP_LIST : - list(processFiles(files, recurse)); return; - case GZIP_TEST : - test(processFiles(files, recurse)); return; - case GZIP_COMPRESS : - compress(processFiles(files, recurse), forced, use_stdout); return; - case GZIP_DECOMPRESS : - decompress(processFiles(files, recurse), forced, use_stdout); return; + if (Suffix.isSet()) suffix = Suffix.getValue(); + + recurse = Recurse.isSet(); + + try { + if (compress) { + compress(processFileList(Files.getValues(), recurse)); + } else { + decompress(processFileList(Files.getValues(), recurse)); + } + } catch (IOException e) { + e.printStackTrace(); + fatal(err_exception_uncaught, 1); } } - protected void compress(File[] files , boolean forced , boolean use_stdout) throws IOException { + private void compress(File[] files) throws IOException { InputStream in; OutputStream out = null; GZIPOutputStream gzout = null; - File gzFile = null; + File gzfile = null; float sizeDiff; - debug("Compress"); - debug("forced=" + forced); - debug("use_stdout=" + use_stdout); - if (files == null) { - debug("stdin > stdout"); - processStream(stdinStream, new GZIPOutputStream(stdoutStream, BUFFER_SIZE)); - } else { - if (use_stdout) gzout = new GZIPOutputStream(stdoutStream, BUFFER_SIZE); - if (use_stdout) debug("files > stdout"); - else debug("files > files"); + processStream(stdin, new GZIPOutputStream(stdout, BUFFER_SIZE)); + return; + } - for (File file : files) { - debug(file.getName()); - if (!file.exists()) { - error("File does not exist: " + file.getName()); - continue; - } - if (!use_stdout) { - gzFile = new File(file.getAbsolutePath() + suffix); - if ((out = openFileWrite(gzFile, true, forced)) == null) continue; - gzout = new GZIPOutputStream(out, BUFFER_SIZE); - } - if ((in = openFileRead(file)) == null) continue; - processStream(in, gzout); - if (!use_stdout) { - gzout.finish(); - gzout.close(); - sizeDiff = ((float) gzFile.length() / (float) file.length()) * 100; - notice(file + ":\t" + sizeDiff + "% -- replaced with " + gzFile); - file.delete(); - } - in.close(); + if (use_stdout) { + gzout = new GZIPOutputStream(stdout, BUFFER_SIZE); + } + + for (File file : files) { + if (!use_stdout) { + gzfile = new File(file.getAbsolutePath() + suffix); + if ((out = openFileWrite(gzfile, true, force)) == null) continue; + gzout = new GZIPOutputStream(out, BUFFER_SIZE); } - if (use_stdout) gzout.finish(); + + if (file.getName().equals("-")) { + processStream(stdin, gzout); + continue; + } + + if ((in = openFileRead(file)) == null) { + if (!use_stdout) gzout.close(); + continue; + } + processStream(in, gzout); + + if (!use_stdout) { + gzout.finish(); + gzout.close(); + sizeDiff = ((float) gzfile.length() / (float) file.length()) * 100; + notice(String.format(fmt_size_diff, file, sizeDiff, gzfile)); + file.delete(); + } + in.close(); } + + if (use_stdout) { + gzout.finish(); + gzout.close(); + } } - protected void decompress(File[] files , boolean forced , boolean use_stdout) throws IOException { + private void decompress(File[] files) throws IOException { InputStream in; OutputStream out = null; - String name; File file = null; float sizeDiff; - debug("Decompress"); - debug("forced=" + forced); - debug("use_stdout=" + use_stdout); + if (files == null) { + processStream(new GZIPInputStream(stdin, BUFFER_SIZE), stdout); + return; + } - if (use_stdout) out = stdoutStream; + if (use_stdout) { + out = stdout; + } - if (files == null) { - debug("stdin > stdout"); - processStream(new GZIPInputStream(stdinStream, BUFFER_SIZE), stdoutStream); - } else { - if (use_stdout) debug("files > stdout"); - else debug("files > files"); + for (File gzfile : files) { + if (!use_stdout) { + file = stripSuffix(gzfile); + if ((out = openFileWrite(file, true, force)) == null) continue; + } - for (File gzFile : files) { - debug(gzFile.getName()); - if (!gzFile.exists()) { - error("File not found: " + gzFile); - continue; - } - if (!gzFile.getName().endsWith(suffix)) { - notice("gzip: " + file + ": unknown suffix -- ignored"); - continue; - } - if (!use_stdout) { - name = gzFile.getAbsolutePath(); - name = name.substring(0, name.length() - suffix.length()); - file = new File(name); - if ((out = openFileWrite(file, true, forced)) == null) continue; - } - - if ((in = new GZIPInputStream(openFileRead(gzFile), BUFFER_SIZE)) == null) continue; - processStream(in, out); - in.close(); - if (!use_stdout) { - sizeDiff = ((float) gzFile.length() / (float) file.length()) * 100; - notice(gzFile + ":\t" + sizeDiff + "% -- replaced with " + file); - gzFile.delete(); - out.close(); - } + if (gzfile.getName().equals("-")) { + processStream(new GZIPInputStream(stdin, BUFFER_SIZE), out); + continue; } + + if ((in = new GZIPInputStream(openFileRead(gzfile), BUFFER_SIZE)) == null) { + if (!use_stdout) out.close(); + continue; + } + processStream(in, out); + in.close(); + + if (!use_stdout) { + out.close(); + sizeDiff = ((float) gzfile.length() / (float) file.length()) * 100; + notice(String.format(fmt_size_diff, gzfile, sizeDiff, file)); + gzfile.delete(); + } } } @@ -178,43 +181,16 @@ protected void list(File[] files) {} - private File[] processFiles(File[] files , boolean recurse) { - if (files == null || files.length == 0) return null; + private File stripSuffix(File file) { + String name = file.getAbsolutePath(); - debug("processFiles(files(" + files.length + ")," + recurse + ")"); - - ArrayList<File> _files = new ArrayList<File>(); - - for (File file : files) { - debug(file.getName()); - if (file.getName().equals("-")) { - debug("found stdin"); - return null; - } - if (!file.exists()) { - error("Cannot find file: " + file); - continue; - } - if (file.isDirectory() && recurse) { - debug("searching directory: " + file); - File[] dirList = file.listFiles(); - for (File subFile : dirList) { - debug(subFile.getName()); - if (subFile.isFile()) { - debug(subFile + " added"); - _files.add(subFile); - } - } - } else { - if (file.isFile()) { - debug(file + " added"); - _files.add(file); - } - } + if (!name.endsWith(suffix)) { + notice(name + " unknown suffix -- ignore"); + return null; } - if (_files.size() == 0) return null; - debug("Found " + _files.size() + " files"); - return _files.toArray(files); + name = name.substring(0, name.length() - suffix.length()); + + return new File(name); } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/GZipCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/GZipCommand.java 2009-03-31 20:21:47 UTC (rev 5201) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/GZipCommand.java 2009-04-01 04:23:57 UTC (rev 5202) @@ -21,9 +21,7 @@ package org.jnode.fs.command.archive; import org.jnode.shell.syntax.Argument; -import org.jnode.shell.syntax.FileArgument; import org.jnode.shell.syntax.FlagArgument; -import org.jnode.shell.syntax.StringArgument; /** * Compresses or decompresses data in the gzip format. @@ -38,69 +36,20 @@ */ public class GZipCommand extends GZip { - private static final String msg_stdout = "Write output on standard output, keep original files"; - private static final String msg_decomp = "decompress"; - private static final String msg_force = "force overwrite of output files and compress links"; - private static final String msg_list = "list compressed file contents"; - private static final String msg_noname = "do not save or restore the original name and time stamp"; - private static final String msg_name = "save or restore the original name and time stamp"; - private static final String msg_quiet = "suppress all warning"; - private static final String msg_recurse = "operate recursively on directories"; - private static final String msg_suffix = "use suffix SUF on compressed files"; - private static final String msg_test = "test compressed file integrity"; - private static final String msg_verbose = "verbose mode"; - private static final String msg_fast = "compress faster"; - private static final String msg_best = "compress better"; - private static final String msg_file = "the files to compress, use stdin if FILE is '-' or no files are listed"; + private static final String help_fast = "compress faster"; + private static final String help_best = "compress better"; - private final FileArgument ArgFile = new FileArgument("file", Argument.OPTIONAL | Argument.MULTIPLE, msg_file); - private final StringArgument ArgSuffix = new StringArgument("suffix", Argument.OPTIONAL, msg_suffix); - private final FlagArgument ArgStdout = new FlagArgument("stdout", Argument.OPTIONAL, msg_stdout); - private final FlagArgument ArgDecomp = new FlagArgument("decompress", Argument.OPTIONAL, msg_decomp); - private final FlagArgument ArgForce = new FlagArgument("force", Argument.OPTIONAL, msg_force); - private final FlagArgument ArgList = new FlagArgument("list", Argument.OPTIONAL, msg_list); - private final FlagArgument ArgNoname = new FlagArgument("noname", Argument.OPTIONAL, msg_noname); - private final FlagArgument ArgName = new FlagArgument("name", Argument.OPTIONAL, msg_name); - private final FlagArgument ArgQuiet = new FlagArgument("quiet", Argument.OPTIONAL, msg_quiet); - private final FlagArgument ArgRecurse = new FlagArgument("recursive", Argument.OPTIONAL, msg_recurse); - private final FlagArgument ArgTest = new FlagArgument("test", Argument.OPTIONAL, msg_test); - private final FlagArgument ArgVerbose = new FlagArgument("verbose", Argument.OPTIONAL, msg_verbose); - private final FlagArgument ArgLvl1 = new FlagArgument("lvl1", Argument.OPTIONAL, msg_fast); - private final FlagArgument ArgLvl9 = new FlagArgument("lvl9", Argument.OPTIONAL, msg_best); - private final FlagArgument ArgDebug = new FlagArgument("debug", Argument.OPTIONAL, " "); + private final FlagArgument Decompress = new FlagArgument("decompress", Argument.OPTIONAL, help_decompress); + private final FlagArgument C1 = new FlagArgument("c1", Argument.OPTIONAL, help_fast); + private final FlagArgument C9 = new FlagArgument("c9", Argument.OPTIONAL, help_best); public GZipCommand() { super("compresses and decompresses files/data"); - registerArguments(ArgFile, ArgSuffix, ArgDecomp, ArgNoname, ArgName, ArgStdout, ArgForce, - ArgQuiet, ArgVerbose, ArgLvl1, ArgLvl9, ArgRecurse, ArgTest, ArgList, ArgDebug); + registerArguments(Decompress, C1, C9); } public void execute() { - if (ArgQuiet.isSet()) { - outMode = 0; - } else { - if (ArgDebug.isSet()) { - outMode |= OUT_DEBUG; - } - if (ArgVerbose.isSet()) { - outMode |= OUT_NOTICE; - } - } - - if (ArgSuffix.isSet()) suffix = ArgSuffix.getValue(); - - if (ArgList.isSet()) mode = GZIP_LIST; - else if (ArgTest.isSet()) mode = GZIP_TEST; - else if (ArgDecomp.isSet()) mode = GZIP_DECOMPRESS; - else mode = GZIP_COMPRESS; - - try { - execute(ArgFile.getValues(), ArgForce.isSet(), ArgStdout.isSet(), ArgRecurse.isSet()); - } catch (Exception e) { - e.printStackTrace(); - exit(1); - } + compress = !Decompress.isSet(); + super.execute(); } - - } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/TarCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/TarCommand.java 2009-03-31 20:21:47 UTC (rev 5201) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/TarCommand.java 2009-04-01 04:23:57 UTC (rev 5202) @@ -68,6 +68,8 @@ private static final String help_verify = "verify the archive after writing it"; private static final String help_xfile = "exclude files matching patterns in <file>"; + private static final String err_options = "required options -Acdtrux not found, or multiple options set"; + private static final int TAR_APPEND = 0x01; private static final int TAR_CREATE = 0x02; private static final int TAR_CONCAT = 0x04; @@ -89,21 +91,18 @@ private final FlagArgument Backup = new FlagArgument("backup", Argument.OPTIONAL, help_backup); private final FlagArgument UseBzip = new FlagArgument("bzip", Argument.OPTIONAL, help_bzip); - private final FlagArgument Debug = new FlagArgument("debug", Argument.OPTIONAL, " "); private final FileArgument ChangeDir = new FileArgument("dir", Argument.OPTIONAL, help_dir); private final StringArgument Exclude = new StringArgument("exclude", Argument.OPTIONAL, help_exclude); private final FileArgument Archive = new FileArgument("file", Argument.OPTIONAL, help_file); private final FileArgument FileList = new FileArgument("fileList", Argument.OPTIONAL, help_file_list); private final FlagArgument UseGzip = new FlagArgument("gzip", Argument.OPTIONAL, help_gzip); private final FlagArgument Interact = new FlagArgument("interact", Argument.OPTIONAL, help_interact); - private final FlagArgument KeepFiles = new FlagArgument("keepFiles", Argument.OPTIONAL, help_keep_old); + private final FlagArgument Keep = new FlagArgument("keep", Argument.OPTIONAL, help_keep_old); private final FlagArgument NoRecurse = new FlagArgument("noRecurse", Argument.OPTIONAL, help_norecurse); private final FlagArgument Recurse = new FlagArgument("recurse", Argument.OPTIONAL, help_recurse); private final FlagArgument RemoveFiles = new FlagArgument("removeFiles", Argument.OPTIONAL, help_remove); private final FlagArgument ShowTotals = new FlagArgument("showTotals", Argument.OPTIONAL, help_totals); private final StringArgument Suffix = new StringArgument("suffix", Argument.OPTIONAL, help_suffix); - private final FlagArgument UseStdout = new FlagArgument("useStdout", Argument.OPTIONAL, help_stdout); - private final FlagArgument Verbose = new FlagArgument("verbose", Argument.OPTIONAL, help_verbose); private final FlagArgument Verify = new FlagArgument("verify", Argument.OPTIONAL, help_verify); private final FileArgument ExcludeFile = new FileArgument("xfile", Argument.OPTIONAL, help_xfile); @@ -122,23 +121,20 @@ private boolean gzip; private boolean interact; private boolean verify; - private boolean use_stdout; private boolean showTotals; - private boolean keepOldFiles; + private boolean keep; public TarCommand() { super("Create/Modify/Extract tape archives"); registerArguments(DoAppend, DoConcat, DoCreate, DoDelete, DoDiff, DoExtract, DoList, DoUpdate, - Backup, UseBzip, Debug, ChangeDir, Exclude, Archive, FileList, UseGzip, Interact, - KeepFiles, NoRecurse, Recurse, RemoveFiles, ShowTotals, Suffix, UseStdout, Verbose, - Verify, Paths, ExcludeFile); + Backup, UseBzip, ChangeDir, Exclude, Archive, FileList, UseGzip, Interact, + Keep, NoRecurse, Recurse, RemoveFiles, ShowTotals, Suffix, Verify, Paths, ExcludeFile); } public void execute() { - setup(); + super.execute(); if (!checkMode()) { - error("required options -Acdtrux not found, or multiple options set"); - exit(1); + fatal(err_options, 1); } if (DoAppend.isSet()) mode = TAR_APPEND; else if (DoConcat.isSet()) mode = TAR_CONCAT; @@ -149,9 +145,6 @@ else if (DoList.isSet()) mode = TAR_LIST; else if (DoUpdate.isSet()) mode = TAR_UPDATE; - if (Debug.isSet()) outMode |= OUT_DEBUG; - if (Verbose.isSet()) outMode |= OUT_NOTICE; - if (Suffix.isSet()) suffix = Suffix.getValue(); if (Exclude.isSet()) exclude = Exclude.getValue(); if (ExcludeFile.isSet()) excludeFile = ExcludeFile.getValue(); @@ -162,9 +155,8 @@ gzip = UseGzip.isSet(); interact = Interact.isSet(); verify = Verify.isSet(); - use_stdout = UseStdout.isSet(); showTotals = ShowTotals.isSet(); - keepOldFiles = KeepFiles.isSet(); + keep = Keep.isSet(); recurse = !NoRecurse.isSet(); if (Archive.isSet()) archive = Archive.getValue(); else error("No archive given"); @@ -183,7 +175,7 @@ debug("Recurse: " + recurse); debug("Verify: " + verify); debug("Use StdOut: " + use_stdout); - debug("Keep Old Files: " + keepOldFiles); + debug("Keep Old Files: " + keep); debug("Show Totals: " + showTotals); debug("pipeInOut: " + pipeInOut); @@ -202,7 +194,7 @@ } } catch (Exception e) { e.printStackTrace(); - exit(2); + fatal(err_exception_uncaught, 1); } } @@ -217,8 +209,7 @@ if (mode == TAR_CREATE || (mode == TAR_APPEND && !archive.exists())) createArchive(); if ((out = openFileWrite(archive, false, false)) == null) { - error("Could not open stream: " + archive); - exit(1); + fatal(err_stream_create + archive, 1); } } else { debug("out=stdout"); @@ -250,13 +241,10 @@ TarInputStream tin; File file; + // add support for reading compress archives with gzip/bzip + if (archive != null) { - if (archive.exists()) { - if ((in = openFileRead(archive)) == null) { - exit(1); - } - } else { - error("File does not exist: " + archive); + if ((in = openFileRead(archive)) == null) { exit(1); } } else { @@ -295,10 +283,6 @@ InputStream in = null; TarInputStream tin; - if (archive == null || !archive.exists()) { - error("Cannot find file: " + archive); - exit(1); - } if ((in = openFileRead(archive)) == null) { exit(1); } @@ -316,10 +300,6 @@ TarInputStream tin; File file; - if (archive == null || !archive.exists()) { - error("Cannot find file: " + archive); - exit(1); - } if ((in = openFileRead(archive)) == null) { exit(1); } @@ -348,11 +328,9 @@ if (archive.exists()) { archive.delete(); } - debug("creating archive: " + archive); archive.createNewFile(); } catch (IOException e) { - error("Could not create file: " + archive); - exit(1); + fatal(err_file_create + archive, 1); } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/ZCatCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/ZCatCommand.java 2009-03-31 20:21:47 UTC (rev 5201) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/ZCatCommand.java 2009-04-01 04:23:57 UTC (rev 5202) @@ -20,46 +20,19 @@ package org.jnode.fs.command.archive; -import org.jnode.shell.syntax.Argument; -import org.jnode.shell.syntax.FileArgument; -import org.jnode.shell.syntax.FlagArgument; - /** * Outputs compressed files to standard out. */ public class ZCatCommand extends GZip { - private static final String msg_file = "the files to compress, use stdin if FILE is '-' or no files are listed"; - - private final FileArgument ArgFile = new FileArgument("file", Argument.OPTIONAL | Argument.MULTIPLE, msg_file); - private final FlagArgument ArgDebug = new FlagArgument("debug", Argument.OPTIONAL, " "); - private final FlagArgument ArgVerbose = new FlagArgument("verbose", Argument.OPTIONAL, " "); - private final FlagArgument ArgQuiet = new FlagArgument("quiet", Argument.OPTIONAL, " "); - public ZCatCommand() { super("decompresses files to standard output"); - registerArguments(ArgFile, ArgDebug, ArgVerbose, ArgQuiet); } public void execute() { - if (ArgQuiet.isSet()) { - outMode = 0; - } else { - if (ArgDebug.isSet()) { - outMode |= OUT_DEBUG; - } - if (ArgVerbose.isSet()) { - outMode |= OUT_NOTICE; - } - } - - mode = GZIP_DECOMPRESS; - - try { - execute(ArgFile.getValues(), false, true, false); - } catch (Exception e) { - e.printStackTrace(); - } + use_stdout = true; + compress = false; + super.execute(); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2009-04-01 15:03:34
|
Revision: 5208 http://jnode.svn.sourceforge.net/jnode/?rev=5208&view=rev Author: lsantha Date: 2009-04-01 15:03:30 +0000 (Wed, 01 Apr 2009) Log Message: ----------- 'find' command implementation - by Alexander Kerner Modified Paths: -------------- trunk/fs/descriptors/org.jnode.fs.command.xml Added Paths: ----------- trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java trunk/fs/src/fs/org/jnode/fs/command/FindCommand.java Modified: trunk/fs/descriptors/org.jnode.fs.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.command.xml 2009-04-01 13:44:48 UTC (rev 5207) +++ trunk/fs/descriptors/org.jnode.fs.command.xml 2009-04-01 15:03:30 UTC (rev 5208) @@ -33,6 +33,7 @@ <alias name="touch" class="org.jnode.fs.command.TouchCommand"/> <alias name="hexdump" class="org.jnode.fs.command.HexdumpCommand"/> <alias name="md5sum" class="org.jnode.fs.command.Md5SumCommand"/> + <alias name="find" class="org.jnode.fs.command.FindCommand"/> </extension> <extension point="org.jnode.shell.syntaxes"> @@ -112,6 +113,20 @@ <syntax alias="touch"> <argument argLabel="file" description="touch the given file"/> </syntax> + <syntax alias="find"> + <sequence description="find files or directories"> + <repeat minCount="1"> + <argument argLabel="directory"/> + </repeat> + <optionSet> + <option argLabel="type" longName="type"/> + <option argLabel="maxdepth" longName="maxdepth"/> + <option argLabel="mindepth" longName="mindepth"/> + <option argLabel="name" longName="name"/> + <option argLabel="iname" longName="iname"/> + </optionSet> + </sequence> + </syntax> </extension> <extension point="org.jnode.security.permissions"> Added: trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java (rev 0) +++ trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java 2009-04-01 15:03:30 UTC (rev 5208) @@ -0,0 +1,113 @@ +package org.jnode.fs.command; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; +import java.util.Stack; + +public abstract class AbstractDirectoryWalker { + + private class FileObject { + final File file; + final Long depth; + + FileObject(File file, Long depth) { + this.file = file; + this.depth = depth; + } + } + + private final Stack<FileObject> stack = new Stack<FileObject>(); + private final Set<FileFilter> filters = new HashSet<FileFilter>(); + private volatile boolean cancelled = false; + private volatile Long maxDepth = null; + private volatile Long minDepth = null; + + public synchronized void walk(final File... dirs) throws IOException { + for (File dir : dirs) { + if (dir == null) + throw new IOException("No such directroy " + dir); + dir = dir.getAbsoluteFile(); // to be able to handle relative paths + if (!dir.canRead() || !dir.isDirectory()) { + throw new IOException("Cannot read directroy " + dir); + } + stack.push(new FileObject(dir, 0L)); + while (!cancelled && !stack.isEmpty()) { + go1(stack.pop()); + } + } + } + + private void go1(final FileObject file) throws IOException { + if ((minDepth != null && file.depth < minDepth) || (maxDepth != null && file.depth > maxDepth)) { + // out of boundaries + } else if (!file.file.canRead()) { + // ignore for now + } else if (validFileOrDirectory(file)) { + handleFileOrDir(file); + } else { + // filtered out + } + go2(file); + } + + private void go2(final FileObject file) throws IOException { + final Stack<File> stack = new Stack<File>(); + final File[] content = file.file.listFiles(); + if (content != null) { + for (File f : content) { + if (f.toString().equals(f.getCanonicalPath())) { + stack.push(f); + } else { + // dont follow symlinks + } + } + while (!stack.isEmpty()) { + File tmp = stack.pop(); + // addToStack(stack.pop(), file.depth + 1); + this.stack.push(new FileObject(tmp, file.depth + 1)); + } + } + } + + private void handleFileOrDir(final FileObject file) { + if (file.file.isDirectory()) + handleDir(file.file); + else if (file.file.isFile()) + handleFile(file.file); + else { + // ignore unknown file type + } + } + + private boolean validFileOrDirectory(final FileObject file) { + if (!filters.isEmpty()) + for (FileFilter filter : filters) + if (!filter.accept(file.file)) + return false; + return true; + } + + public void stoppWalking() { + cancelled = true; + } + + public void setMinDepth(Long min) { + minDepth = min; + } + + public void setMaxDepth(Long max) { + maxDepth = max; + } + + public synchronized void addFilter(FileFilter filter) { + filters.add(filter); + } + + public abstract void handleDir(File f); + + public abstract void handleFile(File f); + +} Added: trunk/fs/src/fs/org/jnode/fs/command/FindCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/FindCommand.java (rev 0) +++ trunk/fs/src/fs/org/jnode/fs/command/FindCommand.java 2009-04-01 15:03:30 UTC (rev 5208) @@ -0,0 +1,108 @@ +package org.jnode.fs.command; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.jnode.shell.AbstractCommand; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FileArgument; +import org.jnode.shell.syntax.LongArgument; +import org.jnode.shell.syntax.StringArgument; + +public class FindCommand extends AbstractCommand { + + private class Walker extends AbstractDirectoryWalker { + + @Override + public void handleDir(File f) { + out.println(f); + } + + @Override + public void handleFile(File f) { + out.println(f); + } + + } + + private final StringArgument nameArg = new StringArgument("name", Argument.OPTIONAL); + private final StringArgument inameArg = new StringArgument("iname", Argument.OPTIONAL); + private final LongArgument maxdepthArg = new LongArgument("maxdepth", Argument.OPTIONAL); + private final LongArgument mindepthArg = new LongArgument("mindepth", Argument.OPTIONAL); + private final StringArgument typeArg = new StringArgument("type", Argument.OPTIONAL); + private final FileArgument dirArg = + new FileArgument("directory", Argument.MANDATORY | Argument.EXISTING + | Argument.MULTIPLE); + private PrintWriter out = null; + + public FindCommand() { + super("Find files and directories"); + registerArguments(dirArg, mindepthArg, maxdepthArg, inameArg, nameArg, typeArg); + } + + public static void main(String[] args) throws IOException { + + new FindCommand().execute(); + } + + public void execute() throws IOException { + out = getOutput().getPrintWriter(); + final Walker walker = new Walker(); + + if (maxdepthArg.isSet()) { + walker.setMaxDepth(maxdepthArg.getValue()); + } + + if (mindepthArg.isSet()) { + walker.setMinDepth(mindepthArg.getValue()); + } + + if (nameArg.isSet()) { + final String value = nameArg.getValue(); + walker.addFilter(new FileFilter() { + @Override + public boolean accept(File file) { + Pattern p = Pattern.compile(value); + Matcher m = p.matcher(file.getName()); + return m.matches(); + } + }); + } + + if (inameArg.isSet()) { + final String value = inameArg.getValue(); + walker.addFilter(new FileFilter() { + @Override + public boolean accept(File file) { + Pattern p = Pattern.compile(value, Pattern.CASE_INSENSITIVE); + Matcher m = p.matcher(file.getName()); + return m.matches(); + } + }); + } + + if (typeArg.isSet()) { + final Character value = typeArg.getValue().charAt(0); + if (value.equals(Character.valueOf('f'))) { + walker.addFilter(new FileFilter() { + @Override + public boolean accept(File file) { + return file.isFile(); + } + }); + } else if (value.equals(Character.valueOf('d'))) { + walker.addFilter(new FileFilter() { + @Override + public boolean accept(File file) { + return file.isDirectory(); + } + }); + } + } + walker.walk(dirArg.getValues()); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-04-03 02:05:05
|
Revision: 5211 http://jnode.svn.sourceforge.net/jnode/?rev=5211&view=rev Author: chrisboertien Date: 2009-04-03 02:05:01 +0000 (Fri, 03 Apr 2009) Log Message: ----------- Implemented bzip/gzip for tar as well as other fixes Signed-off-by: Chris Boertien <chr...@gm...> Modified Paths: -------------- trunk/fs/descriptors/org.jnode.fs.command.archive.xml trunk/fs/src/fs/org/jnode/fs/command/archive/TarCommand.java 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 Modified: trunk/fs/descriptors/org.jnode.fs.command.archive.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.command.archive.xml 2009-04-02 19:01:01 UTC (rev 5210) +++ trunk/fs/descriptors/org.jnode.fs.command.archive.xml 2009-04-03 02:05:01 UTC (rev 5211) @@ -31,7 +31,6 @@ </extension> <extension point="org.jnode.shell.syntaxes"> - <syntax alias="tar"> <sequence> <alternatives description="tar operations"> @@ -54,13 +53,15 @@ <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" shortName="k" longName="keep-old-files" /> + <option argLabel="keep_old" shortName="k" longName="keep-old-files" /> + <option argLabel="keep_new" longName="keep-newer-files" /> <option argLabel="noRecurse" longName="no-recursion" /> <option argLabel="recurse" longName="recursion" /> <option argLabel="removeFiles" longName="remove-files" /> <option argLabel="showTotals" longName="totals" /> <option argLabel="suffix" longName="suffix" /> <option argLabel="stdout" shortName="O" longName="to-stdout" /> + <option argLabel="unlink" longName="unlink" /> <option argLabel="verbose" shortName="v" longName="verbose" /> <option argLabel="verify" shortName="W" longName="verify" /> <option argLabel="xfile" shortName="X" longName="exclude-from"/> @@ -198,10 +199,8 @@ <extension point="org.jnode.security.permissions"> <permission class="java.io.FilePermission" name="<<ALL FILES>>" actions="read,write,delete"/> - <permission class="java.net.SocketPermission" name="*:0-" actions="connect,resolve"/> <permission class="java.util.PropertyPermission" name="user.dir" actions="read,write"/> <permission class="java.util.PropertyPermission" name="*" actions="read,write"/> - <permission class="java.net.NetPermission" name="specifyStreamHandler"/> <permission class="java.lang.RuntimePermission" name="modifyThreadGroup"/> <permission class="java.lang.RuntimePermission" name="exitVM"/> <permission class="org.jnode.security.JNodePermission" name="getVmClass"/> Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/TarCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/TarCommand.java 2009-04-02 19:01:01 UTC (rev 5210) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/TarCommand.java 2009-04-03 02:05:01 UTC (rev 5211) @@ -23,6 +23,8 @@ import org.apache.tools.tar.TarEntry; import org.apache.tools.tar.TarInputStream; import org.apache.tools.tar.TarOutputStream; +import org.apache.tools.bzip2.CBZip2InputStream; +import org.apache.tools.bzip2.CBZip2OutputStream; import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.FlagArgument; @@ -36,7 +38,164 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.TreeMap; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +/** + * + * This version of tar has the ability to magically work with compressed archives without being + * told with the -jz flags on the command line. The -jz flags are seen as an override to force tar + * to work with the selected compression method, and fail if it can't do that. + * + * Reading : + * 1) If the -j or -z flags are set, then tar will check for the magic bytes in the header for the + * given compression method. If they are not found, tar will fail. + * 2) If the -j or -z flags are not set, then tar will check for the magic bytes in the header for + * both compression methods. If either are found, tar will wrap the FileInputStream given to TarInputStream + * with a decompression wrapper stream. If neither are found, then tar assumes the archive is an + * uncompressed archive. + * If the archive is being extracted from stdin, and the archive is compressed, then the -j or -z flags + * must be given, or tar will assume it is already uncompressed. + * + * Creating : + * 1) If the -j or -z flags are set, then tar will output a new archive compressed with the given method. + * 2) If the -j or -z flags are not set, then tar will check the file suffix of the new archive. If the suffix + * is either .tbz, .tbz2, .tar.bz or .tar.bz2, then tar will compress with bzip2. If the suffix is .tar.gz + * then tar will compress with gzip. Otherwise an uncompressed archive is created. + * + * Writing : + * 1) If the -j or -z flags are set, then tar will output an archive compressed with the given method. + * 2) If the -j or -z flags are not set, and the original archive was compressed, then the same method will + * be used to recompress the archive. Otherwise the archive will be output uncompressed. + * + * TODO Currently, in order to set the output stream to the last entry of an archive, in order to append new entries, + * we're moving the archive, creating a new archive, and copying the data via streams. A more effecient method + * would be a reverse search of the file looking for the last block to be written too. Blocks are written in + * groups of 20, so it will be relatively fast to find. Once we read the header, we'll know how big the entry is + * and we can position the OutputStream to the first available block. We can't simply append to the end of the + * file because the last block is not necessarily the end of the file. + * This might not be quite so simple though, especially when dealing with compressed archives. Which can't be + * randomly accessed. + * + * TODO Implement a way to check if a file being handled is actually a tar file. The tar input stream will gladly + * read a file that is not a tar archive. This can cause any sort of irrational behavior, especially if the + * data is binary in nature. + * TODO Implement update/delete. + * TODO Implement interactive (global) + * TODO Implement display totals. (global) + * TODO Implement verification (verify) + * FIXME BUG - if extracting an archive given on stdin, and that archive overwrites files on the filesystem + * it will cause openFileWrite() to prompt the user and ask to overwrite, but reading from stdin + * wont come from the console since stdin is attached to a pipe. In this case we will either have + * to default to overwrite or skip. + * TODO When extracting entries, tar needs to strip any leading slashes by default, turning absolute pathnames + * into relative ones. When inserting entries, leading slashes should also be stripped by default. Also + * warn about inserting entries with a '..' prefix, and refuse to extract them. + * TODO Default behavior when extracting is to overwrite. + * TODO Implement exclusion by date, --newer=<date> ignores files with a mod time older than the given date. + * + * TODO Options to implement + * -P --absolute-names [Create, Append, Update] TODO + * Overrides the default behavior of stripping leading slashes while inserting or extracting entries. Will + * also force tar to extract entries prefixed with '..' + * -N --newer [All] TODO + * Limit operating on files to only those that are newer than the given date. If the value starts with a + * / or ., the value is a file, and its mod time should be used. + * --newer-mtime [All] TODO + * Similar to --newer, except it doesn't take into account status changes made to the file, only content + * changes (might not be a difference atm in jnode, so they'll both be the same). + * --atime-preserve [Create, Append, Update, Extract] + * Preserve the access time of the file. (Not important) + * -a --auto-compress [Create] + * When creating an archive, determine the compression type from the archive suffix. We already do this by + * default if no compress flags (j/z) were given. + * --no-auto-compress [Create] TODO + * Turn off the automatic checking of archive suffix to determine compression type. + * --backup [Extract] TODO + * Backup files instead of overwriting them. We currently implement simple backups using a given or default + * suffix. There is also the option of creating numbered backups. And a hybrid option that makes numbered + * backups if they exist already, simple backups if they do not. As well this option can also apply to the + * archive itself if it is being modified. This option gets its default from the VERSION_CONTROL env variable. + * If this is not set, the default is 'existing'. + * Options are 't' | 'numbered', 'nil' | 'existing' and 'never' | 'simple'. + * --suffix [Extract/backup] + * Need to read the SIMPLE_BACKUP_SUFFIX env variable for the default, otherwise use ~ + * --checkpoint n + * Checkpoints are issued every nth recorded that is written or read to/from the archive. + * --checkpoing-action <action> + * Perform one of the following actions every checkpoint + * - bell Produces an audible bell on the system speaker + * - dot prints a '.' to stdout + * - echo Display a message to stderr + * - echo=string Display string to stderr, string is subject to meta-character expansion + * - exec=command Execute the given command + * - sleep=time Sleep for <time> seconds + * - ttyout=string Output string to /dev/tty (the current console, if stderr is redirected) + * This argument may be given multiple times to perform different actions. They will be executed in the + * order found on the command line. + * -l --check-links + * --delay-directory-restore + * --no-delay-directory-restore + * Restore directory timestamps and permissions after extraction has completed. + * -h --dereference + * Store the file a link points to instead of the link itself + * --anchored + * --no-anchored + * --ignore-case + * --no-ignore-case + * --wildcards + * --no-wildcards + * --wildcards-match-slash + * --no-wildcards-match-slash + * Pattern matching modifier + * --ignore-failed-read + * Do not exit just because a read of a file failed. (We do this by default atm) + * --index-file=<file> + * Send verbose output to <file> + * --overwrite + * --overwrite-dir + * Overwrite existing files when extracting (default) + * + * --lzma + * --lzop + * -Z --compress + * Other compression methods, not supported atm. + * + * --pax-option=<list> + * --owner=<name> + * -o --no-same-owner + * --no-same-permissions + * --no-unquote + * --numberic-owner + * --occurence=<number> + * --one-file-system + * --null + * --no-null + * --no-overwrite-dir + * --no-ignore-command-error + * -M --multi-volume + * --no-check-device + * -g --listed-incremental=<file> + * -V --label=<string> + * -F --info-script=<file> + * -G --incremental + * --group + * --owner + * --mode + * --mtime + * -H --format + * --interactive + * -R --block-number + * -b --blocking-factor + * -i --ignore-zeroes + * -B --read-full-records + * --check-device + * (ignore for now) + * + * @author chris boertien + */ public class TarCommand extends ArchiveCommand { private static final String help_append = "append entries to an archive"; @@ -57,6 +216,7 @@ private static final String help_gzip = "compress the archive with gzip"; private static final String help_interact = "ask for confirmation for every action"; private static final String help_keep_old = "keep existing files; don't overwrite from archive"; + private static final String help_keep_new = "keep existing files if they are newer than the archive entry"; private static final String help_norecurse = "do not recurse into directories"; private static final String help_paths = "files and directories to include in archive"; private static final String help_recurse = "recurse into directories"; @@ -64,22 +224,32 @@ private static final String help_stdout = "extract files to stdout"; private static final String help_suffix = "append <suffix> to backup files (default ~)"; private static final String help_totals = "display total bytes written after creating the archive"; + private static final String help_unlink = "when extracting, delete files if they exist"; private static final String help_verbose = "list files processed"; private static final String help_verify = "verify the archive after writing it"; private static final String help_xfile = "exclude files matching patterns in <file>"; private static final String err_options = "required options -Acdtrux not found, or multiple options set"; - private static final int TAR_APPEND = 0x01; - private static final int TAR_CREATE = 0x02; - private static final int TAR_CONCAT = 0x04; - private static final int TAR_DELETE = 0x08; - private static final int TAR_UPDATE = 0x10; - private static final int TAR_LIST = 0x20; - private static final int TAR_DIFF = 0x40; - private static final int TAR_EXTRACT = 0x80; - private static final int TAR_INSERT = TAR_APPEND | TAR_CREATE; + private static final int TAR_APPEND = 0x01; + private static final int TAR_CREATE = 0x02; + private static final int TAR_CONCAT = 0x04; + private static final int TAR_DELETE = 0x08; + private static final int TAR_UPDATE = 0x10; + private static final int TAR_LIST = 0x20; + private static final int TAR_DIFF = 0x40; + private static final int TAR_EXTRACT = 0x80; + private static final int TAR_REQ_ARCH + = TAR_APPEND | TAR_CREATE | TAR_CONCAT | TAR_DELETE | TAR_UPDATE | TAR_LIST | TAR_DIFF; + private static final int TAR_INSERT = TAR_APPEND | TAR_CREATE; + private static final int TAR_VERIFY = TAR_APPEND | TAR_CONCAT | TAR_DELETE | TAR_UPDATE; + private static final int TAR_COMPRESS = TAR_APPEND | TAR_CREATE | TAR_CONCAT | TAR_DELETE | TAR_UPDATE; + private static final int TAR_DECOMPRESS = + TAR_APPEND | TAR_CONCAT | TAR_DELETE | TAR_DIFF | TAR_UPDATE | TAR_LIST | TAR_EXTRACT; + private static final int USE_BZIP = 1; + private static final int USE_GZIP = 2; + private final FlagArgument DoAppend = new FlagArgument("doAppend", Argument.OPTIONAL, help_append); private final FlagArgument DoConcat = new FlagArgument("doConcat", Argument.OPTIONAL, help_concat); private final FlagArgument DoCreate = new FlagArgument("doCreate", Argument.OPTIONAL, help_create); @@ -97,12 +267,14 @@ private final FileArgument FileList = new FileArgument("fileList", Argument.OPTIONAL, help_file_list); private final FlagArgument UseGzip = new FlagArgument("gzip", Argument.OPTIONAL, help_gzip); private final FlagArgument Interact = new FlagArgument("interact", Argument.OPTIONAL, help_interact); - private final FlagArgument Keep = new FlagArgument("keep", Argument.OPTIONAL, help_keep_old); + private final FlagArgument KeepOld = new FlagArgument("keep_old", Argument.OPTIONAL, help_keep_old); + private final FlagArgument KeepNew = new FlagArgument("keep_new", Argument.OPTIONAL, help_keep_new); private final FlagArgument NoRecurse = new FlagArgument("noRecurse", Argument.OPTIONAL, help_norecurse); private final FlagArgument Recurse = new FlagArgument("recurse", Argument.OPTIONAL, help_recurse); private final FlagArgument RemoveFiles = new FlagArgument("removeFiles", Argument.OPTIONAL, help_remove); private final FlagArgument ShowTotals = new FlagArgument("showTotals", Argument.OPTIONAL, help_totals); private final StringArgument Suffix = new StringArgument("suffix", Argument.OPTIONAL, help_suffix); + private final FlagArgument Unlink = new FlagArgument("unlink", Argument.OPTIONAL, help_unlink); private final FlagArgument Verify = new FlagArgument("verify", Argument.OPTIONAL, help_verify); private final FileArgument ExcludeFile = new FileArgument("xfile", Argument.OPTIONAL, help_xfile); @@ -114,6 +286,8 @@ private String suffix = "~"; private String exclude = ""; private int mode; + private int compress; + private int decompress; private boolean recurse; private boolean pipeInOut; private boolean backup; @@ -122,28 +296,23 @@ private boolean interact; private boolean verify; private boolean showTotals; - private boolean keep; + private boolean keepOld; + private boolean keepNew; + private boolean unlink; public TarCommand() { super("Create/Modify/Extract tape archives"); registerArguments(DoAppend, DoConcat, DoCreate, DoDelete, DoDiff, DoExtract, DoList, DoUpdate, - Backup, UseBzip, ChangeDir, Exclude, Archive, FileList, UseGzip, Interact, - Keep, NoRecurse, Recurse, RemoveFiles, ShowTotals, Suffix, Verify, Paths, ExcludeFile); + Backup, UseBzip, ChangeDir, Exclude, Archive, FileList, UseGzip, Interact, KeepNew, Unlink, + KeepOld, NoRecurse, Recurse, RemoveFiles, ShowTotals, Suffix, Verify, Paths, ExcludeFile); } + // TODO Allow working directory to be changed public void execute() { super.execute(); if (!checkMode()) { fatal(err_options, 1); } - if (DoAppend.isSet()) mode = TAR_APPEND; - else if (DoConcat.isSet()) mode = TAR_CONCAT; - else if (DoCreate.isSet()) mode = TAR_CREATE; - else if (DoDelete.isSet()) mode = TAR_DELETE; - else if (DoDiff.isSet()) mode = TAR_DIFF; - else if (DoExtract.isSet()) mode = TAR_EXTRACT; - else if (DoList.isSet()) mode = TAR_LIST; - else if (DoUpdate.isSet()) mode = TAR_UPDATE; if (Suffix.isSet()) suffix = Suffix.getValue(); if (Exclude.isSet()) exclude = Exclude.getValue(); @@ -156,70 +325,158 @@ interact = Interact.isSet(); verify = Verify.isSet(); showTotals = ShowTotals.isSet(); - keep = Keep.isSet(); + keepOld = KeepOld.isSet(); + keepNew = KeepNew.isSet(); recurse = !NoRecurse.isSet(); + unlink = Unlink.isSet(); if (Archive.isSet()) archive = Archive.getValue(); else error("No archive given"); //if (!(pipeInOut = !Archive.isSet())) archive = Archive.getValue(); - debug("Mode: " + mode); - debug("Archive: " + archive); - debug("Suffix: " + suffix); - debug("Exclude: " + exclude); - debug("Exclude File: " + excludeFile); - debug("File List: " + fileList); - debug("Backup: " + backup); - debug("BZip: " + bzip); - debug("GZip: " + gzip); - debug("Interactive: " + interact); - debug("Recurse: " + recurse); - debug("Verify: " + verify); - debug("Use StdOut: " + use_stdout); - debug("Keep Old Files: " + keep); - debug("Show Totals: " + showTotals); - debug("pipeInOut: " + pipeInOut); - try { + if ((mode & TAR_REQ_ARCH) != 0 && archive == null) { + fatal("Archive required for -Acdtru", 1); + } + + if ((mode & TAR_DECOMPRESS) != 0 && archive != null) { + if (checkCompressed(archive) == -1) { + // happens when -j or -z were specified, but the archive is not + // in the given format. + if (bzip) { + fatal("Archive is not compressed with bzip2.", 1); + } + if (gzip) { + fatal("Archive is not compressed with gzip.", 1); + } + fatal("Internal Error: checkCompressed() returned -1", -1); + } + } + + if ((mode & TAR_COMPRESS) != 0) { + if (bzip) { + compress = USE_BZIP; + } else if (gzip) { + compress = USE_GZIP; + } else { + compress = decompress; + } + } + + if ((mode & TAR_VERIFY) != 0 && verify) { + // backup original archive + } + + if ((mode & TAR_CREATE) != 0 && compress == 0) { + compress = checkSuffix(archive); + } + if ((mode & TAR_INSERT) != 0) { - File[] files; - files = processFiles(Paths.getValues(), recurse); - insert(files); - return; + insert(processFiles(Paths.getValues(), recurse)); } + + if ((mode & TAR_UPDATE) != 0) { + update(processFiles(Paths.getValues(), recurse)); + } + + if ((mode & TAR_CONCAT) != 0) { + concat(processArchives(Paths.getValues())); + } + + if ((mode & TAR_DELETE) != 0) { + //delete(); + } + if ((mode & TAR_EXTRACT) != 0) { + if (decompress == 0 && archive == null) { + if (bzip) { + decompress = USE_BZIP; + } else if (gzip) { + decompress = USE_GZIP; + } + } extract(); } + if ((mode & TAR_LIST) != 0) { list(); } + + if ((mode & TAR_DIFF) != 0) { + diff(); + } } catch (Exception e) { e.printStackTrace(); fatal(err_exception_uncaught, 1); } } + /** + * Concatenates a list of archives with this archive. + * + * TODO If the verify option is set, the original archive is backed up before operating + * on it, and verified before exiting. If the archive is bad, the original is restored. + */ + private void concat(File[] archives) throws IOException { + InputStream in; + OutputStream out; + TarInputStream tin; + TarOutputStream tout; + File tmpArchive; + + // Setup archive for appending + tout = appendTarOutputStream(); + + // Concatenate new archives + for(File arch : archives) { + if ((in = openFileRead(arch)) == null) { + continue; + } + bzip = gzip = false; + decompress = checkCompressed(arch); + if (decompress != 0) { + in = wrapInputStream(in); + } + tin = new TarInputStream(in); + copy(tin, tout); + } + tout.close(); + } + + /** + * Insert a list of files into an archive. + * + * This is used by Create and Append to insert new entries into the archive. + * + * TODO Allow files to be delete from the filesystem after the archive has been written. + * If the verify option is set, then the archive must pass verification before the + * files are deleted. + * + * TODO If the verify option is set, the original archive is backed up before operating + * on it, and verified before exiting. If the archive is bad, the original is restored. + */ private void insert(File[] files) throws IOException { - debug("insert"); InputStream in; OutputStream out; - TarOutputStream tout; + TarOutputStream tout = null; TarEntry entry; + File tmpArchive = null; - if (!use_stdout) { - if (mode == TAR_CREATE || (mode == TAR_APPEND && !archive.exists())) createArchive(); - + if (mode == TAR_APPEND && archive.exists()) { + tout = appendTarOutputStream(); + } else { + createArchive(); if ((out = openFileWrite(archive, false, false)) == null) { - fatal(err_stream_create + archive, 1); + fatal(" ", 1); } - } else { - debug("out=stdout"); - out = getOutput().getOutputStream(); + if (compress != 0) { + out = wrapOutputStream(out); + } + tout = new TarOutputStream(out); } - tout = new TarOutputStream(out); - debug("begin"); + // Insert new entries for (File file : files) { - notice(file.getName()); + notice(file.getPath()); entry = new TarEntry(file); tout.putNextEntry(entry); @@ -231,9 +488,56 @@ tout.closeEntry(); } tout.close(); - debug("end"); } + // TODO + private void update(File[] files) throws IOException { + InputStream in; + TarInputStream tin; + TarEntry entry; + TreeMap<String,Long> entries = new TreeMap(); + + if ((in = openFileRead(archive)) == null) { + fatal(" ", 1); + } + if (decompress != 0) { + in = wrapInputStream(in); + } + + tin = new TarInputStream(in); + + while ((entry = tin.getNextEntry()) != null) { + entries.put(entry.getName(), entry.getModTime().getTime()); + } + tin.close(); + + long etime, ftime; + ArrayList<File> list = new ArrayList<File>(); + for (File file : files) { + if (entries.containsKey(file.getPath())) { + etime = entries.get(file.getPath()).longValue(); + ftime = file.lastModified(); + if (etime >= ftime) { + continue; + } + } + list.add(file); + } + + insert(list.toArray(files)); + } + + // TODO + private void delete(String[] names) throws IOException { + } + + /** + * Extract entries from an archive. + * + * TODO Need to parse Path for choosing specific files/directories either by direct naming + * or by wildcard patterns. + * TODO Read list of entries to extract from FileList if its set. + */ private void extract() throws IOException { TarEntry entry; InputStream in = null; @@ -241,24 +545,23 @@ TarInputStream tin; File file; - // add support for reading compress archives with gzip/bzip - if (archive != null) { if ((in = openFileRead(archive)) == null) { - exit(1); + fatal(" ", 1); } } else { - in = getInput().getInputStream(); + in = stdin; } + if (decompress != 0) { + in = wrapInputStream(in); + } tin = new TarInputStream(in); if (use_stdout) { - debug("out=stdout"); - out = getOutput().getOutputStream(); + out = stdout; } - debug("begin"); while ((entry = tin.getNextEntry()) != null) { notice(entry.getName()); file = new File(entry.getName()); @@ -267,26 +570,43 @@ file.mkdirs(); } continue; + } else { + if (file.exists()) { + if (keepOld || (keepNew && (file.lastModified() >= entry.getModTime().getTime()))) { + continue; + } + if (backup) { + file.renameTo(new File(file.getPath() + suffix)); + } + } } - if ((out = openFileWrite(file, true, false)) == null) { + if ((out = openFileWrite(file, true, true)) == null) { continue; } tin.copyEntryContents(out); out.close(); } tin.close(); - debug("end"); } + /** + * List the contents of an archive. + * + * TODO Need to parse Path for choosing specific files/directories either by direct naming + * or by wildcard patterns. + */ private void list() throws IOException { TarEntry entry; InputStream in = null; TarInputStream tin; if ((in = openFileRead(archive)) == null) { - exit(1); + fatal(" ", 1); } + if (decompress != 0) { + in = wrapInputStream(in); + } tin = new TarInputStream(in); while ((entry = tin.getNextEntry()) != null) { @@ -294,6 +614,9 @@ } } + /** + * Outputs the differences found between the archive and the file system. + */ private void diff() throws IOException { TarEntry entry; InputStream in = null; @@ -304,6 +627,9 @@ exit(1); } + if (decompress != 0) { + in = wrapInputStream(in); + } tin = new TarInputStream(in); while ((entry = tin.getNextEntry()) != null) { @@ -311,29 +637,98 @@ if (!file.exists()) { out(file + ": Warning: No such file or directory"); + continue; } if (file.lastModified() != entry.getModTime().getTime()) { - out(file + ": Mod time differs"); + out(file + ": Mod time is different"); } if (file.length() != entry.getSize()) { - out(file + ": Size differs"); + out(file + ": Size is different"); } + + // TODO check file mode + // TODO check file ownership } } + /** + * Copies an archive to another archive. + * + * This is used to set an output stream into position for appending new entries, + * and to copy entries from another archive into another archive. + * + * FIXME does not verify that tin is actually a tar archive (Concat) + */ + private void copy(TarInputStream tin, TarOutputStream tout) throws IOException { + TarEntry entry; + while ((entry = tin.getNextEntry()) != null) { + tout.putNextEntry(entry); + tin.copyEntryContents(tout); + tout.closeEntry(); + } + tin.close(); + } + + /** + * Sets up a TarOutputStream suitable for appending new entries. + */ + private TarOutputStream appendTarOutputStream() throws IOException { + OutputStream out; + InputStream in; + TarOutputStream tout; + TarInputStream tin; + File tmpArchive; + + tmpArchive = archive.getAbsoluteFile(); + tmpArchive.renameTo(new File(archive.getName() + ".tmp")); + + createArchive(); + + if ((out = openFileWrite(archive, false, false)) == null) { + fatal(" ", 1); + } + if (compress != 0) { + out = wrapOutputStream(out); + } + tout = new TarOutputStream(out); + + if ((in = openFileRead(tmpArchive)) == null) { + fatal(" ", 1); + } + if (decompress != 0) { + in = wrapInputStream(in); + } + tin = new TarInputStream(in); + copy(tin, tout); + tmpArchive.delete(); + + return tout; + } + + /** + * Creates a file for an archive, deleting it first if it already exists. + */ private void createArchive() { try { if (archive.exists()) { archive.delete(); } - archive.createNewFile(); + if (!archive.createNewFile()) { + throw new IOException(); + } } catch (IOException e) { fatal(err_file_create + archive, 1); } } + /** + * Processes a list of files and directories given on the command line + * in order to generate a list of files for Append, Create and Update. + * + * TODO Add parsing of FileList and exclusion filtering. + */ private File[] processFiles(File[] files , boolean recurse) { // FIXME object pollution ArrayList<File> _files = new ArrayList<File>(); @@ -359,16 +754,128 @@ return _files.toArray(files); } + // TODO Need to check that the list of files are actually archives or compressed archives. + private File[] processArchives(File[] files) { + return files; + } + + /** + * Wraps an InputStream with a decompression stream for reading compressed archives. + */ + private InputStream wrapInputStream( InputStream in ) throws IOException { + if (decompress == USE_BZIP) { + return new CBZip2InputStream(in); + } + if (decompress == USE_GZIP) { + return new GZIPInputStream(in, BUFFER_SIZE); + } + + fatal("Internal Error: Unknown compress type", -1); + return null; + } + + /** + * Wraps an OutputStream with a compression stream for writing compressed archives. + */ + private OutputStream wrapOutputStream( OutputStream out ) throws IOException { + if (compress == USE_BZIP) { + return new CBZip2OutputStream(out); + } + if (compress == USE_GZIP) { + return new GZIPOutputStream(out); + } + + fatal("Internal Error: Unknown decompress type", -1); + return null; + } + + /** + * Used by create to determine if the archive should be compressed even if the -j or -z flags + * were not given. + */ + private int checkSuffix(File file) { + String name = file.getName(); + if (name.endsWith(".tbz") || name.endsWith(".tbz2") || name.endsWith(".tar.bz") || name.endsWith(".tar.bz2")) { + return USE_BZIP; + } + if (name.endsWith(".tar.gz")) { + return USE_GZIP; + } + return 0; + } + + /** + * Check via the file header the type of compression used to create it. + */ + private int checkCompressed(File file) throws IOException { + if (bzip) { + return checkBZipMagic(file) ? USE_BZIP : -1; + } + if (gzip) { + return checkGZipMagic(file) ? USE_GZIP : -1; + } + /* + if (checkBZipMagic(file)) { + return USE_BZIP; + } + if (checkGZipMagic(file)) { + return USE_GZIP; + } + */ + return 0; + } + + // TODO + private boolean checkBZipMagic(File file) throws IOException { + return true; + } + + // TODO + private boolean checkGZipMagic(File file) throws IOException { + return true; + } + + /** + * Checks which operational mode was selected. + * + * If no mode was selected, or more than one mode was selected, the return + * value will be false, otherwise the return value is true, and this.mode will + * be set with the selected mode. + */ private boolean checkMode() { int check = 0; - if (DoAppend.isSet()) check++; - if (DoCreate.isSet()) check++; - if (DoConcat.isSet()) check++; - if (DoDelete.isSet()) check++; - if (DoDiff.isSet()) check++; - if (DoExtract.isSet()) check++; - if (DoList.isSet()) check++; - if (DoUpdate.isSet()) check++; + if (DoAppend.isSet()) { + mode = TAR_APPEND; + check++; + } + if (DoCreate.isSet()) { + mode = TAR_CREATE; + check++; + } + if (DoConcat.isSet()) { + mode = TAR_CONCAT; + check++; + } + if (DoDelete.isSet()) { + mode = TAR_DELETE; + check++; + } + if (DoDiff.isSet()) { + mode = TAR_DIFF; + check++; + } + if (DoExtract.isSet()) { + mode = TAR_EXTRACT; + check++; + } + if (DoList.isSet()) { + mode = TAR_LIST; + check++; + } + if (DoUpdate.isSet()) { + mode = TAR_UPDATE; + check++; + } return check == 1; } } 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-02 19:01:01 UTC (rev 5210) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/UnzipCommand.java 2009-04-03 02:05:01 UTC (rev 5211) @@ -37,6 +37,6 @@ } public void execute() { - //setup(); + super.execute(); } } 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-02 19:01:01 UTC (rev 5210) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java 2009-04-03 02:05:01 UTC (rev 5211) @@ -36,23 +36,6 @@ public class Zip extends ArchiveCommand { - private static final int BUFFER_SIZE = 4096; - - private static final int V_DEBUG = 10; - private static final int V_NOTICE = 1; - private static final int V_WARN = 0; - private static final int V_ERROR = -1; - - /* ZIP_DELETE searches the archive for matching entries and removes them - * ZIP_EXTRACT dumps the contents of the zip archive to the file system - * ZIP_ADD searches the filesystem for matching filenames and adds them to the archive - * ZIP_MOVE searches the filesystem for matching filesnames and adds them to the archive, deleting the original - * files when the archive is created. - * ZIP_REFRESH searches the archive for matching entries, then searches the filesystem for files that match - * the entries that have a more recent mod time. If there are any they replace that entry in the archive. - * ZIP_UPDATE searches the filesystem for matching filesnames, adds them if they dont already exist, if they do - * exist, replace only if the filesystem mod time is more recent - */ private static final int ZIP_DELETE = 1; private static final int ZIP_REFRESH = 2; private static final int ZIP_MOVE = 3; @@ -60,98 +43,19 @@ private static final int ZIP_UPDATE = 5; private static final int ZIP_EXTRACT = 6; - private File zfile; - private File tmpFile; - private ZipOutputStream zout; + private File archive; private int mode; - private int verbosity = 0; public Zip(String s) { super(s); } - /* - Zip( File zfile , CommandInput stdin , CommandOutput stdout , CommandOutput stderr ) { - inr = stdin.getReader(); - outw = stdout.getPrintWriter(); - errw = stderr.getPrintWriter(); - this.zfile = zfile; - } - void add( String[] files ) throws IOException { - setupOutputStream(); - // if the zip file already exists we have to copy the entries into the out stream, unless - // one of the given files matches an entry. If so, then either ask the user to overwrite - // or if this is an update operation, then check the mod times. - - File file; - ZipEntry entry; - InputStream in; - - for(String name : files) { - file = new File(name); - if(!file.exists()) { - error(file+" does not exist."); - continue; - } - if((in = new FileInputStream(file)) == null) { - error("Could not open stream"); - continue; - } - - entry = new ZipEntry(name); - zout.putNextEntry(entry); - processStream(in,zout); - zout.closeEntry(); - } - zout.finish(); - zout.close(); + public void execute() { + super.execute(); } void extract() throws IOException { - if(!zfile.exists()) { - error("Cannot find file: "+zfile); - return; - } - ZipFile archive = new ZipFile(zfile); - Enumeration<? extends ZipEntry> entries = archive.entries(); - ZipEntry entry; - File file; - InputStream in; - OutputStream out; - - while(entries.hasMoreElements()) { - entry = entries.nextElement(); - file = new File(entry.getName()); - if(file.exists()) { - if(prompt_yn(file+" exists. Overwrite? ")) { - file.delete(); - } else { - continue; - } - } - file.createNewFile(); - out = new FileOutputStream(file); - in = archive.getInputStream(entry); - if(in == null || out == null) { - error("Could not open streams"); - continue; - } - processStream(in,out); - in.close(); - out.close(); - } } - - void close() throws IOException { - zout.close(); - } - - private void setupOutputStream() throws IOException { - tmpFile = new File(zfile.getName()+".tmp"); - tmpFile.createNewFile(); - zout = new ZipOutputStream( new FileOutputStream(tmpFile) ); - } - */ } 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-02 19:01:01 UTC (rev 5210) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java 2009-04-03 02:05:01 UTC (rev 5211) @@ -52,6 +52,6 @@ } public void execute() { - //setup(); + super.execute(); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-04-04 08:46:49
|
Revision: 5213 http://jnode.svn.sourceforge.net/jnode/?rev=5213&view=rev Author: chrisboertien Date: 2009-04-04 08:46:39 +0000 (Sat, 04 Apr 2009) Log Message: ----------- Fixed help issues with archive commands Signed-off-by: Chris <chr...@gm...> Modified Paths: -------------- trunk/fs/descriptors/org.jnode.fs.command.archive.xml trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/BUnzipCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/BZip.java trunk/fs/src/fs/org/jnode/fs/command/archive/BZipCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/GUnzipCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/GZip.java trunk/fs/src/fs/org/jnode/fs/command/archive/GZipCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/TarCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/UnzipCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/ZCatCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java Modified: trunk/fs/descriptors/org.jnode.fs.command.archive.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.command.archive.xml 2009-04-03 05:36:41 UTC (rev 5212) +++ trunk/fs/descriptors/org.jnode.fs.command.archive.xml 2009-04-04 08:46:39 UTC (rev 5213) @@ -33,7 +33,8 @@ <extension point="org.jnode.shell.syntaxes"> <syntax alias="tar"> <sequence> - <alternatives description="tar operations"> + <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" /> @@ -42,29 +43,31 @@ <option argLabel="doExtract" shortName="x" longName="extract" /> <option argLabel="doList" shortName="t" longName="list" /> <option argLabel="doUpdate" shortName="u" longName="update" /> - </alternatives> - <optionSet description="tar options"> + <!-- Tar Global Options --> + <option argLabel="archive" shortName="f" longName="file" /> <option argLabel="backup" longName="backup" /> <option argLabel="bzip" shortName="j" longName="bzip2" /> - <option argLabel="debug" longName="debug" /> - <option argLabel="dir" shortName="C" longName="directory" /> - <option argLabel="exclude" longName="exclude" label="pattern" /> - <option argLabel="file" shortName="f" longName="file" /> <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="noRecurse" longName="no-recursion" /> - <option argLabel="recurse" longName="recursion" /> <option argLabel="removeFiles" longName="remove-files" /> <option argLabel="showTotals" longName="totals" /> <option argLabel="suffix" longName="suffix" /> - <option argLabel="stdout" shortName="O" longName="to-stdout" /> <option argLabel="unlink" longName="unlink" /> - <option argLabel="verbose" shortName="v" longName="verbose" /> <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" /> + <!-- ArchiveCommand --> + <option argLabel="verbose" shortName="v" longName="verbose" /> + <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" /> @@ -79,19 +82,22 @@ <empty description="compress standard input to standard output" /> <sequence description="compress files"> <optionSet> + <!-- GZipCommand --> + <option argLabel="c1" shortName="1" longName="fast" /> + <option argLabel="c9" shortName="9" longName="best" /> <option argLabel="decompress" shortName="d" longName="decompress" /> + <!-- GZip --> + <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" /> + <!-- 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="c1" shortName="1" longName="fast" /> <option argLabel="debug" longName="debug" /> - <option argLabel="recurse" shortName="r" longName="recursive" /> - <option argLabel="test" shortName="t" longName="test" /> - <option argLabel="list" shortName="l" longName="list" /> - <option argLabel="c9" shortName="9" longName="best" /> </optionSet> <optional eager="true"><option argLabel="suffix" shortName="S" longName="suffix" /></optional> <repeat minCount="1"> @@ -103,16 +109,18 @@ <empty description="decompress standard input to standard output" /> <sequence description="decompress files"> <optionSet> - <option argLabel="debug" longName="debug" /> - <option argLabel="recurse" shortName="r" longName="recursive" /> + <!-- GZip --> <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" /> + <!-- 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="debug" longName="debug" /> </optionSet> <optional eager="true"><option argLabel="suffix" shortName="S" longName="suffix" /></optional> <repeat minCount="1"> @@ -122,16 +130,9 @@ </syntax> <syntax alias="zcat"> <empty description="decompress standard input to standard output" /> - <sequence description="decompress files to standard output"> - <optionSet> - <option argLabel="quiet" shortName="q" longName="quiet" /> - <option argLabel="verbose" shortName="v" longName="verbose" /> - <option argLabel="debug" longName="debug" /> - </optionSet> - <repeat minCount="1"> - <argument argLabel="files" /> - </repeat> - </sequence> + <repeat minCount="1"> + <argument argLabel="files" /> + </repeat> </syntax> <syntax alias="zip"> </syntax> @@ -141,16 +142,7 @@ <empty description="compress stdin to stdout" /> <sequence description="compress files"> <optionSet> - <option argLabel="stdout" shortName="c" longName="stdout" /> - <option argLabel="decompress" shortName="d" longName="decompress" /> - <option argLabel="compress" shortName="z" longName="compress" /> - <option argLabel="test" shortName="t" longName="test" /> - <option argLabel="force" shortName="f" longName="force" /> - <option argLabel="keep" shortName="k" longName="keep" /> - <option argLabel="small" shortName="s" longName="small" /> - <option argLabel="verbose" shortName="v" longName="verbose" /> - <option argLabel="quiet" shortName="q" longName="quiet" /> - <option argLabel="debug" longName="debug" /> + <!-- BZipCommand --> <option argLabel="c1" shortName="1" longName="fast" /> <option argLabel="c2" shortName="2" /> <option argLabel="c3" shortName="3" /> @@ -160,6 +152,18 @@ <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" /> + <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" /> </optionSet> <repeat> <argument argLabel="files" /> @@ -170,11 +174,15 @@ <empty description="decompress stdin to stdout" /> <sequence description="decompress files"> <optionSet> - <option argLabel="stdout" shortName="c" longName="stdout" /> + <!-- BZip --> + <option argLabel="compress" shortName="z" longName="compress"/> + <option argLabel="decompress" shortName="d" longName="decompress"/> <option argLabel="test" shortName="t" longName="test" /> - <option argLabel="force" shortName="f" longName="force" /> <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" /> Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java 2009-04-03 05:36:41 UTC (rev 5212) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java 2009-04-04 08:46:39 UTC (rev 5213) @@ -86,29 +86,28 @@ protected ArchiveCommand(String s) { super(s); - registerArguments(Quiet, Verbose, Debug, Stdout, Force); } - public void execute() { + public void execute(String command) { stdoutWriter = getOutput().getPrintWriter(); stderrWriter = getError().getPrintWriter(); stdinReader = getInput().getReader(); stdin = getInput().getInputStream(); stdout = getOutput().getOutputStream(); - if (Quiet.isSet()) { - outMode = 0; - } else { - if (Verbose.isSet()) { - outMode |= OUT_NOTICE; - } - if (Debug.isSet()) { - outMode |= OUT_DEBUG; - } + if (command.equals("zcat") || command.equals("bzcat")) return; + + if (!command.equals("tar")) { + if (Quiet.isSet()) outMode = 0; + force = Force.isSet(); } if (!use_stdout) use_stdout = Stdout.isSet(); - force = Force.isSet(); + + if (outMode != 0) { + if (Verbose.isSet()) outMode |= OUT_NOTICE; + if (Debug.isSet()) outMode |= OUT_DEBUG; + } } protected void createStreamBuffer(int size) { Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/BUnzipCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/BUnzipCommand.java 2009-04-03 05:36:41 UTC (rev 5212) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/BUnzipCommand.java 2009-04-04 08:46:39 UTC (rev 5213) @@ -24,11 +24,14 @@ public BUnzipCommand() { super("decompresses data in bzip2 format"); - registerArguments(); + // from ArchiveCommand + registerArguments(Quiet, Verbose, Stdout, Force, Debug); + // from BZip + registerArguments(Compress, Decompress, Files, Keep, Small, Test); } public void execute() { compress = false; - super.execute(); + super.execute("bunzip2"); } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/BZip.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/BZip.java 2009-04-03 05:36:41 UTC (rev 5212) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/BZip.java 2009-04-04 08:46:39 UTC (rev 5213) @@ -53,29 +53,33 @@ protected final FlagArgument Small = new FlagArgument("small", Argument.OPTIONAL, help_small); protected final FlagArgument Test = new FlagArgument("test", Argument.OPTIONAL, help_test); - protected int clevel = 9; + protected int clevel; protected boolean keep; + protected boolean small; public BZip(String s) { super(s); - registerArguments(Compress, Decompress, Files, Keep, Small, Test); createStreamBuffer(4096); } - public void execute() { - super.execute(); + public void execute(String command) { + super.execute(command); - if (compress && Decompress.isSet()) { - compress = false; - } - if (!compress && Compress.isSet()) { - compress = true; - } + small = Small.isSet(); - keep = Keep.isSet(); - - if (!keep && use_stdout) { - keep = true; + if (!command.equals("bzcat")) { + if (compress && Decompress.isSet()) { + compress = false; + } + if (!compress && Compress.isSet()) { + compress = true; + } + + keep = Keep.isSet(); + + if (!keep && use_stdout) { + keep = true; + } } try { Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/BZipCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/BZipCommand.java 2009-04-03 05:36:41 UTC (rev 5212) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/BZipCommand.java 2009-04-04 08:46:39 UTC (rev 5213) @@ -40,11 +40,26 @@ public BZipCommand() { super("compresses data with bzip2"); + // from ArchiveCommand + registerArguments(Quiet, Verbose, Stdout, Force, Debug); + // from BZip + registerArguments(Compress, Decompress, Files, Keep, Small, Test); registerArguments(C1, C2, C3, C4, C5, C6, C7, C8, C9); } public void execute() { compress = true; - super.execute(); + if (C1.isSet()) clevel = 1; + if (C2.isSet()) clevel = 2; + if (C3.isSet()) clevel = 3; + if (C4.isSet()) clevel = 4; + if (C5.isSet()) clevel = 5; + if (C6.isSet()) clevel = 6; + if (C7.isSet()) clevel = 7; + if (C8.isSet()) clevel = 8; + if (C9.isSet()) clevel = 9; + else clevel = 6; + + super.execute("bzip2"); } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/GUnzipCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/GUnzipCommand.java 2009-04-03 05:36:41 UTC (rev 5212) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/GUnzipCommand.java 2009-04-04 08:46:39 UTC (rev 5213) @@ -36,10 +36,14 @@ public GUnzipCommand() { super("decompresses files/data"); + // from ArchiveCommand + registerArguments(Quiet, Verbose, Debug, Force, Stdout); + // from GZip + registerArguments(Files, List, NoName, Name, Recurse, Test, Suffix); } public void execute() { compress = false; - super.execute(); + super.execute("gunzip"); } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/GZip.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/GZip.java 2009-04-03 05:36:41 UTC (rev 5212) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/GZip.java 2009-04-04 08:46:39 UTC (rev 5213) @@ -49,29 +49,30 @@ private static final String help_test = "test compressed file integrity"; private static final String help_file = "the files to compress, use stdin if FILE is '-' or no files are listed"; - private final FileArgument Files = new FileArgument("files", Argument.OPTIONAL | Argument.MULTIPLE, help_file); - private final FlagArgument List = new FlagArgument("list", Argument.OPTIONAL, help_list); - private final FlagArgument NoName = new FlagArgument("noname", Argument.OPTIONAL, help_noname); - private final FlagArgument Name = new FlagArgument("name", Argument.OPTIONAL, help_name); - private final FlagArgument Recurse = new FlagArgument("recurse", Argument.OPTIONAL, help_recurse); - private final FlagArgument Test = new FlagArgument("test", Argument.OPTIONAL, help_test); - private final StringArgument Suffix = new StringArgument("suffix", Argument.OPTIONAL, help_suffix); + protected final FileArgument Files = new FileArgument("files", Argument.OPTIONAL | Argument.MULTIPLE, help_file); + protected final FlagArgument List = new FlagArgument("list", Argument.OPTIONAL, help_list); + protected final FlagArgument NoName = new FlagArgument("noname", Argument.OPTIONAL, help_noname); + protected final FlagArgument Name = new FlagArgument("name", Argument.OPTIONAL, help_name); + protected final FlagArgument Recurse = new FlagArgument("recurse", Argument.OPTIONAL, help_recurse); + protected final FlagArgument Test = new FlagArgument("test", Argument.OPTIONAL, help_test); + protected final StringArgument Suffix = new StringArgument("suffix", Argument.OPTIONAL, help_suffix); protected String suffix = ".gz"; protected boolean recurse; protected GZip(String s) { super(s); - registerArguments(Files, List, NoName, Name, Recurse, Test, Suffix); createStreamBuffer(4096); } - public void execute() { - super.execute(); + public void execute(String command) { + super.execute(command); - if (Suffix.isSet()) suffix = Suffix.getValue(); + if (!command.equals("zcat")) { + if (Suffix.isSet()) suffix = Suffix.getValue(); - recurse = Recurse.isSet(); + recurse = Recurse.isSet(); + } try { if (compress) { Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/GZipCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/GZipCommand.java 2009-04-03 05:36:41 UTC (rev 5212) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/GZipCommand.java 2009-04-04 08:46:39 UTC (rev 5213) @@ -45,11 +45,15 @@ public GZipCommand() { super("compresses and decompresses files/data"); + // from ArchiveCommand + registerArguments(Quiet, Verbose, Debug, Force, Stdout); + // from GZip + registerArguments(Files, List, NoName, Name, Recurse, Test, Suffix); registerArguments(Decompress, C1, C9); } public void execute() { compress = !Decompress.isSet(); - super.execute(); + super.execute("gzip"); } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/TarCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/TarCommand.java 2009-04-03 05:36:41 UTC (rev 5212) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/TarCommand.java 2009-04-04 08:46:39 UTC (rev 5213) @@ -207,11 +207,11 @@ private static final String help_list = "list the contents of an archive"; private static final String help_update = "only append files that are newer than the copy in the archive"; + private static final String help_archive = "use the given archive"; private static final String help_backup = "backup files instead of overwriting"; private static final String help_bzip = "compress the archive with bzip2"; private static final String help_dir = "change to directory"; private static final String help_exclude = "exclude files matching <pattern>"; - private static final String help_file = "use the given archive"; private static final String help_file_list = "get names to extract or archive from <file>"; private static final String help_gzip = "compress the archive with gzip"; private static final String help_interact = "ask for confirmation for every action"; @@ -224,7 +224,8 @@ private static final String help_stdout = "extract files to stdout"; private static final String help_suffix = "append <suffix> to backup files (default ~)"; private static final String help_totals = "display total bytes written after creating the archive"; - private static final String help_unlink = "when extracting, delete files if they exist"; + private static final String help_unlink = "when extracting, delete files if they exist. This is the default" + + "action and is used to override other options if they were set"; private static final String help_verbose = "list files processed"; private static final String help_verify = "verify the archive after writing it"; private static final String help_xfile = "exclude files matching patterns in <file>"; @@ -263,7 +264,7 @@ private final FlagArgument UseBzip = new FlagArgument("bzip", Argument.OPTIONAL, help_bzip); private final FileArgument ChangeDir = new FileArgument("dir", Argument.OPTIONAL, help_dir); private final StringArgument Exclude = new StringArgument("exclude", Argument.OPTIONAL, help_exclude); - private final FileArgument Archive = new FileArgument("file", Argument.OPTIONAL, help_file); + private final FileArgument Archive = new FileArgument("archive", Argument.OPTIONAL, help_archive); private final FileArgument FileList = new FileArgument("fileList", Argument.OPTIONAL, help_file_list); private final FlagArgument UseGzip = new FlagArgument("gzip", Argument.OPTIONAL, help_gzip); private final FlagArgument Interact = new FlagArgument("interact", Argument.OPTIONAL, help_interact); @@ -302,36 +303,42 @@ public TarCommand() { super("Create/Modify/Extract tape archives"); - registerArguments(DoAppend, DoConcat, DoCreate, DoDelete, DoDiff, DoExtract, DoList, DoUpdate, - Backup, UseBzip, ChangeDir, Exclude, Archive, FileList, UseGzip, Interact, KeepNew, Unlink, - KeepOld, NoRecurse, Recurse, RemoveFiles, ShowTotals, Suffix, Verify, Paths, ExcludeFile); + // from ArchiveCommand + registerArguments(Verbose, Debug, Stdout); + + // tar Operations + registerArguments(DoAppend, DoConcat, DoCreate, DoDelete, DoDiff, DoExtract, DoList, DoUpdate); + + // tar Global Options + registerArguments(Backup, Suffix, UseBzip, UseGzip, Archive, FileList, ExcludeFile, Interact, KeepNew, KeepOld, + Unlink, RemoveFiles, ShowTotals, Verify, Paths); + // tar Parsing Options + registerArguments(ChangeDir, Exclude, NoRecurse, Recurse); } // TODO Allow working directory to be changed public void execute() { - super.execute(); + super.execute("tar"); if (!checkMode()) { fatal(err_options, 1); } + if (Archive.isSet()) archive = Archive.getValue(); if (Suffix.isSet()) suffix = Suffix.getValue(); if (Exclude.isSet()) exclude = Exclude.getValue(); if (ExcludeFile.isSet()) excludeFile = ExcludeFile.getValue(); if (FileList.isSet()) fileList = FileList.getValue(); - backup = Backup.isSet(); - bzip = UseBzip.isSet(); - gzip = UseGzip.isSet(); - interact = Interact.isSet(); - verify = Verify.isSet(); - showTotals = ShowTotals.isSet(); - keepOld = KeepOld.isSet(); - keepNew = KeepNew.isSet(); - recurse = !NoRecurse.isSet(); - unlink = Unlink.isSet(); - if (Archive.isSet()) archive = Archive.getValue(); - else error("No archive given"); - //if (!(pipeInOut = !Archive.isSet())) archive = Archive.getValue(); + backup = Backup.isSet(); + bzip = UseBzip.isSet(); + gzip = UseGzip.isSet(); + interact = Interact.isSet(); + verify = Verify.isSet(); + showTotals = ShowTotals.isSet(); + keepOld = KeepOld.isSet(); + keepNew = KeepNew.isSet(); + recurse = !NoRecurse.isSet(); + unlink = Unlink.isSet(); try { if ((mode & TAR_REQ_ARCH) != 0 && archive == null) { @@ -427,7 +434,7 @@ tout = appendTarOutputStream(); // Concatenate new archives - for(File arch : archives) { + for (File arch : archives) { if ((in = openFileRead(arch)) == null) { continue; } @@ -495,7 +502,7 @@ InputStream in; TarInputStream tin; TarEntry entry; - TreeMap<String,Long> entries = new TreeMap(); + TreeMap<String, Long> entries = new TreeMap(); if ((in = openFileRead(archive)) == null) { fatal(" ", 1); @@ -675,6 +682,7 @@ * Sets up a TarOutputStream suitable for appending new entries. */ private TarOutputStream appendTarOutputStream() throws IOException { + // FIXME this isnt working. OutputStream out; InputStream in; TarOutputStream tout; @@ -762,7 +770,7 @@ /** * Wraps an InputStream with a decompression stream for reading compressed archives. */ - private InputStream wrapInputStream( InputStream in ) throws IOException { + private InputStream wrapInputStream(InputStream in) throws IOException { if (decompress == USE_BZIP) { return new CBZip2InputStream(in); } @@ -777,7 +785,7 @@ /** * Wraps an OutputStream with a compression stream for writing compressed archives. */ - private OutputStream wrapOutputStream( OutputStream out ) throws IOException { + private OutputStream wrapOutputStream(OutputStream out) throws IOException { if (compress == USE_BZIP) { return new CBZip2OutputStream(out); } 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-03 05:36:41 UTC (rev 5212) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/UnzipCommand.java 2009-04-04 08:46:39 UTC (rev 5213) @@ -20,12 +20,6 @@ package org.jnode.fs.command.archive; -import org.jnode.shell.AbstractCommand; -import org.jnode.shell.syntax.Argument; -import org.jnode.shell.syntax.FileArgument; -import org.jnode.shell.syntax.FlagArgument; -import org.jnode.shell.syntax.StringArgument; - /** * @author chris boertien */ @@ -37,6 +31,6 @@ } public void execute() { - super.execute(); + super.execute("unzip"); } } Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/ZCatCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/ZCatCommand.java 2009-04-03 05:36:41 UTC (rev 5212) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/ZCatCommand.java 2009-04-04 08:46:39 UTC (rev 5213) @@ -28,11 +28,13 @@ public ZCatCommand() { super("decompresses files to standard output"); + // from GZip + registerArguments(Files); } public void execute() { use_stdout = true; compress = false; - super.execute(); + super.execute("zcat"); } } 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-03 05:36:41 UTC (rev 5212) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java 2009-04-04 08:46:39 UTC (rev 5213) @@ -51,8 +51,8 @@ super(s); } - public void execute() { - super.execute(); + public void execute(String command) { + super.execute(command); } void extract() throws IOException { 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-03 05:36:41 UTC (rev 5212) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java 2009-04-04 08:46:39 UTC (rev 5213) @@ -20,12 +20,6 @@ package org.jnode.fs.command.archive; -import org.jnode.shell.AbstractCommand; -import org.jnode.shell.syntax.Argument; -import org.jnode.shell.syntax.FileArgument; -import org.jnode.shell.syntax.FlagArgument; -import org.jnode.shell.syntax.StringArgument; - /** * @author chris boertien */ @@ -52,6 +46,6 @@ } public void execute() { - super.execute(); + super.execute("zip"); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2009-04-05 05:50:54
|
Revision: 5214 http://jnode.svn.sourceforge.net/jnode/?rev=5214&view=rev Author: lsantha Date: 2009-04-05 05:50:44 +0000 (Sun, 05 Apr 2009) Log Message: ----------- Progress with the find command - by Alexander Kerner Modified Paths: -------------- trunk/fs/descriptors/org.jnode.fs.command.xml trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java trunk/fs/src/fs/org/jnode/fs/command/FindCommand.java Modified: trunk/fs/descriptors/org.jnode.fs.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.command.xml 2009-04-04 08:46:39 UTC (rev 5213) +++ trunk/fs/descriptors/org.jnode.fs.command.xml 2009-04-05 05:50:44 UTC (rev 5214) @@ -115,15 +115,15 @@ </syntax> <syntax alias="find"> <sequence description="find files or directories"> - <repeat minCount="1"> - <argument argLabel="directory"/> + <repeat minCount="0"> + <argument argLabel="directory" description="directory to start searching from"/> </repeat> <optionSet> - <option argLabel="type" longName="type"/> - <option argLabel="maxdepth" longName="maxdepth"/> - <option argLabel="mindepth" longName="mindepth"/> - <option argLabel="name" longName="name"/> - <option argLabel="iname" longName="iname"/> + <option argLabel="type" longName="type" shortName="t" description="filter results to show only files of given type. valid types are 'd' for directory and 'f' for file"/> + <option argLabel="maxdepth" longName="maxdepth" shortName="D" description="descent at most to given level of directories"/> + <option argLabel="mindepth" longName="mindepth" shortName="d" description="ignore files and directories at levels less than given level"/> + <option argLabel="name" longName="name" shortName="n" description="filter results to show only files that match given pattern"/> + <option argLabel="iname" longName="iname" shortName="N" description="same like 'n', but case insensitive"/> </optionSet> </sequence> </syntax> Modified: trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java 2009-04-04 08:46:39 UTC (rev 5213) +++ trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java 2009-04-05 05:50:44 UTC (rev 5214) @@ -26,13 +26,15 @@ private volatile Long minDepth = null; public synchronized void walk(final File... dirs) throws IOException { + if (dirs == null) { + throw new NullPointerException("Directory to walk from must not be null"); + } for (File dir : dirs) { - if (dir == null) + if (dir == null || !dir.isDirectory()) throw new IOException("No such directroy " + dir); - dir = dir.getAbsoluteFile(); // to be able to handle relative paths - if (!dir.canRead() || !dir.isDirectory()) { - throw new IOException("Cannot read directroy " + dir); - } + dir = dir.getCanonicalFile(); // to be able to handle relative paths + // and . / .. + handleStartingDir(dir); stack.push(new FileObject(dir, 0L)); while (!cancelled && !stack.isEmpty()) { go1(stack.pop()); @@ -41,22 +43,29 @@ } private void go1(final FileObject file) throws IOException { - if ((minDepth != null && file.depth < minDepth) || (maxDepth != null && file.depth > maxDepth)) { + if ((minDepth != null && file.depth < minDepth) || + (maxDepth != null && file.depth > maxDepth)) { // out of boundaries - } else if (!file.file.canRead()) { - // ignore for now - } else if (validFileOrDirectory(file)) { + } else if (notFiltered(file)) { handleFileOrDir(file); } else { // filtered out } - go2(file); + try { + go2(file); + } catch (SecurityException e) { + handleRestrictedFile(file.file); + } } - private void go2(final FileObject file) throws IOException { + private void go2(final FileObject file) throws IOException, SecurityException { final Stack<File> stack = new Stack<File>(); final File[] content = file.file.listFiles(); - if (content != null) { + if (content == null) { + // I/O Error or file + } else if (content.length == 0) { + // dir is empty + } else { for (File f : content) { if (f.toString().equals(f.getCanonicalPath())) { stack.push(f); @@ -65,11 +74,10 @@ } } while (!stack.isEmpty()) { - File tmp = stack.pop(); - // addToStack(stack.pop(), file.depth + 1); - this.stack.push(new FileObject(tmp, file.depth + 1)); + this.stack.push(new FileObject(stack.pop(), file.depth + 1)); } } + } private void handleFileOrDir(final FileObject file) { @@ -82,7 +90,7 @@ } } - private boolean validFileOrDirectory(final FileObject file) { + private boolean notFiltered(final FileObject file) { if (!filters.isEmpty()) for (FileFilter filter : filters) if (!filter.accept(file.file)) @@ -106,8 +114,16 @@ filters.add(filter); } - public abstract void handleDir(File f); + protected void handleRestrictedFile(final File file) throws IOException { + throw new IOException("Permission denied for " + file); + } - public abstract void handleFile(File f); + protected void handleStartingDir(final File file) { + // do nothing + } + public abstract void handleDir(final File file); + + public abstract void handleFile(final File file); + } Modified: trunk/fs/src/fs/org/jnode/fs/command/FindCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/FindCommand.java 2009-04-04 08:46:39 UTC (rev 5213) +++ trunk/fs/src/fs/org/jnode/fs/command/FindCommand.java 2009-04-05 05:50:44 UTC (rev 5214) @@ -18,6 +18,11 @@ private class Walker extends AbstractDirectoryWalker { @Override + protected void handleRestrictedFile(File file) throws IOException { + err.println("Permission denied for \"" + file + "\""); + } + + @Override public void handleDir(File f) { out.println(f); } @@ -29,15 +34,20 @@ } - private final StringArgument nameArg = new StringArgument("name", Argument.OPTIONAL); - private final StringArgument inameArg = new StringArgument("iname", Argument.OPTIONAL); - private final LongArgument maxdepthArg = new LongArgument("maxdepth", Argument.OPTIONAL); - private final LongArgument mindepthArg = new LongArgument("mindepth", Argument.OPTIONAL); - private final StringArgument typeArg = new StringArgument("type", Argument.OPTIONAL); - private final FileArgument dirArg = - new FileArgument("directory", Argument.MANDATORY | Argument.EXISTING - | Argument.MULTIPLE); + private final StringArgument nameArg = new StringArgument("name", Argument.OPTIONAL, + "filter results to show only files that match given pattern"); + private final StringArgument inameArg = new StringArgument("iname", Argument.OPTIONAL, + "same like 'name', but case insensitive"); + private final LongArgument maxdepthArg = new LongArgument("maxdepth", Argument.OPTIONAL, + "descent at most to given level of directories"); + private final LongArgument mindepthArg = new LongArgument("mindepth", Argument.OPTIONAL, + "ignore files and directories at levels less than given level"); + private final StringArgument typeArg = new StringArgument( "type", Argument.OPTIONAL, + "filter results to show only files of given type. valid types are 'd' for directory and 'f' for file"); + private final FileArgument dirArg = new FileArgument("directory", Argument.OPTIONAL | Argument.MULTIPLE, + "directory to start searching from"); private PrintWriter out = null; + private PrintWriter err = null; public FindCommand() { super("Find files and directories"); @@ -51,6 +61,7 @@ public void execute() throws IOException { out = getOutput().getPrintWriter(); + err = getError().getPrintWriter(); final Walker walker = new Walker(); if (maxdepthArg.isSet()) { @@ -103,6 +114,10 @@ }); } } - walker.walk(dirArg.getValues()); + if (dirArg.isSet()) { + walker.walk(dirArg.getValues()); + } else { + walker.walk(new File(System.getProperty("user.dir"))); + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
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. |
From: <chr...@us...> - 2009-04-16 21:26:26
|
Revision: 5295 http://jnode.svn.sourceforge.net/jnode/?rev=5295&view=rev Author: chrisboertien Date: 2009-04-16 21:26:19 +0000 (Thu, 16 Apr 2009) Log Message: ----------- More zip command implementation Added support for -m -D -p -j -x -i Added javadoc to Zip Extrapolated strings from within code Added 4 FileFilter implementations as nested classes in ADW Signed-off-by: chrisboertien <chr...@gm...> Modified Paths: -------------- trunk/fs/descriptors/org.jnode.fs.command.archive.xml trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java Modified: trunk/fs/descriptors/org.jnode.fs.command.archive.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.command.archive.xml 2009-04-16 20:37:00 UTC (rev 5294) +++ trunk/fs/descriptors/org.jnode.fs.command.archive.xml 2009-04-16 21:26:19 UTC (rev 5295) @@ -15,6 +15,7 @@ <runtime> <library name="jnode-fs.jar"> <export name="org.jnode.fs.command.archive.*" /> + <export name="org.jnode.fs.command.AbstractDirectoryWalker" /> </library> </runtime> @@ -244,7 +245,7 @@ <option argLabel="recurse" shortName="r"/> <!--<option argLabel="recurse-cd" shortName="R"/>--> <option argLabel="newer" shortName="t"/> - <!--<option argLabel="older" shortName="tt"/>--> + <option argLabel="older" longName="tt"/> <!-- Zip --> <option argLabel="no-path" shortName="j"/> <!-- Zip Operations --> @@ -259,14 +260,12 @@ </optionSet> <argument argLabel="archive"/> <repeat> - <argument argLabel="patterns"/> + <alternatives> + <option argLabel="exclude" shortName="x"/> + <option argLabel="include" shortName="i"/> + <argument argLabel="patterns"/> + </alternatives> </repeat> - <!-- TODO - <repeat> - <option argLabel="include" shortName="i"/> - <option argLabel="exclude" shortName="x"/> - </repeat> - --> </sequence> </syntax> </extension> Modified: trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java 2009-04-16 20:37:00 UTC (rev 5294) +++ trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java 2009-04-16 21:26:19 UTC (rev 5295) @@ -28,6 +28,10 @@ import java.util.Stack; import java.util.List; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import org.jnode.shell.PathnamePattern; /** * <p> * <code>AbstractDirectoryWalker</code> - walk through a directory hierarchy @@ -54,6 +58,66 @@ this.depth = depth; } } + + public static class PathnamePatternFilter implements FileFilter { + + private Matcher matcher; + private boolean exclude; + + public PathnamePatternFilter(String pattern, boolean exclude) { + this.exclude = exclude; + this.matcher = PathnamePattern.compilePosixShellPattern(pattern, 0).matcher(""); + } + + public boolean accept(File file) { + return matcher.reset(file.getName()).matches() ^ exclude; + } + } + + public static class RegexPatternFilter implements FileFilter { + + private Matcher matcher; + private boolean exclude; + + public RegexPatternFilter(String pattern, boolean exclude) { + this.exclude = exclude; + this.matcher = Pattern.compile(pattern).matcher(""); + } + + public boolean accept(File file) { + return matcher.reset(file.getName()).matches() ^ exclude; + } + } + + public static class ModTimeFilter implements FileFilter { + + private long modTime; + private boolean newer; + + public ModTimeFilter(long time, boolean newer) { + this.modTime = time; + this.newer = newer; + } + + public boolean accept(File file) { + return file.lastModified() == modTime || ((file.lastModified() < modTime) ^ newer); + } + } + + public static class SizeFilter implements FileFilter { + + private long size; + private boolean greater; + + public SizeFilter(long size, boolean greater) { + this.size = size; + this.greater = greater; + } + + public boolean accept(File file) { + return file.length() == size || ((file.length() < size) ^ greater); + } + } private final Stack<FileObject> stack = new Stack<FileObject>(); private final Set<FileFilter> filters = new HashSet<FileFilter>(); @@ -87,7 +151,7 @@ } public synchronized void walk(final List<File> dirs) throws IOException { - walk(dirs.toArray(new File[0])); + walk(dirs.toArray(new File[dirs.size() ])); } private void handle(final FileObject file) throws IOException { Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java 2009-04-16 20:37:00 UTC (rev 5294) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java 2009-04-16 21:26:19 UTC (rev 5295) @@ -24,6 +24,7 @@ import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.FlagArgument; +import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -35,6 +36,13 @@ import java.util.ArrayList; +import org.apache.tools.zip.ZipFile; + +/** + * This is a base class that holds some convenience methods for implementing archive commands. + * + * @author chris boertien + */ public class ArchiveCommand extends AbstractCommand { private static final String help_verbose = "show the compression ratio for each file compressed"; @@ -76,6 +84,7 @@ protected OutputStream stdout; protected String commandName; + protected int rc; protected boolean use_stdout; protected boolean force; protected boolean compress; @@ -95,6 +104,7 @@ stdin = getInput().getInputStream(); stdout = getOutput().getOutputStream(); + // FIXME get rid of this { if (command.equals("zcat") || command.equals("bzcat")) return; if (!command.equals("tar")) { @@ -108,6 +118,7 @@ if (Verbose.isSet()) outMode |= OUT_NOTICE; if (Debug.isSet()) outMode |= OUT_DEBUG; } + // } } protected void createStreamBuffer(int size) { @@ -247,14 +258,45 @@ } /** + * Convenience method for closing streams and writers. + */ + protected void close(Closeable obj) { + if (obj != null) { + try { + obj.close(); + } catch (IOException _) { + //ignore + } + } + } + + /** + * Convenience method for closing org.apache.tools.zip.ZipFile + */ + protected void close(ZipFile zfile) { + if (zfile != null) { + try { + zfile.close(); + } catch (IOException _) { + // ignore + } + } + } + + /** * Prompt the user with a question asking for a yes or no answer. * + * FIXME This is unsafe as it will trigger an endless loop if stdin + * is not the terminal. + * * @param String the question to ask the user * @return true if the user said yes, false if the user said no */ protected boolean prompt_yn(String s, boolean defaultY) { int choice; - for (;;) { + // put a cap on the looping to prevent non-terminal stdin + // from an infinte loop + for (int i = 0; i < 10; i++) { stdoutWriter.print(s); try { choice = stdinReader.read(); @@ -266,6 +308,8 @@ if (choice == 'n') return false; if (choice == '\n') return defaultY; } + + return false; } protected void out(String s) { 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-16 20:37:00 UTC (rev 5294) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java 2009-04-16 21:26:19 UTC (rev 5295) @@ -21,9 +21,11 @@ package org.jnode.fs.command.archive; import java.io.File; +import java.io.FileFilter; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.LineNumberReader; import java.io.OutputStream; import java.util.ArrayList; import java.util.Enumeration; @@ -33,6 +35,9 @@ import org.apache.tools.zip.ZipExtraField; import org.apache.tools.zip.ZipFile; import org.apache.tools.zip.ZipOutputStream; +import org.jnode.fs.command.AbstractDirectoryWalker; +import org.jnode.fs.command.AbstractDirectoryWalker.ModTimeFilter; +import org.jnode.fs.command.AbstractDirectoryWalker.PathnamePatternFilter; import org.jnode.shell.PathnamePattern; import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.FileArgument; @@ -40,10 +45,17 @@ import org.jnode.shell.syntax.StringArgument; /** + * TODO test return codes + * TODO make sure no archive is created if the creation fails + * TODO implement delete + * TODO implement update + * TODO implement freshen * @author chris boeriten */ public class Zip extends ArchiveCommand { + private static final boolean DEBUG = true; + 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 " + @@ -60,6 +72,28 @@ private static final String help_archive = "the zip archive to use"; private static final String help_patterns = "file matching patterns(wildcards)"; + private static final String fmt_extract = "%11s: %s"; + private static final String fmt_footer = " %8d %8d %d files"; + private static final String fmt_entry = " %8d %8d %d %s"; + private static final String fmt_warn_dup = "%s: %s: %s"; + private static final String fatal_create_arch = "Could not create archive: "; + private static final String fatal_req_arch = "Archive required but not found: "; + private static final String fatal_create_zfile = "Unable to open archive as ZipFile: "; + private static final String fatal_inv_args = "zip error: Invalid arguments (cannot repeat names in zip file)"; + private static final String fatal_walking = "Exception while walking."; + private static final String fatal_read_stdin = "Exception while reading stdin."; + private static final String str_header_1 = " Size CSize Date Time M Name"; + private static final String str_header_2 = " -------- -------- -------- ----- - ----"; + private static final String str_footer = " -------- -------- -------"; + private static final String str_archive = "Archive: "; + private static final String str_creating = "creating"; + private static final String str_inflating = "inflating"; + private static final String str_adding = "adding"; + private static final String str_zip_warn = "zip warning"; + private static final String str_fullname_1 = " first full name"; + private static final String str_fullname_2 = "second full name"; + private static final String str_name_repeat = "name in zip file repeated"; + protected final StringArgument Patterns; protected final FileArgument Archive; protected final FlagArgument Delete; @@ -82,9 +116,11 @@ 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; + /* Populated in ZipCommand and UnzipCommand */ + protected List<String> includes; + protected List<String> excludes; + protected List<String> excludeDirs; + private List<File> files; private List<ZipEntry> fileEntries; private List<ZipEntry> dirEntries; @@ -94,13 +130,14 @@ private File archive; private ZipFile zarchive; protected File tmpDir; - protected String noCompress; + protected String[] noCompress; protected int mode; protected boolean ignore_case; protected boolean keep; protected boolean overwrite; protected boolean backup; protected boolean noDirEntry; + protected boolean noPath; protected boolean recurse; protected boolean filesStdin; protected boolean useStdout; @@ -123,8 +160,13 @@ parseOptions(command); try { - if (mode == ZIP_ADD) { + if ((mode & ZIP_ADD) != 0) { insert(); + if ((mode & ZIP_MOVE) != 0) { + for (File file : files) { + file.delete(); + } + } return; } @@ -140,13 +182,7 @@ } catch (Exception e) { e.printStackTrace(); } finally { - if (zarchive != null) { - try { - zarchive.close(); - } catch (IOException _) { - // ignore - } - } + close(zarchive); exit(0); } } @@ -157,11 +193,12 @@ InputStream in; try { - zout = new ZipOutputStream(new FileOutputStream(archive)); + zout = new ZipOutputStream(archive); for (File file : files) { in = null; + entry = createEntry(file); + out(String.format(fmt_extract, str_adding, entry.getName())); try { - entry = createEntry(file); if (!file.isDirectory()) { if ((in = openFileRead(file)) == null) { continue; @@ -189,27 +226,29 @@ try { zout.finish(); } catch (IOException e) { - // + // ignore } } } } + @SuppressWarnings("unchecked") 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); + for (ZipEntry entry : dirEntries) { printListEntry(entry); count++; - size += entry.getSize(); + } + + for (ZipEntry entry : fileEntries) { + printListEntry(entry); + count++; + size += entry.getSize(); csize += entry.getCompressedSize(); } printListFooter(size, csize, count); @@ -220,44 +259,47 @@ OutputStream out = null; File file; - out("Archive: " + archive.getName()); + out(str_archive + archive.getName()); + for (ZipEntry entry : dirEntries) { - out(String.format("%11s: %s", "creating", entry.getName())); + out(String.format(fmt_extract, str_creating, entry.getName())); file = new File(entry.getName()); file.mkdirs(); } for (ZipEntry entry : fileEntries) { - out(String.format("%11s: %s", "inflating", entry.getName())); + out(String.format(fmt_extract, str_inflating, entry.getName())); file = new File(entry.getName()); try { + File parent = file.getParentFile(); + if (parent != null && !parent.exists()) { + parent.mkdirs(); + } file.createNewFile(); in = zarchive.getInputStream(entry); - out = new FileOutputStream(file); + if ((out = openFileWrite(file, false, false)) == null) { + continue; + } 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; - } - } + close(in); + close(out); } } } + /** + * Creates a ZipEntry for the specified file. + * + * If the file is a directory it will have a trailing slash + * appended to its name. This is used to distinguish files + * from directories in the archive. + * + * If the -j option is given, then only the file name is stored, + * not its full pathname. Conflicts are dealt with in parseFiles() + */ private ZipEntry createEntry(File file) { String name = file.getPath(); ZipEntry entry; @@ -267,37 +309,34 @@ } entry = new ZipEntry(name); entry.setMethod(ZipEntry.STORED); - entry.setCrc(0); - entry.setSize(0); } else { + if (noPath) { + name = file.getName(); + } entry = new ZipEntry(name); entry.setMethod(ZipEntry.DEFLATED); + if (noCompress != null && noCompress.length > 0) { + for (String suf : noCompress) { + if (name.endsWith(suf)) { + entry.setMethod(ZipEntry.STORED); + break; + } + } + } } 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) { + if (DEBUG || Debug.isSet()) { + outMode |= OUT_DEBUG; } - } - - private void parseOptions(String command) { - outMode |= OUT_DEBUG; + if (Verbose.isSet()) { + outMode |= OUT_NOTICE; + } + if (Quiet.isSet()) { + outMode = 0; + } if (command.equals("zip")) { if (Delete.isSet()) { mode = ZIP_DELETE; @@ -306,7 +345,7 @@ } else if (Update.isSet()) { mode = ZIP_UPDATE | ZIP_ADD; } else if (Move.isSet()) { - mode = ZIP_MOVE; + mode = ZIP_MOVE | ZIP_ADD; } else { mode = ZIP_ADD; } @@ -323,9 +362,10 @@ mode = ZIP_EXTRACT; } } - assert mode != 0 : "Invalid mode"; - switch (mode) { + noPath = NoPath.isSet(); + + switch (mode & (ZIP_ADD | ZIP_EXTRACT | ZIP_LIST)) { case ZIP_ADD : parseFiles(); getArchive(true, false); @@ -334,14 +374,26 @@ getArchive(false, true); parseEntries(); break; - case ZIP_LIST : + case ZIP_LIST : getArchive(false, true); + parseEntries(); break; default : throw new UnsupportedOperationException("This mode is not implemented."); } } + /** + * Instantiates the archive. + * + * If zipfile is true, than a ZipFile object for the archive is also created. + * + * This will exit with an error if: + * - The archive does not exist, create is true, but an exception was thrown on creation. + * - The archive does not exist, and create is false. + * - The archive exists and create is true. (FIXME) + * - A ZipFile was requested and there was an exception during instantiation. + */ private void getArchive(boolean create, boolean zipfile) { archive = Archive.getValue(); @@ -354,10 +406,10 @@ try { archive.createNewFile(); } catch (IOException e) { - fatal("Could not create archive: " + archive, 1); + fatal(fatal_create_arch + archive, 1); } } else { - fatal("Archive required but not found: " + archive, 1); + fatal(fatal_req_arch + archive, 1); } } else { if (create) { @@ -370,18 +422,41 @@ zarchive = new ZipFile(archive); } catch (IOException e) { debug(e.getMessage()); - fatal("Unable to open archive as ZipFile: " + archive, 1); + fatal(fatal_create_zfile + 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 class Walker extends AbstractDirectoryWalker { + @Override + public void handleFile(final File file) throws IOException { + addFile(file); + } + @Override + public void handleDir(final File file) throws IOException { + assert !(noDirEntry || noPath) : "handleDir called when noDirEntry || noPath"; + addFile(file); + } + } + + /** + * Creates a list of files based on the files and filename patterns given + * on the command line. If we're using recursion, then a directory walker + * is used with the given include/exclude filters if any are in use. + * + * The -D/-j options prevent directories from being listed. + * The -x/-i options are used to add exclude/include patterns. + * The -r option turns on recursion + * + * This will exit with an error if there was an exception while walking. + */ private void parseFiles() { files = new ArrayList<File>(); + List<File> dirs = new ArrayList<File>(); + if (filesStdin) { + parseFilesStdin(); + } if (Patterns.isSet()) { for (String pattern : Patterns.getValues()) { if (!PathnamePattern.isPattern(pattern)) { @@ -391,7 +466,7 @@ continue; } if (file.isDirectory()) { - addDirectory(file); + dirs.add(file); } else { addFile(file); } @@ -401,7 +476,7 @@ for (String name : list) { File file = new File(name); if (file.isDirectory()) { - addDirectory(file); + dirs.add(file); } else { addFile(file); } @@ -409,10 +484,90 @@ } } } + + if (recurse && dirs.size() > 0) { + Walker walker = new Walker(); + if (noDirEntry || noPath) { + walker.addFilter(new FileFilter() { + @Override + public boolean accept(File file) { + return !file.isDirectory(); + } + }); + } + if (excludes != null && excludes.size() > 0) { + for (String pattern : excludes) { + walker.addFilter(new PathnamePatternFilter(pattern, true)); + } + } + if (includes != null && includes.size() > 0) { + for (String pattern : includes) { + walker.addFilter(new PathnamePatternFilter(pattern, false)); + } + } + if (newer > 0) { + walker.addFilter(new ModTimeFilter(newer, true)); + } + if (older > 0) { + walker.addFilter(new ModTimeFilter(older, false)); + } + try { + walker.walk(dirs); + } catch (IOException e) { + debug(e.getMessage()); + fatal(fatal_walking, 1); + } + } } + /** + * Parses files from stdin, one file per line. + * + * If the file does not exist, it is ignored and omitted. + * + * This will exit with an error if there is an exception while reading stdin. + */ + private void parseFilesStdin() { + LineNumberReader reader = new LineNumberReader(stdinReader); + String line; + File file; + + try { + while ((line = reader.readLine()) != null) { + file = new File(line); + if (file.exists()) { + addFile(file); + } + } + } catch (IOException e) { + fatal(fatal_read_stdin, 1); + } + } + + /** + * Adds a file to the list of files. + * + * If the -j option is used, then the list is scanned for the file name. + * This is done because -j strips the path from the pathname, which can cause + * collisions if two files from separate directories with the same name are added. + */ + private void addFile(File file) { + if (noPath) { + // this isn't effecient by any means, but this is not an often-used + // case, and when it is, its not likely that files.size() is going + // to grow very large. + for (File f : files) { + if (f.getName().equals(file.getName())) { + printDuplicateError(file, f); + fatal(fatal_inv_args, 1); + } + } + } + files.add(file); + } + + @SuppressWarnings("unchecked") private void parseEntries() { - assert zarchive != null : "null archive in parseEntries"; int count = 0; ZipEntry entry; @@ -429,30 +584,34 @@ 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 printListHeader() { + out(str_header_1); + out(str_header_2); } - private void addFile(File file) { - files.add(file); + private void printListEntry(ZipEntry entry) { + out(String.format(fmt_entry, entry.getSize(), entry.getCompressedSize(), entry.getMethod(), entry.getName())); } + private void printListFooter(int size, int csize, int numFiles) { + out(str_footer); + out(String.format(fmt_footer, size, csize, numFiles)); + } + + private void printDuplicateError(File A, File B) { + error(String.format(fmt_warn_dup, str_zip_warn, str_fullname_1, A.getPath())); + error(String.format(fmt_warn_dup, str_zip_warn, str_fullname_2, B.getPath())); + error(String.format(fmt_warn_dup, str_zip_warn, str_name_repeat, A.getName())); + } + + private void printName(String s) { + if (outMode != 0) { + out(s); + } + } + private void debug(ZipEntry entry) { debug("Name: " + entry.getName()); debug("Directory: " + entry.isDirectory()); 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-16 20:37:00 UTC (rev 5294) +++ trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java 2009-04-16 21:26:19 UTC (rev 5295) @@ -20,6 +20,9 @@ package org.jnode.fs.command.archive; +import java.text.DateFormat; +import java.text.ParseException; +import java.util.ArrayList; import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.FlagArgument; import org.jnode.shell.syntax.FileArgument; @@ -37,7 +40,12 @@ 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 static final String help_exclude = "do not includes files matching a pattern"; + private static final String help_include = "only includes files matching a pattern"; + private static final String fatal_bad_newer = "Invalid newer-than date: "; + private static final String fatal_bad_older = "Invalid older-than date: "; + private final FlagArgument FilesStdin; private final FlagArgument NoDirEntry; private final FlagArgument Recurse; @@ -45,6 +53,8 @@ private final StringArgument NoCompress; private final StringArgument NewerThan; private final StringArgument OlderThan; + private final StringArgument Exclude; + private final StringArgument Include; public ZipCommand() { super("compress files into a zip archive"); @@ -56,11 +66,13 @@ 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); + TmpDir = new FileArgument("tmp-dir", Argument.OPTIONAL | Argument.EXISTING, 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); + Exclude = new StringArgument("exclude", Argument.OPTIONAL | Argument.MULTIPLE, help_exclude); + Include = new StringArgument("include", Argument.OPTIONAL | Argument.MULTIPLE, help_include); + registerArguments(FilesStdin, TmpDir, NoDirEntry, NoCompress, Recurse, NewerThan, OlderThan, Exclude, Include); } @Override @@ -68,9 +80,40 @@ recurse = Recurse.isSet(); noDirEntry = NoDirEntry.isSet(); filesStdin = FilesStdin.isSet(); - if (NoCompress.isSet()) noCompress = NoCompress.getValue(); if (TmpDir.isSet()) tmpDir = TmpDir.getValue(); - + /* FIXME + if (NewerThan.isSet()) { + try { + newer = DateFormat.getInstance().parse(NewerThan.getValue()).getTime(); + } catch (ParseException e) { + e.printStackTrace(); + exit(1); + } + } + if (OlderThan.isSet()) { + try { + older = DateFormat.getInstance().parse(OlderThan.getValue()).getTime(); + } catch (ParseException e) { + e.printStackTrace(); + exit(1); + } + } + */ + if (NoCompress.isSet()) { + noCompress = NoCompress.getValue().split(":"); + } + if (Exclude.isSet()) { + excludes = new ArrayList<String>(Exclude.getValues().length); + for (String pattern : Exclude.getValues()) { + excludes.add(pattern); + } + } + if (Include.isSet()) { + includes = new ArrayList<String>(Include.getValues().length); + for (String pattern : Include.getValues()) { + includes.add(pattern); + } + } super.execute("zip"); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2011-07-31 13:46:40
|
Revision: 5840 http://jnode.svn.sourceforge.net/jnode/?rev=5840&view=rev Author: lsantha Date: 2011-07-31 13:46:34 +0000 (Sun, 31 Jul 2011) Log Message: ----------- Extended 'eject' command to load media with the '-t' option and to operate on the first removable media device when no device is specified. Modified Paths: -------------- trunk/fs/descriptors/org.jnode.fs.command.xml trunk/fs/src/fs/org/jnode/fs/command/EjectCommand.java Modified: trunk/fs/descriptors/org.jnode.fs.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.command.xml 2011-07-31 13:43:44 UTC (rev 5839) +++ trunk/fs/descriptors/org.jnode.fs.command.xml 2011-07-31 13:46:34 UTC (rev 5840) @@ -27,7 +27,10 @@ <extension point="org.jnode.shell.syntaxes"> <syntax alias="eject"> - <argument argLabel="device" description="eject a device with a removable medium"/> + <sequence> + <optional><option argLabel="t" shortName="t" description="load a device with a removable medium"/></optional> + <optional><argument argLabel="device" description="eject a device with a removable medium"/></optional> + </sequence> </syntax> <syntax alias="mount"> <empty description="list all mounted filesystems"/> Modified: trunk/fs/src/fs/org/jnode/fs/command/EjectCommand.java =================================================================== --- trunk/fs/src/fs/org/jnode/fs/command/EjectCommand.java 2011-07-31 13:43:44 UTC (rev 5839) +++ trunk/fs/src/fs/org/jnode/fs/command/EjectCommand.java 2011-07-31 13:46:34 UTC (rev 5840) @@ -22,39 +22,65 @@ import java.io.IOException; +import java.util.Iterator; import org.jnode.driver.ApiNotFoundException; import org.jnode.driver.Device; +import org.jnode.driver.DeviceUtils; import org.jnode.driver.RemovableDeviceAPI; import org.jnode.shell.AbstractCommand; import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.DeviceArgument; +import org.jnode.shell.syntax.FlagArgument; - /** * @author Ewout Prangsma (ep...@us...) + * @author Levente S\u00e1ntha */ public class EjectCommand extends AbstractCommand { private static final String help_device = "Device to eject the medium from"; + private static final String help_load = "Load the medium into the device"; private static final String fmt_failed = "Eject failed for %s: %s"; - private final DeviceArgument argDevice - = new DeviceArgument("device", Argument.MANDATORY | Argument.EXISTING, help_device, RemovableDeviceAPI.class); + private final DeviceArgument argDevice = new DeviceArgument("device", Argument.OPTIONAL | Argument.EXISTING, + help_device, RemovableDeviceAPI.class); + private final FlagArgument argLoad = new FlagArgument("t", Argument.OPTIONAL, help_load); public EjectCommand() { super("Eject the medium from a given device"); - registerArguments(argDevice); + registerArguments(argLoad, argDevice); } public static void main(String[] args) throws Exception { new EjectCommand().execute(args); } - public void execute() - throws ApiNotFoundException, IOException { - final Device dev = argDevice.getValue(); + public void execute() throws ApiNotFoundException, IOException { + final Device dev; + if (!argDevice.isSet()) { + Iterator<Device> iter = DeviceUtils.getDevicesByAPI(RemovableDeviceAPI.class).iterator(); + dev = iter.hasNext() ? iter.next() : null; + } else { + dev = argDevice.getValue(); + } + + if (dev == null) { + getError().getPrintWriter().println("No removable device found."); + return; + } + final RemovableDeviceAPI api = dev.getAPI(RemovableDeviceAPI.class); try { - api.eject(); + if (!api.canEject()) { + getError().getPrintWriter().format("No device found to %s.", + argLoad.isSet() ? "load" : "eject"); + return; + } + + if (argLoad.isSet()) { + api.load(); + } else { + api.eject(); + } } catch (IOException ex) { getError().getPrintWriter().format(fmt_failed, dev.getId(), ex.getLocalizedMessage()); exit(1); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ga...@us...> - 2012-03-09 13:06:40
|
Revision: 5890 http://jnode.svn.sourceforge.net/jnode/?rev=5890&view=rev Author: galatnm Date: 2012-03-09 13:06:29 +0000 (Fri, 09 Mar 2012) Log Message: ----------- Add gpt partition support from Luke. Added Paths: ----------- trunk/fs/descriptors/org.jnode.partitions.gpt.xml trunk/fs/src/fs/org/jnode/partitions/gpt/ trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTable.java trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTableEntry.java trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTableType.java trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTypes.java Added: trunk/fs/descriptors/org.jnode.partitions.gpt.xml =================================================================== --- trunk/fs/descriptors/org.jnode.partitions.gpt.xml (rev 0) +++ trunk/fs/descriptors/org.jnode.partitions.gpt.xml 2012-03-09 13:06:29 UTC (rev 5890) @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plugin SYSTEM "jnode.dtd"> + +<plugin id="org.jnode.partitions.gpt" + name="JNode GPT partition table classes" + version="0.2.9-dev" + license-name="lgpl" + provider-name="JNode.org"> + + <requires> + <import plugin="org.jnode.partitions"/> + </requires> + + <runtime> + <library name="jnode-fs.jar"> + <export name="org.jnode.partitions.gpt.*"/> + </library> + </runtime> + + <extension point="org.jnode.partitions.types"> + <type class="org.jnode.partitions.gpt.GptPartitionTableType"/> + </extension> + +</plugin> \ No newline at end of file Added: trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTable.java =================================================================== --- trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTable.java (rev 0) +++ trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTable.java 2012-03-09 13:06:29 UTC (rev 5890) @@ -0,0 +1,128 @@ +/* + * $Id: $ + * + * Copyright (C) 2003-2010 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.partitions.gpt; + +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import org.apache.log4j.Logger; +import org.jnode.driver.Device; +import org.jnode.partitions.PartitionTable; +import org.jnode.partitions.PartitionTableType; +import org.jnode.util.LittleEndian; + +/** + * The main GPT partition table class. + * + * @author Luke Quinane + */ +public class GptPartitionTable implements PartitionTable<GptPartitionTableEntry> { + + /** The type of partition table */ + private final GptPartitionTableType tableType; + + /** The partition entries */ + private final List<GptPartitionTableEntry> partitions = new ArrayList<GptPartitionTableEntry>(); + + /** My logger */ + private static final Logger log = Logger.getLogger(GptPartitionTable.class); + + /** + * Create a new instance + * + * @param tableType the partition table type. + * @param first16KiB the first 16,384 bytes of the disk. + * @param device the drive device. + */ + public GptPartitionTable(GptPartitionTableType tableType, byte[] first16KiB, Device device) { + this.tableType = tableType; + + int blockSize = detectBlockSize(first16KiB); + + if (blockSize != -1) { + long entries = LittleEndian.getUInt32(first16KiB, blockSize + 0x50); + int entrySize = (int) LittleEndian.getUInt32(first16KiB, blockSize + 0x54); + + for (int partitionNumber = 0; partitionNumber < entries; partitionNumber++) { + log.debug("try part " + partitionNumber); + + int offset = blockSize * 2 + (partitionNumber * entrySize); + + GptPartitionTableEntry entry = new GptPartitionTableEntry(this, first16KiB, offset, blockSize); + + if (entry.isValid()) + { + partitions.add(entry); + } + } + } + } + + /** + * Detects the block size of the GPT partition. + * + * @param first16KiB the start of the disk to search for the GPT partition in. + * @return the detected block size or {@code -1} if no GPT partition is found. + */ + private static int detectBlockSize(byte[] first16KiB) { + int[] detectionSizes = new int[] { 0x200, 0x1000 }; + + for (int blockSize : detectionSizes) { + if (first16KiB.length < blockSize + 8) { + // Not enough data to check for a valid partition table + return -1; + } + + byte[] signatureBytes = new byte[8]; + System.arraycopy(first16KiB, blockSize, signatureBytes, 0, signatureBytes.length); + String signature = new String(signatureBytes, Charset.forName("US-ASCII")); + + if ("EFI PART".equals(signature)) { + return blockSize; + } + } + + return -1; + } + + /** + * Checks if the given boot sector contain a GPT partition table. + * + * @param first16KiB the first 16,384 bytes of the disk. + * @return {@code true} if the boot sector contains a GPT partition table. + */ + public static boolean containsPartitionTable(byte[] first16KiB) { + return detectBlockSize(first16KiB) != -1; + } + + public Iterator<GptPartitionTableEntry> iterator() { + return Collections.unmodifiableList(partitions).iterator(); + } + + /** + * @see org.jnode.partitions.PartitionTable#getType() + */ + public PartitionTableType getType() { + return tableType; + } +} \ No newline at end of file Added: trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTableEntry.java =================================================================== --- trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTableEntry.java (rev 0) +++ trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTableEntry.java 2012-03-09 13:06:29 UTC (rev 5890) @@ -0,0 +1,132 @@ +/* + * $Id: $ + * + * Copyright (C) 2003-2010 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.partitions.gpt; + +import java.nio.charset.Charset; +import org.jnode.partitions.PartitionTableEntry; +import org.jnode.partitions.ibm.IBMPartitionTable; +import org.jnode.util.LittleEndian; +import org.jnode.util.NumberUtils; + +/** + * A GPT partition table entry. + * + * @author Luke Quinane + */ +public class GptPartitionTableEntry implements PartitionTableEntry { + + /** The first 16KiB of the drive. */ + private final byte[] first16KiB; + + /** The block size. */ + private int blockSize; + + /** The offset to this partition table entry. */ + private final int offset; + + /** + * Creates a new entry. + * + * @param parent the parent table. + * @param first16KiB the first 16,384 bytes of the disk. + * @param offset the offset of this entry in the table. + * @param blockSize the block size. + */ + public GptPartitionTableEntry(GptPartitionTable parent, byte[] first16KiB, int offset, int blockSize) { + this.first16KiB = first16KiB; + this.blockSize = blockSize; + this.offset = offset; + } + + public boolean isValid() { + return first16KiB.length > offset + 128 && !isEmpty(); + } + + /** + * @see org.jnode.partitions.PartitionTableEntry#getChildPartitionTable() + */ + public IBMPartitionTable getChildPartitionTable() { + throw new UnsupportedOperationException("No child partitions."); + } + + /** + * @see org.jnode.partitions.PartitionTableEntry#hasChildPartitionTable() + */ + public boolean hasChildPartitionTable() { + return false; + } + + public boolean isEmpty() { + return GptPartitionTypes.lookUp(getPartitionTypeGuid()) == GptPartitionTypes.UNUSED_ENTRY; + } + + public byte[] getPartitionTypeGuid() { + byte[] guid = new byte[16]; + System.arraycopy(first16KiB, offset, guid, 0, guid.length); + return guid; + } + + public byte[] getPartitionGuid() { + byte[] guid = new byte[16]; + System.arraycopy(first16KiB, offset + 0x10, guid, 0, guid.length); + return guid; + } + + public long getStartOffset() { + return LittleEndian.getInt64(first16KiB, offset + 0x20) * blockSize; + } + + public long getEndOffset() { + return (LittleEndian.getInt64(first16KiB, offset + 0x28) + 1) * blockSize; + } + + public long getFlags() { + return LittleEndian.getInt64(first16KiB, offset + 0x30); + } + + public String getName() { + byte[] nameBytes = new byte[72]; + System.arraycopy(first16KiB, offset + 0x38, nameBytes, 0, nameBytes.length); + return new String(nameBytes, Charset.forName("UTF-16LE")).replace("\u0000", ""); + } + + public String dump() { + StringBuilder b = new StringBuilder(); + for (int i = 0; i < 128; i++) { + b.append(NumberUtils.hex(LittleEndian.getUInt8(first16KiB, offset + i), 2)); + b.append(' '); + } + return b.toString(); + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuilder builder = new StringBuilder(32); + builder.append('[').append(getName()).append(' '); + builder.append(NumberUtils.hex(getPartitionTypeGuid())).append(' '); + builder.append(NumberUtils.hex(getPartitionGuid())).append(' '); + builder.append("s:").append(getStartOffset()).append(' '); + builder.append("e:").append(getEndOffset()).append(']'); + return builder.toString(); + } +} Added: trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTableType.java =================================================================== --- trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTableType.java (rev 0) +++ trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTableType.java 2012-03-09 13:06:29 UTC (rev 5890) @@ -0,0 +1,47 @@ +/* + * $Id: $ + * + * Copyright (C) 2003-2010 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.partitions.gpt; + +import org.jnode.driver.Device; +import org.jnode.driver.block.BlockDeviceAPI; +import org.jnode.partitions.PartitionTable; +import org.jnode.partitions.PartitionTableException; +import org.jnode.partitions.PartitionTableType; + +/** + * GPT partition table type. + * + * @author Luke Quinane + */ +public class GptPartitionTableType implements PartitionTableType { + + public PartitionTable<?> create(byte[] firstSector, Device device) throws PartitionTableException { + return new GptPartitionTable(this, firstSector, device); + } + + public String getName() { + return "EFI PART"; + } + + public boolean supports(byte[] first16KiB, BlockDeviceAPI devApi) { + return GptPartitionTable.containsPartitionTable(first16KiB); + } +} \ No newline at end of file Added: trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTypes.java =================================================================== --- trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTypes.java (rev 0) +++ trunk/fs/src/fs/org/jnode/partitions/gpt/GptPartitionTypes.java 2012-03-09 13:06:29 UTC (rev 5890) @@ -0,0 +1,165 @@ +/* + * $Id: $ + * + * Copyright (C) 2003-2010 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.partitions.gpt; + +import java.util.UUID; +import org.apache.log4j.Logger; +import org.jnode.util.NumberUtils; + +/** + * Known GPT partition types. + * + * @author Luke Quinane + */ +public enum GptPartitionTypes { + + // General + UNKNOWN(), + UNUSED_ENTRY("00000000-0000-0000-0000-000000000000"), + MBR_PARTITION_SCHEME("024DEE41-33E7-11D3-9D69-0008C781F39F"), + EFI_SYSTEM_PARTITION("C12A7328-F81F-11D2-BA4B-00A0C93EC93B"), + BIOS_BOOT_PARTITION("21686148-6449-6E6F-744E-656564454649"), + + // Windows + MICROSOFT_RESERVED_PARTITION("E3C9E316-0B5C-4DB8-817D-F92DF00215AE"), + MICROSOFT_BASIC_DATA_PARTITION("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7"), + MICROSOFT_LOGICAL_DISK_MANAGER_METADATA_PARTITION("5808C8AA-7E8F-42E0-85D2-E1E90434CFB3"), + MICROSOFT_LOGICAL_DISK_MANAGER_DATA_PARTITION("AF9B60A0-1431-4F62-BC68-3311714A69AD"), + WINDOWS_RECOVERY_ENVIRONMENT("DE94BBA4-06D1-4D40-A16A-BFD50179D6AC"), + IBM_GENERAL_PARALLEL_FILE_SYSTEM_PARTITION("37AFFC90-EF7D-4E96-91C3-2D7AE055B174"), + + // HP-UX + HP_UX_DATA_PARTITION("75894C1E-3AEB-11D3-B7C1-7B03A0000000"), + HP_UX_SERVICE_PARTITION("E2A1E728-32E3-11D6-A682-7B03A0000000"), + + // Linux + LINUX_FILESYSTEM_DATA("0FC63DAF-8483-4772-8E79-3D69D8477DE4"), + LINUX_RAID_PARTITION("A19D880F-05FC-4D3B-A006-743F0F84911E"), + LINUX_SWAP_PARTITION("0657FD6D-A4AB-43C4-84E5-0933C84B4F4F"), + LINUX_LOGICAL_VOLUME_MANAGER_PARTITION("E6D6D379-F507-44C2-A23C-238F2A3DF928"), + LINUX_RESERVED("8DA63339-0007-60C0-C436-083AC8230908"), + + // FreeBSD + FREEBSD_BOOT_PARTITION("83BD6B9D-7F41-11DC-BE0B-001560B84F0F"), + FREEBSD_DATA_PARTITION("516E7CB4-6ECF-11D6-8FF8-00022D09712B"), + FREEBSD_SWAP_PARTITION("516E7CB5-6ECF-11D6-8FF8-00022D09712B"), + FREEBSD_UNIX_FILE_SYSTEM_PARTITION("516E7CB6-6ECF-11D6-8FF8-00022D09712B"), + FREEBSD_VINUM_VOLUME_MANAGER_PARTITION("516E7CB8-6ECF-11D6-8FF8-00022D09712B"), + FREEBSD_ZFS_PARITION("516E7CBA-6ECF-11D6-8FF8-00022D09712B"), + + // Apple + HFS_PLUS_PARTITION("48465300-0000-11AA-AA11-00306543ECAC"), + APPLE_UFS("55465300-0000-11AA-AA11-00306543ECAC"), + APPLE_ZFS("6A898CC3-1DD2-11B2-99A6-080020736631"), // This is the same GUID as SOLARIS_USR_PARTITION + APPLE_RAID_PARTITION("52414944-0000-11AA-AA11-00306543ECAC"), + APPLE_RAID_PARTITION_OFFLINE("52414944-5F4F-11AA-AA11-00306543ECAC"), + APPLE_BOOT_PARTITION("426F6F74-0000-11AA-AA11-00306543ECAC"), + APPLE_lABEL("4C616265-6C00-11AA-AA11-00306543ECAC"), + APPLE_TV_RECOVERY_PARTITION("5265636F-7665-11AA-AA11-00306543ECAC"), + APPLE_CORE_STORAGE_PARTITION("53746F72-6167-11AA-AA11-00306543ECAC"), + + // Solaris + SOLARIS_BOOT_PARTITION("6A82CB45-1DD2-11B2-99A6-080020736631"), + SOLARIS_ROOT_PARTITION("6A85CF4D-1DD2-11B2-99A6-080020736631"), + SOLARIS_SWAP_PARTITION("6A87C46F-1DD2-11B2-99A6-080020736631"), + SOLARIS_BACKUP_PARTITION("6A8B642B-1DD2-11B2-99A6-080020736631"), + SOLARIS_USR_PARTITION("6A898CC3-1DD2-11B2-99A6-080020736631"), // This is the same GUID as APPLE_ZFS + SOLARIS_VAR_PARTITION("6A8EF2E9-1DD2-11B2-99A6-080020736631"), + SOLARIS_HOME_PARTITION("6A90BA39-1DD2-11B2-99A6-080020736631"), + SOLARIS_ALTERNATE_SECTOR("6A9283A5-1DD2-11B2-99A6-080020736631"), + SOLARIS_RESERVED_PARTITION_1("6A945A3B-1DD2-11B2-99A6-080020736631"), + SOLARIS_RESERVED_PARTITION_2("6A9630D1-1DD2-11B2-99A6-080020736631"), + SOLARIS_RESERVED_PARTITION_3("6A980767-1DD2-11B2-99A6-080020736631"), + SOLARIS_RESERVED_PARTITION_4("6A96237F-1DD2-11B2-99A6-080020736631"), + SOLARIS_RESERVED_PARTITION_5("6A8D2AC7-1DD2-11B2-99A6-080020736631"), + + // NetBSD + NETBSD_SWAP_PARTITION("49F48D32-B10E-11DC-B99B-0019D1879648"), + NETBSD_FFS_PARTITION("49F48D5A-B10E-11DC-B99B-0019D1879648"), + NETBSD_LFS_PARTITION("49F48D82-B10E-11DC-B99B-0019D1879648"), + NETBSD_RAID_PARTITION("49F48DAA-B10E-11DC-B99B-0019D1879648"), + NETBSD_CONCATENATED_PARTITION("2DB519C4-B10F-11DC-B99B-0019D1879648"), + NETBSD_ENCRYPTED_PARTITION("2DB519EC-B10F-11DC-B99B-0019D1879648"), + + // ChromeOS + CHROMEOS_KERNEL("FE3A2A5D-4F32-41A7-B725-ACCC3285A309"), + CHROMEOS_ROOTFS("3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC"), + CHROMEOS_FUTURE_USE("2E0A753D-9E48-43B0-8337-B15192CB1B5E"); + + /** Logger */ + private static final Logger log = Logger.getLogger(GptPartitionTypes.class); + + private UUID uuid; + + private GptPartitionTypes() { + } + + private GptPartitionTypes(String guid) { + this.uuid = UUID.fromString(guid); + } + + /** + * Looks up a partition type from its GUID. + * + * @param partitionTypeGuid the GUID to lookup. + * @return the type or {@link #UNKNOWN} if no match is found. + */ + public static GptPartitionTypes lookUp(byte[] partitionTypeGuid) { + + StringBuilder uuidBuilder = new StringBuilder(); + + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[3], 2)); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[2], 2)); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[1], 2)); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[0], 2)); + uuidBuilder.append("-"); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[5], 2)); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[4], 2)); + uuidBuilder.append("-"); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[7], 2)); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[6], 2)); + uuidBuilder.append("-"); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[8], 2)); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[9], 2)); + uuidBuilder.append("-"); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[10], 2)); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[11], 2)); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[12], 2)); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[13], 2)); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[14], 2)); + uuidBuilder.append(NumberUtils.hex(partitionTypeGuid[15], 2)); + + try { + UUID uuidToMatch = UUID.fromString(uuidBuilder.toString()); + + for (GptPartitionTypes type : GptPartitionTypes.values()) { + if (uuidToMatch.equals(type.uuid)) { + return type; + } + } + } + catch (Exception e) { + log.warn("Exception checking uuid: " + uuidBuilder.toString()); + } + + return UNKNOWN; + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ga...@us...> - 2012-08-09 14:08:27
|
Revision: 5904 http://jnode.svn.sourceforge.net/jnode/?rev=5904&view=rev Author: galatnm Date: 2012-08-09 14:08:21 +0000 (Thu, 09 Aug 2012) Log Message: ----------- Initial Apple partition map support (patch from L. Quinane) Added Paths: ----------- trunk/fs/descriptors/org.jnode.partitions.apm.xml trunk/fs/src/fs/org/jnode/partitions/apm/ trunk/fs/src/fs/org/jnode/partitions/apm/ApmPartitionTable.java trunk/fs/src/fs/org/jnode/partitions/apm/ApmPartitionTableEntry.java trunk/fs/src/fs/org/jnode/partitions/apm/ApmPartitionTableType.java Added: trunk/fs/descriptors/org.jnode.partitions.apm.xml =================================================================== --- trunk/fs/descriptors/org.jnode.partitions.apm.xml (rev 0) +++ trunk/fs/descriptors/org.jnode.partitions.apm.xml 2012-08-09 14:08:21 UTC (rev 5904) @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plugin SYSTEM "jnode.dtd"> + +<plugin id="org.jnode.partitions.apm" + name="JNode APM partition table classes" + version="0.2.9-dev" + license-name="lgpl" + provider-name="JNode.org"> + + <requires> + <import plugin="org.jnode.partitions"/> + </requires> + + <runtime> + <library name="jnode-fs.jar"> + <export name="org.jnode.partitions.apm.*"/> + </library> + </runtime> + + <extension point="org.jnode.partitions.types"> + <type class="org.jnode.partitions.apm.ApmPartitionTableType"/> + </extension> + +</plugin> Added: trunk/fs/src/fs/org/jnode/partitions/apm/ApmPartitionTable.java =================================================================== --- trunk/fs/src/fs/org/jnode/partitions/apm/ApmPartitionTable.java (rev 0) +++ trunk/fs/src/fs/org/jnode/partitions/apm/ApmPartitionTable.java 2012-08-09 14:08:21 UTC (rev 5904) @@ -0,0 +1,101 @@ +/* + * $Id: $ + * + * Copyright (C) 2003-2012 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.partitions.apm; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import org.apache.log4j.Logger; +import org.jnode.driver.Device; +import org.jnode.partitions.PartitionTable; +import org.jnode.partitions.PartitionTableType; +import org.jnode.util.LittleEndian; + +/** + * The main Apple Partition Map (APM) partition table class. + * + * @author Luke Quinane + */ +public class ApmPartitionTable implements PartitionTable<ApmPartitionTableEntry> { + + /** The type of partition table */ + private final ApmPartitionTableType tableType; + + /** The partition entries */ + private final List<ApmPartitionTableEntry> partitions = new ArrayList<ApmPartitionTableEntry>(); + + /** My logger */ + private static final Logger log = Logger.getLogger(ApmPartitionTable.class); + + /** + * Create a new instance + * + * @param tableType the partition table type. + * @param first16KiB the first 16,384 bytes of the disk. + * @param device the drive device. + */ + public ApmPartitionTable(ApmPartitionTableType tableType, byte[] first16KiB, Device device) { + this.tableType = tableType; + + long entries = LittleEndian.getUInt32(first16KiB, 0x204); + + for (int partitionNumber = 0; partitionNumber < entries; partitionNumber++) { + log.debug("try part " + partitionNumber); + + int offset = 0x200 + (partitionNumber * 0x200); + + ApmPartitionTableEntry entry = new ApmPartitionTableEntry(this, first16KiB, offset); + + if (entry.isValid()) + { + partitions.add(entry); + } + } + } + + /** + * Checks if the given boot sector contain a APM partition table. + * + * @param first16KiB the first 16,384 bytes of the disk. + * @return {@code true} if the boot sector contains a APM partition table. + */ + public static boolean containsPartitionTable(byte[] first16KiB) { + if ((first16KiB[0x200] & 0xFF) != 0x50) { + return false; + } + if ((first16KiB[0x201] & 0xFF) != 0x4d) { + return false; + } + return true; + } + + public Iterator<ApmPartitionTableEntry> iterator() { + return Collections.unmodifiableList(partitions).iterator(); + } + + /** + * @see org.jnode.partitions.PartitionTable#getType() + */ + public PartitionTableType getType() { + return tableType; + } +} Added: trunk/fs/src/fs/org/jnode/partitions/apm/ApmPartitionTableEntry.java =================================================================== --- trunk/fs/src/fs/org/jnode/partitions/apm/ApmPartitionTableEntry.java (rev 0) +++ trunk/fs/src/fs/org/jnode/partitions/apm/ApmPartitionTableEntry.java 2012-08-09 14:08:21 UTC (rev 5904) @@ -0,0 +1,117 @@ +/* + * $Id: $ + * + * Copyright (C) 2003-2012 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.partitions.apm; + +import java.nio.charset.Charset; +import org.jnode.partitions.PartitionTableEntry; +import org.jnode.partitions.ibm.IBMPartitionTable; +import org.jnode.util.BigEndian; +import org.jnode.util.LittleEndian; +import org.jnode.util.NumberUtils; + +/** + * A APM partition table entry. + * + * @author Luke Quinane + */ +public class ApmPartitionTableEntry implements PartitionTableEntry { + + /** The first 16KiB of the drive. */ + private final byte[] first16KiB; + + /** The offset to this partition table entry. */ + private final int offset; + + /** + * Creates a new entry. + * + * @param parent the parent table. + * @param first16KiB the first 16,384 bytes of the disk. + * @param offset the offset of this entry in the table. + */ + public ApmPartitionTableEntry(ApmPartitionTable parent, byte[] first16KiB, int offset) { + this.first16KiB = first16KiB; + this.offset = offset; + } + + public boolean isValid() { + return first16KiB.length > offset + 128 && !isEmpty(); + } + + /** + * @see org.jnode.partitions.PartitionTableEntry#getChildPartitionTable() + */ + public IBMPartitionTable getChildPartitionTable() { + throw new UnsupportedOperationException("No child partitions."); + } + + /** + * @see org.jnode.partitions.PartitionTableEntry#hasChildPartitionTable() + */ + public boolean hasChildPartitionTable() { + return false; + } + + public boolean isEmpty() { + return "Apple_Scratch".equals(getType()); + } + + public long getStartOffset() { + return BigEndian.getInt32(first16KiB, offset + 0x8) * 0x200L; + } + + public long getEndOffset() { + return getStartOffset() + (BigEndian.getInt32(first16KiB, offset + 0xc) + 1) * 0x200L; + } + + public String getName() { + byte[] nameBytes = new byte[31]; + System.arraycopy(first16KiB, offset + 0x10, nameBytes, 0, nameBytes.length); + return new String(nameBytes, Charset.forName("ASCII")).replace("\u0000", ""); + } + + public String getType() { + byte[] nameBytes = new byte[31]; + System.arraycopy(first16KiB, offset + 0x30, nameBytes, 0, nameBytes.length); + return new String(nameBytes, Charset.forName("ASCII")).replace("\u0000", ""); + } + + public String dump() { + StringBuilder b = new StringBuilder(); + for (int i = 0; i < 128; i++) { + b.append(NumberUtils.hex(LittleEndian.getUInt8(first16KiB, offset + i), 2)); + b.append(' '); + } + return b.toString(); + } + + /** + * @see Object#toString() + */ + public String toString() { + StringBuilder builder = new StringBuilder(32); + builder.append('[').append(getName()).append(' '); + builder.append("t:").append(getType()).append(' '); + builder.append("s:").append(getStartOffset()).append(' '); + builder.append("e:").append(getEndOffset()).append(']'); + return builder.toString(); + } +} Added: trunk/fs/src/fs/org/jnode/partitions/apm/ApmPartitionTableType.java =================================================================== --- trunk/fs/src/fs/org/jnode/partitions/apm/ApmPartitionTableType.java (rev 0) +++ trunk/fs/src/fs/org/jnode/partitions/apm/ApmPartitionTableType.java 2012-08-09 14:08:21 UTC (rev 5904) @@ -0,0 +1,47 @@ +/* + * $Id: $ + * + * Copyright (C) 2003-2012 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.partitions.apm; + +import org.jnode.driver.Device; +import org.jnode.driver.block.BlockDeviceAPI; +import org.jnode.partitions.PartitionTable; +import org.jnode.partitions.PartitionTableException; +import org.jnode.partitions.PartitionTableType; + +/** + * Apple Partition Map (APM) partition table type. + * + * @author Luke Quinane + */ +public class ApmPartitionTableType implements PartitionTableType { + + public PartitionTable<?> create(byte[] firstSector, Device device) throws PartitionTableException { + return new ApmPartitionTable(this, firstSector, device); + } + + public String getName() { + return "APM"; + } + + public boolean supports(byte[] first16KiB, BlockDeviceAPI devApi) { + return ApmPartitionTable.containsPartitionTable(first16KiB); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2013-02-24 17:13:57
|
Revision: 5980 http://jnode.svn.sourceforge.net/jnode/?rev=5980&view=rev Author: lsantha Date: 2013-02-24 17:13:39 +0000 (Sun, 24 Feb 2013) Log Message: ----------- Updated headers. Modified Paths: -------------- trunk/fs/build-tests.xml trunk/fs/build.xml trunk/fs/descriptors/edtftpj.xml trunk/fs/descriptors/jcifs.xml trunk/fs/descriptors/org.jnode.driver.block.floppy.xml trunk/fs/descriptors/org.jnode.driver.block.ide.disk.xml trunk/fs/descriptors/org.jnode.driver.block.ramdisk.command.xml trunk/fs/descriptors/org.jnode.driver.block.ramdisk.xml trunk/fs/descriptors/org.jnode.driver.block.scsi.cdrom.xml trunk/fs/descriptors/org.jnode.driver.block.usb.storage.scsi.xml trunk/fs/descriptors/org.jnode.driver.block.usb.storage.xml trunk/fs/descriptors/org.jnode.driver.block.xml trunk/fs/descriptors/org.jnode.driver.bus.ide.atapi.xml trunk/fs/descriptors/org.jnode.driver.bus.ide.xml trunk/fs/descriptors/org.jnode.driver.bus.scsi.xml trunk/fs/descriptors/org.jnode.fs.command.xml trunk/fs/descriptors/org.jnode.fs.ext2.command.xml trunk/fs/descriptors/org.jnode.fs.ext2.test.command.xml trunk/fs/descriptors/org.jnode.fs.ext2.xml trunk/fs/descriptors/org.jnode.fs.fat.command.xml trunk/fs/descriptors/org.jnode.fs.fat.xml trunk/fs/descriptors/org.jnode.fs.ftpfs.command.xml trunk/fs/descriptors/org.jnode.fs.ftpfs.xml trunk/fs/descriptors/org.jnode.fs.hfsplus.command.xml trunk/fs/descriptors/org.jnode.fs.hfsplus.xml trunk/fs/descriptors/org.jnode.fs.initrd.xml trunk/fs/descriptors/org.jnode.fs.iso9660.xml trunk/fs/descriptors/org.jnode.fs.jfat.command.xml trunk/fs/descriptors/org.jnode.fs.jfat.xml trunk/fs/descriptors/org.jnode.fs.jifs.command.xml trunk/fs/descriptors/org.jnode.fs.jifs.def.xml trunk/fs/descriptors/org.jnode.fs.jifs.example.xml trunk/fs/descriptors/org.jnode.fs.jifs.xml trunk/fs/descriptors/org.jnode.fs.nfs.command.xml trunk/fs/descriptors/org.jnode.fs.nfs.xml trunk/fs/descriptors/org.jnode.fs.ntfs.xml trunk/fs/descriptors/org.jnode.fs.ramfs.def.xml trunk/fs/descriptors/org.jnode.fs.ramfs.xml trunk/fs/descriptors/org.jnode.fs.service.xml trunk/fs/descriptors/org.jnode.fs.smbfs.command.xml trunk/fs/descriptors/org.jnode.fs.smbfs.xml trunk/fs/descriptors/org.jnode.fs.xml trunk/fs/descriptors/org.jnode.partitions.apm.xml trunk/fs/descriptors/org.jnode.partitions.command.xml trunk/fs/descriptors/org.jnode.partitions.gpt.xml trunk/fs/descriptors/org.jnode.partitions.ibm.xml trunk/fs/descriptors/org.jnode.partitions.xml trunk/fs/descriptors/org.jnode.test.fs.xml Modified: trunk/fs/build-tests.xml =================================================================== --- trunk/fs/build-tests.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/build-tests.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,3 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <project name="JNode-FS-Tests" default="all" basedir="."> <import file="${basedir}/../all/build.xml"/> Modified: trunk/fs/build.xml =================================================================== --- trunk/fs/build.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/build.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,3 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <project name="JNode-FS" default="all" basedir="."> <typedef file="${basedir}/../all/lib/jnode.xml"/> Modified: trunk/fs/descriptors/edtftpj.xml =================================================================== --- trunk/fs/descriptors/edtftpj.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/edtftpj.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="edtftpj" @@ -24,4 +43,4 @@ <permission class="java.util.PropertyPermission" name="edtftp.log.log4j" actions="read"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/jcifs.xml =================================================================== --- trunk/fs/descriptors/jcifs.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/jcifs.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="jcifs" @@ -29,4 +48,4 @@ <handler protocol="smb" class="jcifs.smb.Handler" /> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.driver.block.floppy.xml =================================================================== --- trunk/fs/descriptors/org.jnode.driver.block.floppy.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.driver.block.floppy.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.driver.block.floppy" @@ -28,4 +47,4 @@ <permission class="org.jnode.system.resource.ResourcePermission" name="ioports"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.driver.block.ide.disk.xml =================================================================== --- trunk/fs/descriptors/org.jnode.driver.block.ide.disk.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.driver.block.ide.disk.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.driver.block.ide.disk" @@ -22,4 +41,4 @@ <mapper class="org.jnode.driver.block.ide.disk.IDEDiskDeviceToDriverMapper"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.driver.block.ramdisk.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.driver.block.ramdisk.command.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.driver.block.ramdisk.command.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.driver.block.ramdisk.command" Modified: trunk/fs/descriptors/org.jnode.driver.block.ramdisk.xml =================================================================== --- trunk/fs/descriptors/org.jnode.driver.block.ramdisk.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.driver.block.ramdisk.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.driver.block.ramdisk" Modified: trunk/fs/descriptors/org.jnode.driver.block.scsi.cdrom.xml =================================================================== --- trunk/fs/descriptors/org.jnode.driver.block.scsi.cdrom.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.driver.block.scsi.cdrom.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.driver.block.scsi.cdrom" @@ -23,4 +42,4 @@ <mapper class="org.jnode.driver.block.scsi.cdrom.CDROMDeviceToDriverMapper"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.driver.block.usb.storage.scsi.xml =================================================================== --- trunk/fs/descriptors/org.jnode.driver.block.usb.storage.scsi.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.driver.block.usb.storage.scsi.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,26 +1,45 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plugin SYSTEM "jnode.dtd"> - -<plugin id="org.jnode.driver.block.usb.storage.scsi" - name="JNode USB Mass Storage SCSI drivers" - version="@VERSION@" - license-name="lgpl" - provider-name="JNode.org"> - - <requires> - <import plugin="org.jnode.driver.bus.usb"/> - <import plugin="org.jnode.driver.block"/> - <import plugin="org.jnode.driver.bus.scsi"/> - <import plugin="org.jnode.driver.block.usb.storage"/> - </requires> - - <runtime> - <library name="jnode-fs.jar"> - <export name="org.jnode.driver.block.usb.storage.scsi.*"/> - </library> - </runtime> - - <extension point="org.jnode.driver.mappers"> - <mapper class="org.jnode.driver.block.usb.storage.scsi.USBStorageSCSIDeviceToDriverMapper"/> - </extension> -</plugin> +<?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> +<!DOCTYPE plugin SYSTEM "jnode.dtd"> + +<plugin id="org.jnode.driver.block.usb.storage.scsi" + name="JNode USB Mass Storage SCSI drivers" + version="@VERSION@" + license-name="lgpl" + provider-name="JNode.org"> + + <requires> + <import plugin="org.jnode.driver.bus.usb"/> + <import plugin="org.jnode.driver.block"/> + <import plugin="org.jnode.driver.bus.scsi"/> + <import plugin="org.jnode.driver.block.usb.storage"/> + </requires> + + <runtime> + <library name="jnode-fs.jar"> + <export name="org.jnode.driver.block.usb.storage.scsi.*"/> + </library> + </runtime> + + <extension point="org.jnode.driver.mappers"> + <mapper class="org.jnode.driver.block.usb.storage.scsi.USBStorageSCSIDeviceToDriverMapper"/> + </extension> +</plugin> Modified: trunk/fs/descriptors/org.jnode.driver.block.usb.storage.xml =================================================================== --- trunk/fs/descriptors/org.jnode.driver.block.usb.storage.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.driver.block.usb.storage.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.driver.block.usb.storage" Modified: trunk/fs/descriptors/org.jnode.driver.block.xml =================================================================== --- trunk/fs/descriptors/org.jnode.driver.block.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.driver.block.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.driver.block" @@ -21,4 +40,4 @@ <permission class="java.io.FilePermission" name="<<ALL FILES>>" actions="read,write,delete"/> <permission class="java.util.PropertyPermission" name="user.dir" actions="read"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.driver.bus.ide.atapi.xml =================================================================== --- trunk/fs/descriptors/org.jnode.driver.bus.ide.atapi.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.driver.bus.ide.atapi.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.driver.bus.ide.atapi" @@ -22,4 +41,4 @@ <mapper class="org.jnode.driver.bus.ide.atapi.ATAPIDeviceToDriverMapper"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.driver.bus.ide.xml =================================================================== --- trunk/fs/descriptors/org.jnode.driver.bus.ide.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.driver.bus.ide.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.driver.bus.ide" @@ -31,4 +50,4 @@ driver-class="org.jnode.driver.bus.ide.DefaultIDEControllerDriver"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.driver.bus.scsi.xml =================================================================== --- trunk/fs/descriptors/org.jnode.driver.bus.scsi.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.driver.bus.scsi.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.driver.bus.scsi" @@ -19,4 +38,4 @@ </library> </runtime> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.command.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.command.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.command" Modified: trunk/fs/descriptors/org.jnode.fs.ext2.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.ext2.command.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.ext2.command.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.ext2.command" Modified: trunk/fs/descriptors/org.jnode.fs.ext2.test.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.ext2.test.command.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.ext2.test.command.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.ext2.test.command" Modified: trunk/fs/descriptors/org.jnode.fs.ext2.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.ext2.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.ext2.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.ext2" Modified: trunk/fs/descriptors/org.jnode.fs.fat.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.fat.command.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.fat.command.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.fat.command" @@ -31,4 +50,4 @@ </sequence> </syntax> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.fat.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.fat.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.fat.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.fat" @@ -22,4 +41,4 @@ <type class="org.jnode.fs.fat.FatFileSystemType"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.ftpfs.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.ftpfs.command.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.ftpfs.command.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.ftpfs.command" Modified: trunk/fs/descriptors/org.jnode.fs.ftpfs.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.ftpfs.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.ftpfs.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.ftpfs" Modified: trunk/fs/descriptors/org.jnode.fs.hfsplus.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.hfsplus.command.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.hfsplus.command.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.hfsplus.command" @@ -31,4 +50,4 @@ </sequence> </syntax> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.hfsplus.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.hfsplus.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.hfsplus.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.hfsplus" Modified: trunk/fs/descriptors/org.jnode.fs.initrd.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.initrd.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.initrd.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.initrd" @@ -21,4 +40,4 @@ </library> </runtime> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.iso9660.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.iso9660.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.iso9660.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,5 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + Copyright (C) 2003-2013 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. +--> + <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.iso9660" @@ -23,4 +42,4 @@ <type class="org.jnode.fs.iso9660.ISO9660FileSystemType"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.jfat.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.jfat.command.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.jfat.command.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.jfat.command" @@ -42,4 +61,4 @@ <extension point="org.jnode.security.permissions"> <permission class="java.io.FilePermission" name="<<ALL FILES>>" actions="read,write,delete"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.jfat.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.jfat.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.jfat.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.jfat" Modified: trunk/fs/descriptors/org.jnode.fs.jifs.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.jifs.command.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.jifs.command.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.jifs.command" @@ -34,4 +53,4 @@ <permission class="org.jnode.permission.JNodePermission" name="startPlugin"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.jifs.def.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.jifs.def.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.jifs.def.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.jifs.def" @@ -27,4 +46,4 @@ <permission class="org.jnode.permission.JNodePermission" name="getVmThread"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.jifs.example.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.jifs.example.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.jifs.example.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.jifs.example" @@ -18,4 +37,4 @@ <info class="org.jnode.fs.jifs.JIFSFile" name="testfile"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.jifs.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.jifs.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.jifs.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.jifs" @@ -33,4 +52,4 @@ <permission class="org.jnode.permission.JNodePermission" name="getVmThread"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.nfs.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.nfs.command.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.nfs.command.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.nfs.command" Modified: trunk/fs/descriptors/org.jnode.fs.nfs.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.nfs.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.nfs.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.nfs" Modified: trunk/fs/descriptors/org.jnode.fs.ntfs.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.ntfs.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.ntfs.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,5 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + Copyright (C) 2003-2013 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. +--> + <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.ntfs" @@ -23,4 +42,4 @@ <type class="org.jnode.fs.ntfs.NTFSFileSystemType"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.ramfs.def.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.ramfs.def.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.ramfs.def.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.ramfs.def" Modified: trunk/fs/descriptors/org.jnode.fs.ramfs.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.ramfs.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.ramfs.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.ramfs" Modified: trunk/fs/descriptors/org.jnode.fs.service.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.service.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.service.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.service" @@ -21,4 +40,4 @@ <permission class="java.util.PropertyPermission" name="user.dir" actions="read"/> </extension> -</plugin> \ No newline at end of file +</plugin> Modified: trunk/fs/descriptors/org.jnode.fs.smbfs.command.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.smbfs.command.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.smbfs.command.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.smbfs.command" Modified: trunk/fs/descriptors/org.jnode.fs.smbfs.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.smbfs.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.smbfs.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs.smbfs" Modified: trunk/fs/descriptors/org.jnode.fs.xml =================================================================== --- trunk/fs/descriptors/org.jnode.fs.xml 2013-02-24 17:10:10 UTC (rev 5979) +++ trunk/fs/descriptors/org.jnode.fs.xml 2013-02-24 17:13:39 UTC (rev 5980) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.fs" Modified: trunk/fs/descriptors/org.jnode.partitio... [truncated message content] |
From: <ep...@us...> - 2013-11-08 09:35:30
|
Revision: 5988 http://sourceforge.net/p/jnode/svn/5988 Author: epr Date: 2013-11-08 09:35:27 +0000 (Fri, 08 Nov 2013) Log Message: ----------- Removed JRE-container library from Eclipse project settings. It is not needed and conflicts with newer JRE's Modified Paths: -------------- trunk/fs/.classpath trunk/fs/.settings/org.eclipse.jdt.core.prefs Modified: trunk/fs/.classpath =================================================================== --- trunk/fs/.classpath 2013-06-24 18:33:20 UTC (rev 5987) +++ trunk/fs/.classpath 2013-11-08 09:35:27 UTC (rev 5988) @@ -4,7 +4,6 @@ <classpathentry excluding="**/.svn/**" kind="src" path="src/driver"/> <classpathentry excluding="**/.svn/**" kind="src" path="src/test"/> <classpathentry kind="src" path="/shell"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="lib" path="lib/edtftpj-1.5.2.jar"/> <classpathentry kind="lib" path="lib/jcifs-1.2.6.jar"/> <classpathentry combineaccessrules="false" kind="src" path="/net"/> Modified: trunk/fs/.settings/org.eclipse.jdt.core.prefs =================================================================== --- trunk/fs/.settings/org.eclipse.jdt.core.prefs 2013-06-24 18:33:20 UTC (rev 5987) +++ trunk/fs/.settings/org.eclipse.jdt.core.prefs 2013-11-08 09:35:27 UTC (rev 5988) @@ -1,6 +1,6 @@ -#Mon Jul 14 11:33:25 CEST 2008 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.6 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |