]> git.saurik.com Git - apple/libutil.git/blob - getmntopts.c
libutil-30.tar.gz
[apple/libutil.git] / getmntopts.c
1 /* $NetBSD: getmntopts.c,v 1.3 2003/08/07 16:44:58 agc Exp $ */
2
3 /*-
4 * Copyright (c) 1994
5 * The Regents of the University of California. 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 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)getmntopts.c 8.3 (Berkeley) 3/29/95";
36 #else
37 __RCSID("$NetBSD: getmntopts.c,v 1.3 2003/08/07 16:44:58 agc Exp $");
38 #endif
39 #endif /* not lint */
40
41 #include <sys/param.h>
42
43 #include <err.h>
44 #include <errno.h>
45 #include <fstab.h>
46 #include <stdlib.h>
47 #include <string.h>
48
49 #include <mntopts.h>
50
51 int getmnt_silent = 0;
52
53 static const char errmsg[] = "-o %s: option not supported";
54
55 struct mntoptparse {
56 const char *options;
57 const struct mntopt *mopts;
58 char *optbuf;
59 char **optarg;
60 };
61
62 const char *
63 getmntoptstr(mntoptparse_t mp, const char *opt)
64 {
65 const struct mntopt *m;
66
67 for (m = mp->mopts; m->m_option != NULL; m++)
68 if (strcasecmp(opt, m->m_option) == 0)
69 break;
70
71 if (m->m_option == NULL) {
72 if (getmnt_silent == 0)
73 errx(1, errmsg, opt);
74 else
75 return NULL;
76 }
77
78 return mp->optarg[m - mp->mopts];
79 }
80
81 long
82 getmntoptnum(mntoptparse_t mp, const char *opt)
83 {
84 char *ep;
85 long rv;
86 void (*fun)(int, const char *, ...) = NULL;
87 const char *val = getmntoptstr(mp, opt);
88
89 if (val == NULL) {
90 if (getmnt_silent == 0)
91 errx(1, "Missing %s argument", opt);
92 else
93 return -1;
94 }
95
96 errno = 0;
97 rv = strtol(val, &ep, 0);
98
99 if (*ep)
100 fun = errx;
101
102 if (errno == ERANGE && (rv == LONG_MAX || rv == LONG_MIN))
103 fun = err;
104
105 if (fun) {
106 if (getmnt_silent != 0)
107 return -1;
108 (*fun)(1, "Invalid %s argument `%s'", opt, val);
109 }
110 return rv;
111 }
112
113 void
114 freemntopts(mntoptparse_t mp)
115 {
116 free(mp->optbuf);
117 free(mp->optarg);
118 free(mp);
119 }
120
121 mntoptparse_t
122 getmntopts(const char *options, const struct mntopt *m0, int *flagp,
123 int *altflagp)
124 {
125 const struct mntopt *m;
126 int negative;
127 char *opt, *p, *ctx = NULL;
128 int *thisflagp;
129 size_t nopts;
130 mntoptparse_t mp;
131
132 for (nopts = 0, m = m0; m->m_option != NULL; ++m, nopts++)
133 continue;
134
135 if ((mp = malloc(sizeof(struct mntoptparse))) == NULL)
136 return NULL;
137
138 /* Copy option string, since it is about to be torn asunder... */
139 if ((mp->optbuf = strdup(options)) == NULL) {
140 free(mp);
141 return NULL;
142 }
143
144 if ((mp->optarg = calloc(nopts, sizeof(char *))) == NULL) {
145 free(mp->optbuf);
146 free(mp);
147 return NULL;
148 }
149
150 mp->mopts = m0;
151 mp->options = options;
152
153 for (opt = mp->optbuf; (opt = strtok_r(opt, ",", &ctx)) != NULL; opt = NULL) {
154 /* Check for "no" prefix. */
155 if (opt[0] == 'n' && opt[1] == 'o') {
156 negative = 1;
157 opt += 2;
158 } else
159 negative = 0;
160
161 /*
162 * for options with assignments in them (ie. quotas)
163 * ignore the assignment as it's handled elsewhere
164 */
165 p = strchr(opt, '=');
166 if (p) {
167 *p++ = '\0';
168 }
169
170 /* Scan option table. */
171 for (m = m0; m->m_option != NULL; ++m)
172 if (strcasecmp(opt, m->m_option) == 0)
173 break;
174
175 /* Save flag, or fail if option is not recognised. */
176 if (m->m_option) {
177 mp->optarg[m - m0] = p;
178 thisflagp = m->m_altloc ? altflagp : flagp;
179 if (negative == m->m_inverse)
180 *thisflagp |= m->m_flag;
181 else
182 *thisflagp &= ~m->m_flag;
183 } else if (!getmnt_silent) {
184 errx(1, errmsg, opt);
185 }
186 }
187 return mp;
188 }