diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2019-06-28 20:34:33 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2019-06-28 20:34:49 -0400 |
commit | e8b42e513fa97af5c9978eb95ea97712f0ea5bbb (patch) | |
tree | de9d429c0ca37e1cbff85f57a324564e1bfda76e /mtab.c | |
parent | 0473beaa2e3a46dd782af1182413fcdd4d33e275 (diff) | |
download | bfs-e8b42e513fa97af5c9978eb95ea97712f0ea5bbb.tar.xz |
Merge everything into one filesingle-file
Diffstat (limited to 'mtab.c')
-rw-r--r-- | mtab.c | 229 |
1 files changed, 0 insertions, 229 deletions
@@ -1,229 +0,0 @@ -/**************************************************************************** - * bfs * - * Copyright (C) 2017-2019 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 "trie.h" -#include "util.h" -#include <errno.h> -#include <fcntl.h> -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.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 - -struct bfs_mtab { - /** A map from device ID to file system type. */ - struct trie types; - /** The names of all the mount points. */ - struct trie names; -}; - -/** - * Add an entry to the mount table. - */ -static int bfs_mtab_add(struct bfs_mtab *mtab, const char *path, dev_t dev, const char *type) { - if (!trie_insert_str(&mtab->names, xbasename(path))) { - return -1; - } - - struct trie_leaf *leaf = trie_insert_mem(&mtab->types, &dev, sizeof(dev)); - if (!leaf) { - return -1; - } - - if (leaf->value) { - return 0; - } - - leaf->value = strdup(type); - if (leaf->value) { - return 0; - } else { - trie_remove(&mtab->types, leaf); - return -1; - } -} - -struct bfs_mtab *parse_bfs_mtab() { -#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 - file = setmntent("/proc/mounts", "r"); - } - if (!file) { - goto fail; - } - - struct bfs_mtab *mtab = malloc(sizeof(*mtab)); - if (!mtab) { - goto fail_file; - } - trie_init(&mtab->types); - trie_init(&mtab->names); - - struct mntent *mnt; - while ((mnt = getmntent(file))) { - struct bfs_stat sb; - if (bfs_stat(AT_FDCWD, mnt->mnt_dir, BFS_STAT_NOFOLLOW, &sb) != 0) { - continue; - } - - if (bfs_mtab_add(mtab, mnt->mnt_dir, sb.dev, mnt->mnt_type) != 0) { - goto fail_mtab; - } - } - - endmntent(file); - return mtab; - -fail_mtab: - free_bfs_mtab(mtab); -fail_file: - endmntent(file); -fail: - return NULL; - -#elif BFS_MNTINFO - - struct statfs *mntbuf; - int size = getmntinfo(&mntbuf, MNT_WAIT); - if (size < 0) { - return NULL; - } - - struct bfs_mtab *mtab = malloc(sizeof(*mtab)); - if (!mtab) { - goto fail; - } - trie_init(&mtab->types); - trie_init(&mtab->names); - - for (struct statfs *mnt = mntbuf; mnt < mntbuf + size; ++mnt) { - struct bfs_stat sb; - if (bfs_stat(AT_FDCWD, mnt->f_mntonname, BFS_STAT_NOFOLLOW, &sb) != 0) { - continue; - } - - if (bfs_mtab_add(mtab, mnt->f_mntonname, sb.dev, mnt->f_fstypename) != 0) { - goto fail_mtab; - } - } - - return mtab; - -fail_mtab: - free_bfs_mtab(mtab); -fail: - return NULL; - -#elif BFS_MNTTAB - - FILE *file = fopen(MNTTAB, "r"); - if (!file) { - goto fail; - } - - struct bfs_mtab *mtab = malloc(sizeof(*mtab)); - if (!mtab) { - goto fail_file; - } - trie_init(&mtab->types); - trie_init(&mtab->names); - - struct mnttab mnt; - while (getmntent(file, &mnt) == 0) { - struct bfs_stat sb; - if (bfs_stat(AT_FDCWD, mnt.mnt_mountp, BFS_STAT_NOFOLLOW, &sb) != 0) { - continue; - } - - if (bfs_mtab_add(mtab, mnt.mnt_mountp, sb.dev, mnt.mnt_fstype) != 0) { - goto fail_mtab; - } - } - - fclose(file); - return mtab; - -fail_mtab: - free_bfs_mtab(mtab); -fail_file: - fclose(file); -fail: - return NULL; - -#else - - errno = ENOTSUP; - return NULL; -#endif -} - -const char *bfs_fstype(const struct bfs_mtab *mtab, const struct bfs_stat *statbuf) { - 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_maybe_mount(const struct bfs_mtab *mtab, const char *path) { - const char *name = xbasename(path); - return trie_find_str(&mtab->names, name); -} - -void free_bfs_mtab(struct bfs_mtab *mtab) { - if (mtab) { - trie_destroy(&mtab->names); - - struct trie_leaf *leaf; - while ((leaf = trie_first_leaf(&mtab->types))) { - free(leaf->value); - trie_remove(&mtab->types, leaf); - } - trie_destroy(&mtab->types); - - free(mtab); - } -} |