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