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