[hackers] [sbase] add which || Hiltjo Posthuma

From: <git_AT_suckless.org>
Date: Mon, 27 Apr 2015 17:58:49 +0200 (CEST)

commit 58cb564bbde24c758caf3707aa89fb9f27267beb
Author: Hiltjo Posthuma <hiltjo_AT_codemadness.org>
Date: Mon Apr 27 16:24:43 2015 +0200

    add which

diff --git a/Makefile b/Makefile
index 27ce5ef..9baecd8 100644
--- a/Makefile
+++ b/Makefile
_AT_@ -152,6 +152,7 @@ BIN =\
         uudecode\
         uuencode\
         wc\
+ which\
         xargs\
         yes
 
diff --git a/README b/README
index 2009e49..46b2bf7 100644
--- a/README
+++ b/README
_AT_@ -91,6 +91,7 @@ The following tools are implemented:
 =*|o uudecode .
 =*|o uuencode .
 #*|o wc .
+=* x which .
 =*|o xargs (-p)
 =*|x yes .
 
diff --git a/which.1 b/which.1
new file mode 100644
index 0000000..05989ae
--- /dev/null
+++ b/which.1
_AT_@ -0,0 +1,35 @@
+.Dd April 27, 2015
+.Dt WHICH 1
+.Os sbase
+.Sh NAME
+.Nm which
+.Nd locate a program file (or files) in the path
+.Sh SYNOPSIS
+.Nm
+.Op Fl a
+.Op Ar name ...
+.Sh DESCRIPTION
+.Nm
+looks for programs in
+.Ev PATH
+.
+.Pp
+If
+.Fl a
+is specified it will display all matches and not stop at the first match.
+.Sh EXIT STATUS
+The
+.Nm
+utility exits with one of the following values:
+.Bl -tag -width Ds
+.It 0
+All names were successfully resolved.
+.It 1
+Some names were resolved but not all.
+.It 2
+No names were resolved.
+.El
+.Sh DIAGNOSTICS
+If a program is not found it will print "Command not found" to stderr.
+.Sh SEE ALSO
+.Xr environ 7
diff --git a/which.c b/which.c
new file mode 100644
index 0000000..ed09e07
--- /dev/null
+++ b/which.c
_AT_@ -0,0 +1,80 @@
+#include <sys/stat.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "arg.h"
+#include "util.h"
+
+static int aflag;
+
+static int
+which(const char *path, const char *name)
+{
+ char file[PATH_MAX], *p, *s, *ptr;
+ size_t len;
+ struct stat st;
+ int found = 0;
+
+ p = ptr = estrdup(path);
+ for (s = p; (s = strsep(&p, ":")); ) {
+ if (!s[0])
+ s = ".";
+ len = strlen(s);
+
+ if (snprintf(file, sizeof(file), "%s%s%s",
+ s,
+ len > 0 && s[len - 1] != '/' ? "/" : "",
+ name) >= sizeof(file))
+ eprintf("path too long\n");
+
+ if (stat(file, &st) == 0 && S_ISREG(st.st_mode) &&
+ access(file, X_OK) == 0) {
+ found = 1;
+ puts(file);
+ if (!aflag)
+ break;
+ }
+ }
+ free(ptr);
+
+ return found;
+}
+
+static void
+usage(void)
+{
+ eprintf("usage: %s [-a] name...\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *path;
+ int i, found;
+
+ ARGBEGIN {
+ case 'a':
+ aflag = 1;
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if (!argc)
+ usage();
+
+ if (!(path = getenv("PATH")))
+ eprintf("$PATH not set\n");
+
+ for (i = 0, found = 0; i < argc; i++) {
+ if (which(path, argv[i]))
+ found++;
+ else
+ weprintf("%s: Command not found.\n", argv[i]);
+ }
+ return !found ? 2 : found == argc ? 0 : 1;
+}
Received on Mon Apr 27 2015 - 17:58:49 CEST

This archive was generated by hypermail 2.3.0 : Mon Apr 27 2015 - 18:00:12 CEST