summaryrefslogtreecommitdiff
path: root/examples/ldns-zcat.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/ldns-zcat.c')
-rw-r--r--examples/ldns-zcat.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/examples/ldns-zcat.c b/examples/ldns-zcat.c
new file mode 100644
index 0000000..017e632
--- /dev/null
+++ b/examples/ldns-zcat.c
@@ -0,0 +1,171 @@
+/*
+ * read a zone that is split up with ldns-zsplit and re-create
+ * the original zone
+ *
+ * From:
+ * zone1: SOA a b c d e f
+ * zone2: SOA f g h i k l
+ *
+ * Go back to:
+ * zone: SOA a b c d e f g h i j k l
+ *
+ * This is useful in combination with ldns-zsplit
+ *
+ * See the file LICENSE for the license
+ */
+
+#include "config.h"
+#include <errno.h>
+#include <ldns/ldns.h>
+
+#define FIRST_ZONE 0
+#define MIDDLE_ZONE 1
+#define LAST_ZONE 2
+
+static void
+usage(FILE *f, char *progname)
+{
+ fprintf(f, "Usage: %s [OPTIONS] <zonefiles>\n", progname);
+ fprintf(f, " Concatenate signed zone snippets created with ldns-zsplit\n");
+ fprintf(f, " back together. The generate zone file is printed to stdout\n");
+ fprintf(f, " The new zone should be equal to the original zone (before splitting)\n");
+ fprintf(f, "OPTIONS:\n");
+ fprintf(f, "-o ORIGIN\tUse this as initial origin, for zones starting with @\n");
+ fprintf(f, "-v\t\tShow the version number and exit\n");
+}
+
+int
+main(int argc, char **argv)
+{
+ char *progname;
+ FILE *fp;
+ int c;
+ ldns_rdf *origin;
+ size_t i, j;
+ int where;
+ ldns_zone *z;
+ ldns_rr_list *zrr;
+ ldns_rr *current_rr;
+ ldns_rr *soa;
+ ldns_rdf *last_owner;
+ ldns_rr *last_rr;
+ ldns_rr *pop_rr;
+
+ progname = strdup(argv[0]);
+ origin = NULL;
+
+ while ((c = getopt(argc, argv, "o:v")) != -1) {
+ switch(c) {
+ case 'o':
+ origin = ldns_dname_new_frm_str(strdup(optarg));
+ if (!origin) {
+ fprintf(stderr, "Cannot convert the origin %s to a domainname\n", optarg);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case 'v':
+ printf("zone file concatenator version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
+ exit(EXIT_SUCCESS);
+ break;
+ default:
+ fprintf(stderr, "Unrecognized option\n");
+ usage(stdout, progname);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1) {
+ usage(stdout, progname);
+ exit(EXIT_FAILURE);
+ }
+
+ for (i = 0; i < (size_t)argc; i++) {
+
+ if (!(fp = fopen(argv[i], "r"))) {
+ fprintf(stderr, "Error opening key file %s: %s\n", argv[i], strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ if (ldns_zone_new_frm_fp(&z, fp, origin, 0, 0) != LDNS_STATUS_OK) {
+ fprintf(stderr, "Zone file %s could not be parsed correctly\n", argv[i]);
+ exit(EXIT_FAILURE);
+ }
+
+ zrr = ldns_zone_rrs(z);
+ soa = ldns_zone_soa(z); /* SOA is stored separately */
+
+ fprintf(stderr, "%s\n", argv[i]);
+
+ if (0 == i) {
+ where = FIRST_ZONE;
+
+ /* remove the last equal named RRs */
+ last_rr = ldns_rr_list_pop_rr(zrr);
+ last_owner = ldns_rr_owner(last_rr);
+ /* remove until no match */
+ do {
+ pop_rr = ldns_rr_list_pop_rr(zrr);
+ } while(ldns_rdf_compare(last_owner, ldns_rr_owner(pop_rr)) == 0) ;
+ /* we popped one to many, put it back */
+ ldns_rr_list_push_rr(zrr, pop_rr);
+ } else if ((size_t)(argc - 1) == i) {
+ where = LAST_ZONE;
+ } else {
+ where = MIDDLE_ZONE;
+
+ /* remove the last equal named RRs */
+ last_rr = ldns_rr_list_pop_rr(zrr);
+ last_owner = ldns_rr_owner(last_rr);
+ /* remove until no match */
+ do {
+ pop_rr = ldns_rr_list_pop_rr(zrr);
+ } while(ldns_rdf_compare(last_owner, ldns_rr_owner(pop_rr)) == 0) ;
+ /* we popped one to many, put it back */
+ ldns_rr_list_push_rr(zrr, pop_rr);
+ }
+
+ /* printing the RRs */
+ for (j = 0; j < ldns_rr_list_rr_count(zrr); j++) {
+
+ current_rr = ldns_rr_list_rr(zrr, j);
+
+ switch(where) {
+ case FIRST_ZONE:
+ if (soa) {
+ ldns_rr_print(stdout, soa);
+ soa = NULL;
+ }
+ break;
+ case MIDDLE_ZONE:
+ /* rm SOA */
+ /* SOA isn't printed by default */
+
+ /* rm SOA aux records
+ * this also takes care of the DNSKEYs + RRSIGS
+ */
+ if (ldns_rdf_compare(ldns_rr_owner(current_rr),
+ ldns_rr_owner(soa)) == 0) {
+ continue;
+ }
+ break;
+ case LAST_ZONE:
+ /* rm SOA */
+ /* SOA isn't printed by default */
+
+ /* rm SOA aux records
+ * this also takes care of the DNSKEYs + RRSIGS
+ */
+ if (ldns_rdf_compare(ldns_rr_owner(current_rr),
+ ldns_rr_owner(soa)) == 0) {
+ continue;
+ }
+ break;
+ }
+ ldns_rr_print(stdout, current_rr);
+ }
+ }
+ exit(EXIT_SUCCESS);
+}