xref: /freebsd/contrib/ldns/parse.c (revision 5afab0e5e56fe90a378fb57249600e7924e1cab2)
17b5038d7SDag-Erling Smørgrav /*
27b5038d7SDag-Erling Smørgrav  * a generic (simple) parser. Use to parse rr's, private key
37b5038d7SDag-Erling Smørgrav  * information and /etc/resolv.conf files
47b5038d7SDag-Erling Smørgrav  *
57b5038d7SDag-Erling Smørgrav  * a Net::DNS like library for C
67b5038d7SDag-Erling Smørgrav  * LibDNS Team @ NLnet Labs
77b5038d7SDag-Erling Smørgrav  * (c) NLnet Labs, 2005-2006
87b5038d7SDag-Erling Smørgrav  * See the file LICENSE for the license
97b5038d7SDag-Erling Smørgrav  */
107b5038d7SDag-Erling Smørgrav #include <ldns/config.h>
117b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
127b5038d7SDag-Erling Smørgrav 
137b5038d7SDag-Erling Smørgrav #include <limits.h>
147b5038d7SDag-Erling Smørgrav #include <strings.h>
157b5038d7SDag-Erling Smørgrav 
167b5038d7SDag-Erling Smørgrav ldns_lookup_table ldns_directive_types[] = {
177b5038d7SDag-Erling Smørgrav         { LDNS_DIR_TTL, "$TTL" },
187b5038d7SDag-Erling Smørgrav         { LDNS_DIR_ORIGIN, "$ORIGIN" },
197b5038d7SDag-Erling Smørgrav         { LDNS_DIR_INCLUDE, "$INCLUDE" },
207b5038d7SDag-Erling Smørgrav         { 0, NULL }
217b5038d7SDag-Erling Smørgrav };
227b5038d7SDag-Erling Smørgrav 
237b5038d7SDag-Erling Smørgrav /* add max_limit here? */
247b5038d7SDag-Erling Smørgrav ssize_t
257b5038d7SDag-Erling Smørgrav ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit)
267b5038d7SDag-Erling Smørgrav {
277b5038d7SDag-Erling Smørgrav 	return ldns_fget_token_l(f, token, delim, limit, NULL);
287b5038d7SDag-Erling Smørgrav }
297b5038d7SDag-Erling Smørgrav 
30*5afab0e5SDag-Erling Smørgrav ldns_status
31*5afab0e5SDag-Erling Smørgrav ldns_fget_token_l_st(FILE *f, char **token, size_t *limit, bool fixed
32*5afab0e5SDag-Erling Smørgrav                     , const char *delim, int *line_nr)
337b5038d7SDag-Erling Smørgrav {
347b5038d7SDag-Erling Smørgrav 	int c, prev_c;
35*5afab0e5SDag-Erling Smørgrav 	int p; /* 0 -> no parentheses seen, >0 nr of ( seen */
367b5038d7SDag-Erling Smørgrav 	int com, quoted;
37*5afab0e5SDag-Erling Smørgrav 	char *t, *old_token;
387b5038d7SDag-Erling Smørgrav 	size_t i;
397b5038d7SDag-Erling Smørgrav 	const char *d;
407b5038d7SDag-Erling Smørgrav 	const char *del;
417b5038d7SDag-Erling Smørgrav 
42*5afab0e5SDag-Erling Smørgrav 	/* standard delimiters */
437b5038d7SDag-Erling Smørgrav 	if (!delim) {
447b5038d7SDag-Erling Smørgrav 		/* from isspace(3) */
457b5038d7SDag-Erling Smørgrav 		del = LDNS_PARSE_NORMAL;
467b5038d7SDag-Erling Smørgrav 	} else {
477b5038d7SDag-Erling Smørgrav 		del = delim;
487b5038d7SDag-Erling Smørgrav 	}
49*5afab0e5SDag-Erling Smørgrav 	if (!token || !limit)
50*5afab0e5SDag-Erling Smørgrav 		return LDNS_STATUS_NULL;
517b5038d7SDag-Erling Smørgrav 
52*5afab0e5SDag-Erling Smørgrav 	if (fixed) {
53*5afab0e5SDag-Erling Smørgrav 		if (*token == NULL || *limit == 0)
54*5afab0e5SDag-Erling Smørgrav 			return LDNS_STATUS_NULL;
55*5afab0e5SDag-Erling Smørgrav 
56*5afab0e5SDag-Erling Smørgrav 	} else if (*token == NULL) {
57*5afab0e5SDag-Erling Smørgrav 		*limit = LDNS_MAX_LINELEN;
58*5afab0e5SDag-Erling Smørgrav 		if (!(*token = LDNS_XMALLOC(char, *limit + 1)))
59*5afab0e5SDag-Erling Smørgrav 			return LDNS_STATUS_MEM_ERR;
60*5afab0e5SDag-Erling Smørgrav 
61*5afab0e5SDag-Erling Smørgrav 	} else if (*limit == 0)
62*5afab0e5SDag-Erling Smørgrav 		return LDNS_STATUS_ERR;
637b5038d7SDag-Erling Smørgrav 	p = 0;
647b5038d7SDag-Erling Smørgrav 	i = 0;
657b5038d7SDag-Erling Smørgrav 	com = 0;
667b5038d7SDag-Erling Smørgrav 	quoted = 0;
677b5038d7SDag-Erling Smørgrav 	prev_c = 0;
68*5afab0e5SDag-Erling Smørgrav 	t = *token;
697b5038d7SDag-Erling Smørgrav 	if (del[0] == '"') {
707b5038d7SDag-Erling Smørgrav 		quoted = 1;
717b5038d7SDag-Erling Smørgrav 	}
727b5038d7SDag-Erling Smørgrav 	while ((c = getc(f)) != EOF) {
737b5038d7SDag-Erling Smørgrav 		if (c == '\r') /* carriage return */
747b5038d7SDag-Erling Smørgrav 			c = ' ';
757b5038d7SDag-Erling Smørgrav 		if (c == '(' && prev_c != '\\' && !quoted) {
767b5038d7SDag-Erling Smørgrav 			/* this only counts for non-comments */
777b5038d7SDag-Erling Smørgrav 			if (com == 0) {
787b5038d7SDag-Erling Smørgrav 				p++;
797b5038d7SDag-Erling Smørgrav 			}
807b5038d7SDag-Erling Smørgrav 			prev_c = c;
817b5038d7SDag-Erling Smørgrav 			continue;
827b5038d7SDag-Erling Smørgrav 		}
837b5038d7SDag-Erling Smørgrav 
847b5038d7SDag-Erling Smørgrav 		if (c == ')' && prev_c != '\\' && !quoted) {
857b5038d7SDag-Erling Smørgrav 			/* this only counts for non-comments */
867b5038d7SDag-Erling Smørgrav 			if (com == 0) {
877b5038d7SDag-Erling Smørgrav 				p--;
887b5038d7SDag-Erling Smørgrav 			}
897b5038d7SDag-Erling Smørgrav 			prev_c = c;
907b5038d7SDag-Erling Smørgrav 			continue;
917b5038d7SDag-Erling Smørgrav 		}
927b5038d7SDag-Erling Smørgrav 
937b5038d7SDag-Erling Smørgrav 		if (p < 0) {
947b5038d7SDag-Erling Smørgrav 			/* more ) then ( - close off the string */
957b5038d7SDag-Erling Smørgrav 			*t = '\0';
96*5afab0e5SDag-Erling Smørgrav 			return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY
97*5afab0e5SDag-Erling Smørgrav 			              : LDNS_STATUS_OK;
987b5038d7SDag-Erling Smørgrav 		}
997b5038d7SDag-Erling Smørgrav 
1007b5038d7SDag-Erling Smørgrav 		/* do something with comments ; */
1017b5038d7SDag-Erling Smørgrav 		if (c == ';' && quoted == 0) {
1027b5038d7SDag-Erling Smørgrav 			if (prev_c != '\\') {
1037b5038d7SDag-Erling Smørgrav 				com = 1;
1047b5038d7SDag-Erling Smørgrav 			}
1057b5038d7SDag-Erling Smørgrav 		}
1067b5038d7SDag-Erling Smørgrav 		if (c == '\"' && com == 0 && prev_c != '\\') {
1077b5038d7SDag-Erling Smørgrav 			quoted = 1 - quoted;
1087b5038d7SDag-Erling Smørgrav 		}
1097b5038d7SDag-Erling Smørgrav 
1107b5038d7SDag-Erling Smørgrav 		if (c == '\n' && com != 0) {
1117b5038d7SDag-Erling Smørgrav 			/* comments */
1127b5038d7SDag-Erling Smørgrav 			com = 0;
1137b5038d7SDag-Erling Smørgrav 			*t = ' ';
1147b5038d7SDag-Erling Smørgrav 			if (line_nr) {
1157b5038d7SDag-Erling Smørgrav 				*line_nr = *line_nr + 1;
1167b5038d7SDag-Erling Smørgrav 			}
1177b5038d7SDag-Erling Smørgrav 			if (p == 0 && i > 0) {
1187b5038d7SDag-Erling Smørgrav 				goto tokenread;
1197b5038d7SDag-Erling Smørgrav 			} else {
1207b5038d7SDag-Erling Smørgrav 				prev_c = c;
1217b5038d7SDag-Erling Smørgrav 				continue;
1227b5038d7SDag-Erling Smørgrav 			}
1237b5038d7SDag-Erling Smørgrav 		}
1247b5038d7SDag-Erling Smørgrav 
1257b5038d7SDag-Erling Smørgrav 		if (com == 1) {
1267b5038d7SDag-Erling Smørgrav 			*t = ' ';
1277b5038d7SDag-Erling Smørgrav 			prev_c = c;
1287b5038d7SDag-Erling Smørgrav 			continue;
1297b5038d7SDag-Erling Smørgrav 		}
1307b5038d7SDag-Erling Smørgrav 
131*5afab0e5SDag-Erling Smørgrav 		if (c == '\n' && p != 0 && t > *token) {
1327b5038d7SDag-Erling Smørgrav 			/* in parentheses */
1337b5038d7SDag-Erling Smørgrav 			if (line_nr) {
1347b5038d7SDag-Erling Smørgrav 				*line_nr = *line_nr + 1;
1357b5038d7SDag-Erling Smørgrav 			}
136*5afab0e5SDag-Erling Smørgrav 			if (*limit > 0
137*5afab0e5SDag-Erling Smørgrav 			&&  (i >= *limit || (size_t)(t - *token) >= *limit)) {
138*5afab0e5SDag-Erling Smørgrav 				if (fixed) {
139*5afab0e5SDag-Erling Smørgrav 					*t = '\0';
140*5afab0e5SDag-Erling Smørgrav 					return LDNS_STATUS_SYNTAX_ERR;
141*5afab0e5SDag-Erling Smørgrav 				}
142*5afab0e5SDag-Erling Smørgrav 				old_token = *token;
143*5afab0e5SDag-Erling Smørgrav 				*limit *= 2;
144*5afab0e5SDag-Erling Smørgrav 				*token = LDNS_XREALLOC(*token, char, *limit + 1);
145*5afab0e5SDag-Erling Smørgrav 				if (*token == NULL) {
146*5afab0e5SDag-Erling Smørgrav 					*token = old_token;
147*5afab0e5SDag-Erling Smørgrav 					*t = '\0';
148*5afab0e5SDag-Erling Smørgrav 					return LDNS_STATUS_MEM_ERR;
149*5afab0e5SDag-Erling Smørgrav 				}
150*5afab0e5SDag-Erling Smørgrav 				if (*token != old_token)
151*5afab0e5SDag-Erling Smørgrav 					t = *token + (t - old_token);
152*5afab0e5SDag-Erling Smørgrav 			}
1537b5038d7SDag-Erling Smørgrav 			*t++ = ' ';
1547b5038d7SDag-Erling Smørgrav 			prev_c = c;
1557b5038d7SDag-Erling Smørgrav 			continue;
1567b5038d7SDag-Erling Smørgrav 		}
1577b5038d7SDag-Erling Smørgrav 
1587b5038d7SDag-Erling Smørgrav 		/* check if we hit the delim */
1597b5038d7SDag-Erling Smørgrav 		for (d = del; *d; d++) {
1607b5038d7SDag-Erling Smørgrav 			if (c == *d && i > 0 && prev_c != '\\' && p == 0) {
1617b5038d7SDag-Erling Smørgrav 				if (c == '\n' && line_nr) {
1627b5038d7SDag-Erling Smørgrav 					*line_nr = *line_nr + 1;
1637b5038d7SDag-Erling Smørgrav 				}
1647b5038d7SDag-Erling Smørgrav 				goto tokenread;
1657b5038d7SDag-Erling Smørgrav 			}
1667b5038d7SDag-Erling Smørgrav 		}
1677b5038d7SDag-Erling Smørgrav 		if (c != '\0' && c != '\n') {
1687b5038d7SDag-Erling Smørgrav 			i++;
1697b5038d7SDag-Erling Smørgrav 		}
170*5afab0e5SDag-Erling Smørgrav 		if (*limit > 0
171*5afab0e5SDag-Erling Smørgrav 		&&  (i >= *limit || (size_t)(t - *token) >= *limit)) {
172*5afab0e5SDag-Erling Smørgrav 			if (fixed) {
1737b5038d7SDag-Erling Smørgrav 				*t = '\0';
174*5afab0e5SDag-Erling Smørgrav 				return LDNS_STATUS_SYNTAX_ERR;
175*5afab0e5SDag-Erling Smørgrav 			}
176*5afab0e5SDag-Erling Smørgrav 			old_token = *token;
177*5afab0e5SDag-Erling Smørgrav 			*limit *= 2;
178*5afab0e5SDag-Erling Smørgrav 			*token = LDNS_XREALLOC(*token, char, *limit + 1);
179*5afab0e5SDag-Erling Smørgrav 			if (*token == NULL) {
180*5afab0e5SDag-Erling Smørgrav 				*token = old_token;
181*5afab0e5SDag-Erling Smørgrav 				*t = '\0';
182*5afab0e5SDag-Erling Smørgrav 				return LDNS_STATUS_MEM_ERR;
183*5afab0e5SDag-Erling Smørgrav 			}
184*5afab0e5SDag-Erling Smørgrav 			if (*token != old_token)
185*5afab0e5SDag-Erling Smørgrav 				t = *token + (t - old_token);
1867b5038d7SDag-Erling Smørgrav 		}
1877b5038d7SDag-Erling Smørgrav 		if (c != '\0' && c != '\n') {
1887b5038d7SDag-Erling Smørgrav 			*t++ = c;
1897b5038d7SDag-Erling Smørgrav 		}
190*5afab0e5SDag-Erling Smørgrav 		if (c == '\n' && line_nr) {
191*5afab0e5SDag-Erling Smørgrav 			*line_nr = *line_nr + 1;
192*5afab0e5SDag-Erling Smørgrav 		}
1937b5038d7SDag-Erling Smørgrav 		if (c == '\\' && prev_c == '\\')
1947b5038d7SDag-Erling Smørgrav 			prev_c = 0;
1957b5038d7SDag-Erling Smørgrav 		else	prev_c = c;
1967b5038d7SDag-Erling Smørgrav 	}
1977b5038d7SDag-Erling Smørgrav 	*t = '\0';
1987b5038d7SDag-Erling Smørgrav 	if (c == EOF) {
199*5afab0e5SDag-Erling Smørgrav 		return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY : LDNS_STATUS_OK;
2007b5038d7SDag-Erling Smørgrav 	}
2017b5038d7SDag-Erling Smørgrav 
2027b5038d7SDag-Erling Smørgrav 	if (p != 0) {
203*5afab0e5SDag-Erling Smørgrav 		return LDNS_STATUS_SYNTAX_ERR;
2047b5038d7SDag-Erling Smørgrav 	}
205*5afab0e5SDag-Erling Smørgrav 	return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY : LDNS_STATUS_OK;
2067b5038d7SDag-Erling Smørgrav 
2077b5038d7SDag-Erling Smørgrav tokenread:
208986ba33cSDag-Erling Smørgrav 	if(*del == '"') /* do not skip over quotes, they are significant */
209986ba33cSDag-Erling Smørgrav 		ldns_fskipcs_l(f, del+1, line_nr);
210986ba33cSDag-Erling Smørgrav 	else	ldns_fskipcs_l(f, del, line_nr);
2117b5038d7SDag-Erling Smørgrav 	*t = '\0';
2127b5038d7SDag-Erling Smørgrav 	if (p != 0) {
213*5afab0e5SDag-Erling Smørgrav 		return LDNS_STATUS_SYNTAX_ERR;
214*5afab0e5SDag-Erling Smørgrav 	}
215*5afab0e5SDag-Erling Smørgrav 	return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY : LDNS_STATUS_OK;
2167b5038d7SDag-Erling Smørgrav }
2177b5038d7SDag-Erling Smørgrav 
218*5afab0e5SDag-Erling Smørgrav 
219*5afab0e5SDag-Erling Smørgrav ssize_t
220*5afab0e5SDag-Erling Smørgrav ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
221*5afab0e5SDag-Erling Smørgrav {
222*5afab0e5SDag-Erling Smørgrav 	if (limit == 0)
223*5afab0e5SDag-Erling Smørgrav 		limit = LDNS_MAX_LINELEN;
224*5afab0e5SDag-Erling Smørgrav 	if (ldns_fget_token_l_st(f, &token, &limit, true, delim, line_nr))
225*5afab0e5SDag-Erling Smørgrav 		return -1;
226*5afab0e5SDag-Erling Smørgrav 	else
227*5afab0e5SDag-Erling Smørgrav 		return (ssize_t)strlen(token);
2287b5038d7SDag-Erling Smørgrav }
2297b5038d7SDag-Erling Smørgrav 
2307b5038d7SDag-Erling Smørgrav ssize_t
2317b5038d7SDag-Erling Smørgrav ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data,
2327b5038d7SDag-Erling Smørgrav                const char *d_del, size_t data_limit)
2337b5038d7SDag-Erling Smørgrav {
2347b5038d7SDag-Erling Smørgrav        return ldns_fget_keyword_data_l(f, keyword, k_del, data, d_del,
2357b5038d7SDag-Erling Smørgrav 		       data_limit, NULL);
2367b5038d7SDag-Erling Smørgrav }
2377b5038d7SDag-Erling Smørgrav 
2387b5038d7SDag-Erling Smørgrav ssize_t
2397b5038d7SDag-Erling Smørgrav ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data,
2407b5038d7SDag-Erling Smørgrav                const char *d_del, size_t data_limit, int *line_nr)
2417b5038d7SDag-Erling Smørgrav {
2427b5038d7SDag-Erling Smørgrav        /* we assume: keyword|sep|data */
2437b5038d7SDag-Erling Smørgrav        char *fkeyword;
2447b5038d7SDag-Erling Smørgrav        ssize_t i;
2457b5038d7SDag-Erling Smørgrav 
2467b5038d7SDag-Erling Smørgrav        if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
2477b5038d7SDag-Erling Smørgrav                return -1;
2487b5038d7SDag-Erling Smørgrav        fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
2497b5038d7SDag-Erling Smørgrav        if(!fkeyword)
2507b5038d7SDag-Erling Smørgrav                return -1;
2517b5038d7SDag-Erling Smørgrav 
2527b5038d7SDag-Erling Smørgrav        i = ldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN);
2537b5038d7SDag-Erling Smørgrav        if(i==0 || i==-1) {
2547b5038d7SDag-Erling Smørgrav                LDNS_FREE(fkeyword);
2557b5038d7SDag-Erling Smørgrav                return -1;
2567b5038d7SDag-Erling Smørgrav        }
2577b5038d7SDag-Erling Smørgrav 
2587b5038d7SDag-Erling Smørgrav        /* case??? i instead of strlen? */
2597b5038d7SDag-Erling Smørgrav        if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) {
2607b5038d7SDag-Erling Smørgrav                /* whee! */
2617b5038d7SDag-Erling Smørgrav                /* printf("%s\n%s\n", "Matching keyword", fkeyword); */
2627b5038d7SDag-Erling Smørgrav                i = ldns_fget_token_l(f, data, d_del, data_limit, line_nr);
2637b5038d7SDag-Erling Smørgrav                LDNS_FREE(fkeyword);
2647b5038d7SDag-Erling Smørgrav                return i;
2657b5038d7SDag-Erling Smørgrav        } else {
2667b5038d7SDag-Erling Smørgrav                /*printf("no match for %s (read: %s)\n", keyword, fkeyword);*/
2677b5038d7SDag-Erling Smørgrav                LDNS_FREE(fkeyword);
2687b5038d7SDag-Erling Smørgrav                return -1;
2697b5038d7SDag-Erling Smørgrav        }
2707b5038d7SDag-Erling Smørgrav }
2717b5038d7SDag-Erling Smørgrav 
2727b5038d7SDag-Erling Smørgrav 
2737b5038d7SDag-Erling Smørgrav ssize_t
2747b5038d7SDag-Erling Smørgrav ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
2757b5038d7SDag-Erling Smørgrav {
2767b5038d7SDag-Erling Smørgrav 	int c, lc;
277*5afab0e5SDag-Erling Smørgrav 	int p; /* 0 -> no parentheses seen, >0 nr of ( seen */
2787b5038d7SDag-Erling Smørgrav 	int com, quoted;
2797b5038d7SDag-Erling Smørgrav 	char *t;
2807b5038d7SDag-Erling Smørgrav 	size_t i;
2817b5038d7SDag-Erling Smørgrav 	const char *d;
2827b5038d7SDag-Erling Smørgrav 	const char *del;
2837b5038d7SDag-Erling Smørgrav 
2847b5038d7SDag-Erling Smørgrav 	/* standard delimiters */
2857b5038d7SDag-Erling Smørgrav 	if (!delim) {
2867b5038d7SDag-Erling Smørgrav 		/* from isspace(3) */
2877b5038d7SDag-Erling Smørgrav 		del = LDNS_PARSE_NORMAL;
2887b5038d7SDag-Erling Smørgrav 	} else {
2897b5038d7SDag-Erling Smørgrav 		del = delim;
2907b5038d7SDag-Erling Smørgrav 	}
2917b5038d7SDag-Erling Smørgrav 
2927b5038d7SDag-Erling Smørgrav 	p = 0;
2937b5038d7SDag-Erling Smørgrav 	i = 0;
2947b5038d7SDag-Erling Smørgrav 	com = 0;
2957b5038d7SDag-Erling Smørgrav 	quoted = 0;
2967b5038d7SDag-Erling Smørgrav 	t = token;
2977b5038d7SDag-Erling Smørgrav 	lc = 0;
2987b5038d7SDag-Erling Smørgrav 	if (del[0] == '"') {
2997b5038d7SDag-Erling Smørgrav 		quoted = 1;
3007b5038d7SDag-Erling Smørgrav 	}
3017b5038d7SDag-Erling Smørgrav 
3027b5038d7SDag-Erling Smørgrav 	while ((c = ldns_bgetc(b)) != EOF) {
3037b5038d7SDag-Erling Smørgrav 		if (c == '\r') /* carriage return */
3047b5038d7SDag-Erling Smørgrav 			c = ' ';
3057b5038d7SDag-Erling Smørgrav 		if (c == '(' && lc != '\\' && !quoted) {
3067b5038d7SDag-Erling Smørgrav 			/* this only counts for non-comments */
3077b5038d7SDag-Erling Smørgrav 			if (com == 0) {
3087b5038d7SDag-Erling Smørgrav 				p++;
3097b5038d7SDag-Erling Smørgrav 			}
3107b5038d7SDag-Erling Smørgrav 			lc = c;
3117b5038d7SDag-Erling Smørgrav 			continue;
3127b5038d7SDag-Erling Smørgrav 		}
3137b5038d7SDag-Erling Smørgrav 
3147b5038d7SDag-Erling Smørgrav 		if (c == ')' && lc != '\\' && !quoted) {
3157b5038d7SDag-Erling Smørgrav 			/* this only counts for non-comments */
3167b5038d7SDag-Erling Smørgrav 			if (com == 0) {
3177b5038d7SDag-Erling Smørgrav 				p--;
3187b5038d7SDag-Erling Smørgrav 			}
3197b5038d7SDag-Erling Smørgrav 			lc = c;
3207b5038d7SDag-Erling Smørgrav 			continue;
3217b5038d7SDag-Erling Smørgrav 		}
3227b5038d7SDag-Erling Smørgrav 
3237b5038d7SDag-Erling Smørgrav 		if (p < 0) {
3247b5038d7SDag-Erling Smørgrav 			/* more ) then ( */
3257b5038d7SDag-Erling Smørgrav 			*t = '\0';
3267b5038d7SDag-Erling Smørgrav 			return 0;
3277b5038d7SDag-Erling Smørgrav 		}
3287b5038d7SDag-Erling Smørgrav 
3297b5038d7SDag-Erling Smørgrav 		/* do something with comments ; */
3307b5038d7SDag-Erling Smørgrav 		if (c == ';' && quoted == 0) {
3317b5038d7SDag-Erling Smørgrav 			if (lc != '\\') {
3327b5038d7SDag-Erling Smørgrav 				com = 1;
3337b5038d7SDag-Erling Smørgrav 			}
3347b5038d7SDag-Erling Smørgrav 		}
3357b5038d7SDag-Erling Smørgrav 		if (c == '"' && com == 0 && lc != '\\') {
3367b5038d7SDag-Erling Smørgrav 			quoted = 1 - quoted;
3377b5038d7SDag-Erling Smørgrav 		}
3387b5038d7SDag-Erling Smørgrav 
3397b5038d7SDag-Erling Smørgrav 		if (c == '\n' && com != 0) {
3407b5038d7SDag-Erling Smørgrav 			/* comments */
3417b5038d7SDag-Erling Smørgrav 			com = 0;
3427b5038d7SDag-Erling Smørgrav 			*t = ' ';
3437b5038d7SDag-Erling Smørgrav 			lc = c;
3447b5038d7SDag-Erling Smørgrav 			continue;
3457b5038d7SDag-Erling Smørgrav 		}
3467b5038d7SDag-Erling Smørgrav 
3477b5038d7SDag-Erling Smørgrav 		if (com == 1) {
3487b5038d7SDag-Erling Smørgrav 			*t = ' ';
3497b5038d7SDag-Erling Smørgrav 			lc = c;
3507b5038d7SDag-Erling Smørgrav 			continue;
3517b5038d7SDag-Erling Smørgrav 		}
3527b5038d7SDag-Erling Smørgrav 
3537b5038d7SDag-Erling Smørgrav 		if (c == '\n' && p != 0) {
3547b5038d7SDag-Erling Smørgrav 			/* in parentheses */
3557b5038d7SDag-Erling Smørgrav 			*t++ = ' ';
3567b5038d7SDag-Erling Smørgrav 			lc = c;
3577b5038d7SDag-Erling Smørgrav 			continue;
3587b5038d7SDag-Erling Smørgrav 		}
3597b5038d7SDag-Erling Smørgrav 
3607b5038d7SDag-Erling Smørgrav 		/* check if we hit the delim */
3617b5038d7SDag-Erling Smørgrav 		for (d = del; *d; d++) {
3627b5038d7SDag-Erling Smørgrav                         if (c == *d && lc != '\\' && p == 0) {
3637b5038d7SDag-Erling Smørgrav 				goto tokenread;
3647b5038d7SDag-Erling Smørgrav                         }
3657b5038d7SDag-Erling Smørgrav 		}
3667b5038d7SDag-Erling Smørgrav 
3677b5038d7SDag-Erling Smørgrav 		i++;
36817d15b25SDag-Erling Smørgrav 		if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
3697b5038d7SDag-Erling Smørgrav 			*t = '\0';
3707b5038d7SDag-Erling Smørgrav 			return -1;
3717b5038d7SDag-Erling Smørgrav 		}
3727b5038d7SDag-Erling Smørgrav 		*t++ = c;
3737b5038d7SDag-Erling Smørgrav 
3747b5038d7SDag-Erling Smørgrav 		if (c == '\\' && lc == '\\') {
3757b5038d7SDag-Erling Smørgrav 			lc = 0;
3767b5038d7SDag-Erling Smørgrav 		} else {
3777b5038d7SDag-Erling Smørgrav 			lc = c;
3787b5038d7SDag-Erling Smørgrav 		}
3797b5038d7SDag-Erling Smørgrav 	}
3807b5038d7SDag-Erling Smørgrav 	*t = '\0';
3817b5038d7SDag-Erling Smørgrav 	if (i == 0) {
3827b5038d7SDag-Erling Smørgrav 		/* nothing read */
3837b5038d7SDag-Erling Smørgrav 		return -1;
3847b5038d7SDag-Erling Smørgrav 	}
3857b5038d7SDag-Erling Smørgrav 	if (p != 0) {
3867b5038d7SDag-Erling Smørgrav 		return -1;
3877b5038d7SDag-Erling Smørgrav 	}
3887b5038d7SDag-Erling Smørgrav 	return (ssize_t)i;
3897b5038d7SDag-Erling Smørgrav 
3907b5038d7SDag-Erling Smørgrav tokenread:
391986ba33cSDag-Erling Smørgrav 	if(*del == '"') /* do not skip over quotes, they are significant */
392986ba33cSDag-Erling Smørgrav 		ldns_bskipcs(b, del+1);
393986ba33cSDag-Erling Smørgrav 	else	ldns_bskipcs(b, del);
3947b5038d7SDag-Erling Smørgrav 	*t = '\0';
3957b5038d7SDag-Erling Smørgrav 
3967b5038d7SDag-Erling Smørgrav 	if (p != 0) {
3977b5038d7SDag-Erling Smørgrav 		return -1;
3987b5038d7SDag-Erling Smørgrav 	}
3997b5038d7SDag-Erling Smørgrav 	return (ssize_t)i;
4007b5038d7SDag-Erling Smørgrav }
4017b5038d7SDag-Erling Smørgrav 
4027b5038d7SDag-Erling Smørgrav 
4037b5038d7SDag-Erling Smørgrav void
4047b5038d7SDag-Erling Smørgrav ldns_bskipcs(ldns_buffer *buffer, const char *s)
4057b5038d7SDag-Erling Smørgrav {
4067b5038d7SDag-Erling Smørgrav         bool found;
4077b5038d7SDag-Erling Smørgrav         char c;
4087b5038d7SDag-Erling Smørgrav         const char *d;
4097b5038d7SDag-Erling Smørgrav 
4107b5038d7SDag-Erling Smørgrav         while(ldns_buffer_available_at(buffer, buffer->_position, sizeof(char))) {
4117b5038d7SDag-Erling Smørgrav                 c = (char) ldns_buffer_read_u8_at(buffer, buffer->_position);
4127b5038d7SDag-Erling Smørgrav                 found = false;
4137b5038d7SDag-Erling Smørgrav                 for (d = s; *d; d++) {
4147b5038d7SDag-Erling Smørgrav                         if (*d == c) {
4157b5038d7SDag-Erling Smørgrav                                 found = true;
4167b5038d7SDag-Erling Smørgrav                         }
4177b5038d7SDag-Erling Smørgrav                 }
4187b5038d7SDag-Erling Smørgrav                 if (found && buffer->_limit > buffer->_position) {
4197b5038d7SDag-Erling Smørgrav                         buffer->_position += sizeof(char);
4207b5038d7SDag-Erling Smørgrav                 } else {
4217b5038d7SDag-Erling Smørgrav                         return;
4227b5038d7SDag-Erling Smørgrav                 }
4237b5038d7SDag-Erling Smørgrav         }
4247b5038d7SDag-Erling Smørgrav }
4257b5038d7SDag-Erling Smørgrav 
4267b5038d7SDag-Erling Smørgrav void
4277b5038d7SDag-Erling Smørgrav ldns_fskipcs(FILE *fp, const char *s)
4287b5038d7SDag-Erling Smørgrav {
4297b5038d7SDag-Erling Smørgrav 	ldns_fskipcs_l(fp, s, NULL);
4307b5038d7SDag-Erling Smørgrav }
4317b5038d7SDag-Erling Smørgrav 
4327b5038d7SDag-Erling Smørgrav void
4337b5038d7SDag-Erling Smørgrav ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr)
4347b5038d7SDag-Erling Smørgrav {
4357b5038d7SDag-Erling Smørgrav         bool found;
4367b5038d7SDag-Erling Smørgrav         int c;
4377b5038d7SDag-Erling Smørgrav         const char *d;
4387b5038d7SDag-Erling Smørgrav 
4397b5038d7SDag-Erling Smørgrav 	while ((c = fgetc(fp)) != EOF) {
4407b5038d7SDag-Erling Smørgrav 		if (line_nr && c == '\n') {
4417b5038d7SDag-Erling Smørgrav 			*line_nr = *line_nr + 1;
4427b5038d7SDag-Erling Smørgrav 		}
4437b5038d7SDag-Erling Smørgrav                 found = false;
4447b5038d7SDag-Erling Smørgrav                 for (d = s; *d; d++) {
4457b5038d7SDag-Erling Smørgrav                         if (*d == c) {
4467b5038d7SDag-Erling Smørgrav                                 found = true;
4477b5038d7SDag-Erling Smørgrav                         }
4487b5038d7SDag-Erling Smørgrav                 }
4497b5038d7SDag-Erling Smørgrav 		if (!found) {
4507b5038d7SDag-Erling Smørgrav 			/* with getc, we've read too far */
4517b5038d7SDag-Erling Smørgrav 			ungetc(c, fp);
4527b5038d7SDag-Erling Smørgrav 			return;
4537b5038d7SDag-Erling Smørgrav 		}
4547b5038d7SDag-Erling Smørgrav 	}
4557b5038d7SDag-Erling Smørgrav }
4567b5038d7SDag-Erling Smørgrav 
4577b5038d7SDag-Erling Smørgrav ssize_t
4587b5038d7SDag-Erling Smørgrav ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, char
4597b5038d7SDag-Erling Smørgrav *data, const char *d_del, size_t data_limit)
4607b5038d7SDag-Erling Smørgrav {
4617b5038d7SDag-Erling Smørgrav        /* we assume: keyword|sep|data */
4627b5038d7SDag-Erling Smørgrav        char *fkeyword;
4637b5038d7SDag-Erling Smørgrav        ssize_t i;
4647b5038d7SDag-Erling Smørgrav 
4657b5038d7SDag-Erling Smørgrav        if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
4667b5038d7SDag-Erling Smørgrav                return -1;
4677b5038d7SDag-Erling Smørgrav        fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
4687b5038d7SDag-Erling Smørgrav        if(!fkeyword)
4697b5038d7SDag-Erling Smørgrav                return -1; /* out of memory */
4707b5038d7SDag-Erling Smørgrav 
4717b5038d7SDag-Erling Smørgrav        i = ldns_bget_token(b, fkeyword, k_del, data_limit);
4727b5038d7SDag-Erling Smørgrav        if(i==0 || i==-1) {
4737b5038d7SDag-Erling Smørgrav                LDNS_FREE(fkeyword);
4747b5038d7SDag-Erling Smørgrav                return -1; /* nothing read */
4757b5038d7SDag-Erling Smørgrav        }
4767b5038d7SDag-Erling Smørgrav 
4777b5038d7SDag-Erling Smørgrav        /* case??? */
4787b5038d7SDag-Erling Smørgrav        if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) {
4797b5038d7SDag-Erling Smørgrav                LDNS_FREE(fkeyword);
4807b5038d7SDag-Erling Smørgrav                /* whee, the match! */
4817b5038d7SDag-Erling Smørgrav                /* retrieve it's data */
4827b5038d7SDag-Erling Smørgrav                i = ldns_bget_token(b, data, d_del, 0);
4837b5038d7SDag-Erling Smørgrav                return i;
4847b5038d7SDag-Erling Smørgrav        } else {
4857b5038d7SDag-Erling Smørgrav                LDNS_FREE(fkeyword);
4867b5038d7SDag-Erling Smørgrav                return -1;
4877b5038d7SDag-Erling Smørgrav        }
4887b5038d7SDag-Erling Smørgrav }
4897b5038d7SDag-Erling Smørgrav 
490