2 * a generic (simple) parser. Use to parse rr's, private key
3 * information and /etc/resolv.conf files
5 * a Net::DNS like library for C
6 * LibDNS Team @ NLnet Labs
7 * (c) NLnet Labs, 2005-2006
8 * See the file LICENSE for the license
10 #include <ldns/config.h>
11 #include <ldns/ldns.h>
16 ldns_lookup_table ldns_directive_types
[] = {
17 { LDNS_DIR_TTL
, "$TTL" },
18 { LDNS_DIR_ORIGIN
, "$ORIGIN" },
19 { LDNS_DIR_INCLUDE
, "$INCLUDE" },
23 /* add max_limit here? */
25 ldns_fget_token(FILE *f
, char *token
, const char *delim
, size_t limit
)
27 return ldns_fget_token_l(f
, token
, delim
, limit
, NULL
);
31 ldns_fget_token_l(FILE *f
, char *token
, const char *delim
, size_t limit
, int *line_nr
)
34 int p
; /* 0 -> no parenthese seen, >0 nr of ( seen */
41 /* standard delimeters */
44 del
= LDNS_PARSE_NORMAL
;
58 while ((c
= getc(f
)) != EOF
) {
59 if (c
== '\r') /* carriage return */
61 if (c
== '(' && prev_c
!= '\\' && !quoted
) {
62 /* this only counts for non-comments */
70 if (c
== ')' && prev_c
!= '\\' && !quoted
) {
71 /* this only counts for non-comments */
80 /* more ) then ( - close off the string */
85 /* do something with comments ; */
86 if (c
== ';' && quoted
== 0) {
91 if (c
== '\"' && com
== 0 && prev_c
!= '\\') {
95 if (c
== '\n' && com
!= 0) {
100 *line_nr
= *line_nr
+ 1;
102 if (p
== 0 && i
> 0) {
116 if (c
== '\n' && p
!= 0 && t
> token
) {
119 *line_nr
= *line_nr
+ 1;
126 /* check if we hit the delim */
127 for (d
= del
; *d
; d
++) {
128 if (c
== *d
&& i
> 0 && prev_c
!= '\\' && p
== 0) {
129 if (c
== '\n' && line_nr
) {
130 *line_nr
= *line_nr
+ 1;
135 if (c
!= '\0' && c
!= '\n') {
138 if (limit
> 0 && i
>= limit
) {
142 if (c
!= '\0' && c
!= '\n') {
145 if (c
== '\\' && prev_c
== '\\')
164 ldns_fskipcs_l(f
, del
, line_nr
);
174 ldns_fget_keyword_data(FILE *f
, const char *keyword
, const char *k_del
, char *data
,
175 const char *d_del
, size_t data_limit
)
177 return ldns_fget_keyword_data_l(f
, keyword
, k_del
, data
, d_del
,
182 ldns_fget_keyword_data_l(FILE *f
, const char *keyword
, const char *k_del
, char *data
,
183 const char *d_del
, size_t data_limit
, int *line_nr
)
185 /* we assume: keyword|sep|data */
189 if(strlen(keyword
) >= LDNS_MAX_KEYWORDLEN
)
191 fkeyword
= LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN
);
195 i
= ldns_fget_token(f
, fkeyword
, k_del
, LDNS_MAX_KEYWORDLEN
);
201 /* case??? i instead of strlen? */
202 if (strncmp(fkeyword
, keyword
, LDNS_MAX_KEYWORDLEN
- 1) == 0) {
204 /* printf("%s\n%s\n", "Matching keyword", fkeyword); */
205 i
= ldns_fget_token_l(f
, data
, d_del
, data_limit
, line_nr
);
209 /*printf("no match for %s (read: %s)\n", keyword, fkeyword);*/
217 ldns_bget_token(ldns_buffer
*b
, char *token
, const char *delim
, size_t limit
)
220 int p
; /* 0 -> no parenthese seen, >0 nr of ( seen */
227 /* standard delimiters */
229 /* from isspace(3) */
230 del
= LDNS_PARSE_NORMAL
;
245 while ((c
= ldns_bgetc(b
)) != EOF
) {
246 if (c
== '\r') /* carriage return */
248 if (c
== '(' && lc
!= '\\' && !quoted
) {
249 /* this only counts for non-comments */
257 if (c
== ')' && lc
!= '\\' && !quoted
) {
258 /* this only counts for non-comments */
272 /* do something with comments ; */
273 if (c
== ';' && quoted
== 0) {
278 if (c
== '"' && com
== 0 && lc
!= '\\') {
282 if (c
== '\n' && com
!= 0) {
296 if (c
== '\n' && p
!= 0) {
303 /* check if we hit the delim */
304 for (d
= del
; *d
; d
++) {
305 if (c
== *d
&& lc
!= '\\' && p
== 0) {
311 if (limit
> 0 && i
>= limit
) {
317 if (c
== '\\' && lc
== '\\') {
334 ldns_bskipcs(b
, del
);
344 ldns_bskipc(ldns_buffer
*buffer
, char c
)
346 while (c
== (char) ldns_buffer_read_u8_at(buffer
, ldns_buffer_position(buffer
))) {
347 if (ldns_buffer_available_at(buffer
,
348 buffer
->_position
+ sizeof(char), sizeof(char))) {
349 buffer
->_position
+= sizeof(char);
357 ldns_bskipcs(ldns_buffer
*buffer
, const char *s
)
363 while(ldns_buffer_available_at(buffer
, buffer
->_position
, sizeof(char))) {
364 c
= (char) ldns_buffer_read_u8_at(buffer
, buffer
->_position
);
366 for (d
= s
; *d
; d
++) {
371 if (found
&& buffer
->_limit
> buffer
->_position
) {
372 buffer
->_position
+= sizeof(char);
380 ldns_fskipc(ATTR_UNUSED(FILE *fp
), ATTR_UNUSED(char c
))
386 ldns_fskipcs(FILE *fp
, const char *s
)
388 ldns_fskipcs_l(fp
, s
, NULL
);
392 ldns_fskipcs_l(FILE *fp
, const char *s
, int *line_nr
)
398 while ((c
= fgetc(fp
)) != EOF
) {
399 if (line_nr
&& c
== '\n') {
400 *line_nr
= *line_nr
+ 1;
403 for (d
= s
; *d
; d
++) {
409 /* with getc, we've read too far */
417 ldns_bget_keyword_data(ldns_buffer
*b
, const char *keyword
, const char *k_del
, char
418 *data
, const char *d_del
, size_t data_limit
)
420 /* we assume: keyword|sep|data */
424 if(strlen(keyword
) >= LDNS_MAX_KEYWORDLEN
)
426 fkeyword
= LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN
);
428 return -1; /* out of memory */
430 i
= ldns_bget_token(b
, fkeyword
, k_del
, data_limit
);
433 return -1; /* nothing read */
437 if (strncmp(fkeyword
, keyword
, strlen(keyword
)) == 0) {
439 /* whee, the match! */
440 /* retrieve it's data */
441 i
= ldns_bget_token(b
, data
, d_del
, 0);