fstab.c revision 76178
1/* 2 * Copyright (c) 1980, 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * $FreeBSD: head/lib/libc/gen/fstab.c 76178 2001-05-01 09:30:02Z markm $ 34 */ 35 36#if defined(LIBC_SCCS) && !defined(lint) 37#if 0 38static char sccsid[] = "@(#)fstab.c 8.1 (Berkeley) 6/4/93"; 39#else 40static char rcsid[] = 41 "$FreeBSD: head/lib/libc/gen/fstab.c 76178 2001-05-01 09:30:02Z markm $"; 42#endif 43#endif /* LIBC_SCCS and not lint */ 44 45#include "namespace.h" 46#include <sys/param.h> 47#include <sys/lock.h> 48#include <sys/mutex.h> 49#include <sys/mount.h> 50#include <sys/stat.h> 51 52#include <errno.h> 53#include <fstab.h> 54#include <paths.h> 55#include <stdio.h> 56#include <stdlib.h> 57#include <string.h> 58#include <unistd.h> 59#include "un-namespace.h" 60 61static FILE *_fs_fp; 62static struct fstab _fs_fstab; 63static int LineNo = 0; 64 65static void error __P((int)); 66static void fixfsfile __P((void)); 67static int fstabscan __P((void)); 68 69static void 70fixfsfile() 71{ 72 static char buf[sizeof(_PATH_DEV) + MNAMELEN]; 73 struct stat sb; 74 struct statfs sf; 75 76 if (strcmp(_fs_fstab.fs_file, "/") != 0) 77 return; 78 if (statfs("/", &sf) != 0) 79 return; 80 if (sf.f_mntfromname[0] == '/') 81 buf[0] = '\0'; 82 else 83 strcpy(buf, _PATH_DEV); 84 strcat(buf, sf.f_mntfromname); 85 if (stat(buf, &sb) != 0 || 86 (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode))) 87 return; 88 _fs_fstab.fs_spec = buf; 89} 90 91static int 92fstabscan() 93{ 94 char *cp, *p; 95#define MAXLINELENGTH 1024 96 static char line[MAXLINELENGTH]; 97 char subline[MAXLINELENGTH]; 98 int typexx; 99 100 for (;;) { 101 102 if (!(p = fgets(line, sizeof(line), _fs_fp))) 103 return(0); 104/* OLD_STYLE_FSTAB */ 105 ++LineNo; 106 if (*line == '#' || *line == '\n') 107 continue; 108 if (!strpbrk(p, " \t")) { 109 _fs_fstab.fs_spec = strsep(&p, ":\n"); 110 _fs_fstab.fs_file = strsep(&p, ":\n"); 111 fixfsfile(); 112 _fs_fstab.fs_type = strsep(&p, ":\n"); 113 if (_fs_fstab.fs_type) { 114 if (!strcmp(_fs_fstab.fs_type, FSTAB_XX)) 115 continue; 116 _fs_fstab.fs_mntops = _fs_fstab.fs_type; 117 _fs_fstab.fs_vfstype = 118 strcmp(_fs_fstab.fs_type, FSTAB_SW) ? 119 "ufs" : "swap"; 120 if ((cp = strsep(&p, ":\n")) != NULL) { 121 _fs_fstab.fs_freq = atoi(cp); 122 if ((cp = strsep(&p, ":\n")) != NULL) { 123 _fs_fstab.fs_passno = atoi(cp); 124 return(1); 125 } 126 } 127 } 128 goto bad; 129 } 130/* OLD_STYLE_FSTAB */ 131 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 132 ; 133 _fs_fstab.fs_spec = cp; 134 if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#') 135 continue; 136 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 137 ; 138 _fs_fstab.fs_file = cp; 139 fixfsfile(); 140 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 141 ; 142 _fs_fstab.fs_vfstype = cp; 143 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 144 ; 145 _fs_fstab.fs_mntops = cp; 146 if (_fs_fstab.fs_mntops == NULL) 147 goto bad; 148 _fs_fstab.fs_freq = 0; 149 _fs_fstab.fs_passno = 0; 150 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 151 ; 152 if (cp != NULL) { 153 _fs_fstab.fs_freq = atoi(cp); 154 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 155 ; 156 if (cp != NULL) 157 _fs_fstab.fs_passno = atoi(cp); 158 } 159 strcpy(subline, _fs_fstab.fs_mntops); 160 p = subline; 161 for (typexx = 0, cp = strsep(&p, ","); cp; 162 cp = strsep(&p, ",")) { 163 if (strlen(cp) != 2) 164 continue; 165 if (!strcmp(cp, FSTAB_RW)) { 166 _fs_fstab.fs_type = FSTAB_RW; 167 break; 168 } 169 if (!strcmp(cp, FSTAB_RQ)) { 170 _fs_fstab.fs_type = FSTAB_RQ; 171 break; 172 } 173 if (!strcmp(cp, FSTAB_RO)) { 174 _fs_fstab.fs_type = FSTAB_RO; 175 break; 176 } 177 if (!strcmp(cp, FSTAB_SW)) { 178 _fs_fstab.fs_type = FSTAB_SW; 179 break; 180 } 181 if (!strcmp(cp, FSTAB_XX)) { 182 _fs_fstab.fs_type = FSTAB_XX; 183 typexx++; 184 break; 185 } 186 } 187 if (typexx) 188 continue; 189 if (cp != NULL) 190 return(1); 191 192bad: /* no way to distinguish between EOF and syntax error */ 193 error(EFTYPE); 194 } 195 /* NOTREACHED */ 196} 197 198struct fstab * 199getfsent() 200{ 201 if ((!_fs_fp && !setfsent()) || !fstabscan()) 202 return((struct fstab *)NULL); 203 return(&_fs_fstab); 204} 205 206struct fstab * 207getfsspec(name) 208 register const char *name; 209{ 210 if (setfsent()) 211 while (fstabscan()) 212 if (!strcmp(_fs_fstab.fs_spec, name)) 213 return(&_fs_fstab); 214 return((struct fstab *)NULL); 215} 216 217struct fstab * 218getfsfile(name) 219 register const char *name; 220{ 221 if (setfsent()) 222 while (fstabscan()) 223 if (!strcmp(_fs_fstab.fs_file, name)) 224 return(&_fs_fstab); 225 return((struct fstab *)NULL); 226} 227 228int 229setfsent() 230{ 231 if (_fs_fp) { 232 rewind(_fs_fp); 233 LineNo = 0; 234 return(1); 235 } 236 if ((_fs_fp = fopen(_PATH_FSTAB, "r")) != NULL) { 237 LineNo = 0; 238 return(1); 239 } 240 error(errno); 241 return(0); 242} 243 244void 245endfsent() 246{ 247 if (_fs_fp) { 248 (void)fclose(_fs_fp); 249 _fs_fp = NULL; 250 } 251} 252 253static void 254error(err) 255 int err; 256{ 257 char *p; 258 char num[30]; 259 260 (void)_write(STDERR_FILENO, "fstab: ", 7); 261 (void)_write(STDERR_FILENO, _PATH_FSTAB, sizeof(_PATH_FSTAB) - 1); 262 (void)_write(STDERR_FILENO, ":", 1); 263 sprintf(num, "%d: ", LineNo); 264 (void)_write(STDERR_FILENO, num, strlen(num)); 265 p = strerror(err); 266 (void)_write(STDERR_FILENO, p, strlen(p)); 267 (void)_write(STDERR_FILENO, "\n", 1); 268} 269