X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=util-linux%2Fmount.c;h=d58eecaebe7f8735d2279d8219599311fd1bbb40;hb=081df62b921cf17f1d4c4e0214abfa273c92cfde;hp=e511b798b9e78c89ca520d418c8bbb2ebd17dfdf;hpb=1b6261944664beedf0e4e3e546635f0a809da41e;p=oweals%2Fbusybox.git diff --git a/util-linux/mount.c b/util-linux/mount.c index e511b798b..d58eecaeb 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -3,6 +3,7 @@ * Mini mount implementation for busybox * * Copyright (C) 1995, 1996 by Bruce Perens . + * Copyright (C) 1999-2002 by Erik Andersen * * 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 @@ -52,7 +53,7 @@ #include #include #include "busybox.h" -#if defined BB_FEATURE_USE_DEVPS_PATCH +#if defined CONFIG_FEATURE_USE_DEVPS_PATCH # include /* For Erik's nifty devmtab device driver */ #endif @@ -70,10 +71,11 @@ enum { S_IMMUTABLE = 512, /* Immutable file */ MS_NOATIME = 1024, /* Do not update access times. */ MS_NODIRATIME = 2048, /* Do not update directory access times */ + MS_BIND = 4096, /* Use the new linux 2.4.x "mount --bind" feature */ }; -#if defined BB_FEATURE_MOUNT_LOOP +#if defined CONFIG_FEATURE_MOUNT_LOOP #include #include static int use_loop = FALSE; @@ -99,6 +101,7 @@ static const struct mount_options mount_options[] = { {"async", ~MS_SYNCHRONOUS, 0}, {"atime", ~0, ~MS_NOATIME}, {"defaults", ~0, 0}, + {"noauto", ~0, 0}, {"dev", ~MS_NODEV, 0}, {"diratime", ~0, ~MS_NODIRATIME}, {"exec", ~MS_NOEXEC, 0}, @@ -112,22 +115,23 @@ static const struct mount_options mount_options[] = { {"rw", ~MS_RDONLY, 0}, {"suid", ~MS_NOSUID, 0}, {"sync", ~0, MS_SYNCHRONOUS}, + {"bind", ~0, MS_BIND}, {0, 0, 0} }; static int do_mount(char *specialfile, char *dir, char *filesystemtype, long flags, void *string_flags, int useMtab, int fakeIt, - char *mtab_opts) + char *mtab_opts, int mount_all) { int status = 0; -#if defined BB_FEATURE_MOUNT_LOOP +#if defined CONFIG_FEATURE_MOUNT_LOOP char *lofile = NULL; #endif - if (fakeIt == FALSE) + if (! fakeIt) { -#if defined BB_FEATURE_MOUNT_LOOP +#if defined CONFIG_FEATURE_MOUNT_LOOP if (use_loop==TRUE) { int loro = flags & MS_RDONLY; @@ -142,23 +146,26 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, } if (!(flags & MS_RDONLY) && loro) { /* loop is ro, but wanted rw */ error_msg("WARNING: loop device is read-only"); - flags &= ~MS_RDONLY; + flags |= MS_RDONLY; } } #endif status = mount(specialfile, dir, filesystemtype, flags, string_flags); - if (errno == EROFS) { + if (status < 0 && errno == EROFS) { error_msg("%s is write-protected, mounting read-only", specialfile); status = mount(specialfile, dir, filesystemtype, flags |= MS_RDONLY, string_flags); } + /* Don't whine about already mounted filesystems when mounting all. */ + if (status < 0 && errno == EBUSY && mount_all) + return TRUE; } /* If the mount was sucessful, do anything needed, then return TRUE */ if (status == 0 || fakeIt==TRUE) { -#if defined BB_FEATURE_MTAB_SUPPORT - if (useMtab == TRUE) { +#if defined CONFIG_FEATURE_MTAB_SUPPORT + if (useMtab) { erase_mtab(specialfile); // Clean any stale entries write_mtab(specialfile, dir, filesystemtype, flags, mtab_opts); } @@ -167,7 +174,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, } /* Bummer. mount failed. Clean up */ -#if defined BB_FEATURE_MOUNT_LOOP +#if defined CONFIG_FEATURE_MOUNT_LOOP if (lofile != NULL) { del_loop(specialfile); } @@ -204,20 +211,20 @@ parse_mount_options(char *options, int *flags, char *strflags) } f++; } -#if defined BB_FEATURE_MOUNT_LOOP - if (gotone == FALSE && !strcasecmp("loop", options)) { /* loop device support */ +#if defined CONFIG_FEATURE_MOUNT_LOOP + if (! gotone && !strcasecmp("loop", options)) { /* loop device support */ use_loop = TRUE; gotone = TRUE; } #endif - if (*strflags && strflags != '\0' && gotone == FALSE) { + if (*strflags && strflags != '\0' && ! gotone) { char *temp = strflags; temp += strlen(strflags); *temp++ = ','; *temp++ = '\0'; } - if (gotone == FALSE) + if (! gotone) strcat(strflags, options); if (comma) { *comma = ','; @@ -228,15 +235,16 @@ parse_mount_options(char *options, int *flags, char *strflags) } } -extern int +static int mount_one(char *blockDevice, char *directory, char *filesystemType, unsigned long flags, char *string_flags, int useMtab, int fakeIt, - char *mtab_opts, int whineOnErrors) + char *mtab_opts, int whineOnErrors, int mount_all) { int status = 0; +#if defined CONFIG_FEATURE_USE_DEVPS_PATCH if (strcmp(filesystemType, "auto") == 0) { - static const char *noauto_array[] = { "tmpfs", "shm", "proc", "ramfs", "devpts", "devfs", 0 }; + static const char *noauto_array[] = { "tmpfs", "shm", "proc", "ramfs", "devpts", "devfs", "usbdevfs", 0 }; const char **noauto_fstype; const int num_of_filesystems = sysfs(3, 0, 0); char buf[255]; @@ -254,19 +262,47 @@ mount_one(char *blockDevice, char *directory, char *filesystemType, if (!*noauto_fstype) { status = do_mount(blockDevice, directory, filesystemType, flags | MS_MGC_VAL, string_flags, - useMtab, fakeIt, mtab_opts); - if (status == TRUE) + useMtab, fakeIt, mtab_opts, mount_all); + if (status) break; } } - } else { + } +#else + if (strcmp(filesystemType, "auto") == 0) { + char buf[255]; + FILE *f = xfopen("/proc/filesystems", "r"); + + while (fgets(buf, sizeof(buf), f) != NULL) { + filesystemType = buf; + if (*filesystemType == '\t') { // Not a nodev filesystem + + // Add NULL termination to each line + while (*filesystemType && *filesystemType != '\n') + filesystemType++; + *filesystemType = '\0'; + + filesystemType = buf; + filesystemType++; // hop past tab + + status = do_mount(blockDevice, directory, filesystemType, + flags | MS_MGC_VAL, string_flags, + useMtab, fakeIt, mtab_opts, mount_all); + if (status) + break; + } + } + fclose(f); + } +#endif + else { status = do_mount(blockDevice, directory, filesystemType, flags | MS_MGC_VAL, string_flags, useMtab, - fakeIt, mtab_opts); + fakeIt, mtab_opts, mount_all); } - if (status == FALSE) { - if (whineOnErrors == TRUE) { + if (! status) { + if (whineOnErrors) { perror_msg("Mounting %s on %s failed", blockDevice, directory); } return (FALSE); @@ -274,9 +310,9 @@ mount_one(char *blockDevice, char *directory, char *filesystemType, return (TRUE); } -void show_mounts() +void show_mounts(void) { -#if defined BB_FEATURE_USE_DEVPS_PATCH +#if defined CONFIG_FEATURE_USE_DEVPS_PATCH int fd, i, numfilesystems; char device[] = "/dev/mtab"; struct k_mntent *mntentlist; @@ -303,7 +339,7 @@ void show_mounts() mntentlist[i].mnt_opts, mntentlist[i].mnt_freq, mntentlist[i].mnt_passno); } -#ifdef BB_FEATURE_CLEAN_UP +#ifdef CONFIG_FEATURE_CLEAN_UP /* Don't bother to close files or free memory. Exit * does that automagically, so we can save a few bytes */ free( mntentlist); @@ -319,10 +355,14 @@ void show_mounts() while ((m = getmntent(mountTable)) != 0) { char *blockDevice = m->mnt_fsname; if (strcmp(blockDevice, "/dev/root") == 0) { - find_real_root_device_name( blockDevice); + blockDevice = find_real_root_device_name(blockDevice); } printf("%s on %s type %s (%s)\n", blockDevice, m->mnt_dir, m->mnt_type, m->mnt_opts); +#ifdef CONFIG_FEATURE_CLEAN_UP + if(blockDevice != m->mnt_fsname) + free(blockDevice); +#endif } endmntent(mountTable); } else { @@ -370,7 +410,7 @@ extern int mount_main(int argc, char **argv) case 'f': fakeIt = TRUE; break; -#ifdef BB_FEATURE_MTAB_SUPPORT +#ifdef CONFIG_FEATURE_MTAB_SUPPORT case 'n': useMtab = FALSE; break; @@ -385,21 +425,18 @@ extern int mount_main(int argc, char **argv) if (optind < argc) { /* if device is a filename get its real path */ - if ((strchr(argv[optind], ':') == NULL) && - (stat(argv[optind], &statbuf) == 0)) { - realpath(argv[optind], device); + if (stat(argv[optind], &statbuf) == 0) { + char *tmp = simplify_path(argv[optind]); + safe_strncpy(device, tmp, PATH_MAX); } 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 (all == TRUE || optind + 1 == argc) { + if (optind + 1 < argc) + directory = simplify_path(argv[optind + 1]); + + if (all || optind + 1 == argc) { struct mntent *m = NULL; FILE *f = setmntent("/etc/fstab", "r"); fstabmount = TRUE; @@ -408,35 +445,35 @@ extern int mount_main(int argc, char **argv) perror_msg_and_die( "\nCannot read /etc/fstab"); while ((m = getmntent(f)) != NULL) { - if (all == FALSE && optind + 1 == argc && ( + if (! all && optind + 1 == argc && ( (strcmp(device, m->mnt_fsname) != 0) && (strcmp(device, m->mnt_dir) != 0) ) ) { continue; } - if (all == TRUE && ( // If we're mounting 'all' + if (all && ( // If we're mounting 'all' (strstr(m->mnt_opts, "noauto")) || // and the file system isn't noauto, (strstr(m->mnt_type, "swap")) || // and isn't swap or nfs, then mount it (strstr(m->mnt_type, "nfs")) ) ) { continue; } - if (all == TRUE || flags == 0) { // Allow single mount to override fstab flags + if (all || flags == 0) { // Allow single mount to override fstab flags flags = 0; + string_flags = string_flags_buf; *string_flags = '\0'; parse_mount_options(m->mnt_opts, &flags, string_flags); } strcpy(device, m->mnt_fsname); strcpy(directory, m->mnt_dir); - filesystemType = strdup(m->mnt_type); + filesystemType = xstrdup(m->mnt_type); singlemount: - string_flags = strdup(string_flags); + string_flags = xstrdup(string_flags); rc = EXIT_SUCCESS; -#ifdef BB_NFSMOUNT - if (strchr(device, ':') != NULL) +#ifdef CONFIG_NFSMOUNT + if (strchr(device, ':') != NULL) { filesystemType = "nfs"; - if (strcmp(filesystemType, "nfs") == 0) { if (nfsmount (device, directory, &flags, &extra_opts, &string_flags, 1)) { perror_msg("nfsmount failed"); @@ -445,16 +482,16 @@ singlemount: } #endif if (!mount_one(device, directory, filesystemType, flags, - string_flags, useMtab, fakeIt, extra_opts, TRUE)) + string_flags, useMtab, fakeIt, extra_opts, TRUE, all)) rc = EXIT_FAILURE; - if (all == FALSE) + if (! all) break; } - if (fstabmount == TRUE) + if (fstabmount) endmntent(f); - if (all == FALSE && fstabmount == TRUE && m == NULL) + if (! all && fstabmount && m == NULL) fprintf(stderr, "Can't find %s in /etc/fstab\n", device); return rc;