GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/amd/amd/info_file.c Lines: 0 83 0.0 %
Date: 2017-11-07 Branches: 0 90 0.0 %

Line Branch Exec Source
1
/*
2
 * Copyright (c) 1990 Jan-Simon Pendry
3
 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
4
 * Copyright (c) 1990, 1993
5
 *	The Regents of the University of California.  All rights reserved.
6
 *
7
 * This code is derived from software contributed to Berkeley by
8
 * Jan-Simon Pendry at Imperial College, London.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions
12
 * are met:
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in the
17
 *    documentation and/or other materials provided with the distribution.
18
 * 3. Neither the name of the University nor the names of its contributors
19
 *    may be used to endorse or promote products derived from this software
20
 *    without specific prior written permission.
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
 * SUCH DAMAGE.
33
 *
34
 *	from: @(#)info_file.c	8.1 (Berkeley) 6/6/93
35
 *	$Id: info_file.c,v 1.9 2014/10/26 03:03:34 guenther Exp $
36
 */
37
38
/*
39
 * Get info from file
40
 */
41
42
#include "am.h"
43
44
#include <ctype.h>
45
#include <sys/stat.h>
46
47
#define	MAX_LINE_LEN	2048
48
49
static int
50
read_line(char *buf, int size, FILE *fp)
51
{
52
	int done = 0;
53
54
	do {
55
		while (fgets(buf, size, fp)) {
56
			int len = strlen(buf);
57
58
			done += len;
59
			if (len > 1 && buf[len-2] == '\\' &&
60
			    buf[len-1] == '\n') {
61
				int ch;
62
63
				buf += len - 2;
64
				size -= len - 2;
65
				*buf = '\n'; buf[1] = '\0';
66
				/*
67
				 * Skip leading white space on next line
68
				 */
69
				while ((ch = getc(fp)) != EOF &&
70
				    isascii(ch) && isspace(ch))
71
					;
72
				(void) ungetc(ch, fp);
73
			} else {
74
				return done;
75
			}
76
		}
77
	} while (size > 0 && !feof(fp));
78
	return done;
79
}
80
81
/*
82
 * Try to locate a key in a file
83
 */
84
static int
85
search_or_reload_file(FILE *fp, char *map, char *key, char **val, mnt_map *m,
86
    void (*fn)(mnt_map *m, char *, char *))
87
{
88
	char key_val[MAX_LINE_LEN];
89
	int chuck = 0;
90
	int line_no = 0;
91
92
	while (read_line(key_val, sizeof(key_val), fp)) {
93
		char *kp;
94
		char *cp;
95
		char *hash;
96
		int len = strlen(key_val);
97
98
		line_no++;
99
100
		/*
101
		 * Make sure we got the whole line
102
		 */
103
		if (key_val[len-1] != '\n') {
104
			plog(XLOG_WARNING, "line %d in \"%s\" is too long",
105
			    line_no, map);
106
			chuck = 1;
107
		} else {
108
			key_val[len-1] = '\0';
109
		}
110
111
		/*
112
		 * Strip comments
113
		 */
114
		hash = strchr(key_val, '#');
115
		if (hash)
116
			*hash = '\0';
117
118
		/*
119
		 * Find start of key
120
		 */
121
		for (kp = key_val;
122
		    isascii((unsigned char)*kp) && isspace((unsigned char)*kp);
123
		    kp++)
124
			;
125
126
		/*
127
		 * Ignore blank lines
128
		 */
129
		if (!*kp)
130
			goto again;
131
132
		/*
133
		 * Find end of key
134
		 */
135
		for (cp = kp; *cp &&
136
		    (!isascii((unsigned char)*cp) || !isspace((unsigned char)*cp));
137
		    cp++)
138
			;
139
140
		/*
141
		 * Check whether key matches
142
		 */
143
		if (*cp)
144
			*cp++ = '\0';
145
146
		if (fn || (*key == *kp && strcmp(key, kp) == 0)) {
147
			while (isascii((unsigned char)*cp) &&
148
			    isspace((unsigned char)*cp))
149
				cp++;
150
			if (*cp) {
151
				/*
152
				 * Return a copy of the data
153
				 */
154
				char *dc = strdup(cp);
155
				if (fn) {
156
					(*fn)(m, strdup(kp), dc);
157
				} else {
158
					*val = dc;
159
#ifdef DEBUG
160
					dlog("%s returns %s", key, dc);
161
#endif /* DEBUG */
162
				}
163
				if (!fn)
164
					return 0;
165
			} else {
166
				plog(XLOG_USER, "%s: line %d has no value field",
167
				    map, line_no);
168
			}
169
		}
170
171
again:
172
		/*
173
		 * If the last read didn't get a whole line then
174
		 * throw away the remainder before continuing...
175
		 */
176
		if (chuck) {
177
			while (fgets(key_val, sizeof(key_val), fp) &&
178
			    !strchr(key_val, '\n'))
179
					;
180
			chuck = 0;
181
		}
182
	}
183
184
	return fn ? 0 : ENOENT;
185
}
186
187
static FILE *
188
file_open(char *map, time_t *tp)
189
{
190
	FILE *mapf = fopen(map, "r");
191
192
	if (mapf && tp) {
193
		struct stat stb;
194
195
		if (fstat(fileno(mapf), &stb) < 0)
196
			*tp = clocktime();
197
		else
198
			*tp = stb.st_mtime;
199
	}
200
	return mapf;
201
}
202
203
int
204
file_init(char *map, time_t *tp)
205
{
206
	FILE *mapf = file_open(map, tp);
207
208
	if (mapf) {
209
		(void) fclose(mapf);
210
		return 0;
211
	}
212
	return errno;
213
}
214
215
int
216
file_reload(mnt_map *m, char *map, void (*fn)(mnt_map *, char *, char *))
217
{
218
	FILE *mapf = file_open(map, (time_t *) 0);
219
220
	if (mapf) {
221
		int error = search_or_reload_file(mapf, map, 0, 0, m, fn);
222
		(void) fclose(mapf);
223
		return error;
224
	}
225
226
	return errno;
227
}
228
229
int
230
file_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp)
231
{
232
	time_t t;
233
	FILE *mapf = file_open(map, &t);
234
235
	if (mapf) {
236
		int error;
237
		if (*tp < t) {
238
			*tp = t;
239
			error = -1;
240
		} else {
241
			error = search_or_reload_file(mapf, map, key, pval, 0, 0);
242
		}
243
		(void) fclose(mapf);
244
		return error;
245
	}
246
247
	return errno;
248
}
249
250
int
251
file_mtime(char *map, time_t *tp)
252
{
253
	FILE *mapf = file_open(map, tp);
254
255
	if (mapf) {
256
		(void) fclose(mapf);
257
		return 0;
258
	}
259
260
	return errno;
261
}