diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-18 12:09:46 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-18 12:09:46 +0300 |
commit | 768689775c020ae36a0de7b3fdc166777685bd6e (patch) | |
tree | bdbb556b52b04431264010ef237d7efbb41b544e | |
download | nssync-768689775c020ae36a0de7b3fdc166777685bd6e.tar.gz nssync-768689775c020ae36a0de7b3fdc166777685bd6e.tar.bz2 |
Initial commit
-rw-r--r-- | .gitignore | 25 | ||||
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | Makefile.am | 27 | ||||
-rw-r--r-- | acinclude.m4 | 50 | ||||
-rwxr-xr-x | bootstrap | 5 | ||||
-rw-r--r-- | configure.ac | 53 | ||||
m--------- | grecs | 0 | ||||
-rw-r--r-- | src/.gitignore | 2 | ||||
-rw-r--r-- | src/Makefile.am | 42 | ||||
-rw-r--r-- | src/cmdline.opt | 146 | ||||
-rw-r--r-- | src/config.c | 141 | ||||
-rw-r--r-- | src/nssync.c | 58 | ||||
-rw-r--r-- | src/nssync.h | 67 | ||||
-rw-r--r-- | src/output.c | 163 | ||||
-rw-r--r-- | src/sqlop.c | 94 |
15 files changed, 876 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eec45d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +*.a +*.o +*.tar.* +*~ +.deps +.emacs.desktop +.emacs.desktop.lock +.emacsrc +ABOUT-NLS +ChangeLog +INSTALL +Makefile +Makefile.in +TAGS +aclocal.m4 +autom4te.cache +build-aux +config.h +config.h.in +config.log +config.status +configure +core +m4 +stamp-h1 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..fea8f96 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "grecs"] + path = grecs + url = git://git.gnu.org.ua/grecs.git diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..98c53a7 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,27 @@ +# This file is part of NSsync +# Copyright (C) 2011 Sergey Poznyakoff +# +# NSsync is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# NSsync is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NSsync. If not, see <http://www.gnu.org/licenses/>. + +ACLOCAL_AMFLAGS = -I grecs/am + +SUBDIRS = grecs src + +.PHONY: ChangeLog +ChangeLog: + $(AM_V_GEN)if test -d .git; then \ + git log --pretty='format:%ct %an <%ae>%n%n%s%n%n%b%n' | \ + awk -f $(top_srcdir)/grecs/build-aux/git2chg.awk > ChangeLog; \ + fi + diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..f961c8b --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,50 @@ +# Copyright (C) 2001, 2006, 2008-2011 Sergey Poznyakoff +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. + +dnl Arguments: +dnl $1 -- Library to look for +dnl $2 -- Function to check in the library +dnl $3 -- Any additional libraries that might be needed +dnl $4 -- Action to be taken when test succeeds +dnl $5 -- Action to be taken when test fails +dnl $6 -- Directories where the library may reside +AC_DEFUN([WD_CHECK_LIB], +[m4_ifval([$4], , [AH_CHECK_LIB([$1])])dnl +AS_VAR_PUSHDEF([wd_Lib], [wd_cv_lib_$1])dnl +AC_CACHE_CHECK([for $2 in -l$1], [wd_Lib], +[AS_VAR_SET([wd_Lib], [no]) + wd_check_lib_save_LIBS=$LIBS + for path in "" $6 + do + if test -n "$path"; then + wd_ldflags="-L$path -l$1 $3" + else + wd_ldflags="-l$1 $3" + fi + LIBS="$wd_ldflags $wd_check_lib_save_LIBS" + AC_LINK_IFELSE([AC_LANG_CALL([], [$2])], + [AS_VAR_SET([wd_Lib], ["$wd_ldflags"]) + break]) + done + LIBS=$wd_check_lib_save_LIBS]) +AS_IF([test "AS_VAR_GET([wd_Lib])" != no], + [m4_default([$4], [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_LIB$1)) + LIBS="-l$1 $LIBS" +])], + [$5])dnl +AS_VAR_POPDEF([wd_Lib])dnl +])# WD_CHECK_LIB + + diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..ae677ac --- /dev/null +++ b/bootstrap @@ -0,0 +1,5 @@ +#! /bin/sh +set -e +git submodule init +git submodule update +autoreconf -f -i -s diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..96b3e0d --- /dev/null +++ b/configure.ac @@ -0,0 +1,53 @@ +# This file is part of NSsync -*- autoconf -*- +# Copyright (C) 2011 Sergey Poznyakoff +# +# NSsync is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# NSsync is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NSsync. If not, see <http://www.gnu.org/licenses/>. + +AC_PREREQ(2.63) +AC_INIT([nssync], 1.0, [gray+nssync@gnu.org.ua]) +AC_CONFIG_SRCDIR([src/nssync.c]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_HEADER([config.h]) +AM_INIT_AUTOMAKE([1.11 foreign tar-ustar dist-xz std-options silent-rules]) +AC_CONFIG_LIBOBJ_DIR([src]) + +# Enable silent rules by default: +AM_SILENT_RULES([yes]) + +# Checks for programs. +AC_PROG_CC +AC_PROG_RANLIB + +# Checks for libraries. + +# Checks for header files. +AC_HEADER_STDC + +# Checks for library functions. +WD_CHECK_LIB(mysqlclient, + mysql_real_connect, + [-lm], + [:], + [ AC_MSG_FAILURE([The required library libmysqlclient is not found or is unusable]) ], + [/usr/lib/mysql /usr/local/lib/mysql]) +LIBS="$LIBS $wd_cv_lib_mysqlclient" + +# Grecs subsystem + +GRECS_SETUP(grecs, [getopt git2chg parser-bind]) + +AC_CONFIG_FILES([Makefile + src/Makefile]) + +AC_OUTPUT diff --git a/grecs b/grecs new file mode 160000 +Subproject c8865a0d524f3d545836bd4581329089a357661 diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..26e1c2e --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,2 @@ +cmdline.h +nssync diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..4988a5c --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,42 @@ +# This file is part of NSsync +# Copyright (C) 2011 Sergey Poznyakoff +# +# NSsync is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# NSsync is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NSsync. If not, see <http://www.gnu.org/licenses/>. + +sbin_PROGRAMS = nssync +nssync_SOURCES = \ + config.c\ + nssync.c\ + nssync.h\ + output.c\ + sqlop.c + +LDADD=@GRECS_LDADD@ +INCLUDES = @GRECS_INCLUDES@ + +BUILT_SOURCES = cmdline.h +EXTRA_DIST = cmdline.h + +SUFFIXES=.opt .c .h + +.opt.h: + m4 -s $(top_srcdir)/grecs/build-aux/getopt.m4 $< | sed '1d' > $@ + +incdir=$(pkgdatadir)/$(VERSION)/include + +AM_CPPFLAGS= \ + -DSYSCONFDIR=\"$(sysconfdir)\"\ + -DDEFAULT_VERSION_INCLUDE_DIR=\"$(incdir)\"\ + -DDEFAULT_INCLUDE_DIR=\"$(pkgdatadir)/include\"\ + -DDEFAULT_PREPROCESSOR="$(DEFAULT_PREPROCESSOR)" diff --git a/src/cmdline.opt b/src/cmdline.opt new file mode 100644 index 0000000..5f246af --- /dev/null +++ b/src/cmdline.opt @@ -0,0 +1,146 @@ +/* This file is part of NSsync -*- c -*- + Copyright (C) 2011 Sergey Poznyakoff + + NSsync is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + NSsync is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NSsync. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_GETOPT_H +# include <getopt.h> +#endif +#include <unistd.h> + +static struct grecs_txtacc *pp_cmd_acc; +static char *program_name; + +OPTIONS_BEGIN("nssync", + [<Synchronize DLZ database with DNS configuration>], + [<>], + [<gnu>], + [<copyright_year=2011>], + [<copyright_holder=Sergey Poznyakoff>]) + +OPTION(lint,t,, + [<parse configuration file and exit>]) +BEGIN + lint_mode = 1; +END + +OPTION(,E,, + [<preprocess config and exit>]) +BEGIN + preprocess_only = 1; +END + +OPTION(dry-run,n,, + [<do nothing, print almost everything; implies `--debug --stderr', + use additional `--debug' options to get even more info>]) +BEGIN + debug_level++; + dry_run_mode = 1; +END + +OPTION(config-file,c,FILE, + [<use FILE instead of the default configuration>]) +BEGIN + config_file = optarg; +END + +GROUP(Preprocessor control) + +OPTION(include-directory,I,DIR, + [<add include directory>]) +BEGIN + grecs_preproc_add_include_dir(optarg); +END + +OPTION(define,D,SYMBOL[=VALUE], + [<define a preprocessor symbol>]) +BEGIN + char *p; + + if (!pp_cmd_acc) + pp_cmd_acc = grecs_txtacc_create(); + grecs_txtacc_grow(pp_cmd_acc, " \"-D", 4); + for (p = optarg; *p; p++) { + if (*p == '\\' || *p == '"') + grecs_txtacc_grow_char(pp_cmd_acc, '\\'); + grecs_txtacc_grow_char(pp_cmd_acc, *p); + } + grecs_txtacc_grow_char(pp_cmd_acc, '"'); +END + +OPTION(preprocessor,,COMMAND, + [<use COMMAND instead of the default preprocessor>]) +BEGIN + grecs_preprocessor = optarg; +END + +OPTION(no-preprocessor,,, + [<disable preprocessing>]) +BEGIN + grecs_preprocessor = NULL; +END + +GROUP(Debugging) + +OPTION(debug,d,, + [<increase debug level>]) +BEGIN + debug_level++; +END + +OPTION(debug-parser,x,, + [<debug configuration file parser>]) +BEGIN + grecs_gram_trace(1); +END + +OPTION(debug-lexer,X,, + [<debug configuration file lexer>]) +BEGIN + grecs_lex_trace(1); +END + +GROUP([<Additional help>]) +OPTION(config-help,,, + [<show configuration file summary>]) +BEGIN + config_help(); + exit(0); +END + +OPTIONS_END + +void +parse_options(int argc, char *argv[]) +{ + program_name = strrchr(argv[0], '/'); + if (program_name) + program_name++; + else + program_name = argv[0]; + + GETOPT(argc, argv,, exit(EX_USAGE)) + if (pp_cmd_acc && grecs_preprocessor) { + char *args, *cmd; + + grecs_txtacc_grow_char(pp_cmd_acc, 0); + args = grecs_txtacc_finish(pp_cmd_acc, 0); + cmd = grecs_malloc(strlen(grecs_preprocessor) + + strlen(args) + 1); + strcpy(cmd, grecs_preprocessor); + strcat(cmd, args); + grecs_preprocessor = cmd; + } + grecs_txtacc_free(pp_cmd_acc); +} diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..9cae3bc --- /dev/null +++ b/src/config.c @@ -0,0 +1,141 @@ +/* This file is part of NSsync + Copyright (C) 2011 Sergey Poznyakoff + + NSsync is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + NSsync is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NSsync. If not, see <http://www.gnu.org/licenses/>. */ + +#include "nssync.h" +#include <limits.h> + +char *soa_query; +char *rr_query; +char *rev_rr_query; +char *ns_query; + +static struct grecs_keyword nssync_kw[] = { + { "sql-config-file", + "file", "Read MySQL configuration from <file>", + grecs_type_string, &sql_config_file }, + { "sql-config-group", + "name", "Read the named group from the SQL configuration file", + grecs_type_string, &sql_config_group }, + { "host", + "host", "Set SQL server hostname or IP address", + grecs_type_string, &sql_host }, + { "database", + "dbname", "Set database name", + grecs_type_string, &database_name }, + { "user", + "name", "Set SQL user name", + grecs_type_string, &sql_user }, + { "password", + "arg", "Set SQL user password", + grecs_type_string, &sql_password }, + { "ssl-ca", + "file", "File name of the Certificate Authority (CA) certificate", + grecs_type_string, &sql_cacert }, + { "soa-query", + NULL, "Set query for retrieving SOA records", + grecs_type_string, &soa_query }, + { "ns-query", + NULL, "Set query for retrieving NS and similar records", + grecs_type_string, &ns_query }, + { "rr-query", + NULL, "Set query for retrieving the rest of RRs", + grecs_type_string, &rr_query }, + { "rev-rr-query", + NULL, "Set query for retrieving the RRs from reverse delegation zones", + grecs_type_string, &rev_rr_query }, + { NULL } +}; + +void +config_help() +{ + static char docstring[] = + N_("Configuration file structure for NSsync.\n"); + grecs_format_docstring(docstring, 0, stdout); + grecs_format_statement_array(nssync_kw, 1, 0, stdout); +} + +void +config_init() +{ + grecs_include_path_setup(DEFAULT_VERSION_INCLUDE_DIR, + DEFAULT_INCLUDE_DIR, NULL); + grecs_preprocessor = DEFAULT_PREPROCESSOR; + grecs_log_to_stderr = 1; +} + +static int +sql_host_fixup() +{ + char *p; + + if (!sql_host) + return 0; + p = strchr(sql_host, ':'); + if (p) { + *p++ = 0; + if (p[0] == '/') { + sql_socket = grecs_strdup (p); + grecs_free(sql_host); + sql_host = grecs_strdup ("localhost"); + } else { + char *end; + unsigned long n = strtoul(p, &end, 10); + if (*end) { + grecs_error (NULL, 0, + "invalid port number (near %s)", + end); + return 1; + } + if (n == 0 || n > USHRT_MAX) { + grecs_error (NULL, 0, + "port number out of range 1..%d", + USHRT_MAX); + return 1; + } + sql_port = n; + } + } + return 0; +} + +void +config_parse() +{ + int err = 0; + struct grecs_node *tree = grecs_parse(config_file); + if (!tree) + exit(EX_CONFIG); + grecs_tree_reduce(tree, nssync_kw, GRECS_AGGR); + if (grecs_tree_process(tree, nssync_kw)) + exit(EX_CONFIG); + grecs_tree_free(tree); + + if (sql_host_fixup()) + err = 1; + if (!rr_query) { + error("rr-query not defined"); + err = 1; + } + if (!soa_query) { + error("soa-query not defined"); + err = 1; + } + if (err) + exit(EX_CONFIG); + if (lint_mode) + exit(0); +} diff --git a/src/nssync.c b/src/nssync.c new file mode 100644 index 0000000..ce55bc4 --- /dev/null +++ b/src/nssync.c @@ -0,0 +1,58 @@ +/* This file is part of NSsync + Copyright (C) 2011 Sergey Poznyakoff + + NSsync is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + NSsync is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NSsync. If not, see <http://www.gnu.org/licenses/>. */ + +#include "nssync.h" + +#include "cmdline.h" + +int lint_mode; +int dry_run_mode; +int preprocess_only; +int debug_level; +char *config_file = SYSCONFDIR "/nssync.conf"; + +void +verror(const char *fmt, va_list ap) +{ + fprintf(stderr, "%s: ", program_name); + vfprintf(stderr, fmt, ap); + fputc('\n', stderr); +} + +void +error(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verror(fmt, ap); + va_end(ap); +} + +int +main(int argc, char **argv) +{ + config_init(); + parse_options(argc, argv); + if (preprocess_only) + exit(grecs_preproc_run(config_file, grecs_preprocessor) ? + EX_CONFIG : 0); + config_parse(); + sql_connect(); + format_soa(); + //FIXME + + exit(0); +} diff --git a/src/nssync.h b/src/nssync.h new file mode 100644 index 0000000..aef5fa4 --- /dev/null +++ b/src/nssync.h @@ -0,0 +1,67 @@ +/* This file is part of NSsync + Copyright (C) 2011 Sergey Poznyakoff + + NSsync is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + NSsync is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NSsync. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sysexits.h> + +#include <grecs.h> +#include <wordsplit.h> +#include <mysql/mysql.h> + +extern int lint_mode; +extern int dry_run_mode; +extern int preprocess_only; +extern int debug_level; +extern char *config_file; + +extern char *sql_config_file; +extern char *sql_config_group; +extern char *database_name; +extern char *sql_host; +extern char *sql_socket; +extern char *sql_user; +extern char *sql_password; +extern char *sql_cacert; +extern int sql_port; + +extern char *soa_query; +extern char *ns_query; +extern char *rr_query; +extern char *rev_rr_query; + +#ifndef __PRINTFLIKE +# define __PRINTFLIKE(fmt,narg) __attribute__ ((__format__ (__printf__, fmt, narg))) +#endif + +void config_init(void); +void config_parse(void); +void config_help(void); + +void verror(const char *fmt, va_list ap); +void error(const char *fmt, ...) __PRINTFLIKE(1,2); + +void sql_connect(void); +void sql_disconnect(void); +int sql_do_query(const char *query, + int (*fun)(MYSQL_ROW, unsigned, void*), void *data); + + + diff --git a/src/output.c b/src/output.c new file mode 100644 index 0000000..3a6ba35 --- /dev/null +++ b/src/output.c @@ -0,0 +1,163 @@ +/* This file is part of NSsync + Copyright (C) 2011 Sergey Poznyakoff + + NSsync is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + NSsync is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NSsync. If not, see <http://www.gnu.org/licenses/>. */ + +#include "nssync.h" + +#define S(s) ((s) ? (s) : NULL) + +enum { + f_ns_ttl, + f_ns_type, + f_ns_data, + _ns_nfields +}; + +int +format_ns_record(MYSQL_ROW row, unsigned nf, void *data) +{ + if (nf != _ns_nfields) { + error("NS query returned wrong number of fields"); + return 1; + } + /* FIXME: TTL */ + printf("\t%s\t%s\n", + row[f_ns_type], row[f_ns_data]); + return 0; +} + + +enum { + f_rr_host, + f_rr_ttl, + f_rr_type, + f_rr_priority, + f_rr_data, + _rr_nfields +}; + +int +format_rr_record(MYSQL_ROW row, unsigned nf, void *data) +{ + if (nf != _rr_nfields) { + error("RR query returned wrong number of fields"); + return 1; + } + if (!row[f_rr_type]) + return 0; + if (strcasecmp(row[f_rr_type], "MX") == 0) + printf("%s\t%s\tMX\t%s\t%s\n", + row[f_rr_host], S(row[f_rr_ttl]), + row[f_rr_priority], row[f_rr_data]); + else + printf("%s\t%s\t%s\t%s\n", + row[f_rr_host], S(row[f_rr_ttl]), + row[f_rr_type], row[f_rr_data]); + return 0; +} + + +enum { + f_soa_zone, + f_soa_ttl, + f_soa_type, + f_soa_data, + f_soa_person, + f_soa_serial, + f_soa_refresh, + f_soa_retry, + f_soa_expire, + f_soa_minimum, + _soa_nfields +}; + +int +is_reverse_zone(const char *str) +{ + static char suffix[] = ".in-addr.arpa"; + size_t len = strlen(str); + + return len > sizeof(suffix) && + strcasecmp(str + len - sizeof(suffix) + 1, suffix) == 0; +} + +int +format_soa_record(MYSQL_ROW row, unsigned nf, void *data) +{ + struct wordsplit ws; + const char *env[3]; + + if (nf != _soa_nfields) { + error("SOA query returned wrong number of fields"); + return 1; + } + if (!row[f_soa_type]) + return 0; + printf("$ORIGIN .\n"); + if (row[f_soa_ttl]) + printf("$TTL %s\n", row[f_soa_ttl]); + printf("%s %s IN SOA %s %s (\n" + "\t%s ; Serial\n" + "\t%s ; Refresh\n" + "\t%s ; Retry\n" + "\t%s ; Expire\n" + "\t%s) ; Minimum\n", + row[f_soa_zone], + S(row[f_soa_ttl]), + row[f_soa_data], + row[f_soa_person], + row[f_soa_serial], + row[f_soa_refresh], + row[f_soa_retry], + row[f_soa_expire], + row[f_soa_minimum]); + + env[0] = "zone"; + env[1] = row[f_soa_zone]; + env[2] = 0; + + ws.ws_env = env; + if (wordsplit(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, NULL)) + exit(EX_UNAVAILABLE); + + if (wordsplit((rev_rr_query && is_reverse_zone(row[f_soa_zone])) ? + rev_rr_query : rr_query, &ws, + WRDSF_NOCMD | WRDSF_ENV | WRDSF_ENV_KV | WRDSF_NOSPLIT | + WRDSF_KEEPUNDEF | WRDSF_REUSE)) { + error("cannot split rr_query: %s", wordsplit_strerror(&ws)); + exit(EX_SOFTWARE); + } + + if (sql_do_query(ws.ws_wordv[0], format_rr_record, NULL)) + exit(EX_UNAVAILABLE); + + wordsplit_free(&ws); + + return 0; +} + +void +format_soa() +{ + if (sql_do_query(soa_query, format_soa_record, NULL)) + exit(EX_UNAVAILABLE); +} diff --git a/src/sqlop.c b/src/sqlop.c new file mode 100644 index 0000000..eb3f543 --- /dev/null +++ b/src/sqlop.c @@ -0,0 +1,94 @@ +/* This file is part of NSsync + Copyright (C) 2011 Sergey Poznyakoff + + NSsync is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + NSsync is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with NSsync. If not, see <http://www.gnu.org/licenses/>. */ + +#include "nssync.h" + +char *sql_config_file; +char *sql_config_group; +char *database_name; +char *sql_host; +char *sql_socket; +char *sql_user; +char *sql_password; +char *sql_cacert; +int sql_port; + +MYSQL mysql; + +void +sql_connect() +{ + mysql_init(&mysql); + + if (sql_config_file) + mysql_options(&mysql, MYSQL_READ_DEFAULT_FILE, + sql_config_file); + if (sql_config_group) + mysql_options(&mysql, MYSQL_READ_DEFAULT_GROUP, + sql_config_group); + + if (sql_cacert) + mysql_ssl_set(&mysql, NULL, NULL, sql_cacert, NULL, NULL); + if (!mysql_real_connect(&mysql, sql_host, sql_user, + sql_password, database_name, sql_port, + sql_socket, CLIENT_MULTI_RESULTS)) { + error("failed to connect to database: %s", + mysql_error(&mysql)); + exit(EX_UNAVAILABLE); + } + atexit(sql_disconnect); +} + +void +sql_disconnect() +{ + mysql_close(&mysql); +} + +int +sql_do_query(const char *query, + int (*fun)(MYSQL_ROW, unsigned, void*), void *data) +{ + if (mysql_query(&mysql, query)) { + error("%s", mysql_error(&mysql)); + error("in query: %s", query); + return 1; + } + + do { + MYSQL_ROW row; + MYSQL_RES *res; + unsigned n; + + res = mysql_store_result(&mysql); + if (!res) { + error("cannot get result: %s", mysql_error(&mysql)); + error("in query: %s", query); + return 1; + } + + n = mysql_num_fields(res); + + while (row = mysql_fetch_row(res)) + if (fun(row, n, data)) + break; + mysql_free_result(res); + } while (mysql_next_result(&mysql) == 0); + + return 0; +} + + |