summaryrefslogtreecommitdiff
path: root/dns
diff options
context:
space:
mode:
authorGabor Kovesdan <gabor@FreeBSD.org>2007-01-12 23:49:04 +0000
committerGabor Kovesdan <gabor@FreeBSD.org>2007-01-12 23:49:04 +0000
commit69cfea92dc933e2f216c9c0fd90c111556d5176e (patch)
tree74ac223ba88fecbe14a235038ed11eb3bcb35182 /dns
parent(forced commit) (diff)
- Add support for geo backend
- Add support for OpenDBX backend - OPTIONify - Bump PORTREVISION PR: ports/96891 Submitted by: Ralf van der Enden <tremere@cainites.net> (maintainer) Approved by: erwin (mentor)
Notes
Notes: svn path=/head/; revision=182255
Diffstat (limited to 'dns')
-rw-r--r--dns/powerdns-devel/Makefile104
-rw-r--r--dns/powerdns-devel/Makefile.inc1
-rw-r--r--dns/powerdns-devel/files/configure.powerdns70
-rw-r--r--dns/powerdns-devel/files/patch-opendbx1038
-rw-r--r--dns/powerdns-devel/files/pdns.conf26
-rw-r--r--dns/powerdns-devel/files/pdns.in5
-rw-r--r--dns/powerdns-devel/files/pdns_mysql.sql80
-rw-r--r--dns/powerdns-devel/files/pdns_postgresql.sql76
-rw-r--r--dns/powerdns-devel/files/pdns_recursor.in35
-rw-r--r--dns/powerdns-devel/files/pdns_sqlite.sql60
-rw-r--r--dns/powerdns-devel/files/pkg-message.in7
-rw-r--r--dns/powerdns-devel/pkg-plist33
-rw-r--r--dns/powerdns/Makefile104
-rw-r--r--dns/powerdns/Makefile.inc1
-rw-r--r--dns/powerdns/files/configure.powerdns70
-rw-r--r--dns/powerdns/files/patch-opendbx1038
-rw-r--r--dns/powerdns/files/pdns.conf26
-rw-r--r--dns/powerdns/files/pdns.in3
-rw-r--r--dns/powerdns/files/pdns_mysql.sql80
-rw-r--r--dns/powerdns/files/pdns_postgresql.sql76
-rw-r--r--dns/powerdns/files/pdns_recursor.in35
-rw-r--r--dns/powerdns/files/pdns_sqlite.sql60
-rw-r--r--dns/powerdns/files/pkg-message.in7
-rw-r--r--dns/powerdns/pkg-plist33
24 files changed, 2529 insertions, 539 deletions
diff --git a/dns/powerdns-devel/Makefile b/dns/powerdns-devel/Makefile
index 2aacd90397e1..0fdfc7628786 100644
--- a/dns/powerdns-devel/Makefile
+++ b/dns/powerdns-devel/Makefile
@@ -7,14 +7,14 @@
PORTNAME= powerdns
PORTVERSION= 2.9.20
-PORTREVISION= 1
+PORTREVISION= 2
CATEGORIES= dns ipv6
MASTER_SITES= http://downloads.powerdns.com/releases/ \
http://mirrors.evolva.ro/powerdns.com/releases/
DISTNAME= pdns-${PORTVERSION}
MAINTAINER= tremere@cainites.net
-COMMENT= An advanced DNS server with SQL backend
+COMMENT= An advanced DNS server with multiple backends including SQL
BUILD_DEPENDS= bjam:${PORTSDIR}/devel/boost
@@ -25,8 +25,9 @@ USE_LDCONFIG= YES
CXXFLAGS+= -I${LOCALBASE}/include
LDFLAGS+= -L${LOCALBASE}/lib
CONFIGURE_TARGET= --build=${MACHINE_ARCH}-portbld-freebsd${OSREL}
-CONFIGURE_ARGS+= --with-modules="${CONFIGURE_MODULES} pipe" \
- --with-dynmodules=""
+CONFIGURE_ARGS+= --with-modules="pipe" \
+ --with-dynmodules="${CONFIGURE_MODULES}" \
+ --sysconfdir="${PREFIX}/etc/pdns"
# --enable-debug
SCRIPTS_ENV= WRKDIRPREFIX="${WRKDIRPREFIX}" \
CURDIR2="${.CURDIR}" \
@@ -37,97 +38,88 @@ MAN8= pdns_control.8 pdns_server.8 zone2sql.8
SUB_FILES= pkg-message
+OPTIONS= PGSQL "PostgreSQL backend" on \
+ MYSQL "MySQL backend" off \
+ SQLITE "SQLite 2 backend" off \
+ SQLITE3 "SQLite 3 backend" off \
+ OPENDBX "OpenDBX backend" off \
+ OPENLDAP "OpenLDAP backend" off \
+ GEO "Geo backend" off
+
.include <bsd.port.pre.mk>
USE_RC_SUBR+= pdns
-# use user config if possible
-.if exists(${WRKDIRPREFIX}${.CURDIR}/Makefile.inc)
-.include "${WRKDIRPREFIX}${.CURDIR}/Makefile.inc"
+.if defined(WITH_GEO)
+CONFIGURE_MODULES+= "geo"
+PLIST_SUB+= WITHGEO=""
.else
-.if defined(BATCH)
-# default package, can be configured in /etc/make.conf
-POWERDNS_OPTIONS?= \"PostgreSQL\"
+PLIST_SUB+= WITHGEO="@comment "
.endif
-# make INDEX match
-NO_DESCRIBE=yes
+
+.if defined(WITH_SQLITE) && defined(WITH_SQLITE3)
+BROKEN= choose only one SQLite backend version
.endif
-.if defined(WITH_POSTGRESQL_DRIVER) && !defined(WITHOUT_POSTGRESQL_DRIVER)
-LIB_DEPENDS+= pq[+][+].4:${PORTSDIR}/databases/postgresql-libpq++
-CONFIGURE_ARGS+= --enable-pgsql --with-pgsql-includes=${LOCALBASE}/include
+.if defined(WITH_PGSQL)
+USE_PGSQL?= YES
CONFIGURE_MODULES+= "gpgsql"
-CFLAGS+= -DDLLIMPORT=""
+PLIST_SUB+= WITHPGSQL=""
.else
CONFIGURE_ARGS+= --disable-pgsql
+PLIST_SUB+= WITHPGSQL="@comment "
.endif
-.if defined(WITH_MYSQL_DRIVER)
+.if defined(WITH_MYSQL)
USE_MYSQL?= YES
-CONFIGURE_ARGS+= --enable-mysql --with-mysql-includes=${LOCALBASE}
CONFIGURE_MODULES+= "gmysql"
+CXXFLAGS+= -I${LOCALBASE}/include/mysql
+LDFLAGS+= -L${LOCALBASE}/lib/mysql
PLIST_SUB+= WITHMYSQL=""
.else
CONFIGURE_ARGS+= --disable-mysql
PLIST_SUB+= WITHMYSQL="@comment "
.endif
-.if defined(WITH_LDAP)
+.if defined(WITH_OPENLDAP)
USE_OPENLDAP?= YES
CONFIGURE_MODULES+= "ldap"
-PLIST_SUB+= WITHLDAP=""
CXXFLAGS+= -L${LOCALBASE}/lib -DLDAP_DEPRECATED=1
+PLIST_SUB+= WITHOPENLDAP=""
.else
-PLIST_SUB+= WITHLDAP="@comment "
+PLIST_SUB+= WITHOPENLDAP="@comment "
.endif
.if defined(WITH_SQLITE)
-LIB_DEPENDS+= sqlite.2:${PORTSDIR}/databases/sqlite2
-CONFIGURE_ARGS+= --enable-sqlite
+USE_SQLITE?= 2
CONFIGURE_MODULES+= "gsqlite"
-PLIST_SUB+= WITHSQLLITE=""
+PLIST_SUB+= WITHSQLITE=""
.else
-CONFIGURE_ARGS+= --disable-sqlite
-PLIST_SUB+= WITHSQLLITE="@comment "
+PLIST_SUB+= WITHSQLITE="@comment "
.endif
-.if defined(POWERDNS_WITH_RECURSOR)
-USE_RC_SUBR+= pdns_recursor
-CONFIGURE_ARGS+= --enable-recursor
-PLIST_SUB+= RECURSOR=""
+.if defined(WITH_SQLITE3)
+USE_SQLITE?= 3
+CONFIGURE_MODULES+= "gsqlite"
+PLIST_SUB+= WITHSQLITE3=""
.else
-PLIST_SUB+= RECURSOR="@comment "
+PLIST_SUB+= WITHSQLITE3="@comment "
.endif
-.if defined(POWERDNS_WITH_RECURSOR)
-.if exists(/usr/include/ucontext.h) && ${OSVERSION} >= 500000
-UCONTEXT!= ${AWK} '/setcontext/ { print "YES" }' \
- /usr/include/ucontext.h
-.if ${UCONTEXT} == ""
-BROKEN= setcontext for recursor not found or FreeBSD version lower than 5.0
-.endif
-.endif
+.if defined(WITH_OPENDBX)
+LIB_DEPENDS+= opendbx.1:${PORTSDIR}/databases/opendbx
+CONFIGURE_MODULES+= "opendbx"
+PLIST_SUB+= WITHOPENDBX=""
+CXXFLAGS+= -L${LOCALBASE}/lib
+.else
+PLIST_SUB+= WITHOPENDBX="@comment "
.endif
.if ${OSVERSION} < 500039
USE_GCC=3.4
.endif
-.if defined(NO_DESCRIBE)
-describe:
-.if defined(BATCH)
- @ ${SETENV} ${SCRIPTS_ENV} ${SH} ${FILESDIR}/configure.powerdns
-.endif
- @cd ${.CURDIR} && ${MAKE} ${__softMAKEFLAGS} BATCH=yes ${.TARGET}
-.endif
-
-pre-everything::
- @ ${SETENV} ${SCRIPTS_ENV} ${SH} ${FILESDIR}/configure.powerdns
-
-post-clean:
- @ ${RM} -f ${WRKDIRPREFIX}${.CURDIR}/Makefile.inc
-
-.if defined(WITH_LDAP)
+.if defined(WITH_OPENLDAP)
post-patch:
${REINPLACE_CMD} -e 's;-I. ;-I. -I${LOCALBASE}/include ;' \
-e 's;la_LDFLAGS =;la_LDFLAGS = -L${LOCALBASE}/lib;' \
@@ -138,8 +130,8 @@ post-patch:
.endif
post-install:
-.if !exists(${PREFIX}/etc/pdns.conf)
- ${INSTALL_DATA} ${PREFIX}/etc/pdns.conf-dist ${PREFIX}/etc/pdns.conf
+.if !exists(${PREFIX}/etc/pdns/pdns.conf)
+ ${INSTALL_DATA} ${PREFIX}/etc/pdns/pdns.conf-dist ${PREFIX}/etc/pdns/pdns.conf
.endif
.if !defined(NOPORTDOCS)
${MKDIR} ${EXAMPLESDIR}
diff --git a/dns/powerdns-devel/Makefile.inc b/dns/powerdns-devel/Makefile.inc
index d7c17dcb1920..e69de29bb2d1 100644
--- a/dns/powerdns-devel/Makefile.inc
+++ b/dns/powerdns-devel/Makefile.inc
@@ -1 +0,0 @@
-WITH_POSTGRESQL_DRIVER=YES
diff --git a/dns/powerdns-devel/files/configure.powerdns b/dns/powerdns-devel/files/configure.powerdns
deleted file mode 100644
index 43c9b3e1e685..000000000000
--- a/dns/powerdns-devel/files/configure.powerdns
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh
-#
-# $FreeBSD$
-#
-if [ -f ${WRKDIRPREFIX}${CURDIR2}/Makefile.inc ]; then
- exit
-fi
-
-if [ "${POWERDNS_OPTIONS}" ]; then
- set ${POWERDNS_OPTIONS}
-else
- dialog --title "configuration options" --clear \
- --checklist "\n\
-Please select desired options:" -1 -1 8 \
-PostgreSQL "PostgreSQL driver" ON \
-MySQL "MySQL driver" OFF \
-OpenLDAP "OpenLDAP backend" OFF \
-SQLite "SQLite backend" OFF \
-Recursor "Build Recursor (DEPRECATED)" OFF \
-2> /tmp/checklist.tmp.$$
-
- retval=$?
- if [ -s /tmp/checklist.tmp.$$ ]; then
- set `cat /tmp/checklist.tmp.$$`
- fi
- rm -f /tmp/checklist.tmp.$$
-
- case $retval in
- 0) if [ -z "$*" ]; then
- echo "Nothing selected"
- fi
- ;;
- 1) echo "Cancel pressed."
- exit 1
- ;;
- esac
-fi
-
-${MKDIR} ${WRKDIRPREFIX}${CURDIR2}
-exec > ${WRKDIRPREFIX}${CURDIR2}/Makefile.inc
-
-while [ "$1" ]; do
- case $1 in
- \"PostgreSQL\")
- echo WITH_POSTGRESQL_DRIVER=YES
- ;;
- \"MySQL\")
- echo WITH_MYSQL_DRIVER=YES
- ;;
- \"OpenLDAP\")
- echo WITH_LDAP=YES
- ;;
- \"SQLite\")
- echo WITH_SQLITE=YES
- echo SQLITE_PORT?=databases/sqlite
- ;;
- \"Recursor\")
- echo POWERDNS_WITH_RECURSOR=YES
- ;;
- \"nothing\"|true)
- ;;
- *)
- echo "Invalid option(s): $*" > /dev/stderr
- rm -f ${WRKDIRPREFIX}${CURDIR2}/Makefile.inc
- exit 1
- ;;
- esac
- shift
-done
-exec > /dev/stderr
diff --git a/dns/powerdns-devel/files/patch-opendbx b/dns/powerdns-devel/files/patch-opendbx
new file mode 100644
index 000000000000..3f24a01e82b4
--- /dev/null
+++ b/dns/powerdns-devel/files/patch-opendbx
@@ -0,0 +1,1038 @@
+--- modules/opendbxbackend/odbxbackend.hh 2006-03-15 19:29:39.000000000 +0100
++++ modules/opendbxbackend/odbxbackend.hh 2006-09-03 11:34:13.000000000 +0200
+@@ -1,11 +1,10 @@
+ /*
+ * PowerDNS OpenDBX Backend
+- * Copyright (C) 2005 Norbert Sendetzky <norbert@linuxnetworks.de>
++ * Copyright (C) 2005-2006 Norbert Sendetzky <norbert@linuxnetworks.de>
+ *
+ * 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 2 of the License, or
+- * any later version.
++ * it under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+@@ -14,7 +13,7 @@
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+@@ -32,7 +31,6 @@
+ #include <pdns/arguments.hh>
+ #include <pdns/logger.hh>
+ #include <odbx.h>
+-#include "modules/ldapbackend/utils.hh"
+
+
+ #ifndef ODBXBACKEND_HH
+@@ -53,19 +51,23 @@
+
+ class OdbxBackend : public DNSBackend
+ {
++ enum QueryType { READ, WRITE };
++
+ string m_myname;
+ string m_qname;
+ int m_default_ttl;
+ bool m_qlog;
+- odbx_t* m_handle;
++ odbx_t* m_handle[2];
+ odbx_result_t* m_result;
+ char m_escbuf[BUFLEN];
+ char m_buffer[2*BUFLEN];
++ vector<string> m_hosts[2];
+
+- bool getRecord();
+- void execStmt( const char* stmt, unsigned long length, bool select );
+- void getDomainList( const string& query, vector<DomainInfo>* list, bool (*check_fcn)(u_int32_t,u_int32_t,SOAData*,DomainInfo*) );
+- string escape( const string& str );
++ string escape( const string& str, QueryType type );
++ bool connectTo( const vector<string>& host, QueryType type );
++ bool getDomainList( const string& query, vector<DomainInfo>* list, bool (*check_fcn)(u_int32_t,u_int32_t,SOAData*,DomainInfo*) );
++ bool execStmt( const char* stmt, unsigned long length, QueryType type );
++ bool getRecord( QueryType type );
+
+
+ public:
+@@ -107,37 +109,40 @@
+ void declareArguments( const string &suffix="" )
+ {
+ declare( suffix, "backend", "OpenDBX backend","mysql" );
+- declare( suffix, "host", "Name or address of one or more DBMS server","127.0.0.1" );
+- declare( suffix, "port", "Port the DBMS server is listening to","" );
++ declare( suffix, "host-read", "Name or address of one or more DBMS server to read from","127.0.0.1" );
++ declare( suffix, "host-write", "Name or address of one or more DBMS server used for updates","127.0.0.1" );
++ declare( suffix, "port", "Port the DBMS server are listening to","" );
+ declare( suffix, "database", "Database name containing the DNS records","powerdns" );
+ declare( suffix, "username","User for connecting to the DBMS","powerdns");
+ declare( suffix, "password","Password for connecting to the DBMS","");
+
+- declare( suffix, "sql-list", "AXFR query", "SELECT domain_id, name, type, ttl, prio, content FROM records WHERE domain_id=':id'" );
++ declare( suffix, "sql-list", "AXFR query", "SELECT domain_id, name, type, ttl, prio, content FROM records WHERE domain_id=:id" );
+
+ declare( suffix, "sql-lookup", "Lookup query","SELECT domain_id, name, type, ttl, prio, content FROM records WHERE name=':name'" );
+- declare( suffix, "sql-lookupid", "Lookup query with id","SELECT domain_id, name, type, ttl, prio, content FROM records WHERE domain_id=':id' AND name=':name'" );
++ declare( suffix, "sql-lookupid", "Lookup query with id","SELECT domain_id, name, type, ttl, prio, content FROM records WHERE domain_id=:id AND name=':name'" );
+ declare( suffix, "sql-lookuptype", "Lookup query with type","SELECT domain_id, name, type, ttl, prio, content FROM records WHERE name=':name' AND type=':type'" );
+- declare( suffix, "sql-lookuptypeid", "Lookup query with type and id","SELECT domain_id, name, type, ttl, prio, content FROM records WHERE domain_id=':id' AND name=':name' AND type=':type'" );
++ declare( suffix, "sql-lookuptypeid", "Lookup query with type and id","SELECT domain_id, name, type, ttl, prio, content FROM records WHERE domain_id=:id AND name=':name' AND type=':type'" );
+
+- declare( suffix, "sql-zonedelete","Delete all records for this zone","DELETE FROM records WHERE domain_id=':id'" );
+- declare( suffix, "sql-zoneinfo","Get domain info","SELECT d.id, d.name, d.type, d.master, d.last_check, r.content FROM domains AS d LEFT JOIN records AS r ON d.id=r.domain_id WHERE ( d.name=':name' AND r.type='SOA' ) OR ( d.name=':name' AND r.domain_id IS NULL )" );
++ declare( suffix, "sql-zonedelete","Delete all records for this zone","DELETE FROM records WHERE domain_id=:id" );
++ declare( suffix, "sql-zoneinfo","Get domain info","SELECT d.id, d.name, d.type, d.master, d.last_check, r.content FROM domains d LEFT JOIN records r ON ( d.id=r.domain_id AND r.type='SOA' ) WHERE d.name=':name' AND d.status='A'" );
+
+ declare( suffix, "sql-transactbegin", "Start transaction", "BEGIN" );
+ declare( suffix, "sql-transactend", "Finish transaction", "COMMIT" );
+ declare( suffix, "sql-transactabort", "Abort transaction", "ROLLBACK" );
+
+ declare( suffix, "sql-insert-slave","Add slave domain", "INSERT INTO domains ( name, type, master, account ) VALUES ( '%s', 'SLAVE', '%s', '%s' )" );
+- declare( suffix, "sql-insert-record","Feed record into table", "INSERT INTO records ( domain_id, name, type, ttl, prio, content ) VALUES ( '%d', '%s', '%s', '%d', '%d', '%s' )" );
++ declare( suffix, "sql-insert-record","Feed record into table", "INSERT INTO records ( domain_id, name, type, ttl, prio, content ) VALUES ( %d, '%s', '%s', %d, %d, '%s' )" );
+
+- declare( suffix, "sql-update-serial", "Set zone to notified", "UPDATE domains SET notified_serial='%d' WHERE id='%d'" );
+- declare( suffix, "sql-update-lastcheck", "Set time of last check", "UPDATE domains SET last_check='%d' WHERE id='%d'" );
++ declare( suffix, "sql-update-serial", "Set zone to notified", "UPDATE domains SET notified_serial=%d WHERE id=%d" );
++ declare( suffix, "sql-update-lastcheck", "Set time of last check", "UPDATE domains SET last_check=%d WHERE id=%d" );
+
+- declare( suffix, "sql-master", "Get master record for zone", "SELECT master FROM domains WHERE name=':name' AND type='SLAVE'" );
++ declare( suffix, "sql-master", "Get master record for zone", "SELECT master FROM domains WHERE name=':name' AND status='A' AND type='SLAVE'" );
+ declare( suffix, "sql-supermaster","Get supermaster info", "SELECT account FROM supermasters WHERE ip=':ip' AND nameserver=':ns'" );
+
+- declare( suffix, "sql-infoslaves", "Get all unfresh slaves", "SELECT d.id, d.name, d.master, d.notified_serial, d.last_check, r.change_date, r.content FROM domains AS d LEFT JOIN records AS r ON d.id=r.domain_id WHERE ( d.type='SLAVE' AND r.type='SOA' ) OR ( d.type='SLAVE' AND r.domain_id IS NULL )" );
+- declare( suffix, "sql-infomasters", "Get all updated masters", "SELECT d.id, d.name, d.master, d.notified_serial, d.last_check, r.change_date, r.content FROM domains AS d, records AS r WHERE d.type='MASTER' AND d.id=r.domain_id AND r.type='SOA'" );
++ declare( suffix, "sql-infoslaves", "Get all unfresh slaves", "SELECT d.id, d.name, d.master, d.notified_serial, d.last_check, r.change_date, r.content FROM domains d LEFT JOIN records r ON ( d.id=r.domain_id AND r.type='SOA' ) WHERE d.status='A' AND d.type='SLAVE'" );
++ declare( suffix, "sql-infomasters", "Get all updated masters", "SELECT d.id, d.name, d.master, d.notified_serial, d.last_check, r.change_date, r.content FROM domains d JOIN records r ON d.id=r.domain_id WHERE d.status='A' AND d.type='MASTER' AND r.type='SOA'" );
++
++ declare( suffix, "host", "depricated, use host-read and host-write instead","" );
+ }
+
+
+--- modules/opendbxbackend/odbxbackend.cc 2006-03-15 19:29:39.000000000 +0100
++++ modules/opendbxbackend/odbxbackend.cc 2006-06-17 11:39:04.000000000 +0200
+@@ -2,62 +2,80 @@
+
+
+
+-unsigned int odbx_host_index = 0;
++inline string& strbind( const string& search, const string& replace, string& subject )
++{
++ size_t pos = 0;
++
++ while( ( pos = subject.find( search, pos ) ) != string::npos )
++ {
++ subject.replace( pos, search.size(), replace );
++ pos += replace.size();
++ }
++
++ return subject;
++}
++
++
++
++inline string& toLowerByRef( string& str )
++{
++ for( unsigned int i = 0; i < str.length(); i++ )
++ {
++ str[i] = dns_tolower( str[i] );
++ }
++
++ return str;
++}
+
+
+
+ OdbxBackend::OdbxBackend( const string& suffix )
+ {
+- int err = -1;
+- unsigned int idx, i, h;
+ vector<string> hosts;
+
+
+ try
+ {
+ m_result = NULL;
++ m_handle[READ] = NULL;
++ m_handle[WRITE] = NULL;
+ m_myname = "[OpendbxBackend]";
+ m_default_ttl = arg().asNum( "default-ttl" );
+ m_qlog = arg().mustDo( "query-logging" );
+
+ setArgPrefix( "opendbx" + suffix );
+- stringtok( hosts, getArg( "host" ), ", " );
+
+- idx = odbx_host_index++ % hosts.size();
+-
+- for( i = 0; i < hosts.size(); i++ )
++ if( getArg( "host" ).size() > 0 )
+ {
+- h = ( idx + i ) % hosts.size();
+- if( !( err = odbx_init( &m_handle, getArg( "backend" ).c_str(), hosts[h].c_str(), getArg( "port" ).c_str() ) ) ) { break; }
++ L.log( m_myname + " WARNING: Using depricated opendbx-host parameter", Logger::Warning );
++ stringtok( m_hosts[READ], getArg( "host" ), ", " );
++ m_hosts[WRITE] = m_hosts[READ];
+ }
+-
+- if( err < 0 )
++ else
+ {
+- L.log( m_myname + " OdbxBackend: Unable to connect to server - " + string( odbx_error( m_handle, err ) ), Logger::Error );
+- throw( AhuException( "Fatal: odbx_init() failed" ) );
++ stringtok( m_hosts[READ], getArg( "host-read" ), ", " );
++ stringtok( m_hosts[WRITE], getArg( "host-write" ), ", " );
+ }
+
+- if( ( err = odbx_bind_simple( m_handle, getArg( "database" ).c_str(), getArg( "username" ).c_str(), getArg( "password" ).c_str() ) ) < 0 )
+- {
+- L.log( m_myname + " OdbxBackend: Unable to bind to database - " + string( odbx_error( m_handle, err ) ), Logger::Error );
+- throw( AhuException( "Fatal: odbx_bind_simple() failed" ) );
+- }
++ if( !connectTo( m_hosts[READ], READ ) ) { throw( AhuException( "Fatal: Connecting to server for reading failed" ) ); }
++ if( !connectTo( m_hosts[WRITE], WRITE ) ) { throw( AhuException( "Fatal: Connecting to server for writing failed" ) ); }
+ }
+ catch( exception& e )
+ {
+- L.log( m_myname + " OdbxBackend: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Fatal: STL exception" ) );
++ L.log( m_myname + " OdbxBackend(): Caught STL exception - " + e.what(), Logger::Error );
++ throw( AhuException( "Fatal: STL exception" ) );
+ }
+-
+- L.log( m_myname + " Connection succeeded", Logger::Notice );
+ }
+
+
+
+ OdbxBackend::~OdbxBackend()
+ {
+- odbx_unbind( m_handle );
+- odbx_finish( m_handle );
++ odbx_unbind( m_handle[WRITE] );
++ odbx_unbind( m_handle[READ] );
++
++ odbx_finish( m_handle[WRITE] );
++ odbx_finish( m_handle[READ] );
+ }
+
+
+@@ -65,17 +83,17 @@
+ bool OdbxBackend::getDomainInfo( const string& domain, DomainInfo& di )
+ {
+ const char* tmp;
+- string stmt;
+
+
+ try
+ {
+ DLOG( L.log( m_myname + " getDomainInfo()", Logger::Debug ) );
+
+- stmt = strbind( ":name", escape( toLower( domain ) ), getArg( "sql-zoneinfo" ) );
+- execStmt( stmt.c_str(), stmt.size(), true );
++ string stmt = getArg( "sql-zoneinfo" );
++ string& stmtref = strbind( ":name", escape( toLower( domain ), READ ), stmt );
+
+- if( !getRecord() ) { return false; }
++ if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
++ if( !getRecord( READ ) ) { return false; }
+
+ do
+ {
+@@ -95,7 +113,7 @@
+
+ if( ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
+ {
+- di.zone = string( tmp );
++ di.zone = string( tmp, odbx_field_length( m_result, 1 ) );
+ }
+
+ if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
+@@ -112,7 +130,7 @@
+
+ if( ( tmp = odbx_field_value( m_result, 3 ) ) != NULL )
+ {
+- di.master = string( tmp );
++ di.master = string( tmp, odbx_field_length( m_result, 3 ) );
+ }
+
+ if( ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
+@@ -125,16 +143,16 @@
+ SOAData sd;
+
+ sd.serial = 0;
+- DNSPacket::fillSOAData( string( tmp ), sd );
++ DNSPacket::fillSOAData( string( tmp, odbx_field_length( m_result, 6 ) ), sd );
+ di.serial = sd.serial;
+ }
+ }
+- while( getRecord() );
++ while( getRecord( READ ) );
+ }
+ catch( exception& e )
+ {
+ L.log( m_myname + " getDomainInfo: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+@@ -144,11 +162,6 @@
+
+ bool OdbxBackend::list( const string& target, int zoneid )
+ {
+- string stmt;
+- size_t len;
+-
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " list()", Logger::Debug ) );
+@@ -156,22 +169,29 @@
+ m_qname = "";
+ m_result = NULL;
+
+- len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
++ size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ if( len < 0 )
+ {
+- L.log( m_myname + " list: Unable to convert zone id to string", Logger::Error );
+- throw( DBException( "Error: Libc error" ) );
++ L.log( m_myname + " list: Unable to convert zone id to string - format error", Logger::Error );
++ return false;
+ }
+
+- stmt = strbind( ":id", string( m_buffer, len ), getArg( "sql-list" ) );
++ if( len > sizeof( m_buffer ) - 1 )
++ {
++ L.log( m_myname + " list: Unable to convert zone id to string - insufficient buffer space", Logger::Error );
++ return false;
++ }
++
++ string stmt = getArg( "sql-list" );
++ string& stmtref = strbind( ":id", string( m_buffer, len ), stmt );
+
+- execStmt( stmt.c_str(), stmt.size(), true );
++ if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
+ }
+ catch( exception& e )
+ {
+ L.log( m_myname + " list: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+@@ -181,23 +201,24 @@
+
+ void OdbxBackend::lookup( const QType& qtype, const string& qname, DNSPacket* dnspkt, int zoneid )
+ {
+- string stmt;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " lookup()", Logger::Debug ) );
+
++ string stmt;
++ string& stmtref = stmt;
++
+ m_result = NULL;
+ m_qname = qname;
+-
++
+ if( zoneid < 0 )
+ {
+ if( qtype.getCode() == QType::ANY )
+ {
+ stmt = getArg( "sql-lookup" );
+ } else {
+- stmt = strbind( ":type", qtype.getName(), getArg( "sql-lookuptype" ) );
++ stmt = getArg( "sql-lookuptype" );
++ stmtref = strbind( ":type", qtype.getName(), stmt );
+ }
+ }
+ else
+@@ -206,22 +227,34 @@
+ {
+ stmt = getArg( "sql-lookupid" );
+ } else {
+- stmt = strbind( ":type", qtype.getName(), getArg( "sql-lookuptypeid" ) );
++ stmt = getArg( "sql-lookuptypeid" );
++ stmtref = strbind( ":type", qtype.getName(), stmt );
+ }
+-
++
+ size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ if( len < 0 )
+ {
+- L.log( m_myname + " lookup: Unable to convert zone id to string", Logger::Error );
++ L.log( m_myname + " lookup: Unable to convert zone id to string - format error", Logger::Error );
+ throw( DBException( "Error: Libc error" ) );
+ }
+
+- stmt = strbind( ":id", string( m_buffer, len ), stmt );
++ if( len > sizeof( m_buffer ) - 1 )
++ {
++ L.log( m_myname + " lookup: Unable to convert zone id to string - insufficient buffer space", Logger::Error );
++ throw( DBException( "Error: Libc error" ) );
++ }
++
++ stmtref = strbind( ":id", string( m_buffer, len ), stmtref );
+ }
+
+- stmt = strbind( ":name", escape( toLower( qname ) ), stmt );
+- execStmt( stmt.c_str(), stmt.size(), true );
++ string tmp = qname;
++ stmtref = strbind( ":name", escape( toLowerByRef( tmp ), READ ), stmtref );
++
++ if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) )
++ {
++ throw( DBException( "Error: DB statement failed" ) );
++ }
+ }
+ catch( exception& e )
+ {
+@@ -241,7 +274,7 @@
+ {
+ DLOG( L.log( m_myname + " get()", Logger::Debug ) );
+
+- if( getRecord() )
++ if( getRecord( READ ) )
+ {
+ rr.content = "";
+ rr.priority = 0;
+@@ -257,7 +290,7 @@
+
+ if( m_qname.empty() && ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
+ {
+- rr.qname = string( tmp );
++ rr.qname = string( tmp, odbx_field_length( m_result, 1 ) );
+ }
+
+ if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
+@@ -277,7 +310,7 @@
+
+ if( ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
+ {
+- rr.content = string( tmp );
++ rr.content = string( tmp, odbx_field_length( m_result, 5 ) );
+ }
+
+ return true;
+@@ -286,7 +319,7 @@
+ catch( exception& e )
+ {
+ L.log( m_myname + " get: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return false;
+@@ -302,15 +335,30 @@
+ {
+ DLOG( L.log( m_myname + " setFresh()", Logger::Debug ) );
+
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " setFresh: Master server is unreachable", Logger::Error );
++ throw( DBException( "Error: Server unreachable" ) );
++ }
++
+ len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-update-lastcheck" ).c_str(), time( 0 ), domain_id );
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ if( len < 0 )
++ {
++ L.log( m_myname + " setFresh: Unable to insert values into statement '" + getArg( "sql-update-lastcheck" ) + "' - format error", Logger::Error );
++ throw( DBException( "Error: Libc error" ) );
++ }
++
++ if( len > sizeof( m_buffer ) - 1 )
+ {
+- L.log( m_myname + " setFresh: Unable to insert values into statement '" + getArg( "sql-update-lastcheck" ) + "'", Logger::Error );
++ L.log( m_myname + " setFresh: Unable to insert values into statement '" + getArg( "sql-update-lastcheck" ) + "' - insufficient buffer space", Logger::Error );
+ throw( DBException( "Error: Libc error" ) );
+ }
+
+- execStmt( m_buffer, len, false );
++ if( !execStmt( m_buffer, len, WRITE ) )
++ {
++ throw( DBException( "Error: DB statement failed" ) );
++ }
+ }
+ catch ( exception& e )
+ {
+@@ -323,22 +371,34 @@
+
+ void OdbxBackend::setNotified( u_int32_t domain_id, u_int32_t serial )
+ {
+- size_t len;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " setNotified()", Logger::Debug ) );
+
+- len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-update-serial" ).c_str(), serial, domain_id );
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " setFresh: Master server is unreachable", Logger::Error );
++ throw( DBException( "Error: Server unreachable" ) );
++ }
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-update-serial" ).c_str(), serial, domain_id );
++
++ if( len < 0 )
+ {
+- L.log( m_myname + " setNotified: Unable to insert values into statement '" + getArg( "sql-update-serial" ) + "'", Logger::Error );
++ L.log( m_myname + " setNotified: Unable to insert values into statement '" + getArg( "sql-update-serial" ) + "' - format error", Logger::Error );
+ throw( DBException( "Error: Libc error" ) );
+ }
+
+- execStmt( m_buffer, len, false );
++ if( len > sizeof( m_buffer ) - 1 )
++ {
++ L.log( m_myname + " setNotified: Unable to insert values into statement '" + getArg( "sql-update-serial" ) + "' - insufficient buffer space", Logger::Error );
++ throw( DBException( "Error: Libc error" ) );
++ }
++
++ if( !execStmt( m_buffer, len, WRITE ) )
++ {
++ throw( DBException( "Error: DB statement failed" ) );
++ }
+ }
+ catch ( exception& e )
+ {
+@@ -351,17 +411,15 @@
+
+ bool OdbxBackend::isMaster( const string& domain, const string& ip )
+ {
+- string stmt;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " isMaster()", Logger::Debug ) );
+
+- stmt = strbind( ":name", escape( toLower( domain ) ), getArg( "sql-master" ) );
+- execStmt( stmt.c_str(), stmt.size(), true );
++ string stmt = getArg( "sql-master" );
++ string& stmtref = strbind( ":name", escape( toLower( domain ), READ ), stmt );
+
+- if( !getRecord() ) { return false; }
++ if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
++ if( !getRecord( READ ) ) { return false; }
+
+ do
+ {
+@@ -369,16 +427,17 @@
+ {
+ if( !strcmp( odbx_field_value( m_result, 0 ), ip.c_str() ) )
+ {
++ while( getRecord( READ ) );
+ return true;
+ }
+ }
+ }
+- while( getRecord() );
++ while( getRecord( READ ) );
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " isMaster: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return false;
+@@ -392,15 +451,17 @@
+ {
+ DLOG( L.log( m_myname + " getUnfreshSlaveInfos()", Logger::Debug ) );
+
+- if( unfresh != NULL )
++ if( unfresh == NULL )
+ {
+- getDomainList( getArg( "sql-infoslaves" ), unfresh, &checkSlave );
++ L.log( m_myname + " getUnfreshSlaveInfos: invalid parameter - NULL pointer", Logger::Error );
++ return;
+ }
++
++ getDomainList( getArg( "sql-infoslaves" ), unfresh, &checkSlave );
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " getUnfreshSlaveInfo: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
+ }
+ }
+
+@@ -412,15 +473,17 @@
+ {
+ DLOG( L.log( m_myname + " getUpdatedMasters()", Logger::Debug ) );
+
+- if( updated != NULL )
++ if( updated == NULL )
+ {
+- getDomainList( getArg( "sql-infomasters" ), updated, &checkMaster );
++ L.log( m_myname + " getUpdatedMasters: invalid parameter - NULL pointer", Logger::Error );
++ return;
+ }
++
++ getDomainList( getArg( "sql-infomasters" ), updated, &checkMaster );
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " getUpdatedMasters: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
+ }
+ }
+
+@@ -428,43 +491,41 @@
+
+ bool OdbxBackend::superMasterBackend( const string& ip, const string& domain, const vector<DNSResourceRecord>& set, string* account, DNSBackend** ddb )
+ {
+- string stmt;
+- vector<DNSResourceRecord>::const_iterator i;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " superMasterBackend()", Logger::Debug ) );
+
+ if( account != NULL && ddb != NULL )
+ {
++ vector<DNSResourceRecord>::const_iterator i;
++
+ for( i = set.begin(); i != set.end(); i++ )
+ {
+- stmt = strbind( ":ip", escape( ip ), getArg( "sql-supermaster" ) );
+- stmt = strbind( ":ns", escape( i->content ), stmt );
+-
+- execStmt( stmt.c_str(), stmt.size(), true );
++ string stmt = getArg( "sql-supermaster" );
++ string& stmtref = strbind( ":ip", escape( ip, READ ), stmt );
++ stmtref = strbind( ":ns", escape( i->content, READ ), stmtref );
+
+- if( !getRecord() ) { return false; }
++ if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
+
+- do
++ if( getRecord( READ ) )
+ {
+ if( odbx_field_value( m_result, 0 ) != NULL )
+ {
+ *account = string( odbx_field_value( m_result, 0 ), odbx_field_length( m_result, 0 ) );
+ }
+- }
+- while( getRecord() );
+
+- *ddb=this;
+- return true;
++ while( getRecord( READ ) );
++
++ *ddb=this;
++ return true;
++ }
+ }
+ }
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " superMasterBackend: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return false;
+@@ -474,28 +535,38 @@
+
+ bool OdbxBackend::createSlaveDomain( const string& ip, const string& domain, const string& account )
+ {
+- size_t len;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " createSlaveDomain()", Logger::Debug ) );
+
+- len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-slave" ).c_str(), escape( toLower( domain ) ).c_str(),
+- escape( ip ).c_str(), escape( account ).c_str() );
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " createSlaveDomain: Master server is unreachable", Logger::Error );
++ return false;
++ }
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ string tmp = domain;
++ size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-slave" ).c_str(), escape( toLowerByRef( tmp ), WRITE ).c_str(),
++ escape( ip, WRITE ).c_str(), escape( account, WRITE ).c_str() );
++
++ if( len < 0 )
+ {
+- L.log( m_myname + " createSlaveDomain: Unable to insert values in statement '" + getArg( "sql-insert-slave" ) + "'", Logger::Error );
+- throw( DBException( "Error: Libc error" ) );
++ L.log( m_myname + " createSlaveDomain: Unable to insert values in statement '" + getArg( "sql-insert-slave" ) + "' - format error", Logger::Error );
++ return false;
++ }
++
++ if( len > sizeof( m_buffer ) - 1 )
++ {
++ L.log( m_myname + " createSlaveDomain: Unable to insert values in statement '" + getArg( "sql-insert-slave" ) + "' - insufficient buffer space", Logger::Error );
++ return false;
+ }
+
+- execStmt( m_buffer, len, false );
++ if( !execStmt( m_buffer, len, WRITE ) ) { return false; }
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " createSlaveDomain: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+@@ -505,28 +576,39 @@
+
+ bool OdbxBackend::feedRecord( const DNSResourceRecord& rr )
+ {
+- size_t len;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " feedRecord()", Logger::Debug ) );
+
+- len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-record" ).c_str(), rr.domain_id,
+- escape( toLower( rr.qname ) ).c_str(), rr.qtype.getName().c_str(), rr.ttl, rr.priority, escape( rr.content ).c_str() );
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " feedRecord: Master server is unreachable", Logger::Error );
++ return false;
++ }
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ string tmp = rr.qname;
++ size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-record" ).c_str(), rr.domain_id,
++ escape( toLowerByRef( tmp ), WRITE ).c_str(), rr.qtype.getName().c_str(), rr.ttl, rr.priority,
++ escape( rr.content, WRITE ).c_str() );
++
++ if( len < 0 )
+ {
+- L.log( m_myname + " feedRecord: Unable to insert values in statement '" + getArg( "sql-insert-record" ) + "'", Logger::Error );
+- throw( DBException( "Error: Libc error" ) );
++ L.log( m_myname + " feedRecord: Unable to insert values in statement '" + getArg( "sql-insert-record" ) + "' - format error", Logger::Error );
++ return false;
+ }
+
+- execStmt( m_buffer, len, false );
++ if( len > sizeof( m_buffer ) - 1 )
++ {
++ L.log( m_myname + " feedRecord: Unable to insert values in statement '" + getArg( "sql-insert-record" ) + "' - insufficient buffer space", Logger::Error );
++ return false;
++ }
++
++ if( !execStmt( m_buffer, len, WRITE ) ) { return false; }
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " feedRecord: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+@@ -536,33 +618,41 @@
+
+ bool OdbxBackend::startTransaction( const string& domain, int zoneid )
+ {
+- size_t len;
+- string stmt;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " startTransaction()", Logger::Debug ) );
+
+- stmt = getArg( "sql-transactbegin" );
+- execStmt( stmt.c_str(), stmt.size(), false );
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " startTransaction: Master server is unreachable", Logger::Error );
++ return false;
++ }
+
+- len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
++ string& stmtref = const_cast<string&>( getArg( "sql-transactbegin" ) );
++ if( !execStmt( stmtref.c_str(), stmtref.size(), WRITE ) ) { return false; }
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
++
++ if( len < 0 )
+ {
+- L.log( m_myname + " lookup: Unable to convert zone id to string", Logger::Error );
+- throw( DBException( "Error: Libc error" ) );
++ L.log( m_myname + " startTransaction: Unable to convert zone id to string - format error", Logger::Error );
++ return false;
+ }
+
+- stmt = strbind( ":id", string( m_buffer, len ), getArg( "sql-zonedelete" ) );
++ if( len > sizeof( m_buffer ) - 1 )
++ {
++ L.log( m_myname + " startTransaction: Unable to convert zone id to string - insufficient buffer space", Logger::Error );
++ return false;
++ }
+
+- execStmt( stmt.c_str(), stmt.size(), false );
++ string stmt = getArg( "sql-zonedelete" );
++ stmtref = strbind( ":id", string( m_buffer, len ), stmt );
++ if( !execStmt( stmtref.c_str(), stmtref.size(), WRITE ) ) { return false; }
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " startTransaction: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+@@ -576,12 +666,19 @@
+ {
+ DLOG( L.log( m_myname + " commitTransaction()", Logger::Debug ) );
+
+- execStmt( getArg( "sql-transactend" ).c_str(), getArg( "sql-transactend" ).size(), false );
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " commitTransaction: Master server is unreachable", Logger::Error );
++ return false;
++ }
++
++ const string& stmt = getArg( "sql-transactend" );
++ if( !execStmt( stmt.c_str(), stmt.size(), WRITE ) ) { return false; }
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " commitTransaction: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+@@ -595,12 +692,19 @@
+ {
+ DLOG( L.log( m_myname + " abortTransaction()", Logger::Debug ) );
+
+- execStmt( getArg( "sql-transactabort" ).c_str(), getArg( "sql-transabort" ).size(), false );
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " abortTransaction: Master server is unreachable", Logger::Error );
++ return false;
++ }
++
++ const string& stmt = getArg( "sql-transactabort" );
++ if( !execStmt( stmt.c_str(), stmt.size(), WRITE ) ) { return false; }
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " abortTransaction: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+--- modules/opendbxbackend/odbxprivate.cc 2006-03-15 19:29:39.000000000 +0100
++++ modules/opendbxbackend/odbxprivate.cc 2006-09-02 01:02:36.000000000 +0200
+@@ -2,7 +2,50 @@
+
+
+
+-void OdbxBackend::execStmt( const char* stmt, unsigned long length, bool select )
++unsigned int odbx_host_index[2] = { 0, 0 };
++
++
++
++bool OdbxBackend::connectTo( const vector<string>& hosts, QueryType type )
++{
++ int err;
++ unsigned int h, i;
++ int idx = odbx_host_index[type]++ % hosts.size();
++
++
++ if( m_handle[type] )
++ {
++ odbx_unbind( m_handle[type] );
++ odbx_finish( m_handle[type] );
++ m_handle[type] = NULL;
++ }
++
++ for( i = 0; i < hosts.size(); i++ )
++ {
++ h = ( idx + i ) % hosts.size();
++
++ if( ( err = odbx_init( &(m_handle[type]), getArg( "backend" ).c_str(), hosts[h].c_str(), getArg( "port" ).c_str() ) ) == ODBX_ERR_SUCCESS )
++ {
++ if( ( err = odbx_bind_simple( m_handle[type], getArg( "database" ).c_str(), getArg( "username" ).c_str(), getArg( "password" ).c_str() ) ) == ODBX_ERR_SUCCESS )
++ {
++ L.log( m_myname + " Database connection (" + (type ? "write" : "read") + ") to '" + hosts[h] + "' succeeded", Logger::Notice );
++ return true;
++ }
++
++ L.log( m_myname + " Unable to bind to database on host " + hosts[h] + " - " + string( odbx_error( m_handle[type], err ) ), Logger::Error );
++ continue;
++ }
++
++ L.log( m_myname + " Unable to connect to server on host " + hosts[h] + " - " + string( odbx_error( m_handle[type], err ) ), Logger::Error );
++ }
++
++ m_handle[type] = NULL;
++ return false;
++}
++
++
++
++bool OdbxBackend::execStmt( const char* stmt, unsigned long length, QueryType type )
+ {
+ int err;
+
+@@ -11,18 +54,21 @@
+
+ if( m_qlog ) { L.log( m_myname + " Query: " + stmt, Logger::Info ); }
+
+- if( ( err = odbx_query( m_handle, stmt, length ) ) < 0 )
++ if( ( err = odbx_query( m_handle[type], stmt, length ) ) < 0 )
+ {
+- L.log( m_myname + " execStmt: Unable to execute query - " + string( odbx_error( m_handle, err ) ), Logger::Error );
+- throw( AhuException( "Error: odbx_query() failed" ) );
++ L.log( m_myname + " execStmt: Unable to execute query - " + string( odbx_error( m_handle[type], err ) ), Logger::Error );
++ connectTo( m_hosts[type], type );
++ return false;
+ }
+
+- if( !select ) { while( getRecord() ); }
++ if( type == WRITE ) { while( getRecord( type ) ); }
++
++ return true;
+ }
+
+
+
+-bool OdbxBackend::getRecord()
++bool OdbxBackend::getRecord( QueryType type )
+ {
+ int err = 3;
+
+@@ -31,13 +77,19 @@
+
+ do
+ {
++ if( err < 0 )
++ {
++ L.log( m_myname + " getRecord: Unable to get next result - " + string( odbx_error( m_handle[type], err ) ), Logger::Error );
++ throw( AhuException( "Error: odbx_result() failed" ) );
++ }
++
+ if( m_result != NULL )
+ {
+ if( err == 3 )
+ {
+ if( ( err = odbx_row_fetch( m_result ) ) < 0 )
+ {
+- L.log( m_myname + " getRecord: Unable to get next row - " + string( odbx_error( m_handle, err ) ), Logger::Error );
++ L.log( m_myname + " getRecord: Unable to get next row - " + string( odbx_error( m_handle[type], err ) ), Logger::Error );
+ throw( AhuException( "Error: odbx_row_fetch() failed" ) );
+ }
+
+@@ -72,13 +124,7 @@
+ m_result = NULL;
+ }
+ }
+- while( ( err = odbx_result( m_handle, &m_result, NULL, 0 ) ) > 0 );
+-
+- if( err < 0 )
+- {
+- L.log( m_myname + " getRecord: Unable to get next result - " + string( odbx_error( m_handle, err ) ), Logger::Error );
+- throw( AhuException( "Error: odbx_result() failed" ) );
+- }
++ while( ( err = odbx_result( m_handle[type], &m_result, NULL, 0 ) ) != 0 );
+
+ m_result = NULL;
+ return false;
+@@ -86,18 +132,18 @@
+
+
+
+-string OdbxBackend::escape( const string& str )
++string OdbxBackend::escape( const string& str, QueryType type )
+ {
+ int err;
+ unsigned long len = sizeof( m_escbuf );
+
+
+- DLOG( L.log( m_myname + " escape()", Logger::Debug ) );
++ DLOG( L.log( m_myname + " escape(string)", Logger::Debug ) );
+
+- if( ( err = odbx_escape( m_handle, str.c_str(), str.size(), m_escbuf, &len ) ) < 0 )
++ if( ( err = odbx_escape( m_handle[type], str.c_str(), str.size(), m_escbuf, &len ) ) < 0 )
+ {
+- L.log( m_myname + " escape: Unable to escape string - " + string( odbx_error( m_handle, err ) ), Logger::Error );
+- throw( AhuException( "Error: odbx_escape() failed" ) );
++ L.log( m_myname + " escape(string): Unable to escape string - " + string( odbx_error( m_handle[type], err ) ), Logger::Error );
++ throw( runtime_error( "odbx_escape() failed" ) );
+ }
+
+ return string( m_escbuf, len );
+@@ -105,7 +151,7 @@
+
+
+
+-void OdbxBackend::getDomainList( const string& stmt, vector<DomainInfo>* list, bool (*check_fcn)(u_int32_t,u_int32_t,SOAData*,DomainInfo*) )
++bool OdbxBackend::getDomainList( const string& stmt, vector<DomainInfo>* list, bool (*check_fcn)(u_int32_t,u_int32_t,SOAData*,DomainInfo*) )
+ {
+ const char* tmp;
+ u_int32_t nlast, nserial;
+@@ -115,9 +161,8 @@
+
+ DLOG( L.log( m_myname + " getDomainList()", Logger::Debug ) );
+
+- execStmt( stmt.c_str(), stmt.size(), true );
+-
+- if( !getRecord() ) { return; }
++ if( !execStmt( stmt.c_str(), stmt.size(), READ ) ) { return false; }
++ if( !getRecord( READ ) ) { return false; }
+
+ do
+ {
+@@ -128,7 +173,7 @@
+
+ if( ( tmp = odbx_field_value( m_result, 6 ) ) != NULL )
+ {
+- DNSPacket::fillSOAData( string( tmp ), sd );
++ DNSPacket::fillSOAData( string( tmp, odbx_field_length( m_result, 6 ) ), sd );
+ }
+
+ if( !sd.serial && ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
+@@ -171,7 +216,9 @@
+ list->push_back( di );
+ }
+ }
+- while( getRecord() );
++ while( getRecord( READ ) );
++
++ return true;
+ }
+
+
diff --git a/dns/powerdns-devel/files/pdns.conf b/dns/powerdns-devel/files/pdns.conf
index 8a9074387d69..2df98c574b3a 100644
--- a/dns/powerdns-devel/files/pdns.conf
+++ b/dns/powerdns-devel/files/pdns.conf
@@ -16,6 +16,15 @@
#launch=gsqlite
#gsqlite-database=<path to your SQLite database>
+# OpenDBX
+#launch=opendbx
+#opendbx-backend=mysql
+#opendbx-host=127.0.0.1
+#opendbx-database=pdns
+#opendbx-username=pdns
+#opendbx-password=pdns
+
+# Autogenerated configuration file template
#################################
# allow-axfr-ips If disabled, DO allow zonetransfers from these IP addresses
#
@@ -242,6 +251,21 @@
# soa-minimum-ttl=3600
#################################
+# soa-refresh-default Default SOA refresh
+#
+# soa-refresh-default=10800
+
+#################################
+# soa-retry-default Default SOA retry
+#
+# soa-retry-default=3600
+
+#################################
+# soa-expire-default Default SOA expire
+#
+# soa-expire-default=604800
+
+#################################
# soa-serial-offset Make sure that no SOA serial is less than this number
#
# soa-serial-offset=0
@@ -300,5 +324,3 @@
# wildcards Honor wildcards in the database
#
# wildcards=
-
-
diff --git a/dns/powerdns-devel/files/pdns.in b/dns/powerdns-devel/files/pdns.in
index 8735e8268353..7894f49fef83 100644
--- a/dns/powerdns-devel/files/pdns.in
+++ b/dns/powerdns-devel/files/pdns.in
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# $FreeBSD: /tmp/pcvs/ports/dns/powerdns-devel/files/Attic/pdns.in,v 1.2 2006-02-20 20:46:57 dougb Exp $
+# $FreeBSD: /tmp/pcvs/ports/dns/powerdns-devel/files/Attic/pdns.in,v 1.3 2007-01-12 23:49:04 gabor Exp $
#
# PROVIDE: pdns_server
@@ -32,4 +32,7 @@ load_rc_config ${name}
required_files=${pdns_conf}
+monitor_cmd="${command} --daemon=no --guardian=no --control-console --loglevel=9"
+extra_commands="monitor"
+
run_rc_command "$1"
diff --git a/dns/powerdns-devel/files/pdns_mysql.sql b/dns/powerdns-devel/files/pdns_mysql.sql
index 278c5d56c61c..0db1b8665734 100644
--- a/dns/powerdns-devel/files/pdns_mysql.sql
+++ b/dns/powerdns-devel/files/pdns_mysql.sql
@@ -1,38 +1,50 @@
-create table domains (
- id INT auto_increment,
- name VARCHAR(255) NOT NULL,
- master VARCHAR(20) DEFAULT NULL,
- last_check INT DEFAULT NULL,
- type VARCHAR(6) NOT NULL,
- notified_serial INT DEFAULT NULL,
- account VARCHAR(40) DEFAULT NULL,
- primary key (id)
-)type=InnoDB;
-
-CREATE UNIQUE INDEX name_index ON domains(name);
+CREATE TABLE domains (
+ id INT auto_increment,
+ name VARCHAR(255) NOT NULL,
+ type VARCHAR(6) NOT NULL,
+ master VARCHAR(40) DEFAULT NULL,
+ account VARCHAR(40) DEFAULT NULL,
+ notified_serial INT DEFAULT NULL,
+ last_check INT DEFAULT NULL,
+CONSTRAINT pk_id
+ PRIMARY KEY (id),
+CONSTRAINT unq_name
+ UNIQUE (name)
+) type=InnoDB;
+
CREATE TABLE records (
- id INT auto_increment,
- domain_id INT DEFAULT NULL,
- name VARCHAR(255) DEFAULT NULL,
- type VARCHAR(6) DEFAULT NULL,
- content VARCHAR(255) DEFAULT NULL,
- ttl INT DEFAULT NULL,
- prio INT DEFAULT NULL,
- change_date INT DEFAULT NULL,
- primary key(id)
-)type=InnoDB;
-
-CREATE INDEX rec_name_index ON records(name);
-CREATE INDEX nametype_index ON records(name,type);
-CREATE INDEX domain_id ON records(domain_id);
-
-create table supermasters (
- ip VARCHAR(25) NOT NULL,
- nameserver VARCHAR(255) NOT NULL,
- account VARCHAR(40) DEFAULT NULL
+ id INT auto_increment,
+ domain_id INT DEFAULT NULL,
+ name VARCHAR(255) DEFAULT NULL,
+ type VARCHAR(6) DEFAULT NULL,
+ ttl INT DEFAULT NULL,
+ prio INT DEFAULT NULL,
+ content VARCHAR(255) DEFAULT NULL,
+ change_date INT DEFAULT NULL,
+CONSTRAINT pk_id
+ PRIMARY KEY (id),
+CONSTRAINT fk_domainid
+ FOREIGN KEY (domain_id)
+ REFERENCES domains(id)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
+) type=InnoDB;
+
+CREATE INDEX idx_rdomainid ON records(domain_id);
+CREATE INDEX idx_rname ON records(name);
+CREATE INDEX idx_rname_rtype ON records(name,type);
+
+
+CREATE TABLE supermasters (
+ ip VARCHAR(40) NOT NULL,
+ nameserver VARCHAR(255) NOT NULL,
+ account VARCHAR(40) DEFAULT NULL
);
-GRANT SELECT ON supermasters TO pdns;
-GRANT ALL ON domains TO pdns;
-GRANT ALL ON records TO pdns;
+CREATE INDEX idx_smip_smns ON supermasters(ip,nameserver);
+
+
+GRANT SELECT ON supermasters TO powerdns;
+GRANT ALL ON domains TO powerdns;
+GRANT ALL ON records TO powerdns;
diff --git a/dns/powerdns-devel/files/pdns_postgresql.sql b/dns/powerdns-devel/files/pdns_postgresql.sql
index c700a2aa6dc2..481cc98b21b6 100644
--- a/dns/powerdns-devel/files/pdns_postgresql.sql
+++ b/dns/powerdns-devel/files/pdns_postgresql.sql
@@ -1,40 +1,52 @@
-create table domains (
- id SERIAL PRIMARY KEY,
- name VARCHAR(255) NOT NULL,
- master VARCHAR(20) DEFAULT NULL,
- last_check INT DEFAULT NULL,
- type VARCHAR(6) NOT NULL,
- notified_serial INT DEFAULT NULL,
- account VARCHAR(40) DEFAULT NULL
+CREATE TABLE domains (
+ id SERIAL,
+ name VARCHAR(255) NOT NULL,
+ type VARCHAR(6) NOT NULL,
+ master VARCHAR(40) DEFAULT NULL,
+ account VARCHAR(40) DEFAULT NULL
+ notified_serial INT DEFAULT NULL,
+ last_check INT DEFAULT NULL,
+CONSTRAINT pk_id
+ PRIMARY KEY (id),
+CONSTRAINT unq_name
+ UNIQUE (name)
);
-CREATE UNIQUE INDEX name_index ON domains(name);
+
CREATE TABLE records (
- id SERIAL PRIMARY KEY,
- domain_id INT DEFAULT NULL,
- name VARCHAR(255) DEFAULT NULL,
- type VARCHAR(6) DEFAULT NULL,
- content VARCHAR(255) DEFAULT NULL,
- ttl INT DEFAULT NULL,
- prio INT DEFAULT NULL,
- change_date INT DEFAULT NULL,
- CONSTRAINT domain_exists
- FOREIGN KEY(domain_id) REFERENCES domains(id)
- ON DELETE CASCADE
+ id SERIAL,
+ domain_id INT DEFAULT NULL,
+ name VARCHAR(255) DEFAULT NULL,
+ type VARCHAR(6) DEFAULT NULL,
+ ttl INT DEFAULT NULL,
+ prio INT DEFAULT NULL,
+ content VARCHAR(255) DEFAULT NULL,
+ change_date INT DEFAULT NULL,
+CONSTRAINT pk_id
+ PRIMARY KEY (id),
+CONSTRAINT fk_domainid
+ FOREIGN KEY (domain_id)
+ REFERENCES domains(id)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
);
-CREATE INDEX rec_name_index ON records(name);
-CREATE INDEX nametype_index ON records(name,type);
-CREATE INDEX domain_id ON records(domain_id);
+CREATE INDEX idx_rdomainid ON records(domain_id);
+CREATE INDEX idx_rname ON records(name);
+CREATE INDEX idx_rname_rtype ON records(name,type);
+
-create table supermasters (
- ip VARCHAR(25) NOT NULL,
- nameserver VARCHAR(255) NOT NULL,
- account VARCHAR(40) DEFAULT NULL
+CREATE TABLE supermasters (
+ ip VARCHAR(40) NOT NULL,
+ nameserver VARCHAR(255) NOT NULL,
+ account VARCHAR(40) DEFAULT NULL
);
-GRANT SELECT ON supermasters TO pdns;
-GRANT ALL ON domains TO pdns;
-GRANT ALL ON domains_id_seq TO pdns;
-GRANT ALL ON records TO pdns;
-GRANT ALL ON records_id_seq TO pdns;
+CREATE INDEX idx_smip_smns ON supermasters(ip,nameserver);
+
+
+GRANT SELECT ON supermasters TO powerdns;
+GRANT ALL ON domains TO powerdns;
+GRANT ALL ON domains_id_seq TO powerdns;
+GRANT ALL ON records TO powerdns;
+GRANT ALL ON records_id_seq TO powerdns;
diff --git a/dns/powerdns-devel/files/pdns_recursor.in b/dns/powerdns-devel/files/pdns_recursor.in
deleted file mode 100644
index 96bf4743c638..000000000000
--- a/dns/powerdns-devel/files/pdns_recursor.in
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/sh
-#
-# $FreeBSD: /tmp/pcvs/ports/dns/powerdns-devel/files/Attic/pdns_recursor.in,v 1.2 2006-02-20 20:46:57 dougb Exp $
-#
-
-# PROVIDE: pdns_recursor
-# REQUIRE: DAEMON
-# KEYWORD: shutdown
-
-#
-# Add the following lines to /etc/rc.conf to enable pdns_recursor:
-#
-#pdns_recursor_enable="YES"
-#
-# See http://rtfm.powerdns.com for flags.
-#
-
-. %%RC_SUBR%%
-
-name=pdns_recursor
-rcvar=`set_rcvar`
-
-command=%%PREFIX%%/sbin/pdns_recursor
-
-# set defaults
-
-pdns_recursor_enable=${pdns_recursor_enable:-"NO"}
-pdns_recursor_conf=${pdns_recursor_conf:-"%%PREFIX%%/etc/recursor.conf"}
-pdns_recursor_flags=${pdns_recursor_flags:-""}
-
-load_rc_config ${name}
-
-required_files=${pdns_recursor_conf}
-
-run_rc_command "$1"
diff --git a/dns/powerdns-devel/files/pdns_sqlite.sql b/dns/powerdns-devel/files/pdns_sqlite.sql
index f0f831fb2977..a7f8be90470a 100644
--- a/dns/powerdns-devel/files/pdns_sqlite.sql
+++ b/dns/powerdns-devel/files/pdns_sqlite.sql
@@ -1,33 +1,45 @@
-create table domains (
- id INTEGER PRIMARY KEY,
- name VARCHAR(255) NOT NULL,
- master VARCHAR(20) DEFAULT NULL,
- last_check INTEGER DEFAULT NULL,
- type VARCHAR(6) NOT NULL,
- notified_serial INTEGER DEFAULT NULL,
- account VARCHAR(40) DEFAULT NULL
+CREATE TABLE domains (
+ id INT AUTOINCREMENT,
+ name VARCHAR(255) NOT NULL,
+ type VARCHAR(6) NOT NULL,
+ master VARCHAR(40) DEFAULT NULL,
+ account VARCHAR(40) DEFAULT NULL,
+ notified_serial INT DEFAULT NULL,
+ last_check INT DEFAULT NULL,
+CONSTRAINT pk_id
+ PRIMARY KEY (id),
+CONSTRAINT unq_name
+ UNIQUE (name)
);
-CREATE UNIQUE INDEX name_index ON domains(name);
CREATE TABLE records (
- id INTEGER PRIMARY KEY,
- domain_id INTEGER DEFAULT NULL,
- name VARCHAR(255) DEFAULT NULL,
- type VARCHAR(6) DEFAULT NULL,
- content VARCHAR(255) DEFAULT NULL,
- ttl INTEGER DEFAULT NULL,
- prio INTEGER DEFAULT NULL,
- change_date INTEGER DEFAULT NULL
+ id INT AUTOINCREMENT,
+ domain_id INT DEFAULT NULL,
+ name VARCHAR(255) DEFAULT NULL,
+ type VARCHAR(6) DEFAULT NULL,
+ ttl INT DEFAULT NULL,
+ prio INT DEFAULT NULL,
+ content VARCHAR(255) DEFAULT NULL,
+ change_date INT DEFAULT NULL,
+CONSTRAINT pk_id
+ PRIMARY KEY (id),
+CONSTRAINT fk_domainid
+ FOREIGN KEY (domain_id)
+ REFERENCES domains(id)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
);
-CREATE INDEX rec_name_index ON records(name);
-CREATE INDEX nametype_index ON records(name,type);
-CREATE INDEX domain_id ON records(domain_id);
+CREATE INDEX idx_rdomainid ON records(domain_id);
+CREATE INDEX idx_rname ON records(name);
+CREATE INDEX idx_rname_rtype ON records(name,type);
-create table supermasters (
- ip VARCHAR(25) NOT NULL,
- nameserver VARCHAR(255) NOT NULL,
- account VARCHAR(40) DEFAULT NULL
+
+CREATE TABLE supermasters (
+ ip VARCHAR(40) NOT NULL,
+ nameserver VARCHAR(255) NOT NULL,
+ account VARCHAR(40) DEFAULT NULL
);
+CREATE INDEX idx_smip_smns ON supermasters(ip,nameserver);
diff --git a/dns/powerdns-devel/files/pkg-message.in b/dns/powerdns-devel/files/pkg-message.in
index bb7595598837..b0b0983b2e15 100644
--- a/dns/powerdns-devel/files/pkg-message.in
+++ b/dns/powerdns-devel/files/pkg-message.in
@@ -4,12 +4,7 @@
pdns_enable="YES"
- If you want to use the powerdns recursor,
- you need the following additional line in /etc/rc.conf
-
- pdns_recursor_enable="YES"
-
- Configuration templates are available in %%PREFIX%%/etc
+ Configuration templates are available in %%PREFIX%%/etc/pdns
as pdns.conf-dist.
*******************************************************************
diff --git a/dns/powerdns-devel/pkg-plist b/dns/powerdns-devel/pkg-plist
index 5e5921e60e88..923d58226d22 100644
--- a/dns/powerdns-devel/pkg-plist
+++ b/dns/powerdns-devel/pkg-plist
@@ -3,24 +3,39 @@ bin/zone2ldap
bin/zone2sql
sbin/pdns_server
%%WITHMYSQL%%lib/libgmysqlbackend.a
+%%WITHMYSQL%%lib/libgmysqlbackend.la
%%WITHMYSQL%%lib/libgmysqlbackend.so
%%WITHMYSQL%%lib/libgmysqlbackend.so.0
-%%WITHSQLLITE%%lib/libgsqlitebackend.a
-%%WITHSQLLITE%%lib/libgsqlitebackend.so
-%%WITHSQLLITE%%lib/libgsqlitebackend.so.0
-%%WITHLDAP%%lib/libldapbackend.a
-%%WITHLDAP%%lib/libldapbackend.so
-%%WITHLDAP%%lib/libldapbackend.so.0
+%%WITHSQLITE%%lib/libgsqlitebackend.a
+%%WITHSQLITE%%lib/libgsqlitebackend.la
+%%WITHSQLITE%%lib/libgsqlitebackend.so
+%%WITHSQLITE%%lib/libgsqlitebackend.so.0
+%%WITHSQLITE3%%lib/libgsqlitebackend.a
+%%WITHSQLITE3%%lib/libgsqlitebackend.la
+%%WITHSQLITE3%%lib/libgsqlitebackend.so
+%%WITHSQLITE3%%lib/libgsqlitebackend.so.0
+%%WITHOPENLDAP%%lib/libldapbackend.a
+%%WITHOPENLDAP%%lib/libldapbackend.la
+%%WITHOPENLDAP%%lib/libldapbackend.so
+%%WITHOPENLDAP%%lib/libldapbackend.so.0
+%%WITHOPENDBX%%lib/libopendbxbackend.a
+%%WITHOPENDBX%%lib/libopendbxbackend.la
+%%WITHOPENDBX%%lib/libopendbxbackend.so
+%%WITHOPENDBX%%lib/libopendbxbackend.so.0
+%%WITHGEO%%lib/libgeobackend.a
+%%WITHGEO%%lib/libgeobackend.la
+%%WITHGEO%%lib/libgeobackend.so
+%%WITHGEO%%lib/libgeobackend.so.0
lib/libpipebackend.a
lib/libpipebackend.la
lib/libpipebackend.so
lib/libpipebackend.so.0
-%%RECURSOR%%sbin/pdns_recursor
-@unexec if cmp -s %D/etc/pdns.conf %D/etc/pdns.conf-dist; then rm -f %D/etc/pdns.conf; fi
-etc/pdns.conf-dist
+@unexec if cmp -s %D/etc/pdns/pdns.conf %D/etc/pdns/pdns.conf-dist; then rm -f %D/etc/pdns/pdns.conf; fi
+etc/pdns/pdns.conf-dist
@exec [ -f %B/pdns.conf ] || cp %B/%f %B/pdns.conf
%%PORTDOCS%%share/examples/powerdns/pdns.conf
%%PORTDOCS%%share/examples/powerdns/pdns_mysql.sql
%%PORTDOCS%%share/examples/powerdns/pdns_postgresql.sql
%%PORTDOCS%%share/examples/powerdns/pdns_sqlite.sql
%%PORTDOCS%%@dirrm share/examples/powerdns
+@dirrmtry etc/pdns
diff --git a/dns/powerdns/Makefile b/dns/powerdns/Makefile
index 2aacd90397e1..0fdfc7628786 100644
--- a/dns/powerdns/Makefile
+++ b/dns/powerdns/Makefile
@@ -7,14 +7,14 @@
PORTNAME= powerdns
PORTVERSION= 2.9.20
-PORTREVISION= 1
+PORTREVISION= 2
CATEGORIES= dns ipv6
MASTER_SITES= http://downloads.powerdns.com/releases/ \
http://mirrors.evolva.ro/powerdns.com/releases/
DISTNAME= pdns-${PORTVERSION}
MAINTAINER= tremere@cainites.net
-COMMENT= An advanced DNS server with SQL backend
+COMMENT= An advanced DNS server with multiple backends including SQL
BUILD_DEPENDS= bjam:${PORTSDIR}/devel/boost
@@ -25,8 +25,9 @@ USE_LDCONFIG= YES
CXXFLAGS+= -I${LOCALBASE}/include
LDFLAGS+= -L${LOCALBASE}/lib
CONFIGURE_TARGET= --build=${MACHINE_ARCH}-portbld-freebsd${OSREL}
-CONFIGURE_ARGS+= --with-modules="${CONFIGURE_MODULES} pipe" \
- --with-dynmodules=""
+CONFIGURE_ARGS+= --with-modules="pipe" \
+ --with-dynmodules="${CONFIGURE_MODULES}" \
+ --sysconfdir="${PREFIX}/etc/pdns"
# --enable-debug
SCRIPTS_ENV= WRKDIRPREFIX="${WRKDIRPREFIX}" \
CURDIR2="${.CURDIR}" \
@@ -37,97 +38,88 @@ MAN8= pdns_control.8 pdns_server.8 zone2sql.8
SUB_FILES= pkg-message
+OPTIONS= PGSQL "PostgreSQL backend" on \
+ MYSQL "MySQL backend" off \
+ SQLITE "SQLite 2 backend" off \
+ SQLITE3 "SQLite 3 backend" off \
+ OPENDBX "OpenDBX backend" off \
+ OPENLDAP "OpenLDAP backend" off \
+ GEO "Geo backend" off
+
.include <bsd.port.pre.mk>
USE_RC_SUBR+= pdns
-# use user config if possible
-.if exists(${WRKDIRPREFIX}${.CURDIR}/Makefile.inc)
-.include "${WRKDIRPREFIX}${.CURDIR}/Makefile.inc"
+.if defined(WITH_GEO)
+CONFIGURE_MODULES+= "geo"
+PLIST_SUB+= WITHGEO=""
.else
-.if defined(BATCH)
-# default package, can be configured in /etc/make.conf
-POWERDNS_OPTIONS?= \"PostgreSQL\"
+PLIST_SUB+= WITHGEO="@comment "
.endif
-# make INDEX match
-NO_DESCRIBE=yes
+
+.if defined(WITH_SQLITE) && defined(WITH_SQLITE3)
+BROKEN= choose only one SQLite backend version
.endif
-.if defined(WITH_POSTGRESQL_DRIVER) && !defined(WITHOUT_POSTGRESQL_DRIVER)
-LIB_DEPENDS+= pq[+][+].4:${PORTSDIR}/databases/postgresql-libpq++
-CONFIGURE_ARGS+= --enable-pgsql --with-pgsql-includes=${LOCALBASE}/include
+.if defined(WITH_PGSQL)
+USE_PGSQL?= YES
CONFIGURE_MODULES+= "gpgsql"
-CFLAGS+= -DDLLIMPORT=""
+PLIST_SUB+= WITHPGSQL=""
.else
CONFIGURE_ARGS+= --disable-pgsql
+PLIST_SUB+= WITHPGSQL="@comment "
.endif
-.if defined(WITH_MYSQL_DRIVER)
+.if defined(WITH_MYSQL)
USE_MYSQL?= YES
-CONFIGURE_ARGS+= --enable-mysql --with-mysql-includes=${LOCALBASE}
CONFIGURE_MODULES+= "gmysql"
+CXXFLAGS+= -I${LOCALBASE}/include/mysql
+LDFLAGS+= -L${LOCALBASE}/lib/mysql
PLIST_SUB+= WITHMYSQL=""
.else
CONFIGURE_ARGS+= --disable-mysql
PLIST_SUB+= WITHMYSQL="@comment "
.endif
-.if defined(WITH_LDAP)
+.if defined(WITH_OPENLDAP)
USE_OPENLDAP?= YES
CONFIGURE_MODULES+= "ldap"
-PLIST_SUB+= WITHLDAP=""
CXXFLAGS+= -L${LOCALBASE}/lib -DLDAP_DEPRECATED=1
+PLIST_SUB+= WITHOPENLDAP=""
.else
-PLIST_SUB+= WITHLDAP="@comment "
+PLIST_SUB+= WITHOPENLDAP="@comment "
.endif
.if defined(WITH_SQLITE)
-LIB_DEPENDS+= sqlite.2:${PORTSDIR}/databases/sqlite2
-CONFIGURE_ARGS+= --enable-sqlite
+USE_SQLITE?= 2
CONFIGURE_MODULES+= "gsqlite"
-PLIST_SUB+= WITHSQLLITE=""
+PLIST_SUB+= WITHSQLITE=""
.else
-CONFIGURE_ARGS+= --disable-sqlite
-PLIST_SUB+= WITHSQLLITE="@comment "
+PLIST_SUB+= WITHSQLITE="@comment "
.endif
-.if defined(POWERDNS_WITH_RECURSOR)
-USE_RC_SUBR+= pdns_recursor
-CONFIGURE_ARGS+= --enable-recursor
-PLIST_SUB+= RECURSOR=""
+.if defined(WITH_SQLITE3)
+USE_SQLITE?= 3
+CONFIGURE_MODULES+= "gsqlite"
+PLIST_SUB+= WITHSQLITE3=""
.else
-PLIST_SUB+= RECURSOR="@comment "
+PLIST_SUB+= WITHSQLITE3="@comment "
.endif
-.if defined(POWERDNS_WITH_RECURSOR)
-.if exists(/usr/include/ucontext.h) && ${OSVERSION} >= 500000
-UCONTEXT!= ${AWK} '/setcontext/ { print "YES" }' \
- /usr/include/ucontext.h
-.if ${UCONTEXT} == ""
-BROKEN= setcontext for recursor not found or FreeBSD version lower than 5.0
-.endif
-.endif
+.if defined(WITH_OPENDBX)
+LIB_DEPENDS+= opendbx.1:${PORTSDIR}/databases/opendbx
+CONFIGURE_MODULES+= "opendbx"
+PLIST_SUB+= WITHOPENDBX=""
+CXXFLAGS+= -L${LOCALBASE}/lib
+.else
+PLIST_SUB+= WITHOPENDBX="@comment "
.endif
.if ${OSVERSION} < 500039
USE_GCC=3.4
.endif
-.if defined(NO_DESCRIBE)
-describe:
-.if defined(BATCH)
- @ ${SETENV} ${SCRIPTS_ENV} ${SH} ${FILESDIR}/configure.powerdns
-.endif
- @cd ${.CURDIR} && ${MAKE} ${__softMAKEFLAGS} BATCH=yes ${.TARGET}
-.endif
-
-pre-everything::
- @ ${SETENV} ${SCRIPTS_ENV} ${SH} ${FILESDIR}/configure.powerdns
-
-post-clean:
- @ ${RM} -f ${WRKDIRPREFIX}${.CURDIR}/Makefile.inc
-
-.if defined(WITH_LDAP)
+.if defined(WITH_OPENLDAP)
post-patch:
${REINPLACE_CMD} -e 's;-I. ;-I. -I${LOCALBASE}/include ;' \
-e 's;la_LDFLAGS =;la_LDFLAGS = -L${LOCALBASE}/lib;' \
@@ -138,8 +130,8 @@ post-patch:
.endif
post-install:
-.if !exists(${PREFIX}/etc/pdns.conf)
- ${INSTALL_DATA} ${PREFIX}/etc/pdns.conf-dist ${PREFIX}/etc/pdns.conf
+.if !exists(${PREFIX}/etc/pdns/pdns.conf)
+ ${INSTALL_DATA} ${PREFIX}/etc/pdns/pdns.conf-dist ${PREFIX}/etc/pdns/pdns.conf
.endif
.if !defined(NOPORTDOCS)
${MKDIR} ${EXAMPLESDIR}
diff --git a/dns/powerdns/Makefile.inc b/dns/powerdns/Makefile.inc
index d7c17dcb1920..e69de29bb2d1 100644
--- a/dns/powerdns/Makefile.inc
+++ b/dns/powerdns/Makefile.inc
@@ -1 +0,0 @@
-WITH_POSTGRESQL_DRIVER=YES
diff --git a/dns/powerdns/files/configure.powerdns b/dns/powerdns/files/configure.powerdns
deleted file mode 100644
index 43c9b3e1e685..000000000000
--- a/dns/powerdns/files/configure.powerdns
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh
-#
-# $FreeBSD$
-#
-if [ -f ${WRKDIRPREFIX}${CURDIR2}/Makefile.inc ]; then
- exit
-fi
-
-if [ "${POWERDNS_OPTIONS}" ]; then
- set ${POWERDNS_OPTIONS}
-else
- dialog --title "configuration options" --clear \
- --checklist "\n\
-Please select desired options:" -1 -1 8 \
-PostgreSQL "PostgreSQL driver" ON \
-MySQL "MySQL driver" OFF \
-OpenLDAP "OpenLDAP backend" OFF \
-SQLite "SQLite backend" OFF \
-Recursor "Build Recursor (DEPRECATED)" OFF \
-2> /tmp/checklist.tmp.$$
-
- retval=$?
- if [ -s /tmp/checklist.tmp.$$ ]; then
- set `cat /tmp/checklist.tmp.$$`
- fi
- rm -f /tmp/checklist.tmp.$$
-
- case $retval in
- 0) if [ -z "$*" ]; then
- echo "Nothing selected"
- fi
- ;;
- 1) echo "Cancel pressed."
- exit 1
- ;;
- esac
-fi
-
-${MKDIR} ${WRKDIRPREFIX}${CURDIR2}
-exec > ${WRKDIRPREFIX}${CURDIR2}/Makefile.inc
-
-while [ "$1" ]; do
- case $1 in
- \"PostgreSQL\")
- echo WITH_POSTGRESQL_DRIVER=YES
- ;;
- \"MySQL\")
- echo WITH_MYSQL_DRIVER=YES
- ;;
- \"OpenLDAP\")
- echo WITH_LDAP=YES
- ;;
- \"SQLite\")
- echo WITH_SQLITE=YES
- echo SQLITE_PORT?=databases/sqlite
- ;;
- \"Recursor\")
- echo POWERDNS_WITH_RECURSOR=YES
- ;;
- \"nothing\"|true)
- ;;
- *)
- echo "Invalid option(s): $*" > /dev/stderr
- rm -f ${WRKDIRPREFIX}${CURDIR2}/Makefile.inc
- exit 1
- ;;
- esac
- shift
-done
-exec > /dev/stderr
diff --git a/dns/powerdns/files/patch-opendbx b/dns/powerdns/files/patch-opendbx
new file mode 100644
index 000000000000..3f24a01e82b4
--- /dev/null
+++ b/dns/powerdns/files/patch-opendbx
@@ -0,0 +1,1038 @@
+--- modules/opendbxbackend/odbxbackend.hh 2006-03-15 19:29:39.000000000 +0100
++++ modules/opendbxbackend/odbxbackend.hh 2006-09-03 11:34:13.000000000 +0200
+@@ -1,11 +1,10 @@
+ /*
+ * PowerDNS OpenDBX Backend
+- * Copyright (C) 2005 Norbert Sendetzky <norbert@linuxnetworks.de>
++ * Copyright (C) 2005-2006 Norbert Sendetzky <norbert@linuxnetworks.de>
+ *
+ * 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 2 of the License, or
+- * any later version.
++ * it under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+@@ -14,7 +13,7 @@
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+@@ -32,7 +31,6 @@
+ #include <pdns/arguments.hh>
+ #include <pdns/logger.hh>
+ #include <odbx.h>
+-#include "modules/ldapbackend/utils.hh"
+
+
+ #ifndef ODBXBACKEND_HH
+@@ -53,19 +51,23 @@
+
+ class OdbxBackend : public DNSBackend
+ {
++ enum QueryType { READ, WRITE };
++
+ string m_myname;
+ string m_qname;
+ int m_default_ttl;
+ bool m_qlog;
+- odbx_t* m_handle;
++ odbx_t* m_handle[2];
+ odbx_result_t* m_result;
+ char m_escbuf[BUFLEN];
+ char m_buffer[2*BUFLEN];
++ vector<string> m_hosts[2];
+
+- bool getRecord();
+- void execStmt( const char* stmt, unsigned long length, bool select );
+- void getDomainList( const string& query, vector<DomainInfo>* list, bool (*check_fcn)(u_int32_t,u_int32_t,SOAData*,DomainInfo*) );
+- string escape( const string& str );
++ string escape( const string& str, QueryType type );
++ bool connectTo( const vector<string>& host, QueryType type );
++ bool getDomainList( const string& query, vector<DomainInfo>* list, bool (*check_fcn)(u_int32_t,u_int32_t,SOAData*,DomainInfo*) );
++ bool execStmt( const char* stmt, unsigned long length, QueryType type );
++ bool getRecord( QueryType type );
+
+
+ public:
+@@ -107,37 +109,40 @@
+ void declareArguments( const string &suffix="" )
+ {
+ declare( suffix, "backend", "OpenDBX backend","mysql" );
+- declare( suffix, "host", "Name or address of one or more DBMS server","127.0.0.1" );
+- declare( suffix, "port", "Port the DBMS server is listening to","" );
++ declare( suffix, "host-read", "Name or address of one or more DBMS server to read from","127.0.0.1" );
++ declare( suffix, "host-write", "Name or address of one or more DBMS server used for updates","127.0.0.1" );
++ declare( suffix, "port", "Port the DBMS server are listening to","" );
+ declare( suffix, "database", "Database name containing the DNS records","powerdns" );
+ declare( suffix, "username","User for connecting to the DBMS","powerdns");
+ declare( suffix, "password","Password for connecting to the DBMS","");
+
+- declare( suffix, "sql-list", "AXFR query", "SELECT domain_id, name, type, ttl, prio, content FROM records WHERE domain_id=':id'" );
++ declare( suffix, "sql-list", "AXFR query", "SELECT domain_id, name, type, ttl, prio, content FROM records WHERE domain_id=:id" );
+
+ declare( suffix, "sql-lookup", "Lookup query","SELECT domain_id, name, type, ttl, prio, content FROM records WHERE name=':name'" );
+- declare( suffix, "sql-lookupid", "Lookup query with id","SELECT domain_id, name, type, ttl, prio, content FROM records WHERE domain_id=':id' AND name=':name'" );
++ declare( suffix, "sql-lookupid", "Lookup query with id","SELECT domain_id, name, type, ttl, prio, content FROM records WHERE domain_id=:id AND name=':name'" );
+ declare( suffix, "sql-lookuptype", "Lookup query with type","SELECT domain_id, name, type, ttl, prio, content FROM records WHERE name=':name' AND type=':type'" );
+- declare( suffix, "sql-lookuptypeid", "Lookup query with type and id","SELECT domain_id, name, type, ttl, prio, content FROM records WHERE domain_id=':id' AND name=':name' AND type=':type'" );
++ declare( suffix, "sql-lookuptypeid", "Lookup query with type and id","SELECT domain_id, name, type, ttl, prio, content FROM records WHERE domain_id=:id AND name=':name' AND type=':type'" );
+
+- declare( suffix, "sql-zonedelete","Delete all records for this zone","DELETE FROM records WHERE domain_id=':id'" );
+- declare( suffix, "sql-zoneinfo","Get domain info","SELECT d.id, d.name, d.type, d.master, d.last_check, r.content FROM domains AS d LEFT JOIN records AS r ON d.id=r.domain_id WHERE ( d.name=':name' AND r.type='SOA' ) OR ( d.name=':name' AND r.domain_id IS NULL )" );
++ declare( suffix, "sql-zonedelete","Delete all records for this zone","DELETE FROM records WHERE domain_id=:id" );
++ declare( suffix, "sql-zoneinfo","Get domain info","SELECT d.id, d.name, d.type, d.master, d.last_check, r.content FROM domains d LEFT JOIN records r ON ( d.id=r.domain_id AND r.type='SOA' ) WHERE d.name=':name' AND d.status='A'" );
+
+ declare( suffix, "sql-transactbegin", "Start transaction", "BEGIN" );
+ declare( suffix, "sql-transactend", "Finish transaction", "COMMIT" );
+ declare( suffix, "sql-transactabort", "Abort transaction", "ROLLBACK" );
+
+ declare( suffix, "sql-insert-slave","Add slave domain", "INSERT INTO domains ( name, type, master, account ) VALUES ( '%s', 'SLAVE', '%s', '%s' )" );
+- declare( suffix, "sql-insert-record","Feed record into table", "INSERT INTO records ( domain_id, name, type, ttl, prio, content ) VALUES ( '%d', '%s', '%s', '%d', '%d', '%s' )" );
++ declare( suffix, "sql-insert-record","Feed record into table", "INSERT INTO records ( domain_id, name, type, ttl, prio, content ) VALUES ( %d, '%s', '%s', %d, %d, '%s' )" );
+
+- declare( suffix, "sql-update-serial", "Set zone to notified", "UPDATE domains SET notified_serial='%d' WHERE id='%d'" );
+- declare( suffix, "sql-update-lastcheck", "Set time of last check", "UPDATE domains SET last_check='%d' WHERE id='%d'" );
++ declare( suffix, "sql-update-serial", "Set zone to notified", "UPDATE domains SET notified_serial=%d WHERE id=%d" );
++ declare( suffix, "sql-update-lastcheck", "Set time of last check", "UPDATE domains SET last_check=%d WHERE id=%d" );
+
+- declare( suffix, "sql-master", "Get master record for zone", "SELECT master FROM domains WHERE name=':name' AND type='SLAVE'" );
++ declare( suffix, "sql-master", "Get master record for zone", "SELECT master FROM domains WHERE name=':name' AND status='A' AND type='SLAVE'" );
+ declare( suffix, "sql-supermaster","Get supermaster info", "SELECT account FROM supermasters WHERE ip=':ip' AND nameserver=':ns'" );
+
+- declare( suffix, "sql-infoslaves", "Get all unfresh slaves", "SELECT d.id, d.name, d.master, d.notified_serial, d.last_check, r.change_date, r.content FROM domains AS d LEFT JOIN records AS r ON d.id=r.domain_id WHERE ( d.type='SLAVE' AND r.type='SOA' ) OR ( d.type='SLAVE' AND r.domain_id IS NULL )" );
+- declare( suffix, "sql-infomasters", "Get all updated masters", "SELECT d.id, d.name, d.master, d.notified_serial, d.last_check, r.change_date, r.content FROM domains AS d, records AS r WHERE d.type='MASTER' AND d.id=r.domain_id AND r.type='SOA'" );
++ declare( suffix, "sql-infoslaves", "Get all unfresh slaves", "SELECT d.id, d.name, d.master, d.notified_serial, d.last_check, r.change_date, r.content FROM domains d LEFT JOIN records r ON ( d.id=r.domain_id AND r.type='SOA' ) WHERE d.status='A' AND d.type='SLAVE'" );
++ declare( suffix, "sql-infomasters", "Get all updated masters", "SELECT d.id, d.name, d.master, d.notified_serial, d.last_check, r.change_date, r.content FROM domains d JOIN records r ON d.id=r.domain_id WHERE d.status='A' AND d.type='MASTER' AND r.type='SOA'" );
++
++ declare( suffix, "host", "depricated, use host-read and host-write instead","" );
+ }
+
+
+--- modules/opendbxbackend/odbxbackend.cc 2006-03-15 19:29:39.000000000 +0100
++++ modules/opendbxbackend/odbxbackend.cc 2006-06-17 11:39:04.000000000 +0200
+@@ -2,62 +2,80 @@
+
+
+
+-unsigned int odbx_host_index = 0;
++inline string& strbind( const string& search, const string& replace, string& subject )
++{
++ size_t pos = 0;
++
++ while( ( pos = subject.find( search, pos ) ) != string::npos )
++ {
++ subject.replace( pos, search.size(), replace );
++ pos += replace.size();
++ }
++
++ return subject;
++}
++
++
++
++inline string& toLowerByRef( string& str )
++{
++ for( unsigned int i = 0; i < str.length(); i++ )
++ {
++ str[i] = dns_tolower( str[i] );
++ }
++
++ return str;
++}
+
+
+
+ OdbxBackend::OdbxBackend( const string& suffix )
+ {
+- int err = -1;
+- unsigned int idx, i, h;
+ vector<string> hosts;
+
+
+ try
+ {
+ m_result = NULL;
++ m_handle[READ] = NULL;
++ m_handle[WRITE] = NULL;
+ m_myname = "[OpendbxBackend]";
+ m_default_ttl = arg().asNum( "default-ttl" );
+ m_qlog = arg().mustDo( "query-logging" );
+
+ setArgPrefix( "opendbx" + suffix );
+- stringtok( hosts, getArg( "host" ), ", " );
+
+- idx = odbx_host_index++ % hosts.size();
+-
+- for( i = 0; i < hosts.size(); i++ )
++ if( getArg( "host" ).size() > 0 )
+ {
+- h = ( idx + i ) % hosts.size();
+- if( !( err = odbx_init( &m_handle, getArg( "backend" ).c_str(), hosts[h].c_str(), getArg( "port" ).c_str() ) ) ) { break; }
++ L.log( m_myname + " WARNING: Using depricated opendbx-host parameter", Logger::Warning );
++ stringtok( m_hosts[READ], getArg( "host" ), ", " );
++ m_hosts[WRITE] = m_hosts[READ];
+ }
+-
+- if( err < 0 )
++ else
+ {
+- L.log( m_myname + " OdbxBackend: Unable to connect to server - " + string( odbx_error( m_handle, err ) ), Logger::Error );
+- throw( AhuException( "Fatal: odbx_init() failed" ) );
++ stringtok( m_hosts[READ], getArg( "host-read" ), ", " );
++ stringtok( m_hosts[WRITE], getArg( "host-write" ), ", " );
+ }
+
+- if( ( err = odbx_bind_simple( m_handle, getArg( "database" ).c_str(), getArg( "username" ).c_str(), getArg( "password" ).c_str() ) ) < 0 )
+- {
+- L.log( m_myname + " OdbxBackend: Unable to bind to database - " + string( odbx_error( m_handle, err ) ), Logger::Error );
+- throw( AhuException( "Fatal: odbx_bind_simple() failed" ) );
+- }
++ if( !connectTo( m_hosts[READ], READ ) ) { throw( AhuException( "Fatal: Connecting to server for reading failed" ) ); }
++ if( !connectTo( m_hosts[WRITE], WRITE ) ) { throw( AhuException( "Fatal: Connecting to server for writing failed" ) ); }
+ }
+ catch( exception& e )
+ {
+- L.log( m_myname + " OdbxBackend: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Fatal: STL exception" ) );
++ L.log( m_myname + " OdbxBackend(): Caught STL exception - " + e.what(), Logger::Error );
++ throw( AhuException( "Fatal: STL exception" ) );
+ }
+-
+- L.log( m_myname + " Connection succeeded", Logger::Notice );
+ }
+
+
+
+ OdbxBackend::~OdbxBackend()
+ {
+- odbx_unbind( m_handle );
+- odbx_finish( m_handle );
++ odbx_unbind( m_handle[WRITE] );
++ odbx_unbind( m_handle[READ] );
++
++ odbx_finish( m_handle[WRITE] );
++ odbx_finish( m_handle[READ] );
+ }
+
+
+@@ -65,17 +83,17 @@
+ bool OdbxBackend::getDomainInfo( const string& domain, DomainInfo& di )
+ {
+ const char* tmp;
+- string stmt;
+
+
+ try
+ {
+ DLOG( L.log( m_myname + " getDomainInfo()", Logger::Debug ) );
+
+- stmt = strbind( ":name", escape( toLower( domain ) ), getArg( "sql-zoneinfo" ) );
+- execStmt( stmt.c_str(), stmt.size(), true );
++ string stmt = getArg( "sql-zoneinfo" );
++ string& stmtref = strbind( ":name", escape( toLower( domain ), READ ), stmt );
+
+- if( !getRecord() ) { return false; }
++ if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
++ if( !getRecord( READ ) ) { return false; }
+
+ do
+ {
+@@ -95,7 +113,7 @@
+
+ if( ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
+ {
+- di.zone = string( tmp );
++ di.zone = string( tmp, odbx_field_length( m_result, 1 ) );
+ }
+
+ if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
+@@ -112,7 +130,7 @@
+
+ if( ( tmp = odbx_field_value( m_result, 3 ) ) != NULL )
+ {
+- di.master = string( tmp );
++ di.master = string( tmp, odbx_field_length( m_result, 3 ) );
+ }
+
+ if( ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
+@@ -125,16 +143,16 @@
+ SOAData sd;
+
+ sd.serial = 0;
+- DNSPacket::fillSOAData( string( tmp ), sd );
++ DNSPacket::fillSOAData( string( tmp, odbx_field_length( m_result, 6 ) ), sd );
+ di.serial = sd.serial;
+ }
+ }
+- while( getRecord() );
++ while( getRecord( READ ) );
+ }
+ catch( exception& e )
+ {
+ L.log( m_myname + " getDomainInfo: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+@@ -144,11 +162,6 @@
+
+ bool OdbxBackend::list( const string& target, int zoneid )
+ {
+- string stmt;
+- size_t len;
+-
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " list()", Logger::Debug ) );
+@@ -156,22 +169,29 @@
+ m_qname = "";
+ m_result = NULL;
+
+- len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
++ size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ if( len < 0 )
+ {
+- L.log( m_myname + " list: Unable to convert zone id to string", Logger::Error );
+- throw( DBException( "Error: Libc error" ) );
++ L.log( m_myname + " list: Unable to convert zone id to string - format error", Logger::Error );
++ return false;
+ }
+
+- stmt = strbind( ":id", string( m_buffer, len ), getArg( "sql-list" ) );
++ if( len > sizeof( m_buffer ) - 1 )
++ {
++ L.log( m_myname + " list: Unable to convert zone id to string - insufficient buffer space", Logger::Error );
++ return false;
++ }
++
++ string stmt = getArg( "sql-list" );
++ string& stmtref = strbind( ":id", string( m_buffer, len ), stmt );
+
+- execStmt( stmt.c_str(), stmt.size(), true );
++ if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
+ }
+ catch( exception& e )
+ {
+ L.log( m_myname + " list: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+@@ -181,23 +201,24 @@
+
+ void OdbxBackend::lookup( const QType& qtype, const string& qname, DNSPacket* dnspkt, int zoneid )
+ {
+- string stmt;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " lookup()", Logger::Debug ) );
+
++ string stmt;
++ string& stmtref = stmt;
++
+ m_result = NULL;
+ m_qname = qname;
+-
++
+ if( zoneid < 0 )
+ {
+ if( qtype.getCode() == QType::ANY )
+ {
+ stmt = getArg( "sql-lookup" );
+ } else {
+- stmt = strbind( ":type", qtype.getName(), getArg( "sql-lookuptype" ) );
++ stmt = getArg( "sql-lookuptype" );
++ stmtref = strbind( ":type", qtype.getName(), stmt );
+ }
+ }
+ else
+@@ -206,22 +227,34 @@
+ {
+ stmt = getArg( "sql-lookupid" );
+ } else {
+- stmt = strbind( ":type", qtype.getName(), getArg( "sql-lookuptypeid" ) );
++ stmt = getArg( "sql-lookuptypeid" );
++ stmtref = strbind( ":type", qtype.getName(), stmt );
+ }
+-
++
+ size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ if( len < 0 )
+ {
+- L.log( m_myname + " lookup: Unable to convert zone id to string", Logger::Error );
++ L.log( m_myname + " lookup: Unable to convert zone id to string - format error", Logger::Error );
+ throw( DBException( "Error: Libc error" ) );
+ }
+
+- stmt = strbind( ":id", string( m_buffer, len ), stmt );
++ if( len > sizeof( m_buffer ) - 1 )
++ {
++ L.log( m_myname + " lookup: Unable to convert zone id to string - insufficient buffer space", Logger::Error );
++ throw( DBException( "Error: Libc error" ) );
++ }
++
++ stmtref = strbind( ":id", string( m_buffer, len ), stmtref );
+ }
+
+- stmt = strbind( ":name", escape( toLower( qname ) ), stmt );
+- execStmt( stmt.c_str(), stmt.size(), true );
++ string tmp = qname;
++ stmtref = strbind( ":name", escape( toLowerByRef( tmp ), READ ), stmtref );
++
++ if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) )
++ {
++ throw( DBException( "Error: DB statement failed" ) );
++ }
+ }
+ catch( exception& e )
+ {
+@@ -241,7 +274,7 @@
+ {
+ DLOG( L.log( m_myname + " get()", Logger::Debug ) );
+
+- if( getRecord() )
++ if( getRecord( READ ) )
+ {
+ rr.content = "";
+ rr.priority = 0;
+@@ -257,7 +290,7 @@
+
+ if( m_qname.empty() && ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
+ {
+- rr.qname = string( tmp );
++ rr.qname = string( tmp, odbx_field_length( m_result, 1 ) );
+ }
+
+ if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
+@@ -277,7 +310,7 @@
+
+ if( ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
+ {
+- rr.content = string( tmp );
++ rr.content = string( tmp, odbx_field_length( m_result, 5 ) );
+ }
+
+ return true;
+@@ -286,7 +319,7 @@
+ catch( exception& e )
+ {
+ L.log( m_myname + " get: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return false;
+@@ -302,15 +335,30 @@
+ {
+ DLOG( L.log( m_myname + " setFresh()", Logger::Debug ) );
+
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " setFresh: Master server is unreachable", Logger::Error );
++ throw( DBException( "Error: Server unreachable" ) );
++ }
++
+ len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-update-lastcheck" ).c_str(), time( 0 ), domain_id );
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ if( len < 0 )
++ {
++ L.log( m_myname + " setFresh: Unable to insert values into statement '" + getArg( "sql-update-lastcheck" ) + "' - format error", Logger::Error );
++ throw( DBException( "Error: Libc error" ) );
++ }
++
++ if( len > sizeof( m_buffer ) - 1 )
+ {
+- L.log( m_myname + " setFresh: Unable to insert values into statement '" + getArg( "sql-update-lastcheck" ) + "'", Logger::Error );
++ L.log( m_myname + " setFresh: Unable to insert values into statement '" + getArg( "sql-update-lastcheck" ) + "' - insufficient buffer space", Logger::Error );
+ throw( DBException( "Error: Libc error" ) );
+ }
+
+- execStmt( m_buffer, len, false );
++ if( !execStmt( m_buffer, len, WRITE ) )
++ {
++ throw( DBException( "Error: DB statement failed" ) );
++ }
+ }
+ catch ( exception& e )
+ {
+@@ -323,22 +371,34 @@
+
+ void OdbxBackend::setNotified( u_int32_t domain_id, u_int32_t serial )
+ {
+- size_t len;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " setNotified()", Logger::Debug ) );
+
+- len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-update-serial" ).c_str(), serial, domain_id );
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " setFresh: Master server is unreachable", Logger::Error );
++ throw( DBException( "Error: Server unreachable" ) );
++ }
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-update-serial" ).c_str(), serial, domain_id );
++
++ if( len < 0 )
+ {
+- L.log( m_myname + " setNotified: Unable to insert values into statement '" + getArg( "sql-update-serial" ) + "'", Logger::Error );
++ L.log( m_myname + " setNotified: Unable to insert values into statement '" + getArg( "sql-update-serial" ) + "' - format error", Logger::Error );
+ throw( DBException( "Error: Libc error" ) );
+ }
+
+- execStmt( m_buffer, len, false );
++ if( len > sizeof( m_buffer ) - 1 )
++ {
++ L.log( m_myname + " setNotified: Unable to insert values into statement '" + getArg( "sql-update-serial" ) + "' - insufficient buffer space", Logger::Error );
++ throw( DBException( "Error: Libc error" ) );
++ }
++
++ if( !execStmt( m_buffer, len, WRITE ) )
++ {
++ throw( DBException( "Error: DB statement failed" ) );
++ }
+ }
+ catch ( exception& e )
+ {
+@@ -351,17 +411,15 @@
+
+ bool OdbxBackend::isMaster( const string& domain, const string& ip )
+ {
+- string stmt;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " isMaster()", Logger::Debug ) );
+
+- stmt = strbind( ":name", escape( toLower( domain ) ), getArg( "sql-master" ) );
+- execStmt( stmt.c_str(), stmt.size(), true );
++ string stmt = getArg( "sql-master" );
++ string& stmtref = strbind( ":name", escape( toLower( domain ), READ ), stmt );
+
+- if( !getRecord() ) { return false; }
++ if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
++ if( !getRecord( READ ) ) { return false; }
+
+ do
+ {
+@@ -369,16 +427,17 @@
+ {
+ if( !strcmp( odbx_field_value( m_result, 0 ), ip.c_str() ) )
+ {
++ while( getRecord( READ ) );
+ return true;
+ }
+ }
+ }
+- while( getRecord() );
++ while( getRecord( READ ) );
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " isMaster: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return false;
+@@ -392,15 +451,17 @@
+ {
+ DLOG( L.log( m_myname + " getUnfreshSlaveInfos()", Logger::Debug ) );
+
+- if( unfresh != NULL )
++ if( unfresh == NULL )
+ {
+- getDomainList( getArg( "sql-infoslaves" ), unfresh, &checkSlave );
++ L.log( m_myname + " getUnfreshSlaveInfos: invalid parameter - NULL pointer", Logger::Error );
++ return;
+ }
++
++ getDomainList( getArg( "sql-infoslaves" ), unfresh, &checkSlave );
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " getUnfreshSlaveInfo: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
+ }
+ }
+
+@@ -412,15 +473,17 @@
+ {
+ DLOG( L.log( m_myname + " getUpdatedMasters()", Logger::Debug ) );
+
+- if( updated != NULL )
++ if( updated == NULL )
+ {
+- getDomainList( getArg( "sql-infomasters" ), updated, &checkMaster );
++ L.log( m_myname + " getUpdatedMasters: invalid parameter - NULL pointer", Logger::Error );
++ return;
+ }
++
++ getDomainList( getArg( "sql-infomasters" ), updated, &checkMaster );
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " getUpdatedMasters: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
+ }
+ }
+
+@@ -428,43 +491,41 @@
+
+ bool OdbxBackend::superMasterBackend( const string& ip, const string& domain, const vector<DNSResourceRecord>& set, string* account, DNSBackend** ddb )
+ {
+- string stmt;
+- vector<DNSResourceRecord>::const_iterator i;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " superMasterBackend()", Logger::Debug ) );
+
+ if( account != NULL && ddb != NULL )
+ {
++ vector<DNSResourceRecord>::const_iterator i;
++
+ for( i = set.begin(); i != set.end(); i++ )
+ {
+- stmt = strbind( ":ip", escape( ip ), getArg( "sql-supermaster" ) );
+- stmt = strbind( ":ns", escape( i->content ), stmt );
+-
+- execStmt( stmt.c_str(), stmt.size(), true );
++ string stmt = getArg( "sql-supermaster" );
++ string& stmtref = strbind( ":ip", escape( ip, READ ), stmt );
++ stmtref = strbind( ":ns", escape( i->content, READ ), stmtref );
+
+- if( !getRecord() ) { return false; }
++ if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
+
+- do
++ if( getRecord( READ ) )
+ {
+ if( odbx_field_value( m_result, 0 ) != NULL )
+ {
+ *account = string( odbx_field_value( m_result, 0 ), odbx_field_length( m_result, 0 ) );
+ }
+- }
+- while( getRecord() );
+
+- *ddb=this;
+- return true;
++ while( getRecord( READ ) );
++
++ *ddb=this;
++ return true;
++ }
+ }
+ }
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " superMasterBackend: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return false;
+@@ -474,28 +535,38 @@
+
+ bool OdbxBackend::createSlaveDomain( const string& ip, const string& domain, const string& account )
+ {
+- size_t len;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " createSlaveDomain()", Logger::Debug ) );
+
+- len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-slave" ).c_str(), escape( toLower( domain ) ).c_str(),
+- escape( ip ).c_str(), escape( account ).c_str() );
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " createSlaveDomain: Master server is unreachable", Logger::Error );
++ return false;
++ }
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ string tmp = domain;
++ size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-slave" ).c_str(), escape( toLowerByRef( tmp ), WRITE ).c_str(),
++ escape( ip, WRITE ).c_str(), escape( account, WRITE ).c_str() );
++
++ if( len < 0 )
+ {
+- L.log( m_myname + " createSlaveDomain: Unable to insert values in statement '" + getArg( "sql-insert-slave" ) + "'", Logger::Error );
+- throw( DBException( "Error: Libc error" ) );
++ L.log( m_myname + " createSlaveDomain: Unable to insert values in statement '" + getArg( "sql-insert-slave" ) + "' - format error", Logger::Error );
++ return false;
++ }
++
++ if( len > sizeof( m_buffer ) - 1 )
++ {
++ L.log( m_myname + " createSlaveDomain: Unable to insert values in statement '" + getArg( "sql-insert-slave" ) + "' - insufficient buffer space", Logger::Error );
++ return false;
+ }
+
+- execStmt( m_buffer, len, false );
++ if( !execStmt( m_buffer, len, WRITE ) ) { return false; }
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " createSlaveDomain: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+@@ -505,28 +576,39 @@
+
+ bool OdbxBackend::feedRecord( const DNSResourceRecord& rr )
+ {
+- size_t len;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " feedRecord()", Logger::Debug ) );
+
+- len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-record" ).c_str(), rr.domain_id,
+- escape( toLower( rr.qname ) ).c_str(), rr.qtype.getName().c_str(), rr.ttl, rr.priority, escape( rr.content ).c_str() );
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " feedRecord: Master server is unreachable", Logger::Error );
++ return false;
++ }
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ string tmp = rr.qname;
++ size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-record" ).c_str(), rr.domain_id,
++ escape( toLowerByRef( tmp ), WRITE ).c_str(), rr.qtype.getName().c_str(), rr.ttl, rr.priority,
++ escape( rr.content, WRITE ).c_str() );
++
++ if( len < 0 )
+ {
+- L.log( m_myname + " feedRecord: Unable to insert values in statement '" + getArg( "sql-insert-record" ) + "'", Logger::Error );
+- throw( DBException( "Error: Libc error" ) );
++ L.log( m_myname + " feedRecord: Unable to insert values in statement '" + getArg( "sql-insert-record" ) + "' - format error", Logger::Error );
++ return false;
+ }
+
+- execStmt( m_buffer, len, false );
++ if( len > sizeof( m_buffer ) - 1 )
++ {
++ L.log( m_myname + " feedRecord: Unable to insert values in statement '" + getArg( "sql-insert-record" ) + "' - insufficient buffer space", Logger::Error );
++ return false;
++ }
++
++ if( !execStmt( m_buffer, len, WRITE ) ) { return false; }
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " feedRecord: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+@@ -536,33 +618,41 @@
+
+ bool OdbxBackend::startTransaction( const string& domain, int zoneid )
+ {
+- size_t len;
+- string stmt;
+-
+-
+ try
+ {
+ DLOG( L.log( m_myname + " startTransaction()", Logger::Debug ) );
+
+- stmt = getArg( "sql-transactbegin" );
+- execStmt( stmt.c_str(), stmt.size(), false );
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " startTransaction: Master server is unreachable", Logger::Error );
++ return false;
++ }
+
+- len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
++ string& stmtref = const_cast<string&>( getArg( "sql-transactbegin" ) );
++ if( !execStmt( stmtref.c_str(), stmtref.size(), WRITE ) ) { return false; }
+
+- if( len < 0 || len > sizeof( m_buffer ) - 1 )
++ size_t len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
++
++ if( len < 0 )
+ {
+- L.log( m_myname + " lookup: Unable to convert zone id to string", Logger::Error );
+- throw( DBException( "Error: Libc error" ) );
++ L.log( m_myname + " startTransaction: Unable to convert zone id to string - format error", Logger::Error );
++ return false;
+ }
+
+- stmt = strbind( ":id", string( m_buffer, len ), getArg( "sql-zonedelete" ) );
++ if( len > sizeof( m_buffer ) - 1 )
++ {
++ L.log( m_myname + " startTransaction: Unable to convert zone id to string - insufficient buffer space", Logger::Error );
++ return false;
++ }
+
+- execStmt( stmt.c_str(), stmt.size(), false );
++ string stmt = getArg( "sql-zonedelete" );
++ stmtref = strbind( ":id", string( m_buffer, len ), stmt );
++ if( !execStmt( stmtref.c_str(), stmtref.size(), WRITE ) ) { return false; }
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " startTransaction: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+@@ -576,12 +666,19 @@
+ {
+ DLOG( L.log( m_myname + " commitTransaction()", Logger::Debug ) );
+
+- execStmt( getArg( "sql-transactend" ).c_str(), getArg( "sql-transactend" ).size(), false );
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " commitTransaction: Master server is unreachable", Logger::Error );
++ return false;
++ }
++
++ const string& stmt = getArg( "sql-transactend" );
++ if( !execStmt( stmt.c_str(), stmt.size(), WRITE ) ) { return false; }
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " commitTransaction: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+@@ -595,12 +692,19 @@
+ {
+ DLOG( L.log( m_myname + " abortTransaction()", Logger::Debug ) );
+
+- execStmt( getArg( "sql-transactabort" ).c_str(), getArg( "sql-transabort" ).size(), false );
++ if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
++ {
++ L.log( m_myname + " abortTransaction: Master server is unreachable", Logger::Error );
++ return false;
++ }
++
++ const string& stmt = getArg( "sql-transactabort" );
++ if( !execStmt( stmt.c_str(), stmt.size(), WRITE ) ) { return false; }
+ }
+ catch ( exception& e )
+ {
+ L.log( m_myname + " abortTransaction: Caught STL exception - " + e.what(), Logger::Error );
+- throw( DBException( "Error: STL exception" ) );
++ return false;
+ }
+
+ return true;
+--- modules/opendbxbackend/odbxprivate.cc 2006-03-15 19:29:39.000000000 +0100
++++ modules/opendbxbackend/odbxprivate.cc 2006-09-02 01:02:36.000000000 +0200
+@@ -2,7 +2,50 @@
+
+
+
+-void OdbxBackend::execStmt( const char* stmt, unsigned long length, bool select )
++unsigned int odbx_host_index[2] = { 0, 0 };
++
++
++
++bool OdbxBackend::connectTo( const vector<string>& hosts, QueryType type )
++{
++ int err;
++ unsigned int h, i;
++ int idx = odbx_host_index[type]++ % hosts.size();
++
++
++ if( m_handle[type] )
++ {
++ odbx_unbind( m_handle[type] );
++ odbx_finish( m_handle[type] );
++ m_handle[type] = NULL;
++ }
++
++ for( i = 0; i < hosts.size(); i++ )
++ {
++ h = ( idx + i ) % hosts.size();
++
++ if( ( err = odbx_init( &(m_handle[type]), getArg( "backend" ).c_str(), hosts[h].c_str(), getArg( "port" ).c_str() ) ) == ODBX_ERR_SUCCESS )
++ {
++ if( ( err = odbx_bind_simple( m_handle[type], getArg( "database" ).c_str(), getArg( "username" ).c_str(), getArg( "password" ).c_str() ) ) == ODBX_ERR_SUCCESS )
++ {
++ L.log( m_myname + " Database connection (" + (type ? "write" : "read") + ") to '" + hosts[h] + "' succeeded", Logger::Notice );
++ return true;
++ }
++
++ L.log( m_myname + " Unable to bind to database on host " + hosts[h] + " - " + string( odbx_error( m_handle[type], err ) ), Logger::Error );
++ continue;
++ }
++
++ L.log( m_myname + " Unable to connect to server on host " + hosts[h] + " - " + string( odbx_error( m_handle[type], err ) ), Logger::Error );
++ }
++
++ m_handle[type] = NULL;
++ return false;
++}
++
++
++
++bool OdbxBackend::execStmt( const char* stmt, unsigned long length, QueryType type )
+ {
+ int err;
+
+@@ -11,18 +54,21 @@
+
+ if( m_qlog ) { L.log( m_myname + " Query: " + stmt, Logger::Info ); }
+
+- if( ( err = odbx_query( m_handle, stmt, length ) ) < 0 )
++ if( ( err = odbx_query( m_handle[type], stmt, length ) ) < 0 )
+ {
+- L.log( m_myname + " execStmt: Unable to execute query - " + string( odbx_error( m_handle, err ) ), Logger::Error );
+- throw( AhuException( "Error: odbx_query() failed" ) );
++ L.log( m_myname + " execStmt: Unable to execute query - " + string( odbx_error( m_handle[type], err ) ), Logger::Error );
++ connectTo( m_hosts[type], type );
++ return false;
+ }
+
+- if( !select ) { while( getRecord() ); }
++ if( type == WRITE ) { while( getRecord( type ) ); }
++
++ return true;
+ }
+
+
+
+-bool OdbxBackend::getRecord()
++bool OdbxBackend::getRecord( QueryType type )
+ {
+ int err = 3;
+
+@@ -31,13 +77,19 @@
+
+ do
+ {
++ if( err < 0 )
++ {
++ L.log( m_myname + " getRecord: Unable to get next result - " + string( odbx_error( m_handle[type], err ) ), Logger::Error );
++ throw( AhuException( "Error: odbx_result() failed" ) );
++ }
++
+ if( m_result != NULL )
+ {
+ if( err == 3 )
+ {
+ if( ( err = odbx_row_fetch( m_result ) ) < 0 )
+ {
+- L.log( m_myname + " getRecord: Unable to get next row - " + string( odbx_error( m_handle, err ) ), Logger::Error );
++ L.log( m_myname + " getRecord: Unable to get next row - " + string( odbx_error( m_handle[type], err ) ), Logger::Error );
+ throw( AhuException( "Error: odbx_row_fetch() failed" ) );
+ }
+
+@@ -72,13 +124,7 @@
+ m_result = NULL;
+ }
+ }
+- while( ( err = odbx_result( m_handle, &m_result, NULL, 0 ) ) > 0 );
+-
+- if( err < 0 )
+- {
+- L.log( m_myname + " getRecord: Unable to get next result - " + string( odbx_error( m_handle, err ) ), Logger::Error );
+- throw( AhuException( "Error: odbx_result() failed" ) );
+- }
++ while( ( err = odbx_result( m_handle[type], &m_result, NULL, 0 ) ) != 0 );
+
+ m_result = NULL;
+ return false;
+@@ -86,18 +132,18 @@
+
+
+
+-string OdbxBackend::escape( const string& str )
++string OdbxBackend::escape( const string& str, QueryType type )
+ {
+ int err;
+ unsigned long len = sizeof( m_escbuf );
+
+
+- DLOG( L.log( m_myname + " escape()", Logger::Debug ) );
++ DLOG( L.log( m_myname + " escape(string)", Logger::Debug ) );
+
+- if( ( err = odbx_escape( m_handle, str.c_str(), str.size(), m_escbuf, &len ) ) < 0 )
++ if( ( err = odbx_escape( m_handle[type], str.c_str(), str.size(), m_escbuf, &len ) ) < 0 )
+ {
+- L.log( m_myname + " escape: Unable to escape string - " + string( odbx_error( m_handle, err ) ), Logger::Error );
+- throw( AhuException( "Error: odbx_escape() failed" ) );
++ L.log( m_myname + " escape(string): Unable to escape string - " + string( odbx_error( m_handle[type], err ) ), Logger::Error );
++ throw( runtime_error( "odbx_escape() failed" ) );
+ }
+
+ return string( m_escbuf, len );
+@@ -105,7 +151,7 @@
+
+
+
+-void OdbxBackend::getDomainList( const string& stmt, vector<DomainInfo>* list, bool (*check_fcn)(u_int32_t,u_int32_t,SOAData*,DomainInfo*) )
++bool OdbxBackend::getDomainList( const string& stmt, vector<DomainInfo>* list, bool (*check_fcn)(u_int32_t,u_int32_t,SOAData*,DomainInfo*) )
+ {
+ const char* tmp;
+ u_int32_t nlast, nserial;
+@@ -115,9 +161,8 @@
+
+ DLOG( L.log( m_myname + " getDomainList()", Logger::Debug ) );
+
+- execStmt( stmt.c_str(), stmt.size(), true );
+-
+- if( !getRecord() ) { return; }
++ if( !execStmt( stmt.c_str(), stmt.size(), READ ) ) { return false; }
++ if( !getRecord( READ ) ) { return false; }
+
+ do
+ {
+@@ -128,7 +173,7 @@
+
+ if( ( tmp = odbx_field_value( m_result, 6 ) ) != NULL )
+ {
+- DNSPacket::fillSOAData( string( tmp ), sd );
++ DNSPacket::fillSOAData( string( tmp, odbx_field_length( m_result, 6 ) ), sd );
+ }
+
+ if( !sd.serial && ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
+@@ -171,7 +216,9 @@
+ list->push_back( di );
+ }
+ }
+- while( getRecord() );
++ while( getRecord( READ ) );
++
++ return true;
+ }
+
+
diff --git a/dns/powerdns/files/pdns.conf b/dns/powerdns/files/pdns.conf
index 8a9074387d69..2df98c574b3a 100644
--- a/dns/powerdns/files/pdns.conf
+++ b/dns/powerdns/files/pdns.conf
@@ -16,6 +16,15 @@
#launch=gsqlite
#gsqlite-database=<path to your SQLite database>
+# OpenDBX
+#launch=opendbx
+#opendbx-backend=mysql
+#opendbx-host=127.0.0.1
+#opendbx-database=pdns
+#opendbx-username=pdns
+#opendbx-password=pdns
+
+# Autogenerated configuration file template
#################################
# allow-axfr-ips If disabled, DO allow zonetransfers from these IP addresses
#
@@ -242,6 +251,21 @@
# soa-minimum-ttl=3600
#################################
+# soa-refresh-default Default SOA refresh
+#
+# soa-refresh-default=10800
+
+#################################
+# soa-retry-default Default SOA retry
+#
+# soa-retry-default=3600
+
+#################################
+# soa-expire-default Default SOA expire
+#
+# soa-expire-default=604800
+
+#################################
# soa-serial-offset Make sure that no SOA serial is less than this number
#
# soa-serial-offset=0
@@ -300,5 +324,3 @@
# wildcards Honor wildcards in the database
#
# wildcards=
-
-
diff --git a/dns/powerdns/files/pdns.in b/dns/powerdns/files/pdns.in
index ca99abb2963f..9c35fc092087 100644
--- a/dns/powerdns/files/pdns.in
+++ b/dns/powerdns/files/pdns.in
@@ -32,4 +32,7 @@ load_rc_config ${name}
required_files=${pdns_conf}
+monitor_cmd="${command} --daemon=no --guardian=no --control-console --loglevel=9"
+extra_commands="monitor"
+
run_rc_command "$1"
diff --git a/dns/powerdns/files/pdns_mysql.sql b/dns/powerdns/files/pdns_mysql.sql
index 278c5d56c61c..0db1b8665734 100644
--- a/dns/powerdns/files/pdns_mysql.sql
+++ b/dns/powerdns/files/pdns_mysql.sql
@@ -1,38 +1,50 @@
-create table domains (
- id INT auto_increment,
- name VARCHAR(255) NOT NULL,
- master VARCHAR(20) DEFAULT NULL,
- last_check INT DEFAULT NULL,
- type VARCHAR(6) NOT NULL,
- notified_serial INT DEFAULT NULL,
- account VARCHAR(40) DEFAULT NULL,
- primary key (id)
-)type=InnoDB;
-
-CREATE UNIQUE INDEX name_index ON domains(name);
+CREATE TABLE domains (
+ id INT auto_increment,
+ name VARCHAR(255) NOT NULL,
+ type VARCHAR(6) NOT NULL,
+ master VARCHAR(40) DEFAULT NULL,
+ account VARCHAR(40) DEFAULT NULL,
+ notified_serial INT DEFAULT NULL,
+ last_check INT DEFAULT NULL,
+CONSTRAINT pk_id
+ PRIMARY KEY (id),
+CONSTRAINT unq_name
+ UNIQUE (name)
+) type=InnoDB;
+
CREATE TABLE records (
- id INT auto_increment,
- domain_id INT DEFAULT NULL,
- name VARCHAR(255) DEFAULT NULL,
- type VARCHAR(6) DEFAULT NULL,
- content VARCHAR(255) DEFAULT NULL,
- ttl INT DEFAULT NULL,
- prio INT DEFAULT NULL,
- change_date INT DEFAULT NULL,
- primary key(id)
-)type=InnoDB;
-
-CREATE INDEX rec_name_index ON records(name);
-CREATE INDEX nametype_index ON records(name,type);
-CREATE INDEX domain_id ON records(domain_id);
-
-create table supermasters (
- ip VARCHAR(25) NOT NULL,
- nameserver VARCHAR(255) NOT NULL,
- account VARCHAR(40) DEFAULT NULL
+ id INT auto_increment,
+ domain_id INT DEFAULT NULL,
+ name VARCHAR(255) DEFAULT NULL,
+ type VARCHAR(6) DEFAULT NULL,
+ ttl INT DEFAULT NULL,
+ prio INT DEFAULT NULL,
+ content VARCHAR(255) DEFAULT NULL,
+ change_date INT DEFAULT NULL,
+CONSTRAINT pk_id
+ PRIMARY KEY (id),
+CONSTRAINT fk_domainid
+ FOREIGN KEY (domain_id)
+ REFERENCES domains(id)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
+) type=InnoDB;
+
+CREATE INDEX idx_rdomainid ON records(domain_id);
+CREATE INDEX idx_rname ON records(name);
+CREATE INDEX idx_rname_rtype ON records(name,type);
+
+
+CREATE TABLE supermasters (
+ ip VARCHAR(40) NOT NULL,
+ nameserver VARCHAR(255) NOT NULL,
+ account VARCHAR(40) DEFAULT NULL
);
-GRANT SELECT ON supermasters TO pdns;
-GRANT ALL ON domains TO pdns;
-GRANT ALL ON records TO pdns;
+CREATE INDEX idx_smip_smns ON supermasters(ip,nameserver);
+
+
+GRANT SELECT ON supermasters TO powerdns;
+GRANT ALL ON domains TO powerdns;
+GRANT ALL ON records TO powerdns;
diff --git a/dns/powerdns/files/pdns_postgresql.sql b/dns/powerdns/files/pdns_postgresql.sql
index c700a2aa6dc2..481cc98b21b6 100644
--- a/dns/powerdns/files/pdns_postgresql.sql
+++ b/dns/powerdns/files/pdns_postgresql.sql
@@ -1,40 +1,52 @@
-create table domains (
- id SERIAL PRIMARY KEY,
- name VARCHAR(255) NOT NULL,
- master VARCHAR(20) DEFAULT NULL,
- last_check INT DEFAULT NULL,
- type VARCHAR(6) NOT NULL,
- notified_serial INT DEFAULT NULL,
- account VARCHAR(40) DEFAULT NULL
+CREATE TABLE domains (
+ id SERIAL,
+ name VARCHAR(255) NOT NULL,
+ type VARCHAR(6) NOT NULL,
+ master VARCHAR(40) DEFAULT NULL,
+ account VARCHAR(40) DEFAULT NULL
+ notified_serial INT DEFAULT NULL,
+ last_check INT DEFAULT NULL,
+CONSTRAINT pk_id
+ PRIMARY KEY (id),
+CONSTRAINT unq_name
+ UNIQUE (name)
);
-CREATE UNIQUE INDEX name_index ON domains(name);
+
CREATE TABLE records (
- id SERIAL PRIMARY KEY,
- domain_id INT DEFAULT NULL,
- name VARCHAR(255) DEFAULT NULL,
- type VARCHAR(6) DEFAULT NULL,
- content VARCHAR(255) DEFAULT NULL,
- ttl INT DEFAULT NULL,
- prio INT DEFAULT NULL,
- change_date INT DEFAULT NULL,
- CONSTRAINT domain_exists
- FOREIGN KEY(domain_id) REFERENCES domains(id)
- ON DELETE CASCADE
+ id SERIAL,
+ domain_id INT DEFAULT NULL,
+ name VARCHAR(255) DEFAULT NULL,
+ type VARCHAR(6) DEFAULT NULL,
+ ttl INT DEFAULT NULL,
+ prio INT DEFAULT NULL,
+ content VARCHAR(255) DEFAULT NULL,
+ change_date INT DEFAULT NULL,
+CONSTRAINT pk_id
+ PRIMARY KEY (id),
+CONSTRAINT fk_domainid
+ FOREIGN KEY (domain_id)
+ REFERENCES domains(id)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
);
-CREATE INDEX rec_name_index ON records(name);
-CREATE INDEX nametype_index ON records(name,type);
-CREATE INDEX domain_id ON records(domain_id);
+CREATE INDEX idx_rdomainid ON records(domain_id);
+CREATE INDEX idx_rname ON records(name);
+CREATE INDEX idx_rname_rtype ON records(name,type);
+
-create table supermasters (
- ip VARCHAR(25) NOT NULL,
- nameserver VARCHAR(255) NOT NULL,
- account VARCHAR(40) DEFAULT NULL
+CREATE TABLE supermasters (
+ ip VARCHAR(40) NOT NULL,
+ nameserver VARCHAR(255) NOT NULL,
+ account VARCHAR(40) DEFAULT NULL
);
-GRANT SELECT ON supermasters TO pdns;
-GRANT ALL ON domains TO pdns;
-GRANT ALL ON domains_id_seq TO pdns;
-GRANT ALL ON records TO pdns;
-GRANT ALL ON records_id_seq TO pdns;
+CREATE INDEX idx_smip_smns ON supermasters(ip,nameserver);
+
+
+GRANT SELECT ON supermasters TO powerdns;
+GRANT ALL ON domains TO powerdns;
+GRANT ALL ON domains_id_seq TO powerdns;
+GRANT ALL ON records TO powerdns;
+GRANT ALL ON records_id_seq TO powerdns;
diff --git a/dns/powerdns/files/pdns_recursor.in b/dns/powerdns/files/pdns_recursor.in
deleted file mode 100644
index 4a3e0f10e33a..000000000000
--- a/dns/powerdns/files/pdns_recursor.in
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/sh
-#
-# $FreeBSD: /tmp/pcvs/ports/dns/powerdns/files/Attic/pdns_recursor.in,v 1.2 2006-02-20 20:46:57 dougb Exp $
-#
-
-# PROVIDE: pdns_recursor
-# REQUIRE: DAEMON
-# KEYWORD: shutdown
-
-#
-# Add the following lines to /etc/rc.conf to enable pdns_recursor:
-#
-#pdns_recursor_enable="YES"
-#
-# See http://rtfm.powerdns.com for flags.
-#
-
-. %%RC_SUBR%%
-
-name=pdns_recursor
-rcvar=`set_rcvar`
-
-command=%%PREFIX%%/sbin/pdns_recursor
-
-# set defaults
-
-pdns_recursor_enable=${pdns_recursor_enable:-"NO"}
-pdns_recursor_conf=${pdns_recursor_conf:-"%%PREFIX%%/etc/recursor.conf"}
-pdns_recursor_flags=${pdns_recursor_flags:-""}
-
-load_rc_config ${name}
-
-required_files=${pdns_recursor_conf}
-
-run_rc_command "$1"
diff --git a/dns/powerdns/files/pdns_sqlite.sql b/dns/powerdns/files/pdns_sqlite.sql
index f0f831fb2977..a7f8be90470a 100644
--- a/dns/powerdns/files/pdns_sqlite.sql
+++ b/dns/powerdns/files/pdns_sqlite.sql
@@ -1,33 +1,45 @@
-create table domains (
- id INTEGER PRIMARY KEY,
- name VARCHAR(255) NOT NULL,
- master VARCHAR(20) DEFAULT NULL,
- last_check INTEGER DEFAULT NULL,
- type VARCHAR(6) NOT NULL,
- notified_serial INTEGER DEFAULT NULL,
- account VARCHAR(40) DEFAULT NULL
+CREATE TABLE domains (
+ id INT AUTOINCREMENT,
+ name VARCHAR(255) NOT NULL,
+ type VARCHAR(6) NOT NULL,
+ master VARCHAR(40) DEFAULT NULL,
+ account VARCHAR(40) DEFAULT NULL,
+ notified_serial INT DEFAULT NULL,
+ last_check INT DEFAULT NULL,
+CONSTRAINT pk_id
+ PRIMARY KEY (id),
+CONSTRAINT unq_name
+ UNIQUE (name)
);
-CREATE UNIQUE INDEX name_index ON domains(name);
CREATE TABLE records (
- id INTEGER PRIMARY KEY,
- domain_id INTEGER DEFAULT NULL,
- name VARCHAR(255) DEFAULT NULL,
- type VARCHAR(6) DEFAULT NULL,
- content VARCHAR(255) DEFAULT NULL,
- ttl INTEGER DEFAULT NULL,
- prio INTEGER DEFAULT NULL,
- change_date INTEGER DEFAULT NULL
+ id INT AUTOINCREMENT,
+ domain_id INT DEFAULT NULL,
+ name VARCHAR(255) DEFAULT NULL,
+ type VARCHAR(6) DEFAULT NULL,
+ ttl INT DEFAULT NULL,
+ prio INT DEFAULT NULL,
+ content VARCHAR(255) DEFAULT NULL,
+ change_date INT DEFAULT NULL,
+CONSTRAINT pk_id
+ PRIMARY KEY (id),
+CONSTRAINT fk_domainid
+ FOREIGN KEY (domain_id)
+ REFERENCES domains(id)
+ ON UPDATE CASCADE
+ ON DELETE CASCADE
);
-CREATE INDEX rec_name_index ON records(name);
-CREATE INDEX nametype_index ON records(name,type);
-CREATE INDEX domain_id ON records(domain_id);
+CREATE INDEX idx_rdomainid ON records(domain_id);
+CREATE INDEX idx_rname ON records(name);
+CREATE INDEX idx_rname_rtype ON records(name,type);
-create table supermasters (
- ip VARCHAR(25) NOT NULL,
- nameserver VARCHAR(255) NOT NULL,
- account VARCHAR(40) DEFAULT NULL
+
+CREATE TABLE supermasters (
+ ip VARCHAR(40) NOT NULL,
+ nameserver VARCHAR(255) NOT NULL,
+ account VARCHAR(40) DEFAULT NULL
);
+CREATE INDEX idx_smip_smns ON supermasters(ip,nameserver);
diff --git a/dns/powerdns/files/pkg-message.in b/dns/powerdns/files/pkg-message.in
index bb7595598837..b0b0983b2e15 100644
--- a/dns/powerdns/files/pkg-message.in
+++ b/dns/powerdns/files/pkg-message.in
@@ -4,12 +4,7 @@
pdns_enable="YES"
- If you want to use the powerdns recursor,
- you need the following additional line in /etc/rc.conf
-
- pdns_recursor_enable="YES"
-
- Configuration templates are available in %%PREFIX%%/etc
+ Configuration templates are available in %%PREFIX%%/etc/pdns
as pdns.conf-dist.
*******************************************************************
diff --git a/dns/powerdns/pkg-plist b/dns/powerdns/pkg-plist
index 5e5921e60e88..923d58226d22 100644
--- a/dns/powerdns/pkg-plist
+++ b/dns/powerdns/pkg-plist
@@ -3,24 +3,39 @@ bin/zone2ldap
bin/zone2sql
sbin/pdns_server
%%WITHMYSQL%%lib/libgmysqlbackend.a
+%%WITHMYSQL%%lib/libgmysqlbackend.la
%%WITHMYSQL%%lib/libgmysqlbackend.so
%%WITHMYSQL%%lib/libgmysqlbackend.so.0
-%%WITHSQLLITE%%lib/libgsqlitebackend.a
-%%WITHSQLLITE%%lib/libgsqlitebackend.so
-%%WITHSQLLITE%%lib/libgsqlitebackend.so.0
-%%WITHLDAP%%lib/libldapbackend.a
-%%WITHLDAP%%lib/libldapbackend.so
-%%WITHLDAP%%lib/libldapbackend.so.0
+%%WITHSQLITE%%lib/libgsqlitebackend.a
+%%WITHSQLITE%%lib/libgsqlitebackend.la
+%%WITHSQLITE%%lib/libgsqlitebackend.so
+%%WITHSQLITE%%lib/libgsqlitebackend.so.0
+%%WITHSQLITE3%%lib/libgsqlitebackend.a
+%%WITHSQLITE3%%lib/libgsqlitebackend.la
+%%WITHSQLITE3%%lib/libgsqlitebackend.so
+%%WITHSQLITE3%%lib/libgsqlitebackend.so.0
+%%WITHOPENLDAP%%lib/libldapbackend.a
+%%WITHOPENLDAP%%lib/libldapbackend.la
+%%WITHOPENLDAP%%lib/libldapbackend.so
+%%WITHOPENLDAP%%lib/libldapbackend.so.0
+%%WITHOPENDBX%%lib/libopendbxbackend.a
+%%WITHOPENDBX%%lib/libopendbxbackend.la
+%%WITHOPENDBX%%lib/libopendbxbackend.so
+%%WITHOPENDBX%%lib/libopendbxbackend.so.0
+%%WITHGEO%%lib/libgeobackend.a
+%%WITHGEO%%lib/libgeobackend.la
+%%WITHGEO%%lib/libgeobackend.so
+%%WITHGEO%%lib/libgeobackend.so.0
lib/libpipebackend.a
lib/libpipebackend.la
lib/libpipebackend.so
lib/libpipebackend.so.0
-%%RECURSOR%%sbin/pdns_recursor
-@unexec if cmp -s %D/etc/pdns.conf %D/etc/pdns.conf-dist; then rm -f %D/etc/pdns.conf; fi
-etc/pdns.conf-dist
+@unexec if cmp -s %D/etc/pdns/pdns.conf %D/etc/pdns/pdns.conf-dist; then rm -f %D/etc/pdns/pdns.conf; fi
+etc/pdns/pdns.conf-dist
@exec [ -f %B/pdns.conf ] || cp %B/%f %B/pdns.conf
%%PORTDOCS%%share/examples/powerdns/pdns.conf
%%PORTDOCS%%share/examples/powerdns/pdns_mysql.sql
%%PORTDOCS%%share/examples/powerdns/pdns_postgresql.sql
%%PORTDOCS%%share/examples/powerdns/pdns_sqlite.sql
%%PORTDOCS%%@dirrm share/examples/powerdns
+@dirrmtry etc/pdns