More stuff.
[oweals/busybox.git] / util-linux / umount.c
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
22 #include "internal.h"
23 #include <stdio.h>
24 #include <sys/mount.h>
25 #include <mntent.h>
26 #include <fstab.h>
27 #include <errno.h>
28
29 const char umount_usage[] = 
30 "Usage: umount filesystem\n"
31 "   or: umount directory\n"
32 "   or: umount -a"
33 "to unmount all mounted file systems.\n";
34
35 static int
36 umount_all()
37 {
38         int status;
39         struct mntent *m;
40         FILE *mountTable;
41
42         if ((mountTable = setmntent ("/proc/mounts", "r"))) {
43             while ((m = getmntent (mountTable)) != 0) {
44                 char *blockDevice = m->mnt_fsname;
45                 if (strcmp (blockDevice, "/dev/root") == 0)
46                     blockDevice = (getfsfile ("/"))->fs_spec;
47                 status=umount (m->mnt_dir);
48                 if (status!=0) {
49                     /* Don't bother retrying the umount on busy devices */
50                     if (errno==EBUSY) {
51                         perror(m->mnt_dir); 
52                         continue;
53                     }
54                     printf ("Trying to umount %s failed: %s\n", 
55                             m->mnt_dir, strerror(errno)); 
56                     printf ("Instead trying to umount %s\n", blockDevice); 
57                     status=umount (blockDevice);
58                     if (status!=0) {
59                         printf ("Couldn't umount %s on %s (type %s): %s\n", 
60                                 blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
61                     }
62                 }
63             }
64             endmntent (mountTable);
65         }
66         return( TRUE);
67 }
68
69 extern int
70 umount_main(int argc, char * * argv)
71 {
72
73     if (argc < 2) {
74         usage( umount_usage); 
75     }
76     argc--;
77     argv++;
78
79     /* Parse any options */
80     while (**argv == '-') {
81         while (*++(*argv)) switch (**argv) {
82             case 'a':
83                 exit ( umount_all() );
84                 break;
85             default:
86                 usage( umount_usage);
87         }
88     }
89     if ( umount(*argv) == 0 )
90              exit (TRUE);
91     else {
92         perror("umount");
93         exit( FALSE);
94     }
95 }
96