Merge from vendor branch BSDTAR:
[dragonfly.git] / lib / libc / gen / getvfsent.c
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 $
7  * $DragonFly: src/lib/libc/gen/getvfsent.c,v 1.3 2005/04/26 06:16:29 joerg Exp $
8  */
9
10 #include <sys/param.h>
11 #include <sys/linker.h>
12 #include <sys/mount.h>
13 #include <sys/sysctl.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17
18 /* XXX hide some compatibility problems. */
19 #undef getvfsbyname
20 #define vfsconf         ovfsconf
21
22 static struct vfsconf *_vfslist = 0;
23 static struct vfsconf _vfsconf;
24 static size_t _vfslistlen = 0;
25 static int _vfs_keeplist = 0;
26 static size_t _vfs_index = 0;
27
28 static int
29 initvfs(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
56 struct vfsconf *
57 getvfsent(void)
58 {
59         if(!_vfslist && !initvfs())
60                 return 0;
61
62         do {
63                 if(_vfs_index >= _vfslistlen)
64                         return 0;
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
76 struct vfsconf *
77 getvfsbyname(const char *name)
78 {
79         size_t i;
80
81         if(!_vfslist && !initvfs())
82                 return 0;
83
84         for(i = 0; i < _vfslistlen; i++) {
85                 if( ! strcmp(_vfslist[i].vfc_name, name) )
86                         break;
87         }
88
89         if(i < _vfslistlen)
90                 _vfsconf = _vfslist[i];
91
92         if(!_vfs_keeplist) {
93                 free(_vfslist);
94                 _vfslist = 0;
95         }
96
97         if(i < _vfslistlen)
98                 return &_vfsconf;
99         else
100                 return 0;
101 }
102
103 struct vfsconf *
104 getvfsbytype(int type)
105 {
106         size_t i;
107
108         if(!_vfslist && !initvfs())
109                 return 0;
110
111         for(i = 0; i < _vfslistlen; i++) {
112                 if(_vfslist[i].vfc_index == type)
113                         break;
114         }
115
116         if(i < _vfslistlen)
117                 _vfsconf = _vfslist[i];
118
119         if(!_vfs_keeplist) {
120                 free(_vfslist);
121                 _vfslist = 0;
122         }
123
124         if(i < _vfslistlen)
125                 return &_vfsconf;
126         else
127                 return 0;
128 }
129
130 void
131 setvfsent(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
142 void
143 endvfsent(void)
144 {
145         if(_vfslist) {
146                 free(_vfslist);
147                 _vfslist = 0;
148         }
149
150         _vfs_index = 0;
151 }
152
153 int
154 vfsisloadable(const char *name __unused)
155 {
156         return 1;
157 }
158
159 int
160 vfsload(const char *name)
161 {
162         int status;
163
164         status = kldload(name);
165         return status == -1 ? status : 0;
166 }