aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/lsvfs/lsvfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/lsvfs/lsvfs.c')
-rw-r--r--usr.bin/lsvfs/lsvfs.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/usr.bin/lsvfs/lsvfs.c b/usr.bin/lsvfs/lsvfs.c
new file mode 100644
index 000000000000..8925b8988cd3
--- /dev/null
+++ b/usr.bin/lsvfs/lsvfs.c
@@ -0,0 +1,100 @@
+/*
+ * lsvfs - list loaded VFSes
+ * Garrett A. Wollman, September 1994
+ * This file is in the public domain.
+ *
+ */
+
+#include <sys/capsicum.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+
+#include <capsicum_helpers.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define FMT "%-32.32s 0x%08x %5d %s\n"
+#define HDRFMT "%-32.32s %10s %5.5s %s\n"
+#define DASHES "-------------------------------- " \
+ "---------- ----- ---------------\n"
+
+static struct flaglist {
+ int flag;
+ const char str[32]; /* must be longer than the longest one. */
+} fl[] = {
+ { .flag = VFCF_STATIC, .str = "static", },
+ { .flag = VFCF_NETWORK, .str = "network", },
+ { .flag = VFCF_READONLY, .str = "read-only", },
+ { .flag = VFCF_SYNTHETIC, .str = "synthetic", },
+ { .flag = VFCF_LOOPBACK, .str = "loopback", },
+ { .flag = VFCF_UNICODE, .str = "unicode", },
+ { .flag = VFCF_JAIL, .str = "jail", },
+ { .flag = VFCF_DELEGADMIN, .str = "delegated-administration", },
+};
+
+static const char *fmt_flags(int);
+
+int
+main(int argc, char **argv)
+{
+ struct xvfsconf *xvfsp;
+ size_t cnt, buflen;
+ int rv = 0;
+
+ argc--, argv++;
+
+ if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0)
+ err(EXIT_FAILURE, "sysctl(vfs.conflist)");
+ if ((xvfsp = malloc(buflen)) == NULL)
+ errx(EXIT_FAILURE, "malloc failed");
+ if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0)
+ err(EXIT_FAILURE, "sysctl(vfs.conflist)");
+ cnt = buflen / sizeof(struct xvfsconf);
+
+ caph_cache_catpages();
+ if (caph_enter() != 0)
+ err(EXIT_FAILURE, "failed to enter capability mode");
+
+ printf(HDRFMT, "Filesystem", "Num", "Refs", "Flags");
+ fputs(DASHES, stdout);
+
+ for (size_t i = 0; i < cnt; i++) {
+ if (argc > 0) {
+ int j;
+ for (j = 0; j < argc; j++) {
+ if (strcmp(argv[j], xvfsp[i].vfc_name) == 0)
+ break;
+ }
+ if (j == argc)
+ continue;
+ }
+
+ printf(FMT, xvfsp[i].vfc_name, xvfsp[i].vfc_typenum,
+ xvfsp[i].vfc_refcount, fmt_flags(xvfsp[i].vfc_flags));
+ }
+ free(xvfsp);
+
+ return (rv);
+}
+
+static const char *
+fmt_flags(int flags)
+{
+ static char buf[sizeof(struct flaglist) * sizeof(fl)];
+
+ buf[0] = '\0';
+ for (size_t i = 0; i < (int)nitems(fl); i++) {
+ if ((flags & fl[i].flag) != 0) {
+ strlcat(buf, fl[i].str, sizeof(buf));
+ strlcat(buf, ", ", sizeof(buf));
+ }
+ }
+
+ /* Zap the trailing comma + space. */
+ if (buf[0] != '\0')
+ buf[strlen(buf) - 2] = '\0';
+ return (buf);
+}