12965Swollman/*
227624Scharnier * lsvfs - list loaded VFSes
32965Swollman * Garrett A. Wollman, September 1994
42965Swollman * This file is in the public domain.
57094Swollman *
62965Swollman */
72965Swollman
899112Sobrien#include <sys/cdefs.h>
999112Sobrien__FBSDID("$FreeBSD$");
1099112Sobrien
112965Swollman#include <sys/param.h>
122965Swollman#include <sys/mount.h>
13101661Smux#include <sys/sysctl.h>
1423350Sbde
1523350Sbde#include <err.h>
162965Swollman#include <stdio.h>
17101651Smux#include <stdlib.h>
1823350Sbde#include <string.h>
192965Swollman
20251802Shrs#define FMT	"%-32.32s 0x%08x %5d  %s\n"
21251802Shrs#define HDRFMT	"%-32.32s %10s %5.5s  %s\n"
22251802Shrs#define DASHES	"-------------------------------- "	\
23251802Shrs		"---------- -----  ---------------\n"
242965Swollman
25251802Shrsstatic struct flaglist {
26251802Shrs	int		flag;
27251802Shrs	const char	str[32]; /* must be longer than the longest one. */
28251802Shrs} fl[] = {
29251802Shrs	{ .flag = VFCF_STATIC, .str = "static", },
30251802Shrs	{ .flag = VFCF_NETWORK, .str = "network", },
31251802Shrs	{ .flag = VFCF_READONLY, .str = "read-only", },
32251802Shrs	{ .flag = VFCF_SYNTHETIC, .str = "synthetic", },
33251802Shrs	{ .flag = VFCF_LOOPBACK, .str = "loopback", },
34251802Shrs	{ .flag = VFCF_UNICODE, .str = "unicode", },
35251802Shrs	{ .flag = VFCF_JAIL, .str = "jail", },
36251802Shrs	{ .flag = VFCF_DELEGADMIN, .str = "delegated-administration", },
37251802Shrs};
38251802Shrs
397094Swollmanstatic const char *fmt_flags(int);
407094Swollman
412965Swollmanint
422965Swollmanmain(int argc, char **argv)
432965Swollman{
44101651Smux  int cnt, rv = 0, i;
45101651Smux  struct xvfsconf vfc, *xvfsp;
46101651Smux  size_t buflen;
472965Swollman  argc--, argv++;
482965Swollman
49251802Shrs  printf(HDRFMT, "Filesystem", "Num", "Refs", "Flags");
502965Swollman  fputs(DASHES, stdout);
512965Swollman
522965Swollman  if(argc) {
532965Swollman    for(; argc; argc--, argv++) {
5447701Sru      if (getvfsbyname(*argv, &vfc) == 0) {
55251802Shrs        printf(FMT, vfc.vfc_name, vfc.vfc_typenum, vfc.vfc_refcount,
56251802Shrs	    fmt_flags(vfc.vfc_flags));
572965Swollman      } else {
582984Swollman	warnx("VFS %s unknown or not loaded", *argv);
592965Swollman        rv++;
602965Swollman      }
612965Swollman    }
622965Swollman  } else {
63101651Smux    if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0)
64101651Smux      err(1, "sysctl(vfs.conflist)");
65101651Smux    xvfsp = malloc(buflen);
66101651Smux    if (xvfsp == NULL)
67101651Smux      errx(1, "malloc failed");
68101651Smux    if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0)
69101651Smux      err(1, "sysctl(vfs.conflist)");
70101651Smux    cnt = buflen / sizeof(struct xvfsconf);
71101651Smux
72101651Smux    for (i = 0; i < cnt; i++) {
73251802Shrs      printf(FMT, xvfsp[i].vfc_name, xvfsp[i].vfc_typenum,
74251802Shrs	    xvfsp[i].vfc_refcount, fmt_flags(xvfsp[i].vfc_flags));
752965Swollman    }
76101651Smux    free(xvfsp);
772965Swollman  }
782965Swollman
792965Swollman  return rv;
802965Swollman}
812965Swollman
827094Swollmanstatic const char *
837094Swollmanfmt_flags(int flags)
847094Swollman{
85251802Shrs	static char buf[sizeof(struct flaglist) * sizeof(fl)];
86251802Shrs	int i;
877096Swollman
88251802Shrs	buf[0] = '\0';
89251802Shrs	for (i = 0; i < (int)nitems(fl); i++)
90251802Shrs		if (flags & fl[i].flag) {
91251802Shrs			strlcat(buf, fl[i].str, sizeof(buf));
92251802Shrs			strlcat(buf, ", ", sizeof(buf));
93251802Shrs		}
94251802Shrs	if (buf[0] != '\0')
95251802Shrs		buf[strlen(buf) - 2] = '\0';
96251802Shrs	return (buf);
977094Swollman}
98