ldns-read-zone.c

Go to the documentation of this file.
00001 /*
00002  * read a zone file from disk and prints it, one RR per line
00003  *
00004  * (c) NLnetLabs 2005-2008
00005  *
00006  * See the file LICENSE for the license
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 }

Generated on 28 May 2013 for ldns by  doxygen 1.6.1