xref: /titanic_52/usr/src/cmd/backup/dump/dumpfstab.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1996,1998 by Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate  * All rights reserved.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include "dump.h"
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate /*
32*7c478bd9Sstevel@tonic-gate  * File system mount table input routines.  We handle a
33*7c478bd9Sstevel@tonic-gate  * a combination of BSD and SVR4 formats by coding functions
34*7c478bd9Sstevel@tonic-gate  * to explicitly read the SVR4 vfstab file and using
35*7c478bd9Sstevel@tonic-gate  * #define's to build a routine to read both BSD files
36*7c478bd9Sstevel@tonic-gate  * (fstab and mtab) and SVR4's mnttab file.  Internally
37*7c478bd9Sstevel@tonic-gate  * we keep everything in the common (mtab/mnttab) format.
38*7c478bd9Sstevel@tonic-gate  */
39*7c478bd9Sstevel@tonic-gate static struct pmntent {
40*7c478bd9Sstevel@tonic-gate 	struct mntent	*pm_mnt;
41*7c478bd9Sstevel@tonic-gate 	struct pmntent	*pm_next;
42*7c478bd9Sstevel@tonic-gate } *mnttable;
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate /* Note that nothing is ever free()'d, so this is safe */
45*7c478bd9Sstevel@tonic-gate #define	mntstrdup(s)	((s) ? strdup((s)) : "")
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate #ifdef __STDC__
48*7c478bd9Sstevel@tonic-gate static struct mntent *mygetmntent(FILE *, char *);
49*7c478bd9Sstevel@tonic-gate static struct pmntent *addmtab(char *, struct pmntent *);
50*7c478bd9Sstevel@tonic-gate static struct mntent *allocmntent(struct mntent *);
51*7c478bd9Sstevel@tonic-gate #else /* !__STDC__ */
52*7c478bd9Sstevel@tonic-gate static struct pmntent *addmtab();
53*7c478bd9Sstevel@tonic-gate static struct mntent *mygetmntent();
54*7c478bd9Sstevel@tonic-gate static struct mntent *allocmntent();
55*7c478bd9Sstevel@tonic-gate static int idatesort();
56*7c478bd9Sstevel@tonic-gate #endif
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate static struct mntent *
59*7c478bd9Sstevel@tonic-gate mygetmntent(f, name)
60*7c478bd9Sstevel@tonic-gate 	FILE *f;
61*7c478bd9Sstevel@tonic-gate 	char *name;
62*7c478bd9Sstevel@tonic-gate {
63*7c478bd9Sstevel@tonic-gate 	static struct mntent mt;
64*7c478bd9Sstevel@tonic-gate 	int status;
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate 	if ((status = getmntent(f, &mt)) == 0)
67*7c478bd9Sstevel@tonic-gate 		return (&mt);
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate 	switch (status) {
70*7c478bd9Sstevel@tonic-gate 	case EOF:	break;		/* normal exit condition */
71*7c478bd9Sstevel@tonic-gate 	case MNT_TOOLONG:
72*7c478bd9Sstevel@tonic-gate 		msg(gettext("%s has a line that is too long\n"), name);
73*7c478bd9Sstevel@tonic-gate 		break;
74*7c478bd9Sstevel@tonic-gate 	case MNT_TOOMANY:
75*7c478bd9Sstevel@tonic-gate 		msg(gettext("%s has a line with too many entries\n"), name);
76*7c478bd9Sstevel@tonic-gate 		break;
77*7c478bd9Sstevel@tonic-gate 	case MNT_TOOFEW:
78*7c478bd9Sstevel@tonic-gate 		msg(gettext("%s has a line with too few entries\n"), name);
79*7c478bd9Sstevel@tonic-gate 		break;
80*7c478bd9Sstevel@tonic-gate 	default:
81*7c478bd9Sstevel@tonic-gate 		msg(gettext(
82*7c478bd9Sstevel@tonic-gate 			"Unknown return code, %d, from getmntent() on %s\n"),
83*7c478bd9Sstevel@tonic-gate 			status, name);
84*7c478bd9Sstevel@tonic-gate 		break;
85*7c478bd9Sstevel@tonic-gate 	}
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate 	return (NULL);
88*7c478bd9Sstevel@tonic-gate }
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate /*
91*7c478bd9Sstevel@tonic-gate  * Read in SVR4 vfstab-format table.
92*7c478bd9Sstevel@tonic-gate  */
93*7c478bd9Sstevel@tonic-gate static struct pmntent *
94*7c478bd9Sstevel@tonic-gate addvfstab(tablename, pm)
95*7c478bd9Sstevel@tonic-gate 	char	*tablename;
96*7c478bd9Sstevel@tonic-gate 	struct pmntent *pm;
97*7c478bd9Sstevel@tonic-gate {
98*7c478bd9Sstevel@tonic-gate 	struct mnttab *mnt;
99*7c478bd9Sstevel@tonic-gate 	struct vfstab vfs;
100*7c478bd9Sstevel@tonic-gate 	FILE	*tp;
101*7c478bd9Sstevel@tonic-gate 	int status;
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate 	assert(((mnttable == NULL) && (pm == NULL)) || (pm != NULL));
104*7c478bd9Sstevel@tonic-gate 
105*7c478bd9Sstevel@tonic-gate 	/*
106*7c478bd9Sstevel@tonic-gate 	 * No need to secure this, as tablename is hard-coded to VFSTAB,
107*7c478bd9Sstevel@tonic-gate 	 * and that file is in /etc.  If random people have write-permission
108*7c478bd9Sstevel@tonic-gate 	 * there, then there are more problems than any degree of paranoia
109*7c478bd9Sstevel@tonic-gate 	 * on our part can fix.
110*7c478bd9Sstevel@tonic-gate 	 */
111*7c478bd9Sstevel@tonic-gate 	tp = fopen(tablename, "r");
112*7c478bd9Sstevel@tonic-gate 	if (tp == (FILE *)0) {
113*7c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot open %s for dump table information.\n"),
114*7c478bd9Sstevel@tonic-gate 			tablename);
115*7c478bd9Sstevel@tonic-gate 		return ((struct pmntent *)0);
116*7c478bd9Sstevel@tonic-gate 	}
117*7c478bd9Sstevel@tonic-gate 	while ((status = getvfsent(tp, &vfs)) == 0) {
118*7c478bd9Sstevel@tonic-gate 		if (vfs.vfs_fstype == (char *)0 ||
119*7c478bd9Sstevel@tonic-gate 		    strcmp(vfs.vfs_fstype, MNTTYPE_42) != 0)
120*7c478bd9Sstevel@tonic-gate 			continue;
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate 		mnt = (struct mnttab *)xmalloc(sizeof (*mnt));
123*7c478bd9Sstevel@tonic-gate 		mnt->mnt_fsname = mntstrdup(vfs.vfs_special);
124*7c478bd9Sstevel@tonic-gate 		mnt->mnt_dir = mntstrdup(vfs.vfs_mountp);
125*7c478bd9Sstevel@tonic-gate 		mnt->mnt_type = mntstrdup(vfs.vfs_fstype);
126*7c478bd9Sstevel@tonic-gate 		mnt->mnt_opts = mntstrdup(vfs.vfs_mntopts);
127*7c478bd9Sstevel@tonic-gate 
128*7c478bd9Sstevel@tonic-gate 		if (mnttable == (struct pmntent *)0)
129*7c478bd9Sstevel@tonic-gate 			/*
130*7c478bd9Sstevel@tonic-gate 			 * Guaranteed by caller that pm will also be NULL,
131*7c478bd9Sstevel@tonic-gate 			 * so no memory leak to worry about.
132*7c478bd9Sstevel@tonic-gate 			 */
133*7c478bd9Sstevel@tonic-gate 			mnttable = pm = (struct pmntent *)xmalloc(sizeof (*pm));
134*7c478bd9Sstevel@tonic-gate 		else {
135*7c478bd9Sstevel@tonic-gate 			/* Guaranteed pm not NULL by caller and local logic */
136*7c478bd9Sstevel@tonic-gate 			pm->pm_next = (struct pmntent *)xmalloc(sizeof (*pm));
137*7c478bd9Sstevel@tonic-gate 			pm = pm->pm_next;
138*7c478bd9Sstevel@tonic-gate 		}
139*7c478bd9Sstevel@tonic-gate 		pm->pm_mnt = mnt;
140*7c478bd9Sstevel@tonic-gate 		pm->pm_next = (struct pmntent *)0;
141*7c478bd9Sstevel@tonic-gate 	}
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate 	switch (status) {
144*7c478bd9Sstevel@tonic-gate 	case EOF:	break;		/* normal exit condition */
145*7c478bd9Sstevel@tonic-gate 	case VFS_TOOLONG:
146*7c478bd9Sstevel@tonic-gate 		msg(gettext("%s has a line that is too long\n"), tablename);
147*7c478bd9Sstevel@tonic-gate 		break;
148*7c478bd9Sstevel@tonic-gate 	case VFS_TOOMANY:
149*7c478bd9Sstevel@tonic-gate 		msg(gettext("%s has a line with too many entries\n"),
150*7c478bd9Sstevel@tonic-gate 			tablename);
151*7c478bd9Sstevel@tonic-gate 		break;
152*7c478bd9Sstevel@tonic-gate 	case VFS_TOOFEW:
153*7c478bd9Sstevel@tonic-gate 		msg(gettext("%s has a line with too few entries\n"), tablename);
154*7c478bd9Sstevel@tonic-gate 		break;
155*7c478bd9Sstevel@tonic-gate 	default:
156*7c478bd9Sstevel@tonic-gate 		msg(gettext(
157*7c478bd9Sstevel@tonic-gate 			"Unknown return code, %d, from getvfsent() on %s\n"),
158*7c478bd9Sstevel@tonic-gate 			status, tablename);
159*7c478bd9Sstevel@tonic-gate 		break;
160*7c478bd9Sstevel@tonic-gate 	}
161*7c478bd9Sstevel@tonic-gate 	(void) fclose(tp);
162*7c478bd9Sstevel@tonic-gate 	return (pm);
163*7c478bd9Sstevel@tonic-gate }
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate static struct mntent *
166*7c478bd9Sstevel@tonic-gate allocmntent(mnt)
167*7c478bd9Sstevel@tonic-gate 	struct mntent *mnt;
168*7c478bd9Sstevel@tonic-gate {
169*7c478bd9Sstevel@tonic-gate 	struct mntent *new;
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate 	new = (struct mntent *)xmalloc(sizeof (*mnt));
172*7c478bd9Sstevel@tonic-gate 	new->mnt_fsname = mntstrdup(mnt->mnt_fsname);	/* mnt_special */
173*7c478bd9Sstevel@tonic-gate 	new->mnt_dir = mntstrdup(mnt->mnt_dir);		/* mnt_mountp  */
174*7c478bd9Sstevel@tonic-gate 	new->mnt_type = mntstrdup(mnt->mnt_type);	/* mnt_fstype  */
175*7c478bd9Sstevel@tonic-gate 	new->mnt_opts = mntstrdup(mnt->mnt_opts);	/* mnt_mntopts */
176*7c478bd9Sstevel@tonic-gate 	return (new);
177*7c478bd9Sstevel@tonic-gate }
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate void
180*7c478bd9Sstevel@tonic-gate mnttabread()
181*7c478bd9Sstevel@tonic-gate {
182*7c478bd9Sstevel@tonic-gate 	struct pmntent *pm = (struct pmntent *)0;
183*7c478bd9Sstevel@tonic-gate 
184*7c478bd9Sstevel@tonic-gate 	if (mnttable != (struct pmntent *)0)
185*7c478bd9Sstevel@tonic-gate 		return;
186*7c478bd9Sstevel@tonic-gate 	/*
187*7c478bd9Sstevel@tonic-gate 	 * Read in the file system mount tables.  Order
188*7c478bd9Sstevel@tonic-gate 	 * is important as the first matched entry is used
189*7c478bd9Sstevel@tonic-gate 	 * if the target device/filesystem is not mounted.
190*7c478bd9Sstevel@tonic-gate 	 * We try fstab or vfstab first, then mtab or mnttab.
191*7c478bd9Sstevel@tonic-gate 	 */
192*7c478bd9Sstevel@tonic-gate 	pm = addvfstab(VFSTAB, pm);
193*7c478bd9Sstevel@tonic-gate 	(void) addmtab(MOUNTED, pm);
194*7c478bd9Sstevel@tonic-gate }
195*7c478bd9Sstevel@tonic-gate 
196*7c478bd9Sstevel@tonic-gate static struct pmntent *
197*7c478bd9Sstevel@tonic-gate addmtab(tablename, pm)
198*7c478bd9Sstevel@tonic-gate 	char	*tablename;
199*7c478bd9Sstevel@tonic-gate 	struct pmntent *pm;
200*7c478bd9Sstevel@tonic-gate {
201*7c478bd9Sstevel@tonic-gate 	struct mntent *mnt;
202*7c478bd9Sstevel@tonic-gate 	FILE	*tp;
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 	tp = setmntent(tablename, "r");
205*7c478bd9Sstevel@tonic-gate 	if (tp == (FILE *)0) {
206*7c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot open %s for dump table information.\n"),
207*7c478bd9Sstevel@tonic-gate 			tablename);
208*7c478bd9Sstevel@tonic-gate 		return ((struct pmntent *)0);
209*7c478bd9Sstevel@tonic-gate 	}
210*7c478bd9Sstevel@tonic-gate 	while (mnt = mygetmntent(tp, tablename)) {
211*7c478bd9Sstevel@tonic-gate 		if (mnt->mnt_type == (char *)0 ||
212*7c478bd9Sstevel@tonic-gate 		    strcmp(mnt->mnt_type, MNTTYPE_42) != 0)
213*7c478bd9Sstevel@tonic-gate 			continue;
214*7c478bd9Sstevel@tonic-gate 
215*7c478bd9Sstevel@tonic-gate 		mnt = allocmntent(mnt);
216*7c478bd9Sstevel@tonic-gate 		if (mnttable == (struct pmntent *)0)
217*7c478bd9Sstevel@tonic-gate 			/*
218*7c478bd9Sstevel@tonic-gate 			 * Guaranteed by caller that pm will also be NULL,
219*7c478bd9Sstevel@tonic-gate 			 * so no memory leak to worry about.
220*7c478bd9Sstevel@tonic-gate 			 */
221*7c478bd9Sstevel@tonic-gate 			mnttable = pm = (struct pmntent *)xmalloc(sizeof (*pm));
222*7c478bd9Sstevel@tonic-gate 		else {
223*7c478bd9Sstevel@tonic-gate 			/* Guaranteed pm not NULL by caller and local logic */
224*7c478bd9Sstevel@tonic-gate 			pm->pm_next = (struct pmntent *)xmalloc(sizeof (*pm));
225*7c478bd9Sstevel@tonic-gate 			pm = pm->pm_next;
226*7c478bd9Sstevel@tonic-gate 		}
227*7c478bd9Sstevel@tonic-gate 		pm->pm_mnt = mnt;
228*7c478bd9Sstevel@tonic-gate 		pm->pm_next = (struct pmntent *)0;
229*7c478bd9Sstevel@tonic-gate 	}
230*7c478bd9Sstevel@tonic-gate 	(void) endmntent(tp);
231*7c478bd9Sstevel@tonic-gate 	return (pm);
232*7c478bd9Sstevel@tonic-gate }
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate /*
235*7c478bd9Sstevel@tonic-gate  * Search in fstab and potentially mtab for a file name.
236*7c478bd9Sstevel@tonic-gate  * If "mounted" is non-zero, the target file system must
237*7c478bd9Sstevel@tonic-gate  * be mounted in order for the search to succeed.
238*7c478bd9Sstevel@tonic-gate  * This file name can be either the special or the path file name.
239*7c478bd9Sstevel@tonic-gate  *
240*7c478bd9Sstevel@tonic-gate  * The entries in either fstab or mtab are the BLOCK special names,
241*7c478bd9Sstevel@tonic-gate  * not the character special names.
242*7c478bd9Sstevel@tonic-gate  * The caller of mnttabsearch assures that the character device
243*7c478bd9Sstevel@tonic-gate  * is dumped (that is much faster)
244*7c478bd9Sstevel@tonic-gate  *
245*7c478bd9Sstevel@tonic-gate  * The file name can omit the leading '/'.
246*7c478bd9Sstevel@tonic-gate  */
247*7c478bd9Sstevel@tonic-gate struct mntent *
248*7c478bd9Sstevel@tonic-gate mnttabsearch(key, mounted)
249*7c478bd9Sstevel@tonic-gate 	char	*key;
250*7c478bd9Sstevel@tonic-gate 	int	mounted;
251*7c478bd9Sstevel@tonic-gate {
252*7c478bd9Sstevel@tonic-gate 	struct pmntent *pm;
253*7c478bd9Sstevel@tonic-gate 	struct mntent *mnt;
254*7c478bd9Sstevel@tonic-gate 	struct mntent *first = (struct mntent *)0;
255*7c478bd9Sstevel@tonic-gate 	char *s;
256*7c478bd9Sstevel@tonic-gate 	char *gotreal;
257*7c478bd9Sstevel@tonic-gate 	char path[MAXPATHLEN];
258*7c478bd9Sstevel@tonic-gate 
259*7c478bd9Sstevel@tonic-gate 	for (pm = mnttable; pm; pm = pm->pm_next) {
260*7c478bd9Sstevel@tonic-gate 		s = NULL;
261*7c478bd9Sstevel@tonic-gate 		mnt = pm->pm_mnt;
262*7c478bd9Sstevel@tonic-gate 		if (strcmp(mnt->mnt_dir, key) == 0)
263*7c478bd9Sstevel@tonic-gate 			goto found;
264*7c478bd9Sstevel@tonic-gate 		if (strcmp(mnt->mnt_fsname, key) == 0)
265*7c478bd9Sstevel@tonic-gate 			goto found;
266*7c478bd9Sstevel@tonic-gate 		if ((s = rawname(mnt->mnt_fsname)) != NULL &&
267*7c478bd9Sstevel@tonic-gate 		    strcmp(s, key) == 0)
268*7c478bd9Sstevel@tonic-gate 			goto found;
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate 		gotreal = realpath(mnt->mnt_dir, path);
271*7c478bd9Sstevel@tonic-gate 		if (gotreal && strcmp(path, key) == 0)
272*7c478bd9Sstevel@tonic-gate 			goto found;
273*7c478bd9Sstevel@tonic-gate 		if (key[0] != '/') {
274*7c478bd9Sstevel@tonic-gate 			if (*mnt->mnt_fsname == '/' &&
275*7c478bd9Sstevel@tonic-gate 			    strcmp(mnt->mnt_fsname + 1, key) == 0)
276*7c478bd9Sstevel@tonic-gate 				goto found;
277*7c478bd9Sstevel@tonic-gate 			if (*mnt->mnt_dir == '/' &&
278*7c478bd9Sstevel@tonic-gate 			    strcmp(mnt->mnt_dir + 1, key) == 0)
279*7c478bd9Sstevel@tonic-gate 				goto found;
280*7c478bd9Sstevel@tonic-gate 			if (gotreal && *path == '/' &&
281*7c478bd9Sstevel@tonic-gate 			    strcmp(path + 1, key) == 0)
282*7c478bd9Sstevel@tonic-gate 				goto found;
283*7c478bd9Sstevel@tonic-gate 		}
284*7c478bd9Sstevel@tonic-gate 		if (s != NULL && s != mnt->mnt_fsname)
285*7c478bd9Sstevel@tonic-gate 			free(s);
286*7c478bd9Sstevel@tonic-gate 		continue;
287*7c478bd9Sstevel@tonic-gate found:
288*7c478bd9Sstevel@tonic-gate 		/* Pointer comparison, not string comparison */
289*7c478bd9Sstevel@tonic-gate 		if (s != NULL && s != mnt->mnt_fsname)
290*7c478bd9Sstevel@tonic-gate 			free(s);
291*7c478bd9Sstevel@tonic-gate 		/*
292*7c478bd9Sstevel@tonic-gate 		 * Found a match; return immediately if
293*7c478bd9Sstevel@tonic-gate 		 * it is mounted (valid), otherwise just
294*7c478bd9Sstevel@tonic-gate 		 * record if it's the first matched entry.
295*7c478bd9Sstevel@tonic-gate 		 */
296*7c478bd9Sstevel@tonic-gate 		if (lf_ismounted(mnt->mnt_fsname, mnt->mnt_dir) > 0)
297*7c478bd9Sstevel@tonic-gate 			return (mnt);
298*7c478bd9Sstevel@tonic-gate 		else if (first == (struct mntent *)0)
299*7c478bd9Sstevel@tonic-gate 			first = mnt;
300*7c478bd9Sstevel@tonic-gate 	}
301*7c478bd9Sstevel@tonic-gate 	/*
302*7c478bd9Sstevel@tonic-gate 	 * If we get here, there were either
303*7c478bd9Sstevel@tonic-gate 	 * no matches, or no matched entries
304*7c478bd9Sstevel@tonic-gate 	 * were mounted.  Return failure if
305*7c478bd9Sstevel@tonic-gate 	 * we were supposed to find a mounted
306*7c478bd9Sstevel@tonic-gate 	 * entry, otherwise return the first
307*7c478bd9Sstevel@tonic-gate 	 * matched entry (or null).
308*7c478bd9Sstevel@tonic-gate 	 */
309*7c478bd9Sstevel@tonic-gate 	if (mounted)
310*7c478bd9Sstevel@tonic-gate 		return ((struct mntent *)0);
311*7c478bd9Sstevel@tonic-gate 	return (first);
312*7c478bd9Sstevel@tonic-gate }
313*7c478bd9Sstevel@tonic-gate 
314*7c478bd9Sstevel@tonic-gate static struct pmntent *current;
315*7c478bd9Sstevel@tonic-gate static int set;
316*7c478bd9Sstevel@tonic-gate 
317*7c478bd9Sstevel@tonic-gate void
318*7c478bd9Sstevel@tonic-gate #ifdef __STDC__
319*7c478bd9Sstevel@tonic-gate setmnttab(void)
320*7c478bd9Sstevel@tonic-gate #else
321*7c478bd9Sstevel@tonic-gate setmnttab()
322*7c478bd9Sstevel@tonic-gate #endif
323*7c478bd9Sstevel@tonic-gate {
324*7c478bd9Sstevel@tonic-gate 	current = mnttable;
325*7c478bd9Sstevel@tonic-gate 	set = 1;
326*7c478bd9Sstevel@tonic-gate }
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate struct mntent *
329*7c478bd9Sstevel@tonic-gate #ifdef __STDC__
330*7c478bd9Sstevel@tonic-gate getmnttab(void)
331*7c478bd9Sstevel@tonic-gate #else
332*7c478bd9Sstevel@tonic-gate getmnttab()
333*7c478bd9Sstevel@tonic-gate #endif
334*7c478bd9Sstevel@tonic-gate {
335*7c478bd9Sstevel@tonic-gate 	struct pmntent *pm;
336*7c478bd9Sstevel@tonic-gate 
337*7c478bd9Sstevel@tonic-gate 	if (!set)
338*7c478bd9Sstevel@tonic-gate 		setmnttab();
339*7c478bd9Sstevel@tonic-gate 	pm = current;
340*7c478bd9Sstevel@tonic-gate 	if (current) {
341*7c478bd9Sstevel@tonic-gate 		current = current->pm_next;
342*7c478bd9Sstevel@tonic-gate 		return (pm->pm_mnt);
343*7c478bd9Sstevel@tonic-gate 	}
344*7c478bd9Sstevel@tonic-gate 	return ((struct mntent *)0);
345*7c478bd9Sstevel@tonic-gate }
346