summaryrefslogtreecommitdiff
path: root/util-linux/mount.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>1999-10-07 08:30:23 +0000
committerEric Andersen <andersen@codepoet.org>1999-10-07 08:30:23 +0000
commit596e5469d00fa4a74d8a3b1ebfaae20ce8dc3afe (patch)
tree4d48d109e66c5197bb27c8215062aab28d385509 /util-linux/mount.c
parent5c3199e0a519695c367b773e179b5458670f452b (diff)
downloadbusybox-w32-596e5469d00fa4a74d8a3b1ebfaae20ce8dc3afe.tar.gz
busybox-w32-596e5469d00fa4a74d8a3b1ebfaae20ce8dc3afe.tar.bz2
busybox-w32-596e5469d00fa4a74d8a3b1ebfaae20ce8dc3afe.zip
more stuff
Diffstat (limited to '')
-rw-r--r--util-linux/mount.c604
1 files changed, 223 insertions, 381 deletions
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 010757d1e..9a1accc88 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -1,9 +1,29 @@
1/* 1/*
2 3/21/1999 Charles P. Wright <cpwright@cpwright.com> 2 * Mini mount implementation for busybox
3 searches through fstab when -a is passed 3 *
4 will try mounting stuff with all fses when passed -t auto 4 * Copyright (C) 1999 by Erik Andersen <andersee@debian.org>
5 5 *
6 1999-04-17 Dave Cinege...Rewrote -t auto. Fixed ro mtab. 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 * 3/21/1999 Charles P. Wright <cpwright@cpwright.com>
21 * searches through fstab when -a is passed
22 * will try mounting stuff with all fses when passed -t auto
23 *
24 * 1999-04-17 Dave Cinege...Rewrote -t auto. Fixed ro mtab.
25 * 1999-10-07 Erik Andersen. Removed mtab usage, major adjustments,
26 * and some serious dieting all around.
7*/ 27*/
8 28
9#include "internal.h" 29#include "internal.h"
@@ -15,416 +35,238 @@
15#include <mntent.h> 35#include <mntent.h>
16#include <sys/mount.h> 36#include <sys/mount.h>
17#include <ctype.h> 37#include <ctype.h>
18 38#include <fstab.h>
19const char mount_usage[] = "mount\n" 39
20"\t\tmount [flags] special-device directory\n" 40const char mount_usage[] = "Usage:\tmount [flags]\n"
21"\n" 41 "\tmount [flags] device directory [-o options,more-options]\n"
22"Flags:\n" 42 "\n"
23"\t-a:\tMount all file systems in fstab.\n" 43 "Flags:\n"
24"\t-f:\t\"Fake\" mount. Add entry to mount table but don't mount it.\n" 44 "\t-a:\tMount all file systems in fstab.\n"
25"\t-n:\tDon't write a mount table entry.\n" 45 "\t-o option:\tOne of many filesystem options, listed below.\n"
26"\t-o option:\tOne of many filesystem options, listed below.\n" 46 "\t-r:\tMount the filesystem read-only.\n"
27"\t-r:\tMount the filesystem read-only.\n" 47 "\t-t filesystem-type:\tSpecify the filesystem type.\n"
28"\t-t filesystem-type:\tSpecify the filesystem type.\n" 48 "\t-w:\tMount for reading and writing (default).\n"
29"\t-w:\tMount for reading and writing (default).\n" 49 "\n"
30"\n" 50 "Options for use with the \"-o\" flag:\n"
31"Options for use with the \"-o\" flag:\n" 51 "\tasync / sync:\tWrites are asynchronous / synchronous.\n"
32"\tasync / sync:\tWrites are asynchronous / synchronous.\n" 52 "\tdev / nodev:\tAllow use of special device files / disallow them.\n"
33"\tdev / nodev:\tAllow use of special device files / disallow them.\n" 53 "\texec / noexec:\tAllow use of executable files / disallow them.\n"
34"\texec / noexec:\tAllow use of executable files / disallow them.\n" 54 "\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n"
35"\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n" 55 "\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n"
36"\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n" 56 "\tro / rw: Mount for read-only / read-write.\n"
37"\tro / rw: Mount for read-only / read-write.\n" 57 "\t"
38"\t" 58 "There are EVEN MORE flags that are specific to each filesystem.\n"
39"There are EVEN MORE flags that are specific to each filesystem.\n" 59 "You'll have to see the written documentation for those.\n";
40"You'll have to see the written documentation for those.\n";
41 60
42struct mount_options { 61struct mount_options {
43 const char * name; 62 const char *name;
44 unsigned long and; 63 unsigned long and;
45 unsigned long or; 64 unsigned long or;
46}; 65};
47 66
48static const struct mount_options mount_options[] = { 67static const struct mount_options mount_options[] = {
49 { "async", ~MS_SYNCHRONOUS,0 }, 68 {"async", ~MS_SYNCHRONOUS, 0},
50 { "defaults", ~0, 0 }, 69 {"defaults", ~0, 0},
51 { "dev", ~MS_NODEV, 0 }, 70 {"dev", ~MS_NODEV, 0},
52 { "exec", ~MS_NOEXEC, 0 }, 71 {"exec", ~MS_NOEXEC, 0},
53 { "nodev", ~0, MS_NODEV }, 72 {"nodev", ~0, MS_NODEV},
54 { "noexec", ~0, MS_NOEXEC }, 73 {"noexec", ~0, MS_NOEXEC},
55 { "nosuid", ~0, MS_NOSUID }, 74 {"nosuid", ~0, MS_NOSUID},
56 { "remount", ~0, MS_REMOUNT }, 75 {"remount", ~0, MS_REMOUNT},
57 { "ro", ~0, MS_RDONLY }, 76 {"ro", ~0, MS_RDONLY},
58 { "rw", ~MS_RDONLY, 0 }, 77 {"rw", ~MS_RDONLY, 0},
59 { "suid", ~MS_NOSUID, 0 }, 78 {"suid", ~MS_NOSUID, 0},
60 { "sync", ~0, MS_SYNCHRONOUS }, 79 {"sync", ~0, MS_SYNCHRONOUS},
61 { 0, 0, 0 } 80 {0, 0, 0}
62}; 81};
63 82
64static void
65show_flags(unsigned long flags, char * buffer)
66{
67 const struct mount_options * f = mount_options;
68 while ( f->name ) {
69 if ( flags & f->and ) {
70 int length = strlen(f->name);
71 memcpy(buffer, f->name, length);
72 buffer += length;
73 *buffer++ = ',';
74 *buffer = '\0';
75 }
76 f++;
77 }
78}
79 83
80static void 84static void
81one_option( 85parse_mount_options ( char *options, unsigned long *flags, char *data)
82 char * option
83,unsigned long * flags
84,char * data)
85{ 86{
86 const struct mount_options * f = mount_options; 87 printf("option=%s\n", options);
87 88 while (*options) {
88 while ( f->name != 0 ) { 89 char *comma = strchr (options, ',');
89 if ( strcasecmp(f->name, option) == 0 ) { 90 const struct mount_options* f = mount_options;
90 *flags &= f->and; 91 if (comma)
91 *flags |= f->or; 92 *comma = '\0';
92 return; 93
93 } 94 printf("checking option=%s vs %s\n", options, f->name);
94 f++; 95 while (f->name != 0) {
96 printf("checking option=%s vs %s\n", options, f->name);
97 if (strcasecmp (f->name, options) == 0) {
98 *flags &= f->and;
99 *flags |= f->or;
100 return;
101 }
102 f++;
95 } 103 }
96 if ( *data ) { 104 if (*data) {
97 data += strlen(data); 105 data += strlen (data);
98 *data++ = ','; 106 *data++ = ',';
99 }
100 strcpy(data, option);
101}
102
103static void
104parse_mount_options(
105 char * options
106,unsigned long * flags
107,char * data)
108{
109 while ( *options ) {
110 char * comma = strchr(options, ',');
111 if ( comma )
112 *comma = '\0';
113 one_option(options, flags, data);
114 if ( comma ) {
115 *comma = ',';
116 options = ++comma;
117 }
118 else
119 break;
120 } 107 }
108 strcpy (data, options);
109 if (comma) {
110 *comma = ',';
111 options = ++comma;
112 } else
113 break;
114 }
121} 115}
122 116
123int 117int
124mount_one( 118mount_one (
125 char * blockDevice 119 char *blockDevice, char *directory, char *filesystemType,
126,char * directory 120 unsigned long flags, char *string_flags)
127,char * filesystemType
128,unsigned long flags
129,char * string_flags
130,int noMtab
131,int fake)
132{ 121{
133 int error = 0; 122 int status = 0;
134 int status = 0;
135
136 char buf[255];
137
138 if (!fake) {
139 if (*filesystemType == 'a') { //Will fail on real FS starting with 'a'
140
141 FILE *f = fopen("/proc/filesystems", "r");
142
143 if (f == NULL) return 1;
144
145 while (fgets(buf, sizeof(buf), f) != NULL) {
146 filesystemType = buf;
147 if (*filesystemType == '\t') { // Not a nodev filesystem
148
149 while (*filesystemType && *filesystemType != '\n') filesystemType++;
150 *filesystemType = '\0';
151
152 filesystemType = buf;
153 filesystemType++; //hop past tab
154
155 status = mount(blockDevice, directory, filesystemType,
156 flags|MS_MGC_VAL ,string_flags);
157 error = errno;
158
159 if (status == 0) break;
160 }
161 }
162 fclose(f);
163 } else {
164
165 status = mount( blockDevice, directory, filesystemType,
166 flags|MS_MGC_VAL ,string_flags);
167 error = errno;
168 }
169 }
170
171 if ( status == 0 ) {
172 char * s = &string_flags[strlen(string_flags)];
173 FILE * mountTable;
174 if ( s != string_flags ) {
175 *s++ = ',';
176 show_flags(flags, s);
177 }
178 if ( !noMtab && (mountTable = setmntent("/etc/mtab", "a+")) ) {
179 int length = strlen(directory);
180 struct mntent m;
181 123
182 if ( length > 1 && directory[length - 1] == '/' ) 124 char buf[255];
183 directory[length - 1] = '\0';
184 125
185 if ( filesystemType == 0 ) { 126 if (strcmp(filesystemType, "auto") == 0) {
186 struct mntent * p 127 FILE *f = fopen ("/proc/filesystems", "r");
187 = findMountPoint(blockDevice, "/proc/mounts");
188 128
189 if ( p && p->mnt_type ) 129 if (f == NULL)
190 filesystemType = p->mnt_type; 130 return( FALSE);
191 }
192 m.mnt_fsname = blockDevice;
193 m.mnt_dir = directory;
194 m.mnt_type = filesystemType ? filesystemType : "default";
195
196 if (*string_flags) {
197 m.mnt_opts = string_flags;
198 } else {
199 if ( (flags | MS_RDONLY) == flags )
200 m.mnt_opts = "ro";
201 else
202 m.mnt_opts = "rw";
203 }
204
205 m.mnt_freq = 0;
206 m.mnt_passno = 0;
207 addmntent(mountTable, &m);
208 endmntent(mountTable);
209 }
210 return 0;
211 } else {
212 fprintf(stderr, "Mount %s", blockDevice);
213 if ( filesystemType && *filesystemType )
214 fprintf(stderr, " (type %s)", filesystemType);
215 131
216 fprintf( 132 while (fgets (buf, sizeof (buf), f) != NULL) {
217 stderr 133 filesystemType = buf;
218 ," on %s: " 134 if (*filesystemType == '\t') { // Not a nodev filesystem
219 ,directory);
220 135
221 switch ( error ) { 136 // Add NULL termination to each line
222 case EPERM: 137 while (*filesystemType && *filesystemType != '\n')
223 if (geteuid() == 0) 138 filesystemType++;
224 fprintf( 139 *filesystemType = '\0';
225 stderr
226 ,"mount point %s is not a directory"
227 ,blockDevice);
228 else
229 fprintf(
230 stderr
231 ,"must be superuser to use mount");
232 break;
233 case EBUSY:
234 fprintf(
235 stderr
236 ,"%s already mounted or %s busy"
237 ,blockDevice
238 ,directory);
239 break;
240 case ENOENT:
241 {
242 struct stat statbuf;
243 if ( stat(directory, &statbuf) != 0 )
244 fprintf(
245 stderr
246 ,"directory %s does not exist"
247 ,directory);
248 else if ( stat(blockDevice, &statbuf) != 0 )
249 fprintf(
250 stderr
251 ,"block device %s does not exist"
252 ,blockDevice);
253 else
254 fprintf(
255 stderr
256 ,"%s is not mounted on %s, but the mount table says it is."
257 ,blockDevice
258 ,directory);
259 break;
260 }
261 case ENOTDIR:
262 fprintf(
263 stderr
264 ,"%s is not a directory"
265 ,directory);
266 break;
267 case EINVAL:
268 fprintf(
269 stderr
270 ,"wrong filesystem type, or bad superblock on %s"
271 ,blockDevice);
272 break;
273 case EMFILE:
274 fprintf(stderr, "mount table full");
275 break;
276 case EIO:
277 fprintf(
278 stderr
279 ,"I/O error reading %s"
280 ,blockDevice);
281 break;
282 case ENODEV:
283 {
284 FILE * f = fopen("/proc/filesystems", "r");
285 140
286 fprintf( 141 filesystemType = buf;
287 stderr 142 filesystemType++; // hop past tab
288 ,"filesystem type %s not in kernel.\n"
289 ,filesystemType);
290 fprintf(stderr, "Do you need to load a module?\n");
291 if ( f ) {
292 char buf[100];
293 143
294 fprintf( 144 status = mount (blockDevice, directory, filesystemType,
295 stderr 145 flags | MS_MGC_VAL, string_flags);
296 ,"Here are the filesystem types the kernel" 146 if (status == 0)
297 " can mount:\n"); 147 break;
298 while ( fgets(buf, sizeof(buf), f) != 0 ) 148 }
299 fprintf(stderr, "\t%s", buf);
300 fclose(f);
301 }
302 break;
303 }
304 case ENOTBLK:
305 fprintf(
306 stderr
307 ,"%s is not a block device"
308 ,blockDevice);
309 break;
310 case ENXIO:
311 fprintf(
312 stderr
313 ,"%s is not a valid block device"
314 ,blockDevice);
315 break;
316 default:
317 fputs(strerror(errno), stderr);
318 }
319 putc('\n', stderr);
320 return -1;
321 } 149 }
150 fclose (f);
151 } else {
152 status = mount (blockDevice, directory, filesystemType,
153 flags | MS_MGC_VAL, string_flags);
154 }
155
156 if (status) {
157 fprintf (stderr, "Mounting %s on %s failed: %s\n",
158 blockDevice, directory, strerror(errno));
159 return (FALSE);
160 }
161 return (TRUE);
322} 162}
323 163
324extern int 164extern int mount_main (int argc, char **argv)
325mount_main(struct FileInfo * i, int argc, char * * argv)
326{ 165{
327 char string_flags[1024]; 166 char string_flags[1024]="\0";
328 unsigned long flags = 0; 167 unsigned long flags = 0;
329 char * filesystemType = "auto"; 168 char *filesystemType = "auto";
330 int fake = 0; 169 int all = 0;
331 int noMtab = 0; 170 int i = argc;
332 int all = 0; 171
333 172 if (argc == 1) {
334 *string_flags = '\0'; 173 FILE *mountTable;
335 174 if ((mountTable = setmntent ("/proc/mounts", "r"))) {
336 if ( argc == 1 ) { 175 struct mntent *m;
337 FILE * mountTable; 176 while ((m = getmntent (mountTable)) != 0) {
338 if ( (mountTable = setmntent("/etc/mtab", "r")) ) { 177 char *blockDevice = m->mnt_fsname;
339 struct mntent * m; 178 if (strcmp (blockDevice, "/dev/root") == 0)
340 while ( (m = getmntent(mountTable)) != 0 ) { 179 blockDevice = (getfsfile ("/"))->fs_spec;
341 printf( 180 printf ("%s on %s type %s (%s)\n", blockDevice, m->mnt_dir,
342 "%s on %s type %s (%s)\n" 181 m->mnt_type, m->mnt_opts);
343 ,m->mnt_fsname 182 }
344 ,m->mnt_dir 183 endmntent (mountTable);
345 ,m->mnt_type
346 ,m->mnt_opts);
347 }
348 endmntent(mountTable);
349 }
350 return 0;
351 } 184 }
352 185 return( TRUE);
353 while ( argc >= 2 && argv[1][0] == '-' ) { 186 }
354 switch ( argv[1][1] ) { 187
355 case 'f': 188
356 fake = 1; 189 /* Parse options */
357 break; 190 while (**argv) {
358 case 'n': 191 if (**argv == '-') {
359 noMtab = 1; 192 switch (**argv) {
360 break; 193 case 'o':
361 case 'o': 194 if (++argv == 0) {
362 if ( argc < 3 ) { 195 fprintf (stderr, "%s\n", mount_usage);
363 usage(mount_usage); 196 return( FALSE);
364 return 1;
365 }
366 parse_mount_options(argv[2], &flags, string_flags);
367 argc--;
368 argv++;
369 break;
370 case 'r':
371 flags |= MS_RDONLY;
372 break;
373 case 't':
374 if ( argc < 3 ) {
375 usage(mount_usage);
376 return 1;
377 }
378 filesystemType = argv[2];
379 argc--;
380 argv++;
381 break;
382 case 'v':
383 break;
384 case 'w':
385 flags &= ~MS_RDONLY;
386 break;
387 case 'a':
388 all = 1;
389 break;
390 default:
391 usage(mount_usage);
392 return 1;
393 } 197 }
198 parse_mount_options (*argv, &flags, string_flags);
394 argc--; 199 argc--;
395 argv++; 200 argv++;
396 } 201 break;
397 202 case 'r':
398 if (all == 1) { 203 flags |= MS_RDONLY;
399 struct mntent *m; 204 break;
400 FILE *f = setmntent("/etc/fstab", "r"); 205 case 't':
401 206 if (++argv == 0) {
402 if (f == NULL) { 207 fprintf (stderr, "%s\n", mount_usage);
403 return 1; 208 return( FALSE);
404 } 209 }
210 filesystemType = *argv;
211 argc--;
212 argv++;
213 break;
214 case 'w':
215 flags &= ~MS_RDONLY;
216 break;
217 case 'a':
218 all = 1;
219 break;
220 case 'v':
221 case 'h':
222 case '-':
223 fprintf (stderr, "%s\n", mount_usage);
224 return( TRUE);
225 }
226 }
227 i--;
228 argv++;
229 }
405 230
406 // FIXME: Combine read routine (make new function) with unmount_all to save space. 231 if (all == 1) {
232 struct mntent *m;
233 FILE *f = setmntent ("/etc/fstab", "r");
407 234
408 while ((m = getmntent(f)) != NULL) { 235 if (f == NULL) {
409 // If the file system isn't noauto, and isn't mounted on /, mount it 236 perror("/etc/fstab");
410 if ((!strstr(m->mnt_opts, "noauto")) && (m->mnt_dir[1] != '\0') 237 return( FALSE);
411 && !((m->mnt_type[0] == 's') && (m->mnt_type[1] == 'w')) 238 }
412 && !((m->mnt_type[0] == 'n') && (m->mnt_type[1] == 'f'))) { 239 // FIXME: Combine read routine (make new function) with unmount_all
413 mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, flags, m->mnt_opts, noMtab, fake); 240 // to save space.
414 } 241
415 } 242 while ((m = getmntent (f)) != NULL) {
243 // If the file system isn't noauto, and isn't mounted on /, mount
244 // it
245 if ((!strstr (m->mnt_opts, "noauto"))
246 && (m->mnt_dir[1] != '\0') && !((m->mnt_type[0] == 's')
247 && (m->mnt_type[1] == 'w'))
248 && !((m->mnt_type[0] == 'n') && (m->mnt_type[1] == 'f'))) {
249 mount_one (m->mnt_fsname, m->mnt_dir, m->mnt_type, flags,
250 m->mnt_opts);
251 }
252 }
416 253
417 endmntent(f); 254 endmntent (f);
255 } else {
256 if (argc >= 3) {
257 while (i < argc)
258 argv--;
259 while (**argv == '-')
260 argv++;
261 if (mount_one
262 (*argv, *(argv+1), filesystemType, flags,
263 string_flags) == 0) return 0;
264 else
265 return( FALSE);
418 } else { 266 } else {
419 if ( argc >= 3 ) { 267 fprintf (stderr, "%s\n", mount_usage);
420 if ( mount_one( argv[1], argv[2], filesystemType, flags, string_flags, noMtab, fake) == 0 ) 268 return( FALSE);
421 return 0;
422 else
423 return 1;
424 } else {
425 usage(mount_usage);
426 return 1;
427 }
428 } 269 }
429 return 0; 270 }
271 return( TRUE);
430} 272}