parse.c

Go to the documentation of this file.
00001 /*
00002  * a generic (simple) parser. Use to parse rr's, private key 
00003  * information and /etc/resolv.conf files
00004  *
00005  * a Net::DNS like library for C
00006  * LibDNS Team @ NLnet Labs
00007  * (c) NLnet Labs, 2005-2006
00008  * See the file LICENSE for the license
00009  */
00010 #include <ldns/config.h>
00011 #include <ldns/ldns.h>
00012 
00013 #include <limits.h>
00014 #include <strings.h>
00015 
00016 ldns_lookup_table ldns_directive_types[] = {
00017         { LDNS_DIR_TTL, "$TTL" },  
00018         { LDNS_DIR_ORIGIN, "$ORIGIN" }, 
00019         { LDNS_DIR_INCLUDE, "$INCLUDE" },  
00020         { 0, NULL }
00021 };
00022 
00023 /* add max_limit here? */
00024 ssize_t
00025 ldns_fget_token(FILE *f, char *token, const char *delim, size_t limit)
00026 {       
00027         return ldns_fget_token_l(f, token, delim, limit, NULL);
00028 }
00029 
00030 ssize_t
00031 ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
00032 {       
00033         int c;
00034         int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
00035         int com;
00036         char *t;
00037         size_t i;
00038         const char *d;
00039         const char *del;
00040 
00041         /* standard delimeters */
00042         if (!delim) {
00043                 /* from isspace(3) */
00044                 del = LDNS_PARSE_NORMAL;
00045         } else {
00046                 del = delim;
00047         }
00048 
00049         p = 0;
00050         i = 0;
00051         com = 0;
00052         t = token;
00053         while ((c = getc(f)) != EOF) {
00054                 if (c == '(') {
00055                         /* this only counts for non-comments */
00056                         if (com == 0) {
00057                                 p++;
00058                         }
00059                         continue;
00060                 }
00061 
00062                 if (c == ')') {
00063                         /* this only counts for non-comments */
00064                         if (com == 0) {
00065                                 p--;
00066                         }
00067                         continue;
00068                 }
00069 
00070                 if (p < 0) {
00071                         /* more ) then ( - close off the string */
00072                         *t = '\0';
00073                         return 0;
00074                 }
00075 
00076                 /* do something with comments ; */
00077                 if (c == ';') {
00078                         com = 1;
00079                 }
00080 
00081                 if (c == '\n' && com != 0) {
00082                         /* comments */
00083                         com = 0;
00084                         *t = ' ';
00085                         if (line_nr) {
00086                                 *line_nr = *line_nr + 1;
00087                         }
00088                         if (p == 0 && i > 0) {
00089                                 goto tokenread;
00090                         } else {
00091                                 continue;
00092                         }
00093                 }
00094 
00095                 if (com == 1) {
00096                         *t = ' ';
00097                         continue;
00098                 }
00099 
00100                 
00101                 if (c == '\n' && p != 0 && t > token) {
00102                         /* in parentheses */
00103                         if (line_nr) {
00104                                 *line_nr = *line_nr + 1;
00105                         }
00106                         continue;
00107                 }
00108 
00109                 /* check if we hit the delim */
00110                 for (d = del; *d; d++) {
00111                         if (c == *d && i > 0) {
00112                                 if (c == '\n' && line_nr) {
00113                                         *line_nr = *line_nr + 1;
00114                                 }
00115                                 goto tokenread;
00116                         }
00117                 }
00118                 if (c != '\0' && c != '\n') {
00119                         *t++ = c;
00120                         i++;
00121                 }
00122                 if (limit > 0 && i >= limit) {
00123                         *t = '\0';
00124                         return -1;
00125                 }
00126         }
00127         *t = '\0';
00128         if (c == EOF) {
00129                 return (ssize_t)i;
00130         }
00131 
00132         if (i == 0) {
00133                 /* nothing read */
00134                 return -1;
00135         }
00136         if (p != 0) {
00137                 return -1;
00138         }
00139         return (ssize_t)i;
00140 
00141 tokenread:
00142         ldns_fskipcs_l(f, delim, line_nr);
00143         *t = '\0';
00144         if (p != 0) {
00145                 return -1;
00146         }
00147 
00148         return (ssize_t)i;
00149 }
00150 
00151 ssize_t
00152 ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data,
00153                const char *d_del, size_t data_limit)
00154 {
00155        return ldns_fget_keyword_data_l(f, keyword, k_del, data, d_del, 
00156                        data_limit, NULL);
00157 }
00158 
00159 ssize_t
00160 ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data,
00161                const char *d_del, size_t data_limit, int *line_nr)
00162 {
00163        /* we assume: keyword|sep|data */
00164        char *fkeyword;
00165        ssize_t i;
00166 
00167        fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
00168        i = 0;
00169 
00170        i = ldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN);
00171 
00172        /* case??? i instead of strlen? */
00173        if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) {
00174                /* whee! */
00175                /* printf("%s\n%s\n", "Matching keyword", fkeyword); */
00176                i = ldns_fget_token_l(f, data, d_del, data_limit, line_nr);
00177                LDNS_FREE(fkeyword);
00178                return i;
00179        } else {
00180                /*printf("no match for %s (read: %s)\n", keyword, fkeyword);*/
00181                LDNS_FREE(fkeyword);
00182                return -1;
00183        }
00184 }
00185 
00186 
00187 ssize_t
00188 ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
00189 {       
00190         int c, lc;
00191         int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
00192         int com;
00193         char *t;
00194         size_t i;
00195         const char *d;
00196         const char *del;
00197 
00198         /* standard delimiters */
00199         if (!delim) {
00200                 /* from isspace(3) */
00201                 del = LDNS_PARSE_NORMAL;
00202         } else {
00203                 del = delim;
00204         }
00205 
00206         p = 0;
00207         i = 0;
00208         com = 0;
00209         t = token;
00210         lc = 0;
00211         while ((c = ldns_bgetc(b)) != EOF) {
00212                 if (c == '(') {
00213                         p++;
00214                         continue;
00215                 }
00216 
00217                 if (c == ')') {
00218                         p--;
00219                         continue;
00220                 }
00221 
00222                 if (p < 0) {
00223                         /* more ) then ( */
00224                         *t = '\0';
00225                         return 0;
00226                 }
00227 
00228                 /* do something with comments ; */
00229                 if (c == ';') {
00230                         com = 1;
00231                 }
00232 
00233                 if (c == '\n' && com != 0) {
00234                         /* comments */
00235                         com = 0;
00236                         *t = ' ';
00237                         continue;
00238                 }
00239 
00240                 if (com == 1) {
00241                         *t = ' ';
00242                         continue;
00243                 }
00244 
00245                 if (c == '\n' && p != 0) {
00246                         /* in parentheses */
00247                         continue;
00248                 }
00249 
00250                 /* check if we hit the delim */
00251                 for (d = del; *d; d++) {
00252                         if (c == *d && lc != '\\') {
00253                                 goto tokenread;
00254                         }
00255                 }
00256                 
00257                 *t++ = c;
00258                 i++;
00259                 if (limit > 0 && i >= limit - 1) {
00260                         *t = '\0';
00261                         return -1;
00262                 }
00263 
00264                 if (c == '\\' && lc == '\\') {
00265                         lc = 0;
00266                 }
00267                 lc = c;
00268         }
00269         *t = '\0';
00270         if (i == 0) {
00271                 /* nothing read */
00272                 return -1;
00273         }
00274         if (p != 0) {
00275                 return -1;
00276         }
00277         return (ssize_t)i;
00278 
00279 tokenread:
00280         ldns_bskipcs(b, delim);
00281         *t = '\0';
00282         
00283         if (p != 0) {
00284                 return -1; 
00285         }
00286         return (ssize_t)i;
00287 }
00288 
00289 void
00290 ldns_bskipc(ldns_buffer *buffer, char c)
00291 {
00292         while (c == (char) ldns_buffer_read_u8_at(buffer, ldns_buffer_position(buffer))) {
00293                 if (ldns_buffer_available_at(buffer, 
00294                                         buffer->_position + sizeof(char), sizeof(char))) {
00295                         buffer->_position += sizeof(char);
00296                 } else {
00297                         return;
00298                 }
00299         }
00300 }
00301 
00302 void
00303 ldns_bskipcs(ldns_buffer *buffer, const char *s)
00304 {
00305         bool found;
00306         char c;
00307         const char *d;
00308 
00309         while(ldns_buffer_available_at(buffer, buffer->_position, sizeof(char))) {
00310                 c = (char) ldns_buffer_read_u8_at(buffer, buffer->_position);
00311                 found = false;
00312                 for (d = s; *d; d++) {
00313                         if (*d == c) {
00314                                 found = true;
00315                         }
00316                 }
00317                 if (found && buffer->_limit > buffer->_position) {
00318                         buffer->_position += sizeof(char);
00319                 } else {
00320                         return;
00321                 }
00322         }
00323 }
00324 
00325 void
00326 ldns_fskipc(FILE *fp, char c)
00327 {
00328         fp = fp;
00329         c = c;
00330 }
00331 
00332 
00333 void
00334 ldns_fskipcs(FILE *fp, const char *s)
00335 {
00336         ldns_fskipcs_l(fp, s, NULL);
00337 }
00338 
00339 void
00340 ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr)
00341 {
00342         bool found;
00343         int c;
00344         const char *d;
00345 
00346         while ((c = fgetc(fp)) != EOF) {
00347                 if (line_nr && c == '\n') {
00348                         *line_nr = *line_nr + 1;
00349                 }
00350                 found = false;
00351                 for (d = s; *d; d++) {
00352                         if (*d == c) {
00353                                 found = true;
00354                         }
00355                 }
00356                 if (!found) {
00357                         /* with getc, we've read too far */
00358                         ungetc(c, fp);
00359                         return;
00360                 }
00361         }
00362 }
00363 
00364 ssize_t
00365 ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, char
00366 *data, const char *d_del, size_t data_limit)
00367 {
00368        /* we assume: keyword|sep|data */
00369        char *fkeyword;
00370        ssize_t i;
00371 
00372        fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
00373        i = 0;
00374 
00375        i = ldns_bget_token(b, fkeyword, k_del, data_limit);
00376 
00377        /* case??? */
00378        if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) {
00379                /* whee, the match! */
00380                /* retrieve it's data */
00381                i = ldns_bget_token(b, data, d_del, 0);
00382                return i;
00383        } else {
00384                return -1;
00385        }
00386 }
00387 

Generated on Wed Feb 20 06:40:44 2008 for ldns by  doxygen 1.5.4