xref: /freebsd/lib/libc/gen/fstab.c (revision dc36d6f9bb1753f3808552f3afd30eda9a7b206a)
18a16b7a1SPedro F. Giffuni /*-
28a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
38a16b7a1SPedro F. Giffuni  *
458f0484fSRodney W. Grimes  * Copyright (c) 1980, 1988, 1993
558f0484fSRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
658f0484fSRodney W. Grimes  *
758f0484fSRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
858f0484fSRodney W. Grimes  * modification, are permitted provided that the following conditions
958f0484fSRodney W. Grimes  * are met:
1058f0484fSRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
1158f0484fSRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
1258f0484fSRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
1358f0484fSRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
1458f0484fSRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
15fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
1658f0484fSRodney W. Grimes  *    may be used to endorse or promote products derived from this software
1758f0484fSRodney W. Grimes  *    without specific prior written permission.
1858f0484fSRodney W. Grimes  *
1958f0484fSRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2058f0484fSRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2158f0484fSRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2258f0484fSRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2358f0484fSRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2458f0484fSRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2558f0484fSRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2658f0484fSRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2758f0484fSRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2858f0484fSRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2958f0484fSRodney W. Grimes  * SUCH DAMAGE.
3058f0484fSRodney W. Grimes  */
3158f0484fSRodney W. Grimes 
32d201fe46SDaniel Eischen #include "namespace.h"
332e451399SBruce Evans #include <sys/param.h>
342e451399SBruce Evans #include <sys/mount.h>
352e451399SBruce Evans #include <sys/stat.h>
362e451399SBruce Evans 
3758f0484fSRodney W. Grimes #include <errno.h>
3858f0484fSRodney W. Grimes #include <fstab.h>
392e451399SBruce Evans #include <paths.h>
4058f0484fSRodney W. Grimes #include <stdio.h>
4158f0484fSRodney W. Grimes #include <stdlib.h>
4258f0484fSRodney W. Grimes #include <string.h>
4358f0484fSRodney W. Grimes #include <unistd.h>
44da087883SStefan Farfeleder #include <vis.h>
45d201fe46SDaniel Eischen #include "un-namespace.h"
4658f0484fSRodney W. Grimes 
4758f0484fSRodney W. Grimes static FILE *_fs_fp;
4858f0484fSRodney W. Grimes static struct fstab _fs_fstab;
492d4ee3eaSJordan K. Hubbard static int LineNo = 0;
50134dbc4cSMatthew N. Dodd static char *path_fstab;
51134dbc4cSMatthew N. Dodd static char fstab_path[PATH_MAX];
52134dbc4cSMatthew N. Dodd static int fsp_set = 0;
5358f0484fSRodney W. Grimes 
54b231cb39SDavid E. O'Brien static void error(int);
55b231cb39SDavid E. O'Brien static void fixfsfile(void);
56b231cb39SDavid E. O'Brien static int fstabscan(void);
5758f0484fSRodney W. Grimes 
58134dbc4cSMatthew N. Dodd void
setfstab(const char * file)59134dbc4cSMatthew N. Dodd setfstab(const char *file)
60134dbc4cSMatthew N. Dodd {
61134dbc4cSMatthew N. Dodd 
62134dbc4cSMatthew N. Dodd 	if (file == NULL) {
63134dbc4cSMatthew N. Dodd 		path_fstab = _PATH_FSTAB;
64134dbc4cSMatthew N. Dodd 	} else {
65134dbc4cSMatthew N. Dodd 		strncpy(fstab_path, file, PATH_MAX);
66134dbc4cSMatthew N. Dodd 		fstab_path[PATH_MAX - 1] = '\0';
67134dbc4cSMatthew N. Dodd 		path_fstab = fstab_path;
68134dbc4cSMatthew N. Dodd 	}
69134dbc4cSMatthew N. Dodd 	fsp_set = 1;
70134dbc4cSMatthew N. Dodd 
71134dbc4cSMatthew N. Dodd 	return;
72134dbc4cSMatthew N. Dodd }
73134dbc4cSMatthew N. Dodd 
74134dbc4cSMatthew N. Dodd const char *
getfstab(void)75134dbc4cSMatthew N. Dodd getfstab(void)
76134dbc4cSMatthew N. Dodd {
77134dbc4cSMatthew N. Dodd 
78134dbc4cSMatthew N. Dodd 	if (fsp_set)
79134dbc4cSMatthew N. Dodd 		return (path_fstab);
80134dbc4cSMatthew N. Dodd 	else
81134dbc4cSMatthew N. Dodd 		return (_PATH_FSTAB);
82134dbc4cSMatthew N. Dodd }
83134dbc4cSMatthew N. Dodd 
842e451399SBruce Evans static void
fixfsfile(void)85a31c8b58SStefan Farfeleder fixfsfile(void)
862e451399SBruce Evans {
872e451399SBruce Evans 	static char buf[sizeof(_PATH_DEV) + MNAMELEN];
882e451399SBruce Evans 	struct stat sb;
892e451399SBruce Evans 	struct statfs sf;
902e451399SBruce Evans 
91130b3430SSergey Kandaurov 	if (_fs_fstab.fs_file != NULL && strcmp(_fs_fstab.fs_file, "/") != 0)
922e451399SBruce Evans 		return;
932e451399SBruce Evans 	if (statfs("/", &sf) != 0)
942e451399SBruce Evans 		return;
952e451399SBruce Evans 	if (sf.f_mntfromname[0] == '/')
962e451399SBruce Evans 		buf[0] = '\0';
972e451399SBruce Evans 	else
982e451399SBruce Evans 		strcpy(buf, _PATH_DEV);
992e451399SBruce Evans 	strcat(buf, sf.f_mntfromname);
100473ee77fSPeter Wemm 	if (stat(buf, &sb) != 0 ||
101473ee77fSPeter Wemm 	    (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)))
1022e451399SBruce Evans 		return;
1032e451399SBruce Evans 	_fs_fstab.fs_spec = buf;
1042e451399SBruce Evans }
1052e451399SBruce Evans 
1068b102407SPoul-Henning Kamp static int
fstabscan(void)107a31c8b58SStefan Farfeleder fstabscan(void)
10858f0484fSRodney W. Grimes {
109bee5b8efSAndrey A. Chernov 	char *cp, *p;
11058f0484fSRodney W. Grimes #define	MAXLINELENGTH	1024
11158f0484fSRodney W. Grimes 	static char line[MAXLINELENGTH];
11258f0484fSRodney W. Grimes 	char subline[MAXLINELENGTH];
11358f0484fSRodney W. Grimes 	int typexx;
11458f0484fSRodney W. Grimes 
11558f0484fSRodney W. Grimes 	for (;;) {
1162d4ee3eaSJordan K. Hubbard 
117bee5b8efSAndrey A. Chernov 		if (!(p = fgets(line, sizeof(line), _fs_fp)))
11858f0484fSRodney W. Grimes 			return (0);
11958f0484fSRodney W. Grimes /* OLD_STYLE_FSTAB */
1202d4ee3eaSJordan K. Hubbard 		++LineNo;
1212d4ee3eaSJordan K. Hubbard 		if (*line == '#' || *line == '\n')
1222d4ee3eaSJordan K. Hubbard 			continue;
123bee5b8efSAndrey A. Chernov 		if (!strpbrk(p, " \t")) {
124bee5b8efSAndrey A. Chernov 			_fs_fstab.fs_spec = strsep(&p, ":\n");
125bee5b8efSAndrey A. Chernov 			_fs_fstab.fs_file = strsep(&p, ":\n");
1262e451399SBruce Evans 			fixfsfile();
127bee5b8efSAndrey A. Chernov 			_fs_fstab.fs_type = strsep(&p, ":\n");
12858f0484fSRodney W. Grimes 			if (_fs_fstab.fs_type) {
12958f0484fSRodney W. Grimes 				if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
13058f0484fSRodney W. Grimes 					continue;
13158f0484fSRodney W. Grimes 				_fs_fstab.fs_mntops = _fs_fstab.fs_type;
13258f0484fSRodney W. Grimes 				_fs_fstab.fs_vfstype =
13358f0484fSRodney W. Grimes 				    strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
13458f0484fSRodney W. Grimes 				    "ufs" : "swap";
1358b102407SPoul-Henning Kamp 				if ((cp = strsep(&p, ":\n")) != NULL) {
13658f0484fSRodney W. Grimes 					_fs_fstab.fs_freq = atoi(cp);
1378b102407SPoul-Henning Kamp 					if ((cp = strsep(&p, ":\n")) != NULL) {
13858f0484fSRodney W. Grimes 						_fs_fstab.fs_passno = atoi(cp);
13958f0484fSRodney W. Grimes 						return (1);
14058f0484fSRodney W. Grimes 					}
14158f0484fSRodney W. Grimes 				}
14258f0484fSRodney W. Grimes 			}
14358f0484fSRodney W. Grimes 			goto bad;
14458f0484fSRodney W. Grimes 		}
14558f0484fSRodney W. Grimes /* OLD_STYLE_FSTAB */
146bee5b8efSAndrey A. Chernov 		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
147bee5b8efSAndrey A. Chernov 			;
148bee5b8efSAndrey A. Chernov 		_fs_fstab.fs_spec = cp;
1491dcbb995SStefan Farfeleder 		if (_fs_fstab.fs_spec == NULL || *_fs_fstab.fs_spec == '#')
15058f0484fSRodney W. Grimes 			continue;
1511dcbb995SStefan Farfeleder 		if (strunvis(_fs_fstab.fs_spec, _fs_fstab.fs_spec) < 0)
1521dcbb995SStefan Farfeleder 			goto bad;
153bee5b8efSAndrey A. Chernov 		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
154bee5b8efSAndrey A. Chernov 			;
155bee5b8efSAndrey A. Chernov 		_fs_fstab.fs_file = cp;
1561dcbb995SStefan Farfeleder 		if (_fs_fstab.fs_file == NULL)
1571dcbb995SStefan Farfeleder 			goto bad;
1581dcbb995SStefan Farfeleder 		if (strunvis(_fs_fstab.fs_file, _fs_fstab.fs_file) < 0)
1591dcbb995SStefan Farfeleder 			goto bad;
1602e451399SBruce Evans 		fixfsfile();
161bee5b8efSAndrey A. Chernov 		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
162bee5b8efSAndrey A. Chernov 			;
163bee5b8efSAndrey A. Chernov 		_fs_fstab.fs_vfstype = cp;
164bee5b8efSAndrey A. Chernov 		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
165bee5b8efSAndrey A. Chernov 			;
166bee5b8efSAndrey A. Chernov 		_fs_fstab.fs_mntops = cp;
16758f0484fSRodney W. Grimes 		if (_fs_fstab.fs_mntops == NULL)
16858f0484fSRodney W. Grimes 			goto bad;
16958f0484fSRodney W. Grimes 		_fs_fstab.fs_freq = 0;
17058f0484fSRodney W. Grimes 		_fs_fstab.fs_passno = 0;
171bee5b8efSAndrey A. Chernov 		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
172bee5b8efSAndrey A. Chernov 			;
173bee5b8efSAndrey A. Chernov 		if (cp != NULL) {
17458f0484fSRodney W. Grimes 			_fs_fstab.fs_freq = atoi(cp);
175bee5b8efSAndrey A. Chernov 			while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
176bee5b8efSAndrey A. Chernov 				;
177bee5b8efSAndrey A. Chernov 			if (cp != NULL)
17858f0484fSRodney W. Grimes 				_fs_fstab.fs_passno = atoi(cp);
17958f0484fSRodney W. Grimes 		}
18078a452c3SPedro F. Giffuni 		(void)strlcpy(subline, _fs_fstab.fs_mntops, sizeof(subline));
181bee5b8efSAndrey A. Chernov 		p = subline;
182bee5b8efSAndrey A. Chernov 		for (typexx = 0, cp = strsep(&p, ","); cp;
183bee5b8efSAndrey A. Chernov 		     cp = strsep(&p, ",")) {
18458f0484fSRodney W. Grimes 			if (strlen(cp) != 2)
18558f0484fSRodney W. Grimes 				continue;
18658f0484fSRodney W. Grimes 			if (!strcmp(cp, FSTAB_RW)) {
18758f0484fSRodney W. Grimes 				_fs_fstab.fs_type = FSTAB_RW;
18858f0484fSRodney W. Grimes 				break;
18958f0484fSRodney W. Grimes 			}
19058f0484fSRodney W. Grimes 			if (!strcmp(cp, FSTAB_RQ)) {
19158f0484fSRodney W. Grimes 				_fs_fstab.fs_type = FSTAB_RQ;
19258f0484fSRodney W. Grimes 				break;
19358f0484fSRodney W. Grimes 			}
19458f0484fSRodney W. Grimes 			if (!strcmp(cp, FSTAB_RO)) {
19558f0484fSRodney W. Grimes 				_fs_fstab.fs_type = FSTAB_RO;
19658f0484fSRodney W. Grimes 				break;
19758f0484fSRodney W. Grimes 			}
19858f0484fSRodney W. Grimes 			if (!strcmp(cp, FSTAB_SW)) {
19958f0484fSRodney W. Grimes 				_fs_fstab.fs_type = FSTAB_SW;
20058f0484fSRodney W. Grimes 				break;
20158f0484fSRodney W. Grimes 			}
20258f0484fSRodney W. Grimes 			if (!strcmp(cp, FSTAB_XX)) {
20358f0484fSRodney W. Grimes 				_fs_fstab.fs_type = FSTAB_XX;
20458f0484fSRodney W. Grimes 				typexx++;
20558f0484fSRodney W. Grimes 				break;
20658f0484fSRodney W. Grimes 			}
20758f0484fSRodney W. Grimes 		}
20858f0484fSRodney W. Grimes 		if (typexx)
20958f0484fSRodney W. Grimes 			continue;
21058f0484fSRodney W. Grimes 		if (cp != NULL)
21158f0484fSRodney W. Grimes 			return (1);
21258f0484fSRodney W. Grimes 
21358f0484fSRodney W. Grimes bad:		/* no way to distinguish between EOF and syntax error */
21458f0484fSRodney W. Grimes 		error(EFTYPE);
21558f0484fSRodney W. Grimes 	}
21658f0484fSRodney W. Grimes 	/* NOTREACHED */
21758f0484fSRodney W. Grimes }
21858f0484fSRodney W. Grimes 
21958f0484fSRodney W. Grimes struct fstab *
getfsent(void)220a31c8b58SStefan Farfeleder getfsent(void)
22158f0484fSRodney W. Grimes {
222a31c8b58SStefan Farfeleder 
2238b102407SPoul-Henning Kamp 	if ((!_fs_fp && !setfsent()) || !fstabscan())
224a31c8b58SStefan Farfeleder 		return (NULL);
22558f0484fSRodney W. Grimes 	return (&_fs_fstab);
22658f0484fSRodney W. Grimes }
22758f0484fSRodney W. Grimes 
22858f0484fSRodney W. Grimes struct fstab *
getfsspec(const char * name)229a31c8b58SStefan Farfeleder getfsspec(const char *name)
23058f0484fSRodney W. Grimes {
231a31c8b58SStefan Farfeleder 
23258f0484fSRodney W. Grimes 	if (setfsent())
23358f0484fSRodney W. Grimes 		while (fstabscan())
23458f0484fSRodney W. Grimes 			if (!strcmp(_fs_fstab.fs_spec, name))
23558f0484fSRodney W. Grimes 				return (&_fs_fstab);
236a31c8b58SStefan Farfeleder 	return (NULL);
23758f0484fSRodney W. Grimes }
23858f0484fSRodney W. Grimes 
23958f0484fSRodney W. Grimes struct fstab *
getfsfile(const char * name)240a31c8b58SStefan Farfeleder getfsfile(const char *name)
24158f0484fSRodney W. Grimes {
242a31c8b58SStefan Farfeleder 
24358f0484fSRodney W. Grimes 	if (setfsent())
24458f0484fSRodney W. Grimes 		while (fstabscan())
24558f0484fSRodney W. Grimes 			if (!strcmp(_fs_fstab.fs_file, name))
24658f0484fSRodney W. Grimes 				return (&_fs_fstab);
247a31c8b58SStefan Farfeleder 	return (NULL);
24858f0484fSRodney W. Grimes }
24958f0484fSRodney W. Grimes 
2508b102407SPoul-Henning Kamp int
setfsent(void)251a31c8b58SStefan Farfeleder setfsent(void)
25258f0484fSRodney W. Grimes {
25358f0484fSRodney W. Grimes 	if (_fs_fp) {
25458f0484fSRodney W. Grimes 		rewind(_fs_fp);
2552d4ee3eaSJordan K. Hubbard 		LineNo = 0;
25658f0484fSRodney W. Grimes 		return (1);
25758f0484fSRodney W. Grimes 	}
258*68ca8363SMark Johnston 	if (fsp_set == 0)
259*68ca8363SMark Johnston 		setfstab(secure_getenv("PATH_FSTAB"));
260273e3bbfSJilles Tjoelker 	if ((_fs_fp = fopen(path_fstab, "re")) != NULL) {
2612d4ee3eaSJordan K. Hubbard 		LineNo = 0;
26258f0484fSRodney W. Grimes 		return (1);
2632d4ee3eaSJordan K. Hubbard 	}
26458f0484fSRodney W. Grimes 	error(errno);
26558f0484fSRodney W. Grimes 	return (0);
26658f0484fSRodney W. Grimes }
26758f0484fSRodney W. Grimes 
26858f0484fSRodney W. Grimes void
endfsent(void)269a31c8b58SStefan Farfeleder endfsent(void)
27058f0484fSRodney W. Grimes {
271a31c8b58SStefan Farfeleder 
27258f0484fSRodney W. Grimes 	if (_fs_fp) {
27358f0484fSRodney W. Grimes 		(void)fclose(_fs_fp);
27458f0484fSRodney W. Grimes 		_fs_fp = NULL;
27558f0484fSRodney W. Grimes 	}
276134dbc4cSMatthew N. Dodd 
277134dbc4cSMatthew N. Dodd 	fsp_set = 0;
27858f0484fSRodney W. Grimes }
27958f0484fSRodney W. Grimes 
2808b102407SPoul-Henning Kamp static void
error(int err)281a31c8b58SStefan Farfeleder error(int err)
28258f0484fSRodney W. Grimes {
28358f0484fSRodney W. Grimes 	char *p;
2842d4ee3eaSJordan K. Hubbard 	char num[30];
28558f0484fSRodney W. Grimes 
2869233c4d9SJason Evans 	(void)_write(STDERR_FILENO, "fstab: ", 7);
287134dbc4cSMatthew N. Dodd 	(void)_write(STDERR_FILENO, path_fstab, strlen(path_fstab));
2889233c4d9SJason Evans 	(void)_write(STDERR_FILENO, ":", 1);
2892d4ee3eaSJordan K. Hubbard 	sprintf(num, "%d: ", LineNo);
2909233c4d9SJason Evans 	(void)_write(STDERR_FILENO, num, strlen(num));
29158f0484fSRodney W. Grimes 	p = strerror(err);
2929233c4d9SJason Evans 	(void)_write(STDERR_FILENO, p, strlen(p));
2939233c4d9SJason Evans 	(void)_write(STDERR_FILENO, "\n", 1);
29458f0484fSRodney W. Grimes }
295