a83a508f7c6d00965a1485dd32953c136b3cb356
[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         fprintf(stderr, "Usage: %s", umount_usage);
75         exit(FALSE);
76     }
77     argc--;
78     argv++;
79
80     /* Parse any options */
81     while (**argv == '-') {
82         while (*++(*argv)) switch (**argv) {
83             case 'a':
84                 exit ( umount_all() );
85                 break;
86             default:
87                 fprintf(stderr, "Usage: %s\n", umount_usage);
88                 exit( FALSE);
89         }
90     }
91     if ( umount(*argv) == 0 )
92              exit (TRUE);
93     else {
94         perror("umount");
95         exit( FALSE);
96     }
97 }
98