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

Matt Kraai kraai at alumni.carnegiemellon.edu
Mon Aug 6 12:20:03 UTC 2001


On Mon, Aug 06, 2001 at 09:49:51AM -0400, David Douthitt wrote:
> Given two entries in fstab:
> 
> /dev/fd0    /mnt/fd0    [...]
> /dev/floppy /mnt/floppy [...]
> 
> ...and the following files in /dev:
> 
> fd0
> floppy -> fd0
> 
> ...then try this sequence with busybox 0.53 and 0.60:
> 
> # mount /dev/floppy
> # umount /mnt/floppy
> 
> ...in 0.53, this works.  In 0.60, it fails because the link is
> "translated" to /dev/fd0 and is mounted on /mnt/fd0, not /mnt/floppy...

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.

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	Mon Aug  6 12:15:11 2001
@@ -0,0 +1,73 @@
+/* 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;
+
+	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] == '/') {
+			strchop(s+i+1, strspn(s+i+1, "/"));
+
+			if (s[i+1] == '\0')
+				s[i] = '\0';
+			else if (s[i+1] == '.') {
+				if (s[i+2] == '\0' || s[i+2] == '/') {
+					strchop(s+i+1, 1 + strspn(s+i+2, "/"));
+					i--;
+				} 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