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