OpenDNSSEC-signer  1.3.14
toolutil.c
Go to the documentation of this file.
1 /*
2  * $Id: toolutil.c 4172 2010-11-08 14:25:53Z matthijs $
3  *
4  * Copyright (c) 2009 NLNet Labs. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
33 #include <stdio.h>
34 #include "tools/toolutil.h"
35 
36 int
37 read_line(FILE *input, char *line, int multiline, int skip_comments)
38 {
39  int i, li;
40  int depth = 0;
41  int in_string = 0;
42 
43  char c, lc = 0;
44  li = 0;
45  for (i = 0; i < MAX_LINE_LEN; i++) {
46  c = (char) getc(input);
47  /* if a comment does not start at the beginning of the line,
48  * skip it completely */
49  if (c == ';' && !in_string && lc != '\\') {
50  while(c != EOF && c != '\n') {
51  if (!skip_comments && !multiline) {
52  line[li] = c;
53  li++;
54  }
55  c = (char) getc(input);
56  }
57  }
58 
59  if (c == EOF) {
60  if (depth != 0) {
61  fprintf(stderr, "bracket mismatch in multiline RR"
62  "; eof, depth=%i, missing )\n", depth);
63  }
64  if (li > 0) {
65  line[li] = '\0';
66  return li;
67  } else {
68  return -1;
69  }
70  } else if (c == '"' && lc != '\\') {
71  in_string = 1 - in_string;
72  line[li] = c;
73  li++;
74  } else if (c == '(' && multiline) {
75  if (in_string) {
76  line[li] = c;
77  li++;
78  } else {
79  depth++;
80  line[li] = ' ';
81  li++;
82  }
83  } else if (c == ')' && multiline) {
84  if (in_string) {
85  line[li] = c;
86  li++;
87  } else {
88  if (depth < 1) {
89  fprintf(stderr, "bracket mismatch in multiline RR"
90  "; missing (\n");
91  line[li] = '\0';
92  return li;
93  }
94  line[li] = ' ';
95  li++;
96  }
97  depth--;
98  } else if (c != '\n') {
99  line[li] = c;
100  li++;
101  } else {
102  if (!multiline || depth == 0) {
103  break;
104  }
105  }
106  lc = c;
107  }
108  if (depth != 0) {
109  fprintf(stderr, "bracket mismatch in multiline RR"
110  "; depth=%i, missing )\n", depth);
111  }
112  line[li] = '\0';
113  return li;
114 }
115 
116 /* frees all ldns_rr records in the list, and sets the count to 0 */
117 void
118 rr_list_clear(ldns_rr_list *rr_list) {
119  size_t i;
120  for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
121  ldns_rr_free(ldns_rr_list_rr(rr_list, i));
122  }
123  ldns_rr_list_set_rr_count(rr_list, 0);
124 }
125 
126 /* lookup serial, minimum */
127 static uint32_t
128 get_soa_rdata(ldns_rr *rr, int rnum)
129 {
130  uint32_t rdata = 0;
131  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
132  rdata = ldns_rdf2native_int32(ldns_rr_rdf(rr, rnum));
133  }
134  return rdata;
135 }
136 
137 static uint32_t
138 lookup_soa_rdata(FILE* fd, int rnum)
139 {
140  ldns_rr *cur_rr;
141  char line[MAX_LINE_LEN];
142  ldns_status status;
143  uint32_t rdata;
144  int line_len = 0;
145 
146  while (line_len >= 0) {
147  line_len = read_line(fd, line, 1, 0);
148  if (line_len > 0) {
149  if (line[0] != ';') {
150  status = ldns_rr_new_frm_str(&cur_rr, line, 0, NULL, NULL);
151  if (status == LDNS_STATUS_OK) {
152  rdata = get_soa_rdata(cur_rr, rnum);
153  ldns_rr_free(cur_rr);
154  if (rdata != 0) {
155  return rdata;
156  }
157  }
158  }
159  }
160  }
161  return 0;
162 }
163 
164 uint32_t
165 lookup_serial(FILE* fd)
166 {
167  return lookup_soa_rdata(fd, 2);
168 }
169 
170 uint32_t
171 lookup_minimum(FILE* fd)
172 {
173  return lookup_soa_rdata(fd, 6);
174 }
175 
176 ldns_rr_class
177 lookup_class(FILE* fd)
178 {
179  ldns_rr *cur_rr;
180  char line[MAX_LINE_LEN];
181  ldns_status status;
182  ldns_rr_class soa_class;
183  int line_len = 0;
184 
185  while (line_len >= 0) {
186  line_len = read_line(fd, line, 1, 0);
187  if (line_len > 0) {
188  if (line[0] != ';') {
189  status = ldns_rr_new_frm_str(&cur_rr, line, 0, NULL, NULL);
190  if (status == LDNS_STATUS_OK) {
191  soa_class = ldns_rr_get_class(cur_rr);
192  ldns_rr_free(cur_rr);
193  return soa_class;
194  }
195  }
196  }
197  }
198  return LDNS_RR_CLASS_IN;
199 }