OpenDNSSEC-signer  1.4.5
adutil.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009-2011 NLNet Labs. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
32 #include "config.h"
33 #include "adapter/adutil.h"
34 #include "shared/file.h"
35 #include "shared/log.h"
36 
37 #include <ldns/ldns.h>
38 
39 static const char* adapter_str = "adapter";
40 
41 
46 ldns_rr*
48 {
49  ldns_rr *cur_rr = NULL;
50  char line[SE_ADFILE_MAXLINE];
51  ldns_status status = LDNS_STATUS_OK;
52  int line_len = 0;
53  unsigned int l = 0;
54 
55  while (line_len >= 0) {
56  line_len = adutil_readline_frm_file(fd, (char*) line, &l, 0);
57  adutil_rtrim_line(line, &line_len);
58 
59  if (line_len > 0) {
60  if (line[0] != ';') {
61  status = ldns_rr_new_frm_str(&cur_rr, line, 0, NULL, NULL);
62  if (status == LDNS_STATUS_OK) {
63  if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
64  return cur_rr;
65  } else {
66  ldns_rr_free(cur_rr);
67  cur_rr = NULL;
68  }
69  }
70  }
71  }
72  }
73  return NULL;
74 }
75 
76 
81 int
82 adutil_readline_frm_file(FILE* fd, char* line, unsigned int* l,
83  int keep_comments)
84 {
85  int i = 0;
86  int li = 0;
87  int in_string = 0;
88  int depth = 0;
89  int comments = 0;
90  char c = 0;
91  char lc = 0;
92 
93  for (i = 0; i < SE_ADFILE_MAXLINE; i++) {
94  c = (char) ods_fgetc(fd, l);
95  if (comments) {
96  while (c != EOF && c != '\n') {
97  c = (char) ods_fgetc(fd, l);
98  }
99  }
100 
101  if (c == EOF) {
102  if (depth != 0) {
103  ods_log_error("[%s] read line: bracket mismatch discovered at "
104  "line %i, missing ')'", adapter_str, l&&*l?*l:0);
105  }
106  if (li > 0) {
107  line[li] = '\0';
108  return li;
109  } else {
110  return -1;
111  }
112  } else if (c == '"' && lc != '\\') {
113  in_string = 1 - in_string; /* swap status */
114  line[li] = c;
115  li++;
116  } else if (c == '(') {
117  if (in_string) {
118  line[li] = c;
119  li++;
120  } else if (lc != '\\') {
121  depth++;
122  line[li] = ' ';
123  li++;
124  } else {
125  line[li] = c;
126  li++;
127  }
128  } else if (c == ')') {
129  if (in_string) {
130  line[li] = c;
131  li++;
132  } else if (lc != '\\') {
133  if (depth < 1) {
134  ods_log_error("[%s] read line: bracket mismatch "
135  "discovered at line %i, missing '('", adapter_str,
136  l&&*l?*l:0);
137  line[li] = '\0';
138  return li;
139  }
140  depth--;
141  line[li] = ' ';
142  li++;
143  } else {
144  line[li] = c;
145  li++;
146  }
147  } else if (c == ';') {
148  if (in_string) {
149  line[li] = c;
150  li++;
151  } else if (lc != '\\' && !keep_comments) {
152  comments = 1;
153  } else {
154  line[li] = c;
155  li++;
156  }
157  } else if (c == '\n' && lc != '\\') {
158  comments = 0;
159  /* if no depth issue, we are done */
160  if (depth == 0) {
161  break;
162  }
163  line[li] = ' ';
164  li++;
165  } else {
166  line[li] = c;
167  li++;
168  }
169  /* continue with line */
170  lc = c;
171  }
172 
173  /* done */
174  if (depth != 0) {
175  ods_log_error("[%s] read line: bracket mismatch discovered at line %i,"
176  " missing ')'", adapter_str, l&&*l?*l:0);
177  return li;
178  }
179  line[li] = '\0';
180  return li;
181 }
182 
183 
184 /*
185  * Trim trailing whitespace.
186  *
187  */
188 void
189 adutil_rtrim_line(char* line, int* line_len)
190 {
191  int i = strlen(line), nl = 0;
192  int trimmed = 0;
193 
194  while (i>0) {
195  --i;
196  if (line[i] == '\n') {
197  nl = 1;
198  }
199  if (line[i] == ' ' || line[i] == '\t' || line[i] == '\n') {
200  line[i] = '\0';
201  trimmed++;
202  } else {
203  break;
204  }
205  }
206  if (nl) {
207  line[++i] = '\n';
208  }
209  *line_len -= trimmed;
210  return;
211 }
212 
213 
218 int
219 adutil_whitespace_line(char* line, int line_len)
220 {
221  int i;
222  for (i = 0; i < line_len; i++) {
223  if (!isspace((int)line[i])) {
224  return 0;
225  }
226  }
227  return 1;
228 }
ldns_rr * adutil_lookup_soa_rr(FILE *fd)
Definition: adutil.c:47
void ods_log_error(const char *format,...)
Definition: log.c:334
int ods_fgetc(FILE *fd, unsigned int *line_nr)
Definition: file.c:79
int adutil_whitespace_line(char *line, int line_len)
Definition: adutil.c:219
void adutil_rtrim_line(char *line, int *line_len)
Definition: adutil.c:189
#define SE_ADFILE_MAXLINE
Definition: adutil.h:40
int adutil_readline_frm_file(FILE *fd, char *line, unsigned int *l, int keep_comments)
Definition: adutil.c:82