--- /dev/null
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT(mysqlcbackend.cc)
+AC_CANONICAL_SYSTEM
+AM_INIT_AUTOMAKE(mysqlbackend, 2.9)
+
+AC_PREFIX_DEFAULT(/usr)
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+AC_DISABLE_STATIC
+AM_PROG_LIBTOOL
+AC_LANG_CPLUSPLUS
+
+#
+# Location of MySQL installation
+#
+AC_ARG_WITH(mysql,
+ [ --with-mysql=<path> root directory path of MySQL installation],
+ [MYSQL_lib_check="$withval/lib/mysql $with_mysql/lib"
+MYSQL_inc_check="$withval/include/mysql"],
+ [MYSQL_lib_check="/usr/local/mysql/lib/mysql /usr/local/lib/mysql /opt/mysql/lib/mysql /usr/lib/mysql /usr/local/mysql/lib /usr/local/lib /opt/mysql/lib /usr/lib"
+MYSQL_inc_check="/usr/local/mysql/include/mysql /usr/local/include/mysql /opt/mysql/include/mysql /opt/mysql/include /usr/include/mysql"])
+
+AC_ARG_WITH(mysql-lib,
+ [ --with-mysql-lib=<path> directory path of MySQL library installation],
+ [MYSQL_lib_check="$withval/lib/mysql $withval/mysql $withval"])
+
+AC_ARG_WITH(mysql-includes,
+ [ --with-mysql-includes=<path>
+ directory path of MySQL header installation],
+ [MYSQL_inc_check="$withval/include/mysql $withval/mysql $withval"])
+
+AC_MSG_CHECKING([for MySQL library directory])
+MYSQL_libdir=
+for m in $MYSQL_lib_check; do
+ if test -d "$m" && \
+ (test -f "$m/libmysqlclient.so" || test -f "$m/libmysqlclient.a")
+ then
+ MYSQL_libdir=$m
+ break
+ fi
+done
+
+if test -z "$MYSQL_libdir"; then
+ AC_MSG_ERROR([Didn't find the mysql library dir in '$MYSQL_lib_check'])
+fi
+
+case "$MYSQL_libdir" in
+ /* ) ;;
+ * ) AC_MSG_ERROR([The MySQL library directory ($MYSQL_libdir) must be an absolute path.]) ;;
+esac
+
+AC_MSG_RESULT([$MYSQL_libdir])
+
+case "$MYSQL_libdir" in
+ /usr/lib) ;;
+ *) LDFLAGS="$LDFLAGS -L${MYSQL_libdir}" ;;
+esac
+
+AC_MSG_CHECKING([for MySQL include directory])
+MYSQL_incdir=
+for m in $MYSQL_inc_check; do
+ if test -d "$m" && test -f "$m/mysql.h"
+ then
+ MYSQL_incdir=$m
+ break
+ fi
+done
+
+if test -z "$MYSQL_incdir"; then
+ AC_MSG_ERROR([Didn't find the mysql include dir in '$MYSQL_inc_check'])
+fi
+
+case "$MYSQL_incdir" in
+ /* ) ;;
+ * ) AC_MSG_ERROR([The MySQL include directory ($MYSQL_incdir) must be an absolute path.]) ;;
+esac
+
+AC_MSG_RESULT([$MYSQL_incdir])
+
+CPPFLAGS="$CPPFLAGS -I${MYSQL_incdir}"
+
+dnl Checks for programs.
+
+dnl Checks for libraries.
+dnl Replace `main' with a function in -ldl:
+AC_CHECK_LIB(dl, main)
+AC_CHECK_LIB(z, main)
+AC_CHECK_LIB(mysqlclient, mysql_store_result)
+dnl Replace `main' with a function in -lpthread:
+AC_CHECK_LIB(pthread, main)
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(unistd.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+
+dnl Checks for pdns functions
+dnl Check for pdns
+
+search_pdns=1
+
+AC_ARG_WITH(pdns-includes, [ --with-pdns-includes=PATH Specify location of pdns headers],
+[ if test x"$withval" = x"no"; then
+ search_pdns=0
+ else
+ #if test x"$withval" != x"yes"; then
+ if test -d "$withval"; then
+ PDNS_INCLUDES="-I$withval"
+ search_pdns=0
+ has_pdns=1
+ fi
+ fi
+])
+
+
+AC_DEFUN(AC_CHECK_PDNS,
+[ if test x"$search_pdns" != x"0"; then
+ if test -f "$1/$2"; then
+ AC_MSG_RESULT($5)
+ PDNS_LIBS="$3"
+ PDNS_INCLUDES="$4"
+ search_pdns=0
+ has_pdns=1
+ fi
+ fi
+])
+
+AC_DEFUN(AC_SEARCH_PDNS,
+[ AC_MSG_CHECKING("location of pdns logger.hh include")
+ AC_CHECK_PDNS($HOME/programming/pdns, logger.hh,,-I$HOME/programming/pdns, "found in $HOME/programming/pdns")
+ AC_CHECK_PDNS(../pdns, logger.hh,,-I../pdns, "found in ../pdns")
+ AC_CHECK_PDNS(../pdns-1.2, logger.hh,,-I../pdns-1.2, "found in ../pdns-1.2")
+])
+
+if test x"$search_pdns" != x"0"; then
+ AC_SEARCH_PDNS()
+fi
+
+if test x"$has_pdns" = x"1"; then
+ echo Found pdns include file, assuming working and compliant pdns
+else
+ echo
+ echo Did not find pdns include file
+ echo
+ exit 1
+fi
+
+CPPFLAGS="$CPPFLAGS $PDNS_INCLUDES"
+
+
+dnl Checks for library functions.
+
+dnl Check for STL
+AC_CHECK_HEADER(sstream,dontneedstl=1)
+
+if test "$dontneedstl" != "1"
+then
+search_stl=1
+
+AC_ARG_WITH(stl-includes, [ --with-stl-includes=PATH Specify location of STL headers],
+[ if test x"$withval" = x"no"; then
+ search_stl=0
+ else
+ #if test x"$withval" != x"yes"; then
+ if test -d "$withval"; then
+ STL_INCLUDES="-I$withval"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+])
+
+
+
+AC_ARG_WITH(stl-libs, [ --with-stl-libs=PATH Specify location of STL libs],
+[ if test x"$withval" = x"no"; then
+ search_stl=0
+ else
+ #if test x"$withval" != x"yes"; then
+ if test -d "$withval"; then
+ STL_LIBS="$LIBS -L$withval -lstlport_gcc"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+])
+
+AC_DEFUN(AC_CHECK_STL,
+[ if test x"$search_stl" != x"0"; then
+ if test -f "$1/$2"; then
+ AC_MSG_RESULT($5)
+ STL_LIBS="$3"
+ STL_INCLUDES="$4"
+ search_stl=0
+ has_stl=1
+ fi
+ fi
+])
+
+AC_DEFUN(AC_SEARCH_STL,
+[ AC_MSG_CHECKING("location of sstream")
+ AC_CHECK_STL(/usr/include, sstream, -lstlport_gcc,, "found in /usr/include")
+ AC_CHECK_STL(/usr/include/stlport, sstream, -lstlport_gcc, -I/usr/include/stlport, "found in /usr/include/stlport")
+ AC_CHECK_STL(/usr/include, sstream, -lstlport_gcc,, "found in /usr/include")
+ AC_CHECK_STL(/usr/local/include, sstream, -L/usr/local/lib -lstlport_gcc, -I/usr/local/include, "found in /usr/local")
+ AC_CHECK_STL(/usr/local/include/stl, sstream, -L/usr/local/lib -L/usr/local/lib/stl -lstlport_gcc, -I/usr/local/include/stl, "found in /usr/local/include/stl")
+ AC_CHECK_STL(/home/ahu/download/STLport-4.0/stlport, sstream,-L/home/ahu/download/STLport-4.0/lib/ -lstlport_gcc, -I/home/ahu/download/STLport-4.0/stlport/, "found in /home/ahu/download/STLport-4.0/stlport")
+ AC_CHECK_STL($HOME/STLport-4.0/stlport, sstream,-L$HOME/STLport-4.0/lib/ -lstlport_gcc, -I$HOME/STLport-4.0/stlport/, "found in $HOME/STLport-4.0/stlport")
+])
+
+if test x"$search_stl" != x"0"; then
+ AC_SEARCH_STL()
+fi
+
+if test x"$has_stl" = x"1"; then
+ echo Found sstream include file, assuming working and compliant STL
+else
+ echo
+ echo Did not find sstream include file, this probably means that your STL is not
+ echo compliant - the default gcc libstdc++ isn\'t. Download STLport-4.0 from
+ echo http://www.stlport.org, or use --with-stl-includes and --with-stl-libs
+ echo to specify the location of your STL.
+ echo
+ exit 1
+fi
+
+CPPFLAGS="$CPPFLAGS $STL_INCLUDES $MYSQLPP_INCLUDES"
+LIBS="$LIBS $STL_LIBS"
+fi
+
+AM_CONFIG_HEADER(config.h)
+AC_OUTPUT(Makefile buildroot.sh)
--- /dev/null
+// $Id: mysqlcbackend.cc,v 1.1 2002/11/27 15:29:50 ahu Exp $
+#include <string>
+#include <map>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sstream>
+
+using namespace std;
+
+#include <dns.hh>
+#include <dnsbackend.hh>
+#include <mysqlcbackend.hh>
+#include <dnspacket.hh>
+#include <ueberbackend.hh>
+#include <ahuexception.hh>
+#include <logger.hh>
+#include <arguments.hh>
+
+static string backendName="[MySQLbackend]";
+
+string MySQLBackend::sqlEscape(const string &name)
+{
+ string a;
+
+ for(string::const_iterator i=name.begin();i!=name.end();++i)
+
+ if(*i=='\'' || *i=='\\'){
+ a+='\\';
+ a+=*i;
+ }
+ else
+ a+=*i;
+ return a;
+
+}
+
+MySQLBackend::MySQLBackend(const string &suffix)
+{
+ mysql_init(&db);
+ setArgPrefix("mysql"+suffix);
+ if (!mysql_real_connect(&db,getArg("host").c_str(),
+ getArg("user").c_str(),
+ getArg("password").c_str(),
+ getArg("dbname").c_str(),
+ 0,
+ getArg("socket").empty() ?
+ NULL : getArg("socket").c_str(),0)) {
+ L<<Logger::Error<<backendName<<" Failed to connect to database: Error: "<<mysql_error(&db)<<endl;
+ throw(AhuException(backendName+string(" Failed to connect to database: Error: ")+mysql_error(&db)));
+ }
+ d_table=getArg("table");
+ L<<Logger::Warning<<backendName<<" MySQL connection succeeded"<<endl;
+}
+
+MySQLBackend::~MySQLBackend()
+{
+ L<<Logger::Warning<<backendName<<" MySQL connection closed"<<endl;
+ mysql_close(&db);
+}
+
+void MySQLBackend::lookup(const QType &qtype,const string &qname, DNSPacket *pkt_p, int zoneId )
+{
+ string query;
+
+ // suport wildcard searches
+ if(qname[0]!='%')
+ query="select content,ttl,prio,type,domain_id,name,change_date from "+d_table+" where name='";
+ else
+ query="select content,ttl,prio,type,domain_id,name,change_date from "+d_table+" where name like '";
+
+ if(qname.find_first_of("'\\")!=string::npos)
+ query+=sqlEscape(qname);
+ else
+ query+=qname;
+
+ query+="'";
+ if(qtype.getCode()!=255) { // ANY
+ query+=" and type='";
+ query+=qtype.getName();
+ query+="'";
+ }
+
+ if(zoneId>0) {
+ query+=" and domain_id=";
+ ostringstream o;
+ o<<zoneId;
+ query+=o.str();
+ }
+
+ DLOG(L<< backendName<<" Query: '" << query << "'"<<endl);
+
+ if(arg().mustDo("query-logging"))
+ L<<Logger::Error<<"Query: '"<<query<<"'"<<endl;
+
+ if(mysql_query(&db,query.c_str()))
+ throw AhuException("Failed to execute mysql_query '"+query+"'. Error: "+string(mysql_error(&db)));
+
+ if(!(d_res = mysql_use_result(&db)))
+ throw AhuException("mysql_use_result failed. Error: "+string(mysql_error(&db)));
+
+ d_qname=qname;
+ d_qtype=qtype;
+}
+
+bool MySQLBackend::list(int domain_id )
+{
+ DLOG(L<<backendName<<" MySQLBackend constructing handle for list of domain id '"<<domain_id<<"'"<<endl);
+
+ ostringstream o;
+ o<<"select content,ttl,prio,type,domain_id,name,change_date from "+d_table+" where domain_id="<<domain_id;
+
+ if(mysql_query(&db, o.str().c_str()))
+ throw AhuException("Failed to execute mysql_query '"+o.str()+"'. Error: "+string(mysql_error(&db)));
+
+ if(!(d_res=mysql_use_result(&db)))
+ throw AhuException("mysql_use_result failed. Error: "+string(mysql_error(&db)));
+
+ d_qname=""; // this tells 'get' what to do
+ return true;
+}
+
+bool MySQLBackend::get(DNSResourceRecord &r)
+{
+ // L << "MySQLBackend get() was called for "<<qtype.getName() << " record: "<<qname<<endl;
+ MYSQL_ROW row;
+
+ if(!(row = mysql_fetch_row(d_res))) { // end
+ mysql_free_result(d_res);
+ return false;
+ }
+
+ r.content=row[0]; // content
+
+ if(!row[1]) // ttl
+ r.ttl=0;
+ else
+ r.ttl=atoi(row[1]);
+
+
+ if(row[2])
+ r.priority=atoi(row[2]);;
+
+ if(!d_qname.empty()) // use this to distinguish between select with 'name' field (list()) and one without
+ r.qname=d_qname;
+ else
+ r.qname=row[5];
+
+ r.qtype=(const char *)row[3];
+
+ r.domain_id=atoi(row[4]);
+ if(!row[6])
+ r.last_modified=0;
+ else
+ r.last_modified=atoi(row[6]);
+
+ //L << "MySQLBackend get() returning a rr"<<endl;
+
+ return true;
+}
+
+class MySQLFactory : public BackendFactory
+{
+public:
+ MySQLFactory() : BackendFactory("mysql") {}
+
+ void declareArguments(const string &suffix="")
+ {
+ declare(suffix,"dbname","Pdns backend database name to connect to","powerdns");
+ declare(suffix,"user","Pdns backend user to connect as","powerdns");
+ declare(suffix,"host","Pdns backend host to connect to","");
+ declare(suffix,"password","Pdns backend password to connect with","");
+ declare(suffix,"socket","Pdns backend socket to connect to","");
+ declare(suffix,"table","Name of table to use","records");
+ }
+
+ DNSBackend *make(const string &suffix="")
+ {
+ return new MySQLBackend(suffix);
+ }
+};
+
+
+//! Magic class that is activated when the dynamic library is loaded
+class Loader
+{
+public:
+ //! This reports us to the main UeberBackend class
+ Loader()
+ {
+ BackendMakers().report(new MySQLFactory);
+ L<<Logger::Notice<<backendName<<" This is the mysql module version "VERSION" ("__DATE__", "__TIME__") reporting"<<endl;
+ }
+};
+static Loader loader;