use of org.apache.felix.service.command.Process in project felix by apache.
the class Builtin method format.
public CharSequence format(CommandSession session, Object arg) {
Process process = Process.Utils.current();
CharSequence result = session.format(arg, Converter.INSPECT);
process.out().println(result);
return result;
}
use of org.apache.felix.service.command.Process in project felix by apache.
the class Builtin method tac.
/*
* the following methods depend on the internals of the runtime implementation.
* ideally, they should be available via some API.
*/
public Object tac(CommandSession session, String[] argv) throws IOException {
final String[] usage = { "tac - capture stdin as String or List and optionally write to file.", "Usage: tac [-al] [FILE]", " -a --append append to FILE", " -l --list return List<String>", " -? --help show help" };
Process process = Process.Utils.current();
Options opt = Options.compile(usage).parse(argv);
if (opt.isSet("help")) {
opt.usage(process.err());
return null;
}
List<String> args = opt.args();
BufferedWriter fw = null;
if (args.size() == 1) {
Path path = session.currentDir().resolve(args.get(0));
Set<OpenOption> options = new HashSet<>();
options.add(StandardOpenOption.WRITE);
options.add(StandardOpenOption.CREATE);
if (opt.isSet("append")) {
options.add(StandardOpenOption.APPEND);
} else {
options.add(StandardOpenOption.TRUNCATE_EXISTING);
}
fw = Files.newBufferedWriter(path, StandardCharsets.UTF_8, options.toArray(new OpenOption[options.size()]));
}
StringWriter sw = new StringWriter();
BufferedReader rdr = new BufferedReader(new InputStreamReader(process.in()));
ArrayList<String> list = null;
if (opt.isSet("list")) {
list = new ArrayList<String>();
}
boolean first = true;
String s;
while ((s = rdr.readLine()) != null) {
if (list != null) {
list.add(s);
} else {
if (!first) {
sw.write(' ');
}
first = false;
sw.write(s);
}
if (fw != null) {
fw.write(s);
fw.newLine();
}
}
if (fw != null) {
fw.close();
}
return list != null ? list : sw.toString();
}
use of org.apache.felix.service.command.Process in project felix by apache.
the class Builtin method unsetopt.
public void unsetopt(CommandSession session, String[] argv) {
Process process = Process.Utils.current();
Commands.unsetopt(Shell.getReader(session), process.out(), process.err(), argv);
}
use of org.apache.felix.service.command.Process in project felix by apache.
the class Posix method ls.
protected void ls(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = { "ls - list files", "Usage: ls [OPTIONS] [PATTERNS...]", " -? --help show help", " -1 list one entry per line", " -C multi-column output", " --color=WHEN colorize the output, may be `always', `never' or `auto'", " -a list entries starting with .", " -F append file type indicators", " -m comma separated", " -l long listing", " -S sort by size", " -f output is not sorted", " -r reverse sort order", " -t sort by modification time", " -x sort horizontally", " -L list referenced file for links", " -h print sizes in human readable form" };
Options opt = parseOptions(session, usage, argv);
String color = opt.isSet("color") ? opt.get("color") : "auto";
boolean colored;
switch(color) {
case "always":
case "yes":
case "force":
colored = true;
break;
case "never":
case "no":
case "none":
colored = false;
break;
case "auto":
case "tty":
case "if-tty":
colored = process.isTty(1);
break;
default:
throw new IllegalArgumentException("invalid argument ‘" + color + "’ for ‘--color’");
}
Map<String, String> colors = colored ? getLsColorMap(session) : Collections.emptyMap();
class PathEntry implements Comparable<PathEntry> {
final Path abs;
final Path path;
final Map<String, Object> attributes;
public PathEntry(Path abs, Path root) {
this.abs = abs;
this.path = abs.startsWith(root) ? root.relativize(abs) : abs;
this.attributes = readAttributes(abs);
}
@Override
public int compareTo(PathEntry o) {
int c = doCompare(o);
return opt.isSet("r") ? -c : c;
}
private int doCompare(PathEntry o) {
if (opt.isSet("f")) {
return -1;
}
if (opt.isSet("S")) {
long s0 = attributes.get("size") != null ? ((Number) attributes.get("size")).longValue() : 0L;
long s1 = o.attributes.get("size") != null ? ((Number) o.attributes.get("size")).longValue() : 0L;
return s0 > s1 ? -1 : s0 < s1 ? 1 : path.toString().compareTo(o.path.toString());
}
if (opt.isSet("t")) {
long t0 = attributes.get("lastModifiedTime") != null ? ((FileTime) attributes.get("lastModifiedTime")).toMillis() : 0L;
long t1 = o.attributes.get("lastModifiedTime") != null ? ((FileTime) o.attributes.get("lastModifiedTime")).toMillis() : 0L;
return t0 > t1 ? -1 : t0 < t1 ? 1 : path.toString().compareTo(o.path.toString());
}
return path.toString().compareTo(o.path.toString());
}
boolean isNotDirectory() {
return is("isRegularFile") || is("isSymbolicLink") || is("isOther");
}
boolean isDirectory() {
return is("isDirectory");
}
private boolean is(String attr) {
Object d = attributes.get(attr);
return d instanceof Boolean && (Boolean) d;
}
String display() {
String type;
String suffix;
String link = "";
if (is("isSymbolicLink")) {
type = "sl";
suffix = "@";
try {
Path l = Files.readSymbolicLink(abs);
link = " -> " + l.toString();
} catch (IOException e) {
// ignore
}
} else if (is("isDirectory")) {
type = "dr";
suffix = "/";
} else if (is("isExecutable")) {
type = "ex";
suffix = "*";
} else if (is("isOther")) {
type = "ot";
suffix = "";
} else {
type = "";
suffix = "";
}
String col = colors.get(type);
boolean addSuffix = opt.isSet("F");
if (col != null && !col.isEmpty()) {
return "\033[" + col + "m" + path.toString() + "\033[m" + (addSuffix ? suffix : "") + link;
} else {
return path.toString() + (addSuffix ? suffix : "") + link;
}
}
String longDisplay() {
String username;
if (attributes.containsKey("owner")) {
username = Objects.toString(attributes.get("owner"), null);
} else {
username = "owner";
}
if (username.length() > 8) {
username = username.substring(0, 8);
} else {
for (int i = username.length(); i < 8; i++) {
username = username + " ";
}
}
String group;
if (attributes.containsKey("group")) {
group = Objects.toString(attributes.get("group"), null);
} else {
group = "group";
}
if (group.length() > 8) {
group = group.substring(0, 8);
} else {
for (int i = group.length(); i < 8; i++) {
group = group + " ";
}
}
Number length = (Number) attributes.get("size");
if (length == null) {
length = 0L;
}
String lengthString;
if (opt.isSet("h")) {
double l = length.longValue();
String unit = "B";
if (l >= 1000) {
l /= 1024;
unit = "K";
if (l >= 1000) {
l /= 1024;
unit = "M";
if (l >= 1000) {
l /= 1024;
unit = "T";
}
}
}
if (l < 10 && length.longValue() > 1000) {
lengthString = String.format("%.1f", l) + unit;
} else {
lengthString = String.format("%3.0f", l) + unit;
}
} else {
lengthString = String.format("%1$8s", length);
}
@SuppressWarnings("unchecked") Set<PosixFilePermission> perms = (Set<PosixFilePermission>) attributes.get("permissions");
if (perms == null) {
perms = EnumSet.noneOf(PosixFilePermission.class);
}
// TODO: all fields should be padded to align
return (is("isDirectory") ? "d" : (is("isSymbolicLink") ? "l" : (is("isOther") ? "o" : "-"))) + PosixFilePermissions.toString(perms) + " " + String.format("%3s", (attributes.containsKey("nlink") ? attributes.get("nlink").toString() : "1")) + " " + username + " " + group + " " + lengthString + " " + toString((FileTime) attributes.get("lastModifiedTime")) + " " + display();
}
protected String toString(FileTime time) {
long millis = (time != null) ? time.toMillis() : -1L;
if (millis < 0L) {
return "------------";
}
ZonedDateTime dt = Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault());
// Less than six months
if (System.currentTimeMillis() - millis < 183L * 24L * 60L * 60L * 1000L) {
return DateTimeFormatter.ofPattern("MMM ppd HH:mm").format(dt);
} else // Older than six months
{
return DateTimeFormatter.ofPattern("MMM ppd yyyy").format(dt);
}
}
protected Map<String, Object> readAttributes(Path path) {
Map<String, Object> attrs = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (String view : path.getFileSystem().supportedFileAttributeViews()) {
try {
Map<String, Object> ta = Files.readAttributes(path, view + ":*", getLinkOptions(opt.isSet("L")));
ta.entrySet().forEach(e -> attrs.putIfAbsent(e.getKey(), e.getValue()));
} catch (IOException e) {
// Ignore
}
}
attrs.computeIfAbsent("isExecutable", s -> Files.isExecutable(path));
attrs.computeIfAbsent("permissions", s -> getPermissionsFromFile(path.toFile()));
return attrs;
}
}
Path currentDir = session.currentDir();
// Listing
List<Path> expanded = new ArrayList<>();
if (opt.args().isEmpty()) {
expanded.add(currentDir);
} else {
opt.args().forEach(s -> expanded.add(currentDir.resolve(s)));
}
boolean listAll = opt.isSet("a");
Predicate<Path> filter = p -> listAll || !p.getFileName().toString().startsWith(".");
List<PathEntry> all = expanded.stream().filter(filter).map(p -> new PathEntry(p, currentDir)).sorted().collect(Collectors.toList());
// Print files first
List<PathEntry> files = all.stream().filter(PathEntry::isNotDirectory).collect(Collectors.toList());
PrintStream out = process.out();
Consumer<Stream<PathEntry>> display = s -> {
boolean optLine = opt.isSet("1");
boolean optComma = opt.isSet("m");
boolean optLong = opt.isSet("l");
boolean optCol = opt.isSet("C");
if (!optLine && !optComma && !optLong && !optCol) {
if (process.isTty(1)) {
optCol = true;
} else {
optLine = true;
}
}
// One entry per line
if (optLine) {
s.map(PathEntry::display).forEach(out::println);
} else // Comma separated list
if (optComma) {
out.println(s.map(PathEntry::display).collect(Collectors.joining(", ")));
} else // Long listing
if (optLong) {
s.map(PathEntry::longDisplay).forEach(out::println);
} else // Column listing
if (optCol) {
toColumn(session, process, out, s.map(PathEntry::display), opt.isSet("x"));
}
};
boolean space = false;
if (!files.isEmpty()) {
display.accept(files.stream());
space = true;
}
// Print directories
List<PathEntry> directories = all.stream().filter(PathEntry::isDirectory).collect(Collectors.toList());
for (PathEntry entry : directories) {
if (space) {
out.println();
}
space = true;
Path path = currentDir.resolve(entry.path);
if (expanded.size() > 1) {
out.println(currentDir.relativize(path).toString() + ":");
}
display.accept(Stream.concat(Arrays.asList(".", "..").stream().map(path::resolve), Files.list(path)).filter(filter).map(p -> new PathEntry(p, path)).sorted());
}
}
use of org.apache.felix.service.command.Process in project felix by apache.
the class Posix method wc.
protected void wc(CommandSession session, Process process, String[] argv) throws Exception {
String[] usage = { "wc - word, line, character, and byte count", "Usage: wc [OPTIONS] [FILES]", " -? --help Show help", " -l --lines Print line counts", " -c --bytes Print byte counts", " -m --chars Print character counts", " -w --words Print word counts" };
Options opt = parseOptions(session, usage, argv);
List<Source> sources = new ArrayList<>();
if (opt.args().isEmpty()) {
opt.args().add("-");
}
for (String arg : opt.args()) {
if ("-".equals(arg)) {
sources.add(new StdInSource(process));
} else {
sources.add(new PathSource(session.currentDir().resolve(arg), arg));
}
}
boolean displayLines = opt.isSet("lines");
boolean displayWords = opt.isSet("words");
boolean displayChars = opt.isSet("chars");
boolean displayBytes = opt.isSet("bytes");
if (displayChars) {
displayBytes = false;
}
if (!displayLines && !displayWords && !displayChars && !displayBytes) {
displayLines = true;
displayWords = true;
displayBytes = true;
}
String format = "";
if (displayLines) {
format += "%1$8d";
}
if (displayWords) {
format += "%2$8d";
}
if (displayChars) {
format += "%3$8d";
}
if (displayBytes) {
format += "%4$8d";
}
format += " %5s";
int totalLines = 0;
int totalBytes = 0;
int totalChars = 0;
int totalWords = 0;
for (Source src : sources) {
try (InputStream is = src.read()) {
AtomicInteger lines = new AtomicInteger();
AtomicInteger bytes = new AtomicInteger();
AtomicInteger chars = new AtomicInteger();
AtomicInteger words = new AtomicInteger();
AtomicBoolean inWord = new AtomicBoolean();
AtomicBoolean lastNl = new AtomicBoolean(true);
InputStream isc = new FilterInputStream(is) {
@Override
public int read() throws IOException {
int b = super.read();
if (b >= 0) {
bytes.incrementAndGet();
}
return b;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int nb = super.read(b, off, len);
if (nb > 0) {
bytes.addAndGet(nb);
}
return nb;
}
};
IntConsumer consumer = cp -> {
chars.incrementAndGet();
boolean ws = Character.isWhitespace(cp);
if (inWord.getAndSet(!ws) && ws) {
words.incrementAndGet();
}
if (cp == '\n') {
lines.incrementAndGet();
lastNl.set(true);
} else {
lastNl.set(false);
}
};
Reader reader = new InputStreamReader(isc);
while (true) {
int h = reader.read();
if (Character.isHighSurrogate((char) h)) {
int l = reader.read();
if (Character.isLowSurrogate((char) l)) {
int cp = Character.toCodePoint((char) h, (char) l);
consumer.accept(cp);
} else {
consumer.accept(h);
if (l >= 0) {
consumer.accept(l);
} else {
break;
}
}
} else if (h >= 0) {
consumer.accept(h);
} else {
break;
}
}
if (inWord.get()) {
words.incrementAndGet();
}
if (!lastNl.get()) {
lines.incrementAndGet();
}
process.out().println(String.format(format, lines.get(), words.get(), chars.get(), bytes.get(), src.getName()));
totalBytes += bytes.get();
totalChars += chars.get();
totalWords += words.get();
totalLines += lines.get();
}
}
if (sources.size() > 1) {
process.out().println(String.format(format, totalLines, totalWords, totalChars, totalBytes, "total"));
}
}
Aggregations