aboutsummaryrefslogtreecommitdiff
path: root/lib/getmountlist.c
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2014-08-24 23:46:23 -0500
committerRob Landley <rob@landley.net>2014-08-24 23:46:23 -0500
commite996bddf88a946a8ac8338c02e14add57e3d588c (patch)
tree0ee8e48bd53058370b0a3203610aeb131bc62d8a /lib/getmountlist.c
parent5d16faa426b641aefe2d019cbbf76a3d49c4549f (diff)
downloadtoybox-e996bddf88a946a8ac8338c02e14add57e3d588c.tar.gz
Work in progress snapshot of mount, with fallout to umount. (Not done yet.)
Diffstat (limited to 'lib/getmountlist.c')
-rw-r--r--lib/getmountlist.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/lib/getmountlist.c b/lib/getmountlist.c
index 0b7ff06b..a88a7b90 100644
--- a/lib/getmountlist.c
+++ b/lib/getmountlist.c
@@ -6,6 +6,129 @@
#include "toys.h"
#include <mntent.h>
+// 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)
+{
+ char *start = *list, *end;
+
+ if (!*list) return 0;
+
+ if (!(end = strchr(*list, ','))) {
+ *len = strlen(*list);
+ *list = 0;
+ } else *list += (*len = end-start)+1;
+
+ return start;
+}
+
+static void deslash(char *s)
+{
+ char *o = s;
+
+ while (*s) {
+ if (*s == '\\') {
+ int i, oct = 0;
+
+ for (i = 1; i < 4; i++) {
+ if (!isdigit(s[i])) break;
+ oct = (oct<<3)+s[i]-'0';
+ }
+ if (i == 4) {
+ *o++ = oct;
+ s += i;
+ continue;
+ }
+ }
+ *o++ = *s++;
+ }
+
+ *o = 0;
+}
+
+// check all instances of opt and "no"opt in optlist, return true if opt
+// found and last instance wasn't no. If clean, remove each instance from list.
+int comma_scan(char *optlist, char *opt, int clean)
+{
+ int optlen = strlen(opt), len, no, got = 0;
+
+ if (optlist) for (;;) {
+ char *s = comma_iterate(&optlist, &len);
+
+ if (!s) break;
+ no = 2*(*s == 'n' && s[1] == 'o');
+ if (optlen == len+no && !strcmp(opt, s+no)) got = !no;
+ if (clean) memmove(s, optlist, strlen(optlist)+1);
+ }
+
+ return got;
+}
+
+// return true if all scanlist options enabled in optlist
+int comma_scanall(char *optlist, char *scanlist)
+{
+ int i = 1;
+
+ for (;;) {
+ char *opt = comma_iterate(&scanlist, &i), *s = xstrndup(opt, i);
+
+ i = comma_scan(optlist, s, 0);
+ free(s);
+ if (!i) break;
+ }
+
+ return i;
+}
+
+// Check if this type matches list.
+// Odd syntax: typelist all yes = if any, typelist all no = if none.
+
+int mountlist_istype(struct mtab_list *ml, char *typelist)
+{
+ int len, skip;
+ char *t;
+
+ if (!typelist) return 1;
+
+ skip = strncmp(typelist, "no", 2);
+
+ for (;;) {
+ if (!(t = comma_iterate(&typelist, &len))) break;
+ if (!skip) {
+ // If one -t starts with "no", the rest must too
+ if (strncmp(t, "no", 2)) error_exit("bad typelist");
+ if (!strncmp(t+2, ml->type, len-2)) {
+ skip = 1;
+ break;
+ }
+ } else if (!strncmp(t, ml->type, len) && !ml->type[len]) {
+ skip = 0;
+ break;
+ }
+ }
+
+ return !skip;
+}
+
// Get list of mounted filesystems, including stat and statvfs info.
// Returns a reversed list, which is good for finding overmounts and such.
@@ -39,6 +162,9 @@ struct mtab_list *xgetmountlist(char *path)
mt->device = stpcpy(mt->dir, me->mnt_dir)+1;
mt->opts = stpcpy(mt->device, me->mnt_fsname)+1;
strcpy(mt->opts, me->mnt_opts);
+
+ deslash(mt->dir);
+ deslash(mt->device);
}
endmntent(fp);