96d589d05d89ae40d81187fdc6ed01936c1171d1
[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
21 static struct ovfsconf *_vfslist = 0;
22 static struct ovfsconf _vfsconf;
23 static size_t _vfslistlen = 0;
24 static int _vfs_keeplist = 0;
25 static size_t _vfs_index = 0;
26
27 static int
28 initvfs(void)
29 {
30         int mib[2] = { CTL_VFS, VFS_VFSCONF };
31         size_t size = 0;
32         int rv;
33
34         rv = sysctl(mib, 2, (void *)0, &size, (void *)0, (size_t)0);
35         if(rv < 0)
36                 return 0;
37
38         if(_vfslist)
39                 free(_vfslist);
40         _vfslist = malloc(size);
41         if(!_vfslist)
42                 return 0;
43
44         rv = sysctl(mib, 2, _vfslist, &size, (void *)0, (size_t)0);
45         if(rv < 0) {
46                 free(_vfslist);
47                 _vfslist = 0;
48                 return 0;
49         }
50
51         _vfslistlen = size / sizeof(_vfslist[0]);
52         return 1;
53 }
54
55 struct ovfsconf *
56 getvfsent(void)
57 {
58         if(!_vfslist && !initvfs())
59                 return 0;
60
61         do {
62                 if(_vfs_index >= _vfslistlen)
63                         return 0;
64
65                 _vfsconf = _vfslist[_vfs_index++];
66         } while(!_vfsconf.vfc_vfsops);
67
68         if(!_vfs_keeplist) {
69                 free(_vfslist);
70                 _vfslist = 0;
71         }
72         return &_vfsconf;
73 }
74
75 struct ovfsconf *
76 getvfsbyname(const char *name)
77 {
78         size_t i;
79
80         if(!_vfslist && !initvfs())
81                 return 0;
82
83         for(i = 0; i < _vfslistlen; i++) {
84                 if( ! strcmp(_vfslist[i].vfc_name, name) )
85                         break;
86         }
87
88         if(i < _vfslistlen)
89                 _vfsconf = _vfslist[i];
90
91         if(!_vfs_keeplist) {
92                 free(_vfslist);
93                 _vfslist = 0;
94         }
95
96         if(i < _vfslistlen)
97                 return &_vfsconf;
98         else
99                 return 0;
100 }
101
102 struct ovfsconf *
103 getvfsbytype(int type)
104 {
105         size_t i;
106
107         if(!_vfslist && !initvfs())
108                 return 0;
109
110         for(i = 0; i < _vfslistlen; i++) {
111                 if(_vfslist[i].vfc_index == type)
112                         break;
113         }
114
115         if(i < _vfslistlen)
116                 _vfsconf = _vfslist[i];
117
118         if(!_vfs_keeplist) {
119                 free(_vfslist);
120                 _vfslist = 0;
121         }
122
123         if(i < _vfslistlen)
124                 return &_vfsconf;
125         else
126                 return 0;
127 }
128
129 void
130 setvfsent(int keep)
131 {
132         if(_vfslist && !keep) {
133                 free(_vfslist);
134                 _vfslist = 0;
135         }
136
137         _vfs_keeplist = keep;
138         _vfs_index = 0;
139 }
140
141 void
142 endvfsent(void)
143 {
144         if(_vfslist) {
145                 free(_vfslist);
146                 _vfslist = 0;
147         }
148
149         _vfs_index = 0;
150 }
151
152 int
153 vfsisloadable(const char *name __unused)
154 {
155         return 1;
156 }
157
158 int
159 vfsload(const char *name)
160 {
161         int status;
162
163         status = kldload(name);
164         return status == -1 ? status : 0;
165 }