Mercurial > hg > toybox
comparison toys/lsb/umount.c @ 1447:487716951287 draft
Work in progress snapshot of mount, with fallout to umount. (Not done yet.)
author | Rob Landley <rob@landley.net> |
---|---|
date | Sun, 24 Aug 2014 23:46:23 -0500 |
parents | 9748833918b0 |
children |
comparison
equal
deleted
inserted
replaced
1446:f46ccbcf3f13 | 1447:487716951287 |
---|---|
35 struct arg_list *t; | 35 struct arg_list *t; |
36 | 36 |
37 char *types; | 37 char *types; |
38 ) | 38 ) |
39 | 39 |
40 // todo | 40 // todo (done?) |
41 // borrow df code to identify filesystem? | 41 // borrow df code to identify filesystem? |
42 // umount -a from fstab | 42 // umount -a from fstab |
43 // umount when getpid() not 0, according to fstab | 43 // umount when getpid() not 0, according to fstab |
44 // lookup mount: losetup -d, bind, file, block | 44 // lookup mount: losetup -d, bind, file, block |
45 // loopback delete | |
46 // fstab -o user | |
45 | 47 |
46 // TODO | 48 // TODO |
47 // loopback delete | 49 // swapon, swapoff |
48 // fstab -o user | |
49 | |
50 // Realloc *old with oldstring,newstring | |
51 | |
52 void comma_collate(char **old, char *new) | |
53 { | |
54 char *temp, *atold = *old; | |
55 | |
56 // Only add a comma if old string didn't end with one | |
57 if (atold && *atold) { | |
58 char *comma = ","; | |
59 | |
60 if (atold[strlen(atold)-1] == ',') comma = ""; | |
61 temp = xmprintf("%s%s%s", atold, comma, new); | |
62 } else temp = xstrdup(new); | |
63 free (atold); | |
64 *old = temp; | |
65 } | |
66 | |
67 // iterate through strings in a comma separated list. | |
68 // returns start of next entry or NULL if none | |
69 // sets *len to length of entry (not including comma) | |
70 // advances *list to start of next entry | |
71 char *comma_iterate(char **list, int *len) | |
72 { | |
73 char *start = *list, *end; | |
74 | |
75 if (!*list) return 0; | |
76 | |
77 if (!(end = strchr(*list, ','))) { | |
78 *len = strlen(*list); | |
79 *list = 0; | |
80 } else *list += (*len = end-start)+1; | |
81 | |
82 return start; | |
83 } | |
84 | 50 |
85 static void do_umount(char *dir, char *dev, int flags) | 51 static void do_umount(char *dir, char *dev, int flags) |
86 { | 52 { |
53 // is it ok for this user to umount this mount? | |
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 | |
87 if (!umount2(dir, flags)) { | 78 if (!umount2(dir, flags)) { |
88 if (toys.optflags & FLAG_v) xprintf("%s unmounted\n", dir); | 79 if (toys.optflags & FLAG_v) xprintf("%s unmounted\n", dir); |
89 | 80 |
90 // Attempt to disassociate loopback device. This ioctl should be ignored | 81 // Attempt to disassociate loopback device. This ioctl should be ignored |
91 // for anything else, because lanana allocated ioctl range 'L' to loopback | 82 // for anything else, because lanana allocated ioctl range 'L' to loopback |
134 if (toys.optflags & FLAG_a) { | 125 if (toys.optflags & FLAG_a) { |
135 char *typestr = 0; | 126 char *typestr = 0; |
136 struct arg_list *tal; | 127 struct arg_list *tal; |
137 | 128 |
138 for (tal = TT.t; tal; tal = tal->next) comma_collate(&typestr, tal->arg); | 129 for (tal = TT.t; tal; tal = tal->next) comma_collate(&typestr, tal->arg); |
139 for (ml = mlrev; ml; ml = ml->prev) { | 130 for (ml = mlrev; ml; ml = ml->prev) |
140 if (typestr) { | 131 if (mountlist_istype(ml, typestr)) do_umount(ml->dir, ml->device, flags); |
141 char *type, *types = typestr; | |
142 int len, skip = strncmp(types, "no", 2); | |
143 | |
144 for (;;) { | |
145 if (!(type = comma_iterate(&types, &len))) break; | |
146 if (!skip) { | |
147 // If one -t starts with "no", the rest must too | |
148 if (strncmp(type, "no", 2)) error_exit("bad -t"); | |
149 if (!strncmp(type+2, ml->type, len-2)) { | |
150 skip = 1; | |
151 break; | |
152 } | |
153 } else if (!strncmp(type, ml->type, len) && !ml->type[len]) { | |
154 skip = 0; | |
155 break; | |
156 } | |
157 } | |
158 if (skip) continue; | |
159 } | |
160 | |
161 do_umount(ml->dir, ml->device, flags); | |
162 } | |
163 if (CFG_TOYBOX_FREE) { | 132 if (CFG_TOYBOX_FREE) { |
164 free(typestr); | 133 free(typestr); |
165 llist_traverse(mlsave, free); | 134 llist_traverse(mlsave, free); |
166 } | 135 } |
167 // TODO: under what circumstances do we umount non-absolute path? | 136 // TODO: under what circumstances do we umount non-absolute path? |