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 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 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 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