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