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