Work in progress snapshot of mount, with fallout to umount. (Not done yet.)
diff --git a/lib/getmountlist.c b/lib/getmountlist.c
index 0b7ff06..a88a7b9 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 @@
     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);