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 {
_(
"path"),
'p',
"text", 0,
_(
"colon separated path string"), 0},
49 {
_(
"verbose"),
'v', 0, 0,
_(
"verbose messages"), 0},
59static error_t parse_opt(
int key,
char *arg,
struct argp_state *state) {
60 struct wh_opts *wh_opts = state->input;
69 wh_opts->path_env = strdup(arg);
78 if (state->arg_num == 0 || state->arg_num == 1) {
79 wh_opts->argv[state->arg_num] = arg;
80 wh_opts->argc = state->arg_num + 1;
88 return ARGP_ERR_UNKNOWN;
92static struct argp argp = {options, parse_opt, args_doc, doc,
93 nullptr,
nullptr,
nullptr};
95int main(
int argc,
char **argv) {
96 struct wh_opts wh_opts = {};
98 wh_opts.argv[0] =
nullptr;
99 wh_opts.path_env =
nullptr;
102 argp_parse(&argp, argc, argv, 0, 0, &wh_opts);
103 if (wh_opts.path_env !=
nullptr)
104 path_p = getenv(wh_opts.path_env);
111 while (i < wh_opts.argc)
112 found =
whence(wh_opts.argv[i++]
, wh_opts.flags
);
118
119
120
121
122
123
124
125
126
127int whence(
char *file_spec_p,
int flags) {
128 char file_spec[PATH_MAX];
129 char file_dir[PATH_MAX];
130 char file_name[PATH_MAX];
131 char try_spec[PATH_MAX];
132 char try_dir[PATH_MAX];
135 struct stat stat_struct;
142 while (path_l != 0) {
144 if (try_spec[path_l] !=
'/')
147 if (stat(try_spec, &stat_struct) != 0) {
149 printf(
"- %s\n", try_spec);
154 if (!(stat_struct.st_mode & S_ISUID)) {
159 if (!(stat_struct.st_mode & S_ISUID)) {
163 if (!(stat_struct.st_mode & S_IXUSR)) {
169 printf(
_(
"found %s\n"), try_spec);
171 printf(
"%s\n", try_spec);
180
181
182
183
184
185
186
187
193 getcwd(dp, PATH_MAX);
197 while (**pp !=
'\0' && **pp !=
'\n' && **pp !=
'\r' && **pp !=
':') {
202 if (**pp ==
':' && *++(*pp) ==
'\0')
208
209
210
211
212
213
214
215
216
219 char tmp_file_spec[PATH_MAX];
221 struct stat stat_struct;
223 if (stat(file_spec, &stat_struct) != -1)
224 if ((stat_struct.st_mode & S_IFMT) == S_IFDIR) {
225 if (file_spec[strlen(file_path)] !=
'/')
231 if (strlen(file_spec) == 0) {
238 file_spec_l = strlen(tmp_file_spec);
239 if (file_spec_l > 0) {
241 while (i < file_spec_l && tmp_file_spec[i] !=
'\0') {
242 if (tmp_file_spec[i] ==
'/') {
249 if (last_slash < 0) {
251 if (strcmp(file_spec,
".") == 0)
258 tmp_file_spec[last_slash] =
'\0';
261 if (last_slash < file_spec_l)
268
269
270
271
272
273
274void ABEND(
char *pgmid,
int rc,
char *err_msg) {
275 fprintf(stderr,
_(
"%s; error %d; %s\n"), pgmid, rc, err_msg);
280
281
282
283
284
285
286
287
288
289
290
300 while (*s !=
'\0' && *s !=
'\n' && *s !=
'\r' && d < e) {
308
309
310
311
312
313
314
315
316
317
318
319
329 while (*d !=
'\0' && *d !=
'\n' && *d !=
'\r' && d < e) {
333 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)
Capture the current terminal settings for later restoration.
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