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