1 /*     $NetBSD: mnttab.c,v 1.2 2010/02/28 17:36:51 haad Exp $  */
2 
3 /*-
4  * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
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  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 /*
30  * This file implements Solaris compatible getmntany() and hasmntopt()
31  * functions.
32  */
33 
34 #include <sys/cdefs.h>
35 /* __FBSDID("$FreeBSD: src/compat/opensolaris/misc/mnttab.c,v 1.1 2007/04/06 01:08:59 pjd Exp $"); */
36 __RCSID("$NetBSD: mnttab.c,v 1.2 2010/02/28 17:36:51 haad Exp $");
37 
38 #include <sys/param.h>
39 #include <sys/statvfs.h>
40 #include <sys/mntent.h>
41 
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <ctype.h>
46 #include <err.h>
47 
48 #include <sys/mnttab.h>
49 
50 char *
mntopt(char ** p)51 mntopt(char **p)
52 {
53 	char *cp = *p;
54 	char *retstr;
55 
56 	while (*cp && isspace(*cp))
57 		cp++;
58 
59 	retstr = cp;
60 	while (*cp && *cp != ',')
61 		cp++;
62 
63 	if (*cp) {
64 		*cp = '\0';
65 		cp++;
66 	}
67 
68 	*p = cp;
69 	return (retstr);
70 }
71 
72 char *
hasmntopt(struct mnttab * mnt,char * opt)73 hasmntopt(struct mnttab *mnt, char *opt)
74 {
75 	char tmpopts[MNT_LINE_MAX];
76 	char *f, *opts = tmpopts;
77 
78 	if (mnt->mnt_mntopts == NULL)
79 		return (NULL);
80 	(void) strcpy(opts, mnt->mnt_mntopts);
81 	f = mntopt(&opts);
82 	for (; *f; f = mntopt(&opts)) {
83 		if (strncmp(opt, f, strlen(opt)) == 0)
84 			return (f - tmpopts + mnt->mnt_mntopts);
85 	}
86 	return (NULL);
87 }
88 
89 static void
optadd(char * mntopts,size_t size,const char * opt)90 optadd(char *mntopts, size_t size, const char *opt)
91 {
92 
93 	if (mntopts[0] != '\0')
94 		strlcat(mntopts, ",", size);
95 	strlcat(mntopts, opt, size);
96 }
97 
98 int
getmntany(FILE * fd __unused,struct mnttab * mgetp,struct mnttab * mrefp)99 getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
100 {
101 	static struct statvfs *sfs;
102 	static char mntopts[MNTMAXSTR];
103 	struct opt *o;
104 	static int i, n;
105 	int flags;
106 
107 	if (sfs == NULL) {
108 		n = getmntinfo(&sfs, ST_WAIT);
109 		if (n == -1)
110 			return -1;
111 	}
112 	for (i = 0; i < n; i++) {
113 		if (mrefp->mnt_special != NULL &&
114 		    strcmp(mrefp->mnt_special, sfs[i].f_mntfromname) != 0) {
115 			continue;
116 		}
117 		if (mrefp->mnt_mountp != NULL &&
118 		    strcmp(mrefp->mnt_mountp, sfs[i].f_mntonname) != 0) {
119 			continue;
120 		}
121 		if (mrefp->mnt_fstype != NULL &&
122 		    strcmp(mrefp->mnt_fstype, sfs[i].f_fstypename) != 0) {
123 			continue;
124 		}
125 		flags = sfs[i].f_flag;
126 #define	OPTADD(opt)	optadd(mntopts, sizeof(mntopts), (opt))
127 		if (flags & MNT_RDONLY)
128 			OPTADD(MNTOPT_RO);
129 		else
130 			OPTADD(MNTOPT_RW);
131 		if (flags & MNT_NOSUID)
132 			OPTADD(MNTOPT_NOSUID);
133 		else
134 			OPTADD(MNTOPT_SETUID);
135 		if (flags & MNT_UPDATE)
136 			OPTADD(MNTOPT_REMOUNT);
137 		if (flags & MNT_NOATIME)
138 			OPTADD(MNTOPT_NOATIME);
139 		else
140 			OPTADD(MNTOPT_ATIME);
141 		OPTADD(MNTOPT_NOXATTR);
142 		if (flags & MNT_NOEXEC)
143 			OPTADD(MNTOPT_NOEXEC);
144 		else
145 			OPTADD(MNTOPT_EXEC);
146 #undef	OPTADD
147 		mgetp->mnt_special = sfs[i].f_mntfromname;
148 		mgetp->mnt_mountp = sfs[i].f_mntonname;
149 		mgetp->mnt_fstype = sfs[i].f_fstypename;
150 		mgetp->mnt_mntopts = mntopts;
151 		return (0);
152 	}
153 	sfs = NULL;
154 	return (-1);
155 }
156 
157 int
getstatfs(struct statvfs * stat,const char * path)158 getstatfs(struct statvfs *stat, const char *path)
159 {
160 	int fs_num, i;
161 	struct statvfs *statvfs;
162 
163 	fs_num = 0;
164 
165 	if (path == NULL)
166 		return (-1);
167 
168 	fs_num = getvfsstat(NULL, 0, ST_WAIT);
169 
170 	if ((statvfs = malloc(fs_num * sizeof(struct statvfs))) == NULL)
171 	    return (-1);
172 
173 	memset(statvfs, 0, fs_num * sizeof(struct statvfs));
174 
175 	if (getvfsstat(statvfs, fs_num * sizeof(struct statvfs), ST_WAIT) != 0) {
176 		free(statvfs);
177 		return (-1);
178 	}
179 
180 	for( i = 0; i < fs_num; i++) {
181 
182 		if (statvfs[i].f_fstypename != NULL &&
183 		    strcmp(statvfs[i].f_fstypename, MNTTYPE_ZFS) != 0) {
184 			continue;
185 		}
186 
187 		if (statvfs[i].f_mntonname != NULL &&
188 		    strcmp(statvfs[i].f_mntonname, path) != 0) {
189 			continue;
190 		}
191 
192 		memcpy(stat, &statvfs[i], sizeof(struct statvfs));
193 	}
194 
195 	free(statvfs);
196 	return (0);
197 }
198 
199 int
getmntent(FILE * file,struct mnttab * mnttab)200 getmntent(FILE *file, struct mnttab *mnttab) {
201 
202 
203 	return 1;
204 }
205