aboutsummaryrefslogtreecommitdiff
path: root/src/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/output.c')
-rw-r--r--src/output.c109
1 files changed, 87 insertions, 22 deletions
diff --git a/src/output.c b/src/output.c
index a684201..fb8b66c 100644
--- a/src/output.c
+++ b/src/output.c
@@ -15,6 +15,9 @@
along with NSsync. If not, see <http://www.gnu.org/licenses/>. */
#include "nssync.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
#define S(s) ((s) ? (s) : NULL)
@@ -26,15 +29,49 @@ enum {
};
int
-format_ns_record(MYSQL_ROW row, unsigned nf, void *data)
+save_ns_record(MYSQL_ROW row, unsigned nf, void *data)
{
struct nssync *sp = data;
+ struct nsdef *ns;
if (nf != _ns_nfields) {
error("NS query returned wrong number of fields");
return 1;
}
+
+ ns = grecs_malloc(sizeof(*ns));
+ ns->type = grecs_strdup(row[f_ns_type]);
+ ns->data = grecs_strdup(row[f_ns_data]);
/* FIXME: TTL */
- fprintf(sp->fp, "\t%s\t%s\n", row[f_ns_type], row[f_ns_data]);
+ ns->next = NULL;
+
+ if (sp->nsdef_tail)
+ sp->nsdef_tail->next = ns;
+ else
+ sp->nsdef_head = ns;
+ sp->nsdef_tail = ns;
+
+ if (check_ns && !sp->myzone && strcasecmp(ns->type, "NS") == 0) {
+ struct addrinfo *res, *ap, hints;
+ int rc;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ rc = getaddrinfo(ns->data, NULL, &hints, &res);
+ if (rc) {
+ error("can't resolve %s: %s", ns->data,
+ gai_strerror(rc));
+ return 0;
+ }
+
+ for (ap = res; ap; ap = ap->ai_next) {
+ if (is_my_sockaddr((struct sockaddr_in*)res->ai_addr)) {
+ sp->myzone = 1;
+ break;
+ }
+ }
+ freeaddrinfo(res);
+ }
+
return 0;
}
@@ -95,12 +132,30 @@ is_reverse_zone(const char *str)
strcasecmp(str + len - sizeof(suffix) + 1, suffix) == 0;
}
+void
+free_nsdef(struct nssync *sp)
+{
+ struct nsdef *ns;
+
+ for (ns = sp->nsdef_head; ns; ) {
+ struct nsdef *next = ns->next;
+ free(ns->type);
+ free(ns->data);
+ free(ns);
+ ns = ns->next;
+ }
+ sp->nsdef_head = sp->nsdef_tail = NULL;
+}
+
int
format_soa_record(MYSQL_ROW row, unsigned nf, void *data)
{
struct nssync *sp = data;
struct wordsplit ws;
const char *env[3];
+ int wsflags = WRDSF_NOCMD | WRDSF_ENV | WRDSF_ENV_KV |
+ WRDSF_NOSPLIT | WRDSF_KEEPUNDEF;
+ struct nsdef *ns;
if (nf != _soa_nfields) {
error("SOA query returned wrong number of fields");
@@ -109,6 +164,32 @@ format_soa_record(MYSQL_ROW row, unsigned nf, void *data)
if (!row[f_soa_type])
return 0;
+ free_nsdef(sp);
+ sp->myzone = !check_ns;
+
+ /* Fill the list of NS servers */
+ env[0] = "zone";
+ env[1] = row[f_soa_zone];
+ env[2] = 0;
+
+ if (sp->ns_query) {
+ ws.ws_env = env;
+ if (wordsplit(sp->ns_query, &ws, wsflags)) {
+ error("cannot split ns_query: %s",
+ wordsplit_strerror(&ws));
+ exit(EX_SOFTWARE);
+ }
+ wsflags |= WRDSF_REUSE;
+ if (sql_do_query(ws.ws_wordv[0], save_ns_record, sp))
+ exit(EX_UNAVAILABLE);
+ }
+
+ if (!sp->myzone) {
+ debug(1,("%s: not served by me", row[f_soa_zone]));
+ wordsplit_free(&ws);
+ return 0;
+ }
+
grecs_free(sp->file_name);
sp->file_name = bindcf_lookup(sp, row[f_soa_zone]);
if (!sp->file_name)
@@ -140,29 +221,13 @@ format_soa_record(MYSQL_ROW row, unsigned nf, void *data)
row[f_soa_retry],
row[f_soa_expire],
row[f_soa_minimum]);
-
- env[0] = "zone";
- env[1] = row[f_soa_zone];
- env[2] = 0;
- if (sp->ns_query) {
- ws.ws_env = env;
- if (wordsplit(sp->ns_query, &ws,
- WRDSF_NOCMD | WRDSF_ENV | WRDSF_ENV_KV |
- WRDSF_NOSPLIT | WRDSF_KEEPUNDEF)) {
- error("cannot split ns_query: %s",
- wordsplit_strerror(&ws));
- exit(EX_SOFTWARE);
- }
-
- if (sql_do_query(ws.ws_wordv[0], format_ns_record, sp))
- exit(EX_UNAVAILABLE);
- }
+ for (ns = sp->nsdef_head; ns; ns = ns->next)
+ /* FIXME: TTL */
+ fprintf(sp->fp, "\t%s\t%s\n", ns->type, ns->data);
if (wordsplit((sp->rev_rr_query && is_reverse_zone(row[f_soa_zone])) ?
- sp->rev_rr_query : sp->rr_query, &ws,
- WRDSF_NOCMD | WRDSF_ENV | WRDSF_ENV_KV | WRDSF_NOSPLIT |
- WRDSF_KEEPUNDEF | WRDSF_REUSE)) {
+ sp->rev_rr_query : sp->rr_query, &ws, wsflags)) {
error("cannot split rr_query: %s", wordsplit_strerror(&ws));
exit(EX_SOFTWARE);
}

Return to:

Send suggestions and report system problems to the System administrator.