1*057c8b49Smmcc /* $OpenBSD: fstab.c,v 1.22 2016/03/17 23:48:42 mmcc Exp $ */
2df930be7Sderaadt /*
3df930be7Sderaadt * Copyright (c) 1980, 1988, 1993
4df930be7Sderaadt * The Regents of the University of California. All rights reserved.
5df930be7Sderaadt *
6df930be7Sderaadt * Redistribution and use in source and binary forms, with or without
7df930be7Sderaadt * modification, are permitted provided that the following conditions
8df930be7Sderaadt * are met:
9df930be7Sderaadt * 1. Redistributions of source code must retain the above copyright
10df930be7Sderaadt * notice, this list of conditions and the following disclaimer.
11df930be7Sderaadt * 2. Redistributions in binary form must reproduce the above copyright
12df930be7Sderaadt * notice, this list of conditions and the following disclaimer in the
13df930be7Sderaadt * documentation and/or other materials provided with the distribution.
146580fee3Smillert * 3. Neither the name of the University nor the names of its contributors
15df930be7Sderaadt * may be used to endorse or promote products derived from this software
16df930be7Sderaadt * without specific prior written permission.
17df930be7Sderaadt *
18df930be7Sderaadt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19df930be7Sderaadt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20df930be7Sderaadt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21df930be7Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22df930be7Sderaadt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23df930be7Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24df930be7Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25df930be7Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26df930be7Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27df930be7Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28df930be7Sderaadt * SUCH DAMAGE.
29df930be7Sderaadt */
30df930be7Sderaadt
31df930be7Sderaadt #include <sys/types.h>
32df930be7Sderaadt #include <sys/uio.h>
33414a3b85Sdownsj #include <sys/stat.h>
34cd9486a8Smillert
35df930be7Sderaadt #include <errno.h>
36cd9486a8Smillert #include <limits.h>
37df930be7Sderaadt #include <fstab.h>
38df930be7Sderaadt #include <stdio.h>
39df930be7Sderaadt #include <stdlib.h>
40df930be7Sderaadt #include <string.h>
41df930be7Sderaadt #include <unistd.h>
42df930be7Sderaadt
43df930be7Sderaadt static FILE *_fs_fp;
44df930be7Sderaadt static struct fstab _fs_fstab;
45df930be7Sderaadt
46c72b5b24Smillert static int fstabscan(void);
47df930be7Sderaadt
48f3bae140Sderaadt static int
fstabscan(void)4973b3e3c4Sjfb fstabscan(void)
50df930be7Sderaadt {
5180647cb2Sotto char *cp;
52df930be7Sderaadt #define MAXLINELENGTH 1024
53df930be7Sderaadt static char line[MAXLINELENGTH];
54df930be7Sderaadt char subline[MAXLINELENGTH];
5531946108Sblambert const char *errstr;
5631946108Sblambert char *last;
57df930be7Sderaadt int typexx;
58df930be7Sderaadt
59df930be7Sderaadt for (;;) {
60df930be7Sderaadt if (!(cp = fgets(line, sizeof(line), _fs_fp)))
61df930be7Sderaadt return(0);
62df930be7Sderaadt /* OLD_STYLE_FSTAB */
63df930be7Sderaadt if (!strpbrk(cp, " \t")) {
642cab24aaSderaadt _fs_fstab.fs_spec = strtok_r(cp, ":\n", &last);
65df930be7Sderaadt if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
66df930be7Sderaadt continue;
67681f9805Stedu _fs_fstab.fs_file = strtok_r(NULL, ":\n", &last);
68681f9805Stedu _fs_fstab.fs_type = strtok_r(NULL, ":\n", &last);
69df930be7Sderaadt if (_fs_fstab.fs_type) {
70df930be7Sderaadt if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
71df930be7Sderaadt continue;
72df930be7Sderaadt _fs_fstab.fs_mntops = _fs_fstab.fs_type;
73df930be7Sderaadt _fs_fstab.fs_vfstype =
74df930be7Sderaadt strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
75df930be7Sderaadt "ufs" : "swap";
76681f9805Stedu if ((cp = strtok_r(NULL, ":\n", &last))) {
7731946108Sblambert _fs_fstab.fs_freq = strtonum(cp, 0,
7831946108Sblambert INT_MAX, &errstr);
7931946108Sblambert if (errstr)
80cd9486a8Smillert goto bad;
81681f9805Stedu if ((cp = strtok_r(NULL,
822cab24aaSderaadt ":\n", &last))) {
8331946108Sblambert _fs_fstab.fs_passno =
8431946108Sblambert strtonum(cp, 0, INT_MAX,
8531946108Sblambert &errstr);
8631946108Sblambert if (errstr)
87cd9486a8Smillert goto bad;
88df930be7Sderaadt return(1);
89df930be7Sderaadt }
90df930be7Sderaadt }
91df930be7Sderaadt }
92df930be7Sderaadt goto bad;
93df930be7Sderaadt }
94df930be7Sderaadt /* OLD_STYLE_FSTAB */
952cab24aaSderaadt _fs_fstab.fs_spec = strtok_r(cp, " \t\n", &last);
96df930be7Sderaadt if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
97df930be7Sderaadt continue;
98681f9805Stedu _fs_fstab.fs_file = strtok_r(NULL, " \t\n", &last);
99681f9805Stedu _fs_fstab.fs_vfstype = strtok_r(NULL, " \t\n", &last);
100681f9805Stedu _fs_fstab.fs_mntops = strtok_r(NULL, " \t\n", &last);
101df930be7Sderaadt if (_fs_fstab.fs_mntops == NULL)
102df930be7Sderaadt goto bad;
103df930be7Sderaadt _fs_fstab.fs_freq = 0;
104df930be7Sderaadt _fs_fstab.fs_passno = 0;
105681f9805Stedu if ((cp = strtok_r(NULL, " \t\n", &last)) != NULL) {
10631946108Sblambert _fs_fstab.fs_freq = strtonum(cp, 0, INT_MAX, &errstr);
10731946108Sblambert if (errstr)
108cd9486a8Smillert goto bad;
109681f9805Stedu if ((cp = strtok_r(NULL, " \t\n", &last)) != NULL) {
11031946108Sblambert _fs_fstab.fs_passno = strtonum(cp, 0, INT_MAX,
11131946108Sblambert &errstr);
11231946108Sblambert if (errstr)
113cd9486a8Smillert goto bad;
114cd9486a8Smillert }
115df930be7Sderaadt }
116f1a075daSlebel strlcpy(subline, _fs_fstab.fs_mntops, sizeof subline);
1172cab24aaSderaadt for (typexx = 0, cp = strtok_r(subline, ",", &last); cp;
118681f9805Stedu cp = strtok_r(NULL, ",", &last)) {
119df930be7Sderaadt if (strlen(cp) != 2)
120df930be7Sderaadt continue;
121df930be7Sderaadt if (!strcmp(cp, FSTAB_RW)) {
122df930be7Sderaadt _fs_fstab.fs_type = FSTAB_RW;
123df930be7Sderaadt break;
124df930be7Sderaadt }
125df930be7Sderaadt if (!strcmp(cp, FSTAB_RQ)) {
126df930be7Sderaadt _fs_fstab.fs_type = FSTAB_RQ;
127df930be7Sderaadt break;
128df930be7Sderaadt }
129df930be7Sderaadt if (!strcmp(cp, FSTAB_RO)) {
130df930be7Sderaadt _fs_fstab.fs_type = FSTAB_RO;
131df930be7Sderaadt break;
132df930be7Sderaadt }
133df930be7Sderaadt if (!strcmp(cp, FSTAB_SW)) {
134df930be7Sderaadt _fs_fstab.fs_type = FSTAB_SW;
135df930be7Sderaadt break;
136df930be7Sderaadt }
137df930be7Sderaadt if (!strcmp(cp, FSTAB_XX)) {
138df930be7Sderaadt _fs_fstab.fs_type = FSTAB_XX;
139df930be7Sderaadt typexx++;
140df930be7Sderaadt break;
141df930be7Sderaadt }
142df930be7Sderaadt }
143df930be7Sderaadt if (typexx)
144df930be7Sderaadt continue;
145df930be7Sderaadt if (cp != NULL)
146df930be7Sderaadt return(1);
147df930be7Sderaadt
14835924d76Sderaadt bad: /* We silently ignore all bogus lines */
149393ec008Sjsg ;
150df930be7Sderaadt }
151df930be7Sderaadt }
152df930be7Sderaadt
153df930be7Sderaadt struct fstab *
getfsent(void)15473b3e3c4Sjfb getfsent(void)
155df930be7Sderaadt {
156b0f29dd7Smillert if ((!_fs_fp && !setfsent()) || !fstabscan())
157b0f29dd7Smillert return(NULL);
158df930be7Sderaadt return(&_fs_fstab);
159df930be7Sderaadt }
160df930be7Sderaadt
161df930be7Sderaadt struct fstab *
getfsspec(const char * name)16273b3e3c4Sjfb getfsspec(const char *name)
163df930be7Sderaadt {
164df930be7Sderaadt if (setfsent())
165df930be7Sderaadt while (fstabscan())
166df930be7Sderaadt if (!strcmp(_fs_fstab.fs_spec, name))
167df930be7Sderaadt return(&_fs_fstab);
168681f9805Stedu return(NULL);
169df930be7Sderaadt }
170df930be7Sderaadt
171df930be7Sderaadt struct fstab *
getfsfile(const char * name)17273b3e3c4Sjfb getfsfile(const char *name)
173df930be7Sderaadt {
174df930be7Sderaadt if (setfsent())
175df930be7Sderaadt while (fstabscan())
176df930be7Sderaadt if (!strcmp(_fs_fstab.fs_file, name))
177df930be7Sderaadt return(&_fs_fstab);
178681f9805Stedu return(NULL);
179df930be7Sderaadt }
180df930be7Sderaadt
181f3bae140Sderaadt int
setfsent(void)18273b3e3c4Sjfb setfsent(void)
183df930be7Sderaadt {
184414a3b85Sdownsj struct stat sbuf;
185414a3b85Sdownsj
186df930be7Sderaadt if (_fs_fp) {
187df930be7Sderaadt rewind(_fs_fp);
188df930be7Sderaadt return(1);
189df930be7Sderaadt }
190414a3b85Sdownsj
191414a3b85Sdownsj if (stat(_PATH_FSTAB, &sbuf) != 0)
192414a3b85Sdownsj goto fail;
193414a3b85Sdownsj if ((sbuf.st_size == 0) || ((sbuf.st_mode & S_IFMT) != S_IFREG)) {
194414a3b85Sdownsj errno = EFTYPE;
195414a3b85Sdownsj goto fail;
196414a3b85Sdownsj }
197414a3b85Sdownsj
198241db059Sguenther if ((_fs_fp = fopen(_PATH_FSTAB, "re")))
199df930be7Sderaadt return(1);
200414a3b85Sdownsj
201414a3b85Sdownsj fail:
202df930be7Sderaadt return(0);
203df930be7Sderaadt }
204b26f1fe6Sguenther DEF_WEAK(setfsent);
205df930be7Sderaadt
206df930be7Sderaadt void
endfsent(void)20773b3e3c4Sjfb endfsent(void)
208df930be7Sderaadt {
209df930be7Sderaadt if (_fs_fp) {
210df930be7Sderaadt (void)fclose(_fs_fp);
211df930be7Sderaadt _fs_fp = NULL;
212df930be7Sderaadt }
213df930be7Sderaadt }
214