Introduction
Introduction Statistics Contact Development Disclaimer Help
which.c - sbase - suckless unix tools
git clone git://git.suckless.org/sbase
Log
Files
Refs
README
LICENSE
---
which.c (1648B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <sys/stat.h>
3 #include <sys/types.h>
4
5 #include <fcntl.h>
6 #include <limits.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11
12 #include "util.h"
13
14 static int aflag;
15
16 static int
17 canexec(int fd, const char *name)
18 {
19 struct stat st;
20
21 if (fstatat(fd, name, &st, 0) < 0 || !S_ISREG(st.st_mode))
22 return 0;
23 return faccessat(fd, name, X_OK, AT_EACCESS) == 0;
24 }
25
26 static int
27 which(const char *path, const char *name)
28 {
29 char *ptr, *p;
30 size_t i, len;
31 int dirfd, found = 0;
32
33 if (strchr(name, '/')) {
34 found = canexec(AT_FDCWD, name);
35 if (found)
36 puts(name);
37 return found;
38 }
39
40 ptr = p = enstrdup(3, path);
41 len = strlen(p);
42 for (i = 0; i < len + 1; i++) {
43 if (ptr[i] != ':' && ptr[i] != '\0')
44 continue;
45 ptr[i] = '\0';
46 if ((dirfd = open(p, O_RDONLY)) >= 0) {
47 if (canexec(dirfd, name)) {
48 found = 1;
49 fputs(p, stdout);
50 if (i && ptr[i - 1] != '/')
51 fputc('/', stdout);
52 puts(name);
53 }
54 close(dirfd);
55 if (!aflag && found)
56 break;
57 }
58 p = ptr + i + 1;
59 }
60 free(ptr);
61
62 return found;
63 }
64
65 static void
66 usage(void)
67 {
68 eprintf("usage: %s [-a] name ...\n", argv0);
69 }
70
71 int
72 main(int argc, char *argv[])
73 {
74 char *path;
75 int found = 0, foundall = 1;
76
77 ARGBEGIN {
78 case 'a':
79 aflag = 1;
80 break;
81 default:
82 usage();
83 } ARGEND
84
85 if (!argc)
86 usage();
87
88 if (!(path = getenv("PATH")))
89 enprintf(3, "$PATH is not set\n");
90
91 for (; *argv; argc--, argv++) {
92 if (which(path, *argv)) {
93 found = 1;
94 } else {
95 weprintf("%s: not an external command\n", *argv);
96 foundall = 0;
97 }
98 }
99
100 return found ? foundall ? 0 : 1 : 2;
101 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.