]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - cddl/compat/opensolaris/misc/mnttab.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / cddl / compat / opensolaris / misc / mnttab.c
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$");
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 #include <stdlib.h>
41 #include <string.h>
42
43 static char *
44 mntopt(char **p)
45 {
46         char *cp = *p;
47         char *retstr;
48
49         while (*cp && isspace(*cp))
50                 cp++;
51
52         retstr = cp;
53         while (*cp && *cp != ',')
54                 cp++;
55
56         if (*cp) {
57                 *cp = '\0';
58                 cp++;
59         }
60
61         *p = cp;
62         return (retstr);
63 }
64
65 char *
66 hasmntopt(struct mnttab *mnt, char *opt)
67 {
68         char tmpopts[MNT_LINE_MAX];
69         char *f, *opts = tmpopts;
70
71         if (mnt->mnt_mntopts == NULL)
72                 return (NULL);
73         (void) strcpy(opts, mnt->mnt_mntopts);
74         f = mntopt(&opts);
75         for (; *f; f = mntopt(&opts)) {
76                 if (strncmp(opt, f, strlen(opt)) == 0)
77                         return (f - tmpopts + mnt->mnt_mntopts);
78         }
79         return (NULL);
80 }
81
82 static void
83 optadd(char *mntopts, size_t size, const char *opt)
84 {
85
86         if (mntopts[0] != '\0')
87                 strlcat(mntopts, ",", size);
88         strlcat(mntopts, opt, size);
89 }
90
91 int
92 getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
93 {
94         static struct statfs *sfs = NULL;
95         static char mntopts[MNTMAXSTR];
96         struct opt *o;
97         long i, n, flags;
98
99         if (sfs != NULL) {
100                 free(sfs);
101                 sfs = NULL;
102         }
103         mntopts[0] = '\0';
104
105         n = getfsstat(NULL, 0, MNT_NOWAIT);
106         if (n == -1)
107                 return (-1);
108         n = sizeof(*sfs) * (n + 8);
109         sfs = malloc(n);
110         if (sfs == NULL)
111                 return (-1);
112         n = getfsstat(sfs, n, MNT_WAIT);
113         if (n == -1) {
114                 free(sfs);
115                 sfs = NULL;
116                 return (-1);
117         }
118         for (i = 0; i < n; i++) {
119                 if (mrefp->mnt_special != NULL &&
120                     strcmp(mrefp->mnt_special, sfs[i].f_mntfromname) != 0) {
121                         continue;
122                 }
123                 if (mrefp->mnt_mountp != NULL &&
124                     strcmp(mrefp->mnt_mountp, sfs[i].f_mntonname) != 0) {
125                         continue;
126                 }
127                 if (mrefp->mnt_fstype != NULL &&
128                     strcmp(mrefp->mnt_fstype, sfs[i].f_fstypename) != 0) {
129                         continue;
130                 }
131                 flags = sfs[i].f_flags;
132 #define OPTADD(opt)     optadd(mntopts, sizeof(mntopts), (opt))
133                 if (flags & MNT_RDONLY)
134                         OPTADD(MNTOPT_RO);
135                 else
136                         OPTADD(MNTOPT_RW);
137                 if (flags & MNT_NOSUID)
138                         OPTADD(MNTOPT_NOSUID);
139                 else
140                         OPTADD(MNTOPT_SETUID);
141                 if (flags & MNT_UPDATE)
142                         OPTADD(MNTOPT_REMOUNT);
143                 if (flags & MNT_NOATIME)
144                         OPTADD(MNTOPT_NOATIME);
145                 else
146                         OPTADD(MNTOPT_ATIME);
147                 OPTADD(MNTOPT_NOXATTR);
148                 if (flags & MNT_NOEXEC)
149                         OPTADD(MNTOPT_NOEXEC);
150                 else
151                         OPTADD(MNTOPT_EXEC);
152 #undef  OPTADD
153                 mgetp->mnt_special = sfs[i].f_mntfromname;
154                 mgetp->mnt_mountp = sfs[i].f_mntonname;
155                 mgetp->mnt_fstype = sfs[i].f_fstypename;
156                 mgetp->mnt_mntopts = mntopts;
157                 return (0);
158         }
159         free(sfs);
160         sfs = NULL;
161         return (-1);
162 }