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