aboutsummaryrefslogtreecommitdiff
path: root/lib/getmountlist.c
blob: d5a392d6420e84fce1c59f04deeb49a8f6cf6098 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/* getmountlist.c - Get a linked list of mount points, with stat information.
 *
 * Copyright 2006 Rob Landley <rob@landley.net>
 */

#include "toys.h"
#include <mntent.h>

// Get list of mounted filesystems, including stat and statvfs info.
// Returns a reversed list, which is good for finding overmounts and such.

struct mtab_list *xgetmountlist(char *path)
{
  struct mtab_list *mtlist, *mt;
  struct mntent *me;
  FILE *fp;

  if (!path) path = "/proc/mounts";
  if (!(fp = setmntent(path, "r"))) perror_exit("bad %s", path);

  // The "test" part of the loop is done before the first time through and
  // again after each "increment", so putting the actual load there avoids
  // duplicating it. If the load was NULL, the loop stops.

  for (mtlist = 0; (me = getmntent(fp)); mtlist = mt) {
    mt = xzalloc(sizeof(struct mtab_list) + strlen(me->mnt_fsname) +
      strlen(me->mnt_dir) + strlen(me->mnt_type) + strlen(me->mnt_opts) + 4);
    mt->next = mtlist;

    // Collect details about mounted filesystem (don't bother for /etc/fstab).
    if (stat(me->mnt_dir, &(mt->stat)) || statvfs(me->mnt_dir, &(mt->statvfs)))
      perror_msg("stat '%s'");

    // Remember information from /proc/mounts
    mt->dir = stpcpy(mt->type, me->mnt_type)+1;
    mt->device = stpcpy(mt->dir, me->mnt_dir)+1;
    mt->opts = stpcpy(mt->device, me->mnt_fsname)+1;
    strcpy(mt->opts, me->mnt_opts);
  }
  endmntent(fp);

  return mtlist;
}