xref: /netbsd-src/external/bsd/wpa/dist/src/utils/config.c (revision bb6183629cf165db498d8e1f4e2de129f7efb21c)
1*bb618362Schristos /*
2*bb618362Schristos  * Configuration parsing
3*bb618362Schristos  * Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi>
4*bb618362Schristos  *
5*bb618362Schristos  * This software may be distributed under the terms of the BSD license.
6*bb618362Schristos  * See README for more details.
7*bb618362Schristos  */
8*bb618362Schristos 
9*bb618362Schristos #include "includes.h"
10*bb618362Schristos 
11*bb618362Schristos #include "utils/config.h"
12*bb618362Schristos #include "common.h"
13*bb618362Schristos 
14*bb618362Schristos 
15*bb618362Schristos static int newline_terminated(const char *buf, size_t buflen)
16*bb618362Schristos {
17*bb618362Schristos 	size_t len = os_strlen(buf);
18*bb618362Schristos 	if (len == 0)
19*bb618362Schristos 		return 0;
20*bb618362Schristos 	if (len == buflen - 1 && buf[buflen - 1] != '\r' &&
21*bb618362Schristos 	    buf[len - 1] != '\n')
22*bb618362Schristos 		return 0;
23*bb618362Schristos 	return 1;
24*bb618362Schristos }
25*bb618362Schristos 
26*bb618362Schristos 
27*bb618362Schristos static void skip_line_end(FILE *stream)
28*bb618362Schristos {
29*bb618362Schristos 	char buf[100];
30*bb618362Schristos 	while (fgets(buf, sizeof(buf), stream)) {
31*bb618362Schristos 		buf[sizeof(buf) - 1] = '\0';
32*bb618362Schristos 		if (newline_terminated(buf, sizeof(buf)))
33*bb618362Schristos 			return;
34*bb618362Schristos 	}
35*bb618362Schristos }
36*bb618362Schristos 
37*bb618362Schristos 
38*bb618362Schristos char * wpa_config_get_line(char *s, int size, FILE *stream, int *line,
39*bb618362Schristos 			   char **_pos)
40*bb618362Schristos {
41*bb618362Schristos 	char *pos, *end, *sstart;
42*bb618362Schristos 
43*bb618362Schristos 	while (fgets(s, size, stream)) {
44*bb618362Schristos 		(*line)++;
45*bb618362Schristos 		s[size - 1] = '\0';
46*bb618362Schristos 		if (!newline_terminated(s, size)) {
47*bb618362Schristos 			/*
48*bb618362Schristos 			 * The line was truncated - skip rest of it to avoid
49*bb618362Schristos 			 * confusing error messages.
50*bb618362Schristos 			 */
51*bb618362Schristos 			wpa_printf(MSG_INFO, "Long line in configuration file "
52*bb618362Schristos 				   "truncated");
53*bb618362Schristos 			skip_line_end(stream);
54*bb618362Schristos 		}
55*bb618362Schristos 		pos = s;
56*bb618362Schristos 
57*bb618362Schristos 		/* Skip white space from the beginning of line. */
58*bb618362Schristos 		while (*pos == ' ' || *pos == '\t' || *pos == '\r')
59*bb618362Schristos 			pos++;
60*bb618362Schristos 
61*bb618362Schristos 		/* Skip comment lines and empty lines */
62*bb618362Schristos 		if (*pos == '#' || *pos == '\n' || *pos == '\0')
63*bb618362Schristos 			continue;
64*bb618362Schristos 
65*bb618362Schristos 		/*
66*bb618362Schristos 		 * Remove # comments unless they are within a double quoted
67*bb618362Schristos 		 * string.
68*bb618362Schristos 		 */
69*bb618362Schristos 		sstart = pos;
70*bb618362Schristos 		end = os_strchr(sstart, '#');
71*bb618362Schristos 		while (end) {
72*bb618362Schristos 			sstart = os_strchr(sstart, '"');
73*bb618362Schristos 			if (!sstart || sstart > end)
74*bb618362Schristos 				break;
75*bb618362Schristos 			sstart = os_strchr(sstart + 1, '"');
76*bb618362Schristos 			if (!sstart)
77*bb618362Schristos 				break;
78*bb618362Schristos 			sstart++;
79*bb618362Schristos 			if (sstart > end)
80*bb618362Schristos 				end = os_strchr(sstart, '#');
81*bb618362Schristos 		}
82*bb618362Schristos 
83*bb618362Schristos 		if (end)
84*bb618362Schristos 			*end-- = '\0';
85*bb618362Schristos 		else
86*bb618362Schristos 			end = pos + os_strlen(pos) - 1;
87*bb618362Schristos 
88*bb618362Schristos 		/* Remove trailing white space. */
89*bb618362Schristos 		while (end > pos &&
90*bb618362Schristos 		       (*end == '\n' || *end == ' ' || *end == '\t' ||
91*bb618362Schristos 			*end == '\r'))
92*bb618362Schristos 			*end-- = '\0';
93*bb618362Schristos 
94*bb618362Schristos 		if (*pos == '\0')
95*bb618362Schristos 			continue;
96*bb618362Schristos 
97*bb618362Schristos 		if (_pos)
98*bb618362Schristos 			*_pos = pos;
99*bb618362Schristos 		return pos;
100*bb618362Schristos 	}
101*bb618362Schristos 
102*bb618362Schristos 	if (_pos)
103*bb618362Schristos 		*_pos = NULL;
104*bb618362Schristos 	return NULL;
105*bb618362Schristos }
106