OpenDNSSEC-signer  1.3.9
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);
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 {
86  int i = 0;
87  int li = 0;
88  int in_string = 0;
89  int depth = 0;
90  int comments = 0;
91  char c = 0;
92  char lc = 0;
93 
94  for (i = 0; i < SE_ADFILE_MAXLINE; i++) {
95  c = (char) ods_fgetc(fd, l);
96  if (comments) {
97  while (c != EOF && c != '\n') {
98  c = (char) ods_fgetc(fd, l);
99  }
100  }
101 
102  if (c == EOF) {
103  if (depth != 0) {
104  ods_log_error("[%s] read line: bracket mismatch discovered at "
105  "line %i, missing ')'", adapter_str, l&&*l?*l:0);
106  }
107  if (li > 0) {
108  line[li] = '\0';
109  return li;
110  } else {
111  return -1;
112  }
113  } else if (c == '"' && lc != '\\') {
114  in_string = 1 - in_string; /* swap status */
115  line[li] = c;
116  li++;
117  } else if (c == '(') {
118  if (in_string) {
119  line[li] = c;
120  li++;
121  } else if (lc != '\\') {
122  depth++;
123  line[li] = ' ';
124  li++;
125  } else {
126  line[li] = c;
127  li++;
128  }
129  } else if (c == ')') {
130  if (in_string) {
131  line[li] = c;
132  li++;
133  } else if (lc != '\\') {
134  if (depth < 1) {
135  ods_log_error("[%s] read line: bracket mismatch "
136  "discovered at line %i, missing '('", adapter_str,
137  l&&*l?*l:0);
138  line[li] = '\0';
139  return li;
140  }
141  depth--;
142  line[li] = ' ';
143  li++;
144  } else {
145  line[li] = c;
146  li++;
147  }
148  } else if (c == ';') {
149  if (in_string) {
150  line[li] = c;
151  li++;
152  } else if (lc != '\\') {
153  comments = 1;
154  } else {
155  line[li] = c;
156  li++;
157  }
158  } else if (c == '\n' && lc != '\\') {
159  comments = 0;
160  /* if no depth issue, we are done */
161  if (depth == 0) {
162  break;
163  }
164  line[li] = ' ';
165  li++;
166  } else if (c == '\t' && lc != '\\') {
167  line[li] = ' ';
168  li++;
169  } else {
170  line[li] = c;
171  li++;
172  }
173  /* continue with line */
174  lc = c;
175  }
176 
177  /* done */
178  if (depth != 0) {
179  ods_log_error("[%s] read line: bracket mismatch discovered at line %i,"
180  " missing ')'", adapter_str, l&&*l?*l:0);
181  return li;
182  }
183  line[li] = '\0';
184  return li;
185 }
186 
187 
188 /*
189  * Trim trailing whitespace.
190  *
191  */
192 void
193 adutil_rtrim_line(char* line, int* line_len)
194 {
195  int i = strlen(line), nl = 0;
196  int trimmed = 0;
197 
198  while (i>0) {
199  --i;
200  if (line[i] == '\n') {
201  nl = 1;
202  }
203  if (line[i] == ' ' || line[i] == '\t' || line[i] == '\n') {
204  line[i] = '\0';
205  trimmed++;
206  } else {
207  break;
208  }
209  }
210  if (nl) {
211  line[++i] = '\n';
212  }
213  *line_len -= trimmed;
214  return;
215 }
216 
217 
222 int
223 adutil_whitespace_line(char* line, int line_len)
224 {
225  int i;
226  for (i = 0; i < line_len; i++) {
227  if (!isspace((int)line[i])) {
228  return 0;
229  }
230  }
231  return 1;
232 }