xref: /freebsd/contrib/unbound/sldns/parse.c (revision c7f4d7ad9b7dbb008bffe724ae877e10fea2f821)
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