fstab.c revision 71579
1/*
2 * Copyright (c) 1980, 1988, 1993
3 *	The Regents of the University of California.  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 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * $FreeBSD: head/lib/libc/gen/fstab.c 71579 2001-01-24 13:01:12Z deischen $
34 */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37#if 0
38static char sccsid[] = "@(#)fstab.c	8.1 (Berkeley) 6/4/93";
39#else
40static char rcsid[] =
41 "$FreeBSD: head/lib/libc/gen/fstab.c 71579 2001-01-24 13:01:12Z deischen $";
42#endif
43#endif /* LIBC_SCCS and not lint */
44
45#include "namespace.h"
46#include <sys/param.h>
47#include <sys/mount.h>
48#include <sys/stat.h>
49
50#include <errno.h>
51#include <fstab.h>
52#include <paths.h>
53#include <stdio.h>
54#include <stdlib.h>
55#include <string.h>
56#include <unistd.h>
57#include "un-namespace.h"
58
59static FILE *_fs_fp;
60static struct fstab _fs_fstab;
61static int LineNo = 0;
62
63static void error __P((int));
64static void fixfsfile __P((void));
65static int fstabscan __P((void));
66
67static void
68fixfsfile()
69{
70	static char buf[sizeof(_PATH_DEV) + MNAMELEN];
71	struct stat sb;
72	struct statfs sf;
73
74	if (strcmp(_fs_fstab.fs_file, "/") != 0)
75		return;
76	if (statfs("/", &sf) != 0)
77		return;
78	if (sf.f_mntfromname[0] == '/')
79		buf[0] = '\0';
80	else
81		strcpy(buf, _PATH_DEV);
82	strcat(buf, sf.f_mntfromname);
83	if (stat(buf, &sb) != 0 ||
84	    (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)))
85		return;
86	_fs_fstab.fs_spec = buf;
87}
88
89static int
90fstabscan()
91{
92	char *cp, *p;
93#define	MAXLINELENGTH	1024
94	static char line[MAXLINELENGTH];
95	char subline[MAXLINELENGTH];
96	int typexx;
97
98	for (;;) {
99
100		if (!(p = fgets(line, sizeof(line), _fs_fp)))
101			return(0);
102/* OLD_STYLE_FSTAB */
103		++LineNo;
104		if (*line == '#' || *line == '\n')
105			continue;
106		if (!strpbrk(p, " \t")) {
107			_fs_fstab.fs_spec = strsep(&p, ":\n");
108			_fs_fstab.fs_file = strsep(&p, ":\n");
109			fixfsfile();
110			_fs_fstab.fs_type = strsep(&p, ":\n");
111			if (_fs_fstab.fs_type) {
112				if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
113					continue;
114				_fs_fstab.fs_mntops = _fs_fstab.fs_type;
115				_fs_fstab.fs_vfstype =
116				    strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
117				    "ufs" : "swap";
118				if ((cp = strsep(&p, ":\n")) != NULL) {
119					_fs_fstab.fs_freq = atoi(cp);
120					if ((cp = strsep(&p, ":\n")) != NULL) {
121						_fs_fstab.fs_passno = atoi(cp);
122						return(1);
123					}
124				}
125			}
126			goto bad;
127		}
128/* OLD_STYLE_FSTAB */
129		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
130			;
131		_fs_fstab.fs_spec = cp;
132		if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
133			continue;
134		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
135			;
136		_fs_fstab.fs_file = cp;
137		fixfsfile();
138		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
139			;
140		_fs_fstab.fs_vfstype = cp;
141		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
142			;
143		_fs_fstab.fs_mntops = cp;
144		if (_fs_fstab.fs_mntops == NULL)
145			goto bad;
146		_fs_fstab.fs_freq = 0;
147		_fs_fstab.fs_passno = 0;
148		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
149			;
150		if (cp != NULL) {
151			_fs_fstab.fs_freq = atoi(cp);
152			while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
153				;
154			if (cp != NULL)
155				_fs_fstab.fs_passno = atoi(cp);
156		}
157		strcpy(subline, _fs_fstab.fs_mntops);
158		p = subline;
159		for (typexx = 0, cp = strsep(&p, ","); cp;
160		     cp = strsep(&p, ",")) {
161			if (strlen(cp) != 2)
162				continue;
163			if (!strcmp(cp, FSTAB_RW)) {
164				_fs_fstab.fs_type = FSTAB_RW;
165				break;
166			}
167			if (!strcmp(cp, FSTAB_RQ)) {
168				_fs_fstab.fs_type = FSTAB_RQ;
169				break;
170			}
171			if (!strcmp(cp, FSTAB_RO)) {
172				_fs_fstab.fs_type = FSTAB_RO;
173				break;
174			}
175			if (!strcmp(cp, FSTAB_SW)) {
176				_fs_fstab.fs_type = FSTAB_SW;
177				break;
178			}
179			if (!strcmp(cp, FSTAB_XX)) {
180				_fs_fstab.fs_type = FSTAB_XX;
181				typexx++;
182				break;
183			}
184		}
185		if (typexx)
186			continue;
187		if (cp != NULL)
188			return(1);
189
190bad:		/* no way to distinguish between EOF and syntax error */
191		error(EFTYPE);
192	}
193	/* NOTREACHED */
194}
195
196struct fstab *
197getfsent()
198{
199	if ((!_fs_fp && !setfsent()) || !fstabscan())
200		return((struct fstab *)NULL);
201	return(&_fs_fstab);
202}
203
204struct fstab *
205getfsspec(name)
206	register const char *name;
207{
208	if (setfsent())
209		while (fstabscan())
210			if (!strcmp(_fs_fstab.fs_spec, name))
211				return(&_fs_fstab);
212	return((struct fstab *)NULL);
213}
214
215struct fstab *
216getfsfile(name)
217	register const char *name;
218{
219	if (setfsent())
220		while (fstabscan())
221			if (!strcmp(_fs_fstab.fs_file, name))
222				return(&_fs_fstab);
223	return((struct fstab *)NULL);
224}
225
226int
227setfsent()
228{
229	if (_fs_fp) {
230		rewind(_fs_fp);
231		LineNo = 0;
232		return(1);
233	}
234	if ((_fs_fp = fopen(_PATH_FSTAB, "r")) != NULL) {
235		LineNo = 0;
236		return(1);
237	}
238	error(errno);
239	return(0);
240}
241
242void
243endfsent()
244{
245	if (_fs_fp) {
246		(void)fclose(_fs_fp);
247		_fs_fp = NULL;
248	}
249}
250
251static void
252error(err)
253	int err;
254{
255	char *p;
256	char num[30];
257
258	(void)_write(STDERR_FILENO, "fstab: ", 7);
259	(void)_write(STDERR_FILENO, _PATH_FSTAB, sizeof(_PATH_FSTAB) - 1);
260	(void)_write(STDERR_FILENO, ":", 1);
261	sprintf(num, "%d: ", LineNo);
262	(void)_write(STDERR_FILENO, num, strlen(num));
263	p = strerror(err);
264	(void)_write(STDERR_FILENO, p, strlen(p));
265	(void)_write(STDERR_FILENO, "\n", 1);
266}
267