1 /*
2 ** 1999-01-27 - Slim wrapper for the mntent-family of API calls. Required because it
3 ** seems to be a very unstandardized standard (different between Linux and
4 ** Solaris, for example). This has been modeled after the way it works on
5 ** Linux, so systems doing it in some other way will have to have emulation
6 ** code in here... Yuck. Since we're not into writing to these databases,
7 ** that part of the API is not supported. For details about which operations
8 ** need to be implemented for a platform, see "mntent_wrap.h".
9 */
10
11 #include "gentoo.h"
12
13 #include <stdio.h>
14 #include <stdlib.h>
15
16 #include "mntent_wrap.h"
17
18 /* ----------------------------------------------------------------------------------------- */
19
20 struct MntEnt {
21 gchar *fsname;
22 gchar *dir;
23 };
24
25 /* ----------------------------------------------------------------------------------------- */
26
27 #if defined __CYGWIN__ || defined __linux__ || defined __sgi /* Linux and IRIX implementation. */
28
29 #include <mntent.h>
30
mne_setmntent(const gchar * filename)31 FILE * mne_setmntent(const gchar *filename)
32 {
33 return setmntent(filename, "r");
34 }
35
mne_getmntent(FILE * filep)36 const MntEnt * mne_getmntent(FILE *filep)
37 {
38 static MntEnt me;
39 struct mntent *ment;
40
41 if((ment = getmntent(filep)) != NULL)
42 {
43 me.fsname = ment->mnt_fsname;
44 me.dir = ment->mnt_dir;
45 return &me;
46 }
47 return NULL;
48 }
49
mne_endmntent(FILE * filep)50 gint mne_endmntent(FILE *filep)
51 {
52 return endmntent(filep);
53 }
54
55 /* ----------------------------------------------------------------------------------------- */
56
57 #elif defined __svr4__ /* Very weak Solaris detection, I'm sure. */
58
59 #include <sys/mnttab.h>
60
61 /* 1999-01-27 - Since Solaris doesn't include the setmntent() function as a part of their
62 ** mount database access API, but rather just use a plain fopen(), I guess
63 ** the following is a pretty natural way to wrap it.
64 */
mne_setmntent(const gchar * filename)65 FILE * mne_setmntent(const gchar *filename)
66 {
67 return fopen(filename, "rt");
68 }
69
70 /* 1999-01-27 - Grab a new entry from <filep>, and package it up in our platform neutral
71 ** format. If all wrappers were this simple, I would write more of them. :)
72 */
mne_getmntent(FILE * filep)73 const MntEnt * mne_getmntent(FILE *filep)
74 {
75 static MntEnt me;
76 struct mnttab mtab;
77
78 if((getmntent(filep, &mtab)) == 0)
79 {
80 me.fsname = mtab.mnt_special;
81 me.dir = mtab.mnt_mountp;
82 return &me;
83 }
84 return NULL;
85 }
86
87 /* 1999-01-27 - Close down a mount database. The natural complement to mne_setmntent(). */
mne_endmntent(FILE * filep)88 gint mne_endmntent(FILE *filep)
89 {
90 if(filep != NULL)
91 return fclose(filep);
92 return -1;
93 }
94
95 #elif defined __OpenBSD__ || defined __FreeBSD__ || defined __NetBSD__ || defined __DragonFly__ || (defined __osf__ && defined __alpha__)
96
97 /* Here is the implementation for BSD and Alpha Tru64 systems. */
98
99 #include <fstab.h>
100 #include <sys/mount.h>
101 #include <sys/param.h>
102 #include <sys/ucred.h>
103
104 /* A pointer to one of these is returned by mne_setmntent(), depending on which file
105 ** name is given as an input. Note that on BSD systems, the system calls themselves
106 ** deal with the reading of files, so gentoo will never in fact open any files. But
107 ** since the calls used to access currently mounted file systems is very dissimilar
108 ** to the one used to check _available_ file systems, we need a way of keeping track
109 ** of what kind of mount entries we're supposed to deal with. Since gentoo will
110 ** pass a FILE pointer to mne_getmntent() anyway, it seems natural to use it.
111 */
112 #ifdef __DragonFly__
113 static FILE *p_fstab, *p_mtab;
114 #else
115 static FILE f_fstab, f_mtab;
116 #endif
117
118 /* These are used when we're accessing the currently mounted filesystems, using
119 ** a call to getmntinfo(). The mtab_pos and mtab_num integers are then used to
120 ** keep track of where in the returned array of statfs structs we are.
121 */
122 static struct statfs *mtab = NULL;
123 static guint mtab_pos = 0, mtab_num = 0;
124
125 /* 1999-05-09 - An attempt at a BSD implementation, after having received input from
126 ** Alexander M. Tahk <tahk@MIT.EDU>, who went ahead and ported gentoo over.
127 ** Seems the BSD interface is even less flexible than the ones on Linux and
128 ** Solaris. Big deal.
129 */
mne_setmntent(const gchar * filename)130 FILE * mne_setmntent(const gchar *filename)
131 {
132 /* This is possibly incredibly annoying and useless, but I feel serious today. :) */
133 if((strcmp(filename, "/etc/fstab") != 0) || (strcmp(filename, "/etc/mtab") != 0))
134 g_warning("mntent_wrap.c: Ignoring filename '%s'", filename);
135
136 if(strcmp(filename, "/etc/fstab") == 0) /* Looking for available filesystems? */
137 {
138 if(setfsent() == 1)
139 #ifdef __DragonFly__
140 return p_fstab;
141 #else
142 return &f_fstab;
143 #endif
144 }
145 else if(strcmp(filename, "/proc/mtab") == 0) /* Looking for mounted filesystems? */
146 {
147 if((mtab_num = getmntinfo(&mtab, 0)) > 0)
148 {
149 mtab_pos = 0;
150 #ifdef __DragonFly__
151 return p_mtab;
152 #else
153 return &f_mtab;
154 #endif
155 }
156 }
157 return NULL;
158 }
159
160 /* 1999-05-09 - Get another entry of data, either about mounted (filep == &f_mtab) or available
161 ** (filep == &f_fstab) filesystems. Returns NULL when the respective data source
162 ** is exhausted.
163 */
mne_getmntent(FILE * filep)164 const MntEnt * mne_getmntent(FILE *filep)
165 {
166 static MntEnt me;
167
168 #ifdef __DragonFly__
169 if(filep == p_fstab)
170 #else
171 if(filep == &f_fstab)
172 #endif
173 {
174 struct fstab *ment;
175
176 if((ment = getfsent()) != NULL)
177 {
178 me.fsname = ment->fs_spec;
179 me.dir = ment->fs_file;
180 return &me;
181 }
182 }
183 #ifdef __DragonFly__
184 else if(filep == p_mtab)
185 #else
186 else if(filep == &f_mtab)
187 #endif
188 {
189 if(mtab_pos == mtab_num) /* Array exhausted? */
190 return NULL;
191 me.fsname = mtab[mtab_pos].f_mntfromname;
192 me.dir = mtab[mtab_pos].f_mntonname;
193 mtab_pos++;
194 return &me;
195 }
196 else
197 g_warning("MNTENT: Bad pointer to mnt_getmntent() (%p)", filep);
198
199 return NULL;
200 }
201
202 /* 1999-05-09 - Stop traversing mount/fs data. */
mne_endmntent(FILE * filep)203 gint mne_endmntent(FILE *filep)
204 {
205 #ifdef __DragonFly__
206 if(filep == p_fstab)
207 #else
208 if(filep == &f_fstab)
209 #endif
210 endfsent();
211
212 return 0;
213 }
214
215 #endif
216
217 /* ----------------------------------------------------------------------------------------- */
218
219 /* Functions below are platform independant. Nice. */
220
221 /* 1999-01-27 - Create a copy of <src>, using dynamically allocated memory. The
222 ** copy is done so that a) it shares no memory with <src>, and b)
223 ** it is contigous, because that is nice. :)
224 */
mne_copy(const MntEnt * src)225 MntEnt * mne_copy(const MntEnt *src)
226 {
227 MntEnt *ne = NULL;
228 gsize s_fs, s_dir;
229
230 if(src != NULL)
231 {
232 s_fs = strlen(src->fsname) + 1;
233 s_dir = strlen(src->dir) + 1;
234 ne = g_malloc(sizeof *ne + s_fs + s_dir);
235 ne->fsname = (gchar *) (ne + 1);
236 ne->dir = (gchar *) (ne + 1) + s_fs;
237 strcpy(ne->fsname, src->fsname);
238 strcpy(ne->dir, src->dir);
239 }
240 return ne;
241 }
242
243 /* 1999-01-27 - Destroy (free) a previously created mount entry descriptor. You can
244 ** only call this with entries created by mne_copy() above.
245 */
mne_destroy(MntEnt * me)246 void mne_destroy(MntEnt *me)
247 {
248 if(me != NULL)
249 g_free(me); /* Thanks to funky g_malloc()ing, I can do this. */
250 }
251
252 /* 1999-01-27 - Return a pointer to a string giving the full path of the entry's mount
253 ** point.
254 */
mne_get_mountpoint(const MntEnt * me)255 const gchar * mne_get_mountpoint(const MntEnt *me)
256 {
257 return me ? me->dir : NULL;
258 }
259
260 /* 1999-01-27 - Return pointer to string giving the device the entry describes. */
mne_get_device(const MntEnt * me)261 const gchar * mne_get_device(const MntEnt *me)
262 {
263 return me ? me->fsname : NULL;
264 }
265