xref: /csrg-svn/usr.sbin/amd/amd/info_file.c (revision 61776)
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