144626Smckusick /* 2*47526Spendry * $Id: info_file.c,v 5.2.1.2 91/03/03 20:39:34 jsp Alpha $ 344626Smckusick * 444626Smckusick * Copyright (c) 1990 Jan-Simon Pendry 544626Smckusick * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 644626Smckusick * Copyright (c) 1990 The Regents of the University of California. 744626Smckusick * All rights reserved. 844626Smckusick * 944626Smckusick * This code is derived from software contributed to Berkeley by 1044626Smckusick * Jan-Simon Pendry at Imperial College, London. 1144626Smckusick * 1244626Smckusick * %sccs.include.redist.c% 1344626Smckusick * 14*47526Spendry * @(#)info_file.c 5.2 (Berkeley) 03/17/91 1544626Smckusick */ 1644626Smckusick 1744626Smckusick /* 1844626Smckusick * Get info from file 1944626Smckusick */ 2044626Smckusick 2144626Smckusick #include "am.h" 2244626Smckusick 2344626Smckusick #ifdef HAS_FILE_MAPS 2444626Smckusick #include <ctype.h> 2544626Smckusick #include <sys/stat.h> 2644626Smckusick 2744626Smckusick #define MAX_LINE_LEN 2048 2844626Smckusick 29*47526Spendry static int read_line P((char *buf, int size, FILE *fp)); 3044626Smckusick static int read_line(buf, size, fp) 3144626Smckusick char *buf; 3244626Smckusick int size; 3344626Smckusick FILE *fp; 3444626Smckusick { 3544626Smckusick int done = 0; 3644626Smckusick 3744626Smckusick do { 3844626Smckusick while (fgets(buf, size, fp)) { 3944626Smckusick int len = strlen(buf); 4044626Smckusick done += len; 4144626Smckusick if (len > 1 && buf[len-2] == '\\' && 4244626Smckusick buf[len-1] == '\n') { 4344626Smckusick int ch; 4444626Smckusick buf += len - 2; 4544626Smckusick size -= len - 2; 4644626Smckusick /* 4744626Smckusick * Skip leading white space on next line 4844626Smckusick */ 4944626Smckusick while ((ch = getc(fp)) != EOF && 5044626Smckusick isascii(ch) && isspace(ch)) 5144626Smckusick ; 5244626Smckusick (void) ungetc(ch, fp); 5344626Smckusick } else { 5444626Smckusick return done; 5544626Smckusick } 5644626Smckusick } 5744626Smckusick } while (size > 0 && !feof(fp)); 5844626Smckusick 5944626Smckusick return done; 6044626Smckusick } 6144626Smckusick 6244626Smckusick /* 6344626Smckusick * Try to locate a key in a file 6444626Smckusick */ 65*47526Spendry 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*))); 6644626Smckusick static int search_or_reload_file(fp, map, key, val, m, fn) 6744626Smckusick FILE *fp; 6844626Smckusick char *map; 6944626Smckusick char *key; 7044626Smckusick char **val; 7144626Smckusick mnt_map *m; 7244626Smckusick void (*fn) P((mnt_map*, char*, char*)); 7344626Smckusick { 7444626Smckusick char key_val[MAX_LINE_LEN]; 7544626Smckusick int chuck = 0; 7644626Smckusick int line_no = 0; 7744626Smckusick 7844626Smckusick while (read_line(key_val, sizeof(key_val), fp)) { 7944626Smckusick char *kp; 8044626Smckusick char *cp; 8144626Smckusick char *hash; 8244626Smckusick int len = strlen(key_val); 8344626Smckusick line_no++; 8444626Smckusick 8544626Smckusick /* 8644626Smckusick * Make sure we got the whole line 8744626Smckusick */ 8844626Smckusick if (key_val[len-1] != '\n') { 8944626Smckusick plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map); 9044626Smckusick chuck = 1; 9144626Smckusick } else { 9244626Smckusick key_val[len-1] = '\0'; 9344626Smckusick } 9444626Smckusick 9544626Smckusick /* 9644626Smckusick * Strip comments 9744626Smckusick */ 9844626Smckusick hash = strchr(key_val, '#'); 9944626Smckusick if (hash) 10044626Smckusick *hash = '\0'; 10144626Smckusick 10244626Smckusick /* 10344626Smckusick * Find start of key 10444626Smckusick */ 10544626Smckusick for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++) 10644626Smckusick ; 10744626Smckusick 10844626Smckusick /* 10944626Smckusick * Ignore blank lines 11044626Smckusick */ 11144626Smckusick if (!*kp) 11244626Smckusick goto again; 11344626Smckusick 11444626Smckusick /* 11544626Smckusick * Find end of key 11644626Smckusick */ 11744626Smckusick for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++) 11844626Smckusick ; 11944626Smckusick 12044626Smckusick /* 12144626Smckusick * Check whether key matches 12244626Smckusick */ 12344626Smckusick if (*cp) 12444626Smckusick *cp++ = '\0'; 12544626Smckusick 126*47526Spendry if (fn || (*key == *kp && strcmp(key, kp) == 0)) { 12744626Smckusick while (*cp && isascii(*cp) && isspace(*cp)) 12844626Smckusick cp++; 12944626Smckusick if (*cp) { 13044626Smckusick /* 13144626Smckusick * Return a copy of the data 13244626Smckusick */ 13344626Smckusick char *dc = strdup(cp); 134*47526Spendry if (fn) { 135*47526Spendry (*fn)(m, strdup(kp), dc); 136*47526Spendry } else { 13744626Smckusick *val = dc; 13844626Smckusick #ifdef DEBUG 139*47526Spendry dlog("%s returns %s", key, dc); 14044626Smckusick #endif /* DEBUG */ 141*47526Spendry } 14244626Smckusick if (!fn) 14344626Smckusick return 0; 14444626Smckusick } else { 14544626Smckusick plog(XLOG_USER, "%s: line %d has no value field", map, line_no); 14644626Smckusick } 14744626Smckusick } 14844626Smckusick 14944626Smckusick again: 15044626Smckusick /* 15144626Smckusick * If the last read didn't get a whole line then 15244626Smckusick * throw away the remainder before continuing... 15344626Smckusick */ 15444626Smckusick if (chuck) { 15544626Smckusick while (fgets(key_val, sizeof(key_val), fp) && 15644626Smckusick !strchr(key_val, '\n')) 15744626Smckusick ; 15844626Smckusick chuck = 0; 15944626Smckusick } 16044626Smckusick } 16144626Smckusick 16244626Smckusick return fn ? 0 : ENOENT; 16344626Smckusick } 16444626Smckusick 165*47526Spendry static FILE *file_open P((char *map, time_t *tp)); 166*47526Spendry static FILE *file_open(map, tp) 16744626Smckusick char *map; 168*47526Spendry time_t *tp; 16944626Smckusick { 17044626Smckusick FILE *mapf = fopen(map, "r"); 171*47526Spendry if (mapf && tp) { 172*47526Spendry struct stat stb; 173*47526Spendry if (fstat(fileno(mapf), &stb) < 0) 174*47526Spendry *tp = clocktime(); 175*47526Spendry else 176*47526Spendry *tp = stb.st_mtime; 177*47526Spendry } 178*47526Spendry return mapf; 179*47526Spendry } 180*47526Spendry 181*47526Spendry int file_init P((char *map, time_t *tp)); 182*47526Spendry int file_init(map, tp) 183*47526Spendry char *map; 184*47526Spendry time_t *tp; 185*47526Spendry { 186*47526Spendry FILE *mapf = file_open(map, tp); 18744626Smckusick if (mapf) { 18844626Smckusick (void) fclose(mapf); 18944626Smckusick return 0; 19044626Smckusick } 19144626Smckusick return errno; 19244626Smckusick } 19344626Smckusick 194*47526Spendry int file_reload P((mnt_map *m, char *map, void (*fn)())); 19544626Smckusick int file_reload(m, map, fn) 19644626Smckusick mnt_map *m; 19744626Smckusick char *map; 19844626Smckusick void (*fn)(); 19944626Smckusick { 200*47526Spendry FILE *mapf = file_open(map, (time_t *) 0); 20144626Smckusick if (mapf) { 20244626Smckusick int error = search_or_reload_file(mapf, map, 0, 0, m, fn); 20344626Smckusick (void) fclose(mapf); 20444626Smckusick return error; 20544626Smckusick } 20644626Smckusick 20744626Smckusick return errno; 20844626Smckusick } 20944626Smckusick 210*47526Spendry int file_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp)); 21144626Smckusick int file_search(m, map, key, pval, tp) 21244626Smckusick mnt_map *m; 21344626Smckusick char *map; 21444626Smckusick char *key; 21544626Smckusick char **pval; 21644626Smckusick time_t *tp; 21744626Smckusick { 218*47526Spendry time_t t; 219*47526Spendry FILE *mapf = file_open(map, &t); 22044626Smckusick if (mapf) { 22144626Smckusick int error; 222*47526Spendry if (*tp < t) { 223*47526Spendry *tp = t; 22444626Smckusick error = -1; 22544626Smckusick } else { 22644626Smckusick error = search_or_reload_file(mapf, map, key, pval, 0, 0); 22744626Smckusick } 22844626Smckusick (void) fclose(mapf); 22944626Smckusick return error; 23044626Smckusick } 23144626Smckusick 23244626Smckusick return errno; 23344626Smckusick } 234*47526Spendry 235*47526Spendry int file_mtime P((char *map, time_t *tp)); 236*47526Spendry int file_mtime(map, tp) 237*47526Spendry char *map; 238*47526Spendry time_t *tp; 239*47526Spendry { 240*47526Spendry FILE *mapf = file_open(map, tp); 241*47526Spendry if (mapf) { 242*47526Spendry (void) fclose(mapf); 243*47526Spendry return 0; 244*47526Spendry } 245*47526Spendry 246*47526Spendry return errno; 247*47526Spendry } 24844626Smckusick #endif /* HAS_FILE_MAPS */ 249