xref: /openbsd-src/lib/libc/gen/fstab.c (revision 057c8b493d73b1a48351899f266959788731a066)
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