95f7dfb3cbeab4bb9e829d3ea75b343e253ccd1a
[oweals/busybox.git] / umount.c
1 /*
2  * Mini umount implementation for busybox
3  *
4  *
5  * Copyright (C) 1999 by Lineo, inc.
6  * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  *
22  */
23
24 #include "internal.h"
25 #include <stdio.h>
26 #include <sys/mount.h>
27 #include <mntent.h>
28 #include <fstab.h>
29 #include <errno.h>
30
31 static const char umount_usage[] = 
32 "Usage: umount filesystem\n"
33 "   or: umount directory\n"
34 "   or: umount -a"
35 "to unmount all mounted file systems.\n";
36
37 static int
38 umount_all()
39 {
40         int status;
41         struct mntent *m;
42         FILE *mountTable;
43
44         if ((mountTable = setmntent ("/proc/mounts", "r"))) {
45             while ((m = getmntent (mountTable)) != 0) {
46                 char *blockDevice = m->mnt_fsname;
47                 if (strcmp (blockDevice, "/dev/root") == 0)
48                     blockDevice = (getfsfile ("/"))->fs_spec;
49                 status=umount (m->mnt_dir);
50                 if (status!=0) {
51                     /* Don't bother retrying the umount on busy devices */
52                     if (errno==EBUSY) {
53                         perror(m->mnt_dir); 
54                         continue;
55                     }
56                     printf ("Trying to umount %s failed: %s\n", 
57                             m->mnt_dir, strerror(errno)); 
58                     printf ("Instead trying to umount %s\n", blockDevice); 
59                     status=umount (blockDevice);
60                     if (status!=0) {
61                         printf ("Couldn't umount %s on %s (type %s): %s\n", 
62                                 blockDevice, m->mnt_dir, m->mnt_type, strerror(errno));
63                     }
64                 }
65             }
66             endmntent (mountTable);
67         }
68         return( TRUE);
69 }
70
71 extern int
72 umount_main(int argc, char * * argv)
73 {
74
75     if (argc < 2) {
76         usage( umount_usage); 
77     }
78     argc--;
79     argv++;
80
81     /* Parse any options */
82     while (**argv == '-') {
83         while (*++(*argv)) switch (**argv) {
84             case 'a':
85                 exit ( umount_all() );
86                 break;
87             default:
88                 usage( umount_usage);
89         }
90     }
91     if ( umount(*argv) == 0 )
92              exit (TRUE);
93     else {
94         perror("umount");
95         exit( FALSE);
96     }
97 }
98