xref: /freebsd-src/sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c (revision eda14cbc264d6969b02f2b1994cef11148e914f1)
1*eda14cbcSMatt Macy /*
2*eda14cbcSMatt Macy  * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
3*eda14cbcSMatt Macy  * All rights reserved.
4*eda14cbcSMatt Macy  *
5*eda14cbcSMatt Macy  * Redistribution and use in source and binary forms, with or without
6*eda14cbcSMatt Macy  * modification, are permitted provided that the following conditions
7*eda14cbcSMatt Macy  * are met:
8*eda14cbcSMatt Macy  * 1. Redistributions of source code must retain the above copyright
9*eda14cbcSMatt Macy  *    notice, this list of conditions and the following disclaimer.
10*eda14cbcSMatt Macy  * 2. Redistributions in binary form must reproduce the above copyright
11*eda14cbcSMatt Macy  *    notice, this list of conditions and the following disclaimer in the
12*eda14cbcSMatt Macy  *    documentation and/or other materials provided with the distribution.
13*eda14cbcSMatt Macy  *
14*eda14cbcSMatt Macy  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
15*eda14cbcSMatt Macy  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*eda14cbcSMatt Macy  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*eda14cbcSMatt Macy  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
18*eda14cbcSMatt Macy  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*eda14cbcSMatt Macy  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*eda14cbcSMatt Macy  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*eda14cbcSMatt Macy  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*eda14cbcSMatt Macy  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*eda14cbcSMatt Macy  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*eda14cbcSMatt Macy  * SUCH DAMAGE.
25*eda14cbcSMatt Macy  */
26*eda14cbcSMatt Macy 
27*eda14cbcSMatt Macy /*
28*eda14cbcSMatt Macy  * This file implements Solaris compatible getmntany() and hasmntopt()
29*eda14cbcSMatt Macy  * functions.
30*eda14cbcSMatt Macy  */
31*eda14cbcSMatt Macy 
32*eda14cbcSMatt Macy #include <sys/cdefs.h>
33*eda14cbcSMatt Macy __FBSDID("$FreeBSD$");
34*eda14cbcSMatt Macy 
35*eda14cbcSMatt Macy #include <sys/param.h>
36*eda14cbcSMatt Macy #include <sys/mount.h>
37*eda14cbcSMatt Macy #include <sys/mntent.h>
38*eda14cbcSMatt Macy #include <sys/mnttab.h>
39*eda14cbcSMatt Macy 
40*eda14cbcSMatt Macy #include <ctype.h>
41*eda14cbcSMatt Macy #include <errno.h>
42*eda14cbcSMatt Macy #include <stdio.h>
43*eda14cbcSMatt Macy #include <stdlib.h>
44*eda14cbcSMatt Macy #include <string.h>
45*eda14cbcSMatt Macy 
46*eda14cbcSMatt Macy static char *
47*eda14cbcSMatt Macy mntopt(char **p)
48*eda14cbcSMatt Macy {
49*eda14cbcSMatt Macy 	char *cp = *p;
50*eda14cbcSMatt Macy 	char *retstr;
51*eda14cbcSMatt Macy 
52*eda14cbcSMatt Macy 	while (*cp && isspace(*cp))
53*eda14cbcSMatt Macy 		cp++;
54*eda14cbcSMatt Macy 
55*eda14cbcSMatt Macy 	retstr = cp;
56*eda14cbcSMatt Macy 	while (*cp && *cp != ',')
57*eda14cbcSMatt Macy 		cp++;
58*eda14cbcSMatt Macy 
59*eda14cbcSMatt Macy 	if (*cp) {
60*eda14cbcSMatt Macy 		*cp = '\0';
61*eda14cbcSMatt Macy 		cp++;
62*eda14cbcSMatt Macy 	}
63*eda14cbcSMatt Macy 
64*eda14cbcSMatt Macy 	*p = cp;
65*eda14cbcSMatt Macy 	return (retstr);
66*eda14cbcSMatt Macy }
67*eda14cbcSMatt Macy 
68*eda14cbcSMatt Macy char *
69*eda14cbcSMatt Macy hasmntopt(struct mnttab *mnt, char *opt)
70*eda14cbcSMatt Macy {
71*eda14cbcSMatt Macy 	char tmpopts[MNT_LINE_MAX];
72*eda14cbcSMatt Macy 	char *f, *opts = tmpopts;
73*eda14cbcSMatt Macy 
74*eda14cbcSMatt Macy 	if (mnt->mnt_mntopts == NULL)
75*eda14cbcSMatt Macy 		return (NULL);
76*eda14cbcSMatt Macy 	(void) strcpy(opts, mnt->mnt_mntopts);
77*eda14cbcSMatt Macy 	f = mntopt(&opts);
78*eda14cbcSMatt Macy 	for (; *f; f = mntopt(&opts)) {
79*eda14cbcSMatt Macy 		if (strncmp(opt, f, strlen(opt)) == 0)
80*eda14cbcSMatt Macy 			return (f - tmpopts + mnt->mnt_mntopts);
81*eda14cbcSMatt Macy 	}
82*eda14cbcSMatt Macy 	return (NULL);
83*eda14cbcSMatt Macy }
84*eda14cbcSMatt Macy 
85*eda14cbcSMatt Macy static void
86*eda14cbcSMatt Macy optadd(char *mntopts, size_t size, const char *opt)
87*eda14cbcSMatt Macy {
88*eda14cbcSMatt Macy 
89*eda14cbcSMatt Macy 	if (mntopts[0] != '\0')
90*eda14cbcSMatt Macy 		strlcat(mntopts, ",", size);
91*eda14cbcSMatt Macy 	strlcat(mntopts, opt, size);
92*eda14cbcSMatt Macy }
93*eda14cbcSMatt Macy 
94*eda14cbcSMatt Macy void
95*eda14cbcSMatt Macy statfs2mnttab(struct statfs *sfs, struct mnttab *mp)
96*eda14cbcSMatt Macy {
97*eda14cbcSMatt Macy 	static char mntopts[MNTMAXSTR];
98*eda14cbcSMatt Macy 	long flags;
99*eda14cbcSMatt Macy 
100*eda14cbcSMatt Macy 	mntopts[0] = '\0';
101*eda14cbcSMatt Macy 
102*eda14cbcSMatt Macy 	flags = sfs->f_flags;
103*eda14cbcSMatt Macy #define	OPTADD(opt)	optadd(mntopts, sizeof (mntopts), (opt))
104*eda14cbcSMatt Macy 	if (flags & MNT_RDONLY)
105*eda14cbcSMatt Macy 		OPTADD(MNTOPT_RO);
106*eda14cbcSMatt Macy 	else
107*eda14cbcSMatt Macy 		OPTADD(MNTOPT_RW);
108*eda14cbcSMatt Macy 	if (flags & MNT_NOSUID)
109*eda14cbcSMatt Macy 		OPTADD(MNTOPT_NOSETUID);
110*eda14cbcSMatt Macy 	else
111*eda14cbcSMatt Macy 		OPTADD(MNTOPT_SETUID);
112*eda14cbcSMatt Macy 	if (flags & MNT_UPDATE)
113*eda14cbcSMatt Macy 		OPTADD(MNTOPT_REMOUNT);
114*eda14cbcSMatt Macy 	if (flags & MNT_NOATIME)
115*eda14cbcSMatt Macy 		OPTADD(MNTOPT_NOATIME);
116*eda14cbcSMatt Macy 	else
117*eda14cbcSMatt Macy 		OPTADD(MNTOPT_ATIME);
118*eda14cbcSMatt Macy 	OPTADD(MNTOPT_NOXATTR);
119*eda14cbcSMatt Macy 	if (flags & MNT_NOEXEC)
120*eda14cbcSMatt Macy 		OPTADD(MNTOPT_NOEXEC);
121*eda14cbcSMatt Macy 	else
122*eda14cbcSMatt Macy 		OPTADD(MNTOPT_EXEC);
123*eda14cbcSMatt Macy #undef	OPTADD
124*eda14cbcSMatt Macy 	mp->mnt_special = strdup(sfs->f_mntfromname);
125*eda14cbcSMatt Macy 	mp->mnt_mountp = strdup(sfs->f_mntonname);
126*eda14cbcSMatt Macy 	mp->mnt_fstype = strdup(sfs->f_fstypename);
127*eda14cbcSMatt Macy 	mp->mnt_mntopts = strdup(mntopts);
128*eda14cbcSMatt Macy }
129*eda14cbcSMatt Macy 
130*eda14cbcSMatt Macy static struct statfs *gsfs = NULL;
131*eda14cbcSMatt Macy static int allfs = 0;
132*eda14cbcSMatt Macy 
133*eda14cbcSMatt Macy static int
134*eda14cbcSMatt Macy statfs_init(void)
135*eda14cbcSMatt Macy {
136*eda14cbcSMatt Macy 	struct statfs *sfs;
137*eda14cbcSMatt Macy 	int error;
138*eda14cbcSMatt Macy 
139*eda14cbcSMatt Macy 	if (gsfs != NULL) {
140*eda14cbcSMatt Macy 		free(gsfs);
141*eda14cbcSMatt Macy 		gsfs = NULL;
142*eda14cbcSMatt Macy 	}
143*eda14cbcSMatt Macy 	allfs = getfsstat(NULL, 0, MNT_WAIT);
144*eda14cbcSMatt Macy 	if (allfs == -1)
145*eda14cbcSMatt Macy 		goto fail;
146*eda14cbcSMatt Macy 	gsfs = malloc(sizeof (gsfs[0]) * allfs * 2);
147*eda14cbcSMatt Macy 	if (gsfs == NULL)
148*eda14cbcSMatt Macy 		goto fail;
149*eda14cbcSMatt Macy 	allfs = getfsstat(gsfs, (long)(sizeof (gsfs[0]) * allfs * 2),
150*eda14cbcSMatt Macy 	    MNT_WAIT);
151*eda14cbcSMatt Macy 	if (allfs == -1)
152*eda14cbcSMatt Macy 		goto fail;
153*eda14cbcSMatt Macy 	sfs = realloc(gsfs, allfs * sizeof (gsfs[0]));
154*eda14cbcSMatt Macy 	if (sfs != NULL)
155*eda14cbcSMatt Macy 		gsfs = sfs;
156*eda14cbcSMatt Macy 	return (0);
157*eda14cbcSMatt Macy fail:
158*eda14cbcSMatt Macy 	error = errno;
159*eda14cbcSMatt Macy 	if (gsfs != NULL)
160*eda14cbcSMatt Macy 		free(gsfs);
161*eda14cbcSMatt Macy 	gsfs = NULL;
162*eda14cbcSMatt Macy 	allfs = 0;
163*eda14cbcSMatt Macy 	return (error);
164*eda14cbcSMatt Macy }
165*eda14cbcSMatt Macy 
166*eda14cbcSMatt Macy int
167*eda14cbcSMatt Macy getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
168*eda14cbcSMatt Macy {
169*eda14cbcSMatt Macy 	//	struct statfs *sfs;
170*eda14cbcSMatt Macy 	int i, error;
171*eda14cbcSMatt Macy 
172*eda14cbcSMatt Macy 	error = statfs_init();
173*eda14cbcSMatt Macy 	if (error != 0)
174*eda14cbcSMatt Macy 		return (error);
175*eda14cbcSMatt Macy 
176*eda14cbcSMatt Macy 	for (i = 0; i < allfs; i++) {
177*eda14cbcSMatt Macy 		if (mrefp->mnt_special != NULL &&
178*eda14cbcSMatt Macy 		    strcmp(mrefp->mnt_special, gsfs[i].f_mntfromname) != 0) {
179*eda14cbcSMatt Macy 			continue;
180*eda14cbcSMatt Macy 		}
181*eda14cbcSMatt Macy 		if (mrefp->mnt_mountp != NULL &&
182*eda14cbcSMatt Macy 		    strcmp(mrefp->mnt_mountp, gsfs[i].f_mntonname) != 0) {
183*eda14cbcSMatt Macy 			continue;
184*eda14cbcSMatt Macy 		}
185*eda14cbcSMatt Macy 		if (mrefp->mnt_fstype != NULL &&
186*eda14cbcSMatt Macy 		    strcmp(mrefp->mnt_fstype, gsfs[i].f_fstypename) != 0) {
187*eda14cbcSMatt Macy 			continue;
188*eda14cbcSMatt Macy 		}
189*eda14cbcSMatt Macy 		statfs2mnttab(&gsfs[i], mgetp);
190*eda14cbcSMatt Macy 		return (0);
191*eda14cbcSMatt Macy 	}
192*eda14cbcSMatt Macy 	return (-1);
193*eda14cbcSMatt Macy }
194*eda14cbcSMatt Macy 
195*eda14cbcSMatt Macy int
196*eda14cbcSMatt Macy getmntent(FILE *fp, struct mnttab *mp)
197*eda14cbcSMatt Macy {
198*eda14cbcSMatt Macy 	//	struct statfs *sfs;
199*eda14cbcSMatt Macy 	int error, nfs;
200*eda14cbcSMatt Macy 
201*eda14cbcSMatt Macy 	nfs = (int)lseek(fileno(fp), 0, SEEK_CUR);
202*eda14cbcSMatt Macy 	if (nfs == -1)
203*eda14cbcSMatt Macy 		return (errno);
204*eda14cbcSMatt Macy 	/* If nfs is 0, we want to refresh out cache. */
205*eda14cbcSMatt Macy 	if (nfs == 0 || gsfs == NULL) {
206*eda14cbcSMatt Macy 		error = statfs_init();
207*eda14cbcSMatt Macy 		if (error != 0)
208*eda14cbcSMatt Macy 			return (error);
209*eda14cbcSMatt Macy 	}
210*eda14cbcSMatt Macy 	if (nfs >= allfs)
211*eda14cbcSMatt Macy 		return (-1);
212*eda14cbcSMatt Macy 	statfs2mnttab(&gsfs[nfs], mp);
213*eda14cbcSMatt Macy 	if (lseek(fileno(fp), 1, SEEK_CUR) == -1)
214*eda14cbcSMatt Macy 		return (errno);
215*eda14cbcSMatt Macy 	return (0);
216*eda14cbcSMatt Macy }
217