144626Smckusick /*
244626Smckusick * Copyright (c) 1990 Jan-Simon Pendry
344626Smckusick * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
4*61776Sbostic * Copyright (c) 1990, 1993
5*61776Sbostic * The Regents of the University of California. 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*61776Sbostic * @(#)info_file.c 8.1 (Berkeley) 06/06/93
1349683Spendry *
1452460Spendry * $Id: info_file.c,v 5.2.2.1 1992/02/09 15:08:28 jsp beta $
1549683Spendry *
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));
read_line(buf,size,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;
4749683Spendry *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*)));
search_or_reload_file(fp,map,key,val,m,fn)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));
file_open(map,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));
file_init(map,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)()));
file_reload(m,map,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));
file_search(m,map,key,pval,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));
file_mtime(map,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