109a3aaf3SDag-Erling Smørgrav /* 209a3aaf3SDag-Erling Smørgrav * a generic (simple) parser. Use to parse rr's, private key 309a3aaf3SDag-Erling Smørgrav * information and /etc/resolv.conf files 409a3aaf3SDag-Erling Smørgrav * 509a3aaf3SDag-Erling Smørgrav * a Net::DNS like library for C 609a3aaf3SDag-Erling Smørgrav * LibDNS Team @ NLnet Labs 709a3aaf3SDag-Erling Smørgrav * (c) NLnet Labs, 2005-2006 809a3aaf3SDag-Erling Smørgrav * See the file LICENSE for the license 909a3aaf3SDag-Erling Smørgrav */ 1009a3aaf3SDag-Erling Smørgrav #include "config.h" 1109a3aaf3SDag-Erling Smørgrav #include "sldns/parse.h" 1209a3aaf3SDag-Erling Smørgrav #include "sldns/parseutil.h" 1309a3aaf3SDag-Erling Smørgrav #include "sldns/sbuffer.h" 1409a3aaf3SDag-Erling Smørgrav 1509a3aaf3SDag-Erling Smørgrav #include <limits.h> 1609a3aaf3SDag-Erling Smørgrav #include <strings.h> 1709a3aaf3SDag-Erling Smørgrav 1809a3aaf3SDag-Erling Smørgrav sldns_lookup_table sldns_directive_types[] = { 1909a3aaf3SDag-Erling Smørgrav { LDNS_DIR_TTL, "$TTL" }, 2009a3aaf3SDag-Erling Smørgrav { LDNS_DIR_ORIGIN, "$ORIGIN" }, 2109a3aaf3SDag-Erling Smørgrav { LDNS_DIR_INCLUDE, "$INCLUDE" }, 2209a3aaf3SDag-Erling Smørgrav { 0, NULL } 2309a3aaf3SDag-Erling Smørgrav }; 2409a3aaf3SDag-Erling Smørgrav 2509a3aaf3SDag-Erling Smørgrav /* add max_limit here? */ 2609a3aaf3SDag-Erling Smørgrav ssize_t 2709a3aaf3SDag-Erling Smørgrav sldns_fget_token(FILE *f, char *token, const char *delim, size_t limit) 2809a3aaf3SDag-Erling Smørgrav { 2909a3aaf3SDag-Erling Smørgrav return sldns_fget_token_l(f, token, delim, limit, NULL); 3009a3aaf3SDag-Erling Smørgrav } 3109a3aaf3SDag-Erling Smørgrav 3209a3aaf3SDag-Erling Smørgrav ssize_t 3309a3aaf3SDag-Erling Smørgrav sldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr) 3409a3aaf3SDag-Erling Smørgrav { 3509a3aaf3SDag-Erling Smørgrav int c, prev_c; 3609a3aaf3SDag-Erling Smørgrav int p; /* 0 -> no parenthese seen, >0 nr of ( seen */ 3709a3aaf3SDag-Erling Smørgrav int com, quoted; 3809a3aaf3SDag-Erling Smørgrav char *t; 3909a3aaf3SDag-Erling Smørgrav size_t i; 4009a3aaf3SDag-Erling Smørgrav const char *d; 4109a3aaf3SDag-Erling Smørgrav const char *del; 4209a3aaf3SDag-Erling Smørgrav 4309a3aaf3SDag-Erling Smørgrav /* standard delimeters */ 4409a3aaf3SDag-Erling Smørgrav if (!delim) { 4509a3aaf3SDag-Erling Smørgrav /* from isspace(3) */ 4609a3aaf3SDag-Erling Smørgrav del = LDNS_PARSE_NORMAL; 4709a3aaf3SDag-Erling Smørgrav } else { 4809a3aaf3SDag-Erling Smørgrav del = delim; 4909a3aaf3SDag-Erling Smørgrav } 5009a3aaf3SDag-Erling Smørgrav 5109a3aaf3SDag-Erling Smørgrav p = 0; 5209a3aaf3SDag-Erling Smørgrav i = 0; 5309a3aaf3SDag-Erling Smørgrav com = 0; 5409a3aaf3SDag-Erling Smørgrav quoted = 0; 5509a3aaf3SDag-Erling Smørgrav prev_c = 0; 5609a3aaf3SDag-Erling Smørgrav t = token; 5709a3aaf3SDag-Erling Smørgrav if (del[0] == '"') { 5809a3aaf3SDag-Erling Smørgrav quoted = 1; 5909a3aaf3SDag-Erling Smørgrav } 6009a3aaf3SDag-Erling Smørgrav while ((c = getc(f)) != EOF) { 6109a3aaf3SDag-Erling Smørgrav if (c == '\r') /* carriage return */ 6209a3aaf3SDag-Erling Smørgrav c = ' '; 6309a3aaf3SDag-Erling Smørgrav if (c == '(' && prev_c != '\\' && !quoted) { 6409a3aaf3SDag-Erling Smørgrav /* this only counts for non-comments */ 6509a3aaf3SDag-Erling Smørgrav if (com == 0) { 6609a3aaf3SDag-Erling Smørgrav p++; 6709a3aaf3SDag-Erling Smørgrav } 6809a3aaf3SDag-Erling Smørgrav prev_c = c; 6909a3aaf3SDag-Erling Smørgrav continue; 7009a3aaf3SDag-Erling Smørgrav } 7109a3aaf3SDag-Erling Smørgrav 7209a3aaf3SDag-Erling Smørgrav if (c == ')' && prev_c != '\\' && !quoted) { 7309a3aaf3SDag-Erling Smørgrav /* this only counts for non-comments */ 7409a3aaf3SDag-Erling Smørgrav if (com == 0) { 7509a3aaf3SDag-Erling Smørgrav p--; 7609a3aaf3SDag-Erling Smørgrav } 7709a3aaf3SDag-Erling Smørgrav prev_c = c; 7809a3aaf3SDag-Erling Smørgrav continue; 7909a3aaf3SDag-Erling Smørgrav } 8009a3aaf3SDag-Erling Smørgrav 8109a3aaf3SDag-Erling Smørgrav if (p < 0) { 8209a3aaf3SDag-Erling Smørgrav /* more ) then ( - close off the string */ 8309a3aaf3SDag-Erling Smørgrav *t = '\0'; 8409a3aaf3SDag-Erling Smørgrav return 0; 8509a3aaf3SDag-Erling Smørgrav } 8609a3aaf3SDag-Erling Smørgrav 8709a3aaf3SDag-Erling Smørgrav /* do something with comments ; */ 8809a3aaf3SDag-Erling Smørgrav if (c == ';' && quoted == 0) { 8909a3aaf3SDag-Erling Smørgrav if (prev_c != '\\') { 9009a3aaf3SDag-Erling Smørgrav com = 1; 9109a3aaf3SDag-Erling Smørgrav } 9209a3aaf3SDag-Erling Smørgrav } 9309a3aaf3SDag-Erling Smørgrav if (c == '\"' && com == 0 && prev_c != '\\') { 9409a3aaf3SDag-Erling Smørgrav quoted = 1 - quoted; 9509a3aaf3SDag-Erling Smørgrav } 9609a3aaf3SDag-Erling Smørgrav 9709a3aaf3SDag-Erling Smørgrav if (c == '\n' && com != 0) { 9809a3aaf3SDag-Erling Smørgrav /* comments */ 9909a3aaf3SDag-Erling Smørgrav com = 0; 10009a3aaf3SDag-Erling Smørgrav *t = ' '; 10109a3aaf3SDag-Erling Smørgrav if (line_nr) { 10209a3aaf3SDag-Erling Smørgrav *line_nr = *line_nr + 1; 10309a3aaf3SDag-Erling Smørgrav } 10409a3aaf3SDag-Erling Smørgrav if (p == 0 && i > 0) { 10509a3aaf3SDag-Erling Smørgrav goto tokenread; 10609a3aaf3SDag-Erling Smørgrav } else { 10709a3aaf3SDag-Erling Smørgrav prev_c = c; 10809a3aaf3SDag-Erling Smørgrav continue; 10909a3aaf3SDag-Erling Smørgrav } 11009a3aaf3SDag-Erling Smørgrav } 11109a3aaf3SDag-Erling Smørgrav 11209a3aaf3SDag-Erling Smørgrav if (com == 1) { 11309a3aaf3SDag-Erling Smørgrav *t = ' '; 11409a3aaf3SDag-Erling Smørgrav prev_c = c; 11509a3aaf3SDag-Erling Smørgrav continue; 11609a3aaf3SDag-Erling Smørgrav } 11709a3aaf3SDag-Erling Smørgrav 11809a3aaf3SDag-Erling Smørgrav if (c == '\n' && p != 0 && t > token) { 11909a3aaf3SDag-Erling Smørgrav /* in parentheses */ 12009a3aaf3SDag-Erling Smørgrav if (line_nr) { 12109a3aaf3SDag-Erling Smørgrav *line_nr = *line_nr + 1; 12209a3aaf3SDag-Erling Smørgrav } 123*c7f4d7adSDag-Erling Smørgrav if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) { 124*c7f4d7adSDag-Erling Smørgrav *t = '\0'; 125*c7f4d7adSDag-Erling Smørgrav return -1; 126*c7f4d7adSDag-Erling Smørgrav } 12709a3aaf3SDag-Erling Smørgrav *t++ = ' '; 12809a3aaf3SDag-Erling Smørgrav prev_c = c; 12909a3aaf3SDag-Erling Smørgrav continue; 13009a3aaf3SDag-Erling Smørgrav } 13109a3aaf3SDag-Erling Smørgrav 13209a3aaf3SDag-Erling Smørgrav /* check if we hit the delim */ 13309a3aaf3SDag-Erling Smørgrav for (d = del; *d; d++) { 13409a3aaf3SDag-Erling Smørgrav if (c == *d && i > 0 && prev_c != '\\' && p == 0) { 13509a3aaf3SDag-Erling Smørgrav if (c == '\n' && line_nr) { 13609a3aaf3SDag-Erling Smørgrav *line_nr = *line_nr + 1; 13709a3aaf3SDag-Erling Smørgrav } 13809a3aaf3SDag-Erling Smørgrav goto tokenread; 13909a3aaf3SDag-Erling Smørgrav } 14009a3aaf3SDag-Erling Smørgrav } 14109a3aaf3SDag-Erling Smørgrav if (c != '\0' && c != '\n') { 14209a3aaf3SDag-Erling Smørgrav i++; 14309a3aaf3SDag-Erling Smørgrav } 14409a3aaf3SDag-Erling Smørgrav if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) { 14509a3aaf3SDag-Erling Smørgrav *t = '\0'; 14609a3aaf3SDag-Erling Smørgrav return -1; 14709a3aaf3SDag-Erling Smørgrav } 14809a3aaf3SDag-Erling Smørgrav if (c != '\0' && c != '\n') { 14909a3aaf3SDag-Erling Smørgrav *t++ = c; 15009a3aaf3SDag-Erling Smørgrav } 15109a3aaf3SDag-Erling Smørgrav if (c == '\\' && prev_c == '\\') 15209a3aaf3SDag-Erling Smørgrav prev_c = 0; 15309a3aaf3SDag-Erling Smørgrav else prev_c = c; 15409a3aaf3SDag-Erling Smørgrav } 15509a3aaf3SDag-Erling Smørgrav *t = '\0'; 15609a3aaf3SDag-Erling Smørgrav if (c == EOF) { 15709a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 15809a3aaf3SDag-Erling Smørgrav } 15909a3aaf3SDag-Erling Smørgrav 16009a3aaf3SDag-Erling Smørgrav if (i == 0) { 16109a3aaf3SDag-Erling Smørgrav /* nothing read */ 16209a3aaf3SDag-Erling Smørgrav return -1; 16309a3aaf3SDag-Erling Smørgrav } 16409a3aaf3SDag-Erling Smørgrav if (p != 0) { 16509a3aaf3SDag-Erling Smørgrav return -1; 16609a3aaf3SDag-Erling Smørgrav } 16709a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 16809a3aaf3SDag-Erling Smørgrav 16909a3aaf3SDag-Erling Smørgrav tokenread: 17009a3aaf3SDag-Erling Smørgrav if(*del == '"') 17109a3aaf3SDag-Erling Smørgrav /* do not skip over quotes after the string, they are part 17209a3aaf3SDag-Erling Smørgrav * of the next string. But skip over whitespace (if needed)*/ 17309a3aaf3SDag-Erling Smørgrav sldns_fskipcs_l(f, del+1, line_nr); 17409a3aaf3SDag-Erling Smørgrav else sldns_fskipcs_l(f, del, line_nr); 17509a3aaf3SDag-Erling Smørgrav *t = '\0'; 17609a3aaf3SDag-Erling Smørgrav if (p != 0) { 17709a3aaf3SDag-Erling Smørgrav return -1; 17809a3aaf3SDag-Erling Smørgrav } 17909a3aaf3SDag-Erling Smørgrav 18009a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 18109a3aaf3SDag-Erling Smørgrav } 18209a3aaf3SDag-Erling Smørgrav 18309a3aaf3SDag-Erling Smørgrav ssize_t 18409a3aaf3SDag-Erling Smørgrav sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, 18509a3aaf3SDag-Erling Smørgrav const char *d_del, size_t data_limit) 18609a3aaf3SDag-Erling Smørgrav { 18709a3aaf3SDag-Erling Smørgrav return sldns_fget_keyword_data_l(f, keyword, k_del, data, d_del, 18809a3aaf3SDag-Erling Smørgrav data_limit, NULL); 18909a3aaf3SDag-Erling Smørgrav } 19009a3aaf3SDag-Erling Smørgrav 19109a3aaf3SDag-Erling Smørgrav ssize_t 19209a3aaf3SDag-Erling Smørgrav sldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data, 19309a3aaf3SDag-Erling Smørgrav const char *d_del, size_t data_limit, int *line_nr) 19409a3aaf3SDag-Erling Smørgrav { 19509a3aaf3SDag-Erling Smørgrav /* we assume: keyword|sep|data */ 19609a3aaf3SDag-Erling Smørgrav char *fkeyword; 19709a3aaf3SDag-Erling Smørgrav ssize_t i; 19809a3aaf3SDag-Erling Smørgrav 19909a3aaf3SDag-Erling Smørgrav if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN) 20009a3aaf3SDag-Erling Smørgrav return -1; 20109a3aaf3SDag-Erling Smørgrav fkeyword = (char*)malloc(LDNS_MAX_KEYWORDLEN); 20209a3aaf3SDag-Erling Smørgrav if(!fkeyword) 20309a3aaf3SDag-Erling Smørgrav return -1; 20409a3aaf3SDag-Erling Smørgrav 20509a3aaf3SDag-Erling Smørgrav i = sldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN); 20609a3aaf3SDag-Erling Smørgrav if(i==0 || i==-1) { 20709a3aaf3SDag-Erling Smørgrav free(fkeyword); 20809a3aaf3SDag-Erling Smørgrav return -1; 20909a3aaf3SDag-Erling Smørgrav } 21009a3aaf3SDag-Erling Smørgrav 21109a3aaf3SDag-Erling Smørgrav /* case??? i instead of strlen? */ 21209a3aaf3SDag-Erling Smørgrav if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) { 21309a3aaf3SDag-Erling Smørgrav /* whee! */ 21409a3aaf3SDag-Erling Smørgrav /* printf("%s\n%s\n", "Matching keyword", fkeyword); */ 21509a3aaf3SDag-Erling Smørgrav i = sldns_fget_token_l(f, data, d_del, data_limit, line_nr); 21609a3aaf3SDag-Erling Smørgrav free(fkeyword); 21709a3aaf3SDag-Erling Smørgrav return i; 21809a3aaf3SDag-Erling Smørgrav } else { 21909a3aaf3SDag-Erling Smørgrav /*printf("no match for %s (read: %s)\n", keyword, fkeyword);*/ 22009a3aaf3SDag-Erling Smørgrav free(fkeyword); 22109a3aaf3SDag-Erling Smørgrav return -1; 22209a3aaf3SDag-Erling Smørgrav } 22309a3aaf3SDag-Erling Smørgrav } 22409a3aaf3SDag-Erling Smørgrav 22509a3aaf3SDag-Erling Smørgrav int 22609a3aaf3SDag-Erling Smørgrav sldns_bgetc(sldns_buffer *buffer) 22709a3aaf3SDag-Erling Smørgrav { 22809a3aaf3SDag-Erling Smørgrav if (!sldns_buffer_available_at(buffer, buffer->_position, sizeof(uint8_t))) { 22909a3aaf3SDag-Erling Smørgrav sldns_buffer_set_position(buffer, sldns_buffer_limit(buffer)); 23009a3aaf3SDag-Erling Smørgrav /* sldns_buffer_rewind(buffer);*/ 23109a3aaf3SDag-Erling Smørgrav return EOF; 23209a3aaf3SDag-Erling Smørgrav } 23309a3aaf3SDag-Erling Smørgrav return (int)sldns_buffer_read_u8(buffer); 23409a3aaf3SDag-Erling Smørgrav } 23509a3aaf3SDag-Erling Smørgrav 23609a3aaf3SDag-Erling Smørgrav ssize_t 23709a3aaf3SDag-Erling Smørgrav sldns_bget_token(sldns_buffer *b, char *token, const char *delim, size_t limit) 23809a3aaf3SDag-Erling Smørgrav { 23909a3aaf3SDag-Erling Smørgrav return sldns_bget_token_par(b, token, delim, limit, NULL, NULL); 24009a3aaf3SDag-Erling Smørgrav } 24109a3aaf3SDag-Erling Smørgrav 24209a3aaf3SDag-Erling Smørgrav ssize_t 24309a3aaf3SDag-Erling Smørgrav sldns_bget_token_par(sldns_buffer *b, char *token, const char *delim, 24409a3aaf3SDag-Erling Smørgrav size_t limit, int* par, const char* skipw) 24509a3aaf3SDag-Erling Smørgrav { 24609a3aaf3SDag-Erling Smørgrav int c, lc; 24709a3aaf3SDag-Erling Smørgrav int p; /* 0 -> no parenthese seen, >0 nr of ( seen */ 24809a3aaf3SDag-Erling Smørgrav int com, quoted; 24909a3aaf3SDag-Erling Smørgrav char *t; 25009a3aaf3SDag-Erling Smørgrav size_t i; 25109a3aaf3SDag-Erling Smørgrav const char *d; 25209a3aaf3SDag-Erling Smørgrav const char *del; 25309a3aaf3SDag-Erling Smørgrav 25409a3aaf3SDag-Erling Smørgrav /* standard delimiters */ 25509a3aaf3SDag-Erling Smørgrav if (!delim) { 25609a3aaf3SDag-Erling Smørgrav /* from isspace(3) */ 25709a3aaf3SDag-Erling Smørgrav del = LDNS_PARSE_NORMAL; 25809a3aaf3SDag-Erling Smørgrav } else { 25909a3aaf3SDag-Erling Smørgrav del = delim; 26009a3aaf3SDag-Erling Smørgrav } 26109a3aaf3SDag-Erling Smørgrav 26209a3aaf3SDag-Erling Smørgrav p = (par?*par:0); 26309a3aaf3SDag-Erling Smørgrav i = 0; 26409a3aaf3SDag-Erling Smørgrav com = 0; 26509a3aaf3SDag-Erling Smørgrav quoted = 0; 26609a3aaf3SDag-Erling Smørgrav t = token; 26709a3aaf3SDag-Erling Smørgrav lc = 0; 26809a3aaf3SDag-Erling Smørgrav if (del[0] == '"') { 26909a3aaf3SDag-Erling Smørgrav quoted = 1; 27009a3aaf3SDag-Erling Smørgrav } 27109a3aaf3SDag-Erling Smørgrav 27209a3aaf3SDag-Erling Smørgrav while ((c = sldns_bgetc(b)) != EOF) { 27309a3aaf3SDag-Erling Smørgrav if (c == '\r') /* carriage return */ 27409a3aaf3SDag-Erling Smørgrav c = ' '; 27509a3aaf3SDag-Erling Smørgrav if (c == '(' && lc != '\\' && !quoted) { 27609a3aaf3SDag-Erling Smørgrav /* this only counts for non-comments */ 27709a3aaf3SDag-Erling Smørgrav if (com == 0) { 27809a3aaf3SDag-Erling Smørgrav if(par) (*par)++; 27909a3aaf3SDag-Erling Smørgrav p++; 28009a3aaf3SDag-Erling Smørgrav } 28109a3aaf3SDag-Erling Smørgrav lc = c; 28209a3aaf3SDag-Erling Smørgrav continue; 28309a3aaf3SDag-Erling Smørgrav } 28409a3aaf3SDag-Erling Smørgrav 28509a3aaf3SDag-Erling Smørgrav if (c == ')' && lc != '\\' && !quoted) { 28609a3aaf3SDag-Erling Smørgrav /* this only counts for non-comments */ 28709a3aaf3SDag-Erling Smørgrav if (com == 0) { 28809a3aaf3SDag-Erling Smørgrav if(par) (*par)--; 28909a3aaf3SDag-Erling Smørgrav p--; 29009a3aaf3SDag-Erling Smørgrav } 29109a3aaf3SDag-Erling Smørgrav lc = c; 29209a3aaf3SDag-Erling Smørgrav continue; 29309a3aaf3SDag-Erling Smørgrav } 29409a3aaf3SDag-Erling Smørgrav 29509a3aaf3SDag-Erling Smørgrav if (p < 0) { 29609a3aaf3SDag-Erling Smørgrav /* more ) then ( */ 29709a3aaf3SDag-Erling Smørgrav *t = '\0'; 29809a3aaf3SDag-Erling Smørgrav return 0; 29909a3aaf3SDag-Erling Smørgrav } 30009a3aaf3SDag-Erling Smørgrav 30109a3aaf3SDag-Erling Smørgrav /* do something with comments ; */ 30209a3aaf3SDag-Erling Smørgrav if (c == ';' && quoted == 0) { 30309a3aaf3SDag-Erling Smørgrav if (lc != '\\') { 30409a3aaf3SDag-Erling Smørgrav com = 1; 30509a3aaf3SDag-Erling Smørgrav } 30609a3aaf3SDag-Erling Smørgrav } 30709a3aaf3SDag-Erling Smørgrav if (c == '"' && com == 0 && lc != '\\') { 30809a3aaf3SDag-Erling Smørgrav quoted = 1 - quoted; 30909a3aaf3SDag-Erling Smørgrav } 31009a3aaf3SDag-Erling Smørgrav 31109a3aaf3SDag-Erling Smørgrav if (c == '\n' && com != 0) { 31209a3aaf3SDag-Erling Smørgrav /* comments */ 31309a3aaf3SDag-Erling Smørgrav com = 0; 31409a3aaf3SDag-Erling Smørgrav *t = ' '; 31509a3aaf3SDag-Erling Smørgrav lc = c; 31609a3aaf3SDag-Erling Smørgrav continue; 31709a3aaf3SDag-Erling Smørgrav } 31809a3aaf3SDag-Erling Smørgrav 31909a3aaf3SDag-Erling Smørgrav if (com == 1) { 32009a3aaf3SDag-Erling Smørgrav *t = ' '; 32109a3aaf3SDag-Erling Smørgrav lc = c; 32209a3aaf3SDag-Erling Smørgrav continue; 32309a3aaf3SDag-Erling Smørgrav } 32409a3aaf3SDag-Erling Smørgrav 32509a3aaf3SDag-Erling Smørgrav if (c == '\n' && p != 0) { 32609a3aaf3SDag-Erling Smørgrav /* in parentheses */ 32709a3aaf3SDag-Erling Smørgrav /* do not write ' ' if we want to skip spaces */ 32809a3aaf3SDag-Erling Smørgrav if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) 32909a3aaf3SDag-Erling Smørgrav *t++ = ' '; 33009a3aaf3SDag-Erling Smørgrav lc = c; 33109a3aaf3SDag-Erling Smørgrav continue; 33209a3aaf3SDag-Erling Smørgrav } 33309a3aaf3SDag-Erling Smørgrav 33409a3aaf3SDag-Erling Smørgrav /* check to skip whitespace at start, but also after ( */ 33509a3aaf3SDag-Erling Smørgrav if(skipw && i==0 && !com && !quoted && lc != '\\') { 33609a3aaf3SDag-Erling Smørgrav if(strchr(skipw, c)) { 33709a3aaf3SDag-Erling Smørgrav lc = c; 33809a3aaf3SDag-Erling Smørgrav continue; 33909a3aaf3SDag-Erling Smørgrav } 34009a3aaf3SDag-Erling Smørgrav } 34109a3aaf3SDag-Erling Smørgrav 34209a3aaf3SDag-Erling Smørgrav /* check if we hit the delim */ 34309a3aaf3SDag-Erling Smørgrav for (d = del; *d; d++) { 34409a3aaf3SDag-Erling Smørgrav /* we can only exit if no parens or user tracks them */ 34509a3aaf3SDag-Erling Smørgrav if (c == *d && lc != '\\' && (p == 0 || par)) { 34609a3aaf3SDag-Erling Smørgrav goto tokenread; 34709a3aaf3SDag-Erling Smørgrav } 34809a3aaf3SDag-Erling Smørgrav } 34909a3aaf3SDag-Erling Smørgrav 35009a3aaf3SDag-Erling Smørgrav i++; 35109a3aaf3SDag-Erling Smørgrav if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) { 35209a3aaf3SDag-Erling Smørgrav *t = '\0'; 35309a3aaf3SDag-Erling Smørgrav return -1; 35409a3aaf3SDag-Erling Smørgrav } 35509a3aaf3SDag-Erling Smørgrav *t++ = c; 35609a3aaf3SDag-Erling Smørgrav 35709a3aaf3SDag-Erling Smørgrav if (c == '\\' && lc == '\\') { 35809a3aaf3SDag-Erling Smørgrav lc = 0; 35909a3aaf3SDag-Erling Smørgrav } else { 36009a3aaf3SDag-Erling Smørgrav lc = c; 36109a3aaf3SDag-Erling Smørgrav } 36209a3aaf3SDag-Erling Smørgrav } 36309a3aaf3SDag-Erling Smørgrav *t = '\0'; 36409a3aaf3SDag-Erling Smørgrav if (i == 0) { 36509a3aaf3SDag-Erling Smørgrav /* nothing read */ 36609a3aaf3SDag-Erling Smørgrav return -1; 36709a3aaf3SDag-Erling Smørgrav } 36809a3aaf3SDag-Erling Smørgrav if (!par && p != 0) { 36909a3aaf3SDag-Erling Smørgrav return -1; 37009a3aaf3SDag-Erling Smørgrav } 37109a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 37209a3aaf3SDag-Erling Smørgrav 37309a3aaf3SDag-Erling Smørgrav tokenread: 37409a3aaf3SDag-Erling Smørgrav if(*del == '"') 37509a3aaf3SDag-Erling Smørgrav /* do not skip over quotes after the string, they are part 37609a3aaf3SDag-Erling Smørgrav * of the next string. But skip over whitespace (if needed)*/ 37709a3aaf3SDag-Erling Smørgrav sldns_bskipcs(b, del+1); 37809a3aaf3SDag-Erling Smørgrav else sldns_bskipcs(b, del); 37909a3aaf3SDag-Erling Smørgrav *t = '\0'; 38009a3aaf3SDag-Erling Smørgrav 38109a3aaf3SDag-Erling Smørgrav if (!par && p != 0) { 38209a3aaf3SDag-Erling Smørgrav return -1; 38309a3aaf3SDag-Erling Smørgrav } 38409a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 38509a3aaf3SDag-Erling Smørgrav } 38609a3aaf3SDag-Erling Smørgrav 38709a3aaf3SDag-Erling Smørgrav 38809a3aaf3SDag-Erling Smørgrav void 38909a3aaf3SDag-Erling Smørgrav sldns_bskipcs(sldns_buffer *buffer, const char *s) 39009a3aaf3SDag-Erling Smørgrav { 39109a3aaf3SDag-Erling Smørgrav int found; 39209a3aaf3SDag-Erling Smørgrav char c; 39309a3aaf3SDag-Erling Smørgrav const char *d; 39409a3aaf3SDag-Erling Smørgrav 39509a3aaf3SDag-Erling Smørgrav while(sldns_buffer_available_at(buffer, buffer->_position, sizeof(char))) { 39609a3aaf3SDag-Erling Smørgrav c = (char) sldns_buffer_read_u8_at(buffer, buffer->_position); 39709a3aaf3SDag-Erling Smørgrav found = 0; 39809a3aaf3SDag-Erling Smørgrav for (d = s; *d; d++) { 39909a3aaf3SDag-Erling Smørgrav if (*d == c) { 40009a3aaf3SDag-Erling Smørgrav found = 1; 40109a3aaf3SDag-Erling Smørgrav } 40209a3aaf3SDag-Erling Smørgrav } 40309a3aaf3SDag-Erling Smørgrav if (found && buffer->_limit > buffer->_position) { 40409a3aaf3SDag-Erling Smørgrav buffer->_position += sizeof(char); 40509a3aaf3SDag-Erling Smørgrav } else { 40609a3aaf3SDag-Erling Smørgrav return; 40709a3aaf3SDag-Erling Smørgrav } 40809a3aaf3SDag-Erling Smørgrav } 40909a3aaf3SDag-Erling Smørgrav } 41009a3aaf3SDag-Erling Smørgrav 41109a3aaf3SDag-Erling Smørgrav void 41209a3aaf3SDag-Erling Smørgrav sldns_fskipcs(FILE *fp, const char *s) 41309a3aaf3SDag-Erling Smørgrav { 41409a3aaf3SDag-Erling Smørgrav sldns_fskipcs_l(fp, s, NULL); 41509a3aaf3SDag-Erling Smørgrav } 41609a3aaf3SDag-Erling Smørgrav 41709a3aaf3SDag-Erling Smørgrav void 41809a3aaf3SDag-Erling Smørgrav sldns_fskipcs_l(FILE *fp, const char *s, int *line_nr) 41909a3aaf3SDag-Erling Smørgrav { 42009a3aaf3SDag-Erling Smørgrav int found; 42109a3aaf3SDag-Erling Smørgrav int c; 42209a3aaf3SDag-Erling Smørgrav const char *d; 42309a3aaf3SDag-Erling Smørgrav 42409a3aaf3SDag-Erling Smørgrav while ((c = fgetc(fp)) != EOF) { 42509a3aaf3SDag-Erling Smørgrav if (line_nr && c == '\n') { 42609a3aaf3SDag-Erling Smørgrav *line_nr = *line_nr + 1; 42709a3aaf3SDag-Erling Smørgrav } 42809a3aaf3SDag-Erling Smørgrav found = 0; 42909a3aaf3SDag-Erling Smørgrav for (d = s; *d; d++) { 43009a3aaf3SDag-Erling Smørgrav if (*d == c) { 43109a3aaf3SDag-Erling Smørgrav found = 1; 43209a3aaf3SDag-Erling Smørgrav } 43309a3aaf3SDag-Erling Smørgrav } 43409a3aaf3SDag-Erling Smørgrav if (!found) { 43509a3aaf3SDag-Erling Smørgrav /* with getc, we've read too far */ 43609a3aaf3SDag-Erling Smørgrav ungetc(c, fp); 43709a3aaf3SDag-Erling Smørgrav return; 43809a3aaf3SDag-Erling Smørgrav } 43909a3aaf3SDag-Erling Smørgrav } 44009a3aaf3SDag-Erling Smørgrav } 44109a3aaf3SDag-Erling Smørgrav 44209a3aaf3SDag-Erling Smørgrav ssize_t 44309a3aaf3SDag-Erling Smørgrav sldns_bget_keyword_data(sldns_buffer *b, const char *keyword, const char *k_del, char 44409a3aaf3SDag-Erling Smørgrav *data, const char *d_del, size_t data_limit) 44509a3aaf3SDag-Erling Smørgrav { 44609a3aaf3SDag-Erling Smørgrav /* we assume: keyword|sep|data */ 44709a3aaf3SDag-Erling Smørgrav char *fkeyword; 44809a3aaf3SDag-Erling Smørgrav ssize_t i; 44909a3aaf3SDag-Erling Smørgrav 45009a3aaf3SDag-Erling Smørgrav if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN) 45109a3aaf3SDag-Erling Smørgrav return -1; 45209a3aaf3SDag-Erling Smørgrav fkeyword = (char*)malloc(LDNS_MAX_KEYWORDLEN); 45309a3aaf3SDag-Erling Smørgrav if(!fkeyword) 45409a3aaf3SDag-Erling Smørgrav return -1; /* out of memory */ 45509a3aaf3SDag-Erling Smørgrav 45609a3aaf3SDag-Erling Smørgrav i = sldns_bget_token(b, fkeyword, k_del, data_limit); 45709a3aaf3SDag-Erling Smørgrav if(i==0 || i==-1) { 45809a3aaf3SDag-Erling Smørgrav free(fkeyword); 45909a3aaf3SDag-Erling Smørgrav return -1; /* nothing read */ 46009a3aaf3SDag-Erling Smørgrav } 46109a3aaf3SDag-Erling Smørgrav 46209a3aaf3SDag-Erling Smørgrav /* case??? */ 46309a3aaf3SDag-Erling Smørgrav if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) { 46409a3aaf3SDag-Erling Smørgrav free(fkeyword); 46509a3aaf3SDag-Erling Smørgrav /* whee, the match! */ 46609a3aaf3SDag-Erling Smørgrav /* retrieve it's data */ 46709a3aaf3SDag-Erling Smørgrav i = sldns_bget_token(b, data, d_del, 0); 46809a3aaf3SDag-Erling Smørgrav return i; 46909a3aaf3SDag-Erling Smørgrav } else { 47009a3aaf3SDag-Erling Smørgrav free(fkeyword); 47109a3aaf3SDag-Erling Smørgrav return -1; 47209a3aaf3SDag-Erling Smørgrav } 47309a3aaf3SDag-Erling Smørgrav } 47409a3aaf3SDag-Erling Smørgrav 475