which.c (b7a311f2b8b14ef9b7dd0f741a447315fa8d43ee) which.c (cc70d84c4a6b6e1c0224bbdfd5bd306252d9fb4f)
1/**
2 * Copyright (c) 2000 Dan Papasian. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 8 unchanged lines hidden (view full) ---

17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1/**
2 * Copyright (c) 2000 Dan Papasian. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 8 unchanged lines hidden (view full) ---

17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $FreeBSD$
25 */
26
27 */
28
27#include <sys/cdefs.h>
28
29__FBSDID("$FreeBSD$");
30
31#include <sys/stat.h>
32#include <sys/param.h>
33
34#include <err.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <unistd.h>

--- 8 unchanged lines hidden (view full) ---

47main(int argc, char **argv)
48{
49 char *p, *path;
50 ssize_t pathlen;
51 int opt, status;
52
53 status = EXIT_SUCCESS;
54
29#include <sys/stat.h>
30#include <sys/param.h>
31
32#include <err.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <unistd.h>

--- 8 unchanged lines hidden (view full) ---

45main(int argc, char **argv)
46{
47 char *p, *path;
48 ssize_t pathlen;
49 int opt, status;
50
51 status = EXIT_SUCCESS;
52
53 /* If called without args, die silently to conform */
54 if (argc < 2)
55 exit(EXIT_FAILURE);
56
55 while ((opt = getopt(argc, argv, "as")) != -1) {
56 switch (opt) {
57 case 'a':
58 allpaths = 1;
59 break;
60 case 's':
61 silent = 1;
62 break;
63 default:
64 usage();
65 break;
66 }
67 }
68
69 argv += optind;
70 argc -= optind;
71
57 while ((opt = getopt(argc, argv, "as")) != -1) {
58 switch (opt) {
59 case 'a':
60 allpaths = 1;
61 break;
62 case 's':
63 silent = 1;
64 break;
65 default:
66 usage();
67 break;
68 }
69 }
70
71 argv += optind;
72 argc -= optind;
73
72 if (argc == 0)
73 usage();
74
75 if ((p = getenv("PATH")) == NULL)
76 exit(EXIT_FAILURE);
77 pathlen = strlen(p) + 1;
78 path = malloc(pathlen);
79 if (path == NULL)
80 err(EXIT_FAILURE, NULL);
81
74 if ((p = getenv("PATH")) == NULL)
75 exit(EXIT_FAILURE);
76 pathlen = strlen(p) + 1;
77 path = malloc(pathlen);
78 if (path == NULL)
79 err(EXIT_FAILURE, NULL);
80
81 if (argc == 0)
82 status = EXIT_FAILURE;
83
82 while (argc > 0) {
83 memcpy(path, p, pathlen);
84
84 while (argc > 0) {
85 memcpy(path, p, pathlen);
86
85 if (strlen(*argv) >= FILENAME_MAX ||
87 if (strlen(*argv) > FILENAME_MAX ||
86 print_matches(path, *argv) == -1)
87 status = EXIT_FAILURE;
88
89 argv++;
90 argc--;
91 }
92
93 exit(status);
94}
95
96static void
97usage(void)
98{
99
88 print_matches(path, *argv) == -1)
89 status = EXIT_FAILURE;
90
91 argv++;
92 argc--;
93 }
94
95 exit(status);
96}
97
98static void
99usage(void)
100{
101
100 (void)fprintf(stderr, "usage: which [-as] program ...\n");
101 exit(EXIT_FAILURE);
102 errx(EXIT_FAILURE, "usage: which [-as] program ...");
102}
103
104static int
105is_there(char *candidate)
106{
107 struct stat fin;
108
109 /* XXX work around access(2) false positives for superuser */

--- 8 unchanged lines hidden (view full) ---

118 }
119 return (0);
120}
121
122static int
123print_matches(char *path, char *filename)
124{
125 char candidate[PATH_MAX];
103}
104
105static int
106is_there(char *candidate)
107{
108 struct stat fin;
109
110 /* XXX work around access(2) false positives for superuser */

--- 8 unchanged lines hidden (view full) ---

119 }
120 return (0);
121}
122
123static int
124print_matches(char *path, char *filename)
125{
126 char candidate[PATH_MAX];
126 const char *d;
127 char *d;
127 int found;
128
128 int found;
129
129 if (strchr(filename, '/') != NULL)
130 if (*filename == '/')
130 return (is_there(filename) ? 0 : -1);
131 found = 0;
132 while ((d = strsep(&path, ":")) != NULL) {
131 return (is_there(filename) ? 0 : -1);
132 found = 0;
133 while ((d = strsep(&path, ":")) != NULL) {
133 if (*d == '\0')
134 d = ".";
135 if (snprintf(candidate, sizeof(candidate), "%s/%s", d,
134 if (snprintf(candidate, sizeof(candidate), "%s/%s", d,
136 filename) >= (int)sizeof(candidate))
135 filename) >= sizeof(candidate))
137 continue;
138 if (is_there(candidate)) {
139 found = 1;
140 if (!allpaths)
141 break;
142 }
143 }
144 return (found ? 0 : -1);
145}
146
136 continue;
137 if (is_there(candidate)) {
138 found = 1;
139 if (!allpaths)
140 break;
141 }
142 }
143 return (found ? 0 : -1);
144}
145