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