Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / support / fstab.c
1 /*
2  * <fstab.h> wrapper functions.
3  *
4  * Authors:
5  *   Jonathan Pryor (jonpryor@vt.edu)
6  *
7  * Copyright (C) 2004-2005 Jonathan Pryor
8  */
9
10 #include <errno.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <stddef.h>
15
16 #include "map.h"
17 #include "mph.h"
18
19 #if defined (HAVE_CHECKLIST_H)
20 #include <checklist.h>
21 #elif defined (HAVE_FSTAB_H)
22 #include <fstab.h>
23 #endif /* def HAVE_FSTAB_H */
24
25 #ifdef HAVE_SYS_VFSTAB_H
26 #include <sys/vfstab.h>
27 #endif /* def HAVE_SYS_VFSTAB_H */
28
29 G_BEGIN_DECLS
30
31 #ifdef HAVE_CHECKLIST_H
32
33 typedef struct checklist mph_fstab;
34
35 static const mph_string_offset_t
36 fstab_offsets[] = {
37         MPH_STRING_OFFSET (struct checklist, fs_spec, MPH_STRING_OFFSET_PTR),
38         MPH_STRING_OFFSET (struct checklist, fs_dir,  MPH_STRING_OFFSET_PTR),
39         MPH_STRING_OFFSET (struct checklist, fs_type, MPH_STRING_OFFSET_PTR)
40 };
41
42 static const mph_string_offset_t
43 mph_fstab_offsets[] = {
44         MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Fstab, fs_spec, MPH_STRING_OFFSET_PTR),
45         MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Fstab, fs_file, MPH_STRING_OFFSET_PTR),
46         MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Fstab, fs_type, MPH_STRING_OFFSET_PTR)
47 };
48
49 #elif defined (HAVE_FSTAB_H)
50
51 typedef struct fstab mph_fstab;
52
53 static const mph_string_offset_t
54 fstab_offsets[] = {
55         MPH_STRING_OFFSET (struct fstab, fs_spec,     MPH_STRING_OFFSET_PTR),
56         MPH_STRING_OFFSET (struct fstab, fs_file,     MPH_STRING_OFFSET_PTR),
57         MPH_STRING_OFFSET (struct fstab, fs_vfstype,  MPH_STRING_OFFSET_PTR),
58         MPH_STRING_OFFSET (struct fstab, fs_mntops,   MPH_STRING_OFFSET_PTR),
59         MPH_STRING_OFFSET (struct fstab, fs_type,     MPH_STRING_OFFSET_PTR)
60 };
61
62 static const mph_string_offset_t
63 mph_fstab_offsets[] = {
64         MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Fstab, fs_spec,     MPH_STRING_OFFSET_PTR),
65         MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Fstab, fs_file,     MPH_STRING_OFFSET_PTR),
66         MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Fstab, fs_vfstype,  MPH_STRING_OFFSET_PTR),
67         MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Fstab, fs_mntops,   MPH_STRING_OFFSET_PTR),
68         MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Fstab, fs_type,     MPH_STRING_OFFSET_PTR)
69 };
70
71 #endif /* def HAVE_FSTAB_H */
72
73 #if defined (HAVE_CHECKLIST_H) || defined (HAVE_FSTAB_H)
74
75 /*
76  * Copy the native `fstab' structure to it's managed representation.
77  *
78  * To minimize separate mallocs, all the strings are allocated within the same
79  * memory block (stored in _fs_buf_).
80  */
81 static int
82 copy_fstab (struct Mono_Posix_Syscall__Fstab *to, mph_fstab *from)
83 {
84         char *buf;
85
86         memset (to, 0, sizeof(*to));
87
88         buf = _mph_copy_structure_strings (to, mph_fstab_offsets,
89                         from, fstab_offsets, sizeof(fstab_offsets)/sizeof(fstab_offsets[0]));
90
91         to->fs_freq   = from->fs_freq;
92         to->fs_passno = from->fs_passno;
93
94         to->_fs_buf_ = buf;
95         if (buf == NULL) {
96                 return -1;
97         }
98
99         return 0;
100 }
101
102 #endif /* def HAVE_CHECKLIST_H || def HAVE_FSTAB_H */
103
104 #ifdef HAVE_SYS_VFSTAB_H
105
106 /* 
107  * Solaris doesn't provide <fstab.h> but has equivalent functionality in
108  * <sys/fstab.h> via getvfsent(3C) and company.
109  */
110
111 typedef struct vfstab mph_fstab;
112
113 static const mph_string_offset_t
114 vfstab_offsets[] = {
115         MPH_STRING_OFFSET (struct vfstab, vfs_special,  MPH_STRING_OFFSET_PTR),
116         MPH_STRING_OFFSET (struct vfstab, vfs_mountp,   MPH_STRING_OFFSET_PTR),
117         MPH_STRING_OFFSET (struct vfstab, vfs_fstype,   MPH_STRING_OFFSET_PTR),
118         MPH_STRING_OFFSET (struct vfstab, vfs_mntopts,  MPH_STRING_OFFSET_PTR)
119 };
120
121 static const mph_string_offset_t
122 mph_fstab_offsets[] = {
123         MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Fstab, fs_spec,     MPH_STRING_OFFSET_PTR),
124         MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Fstab, fs_file,     MPH_STRING_OFFSET_PTR),
125         MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Fstab, fs_vfstype,  MPH_STRING_OFFSET_PTR),
126         MPH_STRING_OFFSET (struct Mono_Posix_Syscall__Fstab, fs_mntops,   MPH_STRING_OFFSET_PTR)
127 };
128
129 /*
130  * Copy the native `vfstab' structure to it's managed representation.
131  *
132  * To minimize separate mallocs, all the strings are allocated within the same
133  * memory block (stored in _fs_buf_).
134  */
135 static int
136 copy_fstab (struct Mono_Posix_Syscall__Fstab *to, struct vfstab *from)
137 {
138         char *buf;
139
140         memset (to, 0, sizeof(*to));
141
142         buf = _mph_copy_structure_strings (to, mph_fstab_offsets,
143                         from, vfstab_offsets, sizeof(vfstab_offsets)/sizeof(vfstab_offsets[0]));
144
145         to->fs_type   = NULL;
146         to->fs_freq   = -1;
147         to->fs_passno = -1;
148
149         to->_fs_buf_ = buf;
150         if (buf == NULL) {
151                 return -1;
152         }
153
154         return 0;
155 }
156
157 /*
158  * Implement Linux/BSD getfsent(3) in terms of Solaris getvfsent(3C)...
159  */
160 static FILE*
161 etc_fstab;
162
163 static int
164 setfsent (void)
165 {
166         /* protect from bad users calling setfsent(), setfsent(), ... endfsent() */
167         if (etc_fstab != NULL)
168                 fclose (etc_fstab);
169         etc_fstab = fopen ("/etc/vfstab", "r");
170         if (etc_fstab != NULL)
171                 return 1;
172         return 0;
173 }
174
175 static void
176 endfsent (void)
177 {
178         fclose (etc_fstab);
179         etc_fstab = NULL;
180 }
181
182 static struct vfstab
183 cur_vfstab_entry;
184
185 static struct vfstab*
186 getfsent (void)
187 {
188         int r;
189         r = getvfsent (etc_fstab, &cur_vfstab_entry);
190         if (r == 0)
191                 return &cur_vfstab_entry;
192         return NULL;
193 }
194
195 static struct vfstab*
196 getfsfile (const char *mount_point)
197 {
198         int r;
199         int close = 0;
200         if (etc_fstab == 0) {
201                 close = 1;
202                 if (setfsent () != 1)
203                         return NULL;
204         }
205         rewind (etc_fstab);
206         r = getvfsfile (etc_fstab, &cur_vfstab_entry, (char*) mount_point);
207         if (close)
208                 endfsent ();
209         if (r == 0)
210                 return &cur_vfstab_entry;
211         return NULL;
212 }
213
214 static struct vfstab*
215 getfsspec (const char *special_file)
216 {
217         int r;
218         int close = 0;
219         if (etc_fstab == 0) {
220                 close = 1;
221                 if (setfsent () != 1)
222                         return NULL;
223         }
224         rewind (etc_fstab);
225         r = getvfsspec (etc_fstab, &cur_vfstab_entry, (char*) special_file);
226         if (close)
227                 endfsent ();
228         if (r == 0)
229                 return &cur_vfstab_entry;
230         return NULL;
231 }
232
233 #endif /* def HAVE_SYS_VFSTAB_H */
234
235 #if defined (HAVE_FSTAB_H) || defined (HAVE_CHECKPOINT_H) || defined (HAVE_SYS_VFSTAB_H)
236
237 int
238 Mono_Posix_Syscall_endfsent (void)
239 {
240         endfsent ();
241         return 0;
242 }
243
244 gint32
245 Mono_Posix_Syscall_getfsent (struct Mono_Posix_Syscall__Fstab *fsbuf)
246 {
247         mph_fstab *fs;
248
249         if (fsbuf == NULL) {
250                 errno = EFAULT;
251                 return -1;
252         }
253
254         fs = getfsent ();
255         if (fs == NULL)
256                 return -1;
257
258         if (copy_fstab (fsbuf, fs) == -1) {
259                 errno = ENOMEM;
260                 return -1;
261         }
262         return 0;
263 }
264
265 gint32
266 Mono_Posix_Syscall_getfsfile (const char *mount_point, 
267                 struct Mono_Posix_Syscall__Fstab *fsbuf)
268 {
269         mph_fstab *fs;
270
271         if (fsbuf == NULL) {
272                 errno = EFAULT;
273                 return -1;
274         }
275
276         fs = getfsfile (mount_point);
277         if (fs == NULL)
278                 return -1;
279
280         if (copy_fstab (fsbuf, fs) == -1) {
281                 errno = ENOMEM;
282                 return -1;
283         }
284         return 0;
285 }
286
287 gint32
288 Mono_Posix_Syscall_getfsspec (const char *special_file, 
289                 struct Mono_Posix_Syscall__Fstab *fsbuf)
290 {
291         mph_fstab *fs;
292
293         if (fsbuf == NULL) {
294                 errno = EFAULT;
295                 return -1;
296         }
297
298         fs = getfsspec (special_file);
299         if (fs == NULL)
300                 return -1;
301
302         if (copy_fstab (fsbuf, fs) == -1) {
303                 errno = ENOMEM;
304                 return -1;
305         }
306         return 0;
307 }
308
309 gint32
310 Mono_Posix_Syscall_setfsent (void)
311 {
312         return setfsent ();
313 }
314
315 #endif /* def HAVE_FSTAB_H || def HAVE_CHECKPOINT_H || def HAVE_SYS_VFSTAB_H */
316
317 G_END_DECLS
318
319 /*
320  * vim: noexpandtab
321  */