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