xref: /minix/lib/libc/gen/fstab.c (revision 00b67f09)
1 /*	$NetBSD: fstab.c,v 1.31 2012/03/13 21:13:34 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 1980, 1988, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #if defined(LIBC_SCCS) && !defined(lint)
34 #if 0
35 static char sccsid[] = "@(#)fstab.c	8.1 (Berkeley) 6/4/93";
36 #else
37 __RCSID("$NetBSD: fstab.c,v 1.31 2012/03/13 21:13:34 christos Exp $");
38 #endif
39 #endif /* LIBC_SCCS and not lint */
40 
41 #include "namespace.h"
42 #include <sys/types.h>
43 
44 #include <assert.h>
45 #include <err.h>
46 #include <errno.h>
47 #include <fstab.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <unistd.h>
52 
53 #ifdef __weak_alias
54 __weak_alias(endfsent,_endfsent)
55 __weak_alias(getfsent,_getfsent)
56 __weak_alias(getfsfile,_getfsfile)
57 __weak_alias(getfsspec,_getfsspec)
58 __weak_alias(setfsent,_setfsent)
59 #endif
60 
61 static FILE *_fs_fp;
62 static size_t _fs_lineno = 0;
63 static const char *_fs_file = _PATH_FSTAB;
64 static struct fstab _fs_fstab;
65 
66 static char *nextfld(char **, const char *);
67 static int fstabscan(void);
68 
69 
70 static char *
71 nextfld(char **str, const char *sep)
72 {
73 	char *ret;
74 
75 	_DIAGASSERT(str != NULL);
76 	_DIAGASSERT(sep != NULL);
77 
78 	while ((ret = stresep(str, sep, '\\')) != NULL && *ret == '\0')
79 		continue;
80 	return ret;
81 }
82 
83 
84 static int
85 fstabscan(void)
86 {
87 	char *cp, *lp, *sp;
88 #define	MAXLINELENGTH	1024
89 	static char line[MAXLINELENGTH];
90 	char subline[MAXLINELENGTH];
91 	static const char sep[] = ":\n";
92 	static const char ws[] = " \t\n";
93 	static const char *fstab_type[] = {
94 	    FSTAB_RW, FSTAB_RQ, FSTAB_RO, FSTAB_SW, FSTAB_DP, FSTAB_XX, NULL
95 	};
96 
97 	(void)memset(&_fs_fstab, 0, sizeof(_fs_fstab));
98 	for (;;) {
99 		if (!(lp = fgets(line, (int)sizeof(line), _fs_fp)))
100 			return 0;
101 		_fs_lineno++;
102 /* OLD_STYLE_FSTAB */
103 		if (!strpbrk(lp, " \t")) {
104 			_fs_fstab.fs_spec = nextfld(&lp, sep);
105 			if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
106 				continue;
107 			_fs_fstab.fs_file = nextfld(&lp, sep);
108 			_fs_fstab.fs_type = nextfld(&lp, sep);
109 			if (_fs_fstab.fs_type) {
110 				if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
111 					continue;
112 				_fs_fstab.fs_mntops = _fs_fstab.fs_type;
113 				_fs_fstab.fs_vfstype =
114 				    __UNCONST(
115 				    strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
116 				    "ufs" : "swap");
117 				if ((cp = nextfld(&lp, sep)) != NULL) {
118 					_fs_fstab.fs_freq = atoi(cp);
119 					if ((cp = nextfld(&lp, sep)) != NULL) {
120 						_fs_fstab.fs_passno = atoi(cp);
121 						return 1;
122 					}
123 				}
124 			}
125 			goto bad;
126 		}
127 /* OLD_STYLE_FSTAB */
128 		_fs_fstab.fs_spec = nextfld(&lp, ws);
129 		if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#')
130 			continue;
131 		_fs_fstab.fs_file = nextfld(&lp, ws);
132 		_fs_fstab.fs_vfstype = nextfld(&lp, ws);
133 		_fs_fstab.fs_mntops = nextfld(&lp, ws);
134 		if (_fs_fstab.fs_mntops == NULL)
135 			goto bad;
136 		_fs_fstab.fs_freq = 0;
137 		_fs_fstab.fs_passno = 0;
138 		if ((cp = nextfld(&lp, ws)) != NULL) {
139 			_fs_fstab.fs_freq = atoi(cp);
140 			if ((cp = nextfld(&lp, ws)) != NULL)
141 				_fs_fstab.fs_passno = atoi(cp);
142 		}
143 
144 		/* subline truncated iff line truncated */
145 		(void)strlcpy(subline, _fs_fstab.fs_mntops, sizeof(subline));
146 		sp = subline;
147 
148 		while ((cp = nextfld(&sp, ",")) != NULL) {
149 			const char **tp;
150 
151 			if (strlen(cp) != 2)
152 				continue;
153 
154 			for (tp = fstab_type; *tp; tp++)
155 				if (strcmp(cp, *tp) == 0) {
156 					_fs_fstab.fs_type = __UNCONST(*tp);
157 					break;
158 				}
159 			if (*tp)
160 				break;
161 		}
162 		if (_fs_fstab.fs_type == NULL)
163 			goto bad;
164 		if (strcmp(_fs_fstab.fs_type, FSTAB_XX) == 0)
165 			continue;
166 		if (cp != NULL)
167 			return 1;
168 
169 bad:
170 		warnx("%s, %lu: Missing fields", _fs_file, (u_long)_fs_lineno);
171 	}
172 	/* NOTREACHED */
173 }
174 
175 struct fstab *
176 getfsent(void)
177 {
178 	if ((!_fs_fp && !setfsent()) || !fstabscan())
179 		return NULL;
180 	return &_fs_fstab;
181 }
182 
183 struct fstab *
184 getfsspec(const char *name)
185 {
186 
187 	_DIAGASSERT(name != NULL);
188 
189 	if (setfsent())
190 		while (fstabscan())
191 			if (!strcmp(_fs_fstab.fs_spec, name))
192 				return &_fs_fstab;
193 	return NULL;
194 }
195 
196 struct fstab *
197 getfsfile(const char *name)
198 {
199 
200 	_DIAGASSERT(name != NULL);
201 
202 	if (setfsent())
203 		while (fstabscan())
204 			if (!strcmp(_fs_fstab.fs_file, name))
205 				return &_fs_fstab;
206 	return NULL;
207 }
208 
209 int
210 setfsent(void)
211 {
212 	_fs_lineno = 0;
213 	if (_fs_fp) {
214 		rewind(_fs_fp);
215 		return 1;
216 	}
217 	if ((_fs_fp = fopen(_PATH_FSTAB, "re")) == NULL) {
218 		warn("Cannot open `%s'", _PATH_FSTAB);
219 		return 0;
220 	}
221 	return 1;
222 }
223 
224 void
225 endfsent(void)
226 {
227 	if (_fs_fp) {
228 		(void)fclose(_fs_fp);
229 		_fs_fp = NULL;
230 	}
231 }
232