fstab.c revision 243865
1130561Sobrien/* 2130561Sobrien * Copyright (c) 1980, 1988, 1993 3130561Sobrien * The Regents of the University of California. All rights reserved. 4130561Sobrien * 5130561Sobrien * Redistribution and use in source and binary forms, with or without 6130561Sobrien * modification, are permitted provided that the following conditions 7130561Sobrien * are met: 8130561Sobrien * 1. Redistributions of source code must retain the above copyright 9130561Sobrien * notice, this list of conditions and the following disclaimer. 10130561Sobrien * 2. Redistributions in binary form must reproduce the above copyright 11130561Sobrien * notice, this list of conditions and the following disclaimer in the 12130561Sobrien * documentation and/or other materials provided with the distribution. 13130561Sobrien * 4. Neither the name of the University nor the names of its contributors 14130561Sobrien * may be used to endorse or promote products derived from this software 15130561Sobrien * without specific prior written permission. 16130561Sobrien * 17130561Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18130561Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19130561Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20130561Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21130561Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22130561Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23130561Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24130561Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25130561Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26130561Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27130561Sobrien * SUCH DAMAGE. 28130561Sobrien */ 29130561Sobrien 30130561Sobrien#if defined(LIBC_SCCS) && !defined(lint) 31130561Sobrienstatic char sccsid[] = "@(#)fstab.c 8.1 (Berkeley) 6/4/93"; 32130561Sobrien#endif /* LIBC_SCCS and not lint */ 33130561Sobrien#include <sys/cdefs.h> 34130561Sobrien__FBSDID("$FreeBSD: head/lib/libc/gen/fstab.c 243865 2012-12-04 16:54:43Z jilles $"); 35130561Sobrien 36130561Sobrien#include "namespace.h" 37130561Sobrien#include <sys/param.h> 38130561Sobrien#include <sys/mount.h> 39130561Sobrien#include <sys/stat.h> 40130561Sobrien 41130561Sobrien#include <errno.h> 42130561Sobrien#include <fstab.h> 43130561Sobrien#include <paths.h> 44130561Sobrien#include <stdio.h> 45130561Sobrien#include <stdlib.h> 46130561Sobrien#include <string.h> 47130561Sobrien#include <unistd.h> 48130561Sobrien#include <vis.h> 49130561Sobrien#include "un-namespace.h" 50130561Sobrien 51130561Sobrienstatic FILE *_fs_fp; 52130561Sobrienstatic struct fstab _fs_fstab; 53130561Sobrienstatic int LineNo = 0; 54130561Sobrienstatic char *path_fstab; 55130561Sobrienstatic char fstab_path[PATH_MAX]; 56130561Sobrienstatic int fsp_set = 0; 57130561Sobrien 58130561Sobrienstatic void error(int); 59130561Sobrienstatic void fixfsfile(void); 60130561Sobrienstatic int fstabscan(void); 61130561Sobrien 62130561Sobrienvoid 63130561Sobriensetfstab(const char *file) 64130561Sobrien{ 65130561Sobrien 66130561Sobrien if (file == NULL) { 67130561Sobrien path_fstab = _PATH_FSTAB; 68130561Sobrien } else { 69130561Sobrien strncpy(fstab_path, file, PATH_MAX); 70130561Sobrien fstab_path[PATH_MAX - 1] = '\0'; 71130561Sobrien path_fstab = fstab_path; 72130561Sobrien } 73130561Sobrien fsp_set = 1; 74130561Sobrien 75130561Sobrien return; 76130561Sobrien} 77130561Sobrien 78130561Sobrienconst char * 79130561Sobriengetfstab(void) 80130561Sobrien{ 81130561Sobrien 82130561Sobrien if (fsp_set) 83130561Sobrien return (path_fstab); 84130561Sobrien else 85130561Sobrien return (_PATH_FSTAB); 86130561Sobrien} 87130561Sobrien 88130561Sobrienstatic void 89130561Sobrienfixfsfile(void) 90130561Sobrien{ 91130561Sobrien static char buf[sizeof(_PATH_DEV) + MNAMELEN]; 92130561Sobrien struct stat sb; 93130561Sobrien struct statfs sf; 94130561Sobrien 95130561Sobrien if (_fs_fstab.fs_file != NULL && strcmp(_fs_fstab.fs_file, "/") != 0) 96130561Sobrien return; 97130561Sobrien if (statfs("/", &sf) != 0) 98130561Sobrien return; 99130561Sobrien if (sf.f_mntfromname[0] == '/') 100130561Sobrien buf[0] = '\0'; 101130561Sobrien else 102130561Sobrien strcpy(buf, _PATH_DEV); 103130561Sobrien strcat(buf, sf.f_mntfromname); 104130561Sobrien if (stat(buf, &sb) != 0 || 105130561Sobrien (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode))) 106130561Sobrien return; 107130561Sobrien _fs_fstab.fs_spec = buf; 108130561Sobrien} 109130561Sobrien 110130561Sobrienstatic int 111130561Sobrienfstabscan(void) 112130561Sobrien{ 113130561Sobrien char *cp, *p; 114130561Sobrien#define MAXLINELENGTH 1024 115130561Sobrien static char line[MAXLINELENGTH]; 116130561Sobrien char subline[MAXLINELENGTH]; 117130561Sobrien int typexx; 118130561Sobrien 119130561Sobrien for (;;) { 120130561Sobrien 121130561Sobrien if (!(p = fgets(line, sizeof(line), _fs_fp))) 122130561Sobrien return (0); 123130561Sobrien/* OLD_STYLE_FSTAB */ 124130561Sobrien ++LineNo; 125130561Sobrien if (*line == '#' || *line == '\n') 126130561Sobrien continue; 127130561Sobrien if (!strpbrk(p, " \t")) { 128130561Sobrien _fs_fstab.fs_spec = strsep(&p, ":\n"); 129130561Sobrien _fs_fstab.fs_file = strsep(&p, ":\n"); 130130561Sobrien fixfsfile(); 131130561Sobrien _fs_fstab.fs_type = strsep(&p, ":\n"); 132130561Sobrien if (_fs_fstab.fs_type) { 133130561Sobrien if (!strcmp(_fs_fstab.fs_type, FSTAB_XX)) 134130561Sobrien continue; 135130561Sobrien _fs_fstab.fs_mntops = _fs_fstab.fs_type; 136130561Sobrien _fs_fstab.fs_vfstype = 137130561Sobrien strcmp(_fs_fstab.fs_type, FSTAB_SW) ? 138130561Sobrien "ufs" : "swap"; 139130561Sobrien if ((cp = strsep(&p, ":\n")) != NULL) { 140130561Sobrien _fs_fstab.fs_freq = atoi(cp); 141130561Sobrien if ((cp = strsep(&p, ":\n")) != NULL) { 142130561Sobrien _fs_fstab.fs_passno = atoi(cp); 143130561Sobrien return (1); 144130561Sobrien } 145130561Sobrien } 146130561Sobrien } 147130561Sobrien goto bad; 148130561Sobrien } 149130561Sobrien/* OLD_STYLE_FSTAB */ 150130561Sobrien while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 151130561Sobrien ; 152130561Sobrien _fs_fstab.fs_spec = cp; 153130561Sobrien if (_fs_fstab.fs_spec == NULL || *_fs_fstab.fs_spec == '#') 154130561Sobrien continue; 155130561Sobrien if (strunvis(_fs_fstab.fs_spec, _fs_fstab.fs_spec) < 0) 156130561Sobrien goto bad; 157130561Sobrien while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 158130561Sobrien ; 159130561Sobrien _fs_fstab.fs_file = cp; 160130561Sobrien if (_fs_fstab.fs_file == NULL) 161130561Sobrien goto bad; 162130561Sobrien if (strunvis(_fs_fstab.fs_file, _fs_fstab.fs_file) < 0) 163130561Sobrien goto bad; 164130561Sobrien fixfsfile(); 165130561Sobrien while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 166130561Sobrien ; 167130561Sobrien _fs_fstab.fs_vfstype = cp; 168130561Sobrien while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 169130561Sobrien ; 170130561Sobrien _fs_fstab.fs_mntops = cp; 171130561Sobrien if (_fs_fstab.fs_mntops == NULL) 172130561Sobrien goto bad; 173130561Sobrien _fs_fstab.fs_freq = 0; 174130561Sobrien _fs_fstab.fs_passno = 0; 175130561Sobrien while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 176130561Sobrien ; 177130561Sobrien if (cp != NULL) { 178130561Sobrien _fs_fstab.fs_freq = atoi(cp); 179130561Sobrien while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 180130561Sobrien ; 181130561Sobrien if (cp != NULL) 182130561Sobrien _fs_fstab.fs_passno = atoi(cp); 183130561Sobrien } 184130561Sobrien strcpy(subline, _fs_fstab.fs_mntops); 185130561Sobrien p = subline; 186130561Sobrien for (typexx = 0, cp = strsep(&p, ","); cp; 187130561Sobrien cp = strsep(&p, ",")) { 188130561Sobrien if (strlen(cp) != 2) 189130561Sobrien continue; 190130561Sobrien if (!strcmp(cp, FSTAB_RW)) { 191130561Sobrien _fs_fstab.fs_type = FSTAB_RW; 192130561Sobrien break; 193130561Sobrien } 194130561Sobrien if (!strcmp(cp, FSTAB_RQ)) { 195130561Sobrien _fs_fstab.fs_type = FSTAB_RQ; 196130561Sobrien break; 197130561Sobrien } 198130561Sobrien if (!strcmp(cp, FSTAB_RO)) { 199130561Sobrien _fs_fstab.fs_type = FSTAB_RO; 200130561Sobrien break; 201130561Sobrien } 202130561Sobrien if (!strcmp(cp, FSTAB_SW)) { 203130561Sobrien _fs_fstab.fs_type = FSTAB_SW; 204130561Sobrien break; 205130561Sobrien } 206130561Sobrien if (!strcmp(cp, FSTAB_XX)) { 207130561Sobrien _fs_fstab.fs_type = FSTAB_XX; 208130561Sobrien typexx++; 209130561Sobrien break; 210130561Sobrien } 211130561Sobrien } 212130561Sobrien if (typexx) 213130561Sobrien continue; 214130561Sobrien if (cp != NULL) 215130561Sobrien return (1); 216130561Sobrien 217130561Sobrienbad: /* no way to distinguish between EOF and syntax error */ 218130561Sobrien error(EFTYPE); 219130561Sobrien } 220130561Sobrien /* NOTREACHED */ 221130561Sobrien} 222130561Sobrien 223130561Sobrienstruct fstab * 224130561Sobriengetfsent(void) 225130561Sobrien{ 226130561Sobrien 227130561Sobrien if ((!_fs_fp && !setfsent()) || !fstabscan()) 228130561Sobrien return (NULL); 229130561Sobrien return (&_fs_fstab); 230130561Sobrien} 231130561Sobrien 232130561Sobrienstruct fstab * 233130561Sobriengetfsspec(const char *name) 234130561Sobrien{ 235130561Sobrien 236130561Sobrien if (setfsent()) 237130561Sobrien while (fstabscan()) 238130561Sobrien if (!strcmp(_fs_fstab.fs_spec, name)) 239130561Sobrien return (&_fs_fstab); 240130561Sobrien return (NULL); 241130561Sobrien} 242130561Sobrien 243130561Sobrienstruct fstab * 244130561Sobriengetfsfile(const char *name) 245130561Sobrien{ 246130561Sobrien 247130561Sobrien if (setfsent()) 248130561Sobrien while (fstabscan()) 249130561Sobrien if (!strcmp(_fs_fstab.fs_file, name)) 250130561Sobrien return (&_fs_fstab); 251130561Sobrien return (NULL); 252130561Sobrien} 253130561Sobrien 254130561Sobrienint 255130561Sobriensetfsent(void) 256130561Sobrien{ 257130561Sobrien if (_fs_fp) { 258130561Sobrien rewind(_fs_fp); 259130561Sobrien LineNo = 0; 260130561Sobrien return (1); 261130561Sobrien } 262130561Sobrien if (fsp_set == 0) { 263130561Sobrien if (issetugid()) 264130561Sobrien setfstab(NULL); 265130561Sobrien else 266130561Sobrien setfstab(getenv("PATH_FSTAB")); 267130561Sobrien } 268130561Sobrien if ((_fs_fp = fopen(path_fstab, "re")) != NULL) { 269130561Sobrien LineNo = 0; 270130561Sobrien return (1); 271130561Sobrien } 272130561Sobrien error(errno); 273130561Sobrien return (0); 274130561Sobrien} 275130561Sobrien 276130561Sobrienvoid 277130561Sobrienendfsent(void) 278130561Sobrien{ 279130561Sobrien 280130561Sobrien if (_fs_fp) { 281130561Sobrien (void)fclose(_fs_fp); 282130561Sobrien _fs_fp = NULL; 283130561Sobrien } 284130561Sobrien 285130561Sobrien fsp_set = 0; 286130561Sobrien} 287130561Sobrien 288130561Sobrienstatic void 289130561Sobrienerror(int err) 290130561Sobrien{ 291130561Sobrien char *p; 292130561Sobrien char num[30]; 293130561Sobrien 294130561Sobrien (void)_write(STDERR_FILENO, "fstab: ", 7); 295130561Sobrien (void)_write(STDERR_FILENO, path_fstab, strlen(path_fstab)); 296130561Sobrien (void)_write(STDERR_FILENO, ":", 1); 297130561Sobrien sprintf(num, "%d: ", LineNo); 298130561Sobrien (void)_write(STDERR_FILENO, num, strlen(num)); 299130561Sobrien p = strerror(err); 300130561Sobrien (void)_write(STDERR_FILENO, p, strlen(p)); 301130561Sobrien (void)_write(STDERR_FILENO, "\n", 1); 302130561Sobrien} 303130561Sobrien