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