2
3
4
5
6
7
8
31void ABEND(
char *,
int,
char *);
32size_t
strnz__cat(
char *,
const char *, size_t);
33size_t
strnz__cpy(
char *,
const char *, size_t);
41static char doc[] =
"whence locate files in path";
42static char args_doc[] =
"";
44static struct argp_option options[] = {
45 {
"all",
'a', 0, 0,
"list all matches", 0},
46 {
"setuid",
's', 0, 0,
"setuid only", 0},
47 {
"executable",
'x', 0, 0,
"executable only", 0},
48 {
"verbose",
'v', 0, 0,
"verbose messages", 0},
57static error_t parse_opt(
int key,
char *arg,
struct argp_state *state) {
58 struct wh_opts *wh_opts = state->input;
73 if (state->arg_num == 0 || state->arg_num == 1) {
74 wh_opts->argv[state->arg_num] = arg;
75 wh_opts->argc = state->arg_num + 1;
83 return ARGP_ERR_UNKNOWN;
87static struct argp argp = {options, parse_opt, args_doc, doc,
88 nullptr,
nullptr,
nullptr};
90int main(
int argc,
char **argv) {
91 struct wh_opts wh_opts = {0};
93 wh_opts.argv[0] =
nullptr;
96 argp_parse(&argp, argc, argv, 0, 0, &wh_opts);
99 ABEND(argv[0]
, 0
, "PATH environment variable not set");
102 while (i < wh_opts.argc) {
103 found =
whence(wh_opts.argv[i++]
, wh_opts.flags
);
110
111
112
113
114
115
116
117
118
119int whence(
char *file_spec_p,
int flags) {
120 char file_spec[PATH_MAX];
121 char file_dir[PATH_MAX];
122 char file_name[PATH_MAX];
123 char try_spec[PATH_MAX];
124 char try_dir[PATH_MAX];
127 struct stat stat_struct;
134 while (path_l != 0) {
136 if (try_spec[path_l] !=
'/')
139 if (stat(try_spec, &stat_struct) != 0) {
141 printf(
"- %s\n", try_spec);
146 if (!(stat_struct.st_mode & S_ISUID)) {
151 if (!(stat_struct.st_mode & S_ISUID)) {
155 if (!(stat_struct.st_mode & S_IXUSR)) {
161 printf(
"found %s\n", try_spec);
163 printf(
"%s\n", try_spec);
172
173
174
175
176
177
178
179
185 getcwd(dp, PATH_MAX);
189 while (**pp !=
'\0' && **pp !=
'\n' && **pp !=
'\r' && **pp !=
':') {
194 if (**pp ==
':' && *++(*pp) ==
'\0')
200
201
202
203
204
205
206
207
208
211 char tmp_file_spec[PATH_MAX];
213 struct stat stat_struct;
215 if (stat(file_spec, &stat_struct) != -1)
216 if ((stat_struct.st_mode & S_IFMT) == S_IFDIR) {
217 if (file_spec[strlen(file_path)] !=
'/')
223 if (strlen(file_spec) == 0) {
230 file_spec_l = strlen(tmp_file_spec);
231 if (file_spec_l > 0) {
233 while (i < file_spec_l && tmp_file_spec[i] !=
'\0') {
234 if (tmp_file_spec[i] ==
'/') {
241 if (last_slash < 0) {
243 if (strcmp(file_spec,
".") == 0)
250 tmp_file_spec[last_slash] =
'\0';
253 if (last_slash < file_spec_l)
260
261
262
263
264
265
266void ABEND(
char *pgmid,
int rc,
char *err_msg) {
267 fprintf(stderr,
"%s; error %d; %s\n", pgmid, rc, err_msg);
272
273
274
275
276
277
278
279
280
281
282
283size_t
strnz__cpy(
char *d,
const char *s, size_t max_len) {
286 if (s ==
nullptr || d ==
nullptr || max_len == 0) {
287 if (d !=
nullptr && max_len > 0)
292 while (*s !=
'\0' && *s !=
'\n' && *s !=
'\r' && d < e) {
300
301
302
303
304
305
306
307
308
309
310
311
312size_t
strnz__cat(
char *d,
const char *s, size_t max_len) {
315 if (s ==
nullptr || d ==
nullptr || max_len == 0) {
316 if (d !=
nullptr && max_len > 0)
321 while (*d !=
'\0' && *d !=
'\n' && *d !=
'\r' && d < e) {
325 while (*s !=
'\0' && *s !=
'\n' && *s !=
'\r' && d < e) {
void ABEND(int)
The ABEND function is a signal handler that is called when the program receives certain signals (e....
int whence(char *, int)
Find the full path of a file in the directories specified by the PATH environment variable.
int next_path(char *, char **)
Get the next directory path from a colon-separated list of paths.
int file_spec_parts(char *, char *, char *)
Split a file specification into directory and file name components.
const char * argp_program_version
const char * argp_program_bug_address
int main(int argc, char **argv)
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
size_t strnz__cat(char *, const char *, size_t)
safer alternative to strncat