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 "sldns/str2wire.h" 49 #include "sldns/wire2str.h" 50 51 int print_usage(FILE *out, const char *progname) 52 { 53 fprintf(out, "usage: %s [ -u ] <zonefile> [<origin>]\n", progname); 54 fprintf(out, "\t-u\tprint in unknown type (RFC3597) format\n"); 55 return out == stdout ? EXIT_SUCCESS : EXIT_FAILURE; 56 } 57 58 int main(int argc, char *const *argv) 59 { 60 char *progname = argv[0]; 61 uint8_t rr[LDNS_RR_BUF_SIZE]; 62 char *str = malloc(1024 * 1024); 63 size_t str_len = sizeof(str); 64 struct sldns_file_parse_state state; 65 FILE *in = NULL; 66 int s = -1; 67 int opt; 68 int print_in_unknown_type_format = 0; 69 70 while ((opt = getopt(argc, argv, "hu")) != -1) { 71 switch (opt) { 72 case 'h': 73 free(str); 74 return print_usage(stdout, progname); 75 case 'u': 76 print_in_unknown_type_format = 1; 77 break; 78 default: 79 free(str); 80 return print_usage(stderr, progname); 81 } 82 } 83 argc -= optind; 84 argv += optind; 85 86 memset(&state, 0, sizeof(state)); 87 state.default_ttl = 3600; 88 state.lineno = 1; 89 if (argc == 2) { 90 state.origin_len = sizeof(state.origin); 91 s = sldns_str2wire_dname_buf(argv[1], state.origin 92 , &state.origin_len); 93 if (s) { 94 fprintf(stderr, "Error parsing origin: %s\n" 95 , sldns_get_errorstr_parse(s)); 96 free(str); 97 return EXIT_FAILURE; 98 } 99 s = -1; 100 } 101 if (!str) 102 fprintf(stderr, "Memory allocation error: %s\n" 103 , strerror(errno)); 104 105 else if (argc != 1 && argc != 2) { 106 free(str); 107 return print_usage(stderr, progname); 108 } 109 110 else if (!(in = fopen(argv[0], "r"))) 111 fprintf(stderr, "Error opening \"%s\": %s\n" 112 , argv[0], strerror(errno)); 113 else while (!feof(in)) { 114 size_t rr_len = sizeof(rr), dname_len = 0; 115 size_t written; 116 117 s = sldns_fp2wire_rr_buf(in, rr, &rr_len, &dname_len, &state); 118 if (s) { 119 fprintf( stderr, "parse error %d:%d: %s\n" 120 , state.lineno, LDNS_WIREPARSE_OFFSET(s) 121 , sldns_get_errorstr_parse(s)); 122 break; 123 } 124 if (rr_len == 0) 125 continue; 126 127 if (print_in_unknown_type_format) 128 written = sldns_wire2str_rr_unknown_buf( 129 rr, rr_len, str, str_len); 130 else 131 written = sldns_wire2str_rr_buf( 132 rr, rr_len, str, str_len); 133 134 if (written > str_len) { 135 while (written > str_len) 136 str_len *= 2; 137 free(str); 138 if (!(str = malloc(str_len))) { 139 fprintf(stderr, "Memory allocation error: %s\n" 140 , strerror(errno)); 141 s = -1; 142 break; 143 } 144 if (print_in_unknown_type_format) 145 (void) sldns_wire2str_rr_unknown_buf( 146 rr, rr_len, str, str_len); 147 else 148 (void) sldns_wire2str_rr_buf( 149 rr, rr_len, str, str_len); 150 } 151 fprintf(stdout, "%s", str); 152 } 153 if (in) 154 fclose(in); 155 free(str); 156 return !in || s ? EXIT_FAILURE : EXIT_SUCCESS; 157 } 158