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