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