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