freeswitch/libs/ldns/examples/ldns-zcat.c

172 lines
4.1 KiB
C

/*
* 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, "n: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 seperately */
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);
}