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 struct fstab _fs_fstab; 50 static int LineNo = 0; 51 static char *path_fstab; 52 static char fstab_path[PATH_MAX]; 53 static int fsp_set = 0; 54 55 static void error(int); 56 static void fixfsfile(void); 57 static int fstabscan(void); 58 59 void 60 setfstab(const char *file) 61 { 62 63 if (file == NULL) { 64 path_fstab = _PATH_FSTAB; 65 } else { 66 strncpy(fstab_path, file, PATH_MAX); 67 fstab_path[PATH_MAX - 1] = '\0'; 68 path_fstab = fstab_path; 69 } 70 fsp_set = 1; 71 } 72 73 const char * 74 getfstab(void) 75 { 76 77 if (fsp_set) 78 return (path_fstab); 79 else 80 return (_PATH_FSTAB); 81 } 82 83 static void 84 fixfsfile(void) 85 { 86 static char buf[sizeof(_PATH_DEV) + MNAMELEN]; 87 struct stat sb; 88 struct statfs sf; 89 90 if (strcmp(_fs_fstab.fs_file, "/") != 0) 91 return; 92 if (statfs("/", &sf) != 0) 93 return; 94 if (sf.f_mntfromname[0] == '/') 95 buf[0] = '\0'; 96 else 97 strcpy(buf, _PATH_DEV); 98 strcat(buf, sf.f_mntfromname); 99 if (stat(buf, &sb) != 0 || 100 (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode))) 101 return; 102 _fs_fstab.fs_spec = buf; 103 } 104 105 static int 106 fstabscan(void) 107 { 108 char *cp, *p; 109 #define MAXLINELENGTH 1024 110 static char line[MAXLINELENGTH]; 111 char subline[MAXLINELENGTH]; 112 int typexx; 113 114 for (;;) { 115 116 if (!(p = fgets(line, sizeof(line), _fs_fp))) 117 return(0); 118 /* OLD_STYLE_FSTAB */ 119 ++LineNo; 120 if (*line == '#' || *line == '\n') 121 continue; 122 if (!strpbrk(p, " \t")) { 123 _fs_fstab.fs_spec = strsep(&p, ":\n"); 124 _fs_fstab.fs_file = strsep(&p, ":\n"); 125 fixfsfile(); 126 _fs_fstab.fs_type = strsep(&p, ":\n"); 127 if (_fs_fstab.fs_type) { 128 if (!strcmp(_fs_fstab.fs_type, FSTAB_XX)) 129 continue; 130 _fs_fstab.fs_mntops = _fs_fstab.fs_type; 131 _fs_fstab.fs_vfstype = 132 strcmp(_fs_fstab.fs_type, FSTAB_SW) ? 133 "ufs" : "swap"; 134 if ((cp = strsep(&p, ":\n")) != NULL) { 135 _fs_fstab.fs_freq = atoi(cp); 136 if ((cp = strsep(&p, ":\n")) != NULL) { 137 _fs_fstab.fs_passno = atoi(cp); 138 return(1); 139 } 140 } 141 } 142 goto bad; 143 } 144 /* OLD_STYLE_FSTAB */ 145 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 146 ; 147 _fs_fstab.fs_spec = cp; 148 if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#') 149 continue; 150 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 151 ; 152 _fs_fstab.fs_file = cp; 153 fixfsfile(); 154 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 155 ; 156 _fs_fstab.fs_vfstype = cp; 157 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 158 ; 159 _fs_fstab.fs_mntops = cp; 160 if (_fs_fstab.fs_mntops == NULL) 161 goto bad; 162 _fs_fstab.fs_freq = 0; 163 _fs_fstab.fs_passno = 0; 164 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 165 ; 166 if (cp != NULL) { 167 _fs_fstab.fs_freq = atoi(cp); 168 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 169 ; 170 if (cp != NULL) 171 _fs_fstab.fs_passno = atoi(cp); 172 } 173 strcpy(subline, _fs_fstab.fs_mntops); 174 p = subline; 175 for (typexx = 0, cp = strsep(&p, ","); cp; 176 cp = strsep(&p, ",")) { 177 if (strlen(cp) != 2) 178 continue; 179 if (!strcmp(cp, FSTAB_RW)) { 180 _fs_fstab.fs_type = FSTAB_RW; 181 break; 182 } 183 if (!strcmp(cp, FSTAB_RQ)) { 184 _fs_fstab.fs_type = FSTAB_RQ; 185 break; 186 } 187 if (!strcmp(cp, FSTAB_RO)) { 188 _fs_fstab.fs_type = FSTAB_RO; 189 break; 190 } 191 if (!strcmp(cp, FSTAB_SW)) { 192 _fs_fstab.fs_type = FSTAB_SW; 193 break; 194 } 195 if (!strcmp(cp, FSTAB_XX)) { 196 _fs_fstab.fs_type = FSTAB_XX; 197 typexx++; 198 break; 199 } 200 } 201 if (typexx) 202 continue; 203 if (cp != NULL) 204 return(1); 205 206 bad: /* no way to distinguish between EOF and syntax error */ 207 error(EFTYPE); 208 } 209 /* NOTREACHED */ 210 } 211 212 struct fstab * 213 getfsent(void) 214 { 215 if ((!_fs_fp && !setfsent()) || !fstabscan()) 216 return(NULL); 217 return(&_fs_fstab); 218 } 219 220 struct fstab * 221 getfsspec(const char *name) 222 { 223 if (setfsent()) 224 while (fstabscan()) 225 if (!strcmp(_fs_fstab.fs_spec, name)) 226 return(&_fs_fstab); 227 return(NULL); 228 } 229 230 struct fstab * 231 getfsfile(const char *name) 232 { 233 if (setfsent()) 234 while (fstabscan()) 235 if (!strcmp(_fs_fstab.fs_file, name)) 236 return(&_fs_fstab); 237 return(NULL); 238 } 239 240 int 241 setfsent(void) 242 { 243 if (_fs_fp) { 244 rewind(_fs_fp); 245 LineNo = 0; 246 return(1); 247 } 248 if (fsp_set == 0) { 249 if (issetugid()) 250 setfstab(NULL); 251 else 252 setfstab(getenv("PATH_FSTAB")); 253 } 254 if ((_fs_fp = fopen(path_fstab, "r")) != NULL) { 255 LineNo = 0; 256 return(1); 257 } 258 error(errno); 259 return(0); 260 } 261 262 void 263 endfsent(void) 264 { 265 if (_fs_fp) { 266 fclose(_fs_fp); 267 _fs_fp = NULL; 268 } 269 270 fsp_set = 0; 271 } 272 273 static void 274 error(int err) 275 { 276 char *p; 277 char num[30]; 278 279 _write(STDERR_FILENO, "fstab: ", 7); 280 _write(STDERR_FILENO, path_fstab, strlen(path_fstab)); 281 _write(STDERR_FILENO, ":", 1); 282 sprintf(num, "%d: ", LineNo); 283 _write(STDERR_FILENO, num, strlen(num)); 284 p = strerror(err); 285 _write(STDERR_FILENO, p, strlen(p)); 286 _write(STDERR_FILENO, "\n", 1); 287 } 288