1 /* 2 * $Id: info_file.c,v 5.2.1.2 91/03/03 20:39:34 jsp Alpha $ 3 * 4 * Copyright (c) 1990 Jan-Simon Pendry 5 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 6 * Copyright (c) 1990 The Regents of the University of California. 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by 10 * Jan-Simon Pendry at Imperial College, London. 11 * 12 * %sccs.include.redist.c% 13 * 14 * @(#)info_file.c 5.2 (Berkeley) 03/17/91 15 */ 16 17 /* 18 * Get info from file 19 */ 20 21 #include "am.h" 22 23 #ifdef HAS_FILE_MAPS 24 #include <ctype.h> 25 #include <sys/stat.h> 26 27 #define MAX_LINE_LEN 2048 28 29 static int read_line P((char *buf, int size, FILE *fp)); 30 static int read_line(buf, size, fp) 31 char *buf; 32 int size; 33 FILE *fp; 34 { 35 int done = 0; 36 37 do { 38 while (fgets(buf, size, fp)) { 39 int len = strlen(buf); 40 done += len; 41 if (len > 1 && buf[len-2] == '\\' && 42 buf[len-1] == '\n') { 43 int ch; 44 buf += len - 2; 45 size -= len - 2; 46 /* 47 * Skip leading white space on next line 48 */ 49 while ((ch = getc(fp)) != EOF && 50 isascii(ch) && isspace(ch)) 51 ; 52 (void) ungetc(ch, fp); 53 } else { 54 return done; 55 } 56 } 57 } while (size > 0 && !feof(fp)); 58 59 return done; 60 } 61 62 /* 63 * Try to locate a key in a file 64 */ 65 static int search_or_reload_file P((FILE *fp, char *map, char *key, char **val, mnt_map *m, void (*fn)(mnt_map *m, char*, char*))); 66 static int search_or_reload_file(fp, map, key, val, m, fn) 67 FILE *fp; 68 char *map; 69 char *key; 70 char **val; 71 mnt_map *m; 72 void (*fn) P((mnt_map*, char*, char*)); 73 { 74 char key_val[MAX_LINE_LEN]; 75 int chuck = 0; 76 int line_no = 0; 77 78 while (read_line(key_val, sizeof(key_val), fp)) { 79 char *kp; 80 char *cp; 81 char *hash; 82 int len = strlen(key_val); 83 line_no++; 84 85 /* 86 * Make sure we got the whole line 87 */ 88 if (key_val[len-1] != '\n') { 89 plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map); 90 chuck = 1; 91 } else { 92 key_val[len-1] = '\0'; 93 } 94 95 /* 96 * Strip comments 97 */ 98 hash = strchr(key_val, '#'); 99 if (hash) 100 *hash = '\0'; 101 102 /* 103 * Find start of key 104 */ 105 for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++) 106 ; 107 108 /* 109 * Ignore blank lines 110 */ 111 if (!*kp) 112 goto again; 113 114 /* 115 * Find end of key 116 */ 117 for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++) 118 ; 119 120 /* 121 * Check whether key matches 122 */ 123 if (*cp) 124 *cp++ = '\0'; 125 126 if (fn || (*key == *kp && strcmp(key, kp) == 0)) { 127 while (*cp && isascii(*cp) && isspace(*cp)) 128 cp++; 129 if (*cp) { 130 /* 131 * Return a copy of the data 132 */ 133 char *dc = strdup(cp); 134 if (fn) { 135 (*fn)(m, strdup(kp), dc); 136 } else { 137 *val = dc; 138 #ifdef DEBUG 139 dlog("%s returns %s", key, dc); 140 #endif /* DEBUG */ 141 } 142 if (!fn) 143 return 0; 144 } else { 145 plog(XLOG_USER, "%s: line %d has no value field", map, line_no); 146 } 147 } 148 149 again: 150 /* 151 * If the last read didn't get a whole line then 152 * throw away the remainder before continuing... 153 */ 154 if (chuck) { 155 while (fgets(key_val, sizeof(key_val), fp) && 156 !strchr(key_val, '\n')) 157 ; 158 chuck = 0; 159 } 160 } 161 162 return fn ? 0 : ENOENT; 163 } 164 165 static FILE *file_open P((char *map, time_t *tp)); 166 static FILE *file_open(map, tp) 167 char *map; 168 time_t *tp; 169 { 170 FILE *mapf = fopen(map, "r"); 171 if (mapf && tp) { 172 struct stat stb; 173 if (fstat(fileno(mapf), &stb) < 0) 174 *tp = clocktime(); 175 else 176 *tp = stb.st_mtime; 177 } 178 return mapf; 179 } 180 181 int file_init P((char *map, time_t *tp)); 182 int file_init(map, tp) 183 char *map; 184 time_t *tp; 185 { 186 FILE *mapf = file_open(map, tp); 187 if (mapf) { 188 (void) fclose(mapf); 189 return 0; 190 } 191 return errno; 192 } 193 194 int file_reload P((mnt_map *m, char *map, void (*fn)())); 195 int file_reload(m, map, fn) 196 mnt_map *m; 197 char *map; 198 void (*fn)(); 199 { 200 FILE *mapf = file_open(map, (time_t *) 0); 201 if (mapf) { 202 int error = search_or_reload_file(mapf, map, 0, 0, m, fn); 203 (void) fclose(mapf); 204 return error; 205 } 206 207 return errno; 208 } 209 210 int file_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp)); 211 int file_search(m, map, key, pval, tp) 212 mnt_map *m; 213 char *map; 214 char *key; 215 char **pval; 216 time_t *tp; 217 { 218 time_t t; 219 FILE *mapf = file_open(map, &t); 220 if (mapf) { 221 int error; 222 if (*tp < t) { 223 *tp = t; 224 error = -1; 225 } else { 226 error = search_or_reload_file(mapf, map, key, pval, 0, 0); 227 } 228 (void) fclose(mapf); 229 return error; 230 } 231 232 return errno; 233 } 234 235 int file_mtime P((char *map, time_t *tp)); 236 int file_mtime(map, tp) 237 char *map; 238 time_t *tp; 239 { 240 FILE *mapf = file_open(map, tp); 241 if (mapf) { 242 (void) fclose(mapf); 243 return 0; 244 } 245 246 return errno; 247 } 248 #endif /* HAS_FILE_MAPS */ 249