[BusyBox] bug#1205: BusyBox] bug#1205: mount handles links differently in 0.60

Matt Kraai kraai at alumni.carnegiemellon.edu
Tue Aug 7 09:45:02 MDT 2001


On Tue, Aug 07, 2001 at 11:59:02AM +0400, Vladimir N. Oleynik wrote:
> Matt wrote:
> > OK, the following patch should behave more like the standard mount
> > command, in that it doesn't follow symlinks when canonicalizing
> > pathnames.  I'll wait for approval, since the simplify_path
> > function is anything but.
> 
> Im tested you patch.
> If input string is "/" or "/../" or "///" your function retured empty string.

Thanks for the testing.  The problem was a consequence of my last
minute attempt to strip trailing /s.  I believe that the following
patch doesn't have this problem.

As for your patch, it appears to mishandle `foo..'.  Could you
submit a fixed version so that we can compare again?

Matt

Index: Makefile
===================================================================
RCS file: /var/cvs/busybox/Makefile,v
retrieving revision 1.232
diff -u -r1.232 Makefile
--- Makefile	2001/08/02 20:56:16	1.232
+++ Makefile	2001/08/06 17:18:02
@@ -250,7 +250,8 @@
 trim.c unzip.c vdprintf.c verror_msg.c vperror_msg.c wfopen.c xfuncs.c \
 xgetcwd.c xreadlink.c xregcomp.c interface.c remove_file.c last_char_is.c \
 copyfd.c vherror_msg.c herror_msg.c herror_msg_and_die.c xgethostbyname.c \
-dirname.c make_directory.c create_icmp_socket.c u_signal_names.c arith.c
+dirname.c make_directory.c create_icmp_socket.c u_signal_names.c arith.c \
+simplify_path.c
 LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC))
 ifeq ($(strip $(BB_SRC_DIR)),)
     LIBBB_CFLAGS += -I$(LIBBB)
Index: mount.c
===================================================================
RCS file: /var/cvs/busybox/mount.c,v
retrieving revision 1.90
diff -u -r1.90 mount.c
--- mount.c	2001/07/17 01:12:36	1.90
+++ mount.c	2001/08/06 17:21:59
@@ -395,18 +395,15 @@
 	if (optind < argc) {
 		/* if device is a filename get its real path */
 		if (stat(argv[optind], &statbuf) == 0) {
-			realpath(argv[optind], device);
+			device = simplify_path(argv[optind]);
 		} else {
 			safe_strncpy(device, argv[optind], PATH_MAX);
 		}
 	}
 
-	if (optind + 1 < argc) {
-		if (realpath(argv[optind + 1], directory) == NULL) {
-			perror_msg_and_die("%s", directory);
-		}
-	}
-	
+	if (optind + 1 < argc)
+		directory = simplify_path(argv[optind + 1]);
+
 	if (all == TRUE || optind + 1 == argc) {
 		struct mntent *m = NULL;
 		FILE *f = setmntent("/etc/fstab", "r");
Index: libbb/libbb.h
===================================================================
RCS file: /var/cvs/busybox/libbb/libbb.h,v
retrieving revision 1.59
diff -u -r1.59 libbb.h
--- libbb/libbb.h	2001/08/02 10:55:32	1.59
+++ libbb/libbb.h	2001/08/06 17:22:56
@@ -264,6 +264,7 @@
 int make_directory (char *path, long mode, int flags);
 
 const char *u_signal_names(const char *str_sig, int *signo, int startnum);
+char *simplify_path(const char *path);
 
 #define CT_AUTO	0
 #define CT_UNIX2DOS	1
Index: libbb/simplify_path.c
===================================================================
RCS file: simplify_path.c
diff -N simplify_path.c
--- /dev/null	Mon Nov 13 12:19:20 2000
+++ simplify_path.c	Tue Aug  7 08:36:02 2001
@@ -0,0 +1,78 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * simplify_path implementation for busybox
+ *
+ *
+ * Copyright (C) 2001  Matt Kraai <kraai at alumni.carnegiemellon.edu>
+ *
+ *
+ * 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.
+ *
+ * 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
+ *
+ */
+
+#include <libbb.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Chop out LEN bytes of a string, starting at S.  */
+static void strchop(char *s, size_t len)
+{
+	memmove(s, s + len, strlen(s + len) + 1);
+}
+
+/* Change PATH to an absolute path, remove duplicate and trailing
+ * slashes, and eliminate `.' and `..' components.  */
+char *simplify_path(const char *path)
+{
+	char *s;
+	int i, j;
+
+	/* Make the pathname absolute.  */
+	if (path[0] == '/')
+		s = xstrdup(path);
+	else {
+		char *cwd = xgetcwd(NULL);
+		s = concat_path_file(cwd, path);
+		free(cwd);
+	}
+
+	for (i = 0; s[i] != '\0'; i++) {
+		if (s[i] == '/') {
+			/* Strip extra slashes.  */
+			strchop(s+i+1, strspn(s+i+1, "/"));
+
+			/* Strip the trailing slash.  */
+			if (i != 0 && s[i+1] == '\0')
+				s[i] = '\0';
+			else if (s[i+1] == '.') {
+				/* Remove `.' components.  */
+				if (s[i+2] == '\0' || s[i+2] == '/') {
+					strchop(s+i+1, 1 + strspn(s+i+2, "/"));
+					i--;
+				/* Remove `..' components.  */
+				} else if (s[i+2] == '.' && (s[i+3] == '\0' || s[i+3] == '/')) {
+					for (j = i - 1; 0 < j && s[j] != '/'; j--)
+						/* Loop.  */;
+					if (j < 0)
+						j = 0;
+					strchop(s+j+1, (i - j) + 2 + strspn(s+i+3, "/"));
+					i = j - 1;
+				}
+			}
+		}
+	}
+
+	return s;
+}






More information about the busybox mailing list