toybox/lib/getmountlist.c
<<
>>
Prefs
   1/* getmountlist.c - Get a linked list of mount points, with stat information.
   2 *
   3 * Copyright 2006 Rob Landley <rob@landley.net>
   4 */
   5
   6#include "toys.h"
   7#include <mntent.h>
   8
   9static void octal_deslash(char *s)
  10{
  11  char *o = s;
  12
  13  while (*s) {
  14    if (*s == '\\') {
  15      int i, oct = 0;
  16
  17      for (i = 1; i < 4; i++) {
  18        if (!isdigit(s[i])) break;
  19        oct = (oct<<3)+s[i]-'0';
  20      }
  21      if (i == 4) {
  22        *o++ = oct;
  23        s += i;
  24        continue;
  25      }
  26    }
  27    *o++ = *s++;
  28  }
  29
  30  *o = 0;
  31}
  32
  33// Check if this type matches list.
  34// Odd syntax: typelist all yes = if any, typelist all no = if none.
  35
  36int mountlist_istype(struct mtab_list *ml, char *typelist)
  37{
  38  int len, skip;
  39  char *t;
  40
  41  if (!typelist) return 1;
  42
  43  skip = strncmp(typelist, "no", 2);
  44
  45  for (;;) {
  46    if (!(t = comma_iterate(&typelist, &len))) break;
  47    if (!skip) {
  48      // If one -t starts with "no", the rest must too
  49      if (strncmp(t, "no", 2)) error_exit("bad typelist");
  50      if (!strncmp(t+2, ml->type, len-2)) {
  51        skip = 1;
  52        break;
  53      }
  54    } else if (!strncmp(t, ml->type, len) && !ml->type[len]) {
  55      skip = 0;
  56      break;
  57    }
  58  }
  59
  60  return !skip;
  61}
  62
  63// Get list of mounted filesystems, including stat and statvfs info.
  64// Returns a reversed list, which is good for finding overmounts and such.
  65
  66struct mtab_list *xgetmountlist(char *path)
  67{
  68  struct mtab_list *mtlist = 0, *mt;
  69  struct mntent *me;
  70  FILE *fp;
  71  char *p = path ? path : "/proc/mounts";
  72
  73  if (!(fp = setmntent(p, "r"))) perror_exit("bad %s", p);
  74
  75  // The "test" part of the loop is done before the first time through and
  76  // again after each "increment", so putting the actual load there avoids
  77  // duplicating it. If the load was NULL, the loop stops.
  78
  79  while ((me = getmntent(fp))) {
  80    mt = xzalloc(sizeof(struct mtab_list) + strlen(me->mnt_fsname) +
  81      strlen(me->mnt_dir) + strlen(me->mnt_type) + strlen(me->mnt_opts) + 4);
  82    dlist_add_nomalloc((void *)&mtlist, (void *)mt);
  83
  84    // Collect details about mounted filesystem
  85    // Don't report errors, just leave data zeroed
  86    if (!path) {
  87      stat(me->mnt_dir, &(mt->stat));
  88      statvfs(me->mnt_dir, &(mt->statvfs));
  89    }
  90
  91    // Remember information from /proc/mounts
  92    mt->dir = stpcpy(mt->type, me->mnt_type)+1;
  93    mt->device = stpcpy(mt->dir, me->mnt_dir)+1;
  94    mt->opts = stpcpy(mt->device, me->mnt_fsname)+1;
  95    strcpy(mt->opts, me->mnt_opts);
  96
  97    octal_deslash(mt->dir);
  98    octal_deslash(mt->device);
  99  }
 100  endmntent(fp);
 101
 102  return mtlist;
 103}
 104