11573Srgrimes/*
21573Srgrimes * Copyright (c) 1980, 1988, 1993
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer.
101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer in the
121573Srgrimes *    documentation and/or other materials provided with the distribution.
131573Srgrimes * 4. Neither the name of the University nor the names of its contributors
141573Srgrimes *    may be used to endorse or promote products derived from this software
151573Srgrimes *    without specific prior written permission.
161573Srgrimes *
171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271573Srgrimes * SUCH DAMAGE.
281573Srgrimes */
291573Srgrimes
301573Srgrimes#if defined(LIBC_SCCS) && !defined(lint)
311573Srgrimesstatic char sccsid[] = "@(#)fstab.c	8.1 (Berkeley) 6/4/93";
321573Srgrimes#endif /* LIBC_SCCS and not lint */
3390045Sobrien#include <sys/cdefs.h>
3490045Sobrien__FBSDID("$FreeBSD$");
351573Srgrimes
3671579Sdeischen#include "namespace.h"
3742232Sbde#include <sys/param.h>
3842232Sbde#include <sys/mount.h>
3942232Sbde#include <sys/stat.h>
4042232Sbde
411573Srgrimes#include <errno.h>
421573Srgrimes#include <fstab.h>
4342232Sbde#include <paths.h>
441573Srgrimes#include <stdio.h>
451573Srgrimes#include <stdlib.h>
461573Srgrimes#include <string.h>
471573Srgrimes#include <unistd.h>
48241440Sstefanf#include <vis.h>
4971579Sdeischen#include "un-namespace.h"
501573Srgrimes
511573Srgrimesstatic FILE *_fs_fp;
521573Srgrimesstatic struct fstab _fs_fstab;
532569Sjkhstatic int LineNo = 0;
54113219Smdoddstatic char *path_fstab;
55113219Smdoddstatic char fstab_path[PATH_MAX];
56113219Smdoddstatic int fsp_set = 0;
571573Srgrimes
5890045Sobrienstatic void error(int);
5990045Sobrienstatic void fixfsfile(void);
6090045Sobrienstatic int fstabscan(void);
611573Srgrimes
62113219Smdoddvoid
63113219Smdoddsetfstab(const char *file)
64113219Smdodd{
65113219Smdodd
66113219Smdodd	if (file == NULL) {
67113219Smdodd		path_fstab = _PATH_FSTAB;
68113219Smdodd	} else {
69113219Smdodd		strncpy(fstab_path, file, PATH_MAX);
70113219Smdodd		fstab_path[PATH_MAX - 1] = '\0';
71113219Smdodd		path_fstab = fstab_path;
72113219Smdodd	}
73113219Smdodd	fsp_set = 1;
74113219Smdodd
75113219Smdodd	return;
76113219Smdodd}
77113219Smdodd
78113219Smdoddconst char *
79241439Sstefanfgetfstab(void)
80113219Smdodd{
81113219Smdodd
82113219Smdodd	if (fsp_set)
83113219Smdodd		return (path_fstab);
84113219Smdodd	else
85113219Smdodd		return (_PATH_FSTAB);
86113219Smdodd}
87113219Smdodd
8842232Sbdestatic void
89241439Sstefanffixfsfile(void)
9042232Sbde{
9142232Sbde	static char buf[sizeof(_PATH_DEV) + MNAMELEN];
9242232Sbde	struct stat sb;
9342232Sbde	struct statfs sf;
9442232Sbde
95233300Spluknet	if (_fs_fstab.fs_file != NULL && strcmp(_fs_fstab.fs_file, "/") != 0)
9642232Sbde		return;
9742232Sbde	if (statfs("/", &sf) != 0)
9842232Sbde		return;
9942232Sbde	if (sf.f_mntfromname[0] == '/')
10042232Sbde		buf[0] = '\0';
10142232Sbde	else
10242232Sbde		strcpy(buf, _PATH_DEV);
10342232Sbde	strcat(buf, sf.f_mntfromname);
10455028Speter	if (stat(buf, &sb) != 0 ||
10555028Speter	    (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)))
10642232Sbde		return;
10742232Sbde	_fs_fstab.fs_spec = buf;
10842232Sbde}
10942232Sbde
11011659Sphkstatic int
111241439Sstefanffstabscan(void)
1121573Srgrimes{
1137327Sache	char *cp, *p;
1141573Srgrimes#define	MAXLINELENGTH	1024
1151573Srgrimes	static char line[MAXLINELENGTH];
1161573Srgrimes	char subline[MAXLINELENGTH];
1171573Srgrimes	int typexx;
1181573Srgrimes
1191573Srgrimes	for (;;) {
1202569Sjkh
1217327Sache		if (!(p = fgets(line, sizeof(line), _fs_fp)))
122241439Sstefanf			return (0);
1231573Srgrimes/* OLD_STYLE_FSTAB */
1242569Sjkh		++LineNo;
1252569Sjkh		if (*line == '#' || *line == '\n')
1262569Sjkh			continue;
1277327Sache		if (!strpbrk(p, " \t")) {
1287327Sache			_fs_fstab.fs_spec = strsep(&p, ":\n");
1297327Sache			_fs_fstab.fs_file = strsep(&p, ":\n");
13042232Sbde			fixfsfile();
1317327Sache			_fs_fstab.fs_type = strsep(&p, ":\n");
1321573Srgrimes			if (_fs_fstab.fs_type) {
1331573Srgrimes				if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
1341573Srgrimes					continue;
1351573Srgrimes				_fs_fstab.fs_mntops = _fs_fstab.fs_type;
1361573Srgrimes				_fs_fstab.fs_vfstype =
1371573Srgrimes				    strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
1381573Srgrimes				    "ufs" : "swap";
13911659Sphk				if ((cp = strsep(&p, ":\n")) != NULL) {
1401573Srgrimes					_fs_fstab.fs_freq = atoi(cp);
14111659Sphk					if ((cp = strsep(&p, ":\n")) != NULL) {
1421573Srgrimes						_fs_fstab.fs_passno = atoi(cp);
143241439Sstefanf						return (1);
1441573Srgrimes					}
1451573Srgrimes				}
1461573Srgrimes			}
1471573Srgrimes			goto bad;
1481573Srgrimes		}
1491573Srgrimes/* OLD_STYLE_FSTAB */
1507327Sache		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
1517327Sache			;
1527327Sache		_fs_fstab.fs_spec = cp;
153241441Sstefanf		if (_fs_fstab.fs_spec == NULL || *_fs_fstab.fs_spec == '#')
1541573Srgrimes			continue;
155241441Sstefanf		if (strunvis(_fs_fstab.fs_spec, _fs_fstab.fs_spec) < 0)
156241441Sstefanf			goto bad;
1577327Sache		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
1587327Sache			;
159241441Sstefanf		_fs_fstab.fs_file = cp;
160241441Sstefanf		if (_fs_fstab.fs_file == NULL)
161241440Sstefanf			goto bad;
162241441Sstefanf		if (strunvis(_fs_fstab.fs_file, _fs_fstab.fs_file) < 0)
163241441Sstefanf			goto bad;
16442232Sbde		fixfsfile();
1657327Sache		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
1667327Sache			;
1677327Sache		_fs_fstab.fs_vfstype = cp;
1687327Sache		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
1697327Sache			;
1707327Sache		_fs_fstab.fs_mntops = cp;
1711573Srgrimes		if (_fs_fstab.fs_mntops == NULL)
1721573Srgrimes			goto bad;
1731573Srgrimes		_fs_fstab.fs_freq = 0;
1741573Srgrimes		_fs_fstab.fs_passno = 0;
1757327Sache		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
1767327Sache			;
1777327Sache		if (cp != NULL) {
1781573Srgrimes			_fs_fstab.fs_freq = atoi(cp);
1797327Sache			while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
1807327Sache				;
1817327Sache			if (cp != NULL)
1821573Srgrimes				_fs_fstab.fs_passno = atoi(cp);
1831573Srgrimes		}
1841573Srgrimes		strcpy(subline, _fs_fstab.fs_mntops);
1857327Sache		p = subline;
1867327Sache		for (typexx = 0, cp = strsep(&p, ","); cp;
1877327Sache		     cp = strsep(&p, ",")) {
1881573Srgrimes			if (strlen(cp) != 2)
1891573Srgrimes				continue;
1901573Srgrimes			if (!strcmp(cp, FSTAB_RW)) {
1911573Srgrimes				_fs_fstab.fs_type = FSTAB_RW;
1921573Srgrimes				break;
1931573Srgrimes			}
1941573Srgrimes			if (!strcmp(cp, FSTAB_RQ)) {
1951573Srgrimes				_fs_fstab.fs_type = FSTAB_RQ;
1961573Srgrimes				break;
1971573Srgrimes			}
1981573Srgrimes			if (!strcmp(cp, FSTAB_RO)) {
1991573Srgrimes				_fs_fstab.fs_type = FSTAB_RO;
2001573Srgrimes				break;
2011573Srgrimes			}
2021573Srgrimes			if (!strcmp(cp, FSTAB_SW)) {
2031573Srgrimes				_fs_fstab.fs_type = FSTAB_SW;
2041573Srgrimes				break;
2051573Srgrimes			}
2061573Srgrimes			if (!strcmp(cp, FSTAB_XX)) {
2071573Srgrimes				_fs_fstab.fs_type = FSTAB_XX;
2081573Srgrimes				typexx++;
2091573Srgrimes				break;
2101573Srgrimes			}
2111573Srgrimes		}
2121573Srgrimes		if (typexx)
2131573Srgrimes			continue;
2141573Srgrimes		if (cp != NULL)
215241439Sstefanf			return (1);
2161573Srgrimes
2171573Srgrimesbad:		/* no way to distinguish between EOF and syntax error */
2181573Srgrimes		error(EFTYPE);
2191573Srgrimes	}
2201573Srgrimes	/* NOTREACHED */
2211573Srgrimes}
2221573Srgrimes
2231573Srgrimesstruct fstab *
224241439Sstefanfgetfsent(void)
2251573Srgrimes{
226241439Sstefanf
22711659Sphk	if ((!_fs_fp && !setfsent()) || !fstabscan())
228241439Sstefanf		return (NULL);
229241439Sstefanf	return (&_fs_fstab);
2301573Srgrimes}
2311573Srgrimes
2321573Srgrimesstruct fstab *
233241439Sstefanfgetfsspec(const char *name)
2341573Srgrimes{
235241439Sstefanf
2361573Srgrimes	if (setfsent())
2371573Srgrimes		while (fstabscan())
2381573Srgrimes			if (!strcmp(_fs_fstab.fs_spec, name))
239241439Sstefanf				return (&_fs_fstab);
240241439Sstefanf	return (NULL);
2411573Srgrimes}
2421573Srgrimes
2431573Srgrimesstruct fstab *
244241439Sstefanfgetfsfile(const char *name)
2451573Srgrimes{
246241439Sstefanf
2471573Srgrimes	if (setfsent())
2481573Srgrimes		while (fstabscan())
2491573Srgrimes			if (!strcmp(_fs_fstab.fs_file, name))
250241439Sstefanf				return (&_fs_fstab);
251241439Sstefanf	return (NULL);
2521573Srgrimes}
2531573Srgrimes
254241439Sstefanfint
255241439Sstefanfsetfsent(void)
2561573Srgrimes{
2571573Srgrimes	if (_fs_fp) {
2581573Srgrimes		rewind(_fs_fp);
2592569Sjkh		LineNo = 0;
260241439Sstefanf		return (1);
2611573Srgrimes	}
262113219Smdodd	if (fsp_set == 0) {
263113219Smdodd		if (issetugid())
264113219Smdodd			setfstab(NULL);
265113219Smdodd		else
266113219Smdodd			setfstab(getenv("PATH_FSTAB"));
267113219Smdodd	}
268243865Sjilles	if ((_fs_fp = fopen(path_fstab, "re")) != NULL) {
2692569Sjkh		LineNo = 0;
270241439Sstefanf		return (1);
2712569Sjkh	}
2721573Srgrimes	error(errno);
273241439Sstefanf	return (0);
2741573Srgrimes}
2751573Srgrimes
2761573Srgrimesvoid
277241439Sstefanfendfsent(void)
2781573Srgrimes{
279241439Sstefanf
2801573Srgrimes	if (_fs_fp) {
2811573Srgrimes		(void)fclose(_fs_fp);
2821573Srgrimes		_fs_fp = NULL;
2831573Srgrimes	}
284113219Smdodd
285113219Smdodd	fsp_set = 0;
2861573Srgrimes}
2871573Srgrimes
28811659Sphkstatic void
289241439Sstefanferror(int err)
2901573Srgrimes{
2911573Srgrimes	char *p;
2922569Sjkh	char num[30];
2931573Srgrimes
29456698Sjasone	(void)_write(STDERR_FILENO, "fstab: ", 7);
295113219Smdodd	(void)_write(STDERR_FILENO, path_fstab, strlen(path_fstab));
29656698Sjasone	(void)_write(STDERR_FILENO, ":", 1);
2972569Sjkh	sprintf(num, "%d: ", LineNo);
29856698Sjasone	(void)_write(STDERR_FILENO, num, strlen(num));
2991573Srgrimes	p = strerror(err);
30056698Sjasone	(void)_write(STDERR_FILENO, p, strlen(p));
30156698Sjasone	(void)_write(STDERR_FILENO, "\n", 1);
3021573Srgrimes}
303