1 /* $OpenBSD: fstab.c,v 1.18 2009/06/03 18:18:23 jsg Exp $ */ 2 /* 3 * Copyright (c) 1980, 1988, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the University nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #include <sys/types.h> 32 #include <sys/uio.h> 33 #include <sys/stat.h> 34 35 #include <errno.h> 36 #include <limits.h> 37 #include <fstab.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <unistd.h> 42 43 static FILE *_fs_fp; 44 static struct fstab _fs_fstab; 45 46 static int fstabscan(void); 47 48 static int 49 fstabscan(void) 50 { 51 char *cp; 52 #define MAXLINELENGTH 1024 53 static char line[MAXLINELENGTH]; 54 char subline[MAXLINELENGTH]; 55 const char *errstr; 56 char *last; 57 int typexx; 58 59 for (;;) { 60 if (!(cp = fgets(line, sizeof(line), _fs_fp))) 61 return(0); 62 /* OLD_STYLE_FSTAB */ 63 if (!strpbrk(cp, " \t")) { 64 _fs_fstab.fs_spec = strtok_r(cp, ":\n", &last); 65 if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#') 66 continue; 67 _fs_fstab.fs_file = strtok_r((char *)NULL, ":\n", &last); 68 _fs_fstab.fs_type = strtok_r((char *)NULL, ":\n", &last); 69 if (_fs_fstab.fs_type) { 70 if (!strcmp(_fs_fstab.fs_type, FSTAB_XX)) 71 continue; 72 _fs_fstab.fs_mntops = _fs_fstab.fs_type; 73 _fs_fstab.fs_vfstype = 74 strcmp(_fs_fstab.fs_type, FSTAB_SW) ? 75 "ufs" : "swap"; 76 if ((cp = strtok_r((char *)NULL, ":\n", &last))) { 77 _fs_fstab.fs_freq = strtonum(cp, 0, 78 INT_MAX, &errstr); 79 if (errstr) 80 goto bad; 81 if ((cp = strtok_r((char *)NULL, 82 ":\n", &last))) { 83 _fs_fstab.fs_passno = 84 strtonum(cp, 0, INT_MAX, 85 &errstr); 86 if (errstr) 87 goto bad; 88 return(1); 89 } 90 } 91 } 92 goto bad; 93 } 94 /* OLD_STYLE_FSTAB */ 95 _fs_fstab.fs_spec = strtok_r(cp, " \t\n", &last); 96 if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#') 97 continue; 98 _fs_fstab.fs_file = strtok_r((char *)NULL, " \t\n", &last); 99 _fs_fstab.fs_vfstype = strtok_r((char *)NULL, " \t\n", &last); 100 _fs_fstab.fs_mntops = strtok_r((char *)NULL, " \t\n", &last); 101 if (_fs_fstab.fs_mntops == NULL) 102 goto bad; 103 _fs_fstab.fs_freq = 0; 104 _fs_fstab.fs_passno = 0; 105 if ((cp = strtok_r((char *)NULL, " \t\n", &last)) != NULL) { 106 _fs_fstab.fs_freq = strtonum(cp, 0, INT_MAX, &errstr); 107 if (errstr) 108 goto bad; 109 if ((cp = strtok_r((char *)NULL, " \t\n", &last)) != NULL) { 110 _fs_fstab.fs_passno = strtonum(cp, 0, INT_MAX, 111 &errstr); 112 if (errstr) 113 goto bad; 114 } 115 } 116 strlcpy(subline, _fs_fstab.fs_mntops, sizeof subline); 117 for (typexx = 0, cp = strtok_r(subline, ",", &last); cp; 118 cp = strtok_r((char *)NULL, ",", &last)) { 119 if (strlen(cp) != 2) 120 continue; 121 if (!strcmp(cp, FSTAB_RW)) { 122 _fs_fstab.fs_type = FSTAB_RW; 123 break; 124 } 125 if (!strcmp(cp, FSTAB_RQ)) { 126 _fs_fstab.fs_type = FSTAB_RQ; 127 break; 128 } 129 if (!strcmp(cp, FSTAB_RO)) { 130 _fs_fstab.fs_type = FSTAB_RO; 131 break; 132 } 133 if (!strcmp(cp, FSTAB_SW)) { 134 _fs_fstab.fs_type = FSTAB_SW; 135 break; 136 } 137 if (!strcmp(cp, FSTAB_XX)) { 138 _fs_fstab.fs_type = FSTAB_XX; 139 typexx++; 140 break; 141 } 142 } 143 if (typexx) 144 continue; 145 if (cp != NULL) 146 return(1); 147 148 bad: /* We silently ignore all bogus lines */ 149 ; 150 } 151 /* NOTREACHED */ 152 } 153 154 struct fstab * 155 getfsent(void) 156 { 157 if ((!_fs_fp && !setfsent()) || !fstabscan()) 158 return(NULL); 159 return(&_fs_fstab); 160 } 161 162 struct fstab * 163 getfsspec(const char *name) 164 { 165 if (setfsent()) 166 while (fstabscan()) 167 if (!strcmp(_fs_fstab.fs_spec, name)) 168 return(&_fs_fstab); 169 return((struct fstab *)NULL); 170 } 171 172 struct fstab * 173 getfsfile(const char *name) 174 { 175 if (setfsent()) 176 while (fstabscan()) 177 if (!strcmp(_fs_fstab.fs_file, name)) 178 return(&_fs_fstab); 179 return((struct fstab *)NULL); 180 } 181 182 int 183 setfsent(void) 184 { 185 struct stat sbuf; 186 187 if (_fs_fp) { 188 rewind(_fs_fp); 189 return(1); 190 } 191 192 if (stat(_PATH_FSTAB, &sbuf) != 0) 193 goto fail; 194 if ((sbuf.st_size == 0) || ((sbuf.st_mode & S_IFMT) != S_IFREG)) { 195 errno = EFTYPE; 196 goto fail; 197 } 198 199 if ((_fs_fp = fopen(_PATH_FSTAB, "r"))) 200 return(1); 201 202 fail: 203 return(0); 204 } 205 206 void 207 endfsent(void) 208 { 209 if (_fs_fp) { 210 (void)fclose(_fs_fp); 211 _fs_fp = NULL; 212 } 213 } 214