ldns-read-zone.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "config.h"
00010 #include <unistd.h>
00011 #include <stdlib.h>
00012
00013 #include <ldns/ldns.h>
00014 #include <ldns/host2str.h>
00015
00016 #include <errno.h>
00017
00018 int
00019 main(int argc, char **argv)
00020 {
00021 char *filename;
00022 FILE *fp;
00023 ldns_zone *z;
00024 int line_nr = 0;
00025 int c;
00026 bool canonicalize = false;
00027 bool sort = false;
00028 bool strip = false;
00029 bool only_dnssec = false;
00030 bool print_soa = true;
00031 ldns_status s;
00032 size_t i;
00033 ldns_rr_list *stripped_list;
00034 ldns_rr *cur_rr;
00035 ldns_rr_type cur_rr_type;
00036 ldns_output_format fmt = {
00037 ldns_output_format_default->flags,
00038 ldns_output_format_default->data
00039 };
00040 ldns_soa_serial_increment_func_t soa_serial_increment_func = NULL;
00041 int soa_serial_increment_func_data = 0;
00042
00043 while ((c = getopt(argc, argv, "0bcdhnpsvzS:")) != -1) {
00044 switch(c) {
00045 case 'b':
00046 fmt.flags |=
00047 ( LDNS_COMMENT_BUBBLEBABBLE |
00048 LDNS_COMMENT_FLAGS );
00049 break;
00050 case '0':
00051 fmt.flags |= LDNS_FMT_ZEROIZE_RRSIGS;
00052 break;
00053 case 'c':
00054 canonicalize = true;
00055 break;
00056 case 'd':
00057 only_dnssec = true;
00058 if (strip) {
00059 fprintf(stderr, "Warning: stripping both DNSSEC and non-DNSSEC records. Output will be sparse.\n");
00060 }
00061 break;
00062 case 'h':
00063 printf("Usage: %s [OPTIONS] <zonefile>\n", argv[0]);
00064 printf("\tReads the zonefile and prints it.\n");
00065 printf("\tThe RR count of the zone is printed to stderr.\n");
00066 printf("\t-b include bubblebabble of DS's.\n");
00067 printf("\t-0 zeroize timestamps and signature in RRSIG records.\n");
00068 printf("\t-c canonicalize all rrs in the zone.\n");
00069 printf("\t-d only show DNSSEC data from the zone\n");
00070 printf("\t-h show this text\n");
00071 printf("\t-n do not print the SOA record\n");
00072 printf("\t-p prepend SOA serial with spaces so"
00073 " it takes exactly ten characters.\n");
00074 printf("\t-s strip DNSSEC data from the zone\n");
00075 printf("\t-S [[+|-]<number> | YYYYMMDDxx | "
00076 " unixtime ]\n"
00077 "\t\tSet serial number to <number> or,"
00078 " when preceded by a sign,\n"
00079 "\t\toffset the existing number with "
00080 "<number>. With YYYYMMDDxx\n"
00081 "\t\tthe serial is formatted as a datecounter"
00082 ", and with unixtime as the\n"
00083 "\t\tnumber of seconds since 1-1-1970."
00084 " However, on serial number"
00085 "\n\t\tdecrease, +1 is used in stead"
00086 ". (implies -s)\n");
00087 printf("\t-v shows the version and exits\n");
00088 printf("\t-z sort the zone (implies -c).\n");
00089 printf("\nif no file is given standard input is read\n");
00090 exit(EXIT_SUCCESS);
00091 break;
00092 case 'n':
00093 print_soa = false;
00094 break;
00095 case 'p':
00096 fmt.flags |= LDNS_FMT_PAD_SOA_SERIAL;
00097 break;
00098 case 's':
00099 strip = true;
00100 if (only_dnssec) {
00101 fprintf(stderr, "Warning: stripping both DNSSEC and non-DNSSEC records. Output will be sparse.\n");
00102 }
00103 break;
00104 case 'v':
00105 printf("read zone version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
00106 exit(EXIT_SUCCESS);
00107 break;
00108 case 'z':
00109 canonicalize = true;
00110 sort = true;
00111 break;
00112 case 'S':
00113 strip = true;
00114 if (*optarg == '+' || *optarg == '-') {
00115 soa_serial_increment_func_data =
00116 atoi(optarg);
00117 soa_serial_increment_func =
00118 ldns_soa_serial_increment_by;
00119 } else if (! strtok(optarg, "0123456789")) {
00120 soa_serial_increment_func_data =
00121 atoi(optarg);
00122 soa_serial_increment_func =
00123 ldns_soa_serial_identity;
00124 } else if (!strcasecmp(optarg, "YYYYMMDDxx")){
00125 soa_serial_increment_func =
00126 ldns_soa_serial_datecounter;
00127 } else if (!strcasecmp(optarg, "unixtime")){
00128 soa_serial_increment_func =
00129 ldns_soa_serial_unixtime;
00130 } else {
00131 fprintf(stderr, "-S expects a number "
00132 "optionally preceded by a "
00133 "+ or - sign to indicate an "
00134 "offset, or the text YYYYMM"
00135 "DDxx or unixtime\n");
00136 exit(EXIT_FAILURE);
00137 }
00138 break;
00139 }
00140 }
00141
00142 argc -= optind;
00143 argv += optind;
00144
00145 if (argc == 0) {
00146 fp = stdin;
00147 } else {
00148 filename = argv[0];
00149
00150 fp = fopen(filename, "r");
00151 if (!fp) {
00152 fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
00153 exit(EXIT_FAILURE);
00154 }
00155 }
00156
00157 s = ldns_zone_new_frm_fp_l(&z, fp, NULL, 0, LDNS_RR_CLASS_IN, &line_nr);
00158
00159 fclose(fp);
00160 if (s != LDNS_STATUS_OK) {
00161 fprintf(stderr, "%s at %d\n",
00162 ldns_get_errorstr_by_id(s),
00163 line_nr);
00164 exit(EXIT_FAILURE);
00165 }
00166
00167
00168 if (strip) {
00169 stripped_list = ldns_rr_list_new();
00170 while ((cur_rr = ldns_rr_list_pop_rr(ldns_zone_rrs(z)))) {
00171 cur_rr_type = ldns_rr_get_type(cur_rr);
00172 if (cur_rr_type == LDNS_RR_TYPE_RRSIG ||
00173 cur_rr_type == LDNS_RR_TYPE_NSEC ||
00174 cur_rr_type == LDNS_RR_TYPE_NSEC3 ||
00175 cur_rr_type == LDNS_RR_TYPE_NSEC3PARAM
00176 ) {
00177 ldns_rr_free(cur_rr);
00178 } else {
00179 ldns_rr_list_push_rr(stripped_list, cur_rr);
00180 }
00181 }
00182 ldns_rr_list_free(ldns_zone_rrs(z));
00183 ldns_zone_set_rrs(z, stripped_list);
00184 }
00185 if (only_dnssec) {
00186 stripped_list = ldns_rr_list_new();
00187 while ((cur_rr = ldns_rr_list_pop_rr(ldns_zone_rrs(z)))) {
00188 cur_rr_type = ldns_rr_get_type(cur_rr);
00189 if (cur_rr_type == LDNS_RR_TYPE_RRSIG ||
00190 cur_rr_type == LDNS_RR_TYPE_NSEC ||
00191 cur_rr_type == LDNS_RR_TYPE_NSEC3 ||
00192 cur_rr_type == LDNS_RR_TYPE_NSEC3PARAM
00193 ) {
00194 ldns_rr_list_push_rr(stripped_list, cur_rr);
00195 } else {
00196 ldns_rr_free(cur_rr);
00197 }
00198 }
00199 ldns_rr_list_free(ldns_zone_rrs(z));
00200 ldns_zone_set_rrs(z, stripped_list);
00201 }
00202
00203 if (canonicalize) {
00204 ldns_rr2canonical(ldns_zone_soa(z));
00205 for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(z)); i++) {
00206 ldns_rr2canonical(ldns_rr_list_rr(ldns_zone_rrs(z), i));
00207 }
00208 }
00209 if (sort) {
00210 ldns_zone_sort(z);
00211 }
00212
00213 if (print_soa && ldns_zone_soa(z)) {
00214 if (soa_serial_increment_func) {
00215 ldns_rr_soa_increment_func_int(
00216 ldns_zone_soa(z)
00217 , soa_serial_increment_func
00218 , soa_serial_increment_func_data
00219 );
00220 }
00221 ldns_rr_print_fmt(stdout, &fmt, ldns_zone_soa(z));
00222 }
00223 ldns_rr_list_print_fmt(stdout, &fmt, ldns_zone_rrs(z));
00224
00225 ldns_zone_deep_free(z);
00226
00227 exit(EXIT_SUCCESS);
00228 }