xref: /minix/minix/commands/umount/umount.c (revision 7f5f010b)
1 /* umount - unmount a file system		Author: Andy Tanenbaum */
2 
3 #include <minix/type.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <getopt.h>
8 #include <errno.h>
9 #include <limits.h>
10 #include <minix/minlib.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include <sys/mount.h>
15 #include <stdio.h>
16 
17 int main(int argc, char **argv);
18 int find_mtab_entry(char *name);
19 void update_mtab(void);
20 void usage(void);
21 
22 static char device[PATH_MAX], mount_point[PATH_MAX], type[MNTNAMELEN],
23 		flags[MNTFLAGLEN];
24 
25 int main(argc, argv)
26 int argc;
27 char *argv[];
28 {
29   int found;
30   int umount_flags = 0UL;
31   int c;
32   char *name;
33 
34   while ((c = getopt (argc, argv, "e")) != -1)
35   {
36 	switch (c) {
37 		case 'e': umount_flags |= MS_EXISTING; break;
38 		default: break;
39 	}
40   }
41 
42   if (argc - optind != 1) {
43 	   usage();
44   }
45 
46   name = argv[optind];
47 
48   found = find_mtab_entry(name);
49 
50   if (minix_umount(name, umount_flags) < 0) {
51 	if (errno == EINVAL)
52 		std_err("umount: Device not mounted\n");
53 	else if (errno == ENOTBLK)
54 		std_err("umount: Not a mountpoint\n");
55 	else
56 		perror("umount");
57 	exit(1);
58   }
59   if (found) {
60 	printf("%s unmounted from %s\n", device, mount_point);
61   }
62   return(0);
63 }
64 
65 int find_mtab_entry(name)
66 char *name;
67 {
68 /* Find a matching mtab entry for 'name' which may be a special or a path,
69  * and generate a new mtab file without this entry on the fly. Do not write
70  * out the result yet. Return whether we found a matching entry.
71  */
72   char e_dev[PATH_MAX], e_mount_point[PATH_MAX], e_type[MNTNAMELEN],
73 	e_flags[MNTFLAGLEN];
74   struct stat nstat, mstat;
75   int n, found;
76 
77   if (load_mtab("umount") < 0) return 0;
78 
79   if (stat(name, &nstat) != 0) return 0;
80 
81   found = 0;
82   while (1) {
83 	n = get_mtab_entry(e_dev, e_mount_point, e_type, e_flags);
84 	if (n < 0) break;
85 	if (strcmp(name, e_dev) == 0 || (stat(e_mount_point, &mstat) == 0 &&
86 		mstat.st_dev == nstat.st_dev && mstat.st_ino == nstat.st_ino))
87 	{
88 		strlcpy(device, e_dev, PATH_MAX);
89 		strlcpy(mount_point, e_mount_point, PATH_MAX);
90 		strlcpy(type, e_type, MNTNAMELEN);
91 		strlcpy(flags, e_flags, MNTFLAGLEN);
92 		found = 1;
93 		break;
94 	}
95   }
96 
97   return found;
98 }
99 
100 void usage()
101 {
102   std_err("Usage: umount [-e] name\n");
103   exit(1);
104 }
105