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