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 /umount.c | |
parent | 8341a1565306a54e685455d19efb0516ad3328a1 (diff) | |
download | busybox-w32-f811e07b072600a3784a92e5a1dc8a93dac477eb.tar.gz busybox-w32-f811e07b072600a3784a92e5a1dc8a93dac477eb.tar.bz2 busybox-w32-f811e07b072600a3784a92e5a1dc8a93dac477eb.zip |
More stuff.
Diffstat (limited to 'umount.c')
-rw-r--r-- | umount.c | 196 |
1 files changed, 78 insertions, 118 deletions
@@ -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 | |||