"which" rewritten to use stat(). Fixes to improve its compatability

with traditional implementations
This commit is contained in:
Pavel Roskin 2000-06-05 23:41:27 +00:00
parent 82c0ac7e4f
commit c389d91181
3 changed files with 92 additions and 36 deletions

View File

@ -50,6 +50,8 @@
* Fixed all fatalError() calls lacking a "\n", thanks to Pavel Roskin. * Fixed all fatalError() calls lacking a "\n", thanks to Pavel Roskin.
* Fixed a segfault in yes when no args were given -- Pavel Roskin. * Fixed a segfault in yes when no args were given -- Pavel Roskin.
* Simplified freeramdisk and added argument checking -- Pavel Roskin. * Simplified freeramdisk and added argument checking -- Pavel Roskin.
* "which" rewritten to use stat(). Fixes to improve its compatability
with traditional implementations -- Pavel Roskin.
* More doc updates * More doc updates

View File

@ -23,15 +23,18 @@
#include "internal.h" #include "internal.h"
#include <stdio.h> #include <stdio.h>
#include <dirent.h> #include <sys/stat.h>
#include <sys/param.h>
extern int which_main(int argc, char **argv) extern int which_main(int argc, char **argv)
{ {
char *path_list, *test, *tmp; char *path_list, *test, *tmp, *path_parsed;
struct dirent *next; char buf[PATH_MAX];
struct stat filestat;
int count = 0;
if (**(argv + 1) == '-') { if (argc <= 1 || **(argv + 1) == '-') {
usage("which [COMMAND ...]\n" usage("which [COMMAND ...]\n"
#ifndef BB_FEATURE_TRIVIAL_HELP #ifndef BB_FEATURE_TRIVIAL_HELP
"\nLocates a COMMAND.\n" "\nLocates a COMMAND.\n"
@ -44,21 +47,45 @@ extern int which_main(int argc, char **argv)
if (!path_list) if (!path_list)
path_list = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"; path_list = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin";
while(argc-- > 0 && *(argv++) != '\0' && strlen(*argv)) { path_parsed = malloc (strlen(path_list) + 1);
for( test=path_list; (tmp=strchr(test, ':')) && (tmp+1)!=NULL; test=++tmp) { strcpy (path_parsed, path_list);
DIR *dir;
*tmp='\0'; /* Replace colons with zeros in path_parsed and count them */
//printf("Checking directory '%s'\n", test); count = 1;
dir = opendir(test); test = path_parsed;
if (!dir) while (1) {
continue; tmp = strchr(test, ':');
while ((next = readdir(dir)) != NULL) { if (tmp == NULL)
//printf("Checking file '%s'\n", next->d_name); break;
if ((strcmp(next->d_name, *argv) == 0)) { *tmp = 0;
printf("%s/%s\n", test, next->d_name); test = tmp + 1;
exit(TRUE); count++;
} }
while(argc-- > 0) {
int i;
int found = FALSE;
test = path_parsed;
argv++;
for (i = 0; i < count; i++) {
strcpy (buf, test);
strcat (buf, "/");
strcat (buf, *argv);
if (stat (buf, &filestat) == 0
&& filestat.st_mode & S_IXUSR)
{
found = TRUE;
break;
} }
test += (strlen(test) + 1);
}
if (found == TRUE)
printf ("%s\n", buf);
else
{
printf ("which: no %s in (%s)\n", *argv, path_list);
exit (FALSE);
} }
} }
exit(TRUE); exit(TRUE);

61
which.c
View File

@ -23,15 +23,18 @@
#include "internal.h" #include "internal.h"
#include <stdio.h> #include <stdio.h>
#include <dirent.h> #include <sys/stat.h>
#include <sys/param.h>
extern int which_main(int argc, char **argv) extern int which_main(int argc, char **argv)
{ {
char *path_list, *test, *tmp; char *path_list, *test, *tmp, *path_parsed;
struct dirent *next; char buf[PATH_MAX];
struct stat filestat;
int count = 0;
if (**(argv + 1) == '-') { if (argc <= 1 || **(argv + 1) == '-') {
usage("which [COMMAND ...]\n" usage("which [COMMAND ...]\n"
#ifndef BB_FEATURE_TRIVIAL_HELP #ifndef BB_FEATURE_TRIVIAL_HELP
"\nLocates a COMMAND.\n" "\nLocates a COMMAND.\n"
@ -44,21 +47,45 @@ extern int which_main(int argc, char **argv)
if (!path_list) if (!path_list)
path_list = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin"; path_list = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin";
while(argc-- > 0 && *(argv++) != '\0' && strlen(*argv)) { path_parsed = malloc (strlen(path_list) + 1);
for( test=path_list; (tmp=strchr(test, ':')) && (tmp+1)!=NULL; test=++tmp) { strcpy (path_parsed, path_list);
DIR *dir;
*tmp='\0'; /* Replace colons with zeros in path_parsed and count them */
//printf("Checking directory '%s'\n", test); count = 1;
dir = opendir(test); test = path_parsed;
if (!dir) while (1) {
continue; tmp = strchr(test, ':');
while ((next = readdir(dir)) != NULL) { if (tmp == NULL)
//printf("Checking file '%s'\n", next->d_name); break;
if ((strcmp(next->d_name, *argv) == 0)) { *tmp = 0;
printf("%s/%s\n", test, next->d_name); test = tmp + 1;
exit(TRUE); count++;
} }
while(argc-- > 0) {
int i;
int found = FALSE;
test = path_parsed;
argv++;
for (i = 0; i < count; i++) {
strcpy (buf, test);
strcat (buf, "/");
strcat (buf, *argv);
if (stat (buf, &filestat) == 0
&& filestat.st_mode & S_IXUSR)
{
found = TRUE;
break;
} }
test += (strlen(test) + 1);
}
if (found == TRUE)
printf ("%s\n", buf);
else
{
printf ("which: no %s in (%s)\n", *argv, path_list);
exit (FALSE);
} }
} }
exit(TRUE); exit(TRUE);