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 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)fstab.c 8.1 (Berkeley) 6/4/93 30 * $FreeBSD: src/lib/libc/gen/fstab.c,v 1.15 2007/01/09 00:27:53 imp Exp $ 31 * $DragonFly: src/lib/libc/gen/fstab.c,v 1.6 2005/11/13 00:07:42 swildner Exp $ 32 */ 33 34 #include "namespace.h" 35 #include <sys/param.h> 36 #include <sys/mount.h> 37 #include <sys/stat.h> 38 39 #include <errno.h> 40 #include <fstab.h> 41 #include <paths.h> 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <unistd.h> 46 #include "un-namespace.h" 47 48 static FILE *_fs_fp; 49 static char *_fs_spec; /* allocated via getdevpath() */ 50 static struct fstab _fs_fstab; 51 static int LineNo = 0; 52 static char *path_fstab; 53 static char fstab_path[PATH_MAX]; 54 static int fsp_set = 0; 55 56 static void error(int); 57 static void fixfsfile(void); 58 static int fstabscan(void); 59 static char *gdplookup(char *spec); 60 61 void 62 setfstab(const char *file) 63 { 64 65 if (file == NULL) { 66 path_fstab = _PATH_FSTAB; 67 } else { 68 strncpy(fstab_path, file, PATH_MAX); 69 fstab_path[PATH_MAX - 1] = '\0'; 70 path_fstab = fstab_path; 71 } 72 fsp_set = 1; 73 } 74 75 const char * 76 getfstab(void) 77 { 78 79 if (fsp_set) 80 return (path_fstab); 81 else 82 return (_PATH_FSTAB); 83 } 84 85 static void 86 fixfsfile(void) 87 { 88 static char buf[sizeof(_PATH_DEV) + MNAMELEN]; 89 struct stat sb; 90 struct statfs sf; 91 92 if (strcmp(_fs_fstab.fs_file, "/") != 0) 93 return; 94 if (statfs("/", &sf) != 0) 95 return; 96 if (sf.f_mntfromname[0] == '/') 97 buf[0] = '\0'; 98 else 99 strcpy(buf, _PATH_DEV); 100 strcat(buf, sf.f_mntfromname); 101 if (stat(buf, &sb) != 0 || 102 (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode))) 103 return; 104 _fs_fstab.fs_spec = buf; 105 } 106 107 static int 108 fstabscan(void) 109 { 110 char *cp, *p; 111 #define MAXLINELENGTH 1024 112 static char line[MAXLINELENGTH]; 113 char subline[MAXLINELENGTH]; 114 int typexx; 115 116 for (;;) { 117 118 if (!(p = fgets(line, sizeof(line), _fs_fp))) 119 return(0); 120 /* OLD_STYLE_FSTAB */ 121 ++LineNo; 122 if (*line == '#' || *line == '\n') 123 continue; 124 if (!strpbrk(p, " \t")) { 125 _fs_fstab.fs_spec = gdplookup(strsep(&p, ":\n")); 126 _fs_fstab.fs_file = strsep(&p, ":\n"); 127 fixfsfile(); 128 _fs_fstab.fs_type = strsep(&p, ":\n"); 129 if (_fs_fstab.fs_type) { 130 if (!strcmp(_fs_fstab.fs_type, FSTAB_XX)) 131 continue; 132 _fs_fstab.fs_mntops = _fs_fstab.fs_type; 133 _fs_fstab.fs_vfstype = 134 strcmp(_fs_fstab.fs_type, FSTAB_SW) ? 135 "ufs" : "swap"; 136 if ((cp = strsep(&p, ":\n")) != NULL) { 137 _fs_fstab.fs_freq = atoi(cp); 138 if ((cp = strsep(&p, ":\n")) != NULL) { 139 _fs_fstab.fs_passno = atoi(cp); 140 return(1); 141 } 142 } 143 } 144 goto bad; 145 } 146 /* OLD_STYLE_FSTAB */ 147 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 148 ; 149 _fs_fstab.fs_spec = cp; 150 if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#') 151 continue; 152 _fs_fstab.fs_spec = gdplookup(_fs_fstab.fs_spec); 153 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 154 ; 155 _fs_fstab.fs_file = cp; 156 fixfsfile(); 157 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 158 ; 159 _fs_fstab.fs_vfstype = cp; 160 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 161 ; 162 _fs_fstab.fs_mntops = cp; 163 if (_fs_fstab.fs_mntops == NULL) 164 goto bad; 165 _fs_fstab.fs_freq = 0; 166 _fs_fstab.fs_passno = 0; 167 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 168 ; 169 if (cp != NULL) { 170 _fs_fstab.fs_freq = atoi(cp); 171 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 172 ; 173 if (cp != NULL) 174 _fs_fstab.fs_passno = atoi(cp); 175 } 176 strcpy(subline, _fs_fstab.fs_mntops); 177 p = subline; 178 for (typexx = 0, cp = strsep(&p, ","); cp; 179 cp = strsep(&p, ",")) { 180 if (strlen(cp) != 2) 181 continue; 182 if (!strcmp(cp, FSTAB_RW)) { 183 _fs_fstab.fs_type = FSTAB_RW; 184 break; 185 } 186 if (!strcmp(cp, FSTAB_RQ)) { 187 _fs_fstab.fs_type = FSTAB_RQ; 188 break; 189 } 190 if (!strcmp(cp, FSTAB_RO)) { 191 _fs_fstab.fs_type = FSTAB_RO; 192 break; 193 } 194 if (!strcmp(cp, FSTAB_SW)) { 195 _fs_fstab.fs_type = FSTAB_SW; 196 break; 197 } 198 if (!strcmp(cp, FSTAB_XX)) { 199 _fs_fstab.fs_type = FSTAB_XX; 200 typexx++; 201 break; 202 } 203 } 204 if (typexx) 205 continue; 206 if (cp != NULL) 207 return(1); 208 209 bad: /* no way to distinguish between EOF and syntax error */ 210 error(EFTYPE); 211 } 212 /* NOTREACHED */ 213 } 214 215 struct fstab * 216 getfsent(void) 217 { 218 if ((!_fs_fp && !setfsent()) || !fstabscan()) 219 return(NULL); 220 return(&_fs_fstab); 221 } 222 223 struct fstab * 224 getfsspec(const char *name) 225 { 226 if (setfsent()) 227 while (fstabscan()) 228 if (!strcmp(_fs_fstab.fs_spec, name)) 229 return(&_fs_fstab); 230 return(NULL); 231 } 232 233 struct fstab * 234 getfsfile(const char *name) 235 { 236 if (setfsent()) 237 while (fstabscan()) 238 if (!strcmp(_fs_fstab.fs_file, name)) 239 return(&_fs_fstab); 240 return(NULL); 241 } 242 243 int 244 setfsent(void) 245 { 246 if (_fs_fp) { 247 rewind(_fs_fp); 248 LineNo = 0; 249 return(1); 250 } 251 if (fsp_set == 0) { 252 if (issetugid()) 253 setfstab(NULL); 254 else 255 setfstab(getenv("PATH_FSTAB")); 256 } 257 if ((_fs_fp = fopen(path_fstab, "r")) != NULL) { 258 LineNo = 0; 259 return(1); 260 } 261 error(errno); 262 return(0); 263 } 264 265 void 266 endfsent(void) 267 { 268 if (_fs_fp) { 269 fclose(_fs_fp); 270 _fs_fp = NULL; 271 } 272 273 fsp_set = 0; 274 } 275 276 static char * 277 gdplookup(char *spec) 278 { 279 if (_fs_spec) 280 free(_fs_spec); 281 _fs_spec = getdevpath(spec, 0); 282 if (strcmp(_fs_spec, spec) != 0) 283 spec = _fs_spec; 284 return(spec); 285 } 286 287 static void 288 error(int err) 289 { 290 char *p; 291 char num[30]; 292 293 _write(STDERR_FILENO, "fstab: ", 7); 294 _write(STDERR_FILENO, path_fstab, strlen(path_fstab)); 295 _write(STDERR_FILENO, ":", 1); 296 sprintf(num, "%d: ", LineNo); 297 _write(STDERR_FILENO, num, strlen(num)); 298 p = strerror(err); 299 _write(STDERR_FILENO, p, strlen(p)); 300 _write(STDERR_FILENO, "\n", 1); 301 } 302