xref: /csrg-svn/usr.sbin/amd/amd/info_file.c (revision 44626)
1*44626Smckusick /*
2*44626Smckusick  * $Id: info_file.c,v 5.2 90/06/23 22:19:29 jsp Rel $
3*44626Smckusick  *
4*44626Smckusick  * Copyright (c) 1990 Jan-Simon Pendry
5*44626Smckusick  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
6*44626Smckusick  * Copyright (c) 1990 The Regents of the University of California.
7*44626Smckusick  * All rights reserved.
8*44626Smckusick  *
9*44626Smckusick  * This code is derived from software contributed to Berkeley by
10*44626Smckusick  * Jan-Simon Pendry at Imperial College, London.
11*44626Smckusick  *
12*44626Smckusick  * %sccs.include.redist.c%
13*44626Smckusick  *
14*44626Smckusick  *	@(#)info_file.c	5.1 (Berkeley) 06/29/90
15*44626Smckusick  */
16*44626Smckusick 
17*44626Smckusick /*
18*44626Smckusick  * Get info from file
19*44626Smckusick  */
20*44626Smckusick 
21*44626Smckusick #include "am.h"
22*44626Smckusick 
23*44626Smckusick #ifdef HAS_FILE_MAPS
24*44626Smckusick #include <ctype.h>
25*44626Smckusick #include <sys/stat.h>
26*44626Smckusick 
27*44626Smckusick #define	MAX_LINE_LEN	2048
28*44626Smckusick 
29*44626Smckusick static int read_line(buf, size, fp)
30*44626Smckusick char *buf;
31*44626Smckusick int size;
32*44626Smckusick FILE *fp;
33*44626Smckusick {
34*44626Smckusick 	int done = 0;
35*44626Smckusick 
36*44626Smckusick 	do {
37*44626Smckusick 		while (fgets(buf, size, fp)) {
38*44626Smckusick 			int len = strlen(buf);
39*44626Smckusick 			done += len;
40*44626Smckusick 			if (len > 1 && buf[len-2] == '\\' &&
41*44626Smckusick 					buf[len-1] == '\n') {
42*44626Smckusick 				int ch;
43*44626Smckusick 				buf += len - 2;
44*44626Smckusick 				size -= len - 2;
45*44626Smckusick 				/*
46*44626Smckusick 				 * Skip leading white space on next line
47*44626Smckusick 				 */
48*44626Smckusick 				while ((ch = getc(fp)) != EOF &&
49*44626Smckusick 					isascii(ch) && isspace(ch))
50*44626Smckusick 						;
51*44626Smckusick 				(void) ungetc(ch, fp);
52*44626Smckusick 			} else {
53*44626Smckusick 				return done;
54*44626Smckusick 			}
55*44626Smckusick 		}
56*44626Smckusick 	} while (size > 0 && !feof(fp));
57*44626Smckusick 
58*44626Smckusick 	return done;
59*44626Smckusick }
60*44626Smckusick 
61*44626Smckusick /*
62*44626Smckusick  * Try to locate a key in a file
63*44626Smckusick  */
64*44626Smckusick static int search_or_reload_file(fp, map, key, val, m, fn)
65*44626Smckusick FILE *fp;
66*44626Smckusick char *map;
67*44626Smckusick char *key;
68*44626Smckusick char **val;
69*44626Smckusick mnt_map *m;
70*44626Smckusick void (*fn) P((mnt_map*, char*, char*));
71*44626Smckusick {
72*44626Smckusick 	char key_val[MAX_LINE_LEN];
73*44626Smckusick 	int chuck = 0;
74*44626Smckusick 	int line_no = 0;
75*44626Smckusick 
76*44626Smckusick 	while (read_line(key_val, sizeof(key_val), fp)) {
77*44626Smckusick 		char *kp;
78*44626Smckusick 		char *cp;
79*44626Smckusick 		char *hash;
80*44626Smckusick 		int len = strlen(key_val);
81*44626Smckusick 		line_no++;
82*44626Smckusick 
83*44626Smckusick 		/*
84*44626Smckusick 		 * Make sure we got the whole line
85*44626Smckusick 		 */
86*44626Smckusick 		if (key_val[len-1] != '\n') {
87*44626Smckusick 			plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map);
88*44626Smckusick 			chuck = 1;
89*44626Smckusick 		} else {
90*44626Smckusick 			key_val[len-1] = '\0';
91*44626Smckusick 		}
92*44626Smckusick 
93*44626Smckusick 		/*
94*44626Smckusick 		 * Strip comments
95*44626Smckusick 		 */
96*44626Smckusick 		hash = strchr(key_val, '#');
97*44626Smckusick 		if (hash)
98*44626Smckusick 			*hash = '\0';
99*44626Smckusick 
100*44626Smckusick 		/*
101*44626Smckusick 		 * Find start of key
102*44626Smckusick 		 */
103*44626Smckusick 		for (kp = key_val; *kp && isascii(*kp) && isspace(*kp); kp++)
104*44626Smckusick 			;
105*44626Smckusick 
106*44626Smckusick 		/*
107*44626Smckusick 		 * Ignore blank lines
108*44626Smckusick 		 */
109*44626Smckusick 		if (!*kp)
110*44626Smckusick 			goto again;
111*44626Smckusick 
112*44626Smckusick 		/*
113*44626Smckusick 		 * Find end of key
114*44626Smckusick 		 */
115*44626Smckusick 		for (cp = kp; *cp&&(!isascii(*cp)||!isspace(*cp)); cp++)
116*44626Smckusick 			;
117*44626Smckusick 
118*44626Smckusick 		/*
119*44626Smckusick 		 * Check whether key matches
120*44626Smckusick 		 */
121*44626Smckusick 		if (*cp)
122*44626Smckusick 			*cp++ = '\0';
123*44626Smckusick 
124*44626Smckusick 		if ((*key == *kp && strcmp(key, kp) == 0) || fn) {
125*44626Smckusick 			while (*cp && isascii(*cp) && isspace(*cp))
126*44626Smckusick 				cp++;
127*44626Smckusick 			if (*cp) {
128*44626Smckusick 				/*
129*44626Smckusick 				 * Return a copy of the data
130*44626Smckusick 				 */
131*44626Smckusick 				char *dc = strdup(cp);
132*44626Smckusick 				if (fn)
133*44626Smckusick 					(*fn)(m, kp, dc);
134*44626Smckusick 				else
135*44626Smckusick 					*val = dc;
136*44626Smckusick #ifdef DEBUG
137*44626Smckusick 				dlog("%s returns %s", key, dc);
138*44626Smckusick #endif /* DEBUG */
139*44626Smckusick 				if (!fn)
140*44626Smckusick 					return 0;
141*44626Smckusick 			} else {
142*44626Smckusick 				plog(XLOG_USER, "%s: line %d has no value field", map, line_no);
143*44626Smckusick 			}
144*44626Smckusick 		}
145*44626Smckusick 
146*44626Smckusick again:
147*44626Smckusick 		/*
148*44626Smckusick 		 * If the last read didn't get a whole line then
149*44626Smckusick 		 * throw away the remainder before continuing...
150*44626Smckusick 		 */
151*44626Smckusick 		if (chuck) {
152*44626Smckusick 			while (fgets(key_val, sizeof(key_val), fp) &&
153*44626Smckusick 				!strchr(key_val, '\n'))
154*44626Smckusick 					;
155*44626Smckusick 			chuck = 0;
156*44626Smckusick 		}
157*44626Smckusick 	}
158*44626Smckusick 
159*44626Smckusick 	return fn ? 0 : ENOENT;
160*44626Smckusick }
161*44626Smckusick 
162*44626Smckusick int file_init(map)
163*44626Smckusick char *map;
164*44626Smckusick {
165*44626Smckusick 	FILE *mapf = fopen(map, "r");
166*44626Smckusick 	if (mapf) {
167*44626Smckusick 		(void) fclose(mapf);
168*44626Smckusick 		return 0;
169*44626Smckusick 	}
170*44626Smckusick 	return errno;
171*44626Smckusick }
172*44626Smckusick 
173*44626Smckusick int file_reload(m, map, fn)
174*44626Smckusick mnt_map *m;
175*44626Smckusick char *map;
176*44626Smckusick void (*fn)();
177*44626Smckusick {
178*44626Smckusick 	FILE *mapf = fopen(map, "r");
179*44626Smckusick 	if (mapf) {
180*44626Smckusick 		int error = search_or_reload_file(mapf, map, 0, 0, m, fn);
181*44626Smckusick 		(void) fclose(mapf);
182*44626Smckusick 		return error;
183*44626Smckusick 	}
184*44626Smckusick 
185*44626Smckusick 	return errno;
186*44626Smckusick }
187*44626Smckusick 
188*44626Smckusick int file_search(m, map, key, pval, tp)
189*44626Smckusick mnt_map *m;
190*44626Smckusick char *map;
191*44626Smckusick char *key;
192*44626Smckusick char **pval;
193*44626Smckusick time_t *tp;
194*44626Smckusick {
195*44626Smckusick 	FILE *mapf = fopen(map, "r");
196*44626Smckusick 	if (mapf) {
197*44626Smckusick 		struct stat stb;
198*44626Smckusick 		int error;
199*44626Smckusick 		error = fstat(fileno(mapf), &stb);
200*44626Smckusick 		if (!error && *tp < stb.st_mtime) {
201*44626Smckusick 			*tp = stb.st_mtime;
202*44626Smckusick 			error = -1;
203*44626Smckusick 		} else {
204*44626Smckusick 			error = search_or_reload_file(mapf, map, key, pval, 0, 0);
205*44626Smckusick 		}
206*44626Smckusick 		(void) fclose(mapf);
207*44626Smckusick 		return error;
208*44626Smckusick 	}
209*44626Smckusick 
210*44626Smckusick 	return errno;
211*44626Smckusick }
212*44626Smckusick #endif /* HAS_FILE_MAPS */
213