/** * $Id: ls.java 346 2009-12-03 13:14:51Z daldei $ * $Date: 2009-12-03 08:14:51 -0500 (Thu, 03 Dec 2009) $ * */ package org.xmlsh.posix.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.File; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.attribute.PosixFilePermission; import java.nio.file.attribute.PosixFilePermissions; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; import org.xmlsh.core.Options; import org.xmlsh.core.XCommand; import org.xmlsh.core.XValue; 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; /** * Posix command ls * Rewritten from xquery to native java so that it can stream large lists efficiently * * @author David A. Lee */ public class ls extends XCommand { private boolean opt_a = false; private boolean opt_R = false; private boolean opt_l = false; private boolean opt_s = false ; // system @Override public int run(List<XValue> args) throws Exception { Options opts = new Options("a=all,l=long,R=recurse,r,s=system", SerializeOpts .getOptionDefs()); opts.parse(args); args = opts.getRemainingArgs(); OutputPort stdout = getStdout(); SerializeOpts serializeOpts = getSerializeOpts(opts); PrintWriter writer = stdout.asPrintWriter(serializeOpts); if (args == null) args = new ArrayList<XValue>(); if (args.size() == 0) args.add(XValue.newXValue("")); opt_l = opts.hasOpt("l"); opt_a = opts.hasOpt("a"); opt_R = opts.hasOpt("R") || opts.hasOpt("r"); opt_s = opts.hasOpt("s"); int ret = 0; for (XValue arg : args) { // Must go to Shell API to get raw files String sArg = arg.toString(); File dir = getEnv().getShell().getFile(sArg); if (dir == null || !dir.exists()) { printErr("ls: cannot access " + sArg + " : No such file or directory"); ret++; continue; } Path pdir = FileUtils.asValidPath(dir); if( pdir == null ){ printErr("ls: cannot access " + sArg + " : No such file or directory"); ret++; continue; } FileUtils.walkPathTree(pdir, opt_R , new ListVisitor(writer), (new PathMatchOptions()). withFlagsHidden( opt_a ? null : HIDDEN_SYS , opt_a ? null : HIDDEN_NAME , opt_s ? null : SYSTEM ) ); } // writer.write(serializeOpts.getSequence_term()); writer.close(); return ret; } public class ListVisitor implements IPathTreeVisitor { PrintWriter writer; public ListVisitor( PrintWriter 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 attrs) throws IOException { if( root.equals(directory)) return FileVisitResult.CONTINUE; if (opt_l) writeFlags(directory, attrs); writer.write(FileUtils.toJavaPath(root.relativize(directory).toString())); writer.write(getSerializeOpts().getSequence_sep()); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path root, Path path, UnifiedFileAttributes uattrs) throws IOException { if (opt_l) writeFlags(path, uattrs); if( path.equals(root)) writer.write(FileUtils.toJavaPath(path.getFileName().toString())); else writer.write(FileUtils.toJavaPath(root.relativize(path).toString())); writer.write(getSerializeOpts().getSequence_sep()); return FileVisitResult.CONTINUE ; } private void writeFlags(Path path, UnifiedFileAttributes uattrs) throws IOException { StringBuffer flags = new StringBuffer(); Set<PosixFilePermission> perms = FileUtils.getPosixFilePermissions(path,LinkOption.NOFOLLOW_LINKS); flags.append(uattrs.isDirectory() ? "d" : "-"); flags.append( PosixFilePermissions.toString( perms ) ); flags.append(" "); long len = uattrs.size(); String slen = String.valueOf(len); slen = String.format("%1$10s", slen); flags.append(slen); flags.append(" "); String sDate = String.format("%1$tF %1$tT", new Date(Files .getLastModifiedTime(path, LinkOption.NOFOLLOW_LINKS) .toMillis())); flags.append(sDate); flags.append(" "); writer.write(flags.toString()); } public void error(String s, Exception e) { printErr( s , e); } } } // // // 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. //