fstab.c revision 256281
1227753Stheraven/*
2227753Stheraven * Copyright (c) 1980, 1988, 1993
3227753Stheraven *	The Regents of the University of California.  All rights reserved.
4227753Stheraven *
5227753Stheraven * Redistribution and use in source and binary forms, with or without
6227753Stheraven * modification, are permitted provided that the following conditions
7227753Stheraven * are met:
8227753Stheraven * 1. Redistributions of source code must retain the above copyright
9227753Stheraven *    notice, this list of conditions and the following disclaimer.
10227753Stheraven * 2. Redistributions in binary form must reproduce the above copyright
11232498Stheraven *    notice, this list of conditions and the following disclaimer in the
12232498Stheraven *    documentation and/or other materials provided with the distribution.
13232498Stheraven * 4. Neither the name of the University nor the names of its contributors
14232498Stheraven *    may be used to endorse or promote products derived from this software
15232498Stheraven *    without specific prior written permission.
16227753Stheraven *
17227753Stheraven * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18227753Stheraven * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19227753Stheraven * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20232498Stheraven * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21227753Stheraven * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22227753Stheraven * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23227753Stheraven * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24227753Stheraven * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25227753Stheraven * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26227753Stheraven * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27227753Stheraven * SUCH DAMAGE.
28227753Stheraven */
29227753Stheraven
30227753Stheraven#if defined(LIBC_SCCS) && !defined(lint)
31227753Stheravenstatic char sccsid[] = "@(#)fstab.c	8.1 (Berkeley) 6/4/93";
32227753Stheraven#endif /* LIBC_SCCS and not lint */
33227753Stheraven#include <sys/cdefs.h>
34227753Stheraven__FBSDID("$FreeBSD: stable/10/lib/libc/gen/fstab.c 243865 2012-12-04 16:54:43Z jilles $");
35227753Stheraven
36227753Stheraven#include "namespace.h"
37227753Stheraven#include <sys/param.h>
38227753Stheraven#include <sys/mount.h>
39227753Stheraven#include <sys/stat.h>
40227753Stheraven
41227753Stheraven#include <errno.h>
42227753Stheraven#include <fstab.h>
43227753Stheraven#include <paths.h>
44227753Stheraven#include <stdio.h>
45227753Stheraven#include <stdlib.h>
46227753Stheraven#include <string.h>
47227753Stheraven#include <unistd.h>
48227753Stheraven#include <vis.h>
49227753Stheraven#include "un-namespace.h"
50227753Stheraven
51227753Stheravenstatic FILE *_fs_fp;
52227753Stheravenstatic struct fstab _fs_fstab;
53227753Stheravenstatic int LineNo = 0;
54227753Stheravenstatic char *path_fstab;
55227753Stheravenstatic char fstab_path[PATH_MAX];
56227753Stheravenstatic int fsp_set = 0;
57227753Stheraven
58227753Stheravenstatic void error(int);
59227753Stheravenstatic void fixfsfile(void);
60227753Stheravenstatic int fstabscan(void);
61227753Stheraven
62227753Stheravenvoid
63227753Stheravensetfstab(const char *file)
64227753Stheraven{
65227753Stheraven
66227753Stheraven	if (file == NULL) {
67227753Stheraven		path_fstab = _PATH_FSTAB;
68227753Stheraven	} else {
69227753Stheraven		strncpy(fstab_path, file, PATH_MAX);
70227753Stheraven		fstab_path[PATH_MAX - 1] = '\0';
71227753Stheraven		path_fstab = fstab_path;
72227753Stheraven	}
73227753Stheraven	fsp_set = 1;
74227753Stheraven
75227753Stheraven	return;
76227753Stheraven}
77227753Stheraven
78227753Stheravenconst char *
79227753Stheravengetfstab(void)
80227753Stheraven{
81227753Stheraven
82227753Stheraven	if (fsp_set)
83227753Stheraven		return (path_fstab);
84227753Stheraven	else
85227753Stheraven		return (_PATH_FSTAB);
86227753Stheraven}
87227753Stheraven
88232498Stheravenstatic void
89232498Stheravenfixfsfile(void)
90227753Stheraven{
91227753Stheraven	static char buf[sizeof(_PATH_DEV) + MNAMELEN];
92227753Stheraven	struct stat sb;
93227753Stheraven	struct statfs sf;
94232498Stheraven
95232498Stheraven	if (_fs_fstab.fs_file != NULL && strcmp(_fs_fstab.fs_file, "/") != 0)
96227753Stheraven		return;
97227753Stheraven	if (statfs("/", &sf) != 0)
98227753Stheraven		return;
99227753Stheraven	if (sf.f_mntfromname[0] == '/')
100227753Stheraven		buf[0] = '\0';
101227753Stheraven	else
102227753Stheraven		strcpy(buf, _PATH_DEV);
103227753Stheraven	strcat(buf, sf.f_mntfromname);
104227753Stheraven	if (stat(buf, &sb) != 0 ||
105227753Stheraven	    (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)))
106227753Stheraven		return;
107227753Stheraven	_fs_fstab.fs_spec = buf;
108227753Stheraven}
109227753Stheraven
110227753Stheravenstatic int
111227753Stheravenfstabscan(void)
112250883Sed{
113250883Sed	char *cp, *p;
114250883Sed#define	MAXLINELENGTH	1024
115250883Sed	static char line[MAXLINELENGTH];
116227753Stheraven	char subline[MAXLINELENGTH];
117227753Stheraven	int typexx;
118227753Stheraven
119227753Stheraven	for (;;) {
120227753Stheraven
121227753Stheraven		if (!(p = fgets(line, sizeof(line), _fs_fp)))
122227753Stheraven			return (0);
123227753Stheraven/* OLD_STYLE_FSTAB */
124250883Sed		++LineNo;
125250883Sed		if (*line == '#' || *line == '\n')
126250883Sed			continue;
127250883Sed		if (!strpbrk(p, " \t")) {
128227753Stheraven			_fs_fstab.fs_spec = strsep(&p, ":\n");
129227753Stheraven			_fs_fstab.fs_file = strsep(&p, ":\n");
130227753Stheraven			fixfsfile();
131227753Stheraven			_fs_fstab.fs_type = strsep(&p, ":\n");
132227753Stheraven			if (_fs_fstab.fs_type) {
133227753Stheraven				if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
134227753Stheraven					continue;
135227753Stheraven				_fs_fstab.fs_mntops = _fs_fstab.fs_type;
136227753Stheraven				_fs_fstab.fs_vfstype =
137227753Stheraven				    strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
138227753Stheraven				    "ufs" : "swap";
139227753Stheraven				if ((cp = strsep(&p, ":\n")) != NULL) {
140227753Stheraven					_fs_fstab.fs_freq = atoi(cp);
141227753Stheraven					if ((cp = strsep(&p, ":\n")) != NULL) {
142227753Stheraven						_fs_fstab.fs_passno = atoi(cp);
143227753Stheraven						return (1);
144227753Stheraven					}
145227753Stheraven				}
146227753Stheraven			}
147227753Stheraven			goto bad;
148227753Stheraven		}
149227753Stheraven/* OLD_STYLE_FSTAB */
150227753Stheraven		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
151227753Stheraven			;
152227753Stheraven		_fs_fstab.fs_spec = cp;
153227753Stheraven		if (_fs_fstab.fs_spec == NULL || *_fs_fstab.fs_spec == '#')
154227753Stheraven			continue;
155227753Stheraven		if (strunvis(_fs_fstab.fs_spec, _fs_fstab.fs_spec) < 0)
156227753Stheraven			goto bad;
157227753Stheraven		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
158309485Sngie			;
159309485Sngie		_fs_fstab.fs_file = cp;
160309485Sngie		if (_fs_fstab.fs_file == NULL)
161309485Sngie			goto bad;
162309485Sngie		if (strunvis(_fs_fstab.fs_file, _fs_fstab.fs_file) < 0)
163227753Stheraven			goto bad;
164227753Stheraven		fixfsfile();
165227753Stheraven		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
166227753Stheraven			;
167227753Stheraven		_fs_fstab.fs_vfstype = cp;
168227753Stheraven		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
169227753Stheraven			;
170227753Stheraven		_fs_fstab.fs_mntops = cp;
171227753Stheraven		if (_fs_fstab.fs_mntops == NULL)
172227753Stheraven			goto bad;
173227753Stheraven		_fs_fstab.fs_freq = 0;
174227753Stheraven		_fs_fstab.fs_passno = 0;
175227753Stheraven		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
176227753Stheraven			;
177227753Stheraven		if (cp != NULL) {
178227753Stheraven			_fs_fstab.fs_freq = atoi(cp);
179227753Stheraven			while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
180232498Stheraven				;
181232498Stheraven			if (cp != NULL)
182232498Stheraven				_fs_fstab.fs_passno = atoi(cp);
183232498Stheraven		}
184232498Stheraven		strcpy(subline, _fs_fstab.fs_mntops);
185232498Stheraven		p = subline;
186232498Stheraven		for (typexx = 0, cp = strsep(&p, ","); cp;
187232498Stheraven		     cp = strsep(&p, ",")) {
188232498Stheraven			if (strlen(cp) != 2)
189232498Stheraven				continue;
190232498Stheraven			if (!strcmp(cp, FSTAB_RW)) {
191232498Stheraven				_fs_fstab.fs_type = FSTAB_RW;
192232498Stheraven				break;
193232498Stheraven			}
194232498Stheraven			if (!strcmp(cp, FSTAB_RQ)) {
195232498Stheraven				_fs_fstab.fs_type = FSTAB_RQ;
196227753Stheraven				break;
197227753Stheraven			}
198227753Stheraven			if (!strcmp(cp, FSTAB_RO)) {
199227753Stheraven				_fs_fstab.fs_type = FSTAB_RO;
200227753Stheraven				break;
201233173Stheraven			}
202232498Stheraven			if (!strcmp(cp, FSTAB_SW)) {
203232498Stheraven				_fs_fstab.fs_type = FSTAB_SW;
204232498Stheraven				break;
205232498Stheraven			}
206232498Stheraven			if (!strcmp(cp, FSTAB_XX)) {
207232498Stheraven				_fs_fstab.fs_type = FSTAB_XX;
208232498Stheraven				typexx++;
209232498Stheraven				break;
210227753Stheraven			}
211232498Stheraven		}
212227753Stheraven		if (typexx)
213227753Stheraven			continue;
214227753Stheraven		if (cp != NULL)
215227753Stheraven			return (1);
216227753Stheraven
217227753Stheravenbad:		/* no way to distinguish between EOF and syntax error */
218227753Stheraven		error(EFTYPE);
219227753Stheraven	}
220227753Stheraven	/* NOTREACHED */
221227753Stheraven}
222227753Stheraven
223227753Stheravenstruct fstab *
224227753Stheravengetfsent(void)
225227753Stheraven{
226227753Stheraven
227227753Stheraven	if ((!_fs_fp && !setfsent()) || !fstabscan())
228227753Stheraven		return (NULL);
229227753Stheraven	return (&_fs_fstab);
230227753Stheraven}
231227753Stheraven
232struct fstab *
233getfsspec(const char *name)
234{
235
236	if (setfsent())
237		while (fstabscan())
238			if (!strcmp(_fs_fstab.fs_spec, name))
239				return (&_fs_fstab);
240	return (NULL);
241}
242
243struct fstab *
244getfsfile(const char *name)
245{
246
247	if (setfsent())
248		while (fstabscan())
249			if (!strcmp(_fs_fstab.fs_file, name))
250				return (&_fs_fstab);
251	return (NULL);
252}
253
254int
255setfsent(void)
256{
257	if (_fs_fp) {
258		rewind(_fs_fp);
259		LineNo = 0;
260		return (1);
261	}
262	if (fsp_set == 0) {
263		if (issetugid())
264			setfstab(NULL);
265		else
266			setfstab(getenv("PATH_FSTAB"));
267	}
268	if ((_fs_fp = fopen(path_fstab, "re")) != NULL) {
269		LineNo = 0;
270		return (1);
271	}
272	error(errno);
273	return (0);
274}
275
276void
277endfsent(void)
278{
279
280	if (_fs_fp) {
281		(void)fclose(_fs_fp);
282		_fs_fp = NULL;
283	}
284
285	fsp_set = 0;
286}
287
288static void
289error(int err)
290{
291	char *p;
292	char num[30];
293
294	(void)_write(STDERR_FILENO, "fstab: ", 7);
295	(void)_write(STDERR_FILENO, path_fstab, strlen(path_fstab));
296	(void)_write(STDERR_FILENO, ":", 1);
297	sprintf(num, "%d: ", LineNo);
298	(void)_write(STDERR_FILENO, num, strlen(num));
299	p = strerror(err);
300	(void)_write(STDERR_FILENO, p, strlen(p));
301	(void)_write(STDERR_FILENO, "\n", 1);
302}
303