1 /*
2 * Copyright (c) 1992-1998 Michael A. Cooper.
3 * This software may be freely used and distributed provided it is not
4 * sold for profit or used in part or in whole for commercial gain
5 * without prior written agreement, and the author is credited
6 * appropriately.
7 */
8 /*
9 * Copyright (c) 1983 Regents of the University of California.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 */
40
41 #ifndef lint
42 static char RCSid[] =
43 "$Id: filesys-os.c,v 6.18 1998/11/10 04:09:58 mcooper Exp $";
44
45 static char sccsid[] = "@(#)filesys-os.c";
46
47 static char copyright[] =
48 "Copyright (c) 1992-1998 Michael A. Cooper.\n\
49 @(#) Copyright (c) 1983 Regents of the University of California.\n\
50 All rights reserved.\n";
51 #endif /* not lint */
52
53 /*
54 * OS specific file system routines
55 */
56
57 #include "defs.h"
58 #include "filesys.h"
59
60 #if FSI_TYPE == FSI_GETFSSTAT
61 static struct statfs *mnt = NULL;
62 typedef u_long ulong;
63 #endif /* FSI_GETFSSTAT */
64
65 #if FSI_TYPE == FSI_MNTCTL
66 static struct vmount *mnt = NULL;
67 #endif /* FSI_MNTCTL */
68
69 #if (FSI_TYPE == FSI_MNTCTL) || (FSI_TYPE == FSI_GETFSSTAT)
70 static char *mntbuf = NULL;
71 static int entries_left;
72 #endif /* FSI_MNTCTL || FSI_GETFSSTAT */
73
74 #if FSI_TYPE == FSI_MNTCTL
75 /*
76 * AIX version of setmountent()
77 */
setmountent(file,mode)78 FILE *setmountent(file, mode)
79 /*ARGSUSED*/
80 char *file;
81 char *mode;
82 {
83 ulong size;
84
85 if (mntbuf)
86 (void) free(mntbuf);
87
88 mntctl(MCTL_QUERY, sizeof(size), &size);
89 mntbuf = (char *) xmalloc(size);
90
91 entries_left = mntctl(MCTL_QUERY, size, mntbuf);
92 if (!entries_left)
93 return((FILE *)NULL);
94
95 mnt = (struct vmount *)mntbuf;
96 return((FILE *) 1);
97 }
98 #endif /* FSI_MNTCTL */
99
100 #if FSI_TYPE == FSI_GETFSSTAT
101 /*
102 * getfsstat() version of get mount info routines.
103 */
setmountent(file,mode)104 FILE *setmountent(file, mode)
105 /*ARGSUSED*/
106 char *file;
107 char *mode;
108 {
109 ulong size;
110
111 if (mntbuf)
112 (void) free(mntbuf);
113
114 size = getfsstat((struct statfs *) NULL, 0, MNT_WAIT);
115 size *= sizeof(struct statfs);
116 mntbuf = (char *) xmalloc(size);
117
118 entries_left = getfsstat((struct statfs *)mntbuf, size, MNT_WAIT);
119 if (entries_left == -1)
120 return((FILE *) NULL);
121
122 mnt = (struct statfs *) mntbuf;
123
124 return((FILE *) 1);
125 }
126 #endif /* FSI_GETFSSTAT */
127
128 #if FSI_TYPE == FSI_MNTCTL
129 /*
130 * AIX version of getmountent()
131 */
132 /*
133 * Iterate over mount entries
134 */
getmountent(fptr)135 mntent_t *getmountent(fptr)
136 /*ARGSUSED*/
137 FILE *fptr;
138 {
139 static mntent_t mntstruct;
140
141 if (!entries_left)
142 return((mntent_t*)0);
143
144 bzero((char *) &mntstruct, sizeof(mntstruct));
145
146 if (mnt->vmt_flags & MNT_READONLY)
147 mntstruct.me_flags |= MEFLAG_READONLY;
148
149 mntstruct.me_path = vmt2dataptr(mnt, VMT_STUB);
150 switch ((ulong)(struct vmount*)mnt->vmt_gfstype) {
151 case MNT_NFS:
152 mntstruct.me_type = METYPE_NFS;
153 break;
154 default:
155 mntstruct.me_type = METYPE_OTHER;
156 break;
157 }
158
159 mnt = (struct vmount*)((mnt->vmt_length)+(char *)mnt);
160 entries_left--;
161
162 return(&mntstruct);
163 }
164 #endif /* FSI_MNTCTL */
165
166 #if FSI_TYPE == FSI_GETFSSTAT
167 /*
168 * getfsstat() version of getmountent()
169 */
getmountent(fptr)170 mntent_t *getmountent(fptr)
171 /*ARGSUSED*/
172 FILE *fptr;
173 {
174 static mntent_t mntstruct;
175 static char remote_dev[MAXHOSTNAMELEN+MAXPATHLEN+1];
176
177 if (!entries_left)
178 return((mntent_t*)0);
179
180 bzero((char *) &mntstruct, sizeof(mntstruct));
181
182 #if defined(MNT_RDONLY)
183 if (mnt->f_flags & MNT_RDONLY)
184 mntstruct.me_flags |= MEFLAG_READONLY;
185 #endif
186 #if defined(M_RDONLY)
187 if (mnt->f_flags & M_RDONLY)
188 mntstruct.me_flags |= MEFLAG_READONLY;
189 #endif
190 #ifdef MOUNT_NFS
191 switch ((ulong)((struct statfs*)mnt)->f_type) {
192 case MOUNT_NFS:
193 (void) sprintf(remote_dev, "%s", mnt->f_mntfromname);
194 mntstruct.me_path = remote_dev;
195 mntstruct.me_type = METYPE_NFS;
196 break;
197 default:
198 mntstruct.me_path = mnt->f_mntonname;
199 mntstruct.me_type = METYPE_OTHER;
200 break;
201 }
202 #else
203 if ((((struct statfs*)mnt)->f_flags & MNT_LOCAL) == 0) {
204 (void) sprintf(remote_dev, "%s", mnt->f_mntfromname);
205 mntstruct.me_path = remote_dev;
206 mntstruct.me_type = METYPE_NFS;
207 } else {
208 mntstruct.me_path = mnt->f_mntonname;
209 mntstruct.me_type = METYPE_OTHER;
210 }
211 #endif
212
213 mnt++;
214 entries_left--;
215
216 return(&mntstruct);
217 }
218 #endif
219
220 #if (FSI_TYPE == FSI_MNTCTL) || (FSI_TYPE == FSI_GETFSSTAT)
221 /*
222 * Done with iterations
223 */
endmountent(fptr)224 void endmountent(fptr)
225 /*ARGSUSED*/
226 FILE *fptr;
227 {
228 mnt = NULL;
229
230 if (mntbuf) {
231 (void) free(mntbuf);
232 mntbuf = (char *) NULL;
233 }
234 }
235 #endif /* FSI_MNTCTL || FSI_GETFSSTAT */
236
237 #if FSI_TYPE == FSI_GETMNTENT2
238 /*
239 * Prepare to iterate over mounted filesystem list
240 */
setmountent(file,mode)241 FILE *setmountent(file, mode)
242 /*ARGSUSED*/
243 char *file;
244 char *mode;
245 {
246 return(fopen(file, mode));
247 }
248
249 /*
250 * Done with iteration
251 */
endmountent(fptr)252 void endmountent(fptr)
253 /*ARGSUSED*/
254 FILE *fptr;
255 {
256 fclose(fptr);
257 }
258
259 /*
260 * Iterate over mount entries
261 */
getmountent(fptr)262 mntent_t *getmountent(fptr)
263 FILE *fptr;
264 {
265 static mntent_t me;
266 static struct mnttab mntent;
267
268 bzero((char *)&me, sizeof(mntent_t));
269
270 #if defined(UNICOS)
271 if (getmntent(fptr, &mntent) != NULL) {
272 #else
273 if (getmntent(fptr, &mntent) != -1) {
274 #endif
275 me.me_path = mntent.mnt_mountp;
276 me.me_type = mntent.mnt_fstype;
277 if (mntent.mnt_mntopts && hasmntopt(&mntent, MNTOPT_RO))
278 me.me_flags |= MEFLAG_READONLY;
279
280 #if defined(MNTTYPE_IGNORE)
281 if (strcmp(mntent.mnt_fstype, MNTTYPE_IGNORE) == 0)
282 me.me_flags |= MEFLAG_IGNORE;
283 #endif /* MNTTYPE_IGNORE */
284 #if defined(MNTTYPE_SWAP)
285 if (strcmp(mntent.mnt_fstype, MNTTYPE_SWAP) == 0)
286 me.me_flags |= MEFLAG_IGNORE;
287 #endif /* MNTTYPE_SWAP */
288
289 return(&me);
290 } else
291 return((mntent_t *) NULL);
292 }
293 #endif /* FSI_GETMNTNET2 */
294
295 #if FSI_TYPE == FSI_GETMNTENT
296 /*
297 * Prepare to iterate over mounted filesystem list
298 */
setmountent(file,mode)299 FILE *setmountent(file, mode)
300 /*ARGSUSED*/
301 char *file;
302 char *mode;
303 {
304 return(setmntent(file, mode));
305 }
306
307 /*
308 * Done with iteration
309 */
endmountent(fptr)310 void endmountent(fptr)
311 /*ARGSUSED*/
312 FILE *fptr;
313 {
314 endmntent(fptr);
315 }
316
317 /*
318 * Iterate over mount entries
319 */
getmountent(fptr)320 mntent_t *getmountent(fptr)
321 FILE *fptr;
322 {
323 static mntent_t me;
324 struct mntent *mntent;
325
326 bzero((char *)&me, sizeof(mntent_t));
327
328 if (mntent = getmntent(fptr)) {
329 me.me_path = mntent->mnt_dir;
330 me.me_type = mntent->mnt_type;
331 if (mntent->mnt_opts && hasmntopt(mntent, MNTOPT_RO))
332 me.me_flags |= MEFLAG_READONLY;
333
334 #if defined(MNTTYPE_IGNORE)
335 if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
336 me.me_flags |= MEFLAG_IGNORE;
337 #endif /* MNTTYPE_IGNORE */
338 #if defined(MNTTYPE_SWAP)
339 if (strcmp(mntent->mnt_type, MNTTYPE_SWAP) == 0)
340 me.me_flags |= MEFLAG_IGNORE;
341 #endif /* MNTTYPE_SWAP */
342
343 return(&me);
344 } else
345 return((mntent_t *) NULL);
346 }
347 #endif /* FSI_GETMNTNET */
348
349 #if FSI_TYPE == FSI_GETMNT
350 /*
351 * getmnt() interface (Ultrix)
352 */
353
354 #include <sys/fs_types.h>
355
356 static int startmounts = 0;
357
setmountent(file,mode)358 FILE *setmountent(file, mode)
359 /*ARGSUSED*/
360 char *file;
361 char *mode;
362 {
363 startmounts = 0;
364 }
365
endmountent(fptr)366 void endmountent(fptr)
367 /*ARGSUSED*/
368 FILE *fptr;
369 {
370 /* NOOP */
371 }
372
373 /*
374 * Iterate over mounted filesystems using getmnt()
375 */
getmountent(fptr)376 mntent_t *getmountent(fptr)
377 /*ARGSUSED*/
378 FILE *fptr;
379 {
380 struct fs_data fs_data;
381 static mntent_t me;
382
383 if (getmnt(&startmounts, &fs_data, sizeof(fs_data), NOSTAT_MANY,
384 (char *) NULL) <= 0)
385 return((mntent_t *) NULL);
386
387 bzero((char *)&me, sizeof(mntent_t));
388 me.me_path = fs_data.fd_path;
389 if (fs_data.fd_fstype == GT_NFS)
390 me.me_type = METYPE_NFS;
391 else
392 me.me_type = METYPE_OTHER;
393
394 if (fs_data.fd_flags & M_RONLY)
395 me.me_flags |= MEFLAG_READONLY;
396
397 return(&me);
398 }
399 #endif /* FSI_GETMNT */
400
401 /*
402 * Make a new (copy) of a mntent structure.
403 */
newmountent(old)404 mntent_t *newmountent(old)
405 mntent_t *old;
406 {
407 mntent_t *new;
408
409 if (!old)
410 return((mntent_t *) NULL);
411
412 new = (mntent_t *) xcalloc(1, sizeof(mntent_t));
413 new->me_path = strdup(old->me_path);
414 new->me_type = strdup(old->me_type);
415 new->me_flags = old->me_flags;
416
417 return(new);
418 }
419