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; 368a384985SDag-Erling Smørgrav int p; /* 0 -> no parentheses 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 438a384985SDag-Erling Smørgrav /* standard delimiters */ 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 } 123091e9e46SCy Schubert if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) { 124c7f4d7adSDag-Erling Smørgrav *t = '\0'; 125c7f4d7adSDag-Erling Smørgrav return -1; 126c7f4d7adSDag-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 } 144091e9e46SCy Schubert /* is there space for the character and the zero after it */ 145091e9e46SCy Schubert if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) { 14609a3aaf3SDag-Erling Smørgrav *t = '\0'; 14709a3aaf3SDag-Erling Smørgrav return -1; 14809a3aaf3SDag-Erling Smørgrav } 14909a3aaf3SDag-Erling Smørgrav if (c != '\0' && c != '\n') { 15009a3aaf3SDag-Erling Smørgrav *t++ = c; 15109a3aaf3SDag-Erling Smørgrav } 152*5469a995SCy Schubert if (c == '\n' && line_nr) { 153*5469a995SCy Schubert *line_nr = *line_nr + 1; 154*5469a995SCy Schubert } 15509a3aaf3SDag-Erling Smørgrav if (c == '\\' && prev_c == '\\') 15609a3aaf3SDag-Erling Smørgrav prev_c = 0; 15709a3aaf3SDag-Erling Smørgrav else prev_c = c; 15809a3aaf3SDag-Erling Smørgrav } 15909a3aaf3SDag-Erling Smørgrav *t = '\0'; 16009a3aaf3SDag-Erling Smørgrav if (c == EOF) { 16109a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 16209a3aaf3SDag-Erling Smørgrav } 16309a3aaf3SDag-Erling Smørgrav 16409a3aaf3SDag-Erling Smørgrav if (i == 0) { 16509a3aaf3SDag-Erling Smørgrav /* nothing read */ 16609a3aaf3SDag-Erling Smørgrav return -1; 16709a3aaf3SDag-Erling Smørgrav } 16809a3aaf3SDag-Erling Smørgrav if (p != 0) { 16909a3aaf3SDag-Erling Smørgrav return -1; 17009a3aaf3SDag-Erling Smørgrav } 17109a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 17209a3aaf3SDag-Erling Smørgrav 17309a3aaf3SDag-Erling Smørgrav tokenread: 17409a3aaf3SDag-Erling Smørgrav if(*del == '"') 17509a3aaf3SDag-Erling Smørgrav /* do not skip over quotes after the string, they are part 17609a3aaf3SDag-Erling Smørgrav * of the next string. But skip over whitespace (if needed)*/ 17709a3aaf3SDag-Erling Smørgrav sldns_fskipcs_l(f, del+1, line_nr); 17809a3aaf3SDag-Erling Smørgrav else sldns_fskipcs_l(f, del, line_nr); 17909a3aaf3SDag-Erling Smørgrav *t = '\0'; 18009a3aaf3SDag-Erling Smørgrav if (p != 0) { 18109a3aaf3SDag-Erling Smørgrav return -1; 18209a3aaf3SDag-Erling Smørgrav } 18309a3aaf3SDag-Erling Smørgrav 18409a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 18509a3aaf3SDag-Erling Smørgrav } 18609a3aaf3SDag-Erling Smørgrav 18709a3aaf3SDag-Erling Smørgrav ssize_t 18809a3aaf3SDag-Erling Smørgrav sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, 18909a3aaf3SDag-Erling Smørgrav const char *d_del, size_t data_limit) 19009a3aaf3SDag-Erling Smørgrav { 19109a3aaf3SDag-Erling Smørgrav return sldns_fget_keyword_data_l(f, keyword, k_del, data, d_del, 19209a3aaf3SDag-Erling Smørgrav data_limit, NULL); 19309a3aaf3SDag-Erling Smørgrav } 19409a3aaf3SDag-Erling Smørgrav 19509a3aaf3SDag-Erling Smørgrav ssize_t 19609a3aaf3SDag-Erling Smørgrav sldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data, 19709a3aaf3SDag-Erling Smørgrav const char *d_del, size_t data_limit, int *line_nr) 19809a3aaf3SDag-Erling Smørgrav { 19909a3aaf3SDag-Erling Smørgrav /* we assume: keyword|sep|data */ 20009a3aaf3SDag-Erling Smørgrav char *fkeyword; 20109a3aaf3SDag-Erling Smørgrav ssize_t i; 20209a3aaf3SDag-Erling Smørgrav 20309a3aaf3SDag-Erling Smørgrav if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN) 20409a3aaf3SDag-Erling Smørgrav return -1; 20509a3aaf3SDag-Erling Smørgrav fkeyword = (char*)malloc(LDNS_MAX_KEYWORDLEN); 20609a3aaf3SDag-Erling Smørgrav if(!fkeyword) 20709a3aaf3SDag-Erling Smørgrav return -1; 20809a3aaf3SDag-Erling Smørgrav 20909a3aaf3SDag-Erling Smørgrav i = sldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN); 21009a3aaf3SDag-Erling Smørgrav if(i==0 || i==-1) { 21109a3aaf3SDag-Erling Smørgrav free(fkeyword); 21209a3aaf3SDag-Erling Smørgrav return -1; 21309a3aaf3SDag-Erling Smørgrav } 21409a3aaf3SDag-Erling Smørgrav 21509a3aaf3SDag-Erling Smørgrav /* case??? i instead of strlen? */ 21609a3aaf3SDag-Erling Smørgrav if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) { 21709a3aaf3SDag-Erling Smørgrav /* whee! */ 21809a3aaf3SDag-Erling Smørgrav /* printf("%s\n%s\n", "Matching keyword", fkeyword); */ 21909a3aaf3SDag-Erling Smørgrav i = sldns_fget_token_l(f, data, d_del, data_limit, line_nr); 22009a3aaf3SDag-Erling Smørgrav free(fkeyword); 22109a3aaf3SDag-Erling Smørgrav return i; 22209a3aaf3SDag-Erling Smørgrav } else { 22309a3aaf3SDag-Erling Smørgrav /*printf("no match for %s (read: %s)\n", keyword, fkeyword);*/ 22409a3aaf3SDag-Erling Smørgrav free(fkeyword); 22509a3aaf3SDag-Erling Smørgrav return -1; 22609a3aaf3SDag-Erling Smørgrav } 22709a3aaf3SDag-Erling Smørgrav } 22809a3aaf3SDag-Erling Smørgrav 22909a3aaf3SDag-Erling Smørgrav int 23009a3aaf3SDag-Erling Smørgrav sldns_bgetc(sldns_buffer *buffer) 23109a3aaf3SDag-Erling Smørgrav { 23209a3aaf3SDag-Erling Smørgrav if (!sldns_buffer_available_at(buffer, buffer->_position, sizeof(uint8_t))) { 23309a3aaf3SDag-Erling Smørgrav sldns_buffer_set_position(buffer, sldns_buffer_limit(buffer)); 23409a3aaf3SDag-Erling Smørgrav /* sldns_buffer_rewind(buffer);*/ 23509a3aaf3SDag-Erling Smørgrav return EOF; 23609a3aaf3SDag-Erling Smørgrav } 23709a3aaf3SDag-Erling Smørgrav return (int)sldns_buffer_read_u8(buffer); 23809a3aaf3SDag-Erling Smørgrav } 23909a3aaf3SDag-Erling Smørgrav 24009a3aaf3SDag-Erling Smørgrav ssize_t 24109a3aaf3SDag-Erling Smørgrav sldns_bget_token(sldns_buffer *b, char *token, const char *delim, size_t limit) 24209a3aaf3SDag-Erling Smørgrav { 24309a3aaf3SDag-Erling Smørgrav return sldns_bget_token_par(b, token, delim, limit, NULL, NULL); 24409a3aaf3SDag-Erling Smørgrav } 24509a3aaf3SDag-Erling Smørgrav 24609a3aaf3SDag-Erling Smørgrav ssize_t 24709a3aaf3SDag-Erling Smørgrav sldns_bget_token_par(sldns_buffer *b, char *token, const char *delim, 24809a3aaf3SDag-Erling Smørgrav size_t limit, int* par, const char* skipw) 24909a3aaf3SDag-Erling Smørgrav { 25009a3aaf3SDag-Erling Smørgrav int c, lc; 2518a384985SDag-Erling Smørgrav int p; /* 0 -> no parentheses seen, >0 nr of ( seen */ 25209a3aaf3SDag-Erling Smørgrav int com, quoted; 25309a3aaf3SDag-Erling Smørgrav char *t; 25409a3aaf3SDag-Erling Smørgrav size_t i; 25509a3aaf3SDag-Erling Smørgrav const char *d; 25609a3aaf3SDag-Erling Smørgrav const char *del; 25709a3aaf3SDag-Erling Smørgrav 25809a3aaf3SDag-Erling Smørgrav /* standard delimiters */ 25909a3aaf3SDag-Erling Smørgrav if (!delim) { 26009a3aaf3SDag-Erling Smørgrav /* from isspace(3) */ 26109a3aaf3SDag-Erling Smørgrav del = LDNS_PARSE_NORMAL; 26209a3aaf3SDag-Erling Smørgrav } else { 26309a3aaf3SDag-Erling Smørgrav del = delim; 26409a3aaf3SDag-Erling Smørgrav } 26509a3aaf3SDag-Erling Smørgrav 26609a3aaf3SDag-Erling Smørgrav p = (par?*par:0); 26709a3aaf3SDag-Erling Smørgrav i = 0; 26809a3aaf3SDag-Erling Smørgrav com = 0; 26909a3aaf3SDag-Erling Smørgrav quoted = 0; 27009a3aaf3SDag-Erling Smørgrav t = token; 27109a3aaf3SDag-Erling Smørgrav lc = 0; 27209a3aaf3SDag-Erling Smørgrav if (del[0] == '"') { 27309a3aaf3SDag-Erling Smørgrav quoted = 1; 27409a3aaf3SDag-Erling Smørgrav } 27509a3aaf3SDag-Erling Smørgrav 27609a3aaf3SDag-Erling Smørgrav while ((c = sldns_bgetc(b)) != EOF) { 27709a3aaf3SDag-Erling Smørgrav if (c == '\r') /* carriage return */ 27809a3aaf3SDag-Erling Smørgrav c = ' '; 27909a3aaf3SDag-Erling Smørgrav if (c == '(' && lc != '\\' && !quoted) { 28009a3aaf3SDag-Erling Smørgrav /* this only counts for non-comments */ 28109a3aaf3SDag-Erling Smørgrav if (com == 0) { 28209a3aaf3SDag-Erling Smørgrav if(par) (*par)++; 28309a3aaf3SDag-Erling Smørgrav p++; 28409a3aaf3SDag-Erling Smørgrav } 28509a3aaf3SDag-Erling Smørgrav lc = c; 28609a3aaf3SDag-Erling Smørgrav continue; 28709a3aaf3SDag-Erling Smørgrav } 28809a3aaf3SDag-Erling Smørgrav 28909a3aaf3SDag-Erling Smørgrav if (c == ')' && lc != '\\' && !quoted) { 29009a3aaf3SDag-Erling Smørgrav /* this only counts for non-comments */ 29109a3aaf3SDag-Erling Smørgrav if (com == 0) { 29209a3aaf3SDag-Erling Smørgrav if(par) (*par)--; 29309a3aaf3SDag-Erling Smørgrav p--; 29409a3aaf3SDag-Erling Smørgrav } 29509a3aaf3SDag-Erling Smørgrav lc = c; 29609a3aaf3SDag-Erling Smørgrav continue; 29709a3aaf3SDag-Erling Smørgrav } 29809a3aaf3SDag-Erling Smørgrav 29909a3aaf3SDag-Erling Smørgrav if (p < 0) { 30009a3aaf3SDag-Erling Smørgrav /* more ) then ( */ 30109a3aaf3SDag-Erling Smørgrav *t = '\0'; 30209a3aaf3SDag-Erling Smørgrav return 0; 30309a3aaf3SDag-Erling Smørgrav } 30409a3aaf3SDag-Erling Smørgrav 30509a3aaf3SDag-Erling Smørgrav /* do something with comments ; */ 30609a3aaf3SDag-Erling Smørgrav if (c == ';' && quoted == 0) { 30709a3aaf3SDag-Erling Smørgrav if (lc != '\\') { 30809a3aaf3SDag-Erling Smørgrav com = 1; 30909a3aaf3SDag-Erling Smørgrav } 31009a3aaf3SDag-Erling Smørgrav } 31109a3aaf3SDag-Erling Smørgrav if (c == '"' && com == 0 && lc != '\\') { 31209a3aaf3SDag-Erling Smørgrav quoted = 1 - quoted; 31309a3aaf3SDag-Erling Smørgrav } 31409a3aaf3SDag-Erling Smørgrav 31509a3aaf3SDag-Erling Smørgrav if (c == '\n' && com != 0) { 31609a3aaf3SDag-Erling Smørgrav /* comments */ 31709a3aaf3SDag-Erling Smørgrav com = 0; 31809a3aaf3SDag-Erling Smørgrav *t = ' '; 31909a3aaf3SDag-Erling Smørgrav lc = c; 32009a3aaf3SDag-Erling Smørgrav continue; 32109a3aaf3SDag-Erling Smørgrav } 32209a3aaf3SDag-Erling Smørgrav 32309a3aaf3SDag-Erling Smørgrav if (com == 1) { 32409a3aaf3SDag-Erling Smørgrav *t = ' '; 32509a3aaf3SDag-Erling Smørgrav lc = c; 32609a3aaf3SDag-Erling Smørgrav continue; 32709a3aaf3SDag-Erling Smørgrav } 32809a3aaf3SDag-Erling Smørgrav 32909a3aaf3SDag-Erling Smørgrav if (c == '\n' && p != 0) { 33009a3aaf3SDag-Erling Smørgrav /* in parentheses */ 33109a3aaf3SDag-Erling Smørgrav /* do not write ' ' if we want to skip spaces */ 3320eefd307SCy Schubert if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) { 333091e9e46SCy Schubert /* check for space for the space character and a zero delimiter after that. */ 334091e9e46SCy Schubert if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) { 3350eefd307SCy Schubert *t = '\0'; 3360eefd307SCy Schubert return -1; 3370eefd307SCy Schubert } 33809a3aaf3SDag-Erling Smørgrav *t++ = ' '; 3390eefd307SCy Schubert } 34009a3aaf3SDag-Erling Smørgrav lc = c; 34109a3aaf3SDag-Erling Smørgrav continue; 34209a3aaf3SDag-Erling Smørgrav } 34309a3aaf3SDag-Erling Smørgrav 34409a3aaf3SDag-Erling Smørgrav /* check to skip whitespace at start, but also after ( */ 34509a3aaf3SDag-Erling Smørgrav if(skipw && i==0 && !com && !quoted && lc != '\\') { 34609a3aaf3SDag-Erling Smørgrav if(strchr(skipw, c)) { 34709a3aaf3SDag-Erling Smørgrav lc = c; 34809a3aaf3SDag-Erling Smørgrav continue; 34909a3aaf3SDag-Erling Smørgrav } 35009a3aaf3SDag-Erling Smørgrav } 35109a3aaf3SDag-Erling Smørgrav 35209a3aaf3SDag-Erling Smørgrav /* check if we hit the delim */ 35309a3aaf3SDag-Erling Smørgrav for (d = del; *d; d++) { 35409a3aaf3SDag-Erling Smørgrav /* we can only exit if no parens or user tracks them */ 35509a3aaf3SDag-Erling Smørgrav if (c == *d && lc != '\\' && (p == 0 || par)) { 35609a3aaf3SDag-Erling Smørgrav goto tokenread; 35709a3aaf3SDag-Erling Smørgrav } 35809a3aaf3SDag-Erling Smørgrav } 35909a3aaf3SDag-Erling Smørgrav 36009a3aaf3SDag-Erling Smørgrav i++; 361091e9e46SCy Schubert if (limit > 0 && (i+1 >= limit || (size_t)(t-token)+1 >= limit)) { 36209a3aaf3SDag-Erling Smørgrav *t = '\0'; 36309a3aaf3SDag-Erling Smørgrav return -1; 36409a3aaf3SDag-Erling Smørgrav } 36509a3aaf3SDag-Erling Smørgrav *t++ = c; 36609a3aaf3SDag-Erling Smørgrav 36709a3aaf3SDag-Erling Smørgrav if (c == '\\' && lc == '\\') { 36809a3aaf3SDag-Erling Smørgrav lc = 0; 36909a3aaf3SDag-Erling Smørgrav } else { 37009a3aaf3SDag-Erling Smørgrav lc = c; 37109a3aaf3SDag-Erling Smørgrav } 37209a3aaf3SDag-Erling Smørgrav } 37309a3aaf3SDag-Erling Smørgrav *t = '\0'; 37409a3aaf3SDag-Erling Smørgrav if (i == 0) { 37509a3aaf3SDag-Erling Smørgrav /* nothing read */ 37609a3aaf3SDag-Erling Smørgrav return -1; 37709a3aaf3SDag-Erling Smørgrav } 37809a3aaf3SDag-Erling Smørgrav if (!par && p != 0) { 37909a3aaf3SDag-Erling Smørgrav return -1; 38009a3aaf3SDag-Erling Smørgrav } 38109a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 38209a3aaf3SDag-Erling Smørgrav 38309a3aaf3SDag-Erling Smørgrav tokenread: 38409a3aaf3SDag-Erling Smørgrav if(*del == '"') 38509a3aaf3SDag-Erling Smørgrav /* do not skip over quotes after the string, they are part 38609a3aaf3SDag-Erling Smørgrav * of the next string. But skip over whitespace (if needed)*/ 38709a3aaf3SDag-Erling Smørgrav sldns_bskipcs(b, del+1); 38809a3aaf3SDag-Erling Smørgrav else sldns_bskipcs(b, del); 38909a3aaf3SDag-Erling Smørgrav *t = '\0'; 39009a3aaf3SDag-Erling Smørgrav 39109a3aaf3SDag-Erling Smørgrav if (!par && p != 0) { 39209a3aaf3SDag-Erling Smørgrav return -1; 39309a3aaf3SDag-Erling Smørgrav } 39409a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 39509a3aaf3SDag-Erling Smørgrav } 39609a3aaf3SDag-Erling Smørgrav 39709a3aaf3SDag-Erling Smørgrav 39809a3aaf3SDag-Erling Smørgrav void 39909a3aaf3SDag-Erling Smørgrav sldns_bskipcs(sldns_buffer *buffer, const char *s) 40009a3aaf3SDag-Erling Smørgrav { 40109a3aaf3SDag-Erling Smørgrav int found; 40209a3aaf3SDag-Erling Smørgrav char c; 40309a3aaf3SDag-Erling Smørgrav const char *d; 40409a3aaf3SDag-Erling Smørgrav 40509a3aaf3SDag-Erling Smørgrav while(sldns_buffer_available_at(buffer, buffer->_position, sizeof(char))) { 40609a3aaf3SDag-Erling Smørgrav c = (char) sldns_buffer_read_u8_at(buffer, buffer->_position); 40709a3aaf3SDag-Erling Smørgrav found = 0; 40809a3aaf3SDag-Erling Smørgrav for (d = s; *d; d++) { 40909a3aaf3SDag-Erling Smørgrav if (*d == c) { 41009a3aaf3SDag-Erling Smørgrav found = 1; 41109a3aaf3SDag-Erling Smørgrav } 41209a3aaf3SDag-Erling Smørgrav } 41309a3aaf3SDag-Erling Smørgrav if (found && buffer->_limit > buffer->_position) { 41409a3aaf3SDag-Erling Smørgrav buffer->_position += sizeof(char); 41509a3aaf3SDag-Erling Smørgrav } else { 41609a3aaf3SDag-Erling Smørgrav return; 41709a3aaf3SDag-Erling Smørgrav } 41809a3aaf3SDag-Erling Smørgrav } 41909a3aaf3SDag-Erling Smørgrav } 42009a3aaf3SDag-Erling Smørgrav 42109a3aaf3SDag-Erling Smørgrav void 42209a3aaf3SDag-Erling Smørgrav sldns_fskipcs(FILE *fp, const char *s) 42309a3aaf3SDag-Erling Smørgrav { 42409a3aaf3SDag-Erling Smørgrav sldns_fskipcs_l(fp, s, NULL); 42509a3aaf3SDag-Erling Smørgrav } 42609a3aaf3SDag-Erling Smørgrav 42709a3aaf3SDag-Erling Smørgrav void 42809a3aaf3SDag-Erling Smørgrav sldns_fskipcs_l(FILE *fp, const char *s, int *line_nr) 42909a3aaf3SDag-Erling Smørgrav { 43009a3aaf3SDag-Erling Smørgrav int found; 43109a3aaf3SDag-Erling Smørgrav int c; 43209a3aaf3SDag-Erling Smørgrav const char *d; 43309a3aaf3SDag-Erling Smørgrav 43409a3aaf3SDag-Erling Smørgrav while ((c = fgetc(fp)) != EOF) { 43509a3aaf3SDag-Erling Smørgrav if (line_nr && c == '\n') { 43609a3aaf3SDag-Erling Smørgrav *line_nr = *line_nr + 1; 43709a3aaf3SDag-Erling Smørgrav } 43809a3aaf3SDag-Erling Smørgrav found = 0; 43909a3aaf3SDag-Erling Smørgrav for (d = s; *d; d++) { 44009a3aaf3SDag-Erling Smørgrav if (*d == c) { 44109a3aaf3SDag-Erling Smørgrav found = 1; 44209a3aaf3SDag-Erling Smørgrav } 44309a3aaf3SDag-Erling Smørgrav } 44409a3aaf3SDag-Erling Smørgrav if (!found) { 44509a3aaf3SDag-Erling Smørgrav /* with getc, we've read too far */ 44609a3aaf3SDag-Erling Smørgrav ungetc(c, fp); 44709a3aaf3SDag-Erling Smørgrav return; 44809a3aaf3SDag-Erling Smørgrav } 44909a3aaf3SDag-Erling Smørgrav } 45009a3aaf3SDag-Erling Smørgrav } 45109a3aaf3SDag-Erling Smørgrav 45209a3aaf3SDag-Erling Smørgrav ssize_t 45309a3aaf3SDag-Erling Smørgrav sldns_bget_keyword_data(sldns_buffer *b, const char *keyword, const char *k_del, char 45409a3aaf3SDag-Erling Smørgrav *data, const char *d_del, size_t data_limit) 45509a3aaf3SDag-Erling Smørgrav { 45609a3aaf3SDag-Erling Smørgrav /* we assume: keyword|sep|data */ 45709a3aaf3SDag-Erling Smørgrav char *fkeyword; 45809a3aaf3SDag-Erling Smørgrav ssize_t i; 45909a3aaf3SDag-Erling Smørgrav 46009a3aaf3SDag-Erling Smørgrav if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN) 46109a3aaf3SDag-Erling Smørgrav return -1; 46209a3aaf3SDag-Erling Smørgrav fkeyword = (char*)malloc(LDNS_MAX_KEYWORDLEN); 46309a3aaf3SDag-Erling Smørgrav if(!fkeyword) 46409a3aaf3SDag-Erling Smørgrav return -1; /* out of memory */ 46509a3aaf3SDag-Erling Smørgrav 46609a3aaf3SDag-Erling Smørgrav i = sldns_bget_token(b, fkeyword, k_del, data_limit); 46709a3aaf3SDag-Erling Smørgrav if(i==0 || i==-1) { 46809a3aaf3SDag-Erling Smørgrav free(fkeyword); 46909a3aaf3SDag-Erling Smørgrav return -1; /* nothing read */ 47009a3aaf3SDag-Erling Smørgrav } 47109a3aaf3SDag-Erling Smørgrav 47209a3aaf3SDag-Erling Smørgrav /* case??? */ 47309a3aaf3SDag-Erling Smørgrav if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) { 47409a3aaf3SDag-Erling Smørgrav free(fkeyword); 47509a3aaf3SDag-Erling Smørgrav /* whee, the match! */ 47609a3aaf3SDag-Erling Smørgrav /* retrieve it's data */ 47709a3aaf3SDag-Erling Smørgrav i = sldns_bget_token(b, data, d_del, 0); 47809a3aaf3SDag-Erling Smørgrav return i; 47909a3aaf3SDag-Erling Smørgrav } else { 48009a3aaf3SDag-Erling Smørgrav free(fkeyword); 48109a3aaf3SDag-Erling Smørgrav return -1; 48209a3aaf3SDag-Erling Smørgrav } 48309a3aaf3SDag-Erling Smørgrav } 48409a3aaf3SDag-Erling Smørgrav 485