/** * $Id: xfile.java 356 2010-01-01 15:46:31Z daldei $ * $Date: 2010-01-01 10:46:31 -0500 (Fri, 01 Jan 2010) $ * */ package org.xmlsh.internal.commands; import static org.xmlsh.util.UnifiedFileAttributes.MatchFlag.HIDDEN_NAME; import static org.xmlsh.util.UnifiedFileAttributes.MatchFlag.HIDDEN_SYS; import static org.xmlsh.util.UnifiedFileAttributes.MatchFlag.SYSTEM; import java.io.IOException; import java.io.InputStream; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; import java.util.List; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import org.xmlsh.annotations.Command; import org.xmlsh.core.CoreException; import org.xmlsh.core.InputPort; import org.xmlsh.core.Options; import org.xmlsh.core.XCommand; import org.xmlsh.core.XValue; import org.xmlsh.core.io.FileInputPort; import org.xmlsh.core.io.OutputPort; import org.xmlsh.sh.shell.SerializeOpts; import org.xmlsh.util.FileUtils; import org.xmlsh.util.IPathTreeVisitor; import org.xmlsh.util.PathMatchOptions; import org.xmlsh.util.UnifiedFileAttributes; import org.xmlsh.util.Util; import org.xmlsh.util.XFile; import org.xmlsh.util.commands.Checksum; @Command public class xmd5sum extends XCommand { private static final String sFile = "file"; private static final String sName = "name"; private static final String sMd5 = "md5"; private static final String sLen = "length"; private static final String sPath = "path"; private static String sDocRoot = "xmd5"; private boolean opt_a; private boolean opt_s; private boolean opt_r; private Checksum.Format format = Checksum.Format.HEX; @Override public int run(List<XValue> args) throws Exception { mLogger.entry(args); Options opts = new Options( "b=binary,x=xml,a=all,s=system,r=relative,format:", SerializeOpts .getOptionDefs()); opts.parse(args); args = opts.getRemainingArgs(); XMLStreamWriter out = null; OutputPort stdout = mShell.getEnv().getStdout(); setSerializeOpts(opts); opt_a = opts.hasOpt("a"); opt_s = opts.hasOpt("s"); opt_r = opts.hasOpt("r"); if(opts.hasOpt("format")) { String sf = opts.getOptString("format", null); switch(sf){ case "binary": case "bin": format = Checksum.Format.BINARY; break; case "hex": format = Checksum.Format.HEX; break; case "64": case "base64": format = Checksum.Format.BASE64; break; default: this.printErr("Invalid format: " + sf); return 1; } } out = stdout.asXMLStreamWriter(getSerializeOpts()); out.writeStartDocument(); out.writeStartElement(sDocRoot); if(args.isEmpty()) args.add(XValue.newXValue("-")); // else // out.writeAttribute("pwd",FileUtils.toJavaPath(curDir.toString())); for(XValue arg : args) { String sArg = arg.toString(); if(sArg.equals("-") || Util.tryURL(sArg) != null) writeMD5(getInput(arg), sArg, null, out); else { Path path = getEnv().getShell().getPath(sArg); if(path == null || !Files.exists(path, LinkOption.NOFOLLOW_LINKS)) { this.printErr("xmd5sum: cannot access " + sArg + " : No such file or directory"); continue; } FileUtils.walkPathTree(path, true, new ListVisitor(out), (new PathMatchOptions()).withFlagsHidden(opt_a ? null : HIDDEN_SYS, opt_a ? null : HIDDEN_NAME, opt_s ? null : SYSTEM) ); } } out.writeEndElement(); out.writeEndDocument(); out.flush(); out.close(); stdout.writeSequenceTerminator(getSerializeOpts()); return mLogger.exit(0); } public class ListVisitor implements IPathTreeVisitor { XMLStreamWriter writer; public ListVisitor(XMLStreamWriter writer) { this.writer = writer; } @Override public FileVisitResult enterDirectory(Path root, Path directory, UnifiedFileAttributes attrs) { return FileVisitResult.CONTINUE; } @Override public FileVisitResult exitDirectory(Path root, Path directory, UnifiedFileAttributes attrs) { return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitDirectory(Path root, Path directory, UnifiedFileAttributes uattrs) throws IOException { mLogger.entry(root, directory, uattrs); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path root, Path path, UnifiedFileAttributes attrs) throws IOException { mLogger.entry(root, path, attrs); if(!attrs.isRegularFile()) { printErr("Not a regular file: " + path.toString()); return FileVisitResult.CONTINUE; } if(!Files.isReadable(path)) { printErr("File not readable: " + path.toString()); return FileVisitResult.CONTINUE; } try (InputPort port = new FileInputPort(path.toFile())) { XFile xf = new XFile(path, root, attrs); writeMD5(port, xf.getName(), xf, writer); } catch (CoreException | XMLStreamException e) { Util.wrapIOException(e); } return FileVisitResult.CONTINUE; } public void error(String s, Exception e) { printErr(s, e); } } /* * * class ListVisitor extends PathTreeVisitor { * * XMLStreamWriter writer; * * public ListVisitor(Path root, XMLStreamWriter writer) { * super(root, new PathMatchOptions(true, opt_a, opt_s, false)); * this.writer = writer; * } * * @Override * public void visitFile( boolean root,Path path, BasicFileAttributes * attrs)throws IOException { * * mLogger.entry(root, path, attrs); * if( ! attrs.isRegularFile() ){ * * printErr("Not a regular file: " + path.toString()); * return ; * } * if( ! Files.isReadable( path )){ * * printErr("File not readable: " + path.toString()); * return ; * } * * * try ( InputPort port = new FileInputPort( path.toFile() ) ){ * XFile xf = new XFile(path,mRoot); * * writeMD5( port , xf.getName(), xf , writer ); * } catch (CoreException | XMLStreamException e) { * Util.wrapIOException(e); * } * } * * @Override * public void enterDirectory(boolean root,Path path, BasicFileAttributes * attrs)throws IOException { * * } * * @Override * public void exitDirectory(boolean root,Path dir )throws IOException { * } * * * * @Override * public void error(String s, Exception e) { * printErr( s , e); * * } * * * * } * */ private void writeMD5(InputPort inp, String name, XFile xf, XMLStreamWriter out) throws CoreException, IOException, XMLStreamException { mLogger.entry(inp, xf, out); try (InputStream in = inp.asInputStream(getSerializeOpts())) { Checksum cs = Checksum.calcChecksum(in); out.writeStartElement(sFile); out.writeAttribute(sName, name); if(opt_r) { if(xf != null && !Util.isBlank(xf.getPwdRelativeName())) out.writeAttribute(sPath, xf.getPwdRelativeName()); } else { if(xf != null && !Util.isBlank(xf.getPath())) out.writeAttribute(sPath, xf.getPath()); } out.writeAttribute(sMd5, cs.getMD5(format)); out.writeAttribute(sLen, String.valueOf(cs.getLength())); out.writeEndElement(); } mLogger.exit(); } } // // // Copyright (C) 2008-2014 David A. Lee. // // The contents of this file are subject to the "Simplified BSD License" (the // "License"); // you may not use this file except in compliance with the License. You may // obtain a copy of the // License at http://www.opensource.org/licenses/bsd-license.php // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. // See the License for the specific language governing rights and limitations // under the License. // // The Original Code is: all this file. // // The Initial Developer of the Original Code is David A. Lee // // Portions created by (your name) are Copyright (C) (your legal entity). All // Rights Reserved. // // Contributor(s): none. //