fstab.c revision 243865
1130561Sobrien/*
2130561Sobrien * Copyright (c) 1980, 1988, 1993
3130561Sobrien *	The Regents of the University of California.  All rights reserved.
4130561Sobrien *
5130561Sobrien * Redistribution and use in source and binary forms, with or without
6130561Sobrien * modification, are permitted provided that the following conditions
7130561Sobrien * are met:
8130561Sobrien * 1. Redistributions of source code must retain the above copyright
9130561Sobrien *    notice, this list of conditions and the following disclaimer.
10130561Sobrien * 2. Redistributions in binary form must reproduce the above copyright
11130561Sobrien *    notice, this list of conditions and the following disclaimer in the
12130561Sobrien *    documentation and/or other materials provided with the distribution.
13130561Sobrien * 4. Neither the name of the University nor the names of its contributors
14130561Sobrien *    may be used to endorse or promote products derived from this software
15130561Sobrien *    without specific prior written permission.
16130561Sobrien *
17130561Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18130561Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19130561Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20130561Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21130561Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22130561Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23130561Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24130561Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25130561Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26130561Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27130561Sobrien * SUCH DAMAGE.
28130561Sobrien */
29130561Sobrien
30130561Sobrien#if defined(LIBC_SCCS) && !defined(lint)
31130561Sobrienstatic char sccsid[] = "@(#)fstab.c	8.1 (Berkeley) 6/4/93";
32130561Sobrien#endif /* LIBC_SCCS and not lint */
33130561Sobrien#include <sys/cdefs.h>
34130561Sobrien__FBSDID("$FreeBSD: head/lib/libc/gen/fstab.c 243865 2012-12-04 16:54:43Z jilles $");
35130561Sobrien
36130561Sobrien#include "namespace.h"
37130561Sobrien#include <sys/param.h>
38130561Sobrien#include <sys/mount.h>
39130561Sobrien#include <sys/stat.h>
40130561Sobrien
41130561Sobrien#include <errno.h>
42130561Sobrien#include <fstab.h>
43130561Sobrien#include <paths.h>
44130561Sobrien#include <stdio.h>
45130561Sobrien#include <stdlib.h>
46130561Sobrien#include <string.h>
47130561Sobrien#include <unistd.h>
48130561Sobrien#include <vis.h>
49130561Sobrien#include "un-namespace.h"
50130561Sobrien
51130561Sobrienstatic FILE *_fs_fp;
52130561Sobrienstatic struct fstab _fs_fstab;
53130561Sobrienstatic int LineNo = 0;
54130561Sobrienstatic char *path_fstab;
55130561Sobrienstatic char fstab_path[PATH_MAX];
56130561Sobrienstatic int fsp_set = 0;
57130561Sobrien
58130561Sobrienstatic void error(int);
59130561Sobrienstatic void fixfsfile(void);
60130561Sobrienstatic int fstabscan(void);
61130561Sobrien
62130561Sobrienvoid
63130561Sobriensetfstab(const char *file)
64130561Sobrien{
65130561Sobrien
66130561Sobrien	if (file == NULL) {
67130561Sobrien		path_fstab = _PATH_FSTAB;
68130561Sobrien	} else {
69130561Sobrien		strncpy(fstab_path, file, PATH_MAX);
70130561Sobrien		fstab_path[PATH_MAX - 1] = '\0';
71130561Sobrien		path_fstab = fstab_path;
72130561Sobrien	}
73130561Sobrien	fsp_set = 1;
74130561Sobrien
75130561Sobrien	return;
76130561Sobrien}
77130561Sobrien
78130561Sobrienconst char *
79130561Sobriengetfstab(void)
80130561Sobrien{
81130561Sobrien
82130561Sobrien	if (fsp_set)
83130561Sobrien		return (path_fstab);
84130561Sobrien	else
85130561Sobrien		return (_PATH_FSTAB);
86130561Sobrien}
87130561Sobrien
88130561Sobrienstatic void
89130561Sobrienfixfsfile(void)
90130561Sobrien{
91130561Sobrien	static char buf[sizeof(_PATH_DEV) + MNAMELEN];
92130561Sobrien	struct stat sb;
93130561Sobrien	struct statfs sf;
94130561Sobrien
95130561Sobrien	if (_fs_fstab.fs_file != NULL && strcmp(_fs_fstab.fs_file, "/") != 0)
96130561Sobrien		return;
97130561Sobrien	if (statfs("/", &sf) != 0)
98130561Sobrien		return;
99130561Sobrien	if (sf.f_mntfromname[0] == '/')
100130561Sobrien		buf[0] = '\0';
101130561Sobrien	else
102130561Sobrien		strcpy(buf, _PATH_DEV);
103130561Sobrien	strcat(buf, sf.f_mntfromname);
104130561Sobrien	if (stat(buf, &sb) != 0 ||
105130561Sobrien	    (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)))
106130561Sobrien		return;
107130561Sobrien	_fs_fstab.fs_spec = buf;
108130561Sobrien}
109130561Sobrien
110130561Sobrienstatic int
111130561Sobrienfstabscan(void)
112130561Sobrien{
113130561Sobrien	char *cp, *p;
114130561Sobrien#define	MAXLINELENGTH	1024
115130561Sobrien	static char line[MAXLINELENGTH];
116130561Sobrien	char subline[MAXLINELENGTH];
117130561Sobrien	int typexx;
118130561Sobrien
119130561Sobrien	for (;;) {
120130561Sobrien
121130561Sobrien		if (!(p = fgets(line, sizeof(line), _fs_fp)))
122130561Sobrien			return (0);
123130561Sobrien/* OLD_STYLE_FSTAB */
124130561Sobrien		++LineNo;
125130561Sobrien		if (*line == '#' || *line == '\n')
126130561Sobrien			continue;
127130561Sobrien		if (!strpbrk(p, " \t")) {
128130561Sobrien			_fs_fstab.fs_spec = strsep(&p, ":\n");
129130561Sobrien			_fs_fstab.fs_file = strsep(&p, ":\n");
130130561Sobrien			fixfsfile();
131130561Sobrien			_fs_fstab.fs_type = strsep(&p, ":\n");
132130561Sobrien			if (_fs_fstab.fs_type) {
133130561Sobrien				if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
134130561Sobrien					continue;
135130561Sobrien				_fs_fstab.fs_mntops = _fs_fstab.fs_type;
136130561Sobrien				_fs_fstab.fs_vfstype =
137130561Sobrien				    strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
138130561Sobrien				    "ufs" : "swap";
139130561Sobrien				if ((cp = strsep(&p, ":\n")) != NULL) {
140130561Sobrien					_fs_fstab.fs_freq = atoi(cp);
141130561Sobrien					if ((cp = strsep(&p, ":\n")) != NULL) {
142130561Sobrien						_fs_fstab.fs_passno = atoi(cp);
143130561Sobrien						return (1);
144130561Sobrien					}
145130561Sobrien				}
146130561Sobrien			}
147130561Sobrien			goto bad;
148130561Sobrien		}
149130561Sobrien/* OLD_STYLE_FSTAB */
150130561Sobrien		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
151130561Sobrien			;
152130561Sobrien		_fs_fstab.fs_spec = cp;
153130561Sobrien		if (_fs_fstab.fs_spec == NULL || *_fs_fstab.fs_spec == '#')
154130561Sobrien			continue;
155130561Sobrien		if (strunvis(_fs_fstab.fs_spec, _fs_fstab.fs_spec) < 0)
156130561Sobrien			goto bad;
157130561Sobrien		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
158130561Sobrien			;
159130561Sobrien		_fs_fstab.fs_file = cp;
160130561Sobrien		if (_fs_fstab.fs_file == NULL)
161130561Sobrien			goto bad;
162130561Sobrien		if (strunvis(_fs_fstab.fs_file, _fs_fstab.fs_file) < 0)
163130561Sobrien			goto bad;
164130561Sobrien		fixfsfile();
165130561Sobrien		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
166130561Sobrien			;
167130561Sobrien		_fs_fstab.fs_vfstype = cp;
168130561Sobrien		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
169130561Sobrien			;
170130561Sobrien		_fs_fstab.fs_mntops = cp;
171130561Sobrien		if (_fs_fstab.fs_mntops == NULL)
172130561Sobrien			goto bad;
173130561Sobrien		_fs_fstab.fs_freq = 0;
174130561Sobrien		_fs_fstab.fs_passno = 0;
175130561Sobrien		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
176130561Sobrien			;
177130561Sobrien		if (cp != NULL) {
178130561Sobrien			_fs_fstab.fs_freq = atoi(cp);
179130561Sobrien			while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
180130561Sobrien				;
181130561Sobrien			if (cp != NULL)
182130561Sobrien				_fs_fstab.fs_passno = atoi(cp);
183130561Sobrien		}
184130561Sobrien		strcpy(subline, _fs_fstab.fs_mntops);
185130561Sobrien		p = subline;
186130561Sobrien		for (typexx = 0, cp = strsep(&p, ","); cp;
187130561Sobrien		     cp = strsep(&p, ",")) {
188130561Sobrien			if (strlen(cp) != 2)
189130561Sobrien				continue;
190130561Sobrien			if (!strcmp(cp, FSTAB_RW)) {
191130561Sobrien				_fs_fstab.fs_type = FSTAB_RW;
192130561Sobrien				break;
193130561Sobrien			}
194130561Sobrien			if (!strcmp(cp, FSTAB_RQ)) {
195130561Sobrien				_fs_fstab.fs_type = FSTAB_RQ;
196130561Sobrien				break;
197130561Sobrien			}
198130561Sobrien			if (!strcmp(cp, FSTAB_RO)) {
199130561Sobrien				_fs_fstab.fs_type = FSTAB_RO;
200130561Sobrien				break;
201130561Sobrien			}
202130561Sobrien			if (!strcmp(cp, FSTAB_SW)) {
203130561Sobrien				_fs_fstab.fs_type = FSTAB_SW;
204130561Sobrien				break;
205130561Sobrien			}
206130561Sobrien			if (!strcmp(cp, FSTAB_XX)) {
207130561Sobrien				_fs_fstab.fs_type = FSTAB_XX;
208130561Sobrien				typexx++;
209130561Sobrien				break;
210130561Sobrien			}
211130561Sobrien		}
212130561Sobrien		if (typexx)
213130561Sobrien			continue;
214130561Sobrien		if (cp != NULL)
215130561Sobrien			return (1);
216130561Sobrien
217130561Sobrienbad:		/* no way to distinguish between EOF and syntax error */
218130561Sobrien		error(EFTYPE);
219130561Sobrien	}
220130561Sobrien	/* NOTREACHED */
221130561Sobrien}
222130561Sobrien
223130561Sobrienstruct fstab *
224130561Sobriengetfsent(void)
225130561Sobrien{
226130561Sobrien
227130561Sobrien	if ((!_fs_fp && !setfsent()) || !fstabscan())
228130561Sobrien		return (NULL);
229130561Sobrien	return (&_fs_fstab);
230130561Sobrien}
231130561Sobrien
232130561Sobrienstruct fstab *
233130561Sobriengetfsspec(const char *name)
234130561Sobrien{
235130561Sobrien
236130561Sobrien	if (setfsent())
237130561Sobrien		while (fstabscan())
238130561Sobrien			if (!strcmp(_fs_fstab.fs_spec, name))
239130561Sobrien				return (&_fs_fstab);
240130561Sobrien	return (NULL);
241130561Sobrien}
242130561Sobrien
243130561Sobrienstruct fstab *
244130561Sobriengetfsfile(const char *name)
245130561Sobrien{
246130561Sobrien
247130561Sobrien	if (setfsent())
248130561Sobrien		while (fstabscan())
249130561Sobrien			if (!strcmp(_fs_fstab.fs_file, name))
250130561Sobrien				return (&_fs_fstab);
251130561Sobrien	return (NULL);
252130561Sobrien}
253130561Sobrien
254130561Sobrienint
255130561Sobriensetfsent(void)
256130561Sobrien{
257130561Sobrien	if (_fs_fp) {
258130561Sobrien		rewind(_fs_fp);
259130561Sobrien		LineNo = 0;
260130561Sobrien		return (1);
261130561Sobrien	}
262130561Sobrien	if (fsp_set == 0) {
263130561Sobrien		if (issetugid())
264130561Sobrien			setfstab(NULL);
265130561Sobrien		else
266130561Sobrien			setfstab(getenv("PATH_FSTAB"));
267130561Sobrien	}
268130561Sobrien	if ((_fs_fp = fopen(path_fstab, "re")) != NULL) {
269130561Sobrien		LineNo = 0;
270130561Sobrien		return (1);
271130561Sobrien	}
272130561Sobrien	error(errno);
273130561Sobrien	return (0);
274130561Sobrien}
275130561Sobrien
276130561Sobrienvoid
277130561Sobrienendfsent(void)
278130561Sobrien{
279130561Sobrien
280130561Sobrien	if (_fs_fp) {
281130561Sobrien		(void)fclose(_fs_fp);
282130561Sobrien		_fs_fp = NULL;
283130561Sobrien	}
284130561Sobrien
285130561Sobrien	fsp_set = 0;
286130561Sobrien}
287130561Sobrien
288130561Sobrienstatic void
289130561Sobrienerror(int err)
290130561Sobrien{
291130561Sobrien	char *p;
292130561Sobrien	char num[30];
293130561Sobrien
294130561Sobrien	(void)_write(STDERR_FILENO, "fstab: ", 7);
295130561Sobrien	(void)_write(STDERR_FILENO, path_fstab, strlen(path_fstab));
296130561Sobrien	(void)_write(STDERR_FILENO, ":", 1);
297130561Sobrien	sprintf(num, "%d: ", LineNo);
298130561Sobrien	(void)_write(STDERR_FILENO, num, strlen(num));
299130561Sobrien	p = strerror(err);
300130561Sobrien	(void)_write(STDERR_FILENO, p, strlen(p));
301130561Sobrien	(void)_write(STDERR_FILENO, "\n", 1);
302130561Sobrien}
303130561Sobrien