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