summaryrefslogtreecommitdiffstats
path: root/mtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'mtab.c')
-rw-r--r--mtab.c246
1 files changed, 0 insertions, 246 deletions
diff --git a/mtab.c b/mtab.c
deleted file mode 100644
index 8eb90bb..0000000
--- a/mtab.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/****************************************************************************
- * bfs *
- * Copyright (C) 2017-2020 Tavian Barnes <tavianator@tavianator.com> *
- * *
- * Permission to use, copy, modify, and/or distribute this software for any *
- * purpose with or without fee is hereby granted. *
- * *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF *
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR *
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES *
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN *
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
- ****************************************************************************/
-
-#include "mtab.h"
-#include "darray.h"
-#include "stat.h"
-#include "trie.h"
-#include "util.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#if BFS_HAS_SYS_PARAM
-# include <sys/param.h>
-#endif
-
-#if BFS_HAS_MNTENT
-# define BFS_MNTENT 1
-#elif BSD
-# define BFS_MNTINFO 1
-#elif __SVR4
-# define BFS_MNTTAB 1
-#endif
-
-#if BFS_MNTENT
-# include <mntent.h>
-# include <paths.h>
-# include <stdio.h>
-#elif BFS_MNTINFO
-# include <sys/mount.h>
-# include <sys/ucred.h>
-#elif BFS_MNTTAB
-# include <stdio.h>
-# include <sys/mnttab.h>
-#endif
-
-/**
- * A mount point in the table.
- */
-struct bfs_mtab_entry {
- /** The path to the mount point. */
- char *path;
- /** The filesystem type. */
- char *type;
-};
-
-struct bfs_mtab {
- /** The list of mount points. */
- struct bfs_mtab_entry *entries;
- /** The basenames of every mount point. */
- struct trie names;
-
- /** A map from device ID to fstype (populated lazily). */
- struct trie types;
- /** Whether the types map has been populated. */
- bool types_filled;
-};
-
-/**
- * Add an entry to the mount table.
- */
-static int bfs_mtab_add(struct bfs_mtab *mtab, const char *path, const char *type) {
- struct bfs_mtab_entry entry = {
- .path = strdup(path),
- .type = strdup(type),
- };
-
- if (!entry.path || !entry.type) {
- goto fail_entry;
- }
-
- if (DARRAY_PUSH(&mtab->entries, &entry) != 0) {
- goto fail_entry;
- }
-
- if (!trie_insert_str(&mtab->names, xbasename(path))) {
- goto fail;
- }
-
- return 0;
-
-fail_entry:
- free(entry.type);
- free(entry.path);
-fail:
- return -1;
-}
-
-struct bfs_mtab *bfs_mtab_parse(void) {
- struct bfs_mtab *mtab = malloc(sizeof(*mtab));
- if (!mtab) {
- return NULL;
- }
-
- mtab->entries = NULL;
- trie_init(&mtab->names);
- trie_init(&mtab->types);
- mtab->types_filled = false;
-
- int error = 0;
-
-#if BFS_MNTENT
-
- FILE *file = setmntent(_PATH_MOUNTED, "r");
- if (!file) {
- // In case we're in a chroot or something with /proc but no /etc/mtab
- error = errno;
- file = setmntent("/proc/mounts", "r");
- }
- if (!file) {
- goto fail;
- }
-
- struct mntent *mnt;
- while ((mnt = getmntent(file))) {
- if (bfs_mtab_add(mtab, mnt->mnt_dir, mnt->mnt_type) != 0) {
- error = errno;
- endmntent(file);
- goto fail;
- }
- }
-
- endmntent(file);
-
-#elif BFS_MNTINFO
-
-#if __NetBSD__
- typedef struct statvfs bfs_statfs;
-#else
- typedef struct statfs bfs_statfs;
-#endif
-
- bfs_statfs *mntbuf;
- int size = getmntinfo(&mntbuf, MNT_WAIT);
- if (size < 0) {
- error = errno;
- goto fail;
- }
-
- for (bfs_statfs *mnt = mntbuf; mnt < mntbuf + size; ++mnt) {
- if (bfs_mtab_add(mtab, mnt->f_mntonname, mnt->f_fstypename) != 0) {
- error = errno;
- goto fail;
- }
- }
-
-#elif BFS_MNTTAB
-
- FILE *file = xfopen(MNTTAB, O_RDONLY | O_CLOEXEC);
- if (!file) {
- error = errno;
- goto fail;
- }
-
- struct mnttab mnt;
- while (getmntent(file, &mnt) == 0) {
- if (bfs_mtab_add(mtab, mnt.mnt_mountp, mnt.mnt_fstype) != 0) {
- error = errno;
- fclose(file);
- goto fail;
- }
- }
-
- fclose(file);
-
-#else
-
- error = ENOTSUP;
- goto fail;
-
-#endif
-
- return mtab;
-
-fail:
- bfs_mtab_free(mtab);
- errno = error;
- return NULL;
-}
-
-static void bfs_mtab_fill_types(struct bfs_mtab *mtab) {
- for (size_t i = 0; i < darray_length(mtab->entries); ++i) {
- struct bfs_mtab_entry *entry = mtab->entries + i;
-
- struct bfs_stat sb;
- if (bfs_stat(AT_FDCWD, entry->path, BFS_STAT_NOFOLLOW | BFS_STAT_NOSYNC, &sb) != 0) {
- continue;
- }
-
- struct trie_leaf *leaf = trie_insert_mem(&mtab->types, &sb.dev, sizeof(sb.dev));
- if (leaf) {
- leaf->value = entry->type;
- }
- }
-
- mtab->types_filled = true;
-}
-
-const char *bfs_fstype(const struct bfs_mtab *mtab, const struct bfs_stat *statbuf) {
- if (!mtab->types_filled) {
- bfs_mtab_fill_types((struct bfs_mtab *)mtab);
- }
-
- const struct trie_leaf *leaf = trie_find_mem(&mtab->types, &statbuf->dev, sizeof(statbuf->dev));
- if (leaf) {
- return leaf->value;
- } else {
- return "unknown";
- }
-}
-
-bool bfs_might_be_mount(const struct bfs_mtab *mtab, const char *path) {
- const char *name = xbasename(path);
- return trie_find_str(&mtab->names, name);
-}
-
-void bfs_mtab_free(struct bfs_mtab *mtab) {
- if (mtab) {
- trie_destroy(&mtab->types);
- trie_destroy(&mtab->names);
-
- for (size_t i = 0; i < darray_length(mtab->entries); ++i) {
- free(mtab->entries[i].type);
- free(mtab->entries[i].path);
- }
- darray_free(mtab->entries);
-
- free(mtab);
- }
-}