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