00001
00002
00003
00004
00005
00006
00007
00008
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
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, prev_c;
00034 int p;
00035 int com, quoted;
00036 char *t;
00037 size_t i;
00038 const char *d;
00039 const char *del;
00040
00041
00042 if (!delim) {
00043
00044 del = LDNS_PARSE_NORMAL;
00045 } else {
00046 del = delim;
00047 }
00048
00049 p = 0;
00050 i = 0;
00051 com = 0;
00052 quoted = 0;
00053 prev_c = 0;
00054 t = token;
00055 if (del[0] == '"') {
00056 quoted = 1;
00057 }
00058 while ((c = getc(f)) != EOF) {
00059 if (c == '\r')
00060 c = ' ';
00061 if (c == '(' && prev_c != '\\' && !quoted) {
00062
00063 if (com == 0) {
00064 p++;
00065 }
00066 prev_c = c;
00067 continue;
00068 }
00069
00070 if (c == ')' && prev_c != '\\' && !quoted) {
00071
00072 if (com == 0) {
00073 p--;
00074 }
00075 prev_c = c;
00076 continue;
00077 }
00078
00079 if (p < 0) {
00080
00081 *t = '\0';
00082 return 0;
00083 }
00084
00085
00086 if (c == ';' && quoted == 0) {
00087 if (prev_c != '\\') {
00088 com = 1;
00089 }
00090 }
00091 if (c == '\"' && com == 0 && prev_c != '\\') {
00092 quoted = 1 - quoted;
00093 }
00094
00095 if (c == '\n' && com != 0) {
00096
00097 com = 0;
00098 *t = ' ';
00099 if (line_nr) {
00100 *line_nr = *line_nr + 1;
00101 }
00102 if (p == 0 && i > 0) {
00103 goto tokenread;
00104 } else {
00105 prev_c = c;
00106 continue;
00107 }
00108 }
00109
00110 if (com == 1) {
00111 *t = ' ';
00112 prev_c = c;
00113 continue;
00114 }
00115
00116 if (c == '\n' && p != 0 && t > token) {
00117
00118 if (line_nr) {
00119 *line_nr = *line_nr + 1;
00120 }
00121 *t++ = ' ';
00122 prev_c = c;
00123 continue;
00124 }
00125
00126
00127 for (d = del; *d; d++) {
00128 if (c == *d && i > 0 && prev_c != '\\' && p == 0) {
00129 if (c == '\n' && line_nr) {
00130 *line_nr = *line_nr + 1;
00131 }
00132 goto tokenread;
00133 }
00134 }
00135 if (c != '\0' && c != '\n') {
00136 i++;
00137 }
00138 if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
00139 *t = '\0';
00140 return -1;
00141 }
00142 if (c != '\0' && c != '\n') {
00143 *t++ = c;
00144 }
00145 if (c == '\\' && prev_c == '\\')
00146 prev_c = 0;
00147 else prev_c = c;
00148 }
00149 *t = '\0';
00150 if (c == EOF) {
00151 return (ssize_t)i;
00152 }
00153
00154 if (i == 0) {
00155
00156 return -1;
00157 }
00158 if (p != 0) {
00159 return -1;
00160 }
00161 return (ssize_t)i;
00162
00163 tokenread:
00164 ldns_fskipcs_l(f, del, line_nr);
00165 *t = '\0';
00166 if (p != 0) {
00167 return -1;
00168 }
00169
00170 return (ssize_t)i;
00171 }
00172
00173 ssize_t
00174 ldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data,
00175 const char *d_del, size_t data_limit)
00176 {
00177 return ldns_fget_keyword_data_l(f, keyword, k_del, data, d_del,
00178 data_limit, NULL);
00179 }
00180
00181 ssize_t
00182 ldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_del, char *data,
00183 const char *d_del, size_t data_limit, int *line_nr)
00184 {
00185
00186 char *fkeyword;
00187 ssize_t i;
00188
00189 if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
00190 return -1;
00191 fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
00192 if(!fkeyword)
00193 return -1;
00194
00195 i = ldns_fget_token(f, fkeyword, k_del, LDNS_MAX_KEYWORDLEN);
00196 if(i==0 || i==-1) {
00197 LDNS_FREE(fkeyword);
00198 return -1;
00199 }
00200
00201
00202 if (strncmp(fkeyword, keyword, LDNS_MAX_KEYWORDLEN - 1) == 0) {
00203
00204
00205 i = ldns_fget_token_l(f, data, d_del, data_limit, line_nr);
00206 LDNS_FREE(fkeyword);
00207 return i;
00208 } else {
00209
00210 LDNS_FREE(fkeyword);
00211 return -1;
00212 }
00213 }
00214
00215
00216 ssize_t
00217 ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
00218 {
00219 int c, lc;
00220 int p;
00221 int com, quoted;
00222 char *t;
00223 size_t i;
00224 const char *d;
00225 const char *del;
00226
00227
00228 if (!delim) {
00229
00230 del = LDNS_PARSE_NORMAL;
00231 } else {
00232 del = delim;
00233 }
00234
00235 p = 0;
00236 i = 0;
00237 com = 0;
00238 quoted = 0;
00239 t = token;
00240 lc = 0;
00241 if (del[0] == '"') {
00242 quoted = 1;
00243 }
00244
00245 while ((c = ldns_bgetc(b)) != EOF) {
00246 if (c == '\r')
00247 c = ' ';
00248 if (c == '(' && lc != '\\' && !quoted) {
00249
00250 if (com == 0) {
00251 p++;
00252 }
00253 lc = c;
00254 continue;
00255 }
00256
00257 if (c == ')' && lc != '\\' && !quoted) {
00258
00259 if (com == 0) {
00260 p--;
00261 }
00262 lc = c;
00263 continue;
00264 }
00265
00266 if (p < 0) {
00267
00268 *t = '\0';
00269 return 0;
00270 }
00271
00272
00273 if (c == ';' && quoted == 0) {
00274 if (lc != '\\') {
00275 com = 1;
00276 }
00277 }
00278 if (c == '"' && com == 0 && lc != '\\') {
00279 quoted = 1 - quoted;
00280 }
00281
00282 if (c == '\n' && com != 0) {
00283
00284 com = 0;
00285 *t = ' ';
00286 lc = c;
00287 continue;
00288 }
00289
00290 if (com == 1) {
00291 *t = ' ';
00292 lc = c;
00293 continue;
00294 }
00295
00296 if (c == '\n' && p != 0) {
00297
00298 *t++ = ' ';
00299 lc = c;
00300 continue;
00301 }
00302
00303
00304 for (d = del; *d; d++) {
00305 if (c == *d && lc != '\\' && p == 0) {
00306 goto tokenread;
00307 }
00308 }
00309
00310 i++;
00311 if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
00312 *t = '\0';
00313 return -1;
00314 }
00315 *t++ = c;
00316
00317 if (c == '\\' && lc == '\\') {
00318 lc = 0;
00319 } else {
00320 lc = c;
00321 }
00322 }
00323 *t = '\0';
00324 if (i == 0) {
00325
00326 return -1;
00327 }
00328 if (p != 0) {
00329 return -1;
00330 }
00331 return (ssize_t)i;
00332
00333 tokenread:
00334 ldns_bskipcs(b, del);
00335 *t = '\0';
00336
00337 if (p != 0) {
00338 return -1;
00339 }
00340 return (ssize_t)i;
00341 }
00342
00343
00344 void
00345 ldns_bskipcs(ldns_buffer *buffer, const char *s)
00346 {
00347 bool found;
00348 char c;
00349 const char *d;
00350
00351 while(ldns_buffer_available_at(buffer, buffer->_position, sizeof(char))) {
00352 c = (char) ldns_buffer_read_u8_at(buffer, buffer->_position);
00353 found = false;
00354 for (d = s; *d; d++) {
00355 if (*d == c) {
00356 found = true;
00357 }
00358 }
00359 if (found && buffer->_limit > buffer->_position) {
00360 buffer->_position += sizeof(char);
00361 } else {
00362 return;
00363 }
00364 }
00365 }
00366
00367 void
00368 ldns_fskipcs(FILE *fp, const char *s)
00369 {
00370 ldns_fskipcs_l(fp, s, NULL);
00371 }
00372
00373 void
00374 ldns_fskipcs_l(FILE *fp, const char *s, int *line_nr)
00375 {
00376 bool found;
00377 int c;
00378 const char *d;
00379
00380 while ((c = fgetc(fp)) != EOF) {
00381 if (line_nr && c == '\n') {
00382 *line_nr = *line_nr + 1;
00383 }
00384 found = false;
00385 for (d = s; *d; d++) {
00386 if (*d == c) {
00387 found = true;
00388 }
00389 }
00390 if (!found) {
00391
00392 ungetc(c, fp);
00393 return;
00394 }
00395 }
00396 }
00397
00398 ssize_t
00399 ldns_bget_keyword_data(ldns_buffer *b, const char *keyword, const char *k_del, char
00400 *data, const char *d_del, size_t data_limit)
00401 {
00402
00403 char *fkeyword;
00404 ssize_t i;
00405
00406 if(strlen(keyword) >= LDNS_MAX_KEYWORDLEN)
00407 return -1;
00408 fkeyword = LDNS_XMALLOC(char, LDNS_MAX_KEYWORDLEN);
00409 if(!fkeyword)
00410 return -1;
00411
00412 i = ldns_bget_token(b, fkeyword, k_del, data_limit);
00413 if(i==0 || i==-1) {
00414 LDNS_FREE(fkeyword);
00415 return -1;
00416 }
00417
00418
00419 if (strncmp(fkeyword, keyword, strlen(keyword)) == 0) {
00420 LDNS_FREE(fkeyword);
00421
00422
00423 i = ldns_bget_token(b, data, d_del, 0);
00424 return i;
00425 } else {
00426 LDNS_FREE(fkeyword);
00427 return -1;
00428 }
00429 }
00430