1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 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);
}
|