1 /* $OpenBSD: fstab.c,v 1.22 2016/03/17 23:48:42 mmcc 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(NULL, ":\n", &last); 68 _fs_fstab.fs_type = strtok_r(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(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(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(NULL, " \t\n", &last); 99 _fs_fstab.fs_vfstype = strtok_r(NULL, " \t\n", &last); 100 _fs_fstab.fs_mntops = strtok_r(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(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(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(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 } 152 153 struct fstab * 154 getfsent(void) 155 { 156 if ((!_fs_fp && !setfsent()) || !fstabscan()) 157 return(NULL); 158 return(&_fs_fstab); 159 } 160 161 struct fstab * 162 getfsspec(const char *name) 163 { 164 if (setfsent()) 165 while (fstabscan()) 166 if (!strcmp(_fs_fstab.fs_spec, name)) 167 return(&_fs_fstab); 168 return(NULL); 169 } 170 171 struct fstab * 172 getfsfile(const char *name) 173 { 174 if (setfsent()) 175 while (fstabscan()) 176 if (!strcmp(_fs_fstab.fs_file, name)) 177 return(&_fs_fstab); 178 return(NULL); 179 } 180 181 int 182 setfsent(void) 183 { 184 struct stat sbuf; 185 186 if (_fs_fp) { 187 rewind(_fs_fp); 188 return(1); 189 } 190 191 if (stat(_PATH_FSTAB, &sbuf) != 0) 192 goto fail; 193 if ((sbuf.st_size == 0) || ((sbuf.st_mode & S_IFMT) != S_IFREG)) { 194 errno = EFTYPE; 195 goto fail; 196 } 197 198 if ((_fs_fp = fopen(_PATH_FSTAB, "re"))) 199 return(1); 200 201 fail: 202 return(0); 203 } 204 DEF_WEAK(setfsent); 205 206 void 207 endfsent(void) 208 { 209 if (_fs_fp) { 210 (void)fclose(_fs_fp); 211 _fs_fp = NULL; 212 } 213 } 214