diff options
| author | Eric Andersen <andersen@codepoet.org> | 1999-10-09 00:25:00 +0000 |
|---|---|---|
| committer | Eric Andersen <andersen@codepoet.org> | 1999-10-09 00:25:00 +0000 |
| commit | f811e07b072600a3784a92e5a1dc8a93dac477eb (patch) | |
| tree | 820c6366f8bdacf617a9591cc2ca9dfe107b1fa3 /util-linux | |
| parent | 8341a1565306a54e685455d19efb0516ad3328a1 (diff) | |
| download | busybox-w32-f811e07b072600a3784a92e5a1dc8a93dac477eb.tar.gz busybox-w32-f811e07b072600a3784a92e5a1dc8a93dac477eb.tar.bz2 busybox-w32-f811e07b072600a3784a92e5a1dc8a93dac477eb.zip | |
More stuff.
Diffstat (limited to 'util-linux')
| -rw-r--r-- | util-linux/umount.c | 196 |
1 files changed, 78 insertions, 118 deletions
diff --git a/util-linux/umount.c b/util-linux/umount.c index 4efc9f9d9..5274e2f6f 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c | |||
| @@ -1,135 +1,95 @@ | |||
| 1 | /* | ||
| 2 | * Mini umount implementation for busybox | ||
| 3 | * | ||
| 4 | * Copyright (C) 1998 by Erik Andersen <andersee@debian.org> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | * General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | |||
| 1 | #include "internal.h" | 22 | #include "internal.h" |
| 2 | #include <stdlib.h> | ||
| 3 | #include <unistd.h> | ||
| 4 | #include <errno.h> | ||
| 5 | #include <string.h> | ||
| 6 | #include <stdio.h> | 23 | #include <stdio.h> |
| 7 | #include <mntent.h> | ||
| 8 | #include <sys/mount.h> | 24 | #include <sys/mount.h> |
| 25 | #include <mntent.h> | ||
| 26 | #include <fstab.h> | ||
| 27 | #include <errno.h> | ||
| 9 | 28 | ||
| 10 | const char umount_usage[] = "umount {filesystem|directory}\n" | 29 | const char umount_usage[] = "\tumount {filesystem|directory}\n" |
| 11 | "\tumount -a\n" | 30 | "or to unmount all mounted file systems:\n\tumount -a\n"; |
| 12 | "\n" | ||
| 13 | "\tUnmount a filesystem.\n" | ||
| 14 | "\t-a:\tUnmounts all mounted filesystems.\n"; | ||
| 15 | |||
| 16 | static char * | ||
| 17 | stralloc(const char * string) | ||
| 18 | { | ||
| 19 | int length = strlen(string) + 1; | ||
| 20 | char * n = malloc(length); | ||
| 21 | memcpy(n, string, length); | ||
| 22 | return n; | ||
| 23 | } | ||
| 24 | |||
| 25 | extern void | ||
| 26 | erase_mtab(const char * name) | ||
| 27 | { | ||
| 28 | struct mntent entries[100]; | ||
| 29 | int count = 0; | ||
| 30 | FILE * mountTable = setmntent("/etc/mtab", "r"); | ||
| 31 | struct mntent * m; | ||
| 32 | |||
| 33 | if ( mountTable == 0 | ||
| 34 | && (mountTable = setmntent("/proc/mounts", "r")) == 0 ) { | ||
| 35 | name_and_error("/etc/mtab"); | ||
| 36 | return; | ||
| 37 | } | ||
| 38 | |||
| 39 | while ( (m = getmntent(mountTable)) != 0 ) { | ||
| 40 | entries[count].mnt_fsname = stralloc(m->mnt_fsname); | ||
| 41 | entries[count].mnt_dir = stralloc(m->mnt_dir); | ||
| 42 | entries[count].mnt_type = stralloc(m->mnt_type); | ||
| 43 | entries[count].mnt_opts = stralloc(m->mnt_opts); | ||
| 44 | entries[count].mnt_freq = m->mnt_freq; | ||
| 45 | entries[count].mnt_passno = m->mnt_passno; | ||
| 46 | count++; | ||
| 47 | } | ||
| 48 | endmntent(mountTable); | ||
| 49 | if ( (mountTable = setmntent("/etc/mtab", "w")) ) { | ||
| 50 | int i; | ||
| 51 | for ( i = 0; i < count; i++ ) { | ||
| 52 | int result = ( strcmp(entries[i].mnt_fsname, name) == 0 | ||
| 53 | || strcmp(entries[i].mnt_dir, name) == 0 ); | ||
| 54 | |||
| 55 | if ( result ) | ||
| 56 | continue; | ||
| 57 | else | ||
| 58 | addmntent(mountTable, &entries[i]); | ||
| 59 | } | ||
| 60 | endmntent(mountTable); | ||
| 61 | } | ||
| 62 | else if ( errno != EROFS ) | ||
| 63 | name_and_error("/etc/mtab"); | ||
| 64 | } | ||
| 65 | 31 | ||
| 66 | static int | 32 | static int |
| 67 | umount_all(int noMtab) | 33 | umount_all() |
| 68 | { | 34 | { |
| 69 | struct mntent entries[100]; | 35 | int status; |
| 70 | int count = 0; | 36 | struct mntent *m; |
| 71 | FILE * mountTable = setmntent("/etc/mtab", "r"); | 37 | FILE *mountTable; |
| 72 | struct mntent * m; | ||
| 73 | int status = 0; | ||
| 74 | |||
| 75 | if ( mountTable == 0 | ||
| 76 | && (mountTable = setmntent("/proc/mounts", "r")) == 0 ) { | ||
| 77 | name_and_error("/etc/mtab"); | ||
| 78 | return 1; | ||
| 79 | } | ||
| 80 | 38 | ||
| 81 | while ( (m = getmntent(mountTable)) != 0 ) { | 39 | if ((mountTable = setmntent ("/proc/mounts", "r"))) { |
| 82 | entries[count].mnt_fsname = stralloc(m->mnt_fsname); | 40 | while ((m = getmntent (mountTable)) != 0) { |
| 83 | count++; | 41 | char *blockDevice = m->mnt_fsname; |
| 84 | } | 42 | if (strcmp (blockDevice, "/dev/root") == 0) |
| 85 | endmntent(mountTable); | 43 | blockDevice = (getfsfile ("/"))->fs_spec; |
| 86 | 44 | status=umount (m->mnt_dir); | |
| 87 | while ( count > 0 ) { | 45 | if (status!=0) { |
| 88 | int result = umount(entries[--count].mnt_fsname) == 0; | 46 | /* Don't bother retrying the umount on busy devices */ |
| 89 | /* free(entries[count].mnt_fsname); */ | 47 | if (errno==EBUSY) { |
| 90 | if ( result ) { | 48 | perror(m->mnt_dir); |
| 91 | if ( !noMtab ) | 49 | continue; |
| 92 | erase_mtab(entries[count].mnt_fsname); | 50 | } |
| 51 | printf ("Trying to umount %s failed: %s\n", | ||
| 52 | m->mnt_dir, strerror(errno)); | ||
| 53 | printf ("Instead trying to umount %s\n", blockDevice); | ||
| 54 | status=umount (blockDevice); | ||
| 55 | if (status!=0) { | ||
| 56 | printf ("Couldn't umount %s on %s (type %s): %s\n", | ||
| 57 | blockDevice, m->mnt_dir, m->mnt_type, strerror(errno)); | ||
| 58 | } | ||
| 93 | } | 59 | } |
| 94 | else { | 60 | } |
| 95 | status = 1; | 61 | endmntent (mountTable); |
| 96 | name_and_error(entries[count].mnt_fsname); | 62 | } |
| 97 | } | 63 | return( TRUE); |
| 98 | } | ||
| 99 | return status; | ||
| 100 | } | 64 | } |
| 101 | 65 | ||
| 102 | extern int | 66 | extern int |
| 103 | do_umount(const char * name, int noMtab) | 67 | umount_main(int argc, char * * argv) |
| 104 | { | 68 | { |
| 105 | if ( umount(name) == 0 ) { | ||
| 106 | if ( !noMtab ) | ||
| 107 | erase_mtab(name); | ||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | return 1; | ||
| 111 | } | ||
| 112 | 69 | ||
| 113 | extern int | 70 | if (argc < 2) { |
| 114 | umount_main(struct FileInfo * i, int argc, char * * argv) | 71 | fprintf(stderr, "Usage: %s", umount_usage); |
| 115 | { | 72 | return(FALSE); |
| 116 | int noMtab = 0; | 73 | } |
| 74 | argc--; | ||
| 75 | argv++; | ||
| 117 | 76 | ||
| 118 | if ( argv[1][0] == '-' ) { | 77 | /* Parse any options */ |
| 119 | switch ( argv[1][1] ) { | 78 | while (**argv == '-') { |
| 120 | case 'a': | 79 | while (*++(*argv)) switch (**argv) { |
| 121 | return umount_all(noMtab); | 80 | case 'a': |
| 122 | case 'n': | 81 | return umount_all(); |
| 123 | noMtab = 1; | 82 | break; |
| 124 | break; | 83 | default: |
| 125 | default: | 84 | fprintf(stderr, "Usage: %s\n", umount_usage); |
| 126 | usage(umount_usage); | 85 | exit( FALSE); |
| 127 | return 1; | ||
| 128 | } | ||
| 129 | } | ||
| 130 | if ( do_umount(argv[1],noMtab) != 0 ) { | ||
| 131 | fprintf(stderr, "%s: %s.\n", argv[1], strerror(errno)); | ||
| 132 | return 1; | ||
| 133 | } | 86 | } |
| 134 | return 0; | 87 | } |
| 88 | if ( umount(*argv) == 0 ) | ||
| 89 | return (TRUE); | ||
| 90 | else { | ||
| 91 | perror("umount"); | ||
| 92 | return( FALSE); | ||
| 93 | } | ||
| 135 | } | 94 | } |
| 95 | |||
