xref: /netbsd-src/lib/libc/gen/fstab.c (revision c5e820cae412164fcbee52f470436200af5358ea)
1*c5e820caSchristos /*	$NetBSD: fstab.c,v 1.31 2012/03/13 21:13:34 christos Exp $	*/
272c46b1cScgd 
361f28255Scgd /*
472c46b1cScgd  * Copyright (c) 1980, 1988, 1993
572c46b1cScgd  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * Redistribution and use in source and binary forms, with or without
861f28255Scgd  * modification, are permitted provided that the following conditions
961f28255Scgd  * are met:
1061f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1261f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1461f28255Scgd  *    documentation and/or other materials provided with the distribution.
15eb7c1594Sagc  * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd  *    may be used to endorse or promote products derived from this software
1761f28255Scgd  *    without specific prior written permission.
1861f28255Scgd  *
1961f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd  * SUCH DAMAGE.
3061f28255Scgd  */
3161f28255Scgd 
327957cf15Schristos #include <sys/cdefs.h>
3361f28255Scgd #if defined(LIBC_SCCS) && !defined(lint)
3472c46b1cScgd #if 0
3572c46b1cScgd static char sccsid[] = "@(#)fstab.c	8.1 (Berkeley) 6/4/93";
3672c46b1cScgd #else
37*c5e820caSchristos __RCSID("$NetBSD: fstab.c,v 1.31 2012/03/13 21:13:34 christos Exp $");
3872c46b1cScgd #endif
3961f28255Scgd #endif /* LIBC_SCCS and not lint */
4061f28255Scgd 
41550424b2Skleink #include "namespace.h"
425a218126Scgd #include <sys/types.h>
43b48252f3Slukem 
44b48252f3Slukem #include <assert.h>
454a05bcf0Smycroft #include <err.h>
4672c46b1cScgd #include <errno.h>
4761f28255Scgd #include <fstab.h>
4861f28255Scgd #include <stdio.h>
4961f28255Scgd #include <stdlib.h>
5061f28255Scgd #include <string.h>
5172c46b1cScgd #include <unistd.h>
5261f28255Scgd 
5343fa6fe3Sjtc #ifdef __weak_alias
5460549036Smycroft __weak_alias(endfsent,_endfsent)
5560549036Smycroft __weak_alias(getfsent,_getfsent)
5660549036Smycroft __weak_alias(getfsfile,_getfsfile)
5760549036Smycroft __weak_alias(getfsspec,_getfsspec)
5860549036Smycroft __weak_alias(setfsent,_setfsent)
5943fa6fe3Sjtc #endif
6043fa6fe3Sjtc 
6161f28255Scgd static FILE *_fs_fp;
626856868dSchristos static size_t _fs_lineno = 0;
636856868dSchristos static const char *_fs_file = _PATH_FSTAB;
6461f28255Scgd static struct fstab _fs_fstab;
6572c46b1cScgd 
66cbfb283cSchristos static char *nextfld(char **, const char *);
67cbfb283cSchristos static int fstabscan(void);
686856868dSchristos 
696856868dSchristos 
70cbfb283cSchristos static char *
nextfld(char ** str,const char * sep)71cbfb283cSchristos nextfld(char **str, const char *sep)
726856868dSchristos {
736856868dSchristos 	char *ret;
74b48252f3Slukem 
75b48252f3Slukem 	_DIAGASSERT(str != NULL);
76b48252f3Slukem 	_DIAGASSERT(sep != NULL);
77b48252f3Slukem 
78cbfb283cSchristos 	while ((ret = stresep(str, sep, '\\')) != NULL && *ret == '\0')
796856868dSchristos 		continue;
806856868dSchristos 	return ret;
816856868dSchristos }
826856868dSchristos 
836856868dSchristos 
84af07dd15Sjtc static int
fstabscan(void)85cbfb283cSchristos fstabscan(void)
8661f28255Scgd {
876856868dSchristos 	char *cp, *lp, *sp;
8861f28255Scgd #define	MAXLINELENGTH	1024
8961f28255Scgd 	static char line[MAXLINELENGTH];
9061f28255Scgd 	char subline[MAXLINELENGTH];
917957cf15Schristos 	static const char sep[] = ":\n";
927957cf15Schristos 	static const char ws[] = " \t\n";
9303256c6eSchristos 	static const char *fstab_type[] = {
94bdadd563Smrg 	    FSTAB_RW, FSTAB_RQ, FSTAB_RO, FSTAB_SW, FSTAB_DP, FSTAB_XX, NULL
956856868dSchristos 	};
9661f28255Scgd 
979839c99dSlukem 	(void)memset(&_fs_fstab, 0, sizeof(_fs_fstab));
9861f28255Scgd 	for (;;) {
99*c5e820caSchristos 		if (!(lp = fgets(line, (int)sizeof(line), _fs_fp)))
1006856868dSchristos 			return 0;
1016856868dSchristos 		_fs_lineno++;
10261f28255Scgd /* OLD_STYLE_FSTAB */
1036856868dSchristos 		if (!strpbrk(lp, " \t")) {
1046856868dSchristos 			_fs_fstab.fs_spec = nextfld(&lp, sep);
1059a16044fSpk 			if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
1069a16044fSpk 				continue;
1076856868dSchristos 			_fs_fstab.fs_file = nextfld(&lp, sep);
1086856868dSchristos 			_fs_fstab.fs_type = nextfld(&lp, sep);
10961f28255Scgd 			if (_fs_fstab.fs_type) {
11061f28255Scgd 				if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
11161f28255Scgd 					continue;
11261f28255Scgd 				_fs_fstab.fs_mntops = _fs_fstab.fs_type;
11361f28255Scgd 				_fs_fstab.fs_vfstype =
11403256c6eSchristos 				    __UNCONST(
11561f28255Scgd 				    strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
11603256c6eSchristos 				    "ufs" : "swap");
1176856868dSchristos 				if ((cp = nextfld(&lp, sep)) != NULL) {
11861f28255Scgd 					_fs_fstab.fs_freq = atoi(cp);
1196856868dSchristos 					if ((cp = nextfld(&lp, sep)) != NULL) {
12061f28255Scgd 						_fs_fstab.fs_passno = atoi(cp);
1216856868dSchristos 						return 1;
12261f28255Scgd 					}
12361f28255Scgd 				}
12461f28255Scgd 			}
12561f28255Scgd 			goto bad;
12661f28255Scgd 		}
12761f28255Scgd /* OLD_STYLE_FSTAB */
1286856868dSchristos 		_fs_fstab.fs_spec = nextfld(&lp, ws);
12961f28255Scgd 		if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
13061f28255Scgd 			continue;
1316856868dSchristos 		_fs_fstab.fs_file = nextfld(&lp, ws);
1326856868dSchristos 		_fs_fstab.fs_vfstype = nextfld(&lp, ws);
1336856868dSchristos 		_fs_fstab.fs_mntops = nextfld(&lp, ws);
13461f28255Scgd 		if (_fs_fstab.fs_mntops == NULL)
13561f28255Scgd 			goto bad;
13661f28255Scgd 		_fs_fstab.fs_freq = 0;
13761f28255Scgd 		_fs_fstab.fs_passno = 0;
1386856868dSchristos 		if ((cp = nextfld(&lp, ws)) != NULL) {
13961f28255Scgd 			_fs_fstab.fs_freq = atoi(cp);
1406856868dSchristos 			if ((cp = nextfld(&lp, ws)) != NULL)
14161f28255Scgd 				_fs_fstab.fs_passno = atoi(cp);
14261f28255Scgd 		}
143735ccc3fSgroo 
144735ccc3fSgroo 		/* subline truncated iff line truncated */
145735ccc3fSgroo 		(void)strlcpy(subline, _fs_fstab.fs_mntops, sizeof(subline));
146735ccc3fSgroo 		sp = subline;
147735ccc3fSgroo 
1486856868dSchristos 		while ((cp = nextfld(&sp, ",")) != NULL) {
14903256c6eSchristos 			const char **tp;
1506856868dSchristos 
15161f28255Scgd 			if (strlen(cp) != 2)
15261f28255Scgd 				continue;
1536856868dSchristos 
1546856868dSchristos 			for (tp = fstab_type; *tp; tp++)
1556856868dSchristos 				if (strcmp(cp, *tp) == 0) {
15603256c6eSchristos 					_fs_fstab.fs_type = __UNCONST(*tp);
15761f28255Scgd 					break;
15861f28255Scgd 				}
1596856868dSchristos 			if (*tp)
16061f28255Scgd 				break;
16161f28255Scgd 		}
1629839c99dSlukem 		if (_fs_fstab.fs_type == NULL)
1639839c99dSlukem 			goto bad;
1646856868dSchristos 		if (strcmp(_fs_fstab.fs_type, FSTAB_XX) == 0)
16561f28255Scgd 			continue;
16661f28255Scgd 		if (cp != NULL)
1676856868dSchristos 			return 1;
16861f28255Scgd 
1696856868dSchristos bad:
1707c2e6d4cSthorpej 		warnx("%s, %lu: Missing fields", _fs_file, (u_long)_fs_lineno);
17161f28255Scgd 	}
17261f28255Scgd 	/* NOTREACHED */
17361f28255Scgd }
17461f28255Scgd 
17561f28255Scgd struct fstab *
getfsent(void)176cbfb283cSchristos getfsent(void)
17761f28255Scgd {
1787957cf15Schristos 	if ((!_fs_fp && !setfsent()) || !fstabscan())
1796856868dSchristos 		return NULL;
1806856868dSchristos 	return &_fs_fstab;
18161f28255Scgd }
18261f28255Scgd 
18361f28255Scgd struct fstab *
getfsspec(const char * name)184cbfb283cSchristos getfsspec(const char *name)
18561f28255Scgd {
186b48252f3Slukem 
187b48252f3Slukem 	_DIAGASSERT(name != NULL);
188b48252f3Slukem 
18961f28255Scgd 	if (setfsent())
19061f28255Scgd 		while (fstabscan())
19161f28255Scgd 			if (!strcmp(_fs_fstab.fs_spec, name))
1926856868dSchristos 				return &_fs_fstab;
1936856868dSchristos 	return NULL;
19461f28255Scgd }
19561f28255Scgd 
19661f28255Scgd struct fstab *
getfsfile(const char * name)197cbfb283cSchristos getfsfile(const char *name)
19861f28255Scgd {
199b48252f3Slukem 
200b48252f3Slukem 	_DIAGASSERT(name != NULL);
201b48252f3Slukem 
20261f28255Scgd 	if (setfsent())
20361f28255Scgd 		while (fstabscan())
20461f28255Scgd 			if (!strcmp(_fs_fstab.fs_file, name))
2056856868dSchristos 				return &_fs_fstab;
2066856868dSchristos 	return NULL;
20761f28255Scgd }
20861f28255Scgd 
209af07dd15Sjtc int
setfsent(void)210cbfb283cSchristos setfsent(void)
21161f28255Scgd {
2126856868dSchristos 	_fs_lineno = 0;
21361f28255Scgd 	if (_fs_fp) {
21461f28255Scgd 		rewind(_fs_fp);
2156856868dSchristos 		return 1;
21661f28255Scgd 	}
2179292cfb2Schristos 	if ((_fs_fp = fopen(_PATH_FSTAB, "re")) == NULL) {
2186856868dSchristos 		warn("Cannot open `%s'", _PATH_FSTAB);
2196856868dSchristos 		return 0;
2206856868dSchristos 	}
2216856868dSchristos 	return 1;
22261f28255Scgd }
22361f28255Scgd 
22461f28255Scgd void
endfsent(void)225cbfb283cSchristos endfsent(void)
22661f28255Scgd {
22761f28255Scgd 	if (_fs_fp) {
22861f28255Scgd 		(void)fclose(_fs_fp);
22961f28255Scgd 		_fs_fp = NULL;
23061f28255Scgd 	}
23161f28255Scgd }
232