info_file.c revision 42629
1/* 2 * Copyright (c) 1997-1998 Erez Zadok 3 * Copyright (c) 1990 Jan-Simon Pendry 4 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 5 * Copyright (c) 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Jan-Simon Pendry at Imperial College, London. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgment: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * %W% (Berkeley) %G% 40 * 41 * $Id: info_file.c,v 1.1.1.1 1998/11/05 02:04:49 ezk Exp $ 42 * 43 */ 44 45/* 46 * Get info from file 47 */ 48 49#ifdef HAVE_CONFIG_H 50# include <config.h> 51#endif /* HAVE_CONFIG_H */ 52#include <am_defs.h> 53#include <amd.h> 54 55#define MAX_LINE_LEN 1500 56 57/* forward declarations */ 58int file_init(mnt_map *m, char *map, time_t *tp); 59int file_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *)); 60int file_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp); 61int file_mtime(mnt_map *m, char *map, time_t *tp); 62 63 64static int 65read_line(char *buf, int size, FILE * fp) 66{ 67 int done = 0; 68 69 do { 70 while (fgets(buf, size, fp)) { 71 int len = strlen(buf); 72 done += len; 73 if (len > 1 && buf[len - 2] == '\\' && 74 buf[len - 1] == '\n') { 75 int ch; 76 buf += len - 2; 77 size -= len - 2; 78 *buf = '\n'; 79 buf[1] = '\0'; 80 /* 81 * Skip leading white space on next line 82 */ 83 while ((ch = getc(fp)) != EOF && 84 isascii(ch) && isspace(ch)) ; 85 (void) ungetc(ch, fp); 86 } else { 87 return done; 88 } 89 } 90 } while (size > 0 && !feof(fp)); 91 92 return done; 93} 94 95 96/* 97 * Try to locate a key in a file 98 */ 99static int 100search_or_reload_file(FILE * fp, char *map, char *key, char **val, mnt_map *m, void (*fn) (mnt_map *m, char *, char *)) 101{ 102 char key_val[MAX_LINE_LEN]; 103 int chuck = 0; 104 int line_no = 0; 105 106 while (read_line(key_val, sizeof(key_val), fp)) { 107 char *kp; 108 char *cp; 109 char *hash; 110 int len = strlen(key_val); 111 line_no++; 112 113 /* 114 * Make sure we got the whole line 115 */ 116 if (key_val[len - 1] != '\n') { 117 plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map); 118 chuck = 1; 119 } else { 120 key_val[len - 1] = '\0'; 121 } 122 123 /* 124 * Strip comments 125 */ 126 hash = strchr(key_val, '#'); 127 if (hash) 128 *hash = '\0'; 129 130 /* 131 * Find start of key 132 */ 133 for (kp = key_val; *kp && isascii(*kp) && isspace((int)*kp); kp++) ; 134 135 /* 136 * Ignore blank lines 137 */ 138 if (!*kp) 139 goto again; 140 141 /* 142 * Find end of key 143 */ 144 for (cp = kp; *cp && (!isascii(*cp) || !isspace((int)*cp)); cp++) ; 145 146 /* 147 * Check whether key matches 148 */ 149 if (*cp) 150 *cp++ = '\0'; 151 152 if (fn || (*key == *kp && STREQ(key, kp))) { 153 while (*cp && isascii(*cp) && isspace((int)*cp)) 154 cp++; 155 if (*cp) { 156 /* 157 * Return a copy of the data 158 */ 159 char *dc = strdup(cp); 160 if (fn) { 161 (*fn) (m, strdup(kp), dc); 162 } else { 163 *val = dc; 164#ifdef DEBUG 165 dlog("%s returns %s", key, dc); 166#endif /* DEBUG */ 167 } 168 if (!fn) 169 return 0; 170 } else { 171 plog(XLOG_USER, "%s: line %d has no value field", map, line_no); 172 } 173 } 174 175 again: 176 /* 177 * If the last read didn't get a whole line then 178 * throw away the remainder before continuing... 179 */ 180 if (chuck) { 181 while (fgets(key_val, sizeof(key_val), fp) && 182 !strchr(key_val, '\n')) ; 183 chuck = 0; 184 } 185 } 186 187 return fn ? 0 : ENOENT; 188} 189 190 191static FILE * 192file_open(char *map, time_t *tp) 193{ 194 FILE *mapf = fopen(map, "r"); 195 196 if (mapf && tp) { 197 struct stat stb; 198 if (fstat(fileno(mapf), &stb) < 0) 199 *tp = clocktime(); 200 else 201 *tp = stb.st_mtime; 202 } 203 return mapf; 204} 205 206 207int 208file_init(mnt_map *m, char *map, time_t *tp) 209{ 210 FILE *mapf = file_open(map, tp); 211 212 if (mapf) { 213 fclose(mapf); 214 return 0; 215 } 216 return errno; 217} 218 219 220int 221file_reload(mnt_map *m, char *map, void (*fn) (mnt_map *, char *, char *)) 222{ 223 FILE *mapf = file_open(map, (time_t *) 0); 224 225 if (mapf) { 226 int error = search_or_reload_file(mapf, map, 0, 0, m, fn); 227 (void) fclose(mapf); 228 return error; 229 } 230 return errno; 231} 232 233 234int 235file_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp) 236{ 237 time_t t; 238 FILE *mapf = file_open(map, &t); 239 240 if (mapf) { 241 int error; 242 if (*tp < t) { 243 *tp = t; 244 error = -1; 245 } else { 246 error = search_or_reload_file(mapf, map, key, pval, 0, 0); 247 } 248 (void) fclose(mapf); 249 return error; 250 } 251 return errno; 252} 253 254 255int 256file_mtime(mnt_map *m, char *map, time_t *tp) 257{ 258 FILE *mapf = file_open(map, tp); 259 260 if (mapf) { 261 (void) fclose(mapf); 262 return 0; 263 } 264 return errno; 265} 266