xref: /freebsd/lib/libc/gen/fstab.c (revision 68ca8363c7a19d5351dc2b10568cbf2403e07e33)
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 
32b231cb39SDavid E. O'Brien #include <sys/cdefs.h>
33c1920558SJohn Baldwin __SCCSID("@(#)fstab.c	8.1 (Berkeley) 6/4/93");
34b231cb39SDavid E. O'Brien __FBSDID("$FreeBSD$");
3558f0484fSRodney W. Grimes 
36d201fe46SDaniel Eischen #include "namespace.h"
372e451399SBruce Evans #include <sys/param.h>
382e451399SBruce Evans #include <sys/mount.h>
392e451399SBruce Evans #include <sys/stat.h>
402e451399SBruce Evans 
4158f0484fSRodney W. Grimes #include <errno.h>
4258f0484fSRodney W. Grimes #include <fstab.h>
432e451399SBruce Evans #include <paths.h>
4458f0484fSRodney W. Grimes #include <stdio.h>
4558f0484fSRodney W. Grimes #include <stdlib.h>
4658f0484fSRodney W. Grimes #include <string.h>
4758f0484fSRodney W. Grimes #include <unistd.h>
48da087883SStefan Farfeleder #include <vis.h>
49d201fe46SDaniel Eischen #include "un-namespace.h"
5058f0484fSRodney W. Grimes 
5158f0484fSRodney W. Grimes static FILE *_fs_fp;
5258f0484fSRodney W. Grimes static struct fstab _fs_fstab;
532d4ee3eaSJordan K. Hubbard static int LineNo = 0;
54134dbc4cSMatthew N. Dodd static char *path_fstab;
55134dbc4cSMatthew N. Dodd static char fstab_path[PATH_MAX];
56134dbc4cSMatthew N. Dodd static int fsp_set = 0;
5758f0484fSRodney W. Grimes 
58b231cb39SDavid E. O'Brien static void error(int);
59b231cb39SDavid E. O'Brien static void fixfsfile(void);
60b231cb39SDavid E. O'Brien static int fstabscan(void);
6158f0484fSRodney W. Grimes 
62134dbc4cSMatthew N. Dodd void
63134dbc4cSMatthew N. Dodd setfstab(const char *file)
64134dbc4cSMatthew N. Dodd {
65134dbc4cSMatthew N. Dodd 
66134dbc4cSMatthew N. Dodd 	if (file == NULL) {
67134dbc4cSMatthew N. Dodd 		path_fstab = _PATH_FSTAB;
68134dbc4cSMatthew N. Dodd 	} else {
69134dbc4cSMatthew N. Dodd 		strncpy(fstab_path, file, PATH_MAX);
70134dbc4cSMatthew N. Dodd 		fstab_path[PATH_MAX - 1] = '\0';
71134dbc4cSMatthew N. Dodd 		path_fstab = fstab_path;
72134dbc4cSMatthew N. Dodd 	}
73134dbc4cSMatthew N. Dodd 	fsp_set = 1;
74134dbc4cSMatthew N. Dodd 
75134dbc4cSMatthew N. Dodd 	return;
76134dbc4cSMatthew N. Dodd }
77134dbc4cSMatthew N. Dodd 
78134dbc4cSMatthew N. Dodd const char *
79134dbc4cSMatthew N. Dodd getfstab(void)
80134dbc4cSMatthew N. Dodd {
81134dbc4cSMatthew N. Dodd 
82134dbc4cSMatthew N. Dodd 	if (fsp_set)
83134dbc4cSMatthew N. Dodd 		return (path_fstab);
84134dbc4cSMatthew N. Dodd 	else
85134dbc4cSMatthew N. Dodd 		return (_PATH_FSTAB);
86134dbc4cSMatthew N. Dodd }
87134dbc4cSMatthew N. Dodd 
882e451399SBruce Evans static void
89a31c8b58SStefan Farfeleder fixfsfile(void)
902e451399SBruce Evans {
912e451399SBruce Evans 	static char buf[sizeof(_PATH_DEV) + MNAMELEN];
922e451399SBruce Evans 	struct stat sb;
932e451399SBruce Evans 	struct statfs sf;
942e451399SBruce Evans 
95130b3430SSergey Kandaurov 	if (_fs_fstab.fs_file != NULL && strcmp(_fs_fstab.fs_file, "/") != 0)
962e451399SBruce Evans 		return;
972e451399SBruce Evans 	if (statfs("/", &sf) != 0)
982e451399SBruce Evans 		return;
992e451399SBruce Evans 	if (sf.f_mntfromname[0] == '/')
1002e451399SBruce Evans 		buf[0] = '\0';
1012e451399SBruce Evans 	else
1022e451399SBruce Evans 		strcpy(buf, _PATH_DEV);
1032e451399SBruce Evans 	strcat(buf, sf.f_mntfromname);
104473ee77fSPeter Wemm 	if (stat(buf, &sb) != 0 ||
105473ee77fSPeter Wemm 	    (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)))
1062e451399SBruce Evans 		return;
1072e451399SBruce Evans 	_fs_fstab.fs_spec = buf;
1082e451399SBruce Evans }
1092e451399SBruce Evans 
1108b102407SPoul-Henning Kamp static int
111a31c8b58SStefan Farfeleder fstabscan(void)
11258f0484fSRodney W. Grimes {
113bee5b8efSAndrey A. Chernov 	char *cp, *p;
11458f0484fSRodney W. Grimes #define	MAXLINELENGTH	1024
11558f0484fSRodney W. Grimes 	static char line[MAXLINELENGTH];
11658f0484fSRodney W. Grimes 	char subline[MAXLINELENGTH];
11758f0484fSRodney W. Grimes 	int typexx;
11858f0484fSRodney W. Grimes 
11958f0484fSRodney W. Grimes 	for (;;) {
1202d4ee3eaSJordan K. Hubbard 
121bee5b8efSAndrey A. Chernov 		if (!(p = fgets(line, sizeof(line), _fs_fp)))
12258f0484fSRodney W. Grimes 			return (0);
12358f0484fSRodney W. Grimes /* OLD_STYLE_FSTAB */
1242d4ee3eaSJordan K. Hubbard 		++LineNo;
1252d4ee3eaSJordan K. Hubbard 		if (*line == '#' || *line == '\n')
1262d4ee3eaSJordan K. Hubbard 			continue;
127bee5b8efSAndrey A. Chernov 		if (!strpbrk(p, " \t")) {
128bee5b8efSAndrey A. Chernov 			_fs_fstab.fs_spec = strsep(&p, ":\n");
129bee5b8efSAndrey A. Chernov 			_fs_fstab.fs_file = strsep(&p, ":\n");
1302e451399SBruce Evans 			fixfsfile();
131bee5b8efSAndrey A. Chernov 			_fs_fstab.fs_type = strsep(&p, ":\n");
13258f0484fSRodney W. Grimes 			if (_fs_fstab.fs_type) {
13358f0484fSRodney W. Grimes 				if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
13458f0484fSRodney W. Grimes 					continue;
13558f0484fSRodney W. Grimes 				_fs_fstab.fs_mntops = _fs_fstab.fs_type;
13658f0484fSRodney W. Grimes 				_fs_fstab.fs_vfstype =
13758f0484fSRodney W. Grimes 				    strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
13858f0484fSRodney W. Grimes 				    "ufs" : "swap";
1398b102407SPoul-Henning Kamp 				if ((cp = strsep(&p, ":\n")) != NULL) {
14058f0484fSRodney W. Grimes 					_fs_fstab.fs_freq = atoi(cp);
1418b102407SPoul-Henning Kamp 					if ((cp = strsep(&p, ":\n")) != NULL) {
14258f0484fSRodney W. Grimes 						_fs_fstab.fs_passno = atoi(cp);
14358f0484fSRodney W. Grimes 						return (1);
14458f0484fSRodney W. Grimes 					}
14558f0484fSRodney W. Grimes 				}
14658f0484fSRodney W. Grimes 			}
14758f0484fSRodney W. Grimes 			goto bad;
14858f0484fSRodney W. Grimes 		}
14958f0484fSRodney W. Grimes /* OLD_STYLE_FSTAB */
150bee5b8efSAndrey A. Chernov 		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
151bee5b8efSAndrey A. Chernov 			;
152bee5b8efSAndrey A. Chernov 		_fs_fstab.fs_spec = cp;
1531dcbb995SStefan Farfeleder 		if (_fs_fstab.fs_spec == NULL || *_fs_fstab.fs_spec == '#')
15458f0484fSRodney W. Grimes 			continue;
1551dcbb995SStefan Farfeleder 		if (strunvis(_fs_fstab.fs_spec, _fs_fstab.fs_spec) < 0)
1561dcbb995SStefan Farfeleder 			goto bad;
157bee5b8efSAndrey A. Chernov 		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
158bee5b8efSAndrey A. Chernov 			;
159bee5b8efSAndrey A. Chernov 		_fs_fstab.fs_file = cp;
1601dcbb995SStefan Farfeleder 		if (_fs_fstab.fs_file == NULL)
1611dcbb995SStefan Farfeleder 			goto bad;
1621dcbb995SStefan Farfeleder 		if (strunvis(_fs_fstab.fs_file, _fs_fstab.fs_file) < 0)
1631dcbb995SStefan Farfeleder 			goto bad;
1642e451399SBruce Evans 		fixfsfile();
165bee5b8efSAndrey A. Chernov 		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
166bee5b8efSAndrey A. Chernov 			;
167bee5b8efSAndrey A. Chernov 		_fs_fstab.fs_vfstype = cp;
168bee5b8efSAndrey A. Chernov 		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
169bee5b8efSAndrey A. Chernov 			;
170bee5b8efSAndrey A. Chernov 		_fs_fstab.fs_mntops = cp;
17158f0484fSRodney W. Grimes 		if (_fs_fstab.fs_mntops == NULL)
17258f0484fSRodney W. Grimes 			goto bad;
17358f0484fSRodney W. Grimes 		_fs_fstab.fs_freq = 0;
17458f0484fSRodney W. Grimes 		_fs_fstab.fs_passno = 0;
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_freq = atoi(cp);
179bee5b8efSAndrey A. Chernov 			while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
180bee5b8efSAndrey A. Chernov 				;
181bee5b8efSAndrey A. Chernov 			if (cp != NULL)
18258f0484fSRodney W. Grimes 				_fs_fstab.fs_passno = atoi(cp);
18358f0484fSRodney W. Grimes 		}
18478a452c3SPedro F. Giffuni 		(void)strlcpy(subline, _fs_fstab.fs_mntops, sizeof(subline));
185bee5b8efSAndrey A. Chernov 		p = subline;
186bee5b8efSAndrey A. Chernov 		for (typexx = 0, cp = strsep(&p, ","); cp;
187bee5b8efSAndrey A. Chernov 		     cp = strsep(&p, ",")) {
18858f0484fSRodney W. Grimes 			if (strlen(cp) != 2)
18958f0484fSRodney W. Grimes 				continue;
19058f0484fSRodney W. Grimes 			if (!strcmp(cp, FSTAB_RW)) {
19158f0484fSRodney W. Grimes 				_fs_fstab.fs_type = FSTAB_RW;
19258f0484fSRodney W. Grimes 				break;
19358f0484fSRodney W. Grimes 			}
19458f0484fSRodney W. Grimes 			if (!strcmp(cp, FSTAB_RQ)) {
19558f0484fSRodney W. Grimes 				_fs_fstab.fs_type = FSTAB_RQ;
19658f0484fSRodney W. Grimes 				break;
19758f0484fSRodney W. Grimes 			}
19858f0484fSRodney W. Grimes 			if (!strcmp(cp, FSTAB_RO)) {
19958f0484fSRodney W. Grimes 				_fs_fstab.fs_type = FSTAB_RO;
20058f0484fSRodney W. Grimes 				break;
20158f0484fSRodney W. Grimes 			}
20258f0484fSRodney W. Grimes 			if (!strcmp(cp, FSTAB_SW)) {
20358f0484fSRodney W. Grimes 				_fs_fstab.fs_type = FSTAB_SW;
20458f0484fSRodney W. Grimes 				break;
20558f0484fSRodney W. Grimes 			}
20658f0484fSRodney W. Grimes 			if (!strcmp(cp, FSTAB_XX)) {
20758f0484fSRodney W. Grimes 				_fs_fstab.fs_type = FSTAB_XX;
20858f0484fSRodney W. Grimes 				typexx++;
20958f0484fSRodney W. Grimes 				break;
21058f0484fSRodney W. Grimes 			}
21158f0484fSRodney W. Grimes 		}
21258f0484fSRodney W. Grimes 		if (typexx)
21358f0484fSRodney W. Grimes 			continue;
21458f0484fSRodney W. Grimes 		if (cp != NULL)
21558f0484fSRodney W. Grimes 			return (1);
21658f0484fSRodney W. Grimes 
21758f0484fSRodney W. Grimes bad:		/* no way to distinguish between EOF and syntax error */
21858f0484fSRodney W. Grimes 		error(EFTYPE);
21958f0484fSRodney W. Grimes 	}
22058f0484fSRodney W. Grimes 	/* NOTREACHED */
22158f0484fSRodney W. Grimes }
22258f0484fSRodney W. Grimes 
22358f0484fSRodney W. Grimes struct fstab *
224a31c8b58SStefan Farfeleder getfsent(void)
22558f0484fSRodney W. Grimes {
226a31c8b58SStefan Farfeleder 
2278b102407SPoul-Henning Kamp 	if ((!_fs_fp && !setfsent()) || !fstabscan())
228a31c8b58SStefan Farfeleder 		return (NULL);
22958f0484fSRodney W. Grimes 	return (&_fs_fstab);
23058f0484fSRodney W. Grimes }
23158f0484fSRodney W. Grimes 
23258f0484fSRodney W. Grimes struct fstab *
233a31c8b58SStefan Farfeleder getfsspec(const char *name)
23458f0484fSRodney W. Grimes {
235a31c8b58SStefan Farfeleder 
23658f0484fSRodney W. Grimes 	if (setfsent())
23758f0484fSRodney W. Grimes 		while (fstabscan())
23858f0484fSRodney W. Grimes 			if (!strcmp(_fs_fstab.fs_spec, name))
23958f0484fSRodney W. Grimes 				return (&_fs_fstab);
240a31c8b58SStefan Farfeleder 	return (NULL);
24158f0484fSRodney W. Grimes }
24258f0484fSRodney W. Grimes 
24358f0484fSRodney W. Grimes struct fstab *
244a31c8b58SStefan Farfeleder getfsfile(const char *name)
24558f0484fSRodney W. Grimes {
246a31c8b58SStefan Farfeleder 
24758f0484fSRodney W. Grimes 	if (setfsent())
24858f0484fSRodney W. Grimes 		while (fstabscan())
24958f0484fSRodney W. Grimes 			if (!strcmp(_fs_fstab.fs_file, name))
25058f0484fSRodney W. Grimes 				return (&_fs_fstab);
251a31c8b58SStefan Farfeleder 	return (NULL);
25258f0484fSRodney W. Grimes }
25358f0484fSRodney W. Grimes 
2548b102407SPoul-Henning Kamp int
255a31c8b58SStefan Farfeleder setfsent(void)
25658f0484fSRodney W. Grimes {
25758f0484fSRodney W. Grimes 	if (_fs_fp) {
25858f0484fSRodney W. Grimes 		rewind(_fs_fp);
2592d4ee3eaSJordan K. Hubbard 		LineNo = 0;
26058f0484fSRodney W. Grimes 		return (1);
26158f0484fSRodney W. Grimes 	}
262*68ca8363SMark Johnston 	if (fsp_set == 0)
263*68ca8363SMark Johnston 		setfstab(secure_getenv("PATH_FSTAB"));
264273e3bbfSJilles Tjoelker 	if ((_fs_fp = fopen(path_fstab, "re")) != NULL) {
2652d4ee3eaSJordan K. Hubbard 		LineNo = 0;
26658f0484fSRodney W. Grimes 		return (1);
2672d4ee3eaSJordan K. Hubbard 	}
26858f0484fSRodney W. Grimes 	error(errno);
26958f0484fSRodney W. Grimes 	return (0);
27058f0484fSRodney W. Grimes }
27158f0484fSRodney W. Grimes 
27258f0484fSRodney W. Grimes void
273a31c8b58SStefan Farfeleder endfsent(void)
27458f0484fSRodney W. Grimes {
275a31c8b58SStefan Farfeleder 
27658f0484fSRodney W. Grimes 	if (_fs_fp) {
27758f0484fSRodney W. Grimes 		(void)fclose(_fs_fp);
27858f0484fSRodney W. Grimes 		_fs_fp = NULL;
27958f0484fSRodney W. Grimes 	}
280134dbc4cSMatthew N. Dodd 
281134dbc4cSMatthew N. Dodd 	fsp_set = 0;
28258f0484fSRodney W. Grimes }
28358f0484fSRodney W. Grimes 
2848b102407SPoul-Henning Kamp static void
285a31c8b58SStefan Farfeleder error(int err)
28658f0484fSRodney W. Grimes {
28758f0484fSRodney W. Grimes 	char *p;
2882d4ee3eaSJordan K. Hubbard 	char num[30];
28958f0484fSRodney W. Grimes 
2909233c4d9SJason Evans 	(void)_write(STDERR_FILENO, "fstab: ", 7);
291134dbc4cSMatthew N. Dodd 	(void)_write(STDERR_FILENO, path_fstab, strlen(path_fstab));
2929233c4d9SJason Evans 	(void)_write(STDERR_FILENO, ":", 1);
2932d4ee3eaSJordan K. Hubbard 	sprintf(num, "%d: ", LineNo);
2949233c4d9SJason Evans 	(void)_write(STDERR_FILENO, num, strlen(num));
29558f0484fSRodney W. Grimes 	p = strerror(err);
2969233c4d9SJason Evans 	(void)_write(STDERR_FILENO, p, strlen(p));
2979233c4d9SJason Evans 	(void)_write(STDERR_FILENO, "\n", 1);
29858f0484fSRodney W. Grimes }
299