Merge from vendor branch BZIP:
[dragonfly.git] / lib / libc / gen / getvfsent.c
CommitLineData
984263bc
MD
1/*
2 * getvfsent.c - get a listing of installed filesystems
3 * Written September 1994 by Garrett A. Wollman
4 * This file is in the public domain.
5 *
6 * $FreeBSD: src/lib/libc/gen/getvfsent.c,v 1.14.2.1 2001/03/05 09:19:38 obrien Exp $
c4875974 7 * $DragonFly: src/lib/libc/gen/getvfsent.c,v 1.3 2005/04/26 06:16:29 joerg Exp $
984263bc
MD
8 */
9
10#include <sys/param.h>
c4875974 11#include <sys/linker.h>
984263bc
MD
12#include <sys/mount.h>
13#include <sys/sysctl.h>
984263bc 14#include <stdlib.h>
c4875974
JS
15#include <string.h>
16#include <unistd.h>
984263bc
MD
17
18/* XXX hide some compatibility problems. */
19#undef getvfsbyname
20#define vfsconf ovfsconf
21
22static struct vfsconf *_vfslist = 0;
23static struct vfsconf _vfsconf;
24static size_t _vfslistlen = 0;
25static int _vfs_keeplist = 0;
c4875974 26static size_t _vfs_index = 0;
984263bc
MD
27
28static int
29initvfs(void)
30{
31 int mib[2] = { CTL_VFS, VFS_VFSCONF };
32 size_t size = 0;
33 int rv;
34
35 rv = sysctl(mib, 2, (void *)0, &size, (void *)0, (size_t)0);
36 if(rv < 0)
37 return 0;
38
39 if(_vfslist)
40 free(_vfslist);
41 _vfslist = malloc(size);
42 if(!_vfslist)
43 return 0;
44
45 rv = sysctl(mib, 2, _vfslist, &size, (void *)0, (size_t)0);
46 if(rv < 0) {
47 free(_vfslist);
48 _vfslist = 0;
49 return 0;
50 }
51
52 _vfslistlen = size / sizeof _vfslist[0];
53 return 1;
54}
55
56struct vfsconf *
57getvfsent(void)
58{
c4875974 59 if(!_vfslist && !initvfs())
984263bc 60 return 0;
984263bc
MD
61
62 do {
c4875974 63 if(_vfs_index >= _vfslistlen)
984263bc 64 return 0;
984263bc
MD
65
66 _vfsconf = _vfslist[_vfs_index++];
67 } while(!_vfsconf.vfc_vfsops);
68
69 if(!_vfs_keeplist) {
70 free(_vfslist);
71 _vfslist = 0;
72 }
73 return &_vfsconf;
74}
75
76struct vfsconf *
77getvfsbyname(const char *name)
78{
c4875974 79 size_t i;
984263bc 80
c4875974 81 if(!_vfslist && !initvfs())
984263bc 82 return 0;
984263bc
MD
83
84 for(i = 0; i < _vfslistlen; i++) {
85 if( ! strcmp(_vfslist[i].vfc_name, name) )
86 break;
87 }
88
c4875974 89 if(i < _vfslistlen)
984263bc 90 _vfsconf = _vfslist[i];
984263bc
MD
91
92 if(!_vfs_keeplist) {
93 free(_vfslist);
94 _vfslist = 0;
95 }
96
c4875974 97 if(i < _vfslistlen)
984263bc 98 return &_vfsconf;
c4875974 99 else
984263bc 100 return 0;
984263bc
MD
101}
102
103struct vfsconf *
104getvfsbytype(int type)
105{
c4875974 106 size_t i;
984263bc 107
c4875974 108 if(!_vfslist && !initvfs())
984263bc 109 return 0;
984263bc
MD
110
111 for(i = 0; i < _vfslistlen; i++) {
112 if(_vfslist[i].vfc_index == type)
113 break;
114 }
115
c4875974 116 if(i < _vfslistlen)
984263bc 117 _vfsconf = _vfslist[i];
984263bc
MD
118
119 if(!_vfs_keeplist) {
120 free(_vfslist);
121 _vfslist = 0;
122 }
123
c4875974 124 if(i < _vfslistlen)
984263bc 125 return &_vfsconf;
c4875974 126 else
984263bc 127 return 0;
984263bc
MD
128}
129
130void
131setvfsent(int keep)
132{
133 if(_vfslist && !keep) {
134 free(_vfslist);
135 _vfslist = 0;
136 }
137
138 _vfs_keeplist = keep;
139 _vfs_index = 0;
140}
141
142void
143endvfsent(void)
144{
145 if(_vfslist) {
146 free(_vfslist);
147 _vfslist = 0;
148 }
149
150 _vfs_index = 0;
151}
152
153int
c4875974 154vfsisloadable(const char *name __unused)
984263bc
MD
155{
156 return 1;
157}
158
159int
160vfsload(const char *name)
161{
162 int status;
163
164 status = kldload(name);
165 return status == -1 ? status : 0;
166}