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