"which" rewritten to use stat(). Fixes to improve its compatability
with traditional implementations
This commit is contained in:
parent
82c0ac7e4f
commit
c389d91181
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
63
which.c
63
which.c
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user