1*09a3aaf3SDag-Erling Smørgrav /* 2*09a3aaf3SDag-Erling Smørgrav * a generic (simple) parser. Use to parse rr's, private key 3*09a3aaf3SDag-Erling Smørgrav * information and /etc/resolv.conf files 4*09a3aaf3SDag-Erling Smørgrav * 5*09a3aaf3SDag-Erling Smørgrav * a Net::DNS like library for C 6*09a3aaf3SDag-Erling Smørgrav * LibDNS Team @ NLnet Labs 7*09a3aaf3SDag-Erling Smørgrav * (c) NLnet Labs, 2005-2006 8*09a3aaf3SDag-Erling Smørgrav * See the file LICENSE for the license 9*09a3aaf3SDag-Erling Smørgrav */ 10*09a3aaf3SDag-Erling Smørgrav #include "config.h" 11*09a3aaf3SDag-Erling Smørgrav #include "sldns/parse.h" 12*09a3aaf3SDag-Erling Smørgrav #include "sldns/parseutil.h" 13*09a3aaf3SDag-Erling Smørgrav #include "sldns/sbuffer.h" 14*09a3aaf3SDag-Erling Smørgrav 15*09a3aaf3SDag-Erling Smørgrav #include <limits.h> 16*09a3aaf3SDag-Erling Smørgrav #include <strings.h> 17*09a3aaf3SDag-Erling Smørgrav 18*09a3aaf3SDag-Erling Smørgrav sldns_lookup_table sldns_directive_types[] = { 19*09a3aaf3SDag-Erling Smørgrav { LDNS_DIR_TTL, "$TTL" }, 20*09a3aaf3SDag-Erling Smørgrav { LDNS_DIR_ORIGIN, "$ORIGIN" }, 21*09a3aaf3SDag-Erling Smørgrav { LDNS_DIR_INCLUDE, "$INCLUDE" }, 22*09a3aaf3SDag-Erling Smørgrav { 0, NULL } 23*09a3aaf3SDag-Erling Smørgrav }; 24*09a3aaf3SDag-Erling Smørgrav 25*09a3aaf3SDag-Erling Smørgrav /* add max_limit here? */ 26*09a3aaf3SDag-Erling Smørgrav ssize_t 27*09a3aaf3SDag-Erling Smørgrav sldns_fget_token(FILE *f, char *token, const char *delim, size_t limit) 28*09a3aaf3SDag-Erling Smørgrav { 29*09a3aaf3SDag-Erling Smørgrav return sldns_fget_token_l(f, token, delim, limit, NULL); 30*09a3aaf3SDag-Erling Smørgrav } 31*09a3aaf3SDag-Erling Smørgrav 32*09a3aaf3SDag-Erling Smørgrav ssize_t 33*09a3aaf3SDag-Erling Smørgrav sldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr) 34*09a3aaf3SDag-Erling Smørgrav { 35*09a3aaf3SDag-Erling Smørgrav int c, prev_c; 36*09a3aaf3SDag-Erling Smørgrav int p; /* 0 -> no parenthese seen, >0 nr of ( seen */ 37*09a3aaf3SDag-Erling Smørgrav int com, quoted; 38*09a3aaf3SDag-Erling Smørgrav char *t; 39*09a3aaf3SDag-Erling Smørgrav size_t i; 40*09a3aaf3SDag-Erling Smørgrav const char *d; 41*09a3aaf3SDag-Erling Smørgrav const char *del; 42*09a3aaf3SDag-Erling Smørgrav 43*09a3aaf3SDag-Erling Smørgrav /* standard delimeters */ 44*09a3aaf3SDag-Erling Smørgrav if (!delim) { 45*09a3aaf3SDag-Erling Smørgrav /* from isspace(3) */ 46*09a3aaf3SDag-Erling Smørgrav del = LDNS_PARSE_NORMAL; 47*09a3aaf3SDag-Erling Smørgrav } else { 48*09a3aaf3SDag-Erling Smørgrav del = delim; 49*09a3aaf3SDag-Erling Smørgrav } 50*09a3aaf3SDag-Erling Smørgrav 51*09a3aaf3SDag-Erling Smørgrav p = 0; 52*09a3aaf3SDag-Erling Smørgrav i = 0; 53*09a3aaf3SDag-Erling Smørgrav com = 0; 54*09a3aaf3SDag-Erling Smørgrav quoted = 0; 55*09a3aaf3SDag-Erling Smørgrav prev_c = 0; 56*09a3aaf3SDag-Erling Smørgrav t = token; 57*09a3aaf3SDag-Erling Smørgrav if (del[0] == '"') { 58*09a3aaf3SDag-Erling Smørgrav quoted = 1; 59*09a3aaf3SDag-Erling Smørgrav } 60*09a3aaf3SDag-Erling Smørgrav while ((c = getc(f)) != EOF) { 61*09a3aaf3SDag-Erling Smørgrav if (c == '\r') /* carriage return */ 62*09a3aaf3SDag-Erling Smørgrav c = ' '; 63*09a3aaf3SDag-Erling Smørgrav if (c == '(' && prev_c != '\\' && !quoted) { 64*09a3aaf3SDag-Erling Smørgrav /* this only counts for non-comments */ 65*09a3aaf3SDag-Erling Smørgrav if (com == 0) { 66*09a3aaf3SDag-Erling Smørgrav p++; 67*09a3aaf3SDag-Erling Smørgrav } 68*09a3aaf3SDag-Erling Smørgrav prev_c = c; 69*09a3aaf3SDag-Erling Smørgrav continue; 70*09a3aaf3SDag-Erling Smørgrav } 71*09a3aaf3SDag-Erling Smørgrav 72*09a3aaf3SDag-Erling Smørgrav if (c == ')' && prev_c != '\\' && !quoted) { 73*09a3aaf3SDag-Erling Smørgrav /* this only counts for non-comments */ 74*09a3aaf3SDag-Erling Smørgrav if (com == 0) { 75*09a3aaf3SDag-Erling Smørgrav p--; 76*09a3aaf3SDag-Erling Smørgrav } 77*09a3aaf3SDag-Erling Smørgrav prev_c = c; 78*09a3aaf3SDag-Erling Smørgrav continue; 79*09a3aaf3SDag-Erling Smørgrav } 80*09a3aaf3SDag-Erling Smørgrav 81*09a3aaf3SDag-Erling Smørgrav if (p < 0) { 82*09a3aaf3SDag-Erling Smørgrav /* more ) then ( - close off the string */ 83*09a3aaf3SDag-Erling Smørgrav *t = '\0'; 84*09a3aaf3SDag-Erling Smørgrav return 0; 85*09a3aaf3SDag-Erling Smørgrav } 86*09a3aaf3SDag-Erling Smørgrav 87*09a3aaf3SDag-Erling Smørgrav /* do something with comments ; */ 88*09a3aaf3SDag-Erling Smørgrav if (c == ';' && quoted == 0) { 89*09a3aaf3SDag-Erling Smørgrav if (prev_c != '\\') { 90*09a3aaf3SDag-Erling Smørgrav com = 1; 91*09a3aaf3SDag-Erling Smørgrav } 92*09a3aaf3SDag-Erling Smørgrav } 93*09a3aaf3SDag-Erling Smørgrav if (c == '\"' && com == 0 && prev_c != '\\') { 94*09a3aaf3SDag-Erling Smørgrav quoted = 1 - quoted; 95*09a3aaf3SDag-Erling Smørgrav } 96*09a3aaf3SDag-Erling Smørgrav 97*09a3aaf3SDag-Erling Smørgrav if (c == '\n' && com != 0) { 98*09a3aaf3SDag-Erling Smørgrav /* comments */ 99*09a3aaf3SDag-Erling Smørgrav com = 0; 100*09a3aaf3SDag-Erling Smørgrav *t = ' '; 101*09a3aaf3SDag-Erling Smørgrav if (line_nr) { 102*09a3aaf3SDag-Erling Smørgrav *line_nr = *line_nr + 1; 103*09a3aaf3SDag-Erling Smørgrav } 104*09a3aaf3SDag-Erling Smørgrav if (p == 0 && i > 0) { 105*09a3aaf3SDag-Erling Smørgrav goto tokenread; 106*09a3aaf3SDag-Erling Smørgrav } else { 107*09a3aaf3SDag-Erling Smørgrav prev_c = c; 108*09a3aaf3SDag-Erling Smørgrav continue; 109*09a3aaf3SDag-Erling Smørgrav } 110*09a3aaf3SDag-Erling Smørgrav } 111*09a3aaf3SDag-Erling Smørgrav 112*09a3aaf3SDag-Erling Smørgrav if (com == 1) { 113*09a3aaf3SDag-Erling Smørgrav *t = ' '; 114*09a3aaf3SDag-Erling Smørgrav prev_c = c; 115*09a3aaf3SDag-Erling Smørgrav continue; 116*09a3aaf3SDag-Erling Smørgrav } 117*09a3aaf3SDag-Erling Smørgrav 118*09a3aaf3SDag-Erling Smørgrav if (c == '\n' && p != 0 && t > token) { 119*09a3aaf3SDag-Erling Smørgrav /* in parentheses */ 120*09a3aaf3SDag-Erling Smørgrav if (line_nr) { 121*09a3aaf3SDag-Erling Smørgrav *line_nr = *line_nr + 1; 122*09a3aaf3SDag-Erling Smørgrav } 123*09a3aaf3SDag-Erling Smørgrav *t++ = ' '; 124*09a3aaf3SDag-Erling Smørgrav prev_c = c; 125*09a3aaf3SDag-Erling Smørgrav continue; 126*09a3aaf3SDag-Erling Smørgrav } 127*09a3aaf3SDag-Erling Smørgrav 128*09a3aaf3SDag-Erling Smørgrav /* check if we hit the delim */ 129*09a3aaf3SDag-Erling Smørgrav for (d = del; *d; d++) { 130*09a3aaf3SDag-Erling Smørgrav if (c == *d && i > 0 && prev_c != '\\' && p == 0) { 131*09a3aaf3SDag-Erling Smørgrav if (c == '\n' && line_nr) { 132*09a3aaf3SDag-Erling Smørgrav *line_nr = *line_nr + 1; 133*09a3aaf3SDag-Erling Smørgrav } 134*09a3aaf3SDag-Erling Smørgrav goto tokenread; 135*09a3aaf3SDag-Erling Smørgrav } 136*09a3aaf3SDag-Erling Smørgrav } 137*09a3aaf3SDag-Erling Smørgrav if (c != '\0' && c != '\n') { 138*09a3aaf3SDag-Erling Smørgrav i++; 139*09a3aaf3SDag-Erling Smørgrav } 140*09a3aaf3SDag-Erling Smørgrav if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) { 141*09a3aaf3SDag-Erling Smørgrav *t = '\0'; 142*09a3aaf3SDag-Erling Smørgrav return -1; 143*09a3aaf3SDag-Erling Smørgrav } 144*09a3aaf3SDag-Erling Smørgrav if (c != '\0' && c != '\n') { 145*09a3aaf3SDag-Erling Smørgrav *t++ = c; 146*09a3aaf3SDag-Erling Smørgrav } 147*09a3aaf3SDag-Erling Smørgrav if (c == '\\' && prev_c == '\\') 148*09a3aaf3SDag-Erling Smørgrav prev_c = 0; 149*09a3aaf3SDag-Erling Smørgrav else prev_c = c; 150*09a3aaf3SDag-Erling Smørgrav } 151*09a3aaf3SDag-Erling Smørgrav *t = '\0'; 152*09a3aaf3SDag-Erling Smørgrav if (c == EOF) { 153*09a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 154*09a3aaf3SDag-Erling Smørgrav } 155*09a3aaf3SDag-Erling Smørgrav 156*09a3aaf3SDag-Erling Smørgrav if (i == 0) { 157*09a3aaf3SDag-Erling Smørgrav /* nothing read */ 158*09a3aaf3SDag-Erling Smørgrav return -1; 159*09a3aaf3SDag-Erling Smørgrav } 160*09a3aaf3SDag-Erling Smørgrav if (p != 0) { 161*09a3aaf3SDag-Erling Smørgrav return -1; 162*09a3aaf3SDag-Erling Smørgrav } 163*09a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 164*09a3aaf3SDag-Erling Smørgrav 165*09a3aaf3SDag-Erling Smørgrav tokenread: 166*09a3aaf3SDag-Erling Smørgrav if(*del == '"') 167*09a3aaf3SDag-Erling Smørgrav /* do not skip over quotes after the string, they are part 168*09a3aaf3SDag-Erling Smørgrav * of the next string. But skip over whitespace (if needed)*/ 169*09a3aaf3SDag-Erling Smørgrav sldns_fskipcs_l(f, del+1, line_nr); 170*09a3aaf3SDag-Erling Smørgrav else sldns_fskipcs_l(f, del, line_nr); 171*09a3aaf3SDag-Erling Smørgrav *t = '\0'; 172*09a3aaf3SDag-Erling Smørgrav if (p != 0) { 173*09a3aaf3SDag-Erling Smørgrav return -1; 174*09a3aaf3SDag-Erling Smørgrav } 175*09a3aaf3SDag-Erling Smørgrav 176*09a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 177*09a3aaf3SDag-Erling Smørgrav } 178*09a3aaf3SDag-Erling Smørgrav 179*09a3aaf3SDag-Erling Smørgrav ssize_t 180*09a3aaf3SDag-Erling Smørgrav sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, 181*09a3aaf3SDag-Erling Smørgrav const char *d_del, size_t data_limit) 182*09a3aaf3SDag-Erling Smørgrav { 183*09a3aaf3SDag-Erling Smørgrav return sldns_fget_keyword_data_l(f, keyword, k_del, data, d_del, 184*09a3aaf3SDag-Erling Smørgrav data_limit, NULL); 185*09a3aaf3SDag-Erling Smørgrav } 186*09a3aaf3SDag-Erling Smørgrav 187*09a3aaf3SDag-Erling Smørgrav ssize_t 188*09a3aaf3SDag-Erling Smørgrav sldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data, 189*09a3aaf3SDag-Erling Smørgrav const char *d_del, size_t data_limit, int *line_nr) 190*09a3aaf3SDag-Erling Smørgrav { 191*09a3aaf3SDag-Erling Smørgrav /* we assume: keyword|sep|data */ 192*09a3aaf3SDag-Erling Smørgrav char *fkeyword; 193*09a3aaf3SDag-Erling Smørgrav ssize_t i; 194*09a3aaf3SDag-Erling Smørgrav 195*09a3aaf3SDag-Erling Smørgrav if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN) 196*09a3aaf3SDag-Erling Smørgrav return -1; 197*09a3aaf3SDag-Erling Smørgrav fkeyword = (char*)malloc(LDNS_MAX_KEYWORDLEN); 198*09a3aaf3SDag-Erling Smørgrav if(!fkeyword) 199*09a3aaf3SDag-Erling Smørgrav return -1; 200*09a3aaf3SDag-Erling Smørgrav 201*09a3aaf3SDag-Erling Smørgrav i = sldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN); 202*09a3aaf3SDag-Erling Smørgrav if(i==0 || i==-1) { 203*09a3aaf3SDag-Erling Smørgrav free(fkeyword); 204*09a3aaf3SDag-Erling Smørgrav return -1; 205*09a3aaf3SDag-Erling Smørgrav } 206*09a3aaf3SDag-Erling Smørgrav 207*09a3aaf3SDag-Erling Smørgrav /* case??? i instead of strlen? */ 208*09a3aaf3SDag-Erling Smørgrav if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) { 209*09a3aaf3SDag-Erling Smørgrav /* whee! */ 210*09a3aaf3SDag-Erling Smørgrav /* printf("%s\n%s\n", "Matching keyword", fkeyword); */ 211*09a3aaf3SDag-Erling Smørgrav i = sldns_fget_token_l(f, data, d_del, data_limit, line_nr); 212*09a3aaf3SDag-Erling Smørgrav free(fkeyword); 213*09a3aaf3SDag-Erling Smørgrav return i; 214*09a3aaf3SDag-Erling Smørgrav } else { 215*09a3aaf3SDag-Erling Smørgrav /*printf("no match for %s (read: %s)\n", keyword, fkeyword);*/ 216*09a3aaf3SDag-Erling Smørgrav free(fkeyword); 217*09a3aaf3SDag-Erling Smørgrav return -1; 218*09a3aaf3SDag-Erling Smørgrav } 219*09a3aaf3SDag-Erling Smørgrav } 220*09a3aaf3SDag-Erling Smørgrav 221*09a3aaf3SDag-Erling Smørgrav int 222*09a3aaf3SDag-Erling Smørgrav sldns_bgetc(sldns_buffer *buffer) 223*09a3aaf3SDag-Erling Smørgrav { 224*09a3aaf3SDag-Erling Smørgrav if (!sldns_buffer_available_at(buffer, buffer->_position, sizeof(uint8_t))) { 225*09a3aaf3SDag-Erling Smørgrav sldns_buffer_set_position(buffer, sldns_buffer_limit(buffer)); 226*09a3aaf3SDag-Erling Smørgrav /* sldns_buffer_rewind(buffer);*/ 227*09a3aaf3SDag-Erling Smørgrav return EOF; 228*09a3aaf3SDag-Erling Smørgrav } 229*09a3aaf3SDag-Erling Smørgrav return (int)sldns_buffer_read_u8(buffer); 230*09a3aaf3SDag-Erling Smørgrav } 231*09a3aaf3SDag-Erling Smørgrav 232*09a3aaf3SDag-Erling Smørgrav ssize_t 233*09a3aaf3SDag-Erling Smørgrav sldns_bget_token(sldns_buffer *b, char *token, const char *delim, size_t limit) 234*09a3aaf3SDag-Erling Smørgrav { 235*09a3aaf3SDag-Erling Smørgrav return sldns_bget_token_par(b, token, delim, limit, NULL, NULL); 236*09a3aaf3SDag-Erling Smørgrav } 237*09a3aaf3SDag-Erling Smørgrav 238*09a3aaf3SDag-Erling Smørgrav ssize_t 239*09a3aaf3SDag-Erling Smørgrav sldns_bget_token_par(sldns_buffer *b, char *token, const char *delim, 240*09a3aaf3SDag-Erling Smørgrav size_t limit, int* par, const char* skipw) 241*09a3aaf3SDag-Erling Smørgrav { 242*09a3aaf3SDag-Erling Smørgrav int c, lc; 243*09a3aaf3SDag-Erling Smørgrav int p; /* 0 -> no parenthese seen, >0 nr of ( seen */ 244*09a3aaf3SDag-Erling Smørgrav int com, quoted; 245*09a3aaf3SDag-Erling Smørgrav char *t; 246*09a3aaf3SDag-Erling Smørgrav size_t i; 247*09a3aaf3SDag-Erling Smørgrav const char *d; 248*09a3aaf3SDag-Erling Smørgrav const char *del; 249*09a3aaf3SDag-Erling Smørgrav 250*09a3aaf3SDag-Erling Smørgrav /* standard delimiters */ 251*09a3aaf3SDag-Erling Smørgrav if (!delim) { 252*09a3aaf3SDag-Erling Smørgrav /* from isspace(3) */ 253*09a3aaf3SDag-Erling Smørgrav del = LDNS_PARSE_NORMAL; 254*09a3aaf3SDag-Erling Smørgrav } else { 255*09a3aaf3SDag-Erling Smørgrav del = delim; 256*09a3aaf3SDag-Erling Smørgrav } 257*09a3aaf3SDag-Erling Smørgrav 258*09a3aaf3SDag-Erling Smørgrav p = (par?*par:0); 259*09a3aaf3SDag-Erling Smørgrav i = 0; 260*09a3aaf3SDag-Erling Smørgrav com = 0; 261*09a3aaf3SDag-Erling Smørgrav quoted = 0; 262*09a3aaf3SDag-Erling Smørgrav t = token; 263*09a3aaf3SDag-Erling Smørgrav lc = 0; 264*09a3aaf3SDag-Erling Smørgrav if (del[0] == '"') { 265*09a3aaf3SDag-Erling Smørgrav quoted = 1; 266*09a3aaf3SDag-Erling Smørgrav } 267*09a3aaf3SDag-Erling Smørgrav 268*09a3aaf3SDag-Erling Smørgrav while ((c = sldns_bgetc(b)) != EOF) { 269*09a3aaf3SDag-Erling Smørgrav if (c == '\r') /* carriage return */ 270*09a3aaf3SDag-Erling Smørgrav c = ' '; 271*09a3aaf3SDag-Erling Smørgrav if (c == '(' && lc != '\\' && !quoted) { 272*09a3aaf3SDag-Erling Smørgrav /* this only counts for non-comments */ 273*09a3aaf3SDag-Erling Smørgrav if (com == 0) { 274*09a3aaf3SDag-Erling Smørgrav if(par) (*par)++; 275*09a3aaf3SDag-Erling Smørgrav p++; 276*09a3aaf3SDag-Erling Smørgrav } 277*09a3aaf3SDag-Erling Smørgrav lc = c; 278*09a3aaf3SDag-Erling Smørgrav continue; 279*09a3aaf3SDag-Erling Smørgrav } 280*09a3aaf3SDag-Erling Smørgrav 281*09a3aaf3SDag-Erling Smørgrav if (c == ')' && lc != '\\' && !quoted) { 282*09a3aaf3SDag-Erling Smørgrav /* this only counts for non-comments */ 283*09a3aaf3SDag-Erling Smørgrav if (com == 0) { 284*09a3aaf3SDag-Erling Smørgrav if(par) (*par)--; 285*09a3aaf3SDag-Erling Smørgrav p--; 286*09a3aaf3SDag-Erling Smørgrav } 287*09a3aaf3SDag-Erling Smørgrav lc = c; 288*09a3aaf3SDag-Erling Smørgrav continue; 289*09a3aaf3SDag-Erling Smørgrav } 290*09a3aaf3SDag-Erling Smørgrav 291*09a3aaf3SDag-Erling Smørgrav if (p < 0) { 292*09a3aaf3SDag-Erling Smørgrav /* more ) then ( */ 293*09a3aaf3SDag-Erling Smørgrav *t = '\0'; 294*09a3aaf3SDag-Erling Smørgrav return 0; 295*09a3aaf3SDag-Erling Smørgrav } 296*09a3aaf3SDag-Erling Smørgrav 297*09a3aaf3SDag-Erling Smørgrav /* do something with comments ; */ 298*09a3aaf3SDag-Erling Smørgrav if (c == ';' && quoted == 0) { 299*09a3aaf3SDag-Erling Smørgrav if (lc != '\\') { 300*09a3aaf3SDag-Erling Smørgrav com = 1; 301*09a3aaf3SDag-Erling Smørgrav } 302*09a3aaf3SDag-Erling Smørgrav } 303*09a3aaf3SDag-Erling Smørgrav if (c == '"' && com == 0 && lc != '\\') { 304*09a3aaf3SDag-Erling Smørgrav quoted = 1 - quoted; 305*09a3aaf3SDag-Erling Smørgrav } 306*09a3aaf3SDag-Erling Smørgrav 307*09a3aaf3SDag-Erling Smørgrav if (c == '\n' && com != 0) { 308*09a3aaf3SDag-Erling Smørgrav /* comments */ 309*09a3aaf3SDag-Erling Smørgrav com = 0; 310*09a3aaf3SDag-Erling Smørgrav *t = ' '; 311*09a3aaf3SDag-Erling Smørgrav lc = c; 312*09a3aaf3SDag-Erling Smørgrav continue; 313*09a3aaf3SDag-Erling Smørgrav } 314*09a3aaf3SDag-Erling Smørgrav 315*09a3aaf3SDag-Erling Smørgrav if (com == 1) { 316*09a3aaf3SDag-Erling Smørgrav *t = ' '; 317*09a3aaf3SDag-Erling Smørgrav lc = c; 318*09a3aaf3SDag-Erling Smørgrav continue; 319*09a3aaf3SDag-Erling Smørgrav } 320*09a3aaf3SDag-Erling Smørgrav 321*09a3aaf3SDag-Erling Smørgrav if (c == '\n' && p != 0) { 322*09a3aaf3SDag-Erling Smørgrav /* in parentheses */ 323*09a3aaf3SDag-Erling Smørgrav /* do not write ' ' if we want to skip spaces */ 324*09a3aaf3SDag-Erling Smørgrav if(!(skipw && (strchr(skipw, c)||strchr(skipw, ' ')))) 325*09a3aaf3SDag-Erling Smørgrav *t++ = ' '; 326*09a3aaf3SDag-Erling Smørgrav lc = c; 327*09a3aaf3SDag-Erling Smørgrav continue; 328*09a3aaf3SDag-Erling Smørgrav } 329*09a3aaf3SDag-Erling Smørgrav 330*09a3aaf3SDag-Erling Smørgrav /* check to skip whitespace at start, but also after ( */ 331*09a3aaf3SDag-Erling Smørgrav if(skipw && i==0 && !com && !quoted && lc != '\\') { 332*09a3aaf3SDag-Erling Smørgrav if(strchr(skipw, c)) { 333*09a3aaf3SDag-Erling Smørgrav lc = c; 334*09a3aaf3SDag-Erling Smørgrav continue; 335*09a3aaf3SDag-Erling Smørgrav } 336*09a3aaf3SDag-Erling Smørgrav } 337*09a3aaf3SDag-Erling Smørgrav 338*09a3aaf3SDag-Erling Smørgrav /* check if we hit the delim */ 339*09a3aaf3SDag-Erling Smørgrav for (d = del; *d; d++) { 340*09a3aaf3SDag-Erling Smørgrav /* we can only exit if no parens or user tracks them */ 341*09a3aaf3SDag-Erling Smørgrav if (c == *d && lc != '\\' && (p == 0 || par)) { 342*09a3aaf3SDag-Erling Smørgrav goto tokenread; 343*09a3aaf3SDag-Erling Smørgrav } 344*09a3aaf3SDag-Erling Smørgrav } 345*09a3aaf3SDag-Erling Smørgrav 346*09a3aaf3SDag-Erling Smørgrav i++; 347*09a3aaf3SDag-Erling Smørgrav if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) { 348*09a3aaf3SDag-Erling Smørgrav *t = '\0'; 349*09a3aaf3SDag-Erling Smørgrav return -1; 350*09a3aaf3SDag-Erling Smørgrav } 351*09a3aaf3SDag-Erling Smørgrav *t++ = c; 352*09a3aaf3SDag-Erling Smørgrav 353*09a3aaf3SDag-Erling Smørgrav if (c == '\\' && lc == '\\') { 354*09a3aaf3SDag-Erling Smørgrav lc = 0; 355*09a3aaf3SDag-Erling Smørgrav } else { 356*09a3aaf3SDag-Erling Smørgrav lc = c; 357*09a3aaf3SDag-Erling Smørgrav } 358*09a3aaf3SDag-Erling Smørgrav } 359*09a3aaf3SDag-Erling Smørgrav *t = '\0'; 360*09a3aaf3SDag-Erling Smørgrav if (i == 0) { 361*09a3aaf3SDag-Erling Smørgrav /* nothing read */ 362*09a3aaf3SDag-Erling Smørgrav return -1; 363*09a3aaf3SDag-Erling Smørgrav } 364*09a3aaf3SDag-Erling Smørgrav if (!par && p != 0) { 365*09a3aaf3SDag-Erling Smørgrav return -1; 366*09a3aaf3SDag-Erling Smørgrav } 367*09a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 368*09a3aaf3SDag-Erling Smørgrav 369*09a3aaf3SDag-Erling Smørgrav tokenread: 370*09a3aaf3SDag-Erling Smørgrav if(*del == '"') 371*09a3aaf3SDag-Erling Smørgrav /* do not skip over quotes after the string, they are part 372*09a3aaf3SDag-Erling Smørgrav * of the next string. But skip over whitespace (if needed)*/ 373*09a3aaf3SDag-Erling Smørgrav sldns_bskipcs(b, del+1); 374*09a3aaf3SDag-Erling Smørgrav else sldns_bskipcs(b, del); 375*09a3aaf3SDag-Erling Smørgrav *t = '\0'; 376*09a3aaf3SDag-Erling Smørgrav 377*09a3aaf3SDag-Erling Smørgrav if (!par && p != 0) { 378*09a3aaf3SDag-Erling Smørgrav return -1; 379*09a3aaf3SDag-Erling Smørgrav } 380*09a3aaf3SDag-Erling Smørgrav return (ssize_t)i; 381*09a3aaf3SDag-Erling Smørgrav } 382*09a3aaf3SDag-Erling Smørgrav 383*09a3aaf3SDag-Erling Smørgrav 384*09a3aaf3SDag-Erling Smørgrav void 385*09a3aaf3SDag-Erling Smørgrav sldns_bskipcs(sldns_buffer *buffer, const char *s) 386*09a3aaf3SDag-Erling Smørgrav { 387*09a3aaf3SDag-Erling Smørgrav int found; 388*09a3aaf3SDag-Erling Smørgrav char c; 389*09a3aaf3SDag-Erling Smørgrav const char *d; 390*09a3aaf3SDag-Erling Smørgrav 391*09a3aaf3SDag-Erling Smørgrav while(sldns_buffer_available_at(buffer, buffer->_position, sizeof(char))) { 392*09a3aaf3SDag-Erling Smørgrav c = (char) sldns_buffer_read_u8_at(buffer, buffer->_position); 393*09a3aaf3SDag-Erling Smørgrav found = 0; 394*09a3aaf3SDag-Erling Smørgrav for (d = s; *d; d++) { 395*09a3aaf3SDag-Erling Smørgrav if (*d == c) { 396*09a3aaf3SDag-Erling Smørgrav found = 1; 397*09a3aaf3SDag-Erling Smørgrav } 398*09a3aaf3SDag-Erling Smørgrav } 399*09a3aaf3SDag-Erling Smørgrav if (found && buffer->_limit > buffer->_position) { 400*09a3aaf3SDag-Erling Smørgrav buffer->_position += sizeof(char); 401*09a3aaf3SDag-Erling Smørgrav } else { 402*09a3aaf3SDag-Erling Smørgrav return; 403*09a3aaf3SDag-Erling Smørgrav } 404*09a3aaf3SDag-Erling Smørgrav } 405*09a3aaf3SDag-Erling Smørgrav } 406*09a3aaf3SDag-Erling Smørgrav 407*09a3aaf3SDag-Erling Smørgrav void 408*09a3aaf3SDag-Erling Smørgrav sldns_fskipcs(FILE *fp, const char *s) 409*09a3aaf3SDag-Erling Smørgrav { 410*09a3aaf3SDag-Erling Smørgrav sldns_fskipcs_l(fp, s, NULL); 411*09a3aaf3SDag-Erling Smørgrav } 412*09a3aaf3SDag-Erling Smørgrav 413*09a3aaf3SDag-Erling Smørgrav void 414*09a3aaf3SDag-Erling Smørgrav sldns_fskipcs_l(FILE *fp, const char *s, int *line_nr) 415*09a3aaf3SDag-Erling Smørgrav { 416*09a3aaf3SDag-Erling Smørgrav int found; 417*09a3aaf3SDag-Erling Smørgrav int c; 418*09a3aaf3SDag-Erling Smørgrav const char *d; 419*09a3aaf3SDag-Erling Smørgrav 420*09a3aaf3SDag-Erling Smørgrav while ((c = fgetc(fp)) != EOF) { 421*09a3aaf3SDag-Erling Smørgrav if (line_nr && c == '\n') { 422*09a3aaf3SDag-Erling Smørgrav *line_nr = *line_nr + 1; 423*09a3aaf3SDag-Erling Smørgrav } 424*09a3aaf3SDag-Erling Smørgrav found = 0; 425*09a3aaf3SDag-Erling Smørgrav for (d = s; *d; d++) { 426*09a3aaf3SDag-Erling Smørgrav if (*d == c) { 427*09a3aaf3SDag-Erling Smørgrav found = 1; 428*09a3aaf3SDag-Erling Smørgrav } 429*09a3aaf3SDag-Erling Smørgrav } 430*09a3aaf3SDag-Erling Smørgrav if (!found) { 431*09a3aaf3SDag-Erling Smørgrav /* with getc, we've read too far */ 432*09a3aaf3SDag-Erling Smørgrav ungetc(c, fp); 433*09a3aaf3SDag-Erling Smørgrav return; 434*09a3aaf3SDag-Erling Smørgrav } 435*09a3aaf3SDag-Erling Smørgrav } 436*09a3aaf3SDag-Erling Smørgrav } 437*09a3aaf3SDag-Erling Smørgrav 438*09a3aaf3SDag-Erling Smørgrav ssize_t 439*09a3aaf3SDag-Erling Smørgrav sldns_bget_keyword_data(sldns_buffer *b, const char *keyword, const char *k_del, char 440*09a3aaf3SDag-Erling Smørgrav *data, const char *d_del, size_t data_limit) 441*09a3aaf3SDag-Erling Smørgrav { 442*09a3aaf3SDag-Erling Smørgrav /* we assume: keyword|sep|data */ 443*09a3aaf3SDag-Erling Smørgrav char *fkeyword; 444*09a3aaf3SDag-Erling Smørgrav ssize_t i; 445*09a3aaf3SDag-Erling Smørgrav 446*09a3aaf3SDag-Erling Smørgrav if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN) 447*09a3aaf3SDag-Erling Smørgrav return -1; 448*09a3aaf3SDag-Erling Smørgrav fkeyword = (char*)malloc(LDNS_MAX_KEYWORDLEN); 449*09a3aaf3SDag-Erling Smørgrav if(!fkeyword) 450*09a3aaf3SDag-Erling Smørgrav return -1; /* out of memory */ 451*09a3aaf3SDag-Erling Smørgrav 452*09a3aaf3SDag-Erling Smørgrav i = sldns_bget_token(b, fkeyword, k_del, data_limit); 453*09a3aaf3SDag-Erling Smørgrav if(i==0 || i==-1) { 454*09a3aaf3SDag-Erling Smørgrav free(fkeyword); 455*09a3aaf3SDag-Erling Smørgrav return -1; /* nothing read */ 456*09a3aaf3SDag-Erling Smørgrav } 457*09a3aaf3SDag-Erling Smørgrav 458*09a3aaf3SDag-Erling Smørgrav /* case??? */ 459*09a3aaf3SDag-Erling Smørgrav if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) { 460*09a3aaf3SDag-Erling Smørgrav free(fkeyword); 461*09a3aaf3SDag-Erling Smørgrav /* whee, the match! */ 462*09a3aaf3SDag-Erling Smørgrav /* retrieve it's data */ 463*09a3aaf3SDag-Erling Smørgrav i = sldns_bget_token(b, data, d_del, 0); 464*09a3aaf3SDag-Erling Smørgrav return i; 465*09a3aaf3SDag-Erling Smørgrav } else { 466*09a3aaf3SDag-Erling Smørgrav free(fkeyword); 467*09a3aaf3SDag-Erling Smørgrav return -1; 468*09a3aaf3SDag-Erling Smørgrav } 469*09a3aaf3SDag-Erling Smørgrav } 470*09a3aaf3SDag-Erling Smørgrav 471