/* * $Id$ * * Copyright (C) 2003-2015 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.command.archive; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; 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 * TODO use GZIP env variable * TODO implement name/noname flag usage * @author chris boertien */ public class GZip extends ArchiveCommand { 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"; 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); private List<File> files; protected String suffix = ".gz"; protected boolean recurse; protected GZip(String s) { super(s); createStreamBuffer(4096); } public void execute(String command) { super.execute(command); parseOptions(command); try { if (compress) { compress(); } else { decompress(); } rc = 0; } catch (IOException e) { error(err_exception_uncaught); rc = 1; } finally { exit(rc); } } private void compress() throws IOException { InputStream in = null; OutputStream out = null; GZIPOutputStream gzout = null; if (use_stdout) { gzout = new GZIPOutputStream(stdout, BUFFER_SIZE); } for (File file : files) { if (file.getName().equals("-")) { processStream(stdin, gzout); continue; } try { if (use_stdout) { if ((in = openFileRead(file)) == null) { rc = 1; continue; } processStream(in, gzout); continue; } try { File gzfile = new File(file.getAbsolutePath() + suffix); if ((out = openFileWrite(gzfile, true, force)) == null) { rc = 1; continue; } gzout = new GZIPOutputStream(out, BUFFER_SIZE); if ((in = openFileRead(file)) == null) { rc = 1; continue; } processStream(in, gzout); gzout.finish(); float sizeDiff = ((float) gzfile.length() / (float) file.length()) * 100; notice(String.format(fmt_size_diff, file, sizeDiff, gzfile)); file.delete(); } finally { close(gzout); } } finally { close(in); } } if (use_stdout) { gzout.finish(); // TEST need to see if this is even necessary, and if it is // should it be within a finally block gzout.close(); } } private void decompress() throws IOException { InputStream in = null; OutputStream out = stdout; for (File gzfile : files) { if (gzfile.getName().equals("-")) { processStream(new GZIPInputStream(stdin, BUFFER_SIZE), out); continue; } try { if (use_stdout) { if ((in = new GZIPInputStream(openFileRead(gzfile), BUFFER_SIZE)) == null) { continue; } processStream(in, out); continue; } try { File file = stripSuffix(gzfile); if (file == null) { continue; } if ((out = openFileWrite(file, true, force)) == null) { rc = 1; continue; } if ((in = new GZIPInputStream(openFileRead(gzfile), BUFFER_SIZE)) == null) { continue; } processStream(in, out); float sizeDiff = ((float) gzfile.length() / (float) file.length()) * 100; notice(String.format(fmt_size_diff, gzfile, sizeDiff, file)); gzfile.delete(); } finally { close(out); } } finally { close(in); } } } protected void test(File[] files) {} protected void list(File[] files) {} private File stripSuffix(File file) { String name = file.getAbsolutePath(); if (!name.endsWith(suffix)) { notice(name + " unknown suffix -- ignore"); return null; } name = name.substring(0, name.length() - suffix.length()); return new File(name); } private void parseOptions(String command) { if (!command.equals("zcat")) { if (Suffix.isSet()) suffix = Suffix.getValue(); recurse = Recurse.isSet(); } files = new ArrayList<File>(); for (File file : Files.getValues()) { if (file.isDirectory()) { if (recurse) { for (File f : file.listFiles()) { if (!f.isDirectory()) { files.add(f); } } } } else { if (file.getName().equals("-")) { use_stdout = true; } files.add(file); } } if (files.size() == 0) { files.add(new File("-")); } if (files.size() == 1 && files.get(0).getName().equals("-")) { use_stdout = true; } } }