xref: /openbsd/usr.bin/rdistd/filesys-os.c (revision 898184e3)
1 /*	$OpenBSD: filesys-os.c,v 1.10 2009/10/27 23:59:42 deraadt 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 
34 /*
35  * OS specific file system routines
36  */
37 
38 #if 	FSI_TYPE == FSI_GETFSSTAT
39 static struct statfs   *mnt = NULL;
40 #endif	/* FSI_GETFSSTAT */
41 
42 #if	FSI_TYPE == FSI_MNTCTL
43 static struct vmount   *mnt = NULL;
44 #endif	/* FSI_MNTCTL */
45 
46 #if	(FSI_TYPE == FSI_MNTCTL) || (FSI_TYPE == FSI_GETFSSTAT)
47 static char 	       *mntbuf = NULL;
48 static int 		entries_left;
49 #endif	/* FSI_MNTCTL || FSI_GETFSSTAT */
50 
51 #if	FSI_TYPE == FSI_MNTCTL
52 /*
53  * AIX version of setmountent()
54  */
55 FILE *
56 setmountent(const char *file, const char *mode)
57 {
58 	ulong size;
59 
60 	if (mntbuf)
61 		(void) free(mntbuf);
62 
63 	mntctl(MCTL_QUERY, sizeof(size), &size);
64 	mntbuf = (char *) xmalloc(size);
65 
66 	entries_left = mntctl(MCTL_QUERY, size, mntbuf);
67 	if (!entries_left)
68 		return(NULL);
69 
70 	mnt = (struct vmount *)mntbuf;
71 	return((FILE *) 1);
72 }
73 #endif	/* FSI_MNTCTL */
74 
75 #if	FSI_TYPE == FSI_GETFSSTAT
76 /*
77  * getfsstat() version of get mount info routines.
78  */
79 FILE *
80 setmountent(const char *file, const char *mode)
81 {
82 	long size;
83 
84 	if (mntbuf)
85 		(void) free(mntbuf);
86 
87 	size = getfsstat(NULL, 0, MNT_WAIT);
88 	if (size == -1)
89 		return (NULL);
90 	size *= sizeof(struct statfs);
91 	mntbuf = (char *) xmalloc(size);
92 
93 	entries_left = getfsstat((struct statfs *)mntbuf, size, MNT_WAIT);
94 	if (entries_left == -1)
95 		return(NULL);
96 
97 	mnt = (struct statfs *) mntbuf;
98 
99 	return((FILE *) 1);
100 }
101 #endif	/* FSI_GETFSSTAT */
102 
103 #if	FSI_TYPE == FSI_MNTCTL
104 /*
105  * AIX version of getmountent()
106  */
107 /*
108  * Iterate over mount entries
109  */
110 mntent_t *
111 getmountent(FILE *fptr)
112 {
113 	static mntent_t mntstruct;
114 
115 	if (!entries_left)
116 		return((mntent_t*)0);
117 
118 	bzero((char *) &mntstruct, sizeof(mntstruct));
119 
120 	if (mnt->vmt_flags & MNT_READONLY)
121 		mntstruct.me_flags |= MEFLAG_READONLY;
122 
123 	mntstruct.me_path = vmt2dataptr(mnt, VMT_STUB);
124 	switch ((ulong)(struct vmount*)mnt->vmt_gfstype) {
125 	      case MNT_NFS:
126 		mntstruct.me_type = METYPE_NFS;
127 		break;
128 	      default:
129 		mntstruct.me_type = METYPE_OTHER;
130 		break;
131 	}
132 
133 	mnt = (struct vmount*)((mnt->vmt_length)+(char *)mnt);
134 	entries_left--;
135 
136 	return(&mntstruct);
137 }
138 #endif	/* FSI_MNTCTL */
139 
140 #if	FSI_TYPE == FSI_GETFSSTAT
141 /*
142  * getfsstat() version of getmountent()
143  */
144 mntent_t *
145 getmountent(FILE *fptr)
146 {
147 	static mntent_t mntstruct;
148 	static char remote_dev[MAXHOSTNAMELEN+MAXPATHLEN+1];
149 
150 	if (!entries_left)
151 		return((mntent_t*)0);
152 
153 	bzero((char *) &mntstruct, sizeof(mntstruct));
154 
155 #if	defined(MNT_RDONLY)
156 	if (mnt->f_flags & MNT_RDONLY)
157 		mntstruct.me_flags |= MEFLAG_READONLY;
158 #endif
159 #if	defined(M_RDONLY)
160 	if (mnt->f_flags & M_RDONLY)
161 		mntstruct.me_flags |= MEFLAG_READONLY;
162 #endif
163 
164 #ifdef HAVE_FSTYPENAME
165 	if (strcmp(mnt->f_fstypename, "nfs") == 0)
166 #else
167 	if (mnt->f_type == MOUNT_NFS)
168 #endif	/* HAVE_FSTYPENAME */
169 	{
170 		strlcpy(remote_dev, mnt->f_mntfromname, sizeof(remote_dev));
171 		mntstruct.me_path = remote_dev;
172 		mntstruct.me_type = METYPE_NFS;
173 	} else {
174 		mntstruct.me_path = mnt->f_mntonname;
175 		mntstruct.me_type = METYPE_OTHER;
176 	}
177 
178 	mnt++;
179 	entries_left--;
180 
181 	return(&mntstruct);
182 }
183 #endif
184 
185 #if	(FSI_TYPE == FSI_MNTCTL) || (FSI_TYPE == FSI_GETFSSTAT)
186 /*
187  * Done with iterations
188  */
189 void
190 endmountent(FILE *fptr)
191 {
192 	mnt = NULL;
193 
194 	if (mntbuf) {
195 		(void) free(mntbuf);
196 		mntbuf = NULL;
197 	}
198 }
199 #endif	/* FSI_MNTCTL || FSI_GETFSSTAT */
200 
201 #if	FSI_TYPE == FSI_GETMNTENT2
202 /*
203  * Prepare to iterate over mounted filesystem list
204  */
205 FILE *
206 setmountent(const char *file, const char *mode)
207 {
208 	return(fopen(file, mode));
209 }
210 
211 /*
212  * Done with iteration
213  */
214 void
215 endmountent(FILE *fptr)
216 {
217 	fclose(fptr);
218 }
219 
220 /*
221  * Iterate over mount entries
222  */
223 mntent_t *
224 getmountent(FILE *fptr)
225 {
226 	static mntent_t me;
227 	static struct mnttab mntent;
228 
229 	bzero((char *)&me, sizeof(mntent_t));
230 
231 #if     defined(UNICOS)
232         if (getmntent(fptr, &mntent) != NULL) {
233 #else
234         if (getmntent(fptr, &mntent) != -1) {
235 #endif
236 		me.me_path = mntent.mnt_mountp;
237 		me.me_type = mntent.mnt_fstype;
238 		if (mntent.mnt_mntopts && hasmntopt(&mntent, MNTOPT_RO))
239 			me.me_flags |= MEFLAG_READONLY;
240 
241 #if	defined(MNTTYPE_IGNORE)
242 		if (strcmp(mntent.mnt_fstype, MNTTYPE_IGNORE) == 0)
243 			me.me_flags |= MEFLAG_IGNORE;
244 #endif	/* MNTTYPE_IGNORE */
245 #if	defined(MNTTYPE_SWAP)
246 		if (strcmp(mntent.mnt_fstype, MNTTYPE_SWAP) == 0)
247 			me.me_flags |= MEFLAG_IGNORE;
248 #endif	/* MNTTYPE_SWAP */
249 
250 		return(&me);
251 	} else
252 		return(NULL);
253 }
254 #endif	/* FSI_GETMNTNET2 */
255 
256 #if	FSI_TYPE == FSI_GETMNTENT
257 /*
258  * Prepare to iterate over mounted filesystem list
259  */
260 FILE *
261 setmountent(const char *file, const char *mode)
262 {
263 	return(setmntent(file, mode));
264 }
265 
266 /*
267  * Done with iteration
268  */
269 void
270 endmountent(FILE *fptr)
271 {
272 	endmntent(fptr);
273 }
274 
275 /*
276  * Iterate over mount entries
277  */
278 mntent_t *
279 getmountent(FILE *fptr)
280 {
281 	static mntent_t me;
282 	struct mntent *mntent;
283 
284 	bzero((char *)&me, sizeof(mntent_t));
285 
286 	if ((mntent = getmntent(fptr)) != NULL) {
287 		me.me_path = mntent->mnt_dir;
288 		me.me_type = mntent->mnt_type;
289 		if (mntent->mnt_opts && hasmntopt(mntent, MNTOPT_RO))
290 			me.me_flags |= MEFLAG_READONLY;
291 
292 #if	defined(MNTTYPE_IGNORE)
293 		if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
294 			me.me_flags |= MEFLAG_IGNORE;
295 #endif	/* MNTTYPE_IGNORE */
296 #if	defined(MNTTYPE_SWAP)
297 		if (strcmp(mntent->mnt_type, MNTTYPE_SWAP) == 0)
298 			me.me_flags |= MEFLAG_IGNORE;
299 #endif	/* MNTTYPE_SWAP */
300 
301 		return(&me);
302 	} else
303 		return(NULL);
304 }
305 #endif	/* FSI_GETMNTNET */
306 
307 #if	FSI_TYPE == FSI_GETMNT
308 /*
309  * getmnt() interface (Ultrix)
310  */
311 
312 #include <sys/fs_types.h>
313 
314 static int startmounts = 0;
315 
316 FILE *
317 setmountent(const char *file, const char *mode)
318 {
319 	startmounts = 0;
320 	return((FILE *) 1);
321 }
322 
323 void
324 endmountent(FILE *fptr)
325 {
326 	/* NOOP */
327 }
328 
329 /*
330  * Iterate over mounted filesystems using getmnt()
331  */
332 mntent_t *
333 getmountent(FILE *fptr)
334 {
335 	struct fs_data fs_data;
336 	static mntent_t me;
337 
338 	if (getmnt(&startmounts, &fs_data, sizeof(fs_data), NOSTAT_MANY,
339 		   NULL) <= 0)
340 		return(NULL);
341 
342 	bzero((char *)&me, sizeof(mntent_t));
343 	me.me_path = fs_data.fd_path;
344 	if (fs_data.fd_fstype == GT_NFS)
345 		me.me_type = METYPE_NFS;
346 	else
347 		me.me_type = METYPE_OTHER;
348 
349 	if (fs_data.fd_flags & M_RONLY)
350 		me.me_flags |= MEFLAG_READONLY;
351 
352 	return(&me);
353 }
354 #endif	/* FSI_GETMNT */
355 
356 /*
357  * Make a new (copy) of a mntent structure.
358  */
359 mntent_t *
360 newmountent(const mntent_t *old)
361 {
362 	mntent_t *new;
363 
364 	if (!old)
365 		return(NULL);
366 
367 	new = (mntent_t *) xcalloc(1, sizeof(mntent_t));
368 	new->me_path = xstrdup(old->me_path);
369 	new->me_type = xstrdup(old->me_type);
370 	new->me_flags = old->me_flags;
371 
372 	return(new);
373 }
374