44 #include <ldns/ldns.h> 48 static const char* adapter_str =
"adapter";
49 static ods_status adfile_read_file(FILE* fd,
zone_type* zone);
57 adfile_read_rr(FILE* fd,
zone_type* zone,
char* line, ldns_rdf** orig,
58 ldns_rdf** prev, uint32_t* ttl, ldns_status* status,
unsigned int* l)
62 FILE* fd_include = NULL;
64 ods_status s = ODS_STATUS_OK;
79 if (strncmp(line,
"$ORIGIN", 7) == 0 && isspace((
int)line[7])) {
82 ldns_rdf_deep_free(*orig);
86 while (isspace((
int)line[offset])) {
89 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME,
93 *status = LDNS_STATUS_SYNTAX_DNAME_ERR;
98 goto adfile_read_line;
100 }
else if (strncmp(line,
"$TTL", 4) == 0 &&
101 isspace((
int)line[4])) {
104 while (isspace((
int)line[offset])) {
108 *ttl = ldns_str2period(line + offset, &endptr);
111 goto adfile_read_line;
113 }
else if (strncmp(line,
"$INCLUDE", 8) == 0 &&
114 isspace((
int)line[8])) {
117 while (isspace((
int)line[offset])) {
120 fd_include = ods_fopen(line + offset, NULL,
"r");
122 s = adfile_read_file(fd_include, zone);
123 ods_fclose(fd_include);
125 ods_log_error(
"[%s] unable to open include file %s",
126 adapter_str, (line+offset));
127 *status = LDNS_STATUS_SYNTAX_ERR;
130 if (s != ODS_STATUS_OK) {
131 *status = LDNS_STATUS_SYNTAX_ERR;
132 ods_log_error(
"[%s] error in include file %s",
133 adapter_str, (line+offset));
140 goto adfile_read_line;
148 goto adfile_read_line;
154 goto adfile_read_line;
157 *status = ldns_rr_new_frm_str(&rr, line, new_ttl, *orig, prev);
158 if (*status == LDNS_STATUS_OK) {
160 }
else if (*status == LDNS_STATUS_SYNTAX_EMPTY) {
165 *status = LDNS_STATUS_OK;
166 goto adfile_read_line;
169 ods_log_error(
"[%s] error parsing RR at line %i (%s): %s",
170 adapter_str, l&&*l?*l:0,
171 ldns_get_errorstr_by_id(*status), line);
185 *status = LDNS_STATUS_OK;
195 adfile_read_file(FILE* fd,
zone_type* zone)
197 ods_status result = ODS_STATUS_OK;
199 ldns_rdf* prev = NULL;
200 ldns_rdf* orig = NULL;
201 ldns_rdf* dname = NULL;
203 uint32_t new_serial = 0;
204 ldns_status status = LDNS_STATUS_OK;
206 unsigned int line_update_interval = 100000;
207 unsigned int line_update = line_update_interval;
211 ods_log_assert(zone);
216 ods_log_error(
"[%s] error getting default value for $ORIGIN",
218 return ODS_STATUS_ERR;
220 orig = ldns_rdf_clone(dname);
222 ods_log_error(
"[%s] error setting default value for $ORIGIN",
224 return ODS_STATUS_ERR;
229 while ((rr = adfile_read_rr(fd, zone, line, &orig, &prev, &ttl,
230 &status, &l)) != NULL) {
232 if (status != LDNS_STATUS_OK) {
233 ods_log_error(
"[%s] error reading RR at line %i (%s): %s",
234 adapter_str, l, ldns_get_errorstr_by_id(status), line);
235 result = ODS_STATUS_ERR;
239 if (l > line_update) {
240 ods_log_debug(
"[%s] ...at line %i: %s", adapter_str, l, line);
241 line_update += line_update_interval;
244 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
246 ldns_rdf2native_int32(ldns_rr_rdf(rr, SE_SOA_RDATA_SERIAL));
250 if (result == ODS_STATUS_UNCHANGED) {
251 ods_log_debug(
"[%s] skipping RR at line %i (duplicate): %s",
252 adapter_str, l, line);
255 result = ODS_STATUS_OK;
257 }
else if (result != ODS_STATUS_OK) {
258 ods_log_error(
"[%s] error adding RR at line %i: %s",
259 adapter_str, l, line);
267 ldns_rdf_deep_free(orig);
271 ldns_rdf_deep_free(prev);
274 if (result == ODS_STATUS_OK && status != LDNS_STATUS_OK) {
275 ods_log_error(
"[%s] error reading RR at line %i (%s): %s",
276 adapter_str, l, ldns_get_errorstr_by_id(status), line);
277 result = ODS_STATUS_ERR;
280 if (result == ODS_STATUS_OK) {
282 if (result != ODS_STATUS_OK) {
283 ods_log_error(
"[%s] unable to read file: zonefile contains errors",
302 ods_status status = ODS_STATUS_OK;
304 ods_log_error(
"[%s] unable to read file: no input adapter",
306 return ODS_STATUS_ASSERT_ERR;
310 return ODS_STATUS_FOPEN_ERR;
312 status = adfile_read_file(fd, adzone);
314 if (status == ODS_STATUS_OK) {
329 char* tmpname = NULL;
331 ods_status status = ODS_STATUS_OK;
335 ods_log_error(
"[%s] unable to write file: no output adapter",
337 return ODS_STATUS_ASSERT_ERR;
340 ods_log_error(
"[%s] unable to write file: no filename given",
342 return ODS_STATUS_ASSERT_ERR;
347 tmpname = ods_build_path(filename,
".tmp", 0, 0);
349 return ODS_STATUS_MALLOC_ERR;
351 fd = ods_fopen(tmpname, NULL,
"w");
355 if (status == ODS_STATUS_OK) {
357 ods_log_error(
"[%s] unable to write zone %s file %s: one or " 358 "more RR print failed", adapter_str, adzone->
name,
362 status = ODS_STATUS_FWRITE_ERR;
366 status = ODS_STATUS_FOPEN_ERR;
369 if (status == ODS_STATUS_OK) {
370 if (rename((
const char*) tmpname, filename) != 0) {
371 ods_log_error(
"[%s] unable to write file: failed to rename %s " 372 "to %s (%s)", adapter_str, tmpname, filename, strerror(errno));
373 status = ODS_STATUS_RENAME_ERR;
adapter_type * adoutbound
ods_status adfile_read(void *zone)
void adapi_set_serial(zone_type *zone, uint32_t serial)
ods_status adfile_write(void *zone, const char *filename)
ldns_rdf * adapi_get_origin(zone_type *zone)
int adutil_whitespace_line(char *line, int line_len)
void adutil_rtrim_line(char *line, int *line_len)
ods_status adapi_printzone(FILE *fd, zone_type *zone)
void adapi_trans_full(zone_type *zone, unsigned more_coming)
ods_status namedb_examine(namedb_type *db)
ods_status adapi_add_rr(zone_type *zone, ldns_rr *rr, int backup)
#define SE_ADFILE_MAXLINE
int adutil_readline_frm_file(FILE *fd, char *line, unsigned int *l, int keep_comments)
uint32_t adapi_get_ttl(zone_type *zone)