svn commit: trunk/busybox/debianutils

pgf at busybox.net pgf at busybox.net
Wed Sep 14 14:08:40 UTC 2005


Author: pgf
Date: 2005-09-14 07:08:38 -0700 (Wed, 14 Sep 2005)
New Revision: 11454

Log:
committing bug #7:
     0000007: which and wd-located files
	     which doesn't search $PATH when there's a file in the WD with
	     the same name of the 'filename' parameter...


Modified:
   trunk/busybox/debianutils/which.c


Changeset:
Modified: trunk/busybox/debianutils/which.c
===================================================================
--- trunk/busybox/debianutils/which.c	2005-09-14 00:07:26 UTC (rev 11453)
+++ trunk/busybox/debianutils/which.c	2005-09-14 14:08:38 UTC (rev 11454)
@@ -4,36 +4,23 @@
  *
  * Copyright (C) 1999-2004 by Erik Andersen <andersen at codepoet.org>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Licensed under the GPL v2, see the file LICENSE in this tarball.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
  * Based on which from debianutils
  */
 
-
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-
+#include <sys/stat.h>
 #include "busybox.h"
 
-
 extern int which_main(int argc, char **argv)
 {
+	int status = EXIT_SUCCESS;
+	size_t i, count;
 	char *path_list;
-	int i, count=1, status = EXIT_SUCCESS;
 
 	if (argc <= 1 || **(argv + 1) == '-') {
 		bb_show_usage();
@@ -42,10 +29,33 @@
 
 	path_list = getenv("PATH");
 	if (path_list != NULL) {
-		for (i=strlen(path_list); i > 0; i--) {
-			if (path_list[i]==':') {
-				path_list[i]=0;
+		size_t path_len = bb_strlen(path_list);
+		char *new_list = NULL;
+		count = 1;
+
+		for (i = 0; i <= path_len; i++) {
+			char *this_i = &path_list[i];
+			if (*this_i == ':') {
+				/* ^::[^:] == \.: */
+				if (!i && (*(this_i + 1) == ':')) {
+					*this_i = '.';
+					continue;
+				}
+				*this_i = 0;
 				count++;
+				/* ^:[^:] == \.0 and [^:]::[^:] == 0\.0 and [^:]:$ == 0\.0 */
+				if (!i || (*(this_i + 1) == ':') || (i == path_len-1)) {
+					new_list = xrealloc(new_list, path_len += 1);
+					if (i) {
+						memmove(&new_list[i+2], &path_list[i+1], path_len-i);
+						new_list[i+1] = '.';
+						memmove(new_list, path_list, i);
+					} else {
+						memmove(&new_list[i+1], &path_list[i], path_len-i);
+						new_list[i] = '.';
+					}
+					path_list = new_list;
+				}
 			}
 		}
 	} else {
@@ -54,28 +64,31 @@
 	}
 
 	while (argc-- > 0) {
+		struct stat stat_b;
 		char *buf;
 		char *path_n;
 		char found = 0;
+#define is_executable_file(a, b) (!access(a,X_OK) && !stat(a, &b) && \
+		S_ISREG(b.st_mode))
+
 		argv++;
-
-		/*
-		 * Check if we were given the full path, first.
-		 * Otherwise see if the file exists in our $PATH.
-		 */
 		path_n = path_list;
 		buf = *argv;
-		if (access(buf, X_OK) == 0) {
+
+		/* if filename is either absolute or contains slashes,
+		 * stat it */
+		if (strchr(buf, '/') != NULL && is_executable_file(buf, stat_b)) {
 			found = 1;
 		} else {
+			/* Couldn't access file and file doesn't contain slashes */
 			for (i = 0; i < count; i++) {
 				buf = concat_path_file(path_n, *argv);
-				if (access(buf, X_OK) == 0) {
+				if (is_executable_file(buf, stat_b)) {
 					found = 1;
 					break;
 				}
 				free(buf);
-				path_n += (strlen(path_n) + 1);
+				path_n += (bb_strlen(path_n) + 1);
 			}
 		}
 		if (found) {
@@ -84,7 +97,7 @@
 			status = EXIT_FAILURE;
 		}
 	}
-	return status;
+	bb_fflush_stdout_and_exit(status);
 }
 
 /*




More information about the busybox-cvs mailing list