1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#define FOR_umount
32#include "toys.h"
33
34GLOBALS(
35 struct arg_list *t;
36
37 char *types;
38)
39
40
41
42
43
44
45
46
47
48
49
50
51static void do_umount(char *dir, char *dev, int flags)
52{
53
54 if (CFG_TOYBOX_SUID && getuid()) {
55 struct mtab_list *mt = dlist_terminate(xgetmountlist("/etc/fstab"));
56 int len, user = 0;
57
58 while (mt) {
59 struct mtab_list *mtemp = mt;
60 char *s;
61
62 if (!strcmp(mt->dir, dir)) while ((s = comma_iterate(&mt->opts, &len))) {
63 if (len == 4 && strncmp(s, "user", 4)) user = 1;
64 else if (len == 6 && strncmp(s, "nouser", 6)) user = 0;
65 }
66
67 mt = mt->next;
68 free(mtemp);
69 }
70
71 if (!user) {
72 error_msg("not root");
73
74 return;
75 }
76 }
77
78 if (!umount2(dir, flags)) {
79 if (toys.optflags & FLAG_v) xprintf("%s unmounted\n", dir);
80
81
82
83 if (dev && !(toys.optflags & FLAG_D)) {
84 int lfd = open(dev, O_RDONLY);
85
86 if (lfd != -1) {
87
88 if (!ioctl(lfd, 0x4C01) && (toys.optflags & FLAG_v))
89 xprintf("%s cleared\n", dev);
90 close(lfd);
91 }
92 }
93
94 return;
95 }
96
97 if (toys.optflags & FLAG_r) {
98 if (!mount("", dir, "", MS_REMOUNT|MS_RDONLY, "")) {
99 if (toys.optflags & FLAG_v) xprintf("%s remounted ro\n", dir);
100 return;
101 }
102 }
103
104 perror_msg_raw(dir);
105}
106
107void umount_main(void)
108{
109 char **optargs, *pm = "/proc/mounts";
110 struct mtab_list *mlsave = 0, *mlrev = 0, *ml;
111 int flags=0;
112
113 if (!toys.optc && !(toys.optflags & FLAG_a))
114 error_exit("Need 1 arg or -a");
115
116 if (toys.optflags & FLAG_f) flags |= MNT_FORCE;
117 if (toys.optflags & FLAG_l) flags |= MNT_DETACH;
118
119
120
121 if (!(toys.optflags & FLAG_n) && !access(pm, R_OK))
122 mlrev = dlist_terminate(mlsave = xgetmountlist(pm));
123
124
125 if (toys.optflags & FLAG_a) {
126 char *typestr = 0;
127 struct arg_list *tal;
128
129 for (tal = TT.t; tal; tal = tal->next) comma_collate(&typestr, tal->arg);
130 for (ml = mlrev; ml; ml = ml->prev)
131 if (mountlist_istype(ml, typestr)) do_umount(ml->dir, ml->device, flags);
132 if (CFG_TOYBOX_FREE) {
133 free(typestr);
134 llist_traverse(mlsave, free);
135 }
136
137 } else for (optargs = toys.optargs; *optargs; optargs++) {
138 char *abs = xabspath(*optargs, 0);
139
140 for (ml = abs ? mlrev : 0; ml; ml = ml->prev) {
141 if (!strcmp(ml->dir, abs)) break;
142 if (!strcmp(ml->device, abs)) {
143 free(abs);
144 abs = ml->dir;
145 break;
146 }
147 }
148
149 do_umount(abs ? abs : *optargs, ml ? ml->device : 0, flags);
150 if (ml && abs != ml->dir) free(abs);
151 }
152}
153