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