144626Smckusick /* 244626Smckusick * Copyright (c) 1990 Jan-Simon Pendry 344626Smckusick * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 444626Smckusick * Copyright (c) 1990 The Regents of the University of California. 544626Smckusick * All rights reserved. 644626Smckusick * 744626Smckusick * This code is derived from software contributed to Berkeley by 844626Smckusick * Jan-Simon Pendry at Imperial College, London. 944626Smckusick * 1044626Smckusick * %sccs.include.redist.c% 1144626Smckusick * 12*49683Spendry * @(#)info_file.c 5.3 (Berkeley) 05/12/91 13*49683Spendry * 14*49683Spendry * $Id: info_file.c,v 5.2.1.4 91/05/07 22:17:57 jsp Alpha $ 15*49683Spendry * 1644626Smckusick */ 1744626Smckusick 1844626Smckusick /* 1944626Smckusick * Get info from file 2044626Smckusick */ 2144626Smckusick 2244626Smckusick #include "am.h" 2344626Smckusick 2444626Smckusick #ifdef HAS_FILE_MAPS 2544626Smckusick #include <ctype.h> 2644626Smckusick #include <sys/stat.h> 2744626Smckusick 2844626Smckusick #define MAX_LINE_LEN 2048 2944626Smckusick 3047526Spendry static int read_line P((char *buf, int size, FILE *fp)); 3144626Smckusick static int read_line(buf, size, fp) 3244626Smckusick char *buf; 3344626Smckusick int size; 3444626Smckusick FILE *fp; 3544626Smckusick { 3644626Smckusick int done = 0; 3744626Smckusick 3844626Smckusick do { 3944626Smckusick while (fgets(buf, size, fp)) { 4044626Smckusick int len = strlen(buf); 4144626Smckusick done += len; 4244626Smckusick if (len > 1 && buf[len-2] == '\\' && 4344626Smckusick buf[len-1] == '\n') { 4444626Smckusick int ch; 4544626Smckusick buf += len - 2; 4644626Smckusick size -= len - 2; 47*49683Spendry *buf = '\n'; buf[1] = '\0'; 4844626Smckusick /* 4944626Smckusick * Skip leading white space on next line 5044626Smckusick */ 5144626Smckusick while ((ch = getc(fp)) != EOF && 5244626Smckusick isascii(ch) && isspace(ch)) 5344626Smckusick ; 5444626Smckusick (void) ungetc(ch, fp); 5544626Smckusick } else { 5644626Smckusick return done; 5744626Smckusick } 5844626Smckusick } 5944626Smckusick } while (size > 0 && !feof(fp)); 6044626Smckusick 6144626Smckusick return done; 6244626Smckusick } 6344626Smckusick 6444626Smckusick /* 6544626Smckusick * Try to locate a key in a file 6644626Smckusick */ 6747526Spendry 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*))); 6844626Smckusick static int search_or_reload_file(fp, map, key, val, m, fn) 6944626Smckusick FILE *fp; 7044626Smckusick char *map; 7144626Smckusick char *key; 7244626Smckusick char **val; 7344626Smckusick mnt_map *m; 7444626Smckusick void (*fn) P((mnt_map*, char*, char*)); 7544626Smckusick { 7644626Smckusick char key_val[MAX_LINE_LEN]; 7744626Smckusick int chuck = 0; 7844626Smckusick int line_no = 0; 7944626Smckusick 8044626Smckusick while (read_line(key_val, sizeof(key_val), fp)) { 8144626Smckusick char *kp; 8244626Smckusick char *cp; 8344626Smckusick char *hash; 8444626Smckusick int len = strlen(key_val); 8544626Smckusick line_no++; 8644626Smckusick 8744626Smckusick /* 8844626Smckusick * Make sure we got the whole line 8944626Smckusick */ 9044626Smckusick if (key_val[len-1] != '\n') { 9144626Smckusick plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map); 9244626Smckusick chuck = 1; 9344626Smckusick } else { 9444626Smckusick key_val[len-1] = '\0'; 9544626Smckusick } 9644626Smckusick 9744626Smckusick /* 9844626Smckusick * Strip comments 9944626Smckusick */ 10044626Smckusick hash = strchr(key_val, '#'); 10144626Smckusick if (hash) 10244626Smckusick *hash = '\0'; 10344626Smckusick 10444626Smckusick /* 10544626Smckusick * Find start of key 10644626Smckusick */ 10744626Smckusick for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++) 10844626Smckusick ; 10944626Smckusick 11044626Smckusick /* 11144626Smckusick * Ignore blank lines 11244626Smckusick */ 11344626Smckusick if (!*kp) 11444626Smckusick goto again; 11544626Smckusick 11644626Smckusick /* 11744626Smckusick * Find end of key 11844626Smckusick */ 11944626Smckusick for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++) 12044626Smckusick ; 12144626Smckusick 12244626Smckusick /* 12344626Smckusick * Check whether key matches 12444626Smckusick */ 12544626Smckusick if (*cp) 12644626Smckusick *cp++ = '\0'; 12744626Smckusick 12847526Spendry if (fn || (*key == *kp && strcmp(key, kp) == 0)) { 12944626Smckusick while (*cp && isascii(*cp) && isspace(*cp)) 13044626Smckusick cp++; 13144626Smckusick if (*cp) { 13244626Smckusick /* 13344626Smckusick * Return a copy of the data 13444626Smckusick */ 13544626Smckusick char *dc = strdup(cp); 13647526Spendry if (fn) { 13747526Spendry (*fn)(m, strdup(kp), dc); 13847526Spendry } else { 13944626Smckusick *val = dc; 14044626Smckusick #ifdef DEBUG 14147526Spendry dlog("%s returns %s", key, dc); 14244626Smckusick #endif /* DEBUG */ 14347526Spendry } 14444626Smckusick if (!fn) 14544626Smckusick return 0; 14644626Smckusick } else { 14744626Smckusick plog(XLOG_USER, "%s: line %d has no value field", map, line_no); 14844626Smckusick } 14944626Smckusick } 15044626Smckusick 15144626Smckusick again: 15244626Smckusick /* 15344626Smckusick * If the last read didn't get a whole line then 15444626Smckusick * throw away the remainder before continuing... 15544626Smckusick */ 15644626Smckusick if (chuck) { 15744626Smckusick while (fgets(key_val, sizeof(key_val), fp) && 15844626Smckusick !strchr(key_val, '\n')) 15944626Smckusick ; 16044626Smckusick chuck = 0; 16144626Smckusick } 16244626Smckusick } 16344626Smckusick 16444626Smckusick return fn ? 0 : ENOENT; 16544626Smckusick } 16644626Smckusick 16747526Spendry static FILE *file_open P((char *map, time_t *tp)); 16847526Spendry static FILE *file_open(map, tp) 16944626Smckusick char *map; 17047526Spendry time_t *tp; 17144626Smckusick { 17244626Smckusick FILE *mapf = fopen(map, "r"); 17347526Spendry if (mapf && tp) { 17447526Spendry struct stat stb; 17547526Spendry if (fstat(fileno(mapf), &stb) < 0) 17647526Spendry *tp = clocktime(); 17747526Spendry else 17847526Spendry *tp = stb.st_mtime; 17947526Spendry } 18047526Spendry return mapf; 18147526Spendry } 18247526Spendry 18347526Spendry int file_init P((char *map, time_t *tp)); 18447526Spendry int file_init(map, tp) 18547526Spendry char *map; 18647526Spendry time_t *tp; 18747526Spendry { 18847526Spendry FILE *mapf = file_open(map, tp); 18944626Smckusick if (mapf) { 19044626Smckusick (void) fclose(mapf); 19144626Smckusick return 0; 19244626Smckusick } 19344626Smckusick return errno; 19444626Smckusick } 19544626Smckusick 19647526Spendry int file_reload P((mnt_map *m, char *map, void (*fn)())); 19744626Smckusick int file_reload(m, map, fn) 19844626Smckusick mnt_map *m; 19944626Smckusick char *map; 20044626Smckusick void (*fn)(); 20144626Smckusick { 20247526Spendry FILE *mapf = file_open(map, (time_t *) 0); 20344626Smckusick if (mapf) { 20444626Smckusick int error = search_or_reload_file(mapf, map, 0, 0, m, fn); 20544626Smckusick (void) fclose(mapf); 20644626Smckusick return error; 20744626Smckusick } 20844626Smckusick 20944626Smckusick return errno; 21044626Smckusick } 21144626Smckusick 21247526Spendry int file_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp)); 21344626Smckusick int file_search(m, map, key, pval, tp) 21444626Smckusick mnt_map *m; 21544626Smckusick char *map; 21644626Smckusick char *key; 21744626Smckusick char **pval; 21844626Smckusick time_t *tp; 21944626Smckusick { 22047526Spendry time_t t; 22147526Spendry FILE *mapf = file_open(map, &t); 22244626Smckusick if (mapf) { 22344626Smckusick int error; 22447526Spendry if (*tp < t) { 22547526Spendry *tp = t; 22644626Smckusick error = -1; 22744626Smckusick } else { 22844626Smckusick error = search_or_reload_file(mapf, map, key, pval, 0, 0); 22944626Smckusick } 23044626Smckusick (void) fclose(mapf); 23144626Smckusick return error; 23244626Smckusick } 23344626Smckusick 23444626Smckusick return errno; 23544626Smckusick } 23647526Spendry 23747526Spendry int file_mtime P((char *map, time_t *tp)); 23847526Spendry int file_mtime(map, tp) 23947526Spendry char *map; 24047526Spendry time_t *tp; 24147526Spendry { 24247526Spendry FILE *mapf = file_open(map, tp); 24347526Spendry if (mapf) { 24447526Spendry (void) fclose(mapf); 24547526Spendry return 0; 24647526Spendry } 24747526Spendry 24847526Spendry return errno; 24947526Spendry } 25044626Smckusick #endif /* HAS_FILE_MAPS */ 251