1 /* $OpenBSD: fstab.c,v 1.22 2016/03/17 23:48:42 mmcc Exp $ */
2 /*
3 * Copyright (c) 1980, 1988, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the University nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 #include <sys/types.h>
32 #include <sys/uio.h>
33 #include <sys/stat.h>
34
35 #include <errno.h>
36 #include <limits.h>
37 #include <fstab.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42
43 static FILE *_fs_fp;
44 static struct fstab _fs_fstab;
45
46 static int fstabscan(void);
47
48 static int
fstabscan(void)49 fstabscan(void)
50 {
51 char *cp;
52 #define MAXLINELENGTH 1024
53 static char line[MAXLINELENGTH];
54 char subline[MAXLINELENGTH];
55 const char *errstr;
56 char *last;
57 int typexx;
58
59 for (;;) {
60 if (!(cp = fgets(line, sizeof(line), _fs_fp)))
61 return(0);
62 /* OLD_STYLE_FSTAB */
63 if (!strpbrk(cp, " \t")) {
64 _fs_fstab.fs_spec = strtok_r(cp, ":\n", &last);
65 if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
66 continue;
67 _fs_fstab.fs_file = strtok_r(NULL, ":\n", &last);
68 _fs_fstab.fs_type = strtok_r(NULL, ":\n", &last);
69 if (_fs_fstab.fs_type) {
70 if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
71 continue;
72 _fs_fstab.fs_mntops = _fs_fstab.fs_type;
73 _fs_fstab.fs_vfstype =
74 strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
75 "ufs" : "swap";
76 if ((cp = strtok_r(NULL, ":\n", &last))) {
77 _fs_fstab.fs_freq = strtonum(cp, 0,
78 INT_MAX, &errstr);
79 if (errstr)
80 goto bad;
81 if ((cp = strtok_r(NULL,
82 ":\n", &last))) {
83 _fs_fstab.fs_passno =
84 strtonum(cp, 0, INT_MAX,
85 &errstr);
86 if (errstr)
87 goto bad;
88 return(1);
89 }
90 }
91 }
92 goto bad;
93 }
94 /* OLD_STYLE_FSTAB */
95 _fs_fstab.fs_spec = strtok_r(cp, " \t\n", &last);
96 if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
97 continue;
98 _fs_fstab.fs_file = strtok_r(NULL, " \t\n", &last);
99 _fs_fstab.fs_vfstype = strtok_r(NULL, " \t\n", &last);
100 _fs_fstab.fs_mntops = strtok_r(NULL, " \t\n", &last);
101 if (_fs_fstab.fs_mntops == NULL)
102 goto bad;
103 _fs_fstab.fs_freq = 0;
104 _fs_fstab.fs_passno = 0;
105 if ((cp = strtok_r(NULL, " \t\n", &last)) != NULL) {
106 _fs_fstab.fs_freq = strtonum(cp, 0, INT_MAX, &errstr);
107 if (errstr)
108 goto bad;
109 if ((cp = strtok_r(NULL, " \t\n", &last)) != NULL) {
110 _fs_fstab.fs_passno = strtonum(cp, 0, INT_MAX,
111 &errstr);
112 if (errstr)
113 goto bad;
114 }
115 }
116 strlcpy(subline, _fs_fstab.fs_mntops, sizeof subline);
117 for (typexx = 0, cp = strtok_r(subline, ",", &last); cp;
118 cp = strtok_r(NULL, ",", &last)) {
119 if (strlen(cp) != 2)
120 continue;
121 if (!strcmp(cp, FSTAB_RW)) {
122 _fs_fstab.fs_type = FSTAB_RW;
123 break;
124 }
125 if (!strcmp(cp, FSTAB_RQ)) {
126 _fs_fstab.fs_type = FSTAB_RQ;
127 break;
128 }
129 if (!strcmp(cp, FSTAB_RO)) {
130 _fs_fstab.fs_type = FSTAB_RO;
131 break;
132 }
133 if (!strcmp(cp, FSTAB_SW)) {
134 _fs_fstab.fs_type = FSTAB_SW;
135 break;
136 }
137 if (!strcmp(cp, FSTAB_XX)) {
138 _fs_fstab.fs_type = FSTAB_XX;
139 typexx++;
140 break;
141 }
142 }
143 if (typexx)
144 continue;
145 if (cp != NULL)
146 return(1);
147
148 bad: /* We silently ignore all bogus lines */
149 ;
150 }
151 }
152
153 struct fstab *
getfsent(void)154 getfsent(void)
155 {
156 if ((!_fs_fp && !setfsent()) || !fstabscan())
157 return(NULL);
158 return(&_fs_fstab);
159 }
160
161 struct fstab *
getfsspec(const char * name)162 getfsspec(const char *name)
163 {
164 if (setfsent())
165 while (fstabscan())
166 if (!strcmp(_fs_fstab.fs_spec, name))
167 return(&_fs_fstab);
168 return(NULL);
169 }
170
171 struct fstab *
getfsfile(const char * name)172 getfsfile(const char *name)
173 {
174 if (setfsent())
175 while (fstabscan())
176 if (!strcmp(_fs_fstab.fs_file, name))
177 return(&_fs_fstab);
178 return(NULL);
179 }
180
181 int
setfsent(void)182 setfsent(void)
183 {
184 struct stat sbuf;
185
186 if (_fs_fp) {
187 rewind(_fs_fp);
188 return(1);
189 }
190
191 if (stat(_PATH_FSTAB, &sbuf) != 0)
192 goto fail;
193 if ((sbuf.st_size == 0) || ((sbuf.st_mode & S_IFMT) != S_IFREG)) {
194 errno = EFTYPE;
195 goto fail;
196 }
197
198 if ((_fs_fp = fopen(_PATH_FSTAB, "re")))
199 return(1);
200
201 fail:
202 return(0);
203 }
204 DEF_WEAK(setfsent);
205
206 void
endfsent(void)207 endfsent(void)
208 {
209 if (_fs_fp) {
210 (void)fclose(_fs_fp);
211 _fs_fp = NULL;
212 }
213 }
214