OpenDNSSEC-signer  1.4.3
adutil.c
Go to the documentation of this file.
1 /*
2  * $Id$
3  *
4  * Copyright (c) 2009-2011 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 
34 #include "config.h"
35 #include "adapter/adutil.h"
36 #include "shared/file.h"
37 #include "shared/log.h"
38 
39 #include <ldns/ldns.h>
40 
41 static const char* adapter_str = "adapter";
42 
43 
48 ldns_rr*
50 {
51  ldns_rr *cur_rr = NULL;
52  char line[SE_ADFILE_MAXLINE];
53  ldns_status status = LDNS_STATUS_OK;
54  int line_len = 0;
55  unsigned int l = 0;
56 
57  while (line_len >= 0) {
58  line_len = adutil_readline_frm_file(fd, (char*) line, &l, 0);
59  adutil_rtrim_line(line, &line_len);
60 
61  if (line_len > 0) {
62  if (line[0] != ';') {
63  status = ldns_rr_new_frm_str(&cur_rr, line, 0, NULL, NULL);
64  if (status == LDNS_STATUS_OK) {
65  if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
66  return cur_rr;
67  } else {
68  ldns_rr_free(cur_rr);
69  cur_rr = NULL;
70  }
71  }
72  }
73  }
74  }
75  return NULL;
76 }
77 
78 
83 int
84 adutil_readline_frm_file(FILE* fd, char* line, unsigned int* l,
85  int keep_comments)
86 {
87  int i = 0;
88  int li = 0;
89  int in_string = 0;
90  int depth = 0;
91  int comments = 0;
92  char c = 0;
93  char lc = 0;
94 
95  for (i = 0; i < SE_ADFILE_MAXLINE; i++) {
96  c = (char) ods_fgetc(fd, l);
97  if (comments) {
98  while (c != EOF && c != '\n') {
99  c = (char) ods_fgetc(fd, l);
100  }
101  }
102 
103  if (c == EOF) {
104  if (depth != 0) {
105  ods_log_error("[%s] read line: bracket mismatch discovered at "
106  "line %i, missing ')'", adapter_str, l&&*l?*l:0);
107  }
108  if (li > 0) {
109  line[li] = '\0';
110  return li;
111  } else {
112  return -1;
113  }
114  } else if (c == '"' && lc != '\\') {
115  in_string = 1 - in_string; /* swap status */
116  line[li] = c;
117  li++;
118  } else if (c == '(') {
119  if (in_string) {
120  line[li] = c;
121  li++;
122  } else if (lc != '\\') {
123  depth++;
124  line[li] = ' ';
125  li++;
126  } else {
127  line[li] = c;
128  li++;
129  }
130  } else if (c == ')') {
131  if (in_string) {
132  line[li] = c;
133  li++;
134  } else if (lc != '\\') {
135  if (depth < 1) {
136  ods_log_error("[%s] read line: bracket mismatch "
137  "discovered at line %i, missing '('", adapter_str,
138  l&&*l?*l:0);
139  line[li] = '\0';
140  return li;
141  }
142  depth--;
143  line[li] = ' ';
144  li++;
145  } else {
146  line[li] = c;
147  li++;
148  }
149  } else if (c == ';') {
150  if (in_string) {
151  line[li] = c;
152  li++;
153  } else if (lc != '\\' && !keep_comments) {
154  comments = 1;
155  } else {
156  line[li] = c;
157  li++;
158  }
159  } else if (c == '\n' && lc != '\\') {
160  comments = 0;
161  /* if no depth issue, we are done */
162  if (depth == 0) {
163  break;
164  }
165  line[li] = ' ';
166  li++;
167  } else if (c == '\t' && lc != '\\') {
168  line[li] = ' ';
169  li++;
170  } else {
171  line[li] = c;
172  li++;
173  }
174  /* continue with line */
175  lc = c;
176  }
177 
178  /* done */
179  if (depth != 0) {
180  ods_log_error("[%s] read line: bracket mismatch discovered at line %i,"
181  " missing ')'", adapter_str, l&&*l?*l:0);
182  return li;
183  }
184  line[li] = '\0';
185  return li;
186 }
187 
188 
189 /*
190  * Trim trailing whitespace.
191  *
192  */
193 void
194 adutil_rtrim_line(char* line, int* line_len)
195 {
196  int i = strlen(line), nl = 0;
197  int trimmed = 0;
198 
199  while (i>0) {
200  --i;
201  if (line[i] == '\n') {
202  nl = 1;
203  }
204  if (line[i] == ' ' || line[i] == '\t' || line[i] == '\n') {
205  line[i] = '\0';
206  trimmed++;
207  } else {
208  break;
209  }
210  }
211  if (nl) {
212  line[++i] = '\n';
213  }
214  *line_len -= trimmed;
215  return;
216 }
217 
218 
223 int
224 adutil_whitespace_line(char* line, int line_len)
225 {
226  int i;
227  for (i = 0; i < line_len; i++) {
228  if (!isspace((int)line[i])) {
229  return 0;
230  }
231  }
232  return 1;
233 }
ldns_rr * adutil_lookup_soa_rr(FILE *fd)
Definition: adutil.c:49
void ods_log_error(const char *format,...)
Definition: log.c:336
int ods_fgetc(FILE *fd, unsigned int *line_nr)
Definition: file.c:81
int adutil_whitespace_line(char *line, int line_len)
Definition: adutil.c:224
void adutil_rtrim_line(char *line, int *line_len)
Definition: adutil.c:194
#define SE_ADFILE_MAXLINE
Definition: adutil.h:42
int adutil_readline_frm_file(FILE *fd, char *line, unsigned int *l, int keep_comments)
Definition: adutil.c:84