xref: /dragonfly/contrib/ldns/parse.c (revision ee791feb)
1825eb42bSJan Lentfer /*
2825eb42bSJan Lentfer  * a generic (simple) parser. Use to parse rr's, private key
3825eb42bSJan Lentfer  * information and /etc/resolv.conf files
4825eb42bSJan Lentfer  *
5825eb42bSJan Lentfer  * a Net::DNS like library for C
6825eb42bSJan Lentfer  * LibDNS Team @ NLnet Labs
7825eb42bSJan Lentfer  * (c) NLnet Labs, 2005-2006
8825eb42bSJan Lentfer  * See the file LICENSE for the license
9825eb42bSJan Lentfer  */
10825eb42bSJan Lentfer #include <ldns/config.h>
11825eb42bSJan Lentfer #include <ldns/ldns.h>
12825eb42bSJan Lentfer 
13825eb42bSJan Lentfer #include <limits.h>
14825eb42bSJan Lentfer #include <strings.h>
15825eb42bSJan Lentfer 
16825eb42bSJan Lentfer ldns_lookup_table ldns_directive_types[] = {
17825eb42bSJan Lentfer         { LDNS_DIR_TTL, "$TTL" },
18825eb42bSJan Lentfer         { LDNS_DIR_ORIGIN, "$ORIGIN" },
19825eb42bSJan Lentfer         { LDNS_DIR_INCLUDE, "$INCLUDE" },
20825eb42bSJan Lentfer         { 0, NULL }
21825eb42bSJan Lentfer };
22825eb42bSJan Lentfer 
23825eb42bSJan Lentfer /* add max_limit here? */
24825eb42bSJan Lentfer ssize_t
ldns_fget_token(FILE * f,char * token,const char * delim,size_t limit)25825eb42bSJan Lentfer ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit)
26825eb42bSJan Lentfer {
27825eb42bSJan Lentfer 	return ldns_fget_token_l(f, token, delim, limit, NULL);
28825eb42bSJan Lentfer }
29825eb42bSJan Lentfer 
30*ee791febSAntonio Huete Jimenez ldns_status
ldns_fget_token_l_st(FILE * f,char ** token,size_t * limit,bool fixed,const char * delim,int * line_nr)31*ee791febSAntonio Huete Jimenez ldns_fget_token_l_st(FILE *f, char **token, size_t *limit, bool fixed
32*ee791febSAntonio Huete Jimenez                     , const char *delim, int *line_nr)
33825eb42bSJan Lentfer {
34825eb42bSJan Lentfer 	int c, prev_c;
35*ee791febSAntonio Huete Jimenez 	int p; /* 0 -> no parentheses seen, >0 nr of ( seen */
36825eb42bSJan Lentfer 	int com, quoted;
37*ee791febSAntonio Huete Jimenez 	char *t, *old_token;
38825eb42bSJan Lentfer 	size_t i;
39825eb42bSJan Lentfer 	const char *d;
40825eb42bSJan Lentfer 	const char *del;
41825eb42bSJan Lentfer 
42*ee791febSAntonio Huete Jimenez 	/* standard delimiters */
43825eb42bSJan Lentfer 	if (!delim) {
44825eb42bSJan Lentfer 		/* from isspace(3) */
45825eb42bSJan Lentfer 		del = LDNS_PARSE_NORMAL;
46825eb42bSJan Lentfer 	} else {
47825eb42bSJan Lentfer 		del = delim;
48825eb42bSJan Lentfer 	}
49*ee791febSAntonio Huete Jimenez 	if (!token || !limit)
50*ee791febSAntonio Huete Jimenez 		return LDNS_STATUS_NULL;
51825eb42bSJan Lentfer 
52*ee791febSAntonio Huete Jimenez 	if (fixed) {
53*ee791febSAntonio Huete Jimenez 		if (*token == NULL || *limit == 0)
54*ee791febSAntonio Huete Jimenez 			return LDNS_STATUS_NULL;
55*ee791febSAntonio Huete Jimenez 
56*ee791febSAntonio Huete Jimenez 	} else if (*token == NULL) {
57*ee791febSAntonio Huete Jimenez 		*limit = LDNS_MAX_LINELEN;
58*ee791febSAntonio Huete Jimenez 		if (!(*token = LDNS_XMALLOC(char, *limit + 1)))
59*ee791febSAntonio Huete Jimenez 			return LDNS_STATUS_MEM_ERR;
60*ee791febSAntonio Huete Jimenez 
61*ee791febSAntonio Huete Jimenez 	} else if (*limit == 0)
62*ee791febSAntonio Huete Jimenez 		return LDNS_STATUS_ERR;
63825eb42bSJan Lentfer 	p = 0;
64825eb42bSJan Lentfer 	i = 0;
65825eb42bSJan Lentfer 	com = 0;
66825eb42bSJan Lentfer 	quoted = 0;
67825eb42bSJan Lentfer 	prev_c = 0;
68*ee791febSAntonio Huete Jimenez 	t = *token;
69825eb42bSJan Lentfer 	if (del[0] == '"') {
70825eb42bSJan Lentfer 		quoted = 1;
71825eb42bSJan Lentfer 	}
72825eb42bSJan Lentfer 	while ((c = getc(f)) != EOF) {
73d1b2b5caSJohn Marino 		if (c == '\r') /* carriage return */
74d1b2b5caSJohn Marino 			c = ' ';
75825eb42bSJan Lentfer 		if (c == '(' && prev_c != '\\' && !quoted) {
76825eb42bSJan Lentfer 			/* this only counts for non-comments */
77825eb42bSJan Lentfer 			if (com == 0) {
78825eb42bSJan Lentfer 				p++;
79825eb42bSJan Lentfer 			}
80825eb42bSJan Lentfer 			prev_c = c;
81825eb42bSJan Lentfer 			continue;
82825eb42bSJan Lentfer 		}
83825eb42bSJan Lentfer 
84825eb42bSJan Lentfer 		if (c == ')' && prev_c != '\\' && !quoted) {
85825eb42bSJan Lentfer 			/* this only counts for non-comments */
86825eb42bSJan Lentfer 			if (com == 0) {
87825eb42bSJan Lentfer 				p--;
88825eb42bSJan Lentfer 			}
89825eb42bSJan Lentfer 			prev_c = c;
90825eb42bSJan Lentfer 			continue;
91825eb42bSJan Lentfer 		}
92825eb42bSJan Lentfer 
93825eb42bSJan Lentfer 		if (p < 0) {
94825eb42bSJan Lentfer 			/* more ) then ( - close off the string */
95825eb42bSJan Lentfer 			*t = '\0';
96*ee791febSAntonio Huete Jimenez 			return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY
97*ee791febSAntonio Huete Jimenez 			              : LDNS_STATUS_OK;
98825eb42bSJan Lentfer 		}
99825eb42bSJan Lentfer 
100825eb42bSJan Lentfer 		/* do something with comments ; */
101825eb42bSJan Lentfer 		if (c == ';' && quoted == 0) {
102825eb42bSJan Lentfer 			if (prev_c != '\\') {
103825eb42bSJan Lentfer 				com = 1;
104825eb42bSJan Lentfer 			}
105825eb42bSJan Lentfer 		}
106825eb42bSJan Lentfer 		if (c == '\"' && com == 0 && prev_c != '\\') {
107825eb42bSJan Lentfer 			quoted = 1 - quoted;
108825eb42bSJan Lentfer 		}
109825eb42bSJan Lentfer 
110825eb42bSJan Lentfer 		if (c == '\n' && com != 0) {
111825eb42bSJan Lentfer 			/* comments */
112825eb42bSJan Lentfer 			com = 0;
113825eb42bSJan Lentfer 			*t = ' ';
114825eb42bSJan Lentfer 			if (line_nr) {
115825eb42bSJan Lentfer 				*line_nr = *line_nr + 1;
116825eb42bSJan Lentfer 			}
117825eb42bSJan Lentfer 			if (p == 0 && i > 0) {
118825eb42bSJan Lentfer 				goto tokenread;
119825eb42bSJan Lentfer 			} else {
120825eb42bSJan Lentfer 				prev_c = c;
121825eb42bSJan Lentfer 				continue;
122825eb42bSJan Lentfer 			}
123825eb42bSJan Lentfer 		}
124825eb42bSJan Lentfer 
125825eb42bSJan Lentfer 		if (com == 1) {
126825eb42bSJan Lentfer 			*t = ' ';
127825eb42bSJan Lentfer 			prev_c = c;
128825eb42bSJan Lentfer 			continue;
129825eb42bSJan Lentfer 		}
130825eb42bSJan Lentfer 
131*ee791febSAntonio Huete Jimenez 		if (c == '\n' && p != 0 && t > *token) {
132825eb42bSJan Lentfer 			/* in parentheses */
133825eb42bSJan Lentfer 			if (line_nr) {
134825eb42bSJan Lentfer 				*line_nr = *line_nr + 1;
135825eb42bSJan Lentfer 			}
136*ee791febSAntonio Huete Jimenez 			if (*limit > 0
137*ee791febSAntonio Huete Jimenez 			&&  (i >= *limit || (size_t)(t - *token) >= *limit)) {
138*ee791febSAntonio Huete Jimenez 				if (fixed) {
139819dec71SDaniel Fojt 					*t = '\0';
140*ee791febSAntonio Huete Jimenez 					return LDNS_STATUS_SYNTAX_ERR;
141*ee791febSAntonio Huete Jimenez 				}
142*ee791febSAntonio Huete Jimenez 				old_token = *token;
143*ee791febSAntonio Huete Jimenez 				*limit *= 2;
144*ee791febSAntonio Huete Jimenez 				*token = LDNS_XREALLOC(*token, char, *limit + 1);
145*ee791febSAntonio Huete Jimenez 				if (*token == NULL) {
146*ee791febSAntonio Huete Jimenez 					*token = old_token;
147*ee791febSAntonio Huete Jimenez 					*t = '\0';
148*ee791febSAntonio Huete Jimenez 					return LDNS_STATUS_MEM_ERR;
149*ee791febSAntonio Huete Jimenez 				}
150*ee791febSAntonio Huete Jimenez 				if (*token != old_token)
151*ee791febSAntonio Huete Jimenez 					t = *token + (t - old_token);
152819dec71SDaniel Fojt 			}
153ac996e71SJan Lentfer 			*t++ = ' ';
154825eb42bSJan Lentfer 			prev_c = c;
155825eb42bSJan Lentfer 			continue;
156825eb42bSJan Lentfer 		}
157825eb42bSJan Lentfer 
158825eb42bSJan Lentfer 		/* check if we hit the delim */
159825eb42bSJan Lentfer 		for (d = del; *d; d++) {
160d1b2b5caSJohn Marino 			if (c == *d && i > 0 && prev_c != '\\' && p == 0) {
161825eb42bSJan Lentfer 				if (c == '\n' && line_nr) {
162825eb42bSJan Lentfer 					*line_nr = *line_nr + 1;
163825eb42bSJan Lentfer 				}
164825eb42bSJan Lentfer 				goto tokenread;
165825eb42bSJan Lentfer 			}
166825eb42bSJan Lentfer 		}
167825eb42bSJan Lentfer 		if (c != '\0' && c != '\n') {
168825eb42bSJan Lentfer 			i++;
169825eb42bSJan Lentfer 		}
170*ee791febSAntonio Huete Jimenez 		if (*limit > 0
171*ee791febSAntonio Huete Jimenez 		&&  (i >= *limit || (size_t)(t - *token) >= *limit)) {
172*ee791febSAntonio Huete Jimenez 			if (fixed) {
173825eb42bSJan Lentfer 				*t = '\0';
174*ee791febSAntonio Huete Jimenez 				return LDNS_STATUS_SYNTAX_ERR;
175*ee791febSAntonio Huete Jimenez 			}
176*ee791febSAntonio Huete Jimenez 			old_token = *token;
177*ee791febSAntonio Huete Jimenez 			*limit *= 2;
178*ee791febSAntonio Huete Jimenez 			*token = LDNS_XREALLOC(*token, char, *limit + 1);
179*ee791febSAntonio Huete Jimenez 			if (*token == NULL) {
180*ee791febSAntonio Huete Jimenez 				*token = old_token;
181*ee791febSAntonio Huete Jimenez 				*t = '\0';
182*ee791febSAntonio Huete Jimenez 				return LDNS_STATUS_MEM_ERR;
183*ee791febSAntonio Huete Jimenez 			}
184*ee791febSAntonio Huete Jimenez 			if (*token != old_token)
185*ee791febSAntonio Huete Jimenez 				t = *token + (t - old_token);
186825eb42bSJan Lentfer 		}
187b5dedccaSJan Lentfer 		if (c != '\0' && c != '\n') {
188b5dedccaSJan Lentfer 			*t++ = c;
189b5dedccaSJan Lentfer 		}
190*ee791febSAntonio Huete Jimenez 		if (c == '\n' && line_nr) {
191*ee791febSAntonio Huete Jimenez 			*line_nr = *line_nr + 1;
192*ee791febSAntonio Huete Jimenez 		}
193825eb42bSJan Lentfer 		if (c == '\\' && prev_c == '\\')
194825eb42bSJan Lentfer 			prev_c = 0;
195825eb42bSJan Lentfer 		else	prev_c = c;
196825eb42bSJan Lentfer 	}
197825eb42bSJan Lentfer 	*t = '\0';
198825eb42bSJan Lentfer 	if (c == EOF) {
199*ee791febSAntonio Huete Jimenez 		return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY : LDNS_STATUS_OK;
200825eb42bSJan Lentfer 	}
201825eb42bSJan Lentfer 
202825eb42bSJan Lentfer 	if (p != 0) {
203*ee791febSAntonio Huete Jimenez 		return LDNS_STATUS_SYNTAX_ERR;
204825eb42bSJan Lentfer 	}
205*ee791febSAntonio Huete Jimenez 	return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY : LDNS_STATUS_OK;
206825eb42bSJan Lentfer 
207825eb42bSJan Lentfer tokenread:
2085340022aSzrj 	if(*del == '"') /* do not skip over quotes, they are significant */
2095340022aSzrj 		ldns_fskipcs_l(f, del+1, line_nr);
2105340022aSzrj 	else	ldns_fskipcs_l(f, del, line_nr);
211825eb42bSJan Lentfer 	*t = '\0';
212825eb42bSJan Lentfer 	if (p != 0) {
213*ee791febSAntonio Huete Jimenez 		return LDNS_STATUS_SYNTAX_ERR;
214*ee791febSAntonio Huete Jimenez 	}
215*ee791febSAntonio Huete Jimenez 	return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY : LDNS_STATUS_OK;
216825eb42bSJan Lentfer }
217825eb42bSJan Lentfer 
218*ee791febSAntonio Huete Jimenez 
219*ee791febSAntonio Huete Jimenez ssize_t
ldns_fget_token_l(FILE * f,char * token,const char * delim,size_t limit,int * line_nr)220*ee791febSAntonio Huete Jimenez ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
221*ee791febSAntonio Huete Jimenez {
222*ee791febSAntonio Huete Jimenez 	if (limit == 0)
223*ee791febSAntonio Huete Jimenez 		limit = LDNS_MAX_LINELEN;
224*ee791febSAntonio Huete Jimenez 	if (ldns_fget_token_l_st(f, &token, &limit, true, delim, line_nr))
225*ee791febSAntonio Huete Jimenez 		return -1;
226*ee791febSAntonio Huete Jimenez 	else
227*ee791febSAntonio Huete Jimenez 		return (ssize_t)strlen(token);
228825eb42bSJan Lentfer }
229825eb42bSJan Lentfer 
230825eb42bSJan Lentfer ssize_t
ldns_fget_keyword_data(FILE * f,const char * keyword,const char * k_del,char * data,const char * d_del,size_t data_limit)231825eb42bSJan Lentfer ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data,
232825eb42bSJan Lentfer                const char *d_del, size_t data_limit)
233825eb42bSJan Lentfer {
234825eb42bSJan Lentfer        return ldns_fget_keyword_data_l(f, keyword, k_del, data, d_del,
235825eb42bSJan Lentfer 		       data_limit, NULL);
236825eb42bSJan Lentfer }
237825eb42bSJan Lentfer 
238825eb42bSJan Lentfer ssize_t
ldns_fget_keyword_data_l(FILE * f,const char * keyword,const char * k_del,char * data,const char * d_del,size_t data_limit,int * line_nr)239825eb42bSJan Lentfer ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data,
240825eb42bSJan Lentfer                const char *d_del, size_t data_limit, int *line_nr)
241825eb42bSJan Lentfer {
242825eb42bSJan Lentfer        /* we assume: keyword|sep|data */
243825eb42bSJan Lentfer        char *fkeyword;
244825eb42bSJan Lentfer        ssize_t i;
245825eb42bSJan Lentfer 
246fd185f4dSJan Lentfer        if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
247fd185f4dSJan Lentfer                return -1;
248825eb42bSJan Lentfer        fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
249ac996e71SJan Lentfer        if(!fkeyword)
250ac996e71SJan Lentfer                return -1;
251825eb42bSJan Lentfer 
252825eb42bSJan Lentfer        i = ldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN);
253ac996e71SJan Lentfer        if(i==0 || i==-1) {
254ac996e71SJan Lentfer                LDNS_FREE(fkeyword);
255ac996e71SJan Lentfer                return -1;
256ac996e71SJan Lentfer        }
257825eb42bSJan Lentfer 
258825eb42bSJan Lentfer        /* case??? i instead of strlen? */
259825eb42bSJan Lentfer        if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) {
260825eb42bSJan Lentfer                /* whee! */
261825eb42bSJan Lentfer                /* printf("%s\n%s\n", "Matching keyword", fkeyword); */
262825eb42bSJan Lentfer                i = ldns_fget_token_l(f, data, d_del, data_limit, line_nr);
263825eb42bSJan Lentfer                LDNS_FREE(fkeyword);
264825eb42bSJan Lentfer                return i;
265825eb42bSJan Lentfer        } else {
266825eb42bSJan Lentfer                /*printf("no match for %s (read: %s)\n", keyword, fkeyword);*/
267825eb42bSJan Lentfer                LDNS_FREE(fkeyword);
268825eb42bSJan Lentfer                return -1;
269825eb42bSJan Lentfer        }
270825eb42bSJan Lentfer }
271825eb42bSJan Lentfer 
272825eb42bSJan Lentfer 
273825eb42bSJan Lentfer ssize_t
ldns_bget_token(ldns_buffer * b,char * token,const char * delim,size_t limit)274825eb42bSJan Lentfer ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
275825eb42bSJan Lentfer {
276825eb42bSJan Lentfer 	int c, lc;
277*ee791febSAntonio Huete Jimenez 	int p; /* 0 -> no parentheses seen, >0 nr of ( seen */
278825eb42bSJan Lentfer 	int com, quoted;
279825eb42bSJan Lentfer 	char *t;
280825eb42bSJan Lentfer 	size_t i;
281825eb42bSJan Lentfer 	const char *d;
282825eb42bSJan Lentfer 	const char *del;
283825eb42bSJan Lentfer 
284825eb42bSJan Lentfer 	/* standard delimiters */
285825eb42bSJan Lentfer 	if (!delim) {
286825eb42bSJan Lentfer 		/* from isspace(3) */
287825eb42bSJan Lentfer 		del = LDNS_PARSE_NORMAL;
288825eb42bSJan Lentfer 	} else {
289825eb42bSJan Lentfer 		del = delim;
290825eb42bSJan Lentfer 	}
291825eb42bSJan Lentfer 
292825eb42bSJan Lentfer 	p = 0;
293825eb42bSJan Lentfer 	i = 0;
294825eb42bSJan Lentfer 	com = 0;
295825eb42bSJan Lentfer 	quoted = 0;
296825eb42bSJan Lentfer 	t = token;
297825eb42bSJan Lentfer 	lc = 0;
298ac996e71SJan Lentfer 	if (del[0] == '"') {
299825eb42bSJan Lentfer 		quoted = 1;
300825eb42bSJan Lentfer 	}
301825eb42bSJan Lentfer 
302825eb42bSJan Lentfer 	while ((c = ldns_bgetc(b)) != EOF) {
303d1b2b5caSJohn Marino 		if (c == '\r') /* carriage return */
304d1b2b5caSJohn Marino 			c = ' ';
305825eb42bSJan Lentfer 		if (c == '(' && lc != '\\' && !quoted) {
306825eb42bSJan Lentfer 			/* this only counts for non-comments */
307825eb42bSJan Lentfer 			if (com == 0) {
308825eb42bSJan Lentfer 				p++;
309825eb42bSJan Lentfer 			}
310825eb42bSJan Lentfer 			lc = c;
311825eb42bSJan Lentfer 			continue;
312825eb42bSJan Lentfer 		}
313825eb42bSJan Lentfer 
314825eb42bSJan Lentfer 		if (c == ')' && lc != '\\' && !quoted) {
315825eb42bSJan Lentfer 			/* this only counts for non-comments */
316825eb42bSJan Lentfer 			if (com == 0) {
317825eb42bSJan Lentfer 				p--;
318825eb42bSJan Lentfer 			}
319825eb42bSJan Lentfer 			lc = c;
320825eb42bSJan Lentfer 			continue;
321825eb42bSJan Lentfer 		}
322825eb42bSJan Lentfer 
323825eb42bSJan Lentfer 		if (p < 0) {
324825eb42bSJan Lentfer 			/* more ) then ( */
325825eb42bSJan Lentfer 			*t = '\0';
326825eb42bSJan Lentfer 			return 0;
327825eb42bSJan Lentfer 		}
328825eb42bSJan Lentfer 
329825eb42bSJan Lentfer 		/* do something with comments ; */
330825eb42bSJan Lentfer 		if (c == ';' && quoted == 0) {
331825eb42bSJan Lentfer 			if (lc != '\\') {
332825eb42bSJan Lentfer 				com = 1;
333825eb42bSJan Lentfer 			}
334825eb42bSJan Lentfer 		}
335825eb42bSJan Lentfer 		if (c == '"' && com == 0 && lc != '\\') {
336825eb42bSJan Lentfer 			quoted = 1 - quoted;
337825eb42bSJan Lentfer 		}
338825eb42bSJan Lentfer 
339825eb42bSJan Lentfer 		if (c == '\n' && com != 0) {
340825eb42bSJan Lentfer 			/* comments */
341825eb42bSJan Lentfer 			com = 0;
342825eb42bSJan Lentfer 			*t = ' ';
343825eb42bSJan Lentfer 			lc = c;
344825eb42bSJan Lentfer 			continue;
345825eb42bSJan Lentfer 		}
346825eb42bSJan Lentfer 
347825eb42bSJan Lentfer 		if (com == 1) {
348825eb42bSJan Lentfer 			*t = ' ';
349825eb42bSJan Lentfer 			lc = c;
350825eb42bSJan Lentfer 			continue;
351825eb42bSJan Lentfer 		}
352825eb42bSJan Lentfer 
353825eb42bSJan Lentfer 		if (c == '\n' && p != 0) {
354825eb42bSJan Lentfer 			/* in parentheses */
355ac996e71SJan Lentfer 			*t++ = ' ';
356825eb42bSJan Lentfer 			lc = c;
357825eb42bSJan Lentfer 			continue;
358825eb42bSJan Lentfer 		}
359825eb42bSJan Lentfer 
360825eb42bSJan Lentfer 		/* check if we hit the delim */
361825eb42bSJan Lentfer 		for (d = del; *d; d++) {
362d1b2b5caSJohn Marino                         if (c == *d && lc != '\\' && p == 0) {
363825eb42bSJan Lentfer 				goto tokenread;
364825eb42bSJan Lentfer                         }
365825eb42bSJan Lentfer 		}
366825eb42bSJan Lentfer 
367825eb42bSJan Lentfer 		i++;
3685340022aSzrj 		if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
369825eb42bSJan Lentfer 			*t = '\0';
370825eb42bSJan Lentfer 			return -1;
371825eb42bSJan Lentfer 		}
372b5dedccaSJan Lentfer 		*t++ = c;
373825eb42bSJan Lentfer 
374825eb42bSJan Lentfer 		if (c == '\\' && lc == '\\') {
375825eb42bSJan Lentfer 			lc = 0;
376825eb42bSJan Lentfer 		} else {
377825eb42bSJan Lentfer 			lc = c;
378825eb42bSJan Lentfer 		}
379825eb42bSJan Lentfer 	}
380825eb42bSJan Lentfer 	*t = '\0';
381825eb42bSJan Lentfer 	if (i == 0) {
382825eb42bSJan Lentfer 		/* nothing read */
383825eb42bSJan Lentfer 		return -1;
384825eb42bSJan Lentfer 	}
385825eb42bSJan Lentfer 	if (p != 0) {
386825eb42bSJan Lentfer 		return -1;
387825eb42bSJan Lentfer 	}
388825eb42bSJan Lentfer 	return (ssize_t)i;
389825eb42bSJan Lentfer 
390825eb42bSJan Lentfer tokenread:
3915340022aSzrj 	if(*del == '"') /* do not skip over quotes, they are significant */
3925340022aSzrj 		ldns_bskipcs(b, del+1);
3935340022aSzrj 	else	ldns_bskipcs(b, del);
394825eb42bSJan Lentfer 	*t = '\0';
395825eb42bSJan Lentfer 
396825eb42bSJan Lentfer 	if (p != 0) {
397825eb42bSJan Lentfer 		return -1;
398825eb42bSJan Lentfer 	}
399825eb42bSJan Lentfer 	return (ssize_t)i;
400825eb42bSJan Lentfer }
401825eb42bSJan Lentfer 
402825eb42bSJan Lentfer 
403825eb42bSJan Lentfer void
ldns_bskipcs(ldns_buffer * buffer,const char * s)404825eb42bSJan Lentfer ldns_bskipcs(ldns_buffer *buffer, const char *s)
405825eb42bSJan Lentfer {
406825eb42bSJan Lentfer         bool found;
407825eb42bSJan Lentfer         char c;
408825eb42bSJan Lentfer         const char *d;
409825eb42bSJan Lentfer 
410825eb42bSJan Lentfer         while(ldns_buffer_available_at(buffer, buffer->_position, sizeof(char))) {
411825eb42bSJan Lentfer                 c = (char) ldns_buffer_read_u8_at(buffer, buffer->_position);
412825eb42bSJan Lentfer                 found = false;
413825eb42bSJan Lentfer                 for (d = s; *d; d++) {
414825eb42bSJan Lentfer                         if (*d == c) {
415825eb42bSJan Lentfer                                 found = true;
416825eb42bSJan Lentfer                         }
417825eb42bSJan Lentfer                 }
418825eb42bSJan Lentfer                 if (found && buffer->_limit > buffer->_position) {
419825eb42bSJan Lentfer                         buffer->_position += sizeof(char);
420825eb42bSJan Lentfer                 } else {
421825eb42bSJan Lentfer                         return;
422825eb42bSJan Lentfer                 }
423825eb42bSJan Lentfer         }
424825eb42bSJan Lentfer }
425825eb42bSJan Lentfer 
426825eb42bSJan Lentfer void
ldns_fskipcs(FILE * fp,const char * s)427825eb42bSJan Lentfer ldns_fskipcs(FILE *fp, const char *s)
428825eb42bSJan Lentfer {
429825eb42bSJan Lentfer 	ldns_fskipcs_l(fp, s, NULL);
430825eb42bSJan Lentfer }
431825eb42bSJan Lentfer 
432825eb42bSJan Lentfer void
ldns_fskipcs_l(FILE * fp,const char * s,int * line_nr)433825eb42bSJan Lentfer ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr)
434825eb42bSJan Lentfer {
435825eb42bSJan Lentfer         bool found;
436825eb42bSJan Lentfer         int c;
437825eb42bSJan Lentfer         const char *d;
438825eb42bSJan Lentfer 
439825eb42bSJan Lentfer 	while ((c = fgetc(fp)) != EOF) {
440825eb42bSJan Lentfer 		if (line_nr && c == '\n') {
441825eb42bSJan Lentfer 			*line_nr = *line_nr + 1;
442825eb42bSJan Lentfer 		}
443825eb42bSJan Lentfer                 found = false;
444825eb42bSJan Lentfer                 for (d = s; *d; d++) {
445825eb42bSJan Lentfer                         if (*d == c) {
446825eb42bSJan Lentfer                                 found = true;
447825eb42bSJan Lentfer                         }
448825eb42bSJan Lentfer                 }
449825eb42bSJan Lentfer 		if (!found) {
450825eb42bSJan Lentfer 			/* with getc, we've read too far */
451825eb42bSJan Lentfer 			ungetc(c, fp);
452825eb42bSJan Lentfer 			return;
453825eb42bSJan Lentfer 		}
454825eb42bSJan Lentfer 	}
455825eb42bSJan Lentfer }
456825eb42bSJan Lentfer 
457825eb42bSJan Lentfer ssize_t
ldns_bget_keyword_data(ldns_buffer * b,const char * keyword,const char * k_del,char * data,const char * d_del,size_t data_limit)458825eb42bSJan Lentfer ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, char
459825eb42bSJan Lentfer *data, const char *d_del, size_t data_limit)
460825eb42bSJan Lentfer {
461825eb42bSJan Lentfer        /* we assume: keyword|sep|data */
462825eb42bSJan Lentfer        char *fkeyword;
463825eb42bSJan Lentfer        ssize_t i;
464825eb42bSJan Lentfer 
465fd185f4dSJan Lentfer        if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
466fd185f4dSJan Lentfer                return -1;
467825eb42bSJan Lentfer        fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
468ac996e71SJan Lentfer        if(!fkeyword)
469ac996e71SJan Lentfer                return -1; /* out of memory */
470825eb42bSJan Lentfer 
471825eb42bSJan Lentfer        i = ldns_bget_token(b, fkeyword, k_del, data_limit);
472ac996e71SJan Lentfer        if(i==0 || i==-1) {
473ac996e71SJan Lentfer                LDNS_FREE(fkeyword);
474ac996e71SJan Lentfer                return -1; /* nothing read */
475ac996e71SJan Lentfer        }
476825eb42bSJan Lentfer 
477825eb42bSJan Lentfer        /* case??? */
478825eb42bSJan Lentfer        if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) {
479ac996e71SJan Lentfer                LDNS_FREE(fkeyword);
480825eb42bSJan Lentfer                /* whee, the match! */
481825eb42bSJan Lentfer                /* retrieve it's data */
482825eb42bSJan Lentfer                i = ldns_bget_token(b, data, d_del, 0);
483825eb42bSJan Lentfer                return i;
484825eb42bSJan Lentfer        } else {
485ac996e71SJan Lentfer                LDNS_FREE(fkeyword);
486825eb42bSJan Lentfer                return -1;
487825eb42bSJan Lentfer        }
488825eb42bSJan Lentfer }
489825eb42bSJan Lentfer 
490