mnttab.c revision 168404
1/*-
2 * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * This file implements Solaris compatible getmntany() and hasmntopt()
29 * functions.
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/cddl/compat/opensolaris/misc/mnttab.c 168404 2007-04-06 01:09:06Z pjd $");
34
35#include <sys/param.h>
36#include <sys/mount.h>
37#include <sys/mntent.h>
38#include <sys/mnttab.h>
39#include <stdio.h>
40
41static char *
42mntopt(char **p)
43{
44	char *cp = *p;
45	char *retstr;
46
47	while (*cp && isspace(*cp))
48		cp++;
49
50	retstr = cp;
51	while (*cp && *cp != ',')
52		cp++;
53
54	if (*cp) {
55		*cp = '\0';
56		cp++;
57	}
58
59	*p = cp;
60	return (retstr);
61}
62
63char *
64hasmntopt(struct mnttab *mnt, char *opt)
65{
66	char tmpopts[MNT_LINE_MAX];
67	char *f, *opts = tmpopts;
68
69	if (mnt->mnt_mntopts == NULL)
70		return (NULL);
71	(void) strcpy(opts, mnt->mnt_mntopts);
72	f = mntopt(&opts);
73	for (; *f; f = mntopt(&opts)) {
74		if (strncmp(opt, f, strlen(opt)) == 0)
75			return (f - tmpopts + mnt->mnt_mntopts);
76	}
77	return (NULL);
78}
79
80static void
81optadd(char *mntopts, size_t size, const char *opt)
82{
83
84	if (mntopts[0] != '\0')
85		strlcat(mntopts, ",", size);
86	strlcat(mntopts, opt, size);
87}
88
89int
90getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
91{
92	static struct statfs *sfs = NULL;
93	static char mntopts[MNTMAXSTR];
94	struct opt *o;
95	long i, n, flags;
96
97	if (sfs != NULL) {
98		free(sfs);
99		sfs = NULL;
100	}
101	mntopts[0] = '\0';
102
103	n = getfsstat(NULL, 0, MNT_NOWAIT);
104	if (n == -1)
105		return (-1);
106	n = sizeof(*sfs) * (n + 8);
107	sfs = malloc(n);
108	if (sfs == NULL)
109		return (-1);
110	n = getfsstat(sfs, n, MNT_WAIT);
111	if (n == -1) {
112		free(sfs);
113		sfs = NULL;
114		return (-1);
115	}
116	for (i = 0; i < n; i++) {
117		if (mrefp->mnt_special != NULL &&
118		    strcmp(mrefp->mnt_special, sfs[i].f_mntfromname) != 0) {
119			continue;
120		}
121		if (mrefp->mnt_mountp != NULL &&
122		    strcmp(mrefp->mnt_mountp, sfs[i].f_mntonname) != 0) {
123			continue;
124		}
125		if (mrefp->mnt_fstype != NULL &&
126		    strcmp(mrefp->mnt_fstype, sfs[i].f_fstypename) != 0) {
127			continue;
128		}
129		flags = sfs[i].f_flags;
130#define	OPTADD(opt)	optadd(mntopts, sizeof(mntopts), (opt))
131		if (flags & MNT_RDONLY)
132			OPTADD(MNTOPT_RO);
133		else
134			OPTADD(MNTOPT_RW);
135		if (flags & MNT_NOSUID)
136			OPTADD(MNTOPT_NOSUID);
137		else
138			OPTADD(MNTOPT_SETUID);
139		if (flags & MNT_UPDATE)
140			OPTADD(MNTOPT_REMOUNT);
141		if (flags & MNT_NOATIME)
142			OPTADD(MNTOPT_NOATIME);
143		else
144			OPTADD(MNTOPT_ATIME);
145		OPTADD(MNTOPT_NOXATTR);
146		if (flags & MNT_NOEXEC)
147			OPTADD(MNTOPT_NOEXEC);
148		else
149			OPTADD(MNTOPT_EXEC);
150#undef	OPTADD
151		mgetp->mnt_special = sfs[i].f_mntfromname;
152		mgetp->mnt_mountp = sfs[i].f_mntonname;
153		mgetp->mnt_fstype = sfs[i].f_fstypename;
154		mgetp->mnt_mntopts = mntopts;
155		return (0);
156	}
157	free(sfs);
158	sfs = NULL;
159	return (-1);
160}
161