1 /* 2 * testcode/readzone.c - readzone tool reads zonefiles 3 * 4 * Copyright (c) 2021, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * Neither the name of the NLNET LABS nor the names of its contributors may 20 * be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 */ 36 /** 37 * \file 38 * Command to read and echo a zonefile. 39 */ 40 41 #include "config.h" 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <errno.h> 45 #include <string.h> 46 #include <unistd.h> 47 48 #include <stdint.h> 49 #include "sldns/str2wire.h" 50 #include "sldns/wire2str.h" 51 52 int print_usage(FILE *out, const char *progname) 53 { 54 fprintf(out, "usage: %s [ -u ] <zonefile> [<origin>]\n", progname); 55 fprintf(out, "\t-u\tprint in unknown type (RFC3597) format\n"); 56 return out == stdout ? EXIT_SUCCESS : EXIT_FAILURE; 57 } 58 59 int main(int argc, char *const *argv) 60 { 61 char *progname = argv[0]; 62 uint8_t rr[LDNS_RR_BUF_SIZE]; 63 char *str = malloc(1024 * 1024); 64 size_t str_len = sizeof(str); 65 struct sldns_file_parse_state state; 66 FILE *in = NULL; 67 int s = -1; 68 int opt; 69 int print_in_unknown_type_format = 0; 70 71 while ((opt = getopt(argc, argv, "hu")) != -1) { 72 switch (opt) { 73 case 'h': 74 free(str); 75 return print_usage(stdout, progname); 76 case 'u': 77 print_in_unknown_type_format = 1; 78 break; 79 default: 80 free(str); 81 return print_usage(stderr, progname); 82 } 83 } 84 argc -= optind; 85 argv += optind; 86 87 memset(&state, 0, sizeof(state)); 88 state.default_ttl = 3600; 89 state.lineno = 1; 90 if (argc == 2) { 91 state.origin_len = sizeof(state.origin); 92 s = sldns_str2wire_dname_buf(argv[1], state.origin 93 , &state.origin_len); 94 if (s) { 95 fprintf(stderr, "Error parsing origin: %s\n" 96 , sldns_get_errorstr_parse(s)); 97 free(str); 98 return EXIT_FAILURE; 99 } 100 s = -1; 101 } 102 if (!str) 103 fprintf(stderr, "Memory allocation error: %s\n" 104 , strerror(errno)); 105 106 else if (argc != 1 && argc != 2) { 107 free(str); 108 return print_usage(stderr, progname); 109 } 110 111 else if (!(in = fopen(argv[0], "r"))) 112 fprintf(stderr, "Error opening \"%s\": %s\n" 113 , argv[0], strerror(errno)); 114 else while (!feof(in)) { 115 size_t rr_len = sizeof(rr), dname_len = 0; 116 size_t written; 117 118 s = sldns_fp2wire_rr_buf(in, rr, &rr_len, &dname_len, &state); 119 if (s) { 120 fprintf( stderr, "parse error %d:%d: %s\n" 121 , state.lineno, LDNS_WIREPARSE_OFFSET(s) 122 , sldns_get_errorstr_parse(s)); 123 break; 124 } 125 if (rr_len == 0) 126 continue; 127 128 if (print_in_unknown_type_format) 129 written = sldns_wire2str_rr_unknown_buf( 130 rr, rr_len, str, str_len); 131 else 132 written = sldns_wire2str_rr_buf( 133 rr, rr_len, str, str_len); 134 135 if (written > str_len) { 136 while (written > str_len) 137 str_len *= 2; 138 free(str); 139 if (!(str = malloc(str_len))) { 140 fprintf(stderr, "Memory allocation error: %s\n" 141 , strerror(errno)); 142 s = -1; 143 break; 144 } 145 if (print_in_unknown_type_format) 146 (void) sldns_wire2str_rr_unknown_buf( 147 rr, rr_len, str, str_len); 148 else 149 (void) sldns_wire2str_rr_buf( 150 rr, rr_len, str, str_len); 151 } 152 fprintf(stdout, "%s", str); 153 } 154 if (in) 155 fclose(in); 156 free(str); 157 return !in || s ? EXIT_FAILURE : EXIT_SUCCESS; 158 } 159