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