add which
This commit is contained in:
parent
5595af5742
commit
58cb564bbd
1
Makefile
1
Makefile
|
@ -152,6 +152,7 @@ BIN =\
|
||||||
uudecode\
|
uudecode\
|
||||||
uuencode\
|
uuencode\
|
||||||
wc\
|
wc\
|
||||||
|
which\
|
||||||
xargs\
|
xargs\
|
||||||
yes
|
yes
|
||||||
|
|
||||||
|
|
1
README
1
README
|
@ -91,6 +91,7 @@ The following tools are implemented:
|
||||||
=*|o uudecode .
|
=*|o uudecode .
|
||||||
=*|o uuencode .
|
=*|o uuencode .
|
||||||
#*|o wc .
|
#*|o wc .
|
||||||
|
=* x which .
|
||||||
=*|o xargs (-p)
|
=*|o xargs (-p)
|
||||||
=*|x yes .
|
=*|x yes .
|
||||||
|
|
||||||
|
|
35
which.1
Normal file
35
which.1
Normal 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
80
which.c
Normal 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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user