add which

This commit is contained in:
Hiltjo Posthuma 2015-04-27 16:24:43 +02:00 committed by sin
parent 5595af5742
commit 58cb564bbd
4 changed files with 117 additions and 0 deletions

View File

@ -152,6 +152,7 @@ BIN =\
uudecode\
uuencode\
wc\
which\
xargs\
yes

1
README
View File

@ -91,6 +91,7 @@ The following tools are implemented:
=*|o uudecode .
=*|o uuencode .
#*|o wc .
=* x which .
=*|o xargs (-p)
=*|x yes .

35
which.1 Normal file
View File

@ -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

80
which.c Normal file
View File

@ -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;
}