17b5038d7SDag-Erling Smørgrav /* 27b5038d7SDag-Erling Smørgrav * a generic (simple) parser. Use to parse rr's, private key 37b5038d7SDag-Erling Smørgrav * information and /etc/resolv.conf files 47b5038d7SDag-Erling Smørgrav * 57b5038d7SDag-Erling Smørgrav * a Net::DNS like library for C 67b5038d7SDag-Erling Smørgrav * LibDNS Team @ NLnet Labs 77b5038d7SDag-Erling Smørgrav * (c) NLnet Labs, 2005-2006 87b5038d7SDag-Erling Smørgrav * See the file LICENSE for the license 97b5038d7SDag-Erling Smørgrav */ 107b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 117b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 127b5038d7SDag-Erling Smørgrav 137b5038d7SDag-Erling Smørgrav #include <limits.h> 147b5038d7SDag-Erling Smørgrav #include <strings.h> 157b5038d7SDag-Erling Smørgrav 167b5038d7SDag-Erling Smørgrav ldns_lookup_table ldns_directive_types[] = { 177b5038d7SDag-Erling Smørgrav { LDNS_DIR_TTL, "$TTL" }, 187b5038d7SDag-Erling Smørgrav { LDNS_DIR_ORIGIN, "$ORIGIN" }, 197b5038d7SDag-Erling Smørgrav { LDNS_DIR_INCLUDE, "$INCLUDE" }, 207b5038d7SDag-Erling Smørgrav { 0, NULL } 217b5038d7SDag-Erling Smørgrav }; 227b5038d7SDag-Erling Smørgrav 237b5038d7SDag-Erling Smørgrav /* add max_limit here? */ 247b5038d7SDag-Erling Smørgrav ssize_t 257b5038d7SDag-Erling Smørgrav ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit) 267b5038d7SDag-Erling Smørgrav { 277b5038d7SDag-Erling Smørgrav return ldns_fget_token_l(f, token, delim, limit, NULL); 287b5038d7SDag-Erling Smørgrav } 297b5038d7SDag-Erling Smørgrav 30*5afab0e5SDag-Erling Smørgrav ldns_status 31*5afab0e5SDag-Erling Smørgrav ldns_fget_token_l_st(FILE *f, char **token, size_t *limit, bool fixed 32*5afab0e5SDag-Erling Smørgrav , const char *delim, int *line_nr) 337b5038d7SDag-Erling Smørgrav { 347b5038d7SDag-Erling Smørgrav int c, prev_c; 35*5afab0e5SDag-Erling Smørgrav int p; /* 0 -> no parentheses seen, >0 nr of ( seen */ 367b5038d7SDag-Erling Smørgrav int com, quoted; 37*5afab0e5SDag-Erling Smørgrav char *t, *old_token; 387b5038d7SDag-Erling Smørgrav size_t i; 397b5038d7SDag-Erling Smørgrav const char *d; 407b5038d7SDag-Erling Smørgrav const char *del; 417b5038d7SDag-Erling Smørgrav 42*5afab0e5SDag-Erling Smørgrav /* standard delimiters */ 437b5038d7SDag-Erling Smørgrav if (!delim) { 447b5038d7SDag-Erling Smørgrav /* from isspace(3) */ 457b5038d7SDag-Erling Smørgrav del = LDNS_PARSE_NORMAL; 467b5038d7SDag-Erling Smørgrav } else { 477b5038d7SDag-Erling Smørgrav del = delim; 487b5038d7SDag-Erling Smørgrav } 49*5afab0e5SDag-Erling Smørgrav if (!token || !limit) 50*5afab0e5SDag-Erling Smørgrav return LDNS_STATUS_NULL; 517b5038d7SDag-Erling Smørgrav 52*5afab0e5SDag-Erling Smørgrav if (fixed) { 53*5afab0e5SDag-Erling Smørgrav if (*token == NULL || *limit == 0) 54*5afab0e5SDag-Erling Smørgrav return LDNS_STATUS_NULL; 55*5afab0e5SDag-Erling Smørgrav 56*5afab0e5SDag-Erling Smørgrav } else if (*token == NULL) { 57*5afab0e5SDag-Erling Smørgrav *limit = LDNS_MAX_LINELEN; 58*5afab0e5SDag-Erling Smørgrav if (!(*token = LDNS_XMALLOC(char, *limit + 1))) 59*5afab0e5SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 60*5afab0e5SDag-Erling Smørgrav 61*5afab0e5SDag-Erling Smørgrav } else if (*limit == 0) 62*5afab0e5SDag-Erling Smørgrav return LDNS_STATUS_ERR; 637b5038d7SDag-Erling Smørgrav p = 0; 647b5038d7SDag-Erling Smørgrav i = 0; 657b5038d7SDag-Erling Smørgrav com = 0; 667b5038d7SDag-Erling Smørgrav quoted = 0; 677b5038d7SDag-Erling Smørgrav prev_c = 0; 68*5afab0e5SDag-Erling Smørgrav t = *token; 697b5038d7SDag-Erling Smørgrav if (del[0] == '"') { 707b5038d7SDag-Erling Smørgrav quoted = 1; 717b5038d7SDag-Erling Smørgrav } 727b5038d7SDag-Erling Smørgrav while ((c = getc(f)) != EOF) { 737b5038d7SDag-Erling Smørgrav if (c == '\r') /* carriage return */ 747b5038d7SDag-Erling Smørgrav c = ' '; 757b5038d7SDag-Erling Smørgrav if (c == '(' && prev_c != '\\' && !quoted) { 767b5038d7SDag-Erling Smørgrav /* this only counts for non-comments */ 777b5038d7SDag-Erling Smørgrav if (com == 0) { 787b5038d7SDag-Erling Smørgrav p++; 797b5038d7SDag-Erling Smørgrav } 807b5038d7SDag-Erling Smørgrav prev_c = c; 817b5038d7SDag-Erling Smørgrav continue; 827b5038d7SDag-Erling Smørgrav } 837b5038d7SDag-Erling Smørgrav 847b5038d7SDag-Erling Smørgrav if (c == ')' && prev_c != '\\' && !quoted) { 857b5038d7SDag-Erling Smørgrav /* this only counts for non-comments */ 867b5038d7SDag-Erling Smørgrav if (com == 0) { 877b5038d7SDag-Erling Smørgrav p--; 887b5038d7SDag-Erling Smørgrav } 897b5038d7SDag-Erling Smørgrav prev_c = c; 907b5038d7SDag-Erling Smørgrav continue; 917b5038d7SDag-Erling Smørgrav } 927b5038d7SDag-Erling Smørgrav 937b5038d7SDag-Erling Smørgrav if (p < 0) { 947b5038d7SDag-Erling Smørgrav /* more ) then ( - close off the string */ 957b5038d7SDag-Erling Smørgrav *t = '\0'; 96*5afab0e5SDag-Erling Smørgrav return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY 97*5afab0e5SDag-Erling Smørgrav : LDNS_STATUS_OK; 987b5038d7SDag-Erling Smørgrav } 997b5038d7SDag-Erling Smørgrav 1007b5038d7SDag-Erling Smørgrav /* do something with comments ; */ 1017b5038d7SDag-Erling Smørgrav if (c == ';' && quoted == 0) { 1027b5038d7SDag-Erling Smørgrav if (prev_c != '\\') { 1037b5038d7SDag-Erling Smørgrav com = 1; 1047b5038d7SDag-Erling Smørgrav } 1057b5038d7SDag-Erling Smørgrav } 1067b5038d7SDag-Erling Smørgrav if (c == '\"' && com == 0 && prev_c != '\\') { 1077b5038d7SDag-Erling Smørgrav quoted = 1 - quoted; 1087b5038d7SDag-Erling Smørgrav } 1097b5038d7SDag-Erling Smørgrav 1107b5038d7SDag-Erling Smørgrav if (c == '\n' && com != 0) { 1117b5038d7SDag-Erling Smørgrav /* comments */ 1127b5038d7SDag-Erling Smørgrav com = 0; 1137b5038d7SDag-Erling Smørgrav *t = ' '; 1147b5038d7SDag-Erling Smørgrav if (line_nr) { 1157b5038d7SDag-Erling Smørgrav *line_nr = *line_nr + 1; 1167b5038d7SDag-Erling Smørgrav } 1177b5038d7SDag-Erling Smørgrav if (p == 0 && i > 0) { 1187b5038d7SDag-Erling Smørgrav goto tokenread; 1197b5038d7SDag-Erling Smørgrav } else { 1207b5038d7SDag-Erling Smørgrav prev_c = c; 1217b5038d7SDag-Erling Smørgrav continue; 1227b5038d7SDag-Erling Smørgrav } 1237b5038d7SDag-Erling Smørgrav } 1247b5038d7SDag-Erling Smørgrav 1257b5038d7SDag-Erling Smørgrav if (com == 1) { 1267b5038d7SDag-Erling Smørgrav *t = ' '; 1277b5038d7SDag-Erling Smørgrav prev_c = c; 1287b5038d7SDag-Erling Smørgrav continue; 1297b5038d7SDag-Erling Smørgrav } 1307b5038d7SDag-Erling Smørgrav 131*5afab0e5SDag-Erling Smørgrav if (c == '\n' && p != 0 && t > *token) { 1327b5038d7SDag-Erling Smørgrav /* in parentheses */ 1337b5038d7SDag-Erling Smørgrav if (line_nr) { 1347b5038d7SDag-Erling Smørgrav *line_nr = *line_nr + 1; 1357b5038d7SDag-Erling Smørgrav } 136*5afab0e5SDag-Erling Smørgrav if (*limit > 0 137*5afab0e5SDag-Erling Smørgrav && (i >= *limit || (size_t)(t - *token) >= *limit)) { 138*5afab0e5SDag-Erling Smørgrav if (fixed) { 139*5afab0e5SDag-Erling Smørgrav *t = '\0'; 140*5afab0e5SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ERR; 141*5afab0e5SDag-Erling Smørgrav } 142*5afab0e5SDag-Erling Smørgrav old_token = *token; 143*5afab0e5SDag-Erling Smørgrav *limit *= 2; 144*5afab0e5SDag-Erling Smørgrav *token = LDNS_XREALLOC(*token, char, *limit + 1); 145*5afab0e5SDag-Erling Smørgrav if (*token == NULL) { 146*5afab0e5SDag-Erling Smørgrav *token = old_token; 147*5afab0e5SDag-Erling Smørgrav *t = '\0'; 148*5afab0e5SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 149*5afab0e5SDag-Erling Smørgrav } 150*5afab0e5SDag-Erling Smørgrav if (*token != old_token) 151*5afab0e5SDag-Erling Smørgrav t = *token + (t - old_token); 152*5afab0e5SDag-Erling Smørgrav } 1537b5038d7SDag-Erling Smørgrav *t++ = ' '; 1547b5038d7SDag-Erling Smørgrav prev_c = c; 1557b5038d7SDag-Erling Smørgrav continue; 1567b5038d7SDag-Erling Smørgrav } 1577b5038d7SDag-Erling Smørgrav 1587b5038d7SDag-Erling Smørgrav /* check if we hit the delim */ 1597b5038d7SDag-Erling Smørgrav for (d = del; *d; d++) { 1607b5038d7SDag-Erling Smørgrav if (c == *d && i > 0 && prev_c != '\\' && p == 0) { 1617b5038d7SDag-Erling Smørgrav if (c == '\n' && line_nr) { 1627b5038d7SDag-Erling Smørgrav *line_nr = *line_nr + 1; 1637b5038d7SDag-Erling Smørgrav } 1647b5038d7SDag-Erling Smørgrav goto tokenread; 1657b5038d7SDag-Erling Smørgrav } 1667b5038d7SDag-Erling Smørgrav } 1677b5038d7SDag-Erling Smørgrav if (c != '\0' && c != '\n') { 1687b5038d7SDag-Erling Smørgrav i++; 1697b5038d7SDag-Erling Smørgrav } 170*5afab0e5SDag-Erling Smørgrav if (*limit > 0 171*5afab0e5SDag-Erling Smørgrav && (i >= *limit || (size_t)(t - *token) >= *limit)) { 172*5afab0e5SDag-Erling Smørgrav if (fixed) { 1737b5038d7SDag-Erling Smørgrav *t = '\0'; 174*5afab0e5SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ERR; 175*5afab0e5SDag-Erling Smørgrav } 176*5afab0e5SDag-Erling Smørgrav old_token = *token; 177*5afab0e5SDag-Erling Smørgrav *limit *= 2; 178*5afab0e5SDag-Erling Smørgrav *token = LDNS_XREALLOC(*token, char, *limit + 1); 179*5afab0e5SDag-Erling Smørgrav if (*token == NULL) { 180*5afab0e5SDag-Erling Smørgrav *token = old_token; 181*5afab0e5SDag-Erling Smørgrav *t = '\0'; 182*5afab0e5SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 183*5afab0e5SDag-Erling Smørgrav } 184*5afab0e5SDag-Erling Smørgrav if (*token != old_token) 185*5afab0e5SDag-Erling Smørgrav t = *token + (t - old_token); 1867b5038d7SDag-Erling Smørgrav } 1877b5038d7SDag-Erling Smørgrav if (c != '\0' && c != '\n') { 1887b5038d7SDag-Erling Smørgrav *t++ = c; 1897b5038d7SDag-Erling Smørgrav } 190*5afab0e5SDag-Erling Smørgrav if (c == '\n' && line_nr) { 191*5afab0e5SDag-Erling Smørgrav *line_nr = *line_nr + 1; 192*5afab0e5SDag-Erling Smørgrav } 1937b5038d7SDag-Erling Smørgrav if (c == '\\' && prev_c == '\\') 1947b5038d7SDag-Erling Smørgrav prev_c = 0; 1957b5038d7SDag-Erling Smørgrav else prev_c = c; 1967b5038d7SDag-Erling Smørgrav } 1977b5038d7SDag-Erling Smørgrav *t = '\0'; 1987b5038d7SDag-Erling Smørgrav if (c == EOF) { 199*5afab0e5SDag-Erling Smørgrav return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY : LDNS_STATUS_OK; 2007b5038d7SDag-Erling Smørgrav } 2017b5038d7SDag-Erling Smørgrav 2027b5038d7SDag-Erling Smørgrav if (p != 0) { 203*5afab0e5SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ERR; 2047b5038d7SDag-Erling Smørgrav } 205*5afab0e5SDag-Erling Smørgrav return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY : LDNS_STATUS_OK; 2067b5038d7SDag-Erling Smørgrav 2077b5038d7SDag-Erling Smørgrav tokenread: 208986ba33cSDag-Erling Smørgrav if(*del == '"') /* do not skip over quotes, they are significant */ 209986ba33cSDag-Erling Smørgrav ldns_fskipcs_l(f, del+1, line_nr); 210986ba33cSDag-Erling Smørgrav else ldns_fskipcs_l(f, del, line_nr); 2117b5038d7SDag-Erling Smørgrav *t = '\0'; 2127b5038d7SDag-Erling Smørgrav if (p != 0) { 213*5afab0e5SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ERR; 214*5afab0e5SDag-Erling Smørgrav } 215*5afab0e5SDag-Erling Smørgrav return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY : LDNS_STATUS_OK; 2167b5038d7SDag-Erling Smørgrav } 2177b5038d7SDag-Erling Smørgrav 218*5afab0e5SDag-Erling Smørgrav 219*5afab0e5SDag-Erling Smørgrav ssize_t 220*5afab0e5SDag-Erling Smørgrav ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr) 221*5afab0e5SDag-Erling Smørgrav { 222*5afab0e5SDag-Erling Smørgrav if (limit == 0) 223*5afab0e5SDag-Erling Smørgrav limit = LDNS_MAX_LINELEN; 224*5afab0e5SDag-Erling Smørgrav if (ldns_fget_token_l_st(f, &token, &limit, true, delim, line_nr)) 225*5afab0e5SDag-Erling Smørgrav return -1; 226*5afab0e5SDag-Erling Smørgrav else 227*5afab0e5SDag-Erling Smørgrav return (ssize_t)strlen(token); 2287b5038d7SDag-Erling Smørgrav } 2297b5038d7SDag-Erling Smørgrav 2307b5038d7SDag-Erling Smørgrav ssize_t 2317b5038d7SDag-Erling Smørgrav ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, 2327b5038d7SDag-Erling Smørgrav const char *d_del, size_t data_limit) 2337b5038d7SDag-Erling Smørgrav { 2347b5038d7SDag-Erling Smørgrav return ldns_fget_keyword_data_l(f, keyword, k_del, data, d_del, 2357b5038d7SDag-Erling Smørgrav data_limit, NULL); 2367b5038d7SDag-Erling Smørgrav } 2377b5038d7SDag-Erling Smørgrav 2387b5038d7SDag-Erling Smørgrav ssize_t 2397b5038d7SDag-Erling Smørgrav ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data, 2407b5038d7SDag-Erling Smørgrav const char *d_del, size_t data_limit, int *line_nr) 2417b5038d7SDag-Erling Smørgrav { 2427b5038d7SDag-Erling Smørgrav /* we assume: keyword|sep|data */ 2437b5038d7SDag-Erling Smørgrav char *fkeyword; 2447b5038d7SDag-Erling Smørgrav ssize_t i; 2457b5038d7SDag-Erling Smørgrav 2467b5038d7SDag-Erling Smørgrav if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN) 2477b5038d7SDag-Erling Smørgrav return -1; 2487b5038d7SDag-Erling Smørgrav fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN); 2497b5038d7SDag-Erling Smørgrav if(!fkeyword) 2507b5038d7SDag-Erling Smørgrav return -1; 2517b5038d7SDag-Erling Smørgrav 2527b5038d7SDag-Erling Smørgrav i = ldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN); 2537b5038d7SDag-Erling Smørgrav if(i==0 || i==-1) { 2547b5038d7SDag-Erling Smørgrav LDNS_FREE(fkeyword); 2557b5038d7SDag-Erling Smørgrav return -1; 2567b5038d7SDag-Erling Smørgrav } 2577b5038d7SDag-Erling Smørgrav 2587b5038d7SDag-Erling Smørgrav /* case??? i instead of strlen? */ 2597b5038d7SDag-Erling Smørgrav if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) { 2607b5038d7SDag-Erling Smørgrav /* whee! */ 2617b5038d7SDag-Erling Smørgrav /* printf("%s\n%s\n", "Matching keyword", fkeyword); */ 2627b5038d7SDag-Erling Smørgrav i = ldns_fget_token_l(f, data, d_del, data_limit, line_nr); 2637b5038d7SDag-Erling Smørgrav LDNS_FREE(fkeyword); 2647b5038d7SDag-Erling Smørgrav return i; 2657b5038d7SDag-Erling Smørgrav } else { 2667b5038d7SDag-Erling Smørgrav /*printf("no match for %s (read: %s)\n", keyword, fkeyword);*/ 2677b5038d7SDag-Erling Smørgrav LDNS_FREE(fkeyword); 2687b5038d7SDag-Erling Smørgrav return -1; 2697b5038d7SDag-Erling Smørgrav } 2707b5038d7SDag-Erling Smørgrav } 2717b5038d7SDag-Erling Smørgrav 2727b5038d7SDag-Erling Smørgrav 2737b5038d7SDag-Erling Smørgrav ssize_t 2747b5038d7SDag-Erling Smørgrav ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit) 2757b5038d7SDag-Erling Smørgrav { 2767b5038d7SDag-Erling Smørgrav int c, lc; 277*5afab0e5SDag-Erling Smørgrav int p; /* 0 -> no parentheses seen, >0 nr of ( seen */ 2787b5038d7SDag-Erling Smørgrav int com, quoted; 2797b5038d7SDag-Erling Smørgrav char *t; 2807b5038d7SDag-Erling Smørgrav size_t i; 2817b5038d7SDag-Erling Smørgrav const char *d; 2827b5038d7SDag-Erling Smørgrav const char *del; 2837b5038d7SDag-Erling Smørgrav 2847b5038d7SDag-Erling Smørgrav /* standard delimiters */ 2857b5038d7SDag-Erling Smørgrav if (!delim) { 2867b5038d7SDag-Erling Smørgrav /* from isspace(3) */ 2877b5038d7SDag-Erling Smørgrav del = LDNS_PARSE_NORMAL; 2887b5038d7SDag-Erling Smørgrav } else { 2897b5038d7SDag-Erling Smørgrav del = delim; 2907b5038d7SDag-Erling Smørgrav } 2917b5038d7SDag-Erling Smørgrav 2927b5038d7SDag-Erling Smørgrav p = 0; 2937b5038d7SDag-Erling Smørgrav i = 0; 2947b5038d7SDag-Erling Smørgrav com = 0; 2957b5038d7SDag-Erling Smørgrav quoted = 0; 2967b5038d7SDag-Erling Smørgrav t = token; 2977b5038d7SDag-Erling Smørgrav lc = 0; 2987b5038d7SDag-Erling Smørgrav if (del[0] == '"') { 2997b5038d7SDag-Erling Smørgrav quoted = 1; 3007b5038d7SDag-Erling Smørgrav } 3017b5038d7SDag-Erling Smørgrav 3027b5038d7SDag-Erling Smørgrav while ((c = ldns_bgetc(b)) != EOF) { 3037b5038d7SDag-Erling Smørgrav if (c == '\r') /* carriage return */ 3047b5038d7SDag-Erling Smørgrav c = ' '; 3057b5038d7SDag-Erling Smørgrav if (c == '(' && lc != '\\' && !quoted) { 3067b5038d7SDag-Erling Smørgrav /* this only counts for non-comments */ 3077b5038d7SDag-Erling Smørgrav if (com == 0) { 3087b5038d7SDag-Erling Smørgrav p++; 3097b5038d7SDag-Erling Smørgrav } 3107b5038d7SDag-Erling Smørgrav lc = c; 3117b5038d7SDag-Erling Smørgrav continue; 3127b5038d7SDag-Erling Smørgrav } 3137b5038d7SDag-Erling Smørgrav 3147b5038d7SDag-Erling Smørgrav if (c == ')' && lc != '\\' && !quoted) { 3157b5038d7SDag-Erling Smørgrav /* this only counts for non-comments */ 3167b5038d7SDag-Erling Smørgrav if (com == 0) { 3177b5038d7SDag-Erling Smørgrav p--; 3187b5038d7SDag-Erling Smørgrav } 3197b5038d7SDag-Erling Smørgrav lc = c; 3207b5038d7SDag-Erling Smørgrav continue; 3217b5038d7SDag-Erling Smørgrav } 3227b5038d7SDag-Erling Smørgrav 3237b5038d7SDag-Erling Smørgrav if (p < 0) { 3247b5038d7SDag-Erling Smørgrav /* more ) then ( */ 3257b5038d7SDag-Erling Smørgrav *t = '\0'; 3267b5038d7SDag-Erling Smørgrav return 0; 3277b5038d7SDag-Erling Smørgrav } 3287b5038d7SDag-Erling Smørgrav 3297b5038d7SDag-Erling Smørgrav /* do something with comments ; */ 3307b5038d7SDag-Erling Smørgrav if (c == ';' && quoted == 0) { 3317b5038d7SDag-Erling Smørgrav if (lc != '\\') { 3327b5038d7SDag-Erling Smørgrav com = 1; 3337b5038d7SDag-Erling Smørgrav } 3347b5038d7SDag-Erling Smørgrav } 3357b5038d7SDag-Erling Smørgrav if (c == '"' && com == 0 && lc != '\\') { 3367b5038d7SDag-Erling Smørgrav quoted = 1 - quoted; 3377b5038d7SDag-Erling Smørgrav } 3387b5038d7SDag-Erling Smørgrav 3397b5038d7SDag-Erling Smørgrav if (c == '\n' && com != 0) { 3407b5038d7SDag-Erling Smørgrav /* comments */ 3417b5038d7SDag-Erling Smørgrav com = 0; 3427b5038d7SDag-Erling Smørgrav *t = ' '; 3437b5038d7SDag-Erling Smørgrav lc = c; 3447b5038d7SDag-Erling Smørgrav continue; 3457b5038d7SDag-Erling Smørgrav } 3467b5038d7SDag-Erling Smørgrav 3477b5038d7SDag-Erling Smørgrav if (com == 1) { 3487b5038d7SDag-Erling Smørgrav *t = ' '; 3497b5038d7SDag-Erling Smørgrav lc = c; 3507b5038d7SDag-Erling Smørgrav continue; 3517b5038d7SDag-Erling Smørgrav } 3527b5038d7SDag-Erling Smørgrav 3537b5038d7SDag-Erling Smørgrav if (c == '\n' && p != 0) { 3547b5038d7SDag-Erling Smørgrav /* in parentheses */ 3557b5038d7SDag-Erling Smørgrav *t++ = ' '; 3567b5038d7SDag-Erling Smørgrav lc = c; 3577b5038d7SDag-Erling Smørgrav continue; 3587b5038d7SDag-Erling Smørgrav } 3597b5038d7SDag-Erling Smørgrav 3607b5038d7SDag-Erling Smørgrav /* check if we hit the delim */ 3617b5038d7SDag-Erling Smørgrav for (d = del; *d; d++) { 3627b5038d7SDag-Erling Smørgrav if (c == *d && lc != '\\' && p == 0) { 3637b5038d7SDag-Erling Smørgrav goto tokenread; 3647b5038d7SDag-Erling Smørgrav } 3657b5038d7SDag-Erling Smørgrav } 3667b5038d7SDag-Erling Smørgrav 3677b5038d7SDag-Erling Smørgrav i++; 36817d15b25SDag-Erling Smørgrav if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) { 3697b5038d7SDag-Erling Smørgrav *t = '\0'; 3707b5038d7SDag-Erling Smørgrav return -1; 3717b5038d7SDag-Erling Smørgrav } 3727b5038d7SDag-Erling Smørgrav *t++ = c; 3737b5038d7SDag-Erling Smørgrav 3747b5038d7SDag-Erling Smørgrav if (c == '\\' && lc == '\\') { 3757b5038d7SDag-Erling Smørgrav lc = 0; 3767b5038d7SDag-Erling Smørgrav } else { 3777b5038d7SDag-Erling Smørgrav lc = c; 3787b5038d7SDag-Erling Smørgrav } 3797b5038d7SDag-Erling Smørgrav } 3807b5038d7SDag-Erling Smørgrav *t = '\0'; 3817b5038d7SDag-Erling Smørgrav if (i == 0) { 3827b5038d7SDag-Erling Smørgrav /* nothing read */ 3837b5038d7SDag-Erling Smørgrav return -1; 3847b5038d7SDag-Erling Smørgrav } 3857b5038d7SDag-Erling Smørgrav if (p != 0) { 3867b5038d7SDag-Erling Smørgrav return -1; 3877b5038d7SDag-Erling Smørgrav } 3887b5038d7SDag-Erling Smørgrav return (ssize_t)i; 3897b5038d7SDag-Erling Smørgrav 3907b5038d7SDag-Erling Smørgrav tokenread: 391986ba33cSDag-Erling Smørgrav if(*del == '"') /* do not skip over quotes, they are significant */ 392986ba33cSDag-Erling Smørgrav ldns_bskipcs(b, del+1); 393986ba33cSDag-Erling Smørgrav else ldns_bskipcs(b, del); 3947b5038d7SDag-Erling Smørgrav *t = '\0'; 3957b5038d7SDag-Erling Smørgrav 3967b5038d7SDag-Erling Smørgrav if (p != 0) { 3977b5038d7SDag-Erling Smørgrav return -1; 3987b5038d7SDag-Erling Smørgrav } 3997b5038d7SDag-Erling Smørgrav return (ssize_t)i; 4007b5038d7SDag-Erling Smørgrav } 4017b5038d7SDag-Erling Smørgrav 4027b5038d7SDag-Erling Smørgrav 4037b5038d7SDag-Erling Smørgrav void 4047b5038d7SDag-Erling Smørgrav ldns_bskipcs(ldns_buffer *buffer, const char *s) 4057b5038d7SDag-Erling Smørgrav { 4067b5038d7SDag-Erling Smørgrav bool found; 4077b5038d7SDag-Erling Smørgrav char c; 4087b5038d7SDag-Erling Smørgrav const char *d; 4097b5038d7SDag-Erling Smørgrav 4107b5038d7SDag-Erling Smørgrav while(ldns_buffer_available_at(buffer, buffer->_position, sizeof(char))) { 4117b5038d7SDag-Erling Smørgrav c = (char) ldns_buffer_read_u8_at(buffer, buffer->_position); 4127b5038d7SDag-Erling Smørgrav found = false; 4137b5038d7SDag-Erling Smørgrav for (d = s; *d; d++) { 4147b5038d7SDag-Erling Smørgrav if (*d == c) { 4157b5038d7SDag-Erling Smørgrav found = true; 4167b5038d7SDag-Erling Smørgrav } 4177b5038d7SDag-Erling Smørgrav } 4187b5038d7SDag-Erling Smørgrav if (found && buffer->_limit > buffer->_position) { 4197b5038d7SDag-Erling Smørgrav buffer->_position += sizeof(char); 4207b5038d7SDag-Erling Smørgrav } else { 4217b5038d7SDag-Erling Smørgrav return; 4227b5038d7SDag-Erling Smørgrav } 4237b5038d7SDag-Erling Smørgrav } 4247b5038d7SDag-Erling Smørgrav } 4257b5038d7SDag-Erling Smørgrav 4267b5038d7SDag-Erling Smørgrav void 4277b5038d7SDag-Erling Smørgrav ldns_fskipcs(FILE *fp, const char *s) 4287b5038d7SDag-Erling Smørgrav { 4297b5038d7SDag-Erling Smørgrav ldns_fskipcs_l(fp, s, NULL); 4307b5038d7SDag-Erling Smørgrav } 4317b5038d7SDag-Erling Smørgrav 4327b5038d7SDag-Erling Smørgrav void 4337b5038d7SDag-Erling Smørgrav ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr) 4347b5038d7SDag-Erling Smørgrav { 4357b5038d7SDag-Erling Smørgrav bool found; 4367b5038d7SDag-Erling Smørgrav int c; 4377b5038d7SDag-Erling Smørgrav const char *d; 4387b5038d7SDag-Erling Smørgrav 4397b5038d7SDag-Erling Smørgrav while ((c = fgetc(fp)) != EOF) { 4407b5038d7SDag-Erling Smørgrav if (line_nr && c == '\n') { 4417b5038d7SDag-Erling Smørgrav *line_nr = *line_nr + 1; 4427b5038d7SDag-Erling Smørgrav } 4437b5038d7SDag-Erling Smørgrav found = false; 4447b5038d7SDag-Erling Smørgrav for (d = s; *d; d++) { 4457b5038d7SDag-Erling Smørgrav if (*d == c) { 4467b5038d7SDag-Erling Smørgrav found = true; 4477b5038d7SDag-Erling Smørgrav } 4487b5038d7SDag-Erling Smørgrav } 4497b5038d7SDag-Erling Smørgrav if (!found) { 4507b5038d7SDag-Erling Smørgrav /* with getc, we've read too far */ 4517b5038d7SDag-Erling Smørgrav ungetc(c, fp); 4527b5038d7SDag-Erling Smørgrav return; 4537b5038d7SDag-Erling Smørgrav } 4547b5038d7SDag-Erling Smørgrav } 4557b5038d7SDag-Erling Smørgrav } 4567b5038d7SDag-Erling Smørgrav 4577b5038d7SDag-Erling Smørgrav ssize_t 4587b5038d7SDag-Erling Smørgrav ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, char 4597b5038d7SDag-Erling Smørgrav *data, const char *d_del, size_t data_limit) 4607b5038d7SDag-Erling Smørgrav { 4617b5038d7SDag-Erling Smørgrav /* we assume: keyword|sep|data */ 4627b5038d7SDag-Erling Smørgrav char *fkeyword; 4637b5038d7SDag-Erling Smørgrav ssize_t i; 4647b5038d7SDag-Erling Smørgrav 4657b5038d7SDag-Erling Smørgrav if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN) 4667b5038d7SDag-Erling Smørgrav return -1; 4677b5038d7SDag-Erling Smørgrav fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN); 4687b5038d7SDag-Erling Smørgrav if(!fkeyword) 4697b5038d7SDag-Erling Smørgrav return -1; /* out of memory */ 4707b5038d7SDag-Erling Smørgrav 4717b5038d7SDag-Erling Smørgrav i = ldns_bget_token(b, fkeyword, k_del, data_limit); 4727b5038d7SDag-Erling Smørgrav if(i==0 || i==-1) { 4737b5038d7SDag-Erling Smørgrav LDNS_FREE(fkeyword); 4747b5038d7SDag-Erling Smørgrav return -1; /* nothing read */ 4757b5038d7SDag-Erling Smørgrav } 4767b5038d7SDag-Erling Smørgrav 4777b5038d7SDag-Erling Smørgrav /* case??? */ 4787b5038d7SDag-Erling Smørgrav if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) { 4797b5038d7SDag-Erling Smørgrav LDNS_FREE(fkeyword); 4807b5038d7SDag-Erling Smørgrav /* whee, the match! */ 4817b5038d7SDag-Erling Smørgrav /* retrieve it's data */ 4827b5038d7SDag-Erling Smørgrav i = ldns_bget_token(b, data, d_del, 0); 4837b5038d7SDag-Erling Smørgrav return i; 4847b5038d7SDag-Erling Smørgrav } else { 4857b5038d7SDag-Erling Smørgrav LDNS_FREE(fkeyword); 4867b5038d7SDag-Erling Smørgrav return -1; 4877b5038d7SDag-Erling Smørgrav } 4887b5038d7SDag-Erling Smørgrav } 4897b5038d7SDag-Erling Smørgrav 490