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: src/lib/libc/gen/fstab.c,v 1.8 2000/01/27 23:06:15 jasone Exp $ 34 * $DragonFly: src/lib/libc/gen/fstab.c,v 1.4 2004/06/06 15:05:55 hmp Exp $ 35 * 36 * @(#)fstab.c 8.1 (Berkeley) 6/4/93 37 * $FreeBSD: src/lib/libc/gen/fstab.c,v 1.8 2000/01/27 23:06:15 jasone Exp $ 38 */ 39 40 #include <sys/param.h> 41 #include <sys/mount.h> 42 #include <sys/stat.h> 43 44 #include <errno.h> 45 #include <fstab.h> 46 #include <paths.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <unistd.h> 51 52 static FILE *_fs_fp; 53 static struct fstab _fs_fstab; 54 static int LineNo = 0; 55 56 static void error (int); 57 static void fixfsfile (void); 58 static int fstabscan (void); 59 60 static void 61 fixfsfile() 62 { 63 static char buf[sizeof(_PATH_DEV) + MNAMELEN]; 64 struct stat sb; 65 struct statfs sf; 66 67 if (strcmp(_fs_fstab.fs_file, "/") != 0) 68 return; 69 if (statfs("/", &sf) != 0) 70 return; 71 if (sf.f_mntfromname[0] == '/') 72 buf[0] = '\0'; 73 else 74 strcpy(buf, _PATH_DEV); 75 strcat(buf, sf.f_mntfromname); 76 if (stat(buf, &sb) != 0 || 77 (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode))) 78 return; 79 _fs_fstab.fs_spec = buf; 80 } 81 82 static int 83 fstabscan() 84 { 85 char *cp, *p; 86 #define MAXLINELENGTH 1024 87 static char line[MAXLINELENGTH]; 88 char subline[MAXLINELENGTH]; 89 int typexx; 90 91 for (;;) { 92 93 if (!(p = fgets(line, sizeof(line), _fs_fp))) 94 return(0); 95 /* OLD_STYLE_FSTAB */ 96 ++LineNo; 97 if (*line == '#' || *line == '\n') 98 continue; 99 if (!strpbrk(p, " \t")) { 100 _fs_fstab.fs_spec = strsep(&p, ":\n"); 101 _fs_fstab.fs_file = strsep(&p, ":\n"); 102 fixfsfile(); 103 _fs_fstab.fs_type = strsep(&p, ":\n"); 104 if (_fs_fstab.fs_type) { 105 if (!strcmp(_fs_fstab.fs_type, FSTAB_XX)) 106 continue; 107 _fs_fstab.fs_mntops = _fs_fstab.fs_type; 108 _fs_fstab.fs_vfstype = 109 strcmp(_fs_fstab.fs_type, FSTAB_SW) ? 110 "ufs" : "swap"; 111 if ((cp = strsep(&p, ":\n")) != NULL) { 112 _fs_fstab.fs_freq = atoi(cp); 113 if ((cp = strsep(&p, ":\n")) != NULL) { 114 _fs_fstab.fs_passno = atoi(cp); 115 return(1); 116 } 117 } 118 } 119 goto bad; 120 } 121 /* OLD_STYLE_FSTAB */ 122 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 123 ; 124 _fs_fstab.fs_spec = cp; 125 if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#') 126 continue; 127 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 128 ; 129 _fs_fstab.fs_file = cp; 130 fixfsfile(); 131 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 132 ; 133 _fs_fstab.fs_vfstype = cp; 134 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 135 ; 136 _fs_fstab.fs_mntops = cp; 137 if (_fs_fstab.fs_mntops == NULL) 138 goto bad; 139 _fs_fstab.fs_freq = 0; 140 _fs_fstab.fs_passno = 0; 141 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 142 ; 143 if (cp != NULL) { 144 _fs_fstab.fs_freq = atoi(cp); 145 while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') 146 ; 147 if (cp != NULL) 148 _fs_fstab.fs_passno = atoi(cp); 149 } 150 strcpy(subline, _fs_fstab.fs_mntops); 151 p = subline; 152 for (typexx = 0, cp = strsep(&p, ","); cp; 153 cp = strsep(&p, ",")) { 154 if (strlen(cp) != 2) 155 continue; 156 if (!strcmp(cp, FSTAB_RW)) { 157 _fs_fstab.fs_type = FSTAB_RW; 158 break; 159 } 160 if (!strcmp(cp, FSTAB_RQ)) { 161 _fs_fstab.fs_type = FSTAB_RQ; 162 break; 163 } 164 if (!strcmp(cp, FSTAB_RO)) { 165 _fs_fstab.fs_type = FSTAB_RO; 166 break; 167 } 168 if (!strcmp(cp, FSTAB_SW)) { 169 _fs_fstab.fs_type = FSTAB_SW; 170 break; 171 } 172 if (!strcmp(cp, FSTAB_XX)) { 173 _fs_fstab.fs_type = FSTAB_XX; 174 typexx++; 175 break; 176 } 177 } 178 if (typexx) 179 continue; 180 if (cp != NULL) 181 return(1); 182 183 bad: /* no way to distinguish between EOF and syntax error */ 184 error(EFTYPE); 185 } 186 /* NOTREACHED */ 187 } 188 189 struct fstab * 190 getfsent() 191 { 192 if ((!_fs_fp && !setfsent()) || !fstabscan()) 193 return((struct fstab *)NULL); 194 return(&_fs_fstab); 195 } 196 197 struct fstab * 198 getfsspec(name) 199 const char *name; 200 { 201 if (setfsent()) 202 while (fstabscan()) 203 if (!strcmp(_fs_fstab.fs_spec, name)) 204 return(&_fs_fstab); 205 return((struct fstab *)NULL); 206 } 207 208 struct fstab * 209 getfsfile(name) 210 const char *name; 211 { 212 if (setfsent()) 213 while (fstabscan()) 214 if (!strcmp(_fs_fstab.fs_file, name)) 215 return(&_fs_fstab); 216 return((struct fstab *)NULL); 217 } 218 219 int 220 setfsent() 221 { 222 if (_fs_fp) { 223 rewind(_fs_fp); 224 LineNo = 0; 225 return(1); 226 } 227 if ((_fs_fp = fopen(_PATH_FSTAB, "r")) != NULL) { 228 LineNo = 0; 229 return(1); 230 } 231 error(errno); 232 return(0); 233 } 234 235 void 236 endfsent() 237 { 238 if (_fs_fp) { 239 (void)fclose(_fs_fp); 240 _fs_fp = NULL; 241 } 242 } 243 244 static void 245 error(err) 246 int err; 247 { 248 char *p; 249 char num[30]; 250 251 (void)_write(STDERR_FILENO, "fstab: ", 7); 252 (void)_write(STDERR_FILENO, _PATH_FSTAB, sizeof(_PATH_FSTAB) - 1); 253 (void)_write(STDERR_FILENO, ":", 1); 254 sprintf(num, "%d: ", LineNo); 255 (void)_write(STDERR_FILENO, num, strlen(num)); 256 p = strerror(err); 257 (void)_write(STDERR_FILENO, p, strlen(p)); 258 (void)_write(STDERR_FILENO, "\n", 1); 259 } 260