OpenDNSSEC-signer 1.3.0
|
00001 /* 00002 * $Id: toolutil.c 5320 2011-07-12 10:42:26Z jakob $ 00003 * 00004 * Copyright (c) 2009 NLNet Labs. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00019 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00020 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00021 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00023 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00024 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00025 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 * 00027 */ 00028 00033 #include <stdio.h> 00034 #include "tools/toolutil.h" 00035 00036 int 00037 read_line(FILE *input, char *line, int multiline, int skip_comments) 00038 { 00039 int i, li; 00040 int depth = 0; 00041 int in_string = 0; 00042 00043 char c, lc = 0; 00044 li = 0; 00045 for (i = 0; i < MAX_LINE_LEN; i++) { 00046 c = (char) getc(input); 00047 /* if a comment does not start at the beginning of the line, 00048 * skip it completely */ 00049 if (c == ';' && !in_string && lc != '\\') { 00050 while(c != EOF && c != '\n') { 00051 if (!skip_comments && !multiline) { 00052 line[li] = c; 00053 li++; 00054 } 00055 c = (char) getc(input); 00056 } 00057 } 00058 00059 if (c == EOF) { 00060 if (depth != 0) { 00061 fprintf(stderr, "bracket mismatch in multiline RR" 00062 "; eof, depth=%i, missing )\n", depth); 00063 } 00064 if (li > 0) { 00065 line[li] = '\0'; 00066 return li; 00067 } else { 00068 return -1; 00069 } 00070 } else if (c == '"' && lc != '\\') { 00071 in_string = 1 - in_string; 00072 line[li] = c; 00073 li++; 00074 } else if (c == '(' && multiline) { 00075 if (in_string) { 00076 line[li] = c; 00077 li++; 00078 } else { 00079 depth++; 00080 line[li] = ' '; 00081 li++; 00082 } 00083 } else if (c == ')' && multiline) { 00084 if (in_string) { 00085 line[li] = c; 00086 li++; 00087 } else { 00088 if (depth < 1) { 00089 fprintf(stderr, "bracket mismatch in multiline RR" 00090 "; missing (\n"); 00091 line[li] = '\0'; 00092 return li; 00093 } 00094 line[li] = ' '; 00095 li++; 00096 } 00097 depth--; 00098 } else if (c != '\n') { 00099 line[li] = c; 00100 li++; 00101 } else { 00102 if (!multiline || depth == 0) { 00103 break; 00104 } 00105 } 00106 lc = c; 00107 } 00108 if (depth != 0) { 00109 fprintf(stderr, "bracket mismatch in multiline RR" 00110 "; depth=%i, missing )\n", depth); 00111 } 00112 line[li] = '\0'; 00113 return li; 00114 } 00115 00116 /* frees all ldns_rr records in the list, and sets the count to 0 */ 00117 void 00118 rr_list_clear(ldns_rr_list *rr_list) { 00119 size_t i; 00120 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { 00121 ldns_rr_free(ldns_rr_list_rr(rr_list, i)); 00122 } 00123 ldns_rr_list_set_rr_count(rr_list, 0); 00124 } 00125 00126 /* lookup serial, minimum */ 00127 static uint32_t 00128 get_soa_rdata(ldns_rr *rr, int rnum) 00129 { 00130 uint32_t rdata = 0; 00131 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) { 00132 rdata = ldns_rdf2native_int32(ldns_rr_rdf(rr, rnum)); 00133 } 00134 return rdata; 00135 } 00136 00137 static uint32_t 00138 lookup_soa_rdata(FILE* fd, int rnum) 00139 { 00140 ldns_rr *cur_rr; 00141 char line[MAX_LINE_LEN]; 00142 ldns_status status; 00143 uint32_t rdata; 00144 int line_len = 0; 00145 00146 while (line_len >= 0) { 00147 line_len = read_line(fd, line, 1, 0); 00148 if (line_len > 0) { 00149 if (line[0] != ';') { 00150 status = ldns_rr_new_frm_str(&cur_rr, line, 0, NULL, NULL); 00151 if (status == LDNS_STATUS_OK) { 00152 rdata = get_soa_rdata(cur_rr, rnum); 00153 ldns_rr_free(cur_rr); 00154 if (rdata != 0) { 00155 return rdata; 00156 } 00157 } 00158 } 00159 } 00160 } 00161 return 0; 00162 } 00163 00164 uint32_t 00165 lookup_serial(FILE* fd) 00166 { 00167 return lookup_soa_rdata(fd, 2); 00168 } 00169 00170 uint32_t 00171 lookup_minimum(FILE* fd) 00172 { 00173 return lookup_soa_rdata(fd, 6); 00174 } 00175 00176 ldns_rr_class 00177 lookup_class(FILE* fd) 00178 { 00179 ldns_rr *cur_rr; 00180 char line[MAX_LINE_LEN]; 00181 ldns_status status; 00182 ldns_rr_class soa_class; 00183 int line_len = 0; 00184 00185 while (line_len >= 0) { 00186 line_len = read_line(fd, line, 1, 0); 00187 if (line_len > 0) { 00188 if (line[0] != ';') { 00189 status = ldns_rr_new_frm_str(&cur_rr, line, 0, NULL, NULL); 00190 if (status == LDNS_STATUS_OK) { 00191 soa_class = ldns_rr_get_class(cur_rr); 00192 ldns_rr_free(cur_rr); 00193 return soa_class; 00194 } 00195 } 00196 } 00197 } 00198 return LDNS_RR_CLASS_IN; 00199 }