fstab.c revision 256281
1227753Stheraven/* 2227753Stheraven * Copyright (c) 1980, 1988, 1993 3227753Stheraven * The Regents of the University of California. All rights reserved. 4227753Stheraven * 5227753Stheraven * Redistribution and use in source and binary forms, with or without 6227753Stheraven * modification, are permitted provided that the following conditions 7227753Stheraven * are met: 8227753Stheraven * 1. Redistributions of source code must retain the above copyright 9227753Stheraven * notice, this list of conditions and the following disclaimer. 10227753Stheraven * 2. Redistributions in binary form must reproduce the above copyright 11232498Stheraven * notice, this list of conditions and the following disclaimer in the 12232498Stheraven * documentation and/or other materials provided with the distribution. 13232498Stheraven * 4. Neither the name of the University nor the names of its contributors 14232498Stheraven * may be used to endorse or promote products derived from this software 15232498Stheraven * without specific prior written permission. 16227753Stheraven * 17227753Stheraven * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18227753Stheraven * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19227753Stheraven * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20232498Stheraven * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21227753Stheraven * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22227753Stheraven * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23227753Stheraven * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24227753Stheraven * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25227753Stheraven * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26227753Stheraven * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27227753Stheraven * SUCH DAMAGE. 28227753Stheraven */ 29227753Stheraven 30227753Stheraven#if defined(LIBC_SCCS) && !defined(lint) 31227753Stheravenstatic char sccsid[] = "@(#)fstab.c 8.1 (Berkeley) 6/4/93"; 32227753Stheraven#endif /* LIBC_SCCS and not lint */ 33227753Stheraven#include <sys/cdefs.h> 34227753Stheraven__FBSDID("$FreeBSD: stable/10/lib/libc/gen/fstab.c 243865 2012-12-04 16:54:43Z jilles $"); 35227753Stheraven 36227753Stheraven#include "namespace.h" 37227753Stheraven#include <sys/param.h> 38227753Stheraven#include <sys/mount.h> 39227753Stheraven#include <sys/stat.h> 40227753Stheraven 41227753Stheraven#include <errno.h> 42227753Stheraven#include <fstab.h> 43227753Stheraven#include <paths.h> 44227753Stheraven#include <stdio.h> 45227753Stheraven#include <stdlib.h> 46227753Stheraven#include <string.h> 47227753Stheraven#include <unistd.h> 48227753Stheraven#include <vis.h> 49227753Stheraven#include "un-namespace.h" 50227753Stheraven 51227753Stheravenstatic FILE *_fs_fp; 52227753Stheravenstatic struct fstab _fs_fstab; 53227753Stheravenstatic int LineNo = 0; 54227753Stheravenstatic char *path_fstab; 55227753Stheravenstatic char fstab_path[PATH_MAX]; 56227753Stheravenstatic int fsp_set = 0; 57227753Stheraven 58227753Stheravenstatic void error(int); 59227753Stheravenstatic void fixfsfile(void); 60227753Stheravenstatic int fstabscan(void); 61227753Stheraven 62227753Stheravenvoid 63227753Stheravensetfstab(const char *file) 64227753Stheraven{ 65227753Stheraven 66227753Stheraven if (file == NULL) { 67227753Stheraven path_fstab = _PATH_FSTAB; 68227753Stheraven } else { 69227753Stheraven strncpy(fstab_path, file, PATH_MAX); 70227753Stheraven fstab_path[PATH_MAX - 1] = '\0'; 71227753Stheraven path_fstab = fstab_path; 72227753Stheraven } 73227753Stheraven fsp_set = 1; 74227753Stheraven 75227753Stheraven return; 76227753Stheraven} 77227753Stheraven 78227753Stheravenconst char * 79227753Stheravengetfstab(void) 80227753Stheraven{ 81227753Stheraven 82227753Stheraven if (fsp_set) 83227753Stheraven return (path_fstab); 84227753Stheraven else 85227753Stheraven return (_PATH_FSTAB); 86227753Stheraven} 87227753Stheraven 88232498Stheravenstatic void 89232498Stheravenfixfsfile(void) 90227753Stheraven{ 91227753Stheraven static char buf[sizeof(_PATH_DEV) + MNAMELEN]; 92227753Stheraven struct stat sb; 93227753Stheraven struct statfs sf; 94232498Stheraven 95232498Stheraven if (_fs_fstab.fs_file != NULL && strcmp(_fs_fstab.fs_file, "/") != 0) 96227753Stheraven return; 97227753Stheraven if (statfs("/", &sf) != 0) 98227753Stheraven return; 99227753Stheraven if (sf.f_mntfromname[0] == '/') 100227753Stheraven buf[0] = '\0'; 101227753Stheraven else 102227753Stheraven strcpy(buf, _PATH_DEV); 103227753Stheraven strcat(buf, sf.f_mntfromname); 104227753Stheraven if (stat(buf, &sb) != 0 || 105227753Stheraven (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode))) 106227753Stheraven return; 107227753Stheraven _fs_fstab.fs_spec = buf; 108227753Stheraven} 109227753Stheraven 110227753Stheravenstatic int 111227753Stheravenfstabscan(void) 112250883Sed{ 113250883Sed char *cp, *p; 114250883Sed#define MAXLINELENGTH 1024 115250883Sed static char line[MAXLINELENGTH]; 116227753Stheraven char subline[MAXLINELENGTH]; 117227753Stheraven int typexx; 118227753Stheraven 119227753Stheraven for (;;) { 120227753Stheraven 121227753Stheraven if (!(p = fgets(line, sizeof(line), _fs_fp))) 122227753Stheraven return (0); 123227753Stheraven/* OLD_STYLE_FSTAB */ 124250883Sed ++LineNo; 125250883Sed if (*line == '#' || *line == '\n') 126250883Sed continue; 127250883Sed if (!strpbrk(p, " \t")) { 128227753Stheraven _fs_fstab.fs_spec = strsep(&p, ":\n"); 129227753Stheraven _fs_fstab.fs_file = strsep(&p, ":\n"); 130227753Stheraven fixfsfile(); 131227753Stheraven _fs_fstab.fs_type = strsep(&p, ":\n"); 132227753Stheraven if (_fs_fstab.fs_type) { 133227753Stheraven if (!strcmp(_fs_fstab.fs_type, FSTAB_XX)) 134227753Stheraven continue; 135227753Stheraven _fs_fstab.fs_mntops = _fs_fstab.fs_type; 136227753Stheraven _fs_fstab.fs_vfstype = 137227753Stheraven strcmp(_fs_fstab.fs_type, FSTAB_SW) ? 138227753Stheraven "ufs" : "swap"; 139227753Stheraven if ((cp = strsep(&p, ":\n")) != NULL) { 140227753Stheraven _fs_fstab.fs_freq = atoi(cp); 141227753Stheraven if ((cp = strsep(&p, ":\n")) != NULL) { 142227753Stheraven _fs_fstab.fs_passno = atoi(cp); 143227753Stheraven return (1); 144227753Stheraven } 145227753Stheraven } 146227753Stheraven } 147227753Stheraven goto bad; 148227753Stheraven } 149227753Stheraven/* OLD_STYLE_FSTAB */ 150227753Stheraven while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 151227753Stheraven ; 152227753Stheraven _fs_fstab.fs_spec = cp; 153227753Stheraven if (_fs_fstab.fs_spec == NULL || *_fs_fstab.fs_spec == '#') 154227753Stheraven continue; 155227753Stheraven if (strunvis(_fs_fstab.fs_spec, _fs_fstab.fs_spec) < 0) 156227753Stheraven goto bad; 157227753Stheraven while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 158309485Sngie ; 159309485Sngie _fs_fstab.fs_file = cp; 160309485Sngie if (_fs_fstab.fs_file == NULL) 161309485Sngie goto bad; 162309485Sngie if (strunvis(_fs_fstab.fs_file, _fs_fstab.fs_file) < 0) 163227753Stheraven goto bad; 164227753Stheraven fixfsfile(); 165227753Stheraven while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 166227753Stheraven ; 167227753Stheraven _fs_fstab.fs_vfstype = cp; 168227753Stheraven while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 169227753Stheraven ; 170227753Stheraven _fs_fstab.fs_mntops = cp; 171227753Stheraven if (_fs_fstab.fs_mntops == NULL) 172227753Stheraven goto bad; 173227753Stheraven _fs_fstab.fs_freq = 0; 174227753Stheraven _fs_fstab.fs_passno = 0; 175227753Stheraven while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 176227753Stheraven ; 177227753Stheraven if (cp != NULL) { 178227753Stheraven _fs_fstab.fs_freq = atoi(cp); 179227753Stheraven while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 180232498Stheraven ; 181232498Stheraven if (cp != NULL) 182232498Stheraven _fs_fstab.fs_passno = atoi(cp); 183232498Stheraven } 184232498Stheraven strcpy(subline, _fs_fstab.fs_mntops); 185232498Stheraven p = subline; 186232498Stheraven for (typexx = 0, cp = strsep(&p, ","); cp; 187232498Stheraven cp = strsep(&p, ",")) { 188232498Stheraven if (strlen(cp) != 2) 189232498Stheraven continue; 190232498Stheraven if (!strcmp(cp, FSTAB_RW)) { 191232498Stheraven _fs_fstab.fs_type = FSTAB_RW; 192232498Stheraven break; 193232498Stheraven } 194232498Stheraven if (!strcmp(cp, FSTAB_RQ)) { 195232498Stheraven _fs_fstab.fs_type = FSTAB_RQ; 196227753Stheraven break; 197227753Stheraven } 198227753Stheraven if (!strcmp(cp, FSTAB_RO)) { 199227753Stheraven _fs_fstab.fs_type = FSTAB_RO; 200227753Stheraven break; 201233173Stheraven } 202232498Stheraven if (!strcmp(cp, FSTAB_SW)) { 203232498Stheraven _fs_fstab.fs_type = FSTAB_SW; 204232498Stheraven break; 205232498Stheraven } 206232498Stheraven if (!strcmp(cp, FSTAB_XX)) { 207232498Stheraven _fs_fstab.fs_type = FSTAB_XX; 208232498Stheraven typexx++; 209232498Stheraven break; 210227753Stheraven } 211232498Stheraven } 212227753Stheraven if (typexx) 213227753Stheraven continue; 214227753Stheraven if (cp != NULL) 215227753Stheraven return (1); 216227753Stheraven 217227753Stheravenbad: /* no way to distinguish between EOF and syntax error */ 218227753Stheraven error(EFTYPE); 219227753Stheraven } 220227753Stheraven /* NOTREACHED */ 221227753Stheraven} 222227753Stheraven 223227753Stheravenstruct fstab * 224227753Stheravengetfsent(void) 225227753Stheraven{ 226227753Stheraven 227227753Stheraven if ((!_fs_fp && !setfsent()) || !fstabscan()) 228227753Stheraven return (NULL); 229227753Stheraven return (&_fs_fstab); 230227753Stheraven} 231227753Stheraven 232struct fstab * 233getfsspec(const char *name) 234{ 235 236 if (setfsent()) 237 while (fstabscan()) 238 if (!strcmp(_fs_fstab.fs_spec, name)) 239 return (&_fs_fstab); 240 return (NULL); 241} 242 243struct fstab * 244getfsfile(const char *name) 245{ 246 247 if (setfsent()) 248 while (fstabscan()) 249 if (!strcmp(_fs_fstab.fs_file, name)) 250 return (&_fs_fstab); 251 return (NULL); 252} 253 254int 255setfsent(void) 256{ 257 if (_fs_fp) { 258 rewind(_fs_fp); 259 LineNo = 0; 260 return (1); 261 } 262 if (fsp_set == 0) { 263 if (issetugid()) 264 setfstab(NULL); 265 else 266 setfstab(getenv("PATH_FSTAB")); 267 } 268 if ((_fs_fp = fopen(path_fstab, "re")) != NULL) { 269 LineNo = 0; 270 return (1); 271 } 272 error(errno); 273 return (0); 274} 275 276void 277endfsent(void) 278{ 279 280 if (_fs_fp) { 281 (void)fclose(_fs_fp); 282 _fs_fp = NULL; 283 } 284 285 fsp_set = 0; 286} 287 288static void 289error(int err) 290{ 291 char *p; 292 char num[30]; 293 294 (void)_write(STDERR_FILENO, "fstab: ", 7); 295 (void)_write(STDERR_FILENO, path_fstab, strlen(path_fstab)); 296 (void)_write(STDERR_FILENO, ":", 1); 297 sprintf(num, "%d: ", LineNo); 298 (void)_write(STDERR_FILENO, num, strlen(num)); 299 p = strerror(err); 300 (void)_write(STDERR_FILENO, p, strlen(p)); 301 (void)_write(STDERR_FILENO, "\n", 1); 302} 303