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