diff options
Diffstat (limited to 'toys/lsb/umount.c')
-rw-r--r-- | toys/lsb/umount.c | 87 |
1 files changed, 28 insertions, 59 deletions
diff --git a/toys/lsb/umount.c b/toys/lsb/umount.c index 002ffd68..c7998e41 100644 --- a/toys/lsb/umount.c +++ b/toys/lsb/umount.c @@ -37,53 +37,44 @@ GLOBALS( char *types; ) -// todo +// todo (done?) // borrow df code to identify filesystem? // umount -a from fstab // umount when getpid() not 0, according to fstab // lookup mount: losetup -d, bind, file, block +// loopback delete +// fstab -o user // TODO -// loopback delete -// fstab -o user +// swapon, swapoff -// Realloc *old with oldstring,newstring - -void comma_collate(char **old, char *new) -{ - char *temp, *atold = *old; - - // Only add a comma if old string didn't end with one - if (atold && *atold) { - char *comma = ","; - - if (atold[strlen(atold)-1] == ',') comma = ""; - temp = xmprintf("%s%s%s", atold, comma, new); - } else temp = xstrdup(new); - free (atold); - *old = temp; -} - -// iterate through strings in a comma separated list. -// returns start of next entry or NULL if none -// sets *len to length of entry (not including comma) -// advances *list to start of next entry -char *comma_iterate(char **list, int *len) +static void do_umount(char *dir, char *dev, int flags) { - char *start = *list, *end; + // is it ok for this user to umount this mount? + if (CFG_TOYBOX_SUID && getuid()) { + struct mtab_list *mt = dlist_terminate(xgetmountlist("/etc/fstab")); + int len, user = 0; + + while (mt) { + struct mtab_list *mtemp = mt; + char *s; + + if (!strcmp(mt->dir, dir)) while ((s = comma_iterate(&mt->opts, &len))) { + if (len == 4 && strncmp(s, "user", 4)) user = 1; + else if (len == 6 && strncmp(s, "nouser", 6)) user = 0; + } - if (!*list) return 0; + mt = mt->next; + free(mtemp); + } - if (!(end = strchr(*list, ','))) { - *len = strlen(*list); - *list = 0; - } else *list += (*len = end-start)+1; + if (!user) { + error_msg("not root"); - return start; -} + return; + } + } -static void do_umount(char *dir, char *dev, int flags) -{ if (!umount2(dir, flags)) { if (toys.optflags & FLAG_v) xprintf("%s unmounted\n", dir); @@ -136,30 +127,8 @@ void umount_main(void) struct arg_list *tal; for (tal = TT.t; tal; tal = tal->next) comma_collate(&typestr, tal->arg); - for (ml = mlrev; ml; ml = ml->prev) { - if (typestr) { - char *type, *types = typestr; - int len, skip = strncmp(types, "no", 2); - - for (;;) { - if (!(type = comma_iterate(&types, &len))) break; - if (!skip) { - // If one -t starts with "no", the rest must too - if (strncmp(type, "no", 2)) error_exit("bad -t"); - if (!strncmp(type+2, ml->type, len-2)) { - skip = 1; - break; - } - } else if (!strncmp(type, ml->type, len) && !ml->type[len]) { - skip = 0; - break; - } - } - if (skip) continue; - } - - do_umount(ml->dir, ml->device, flags); - } + for (ml = mlrev; ml; ml = ml->prev) + if (mountlist_istype(ml, typestr)) do_umount(ml->dir, ml->device, flags); if (CFG_TOYBOX_FREE) { free(typestr); llist_traverse(mlsave, free); |