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