From: Jelte Jansen Date: Wed, 21 Sep 2005 13:18:58 +0000 (+0000) Subject: parse $ORIGIN and $TTL directives in zonefiles X-Git-Tag: release-1.0.0~114 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c384b30fad4727de554eb0974f38e8a1f16a3cf2;p=thirdparty%2Fldns.git parse $ORIGIN and $TTL directives in zonefiles --- diff --git a/examples/ldns-read-zone.c b/examples/ldns-read-zone.c index d56b5ffd..6d0a5b0c 100644 --- a/examples/ldns-read-zone.c +++ b/examples/ldns-read-zone.c @@ -41,6 +41,7 @@ main(int argc, char **argv) if (z) { ldns_zone_print(stdout, z); + ldns_zone_deep_free(z); } fclose(fp); diff --git a/ldns/rr.h b/ldns/rr.h index 97504f90..56eb673b 100644 --- a/ldns/rr.h +++ b/ldns/rr.h @@ -265,7 +265,7 @@ void ldns_rr_free(ldns_rr *rr); * The string should be a fully filled-in rr, like * ownername <space> TTL <space> CLASS <space> TYPE <space> RDATA. * \param[in] str the string to convert - * \param[in] default_ttl a default ttl for the rr. If 0 DEF_TTL will be used + * \param[in] default_ttl pointer to a default ttl for the rr. If 0 DEF_TTL will be used * \param[in] origin when the owner is relative add this * \return the new rr */ @@ -274,21 +274,25 @@ ldns_rr* ldns_rr_new_frm_str(const char *str, uint16_t default_ttl, ldns_rdf *or /** * creates a new rr from a file containing a string. * \param[in] fp the file pointer to use - * \param[in] default_ttl a default ttl for the rr. If 0 DEF_TTL will be used + * \param[in] default_ttl pointer to a default ttl for the rr. If NULL DEF_TTL will be used + * the pointer will be updated if the file contains a $TTL directive * \param[in] origin when the owner is relative add this + * the pointer will be updated if the file contains a $ORIGIN directive * \return ldns_rr* */ -ldns_rr* ldns_rr_new_frm_fp(FILE *fp, uint16_t default_ttl, ldns_rdf *origin); +ldns_rr* ldns_rr_new_frm_fp(FILE *fp, uint16_t *default_ttl, ldns_rdf **origin); /** * creates a new rr from a file containing a string. * \param[in] fp the file pointer to use * \param[in] default_ttl a default ttl for the rr. If 0 DEF_TTL will be used + * the pointer will be updated if the file contains a $TTL directive * \param[in] origin when the owner is relative add this + * the pointer will be updated if the file contains a $ORIGIN directive * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes) * \return ldns_rr* */ -ldns_rr* ldns_rr_new_frm_fp_l(FILE *fp, uint16_t default_ttl, ldns_rdf *origin, int *line_nr); +ldns_rr* ldns_rr_new_frm_fp_l(FILE *fp, uint16_t *default_ttl, ldns_rdf **origin, int *line_nr); /** * sets the owner in the rr structure. diff --git a/rr.c b/rr.c index 7b7a56a7..4915608d 100644 --- a/rr.c +++ b/rr.c @@ -229,6 +229,7 @@ ldns_rr_new_frm_str(const char *str, uint16_t default_ttl, ldns_rdf *origin) LDNS_FREE(ttl); LDNS_FREE(clas); LDNS_FREE(type); + LDNS_FREE(rdata); LDNS_FREE(rd); LDNS_FREE(rd_buf); ldns_buffer_free(rr_buf); @@ -261,6 +262,7 @@ ldns_rr_new_frm_str(const char *str, uint16_t default_ttl, ldns_rdf *origin) LDNS_FREE(ttl); LDNS_FREE(clas); LDNS_FREE(type); + LDNS_FREE(rdata); LDNS_FREE(rd); LDNS_FREE(rd_buf); ldns_buffer_free(rr_buf); @@ -380,16 +382,24 @@ ldns_rr_new_frm_str(const char *str, uint16_t default_ttl, ldns_rdf *origin) } ldns_rr * -ldns_rr_new_frm_fp(FILE *fp, uint16_t ttl, ldns_rdf *origin) +ldns_rr_new_frm_fp(FILE *fp, uint16_t *ttl, ldns_rdf **origin) { return ldns_rr_new_frm_fp_l(fp, ttl, origin, NULL); } ldns_rr * -ldns_rr_new_frm_fp_l(FILE *fp, uint16_t ttl, ldns_rdf *origin, int *line_nr) +ldns_rr_new_frm_fp_l(FILE *fp, uint16_t *default_ttl, ldns_rdf **origin, int *line_nr) { char *line; ldns_rr *rr; + char *keyword; + uint16_t ttl; + + if (default_ttl) { + ttl = *default_ttl; + } else { + ttl = 0; + } line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1); if (!line) { @@ -405,7 +415,18 @@ ldns_rr_new_frm_fp_l(FILE *fp, uint16_t ttl, ldns_rdf *origin, int *line_nr) return NULL; } - rr = ldns_rr_new_frm_str((const char*) line, ttl, origin); + rr = ldns_rr_new_frm_str((const char*) line, ttl, *origin); + if (!rr) { + if ((keyword = strstr(line, "$ORIGIN "))) { + if (*origin) { + ldns_rdf_free(*origin); + *origin = NULL; + } + *origin = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, keyword + 8); + } else if ((keyword = strstr(line, "$TTL "))) { + *default_ttl = atoi(keyword + 5); + } + } LDNS_FREE(line); return rr; } diff --git a/zone.c b/zone.c index 86b0b24f..e46529cb 100644 --- a/zone.c +++ b/zone.c @@ -155,7 +155,7 @@ ldns_zone_new_frm_fp_l(FILE *fp, ldns_rdf *origin, uint16_t ttl, ldns_rr_class c { ldns_zone *newzone; ldns_rr *rr; - ldns_rdf *my_origin = origin; + ldns_rdf *my_origin = NULL; uint16_t my_ttl = ttl; ldns_rr_class my_class = c; ldns_rr *last_rr = NULL; @@ -171,9 +171,14 @@ ldns_zone_new_frm_fp_l(FILE *fp, ldns_rdf *origin, uint16_t ttl, ldns_rr_class c * except $directives */ + if (origin) { + my_origin = ldns_rdf_clone(origin); + } + i = 0; do { - rr = ldns_rr_new_frm_fp_l(fp, my_ttl, my_origin, line_nr); + rr = ldns_rr_new_frm_fp_l(fp, &my_ttl, &my_origin, line_nr); +printf("RR at %p\n", rr); i++; } while (!rr && i <= 9); @@ -183,27 +188,39 @@ ldns_zone_new_frm_fp_l(FILE *fp, ldns_rdf *origin, uint16_t ttl, ldns_rr_class c if (rr) { ldns_rr_free(rr); } + if (my_origin) { + ldns_rdf_free(my_origin); + } + ldns_zone_deep_free(newzone); return NULL; } if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_SOA) { /* first rr MUST be the soa */ ldns_rr_free(rr); + if (my_origin) { + ldns_rdf_free(my_origin); + } + ldns_zone_deep_free(newzone); return NULL; } ldns_zone_set_soa(newzone, rr); if (!my_origin) { - my_origin = ldns_rr_owner(rr); + my_origin = ldns_rdf_clone(ldns_rr_owner(rr)); } while(!feof(fp)) { - rr = ldns_rr_new_frm_fp_l(fp, my_ttl, my_origin, line_nr); + rr = ldns_rr_new_frm_fp_l(fp, &my_ttl, &my_origin, line_nr); if (rr) { last_rr = rr; if (!ldns_zone_push_rr(newzone, rr)) { dprintf("%s", "error pushing rr\n"); + if (my_origin) { + ldns_rdf_free(my_origin); + } + ldns_zone_deep_free(newzone); return NULL; } @@ -224,6 +241,9 @@ ldns_zone_new_frm_fp_l(FILE *fp, ldns_rdf *origin, uint16_t ttl, ldns_rr_class c dprintf("%s", "\n"); } } + if (my_origin) { + ldns_rdf_deep_free(my_origin); + } return newzone; }