]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/extra/m_pgsql.cpp
Newly revamped ziplinks module, work of psychon.. resolves (a lot) of problems with...
[user/henk/code/inspircd.git] / src / modules / extra / m_pgsql.cpp
index 76259a35b4ba9a7ba47f277a66a113dffcd24669..6b8638b7b973c4b10e6fa30a0f48601a66e532df 100644 (file)
@@ -2,7 +2,7 @@
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
- *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
+ *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
  * See: http://www.inspircd.org/wiki/index.php/Credits
  *
  * This program is free but copyrighted software; see
  * ---------------------------------------------------
  */
 
+#include "inspircd.h"
 #include <cstdlib>
 #include <sstream>
-#include <string>
-#include <deque>
-#include <map>
 #include <libpq-fe.h>
-
 #include "users.h"
 #include "channels.h"
 #include "modules.h"
-#include "inspircd.h"
 #include "configreader.h"
-
 #include "m_sqlv2.h"
 
 /* $ModDesc: PostgreSQL Service Provider module for all other m_sql* modules, uses v2 of the SQL API */
@@ -34,7 +29,7 @@
 
 /* SQLConn rewritten by peavey to
  * use EventHandler instead of
- * InspSocket. This is much neater
+ * BufferedSocket. This is much neater
  * and gives total control of destroy
  * and delete of resources.
  */
@@ -86,13 +81,13 @@ std::string SQLhost::GetDSN()
        return conninfo.str();
 }
 
-class ReconnectTimer : public InspTimer
+class ReconnectTimer : public Timer
 {
 private:
+ private:
        Module* mod;
 public:
+ public:
        ReconnectTimer(InspIRCd* SI, Module* m)
-       : InspTimer(5, SI->Time(), false), mod(m)
+       : Timer(5, SI->Time(), false), mod(m)
        {
        }
        virtual void Tick(time_t TIME);
@@ -112,11 +107,11 @@ class SQLresolver : public Resolver
        {
        }
 
-       virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached);
+       virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached, int resultnum = 0);
 
        virtual void OnError(ResolverError e, const std::string &errormessage)
        {
-               ServerInstance->Log(DEBUG, "PgSQL: DNS lookup failed (%s), dying horribly", errormessage.c_str());
+               ServerInstance->Logs->Log("m_pgsql",DEBUG, "PgSQL: DNS lookup failed (%s), dying horribly", errormessage.c_str());
        }
 };
 
@@ -137,8 +132,8 @@ class PgSQLresult : public SQLresult
        SQLfieldList* fieldlist;
        SQLfieldMap* fieldmap;
 public:
-       PgSQLresult(Module* self, Module* to, unsigned long id, PGresult* result)
-       : SQLresult(self, to, id), res(result), currentrow(0), fieldlist(NULL), fieldmap(NULL)
+       PgSQLresult(Module* self, Module* to, unsigned long rid, PGresult* result)
+       : SQLresult(self, to, rid), res(result), currentrow(0), fieldlist(NULL), fieldmap(NULL)
        {
                rows = PQntuples(res);
                cols = PQnfields(res);
@@ -148,10 +143,10 @@ public:
        {
                /* If we allocated these, free them... */
                if(fieldlist)
-                       DELETE(fieldlist);
+                       delete fieldlist;
 
                if(fieldmap)
-                       DELETE(fieldmap);
+                       delete fieldmap;
 
                PQclear(res);
        }
@@ -224,9 +219,9 @@ public:
 
                if(currentrow < PQntuples(res))
                {
-                       int cols = PQnfields(res);
+                       int ncols = PQnfields(res);
 
-                       for(int i = 0; i < cols; i++)
+                       for(int i = 0; i < ncols; i++)
                        {
                                fieldlist->push_back(GetValue(currentrow, i));
                        }
@@ -253,9 +248,9 @@ public:
 
                if(currentrow < PQntuples(res))
                {
-                       int cols = PQnfields(res);
+                       int ncols = PQnfields(res);
 
-                       for(int i = 0; i < cols; i++)
+                       for(int i = 0; i < ncols; i++)
                        {
                                fieldmap->insert(std::make_pair(ColName(i), GetValue(currentrow, i)));
                        }
@@ -272,9 +267,9 @@ public:
 
                if(currentrow < PQntuples(res))
                {
-                       int cols = PQnfields(res);
+                       int ncols = PQnfields(res);
 
-                       for(int i = 0; i < cols; i++)
+                       for(int i = 0; i < ncols; i++)
                        {
                                fl->push_back(GetValue(currentrow, i));
                        }
@@ -291,9 +286,9 @@ public:
 
                if(currentrow < PQntuples(res))
                {
-                       int cols = PQnfields(res);
+                       int ncols = PQnfields(res);
 
-                       for(int i = 0; i < cols; i++)
+                       for(int i = 0; i < ncols; i++)
                        {
                                fm->insert(std::make_pair(ColName(i), GetValue(currentrow, i)));
                        }
@@ -306,12 +301,12 @@ public:
 
        virtual void Free(SQLfieldMap* fm)
        {
-               DELETE(fm);
+               delete fm;
        }
 
        virtual void Free(SQLfieldList* fl)
        {
-               DELETE(fl);
+               delete fl;
        }
 };
 
@@ -319,8 +314,8 @@ public:
  */
 class SQLConn : public EventHandler
 {
 private:
-       InspIRCd*               Instance;
+ private:
+       InspIRCd*               Instance;
        SQLhost                 confhost;       /* The <database> entry */
        Module*                 us;                     /* Pointer to the SQL provider itself */
        PGconn*                 sql;            /* PgSQL database connection handle */
@@ -329,14 +324,14 @@ class SQLConn : public EventHandler
        QueryQueue              queue;          /* Queue of queries waiting to be executed on this connection */
        time_t                  idle;           /* Time we last heard from the database */
 
 public:
+ public:
        SQLConn(InspIRCd* SI, Module* self, const SQLhost& hi)
        : EventHandler(), Instance(SI), confhost(hi), us(self), sql(NULL), status(CWRITE), qinprog(false)
        {
                idle = this->Instance->Time();
                if(!DoConnect())
                {
-                       Instance->Log(DEFAULT, "WARNING: Could not connect to database with id: " + ConvToStr(hi.id));
+                       Instance->Logs->Log("m_pgsql",DEFAULT, "WARNING: Could not connect to database with id: " + ConvToStr(hi.id));
                        DelayReconnect();
                }
        }
@@ -388,7 +383,7 @@ class SQLConn : public EventHandler
 
                if (!this->Instance->SE->AddFd(this))
                {
-                       Instance->Log(DEBUG, "BUG: Couldn't add pgsql socket to socket engine");
+                       Instance->Logs->Log("m_pgsql",DEBUG, "BUG: Couldn't add pgsql socket to socket engine");
                        return false;
                }
 
@@ -626,7 +621,7 @@ class SQLConn : public EventHandler
 #endif
                                                        if(error)
                                                        {
-                                                               Instance->Log(DEBUG, "BUG: Apparently PQescapeStringConn() failed somehow...don't know how or what to do...");
+                                                               Instance->Logs->Log("m_pgsql",DEBUG, "BUG: Apparently PQescapeStringConn() failed somehow...don't know how or what to do...");
                                                        }
 
                                                        /* Incremenet queryend to the end of the newly escaped parameter */
@@ -637,7 +632,7 @@ class SQLConn : public EventHandler
                                                }
                                                else
                                                {
-                                                       Instance->Log(DEBUG, "BUG: Found a substitution location but no parameter to substitute :|");
+                                                       Instance->Logs->Log("m_pgsql",DEBUG, "BUG: Found a substitution location but no parameter to substitute :|");
                                                        break;
                                                }
                                        }
@@ -703,7 +698,7 @@ class SQLConn : public EventHandler
                        }
                        else
                        {
-                               Instance->Log(DEBUG, "BUG: PQsocket cant be removed from socket engine!");
+                               Instance->Logs->Log("m_pgsql",DEBUG, "BUG: PQsocket cant be removed from socket engine!");
                        }
                }
 
@@ -718,30 +713,32 @@ class SQLConn : public EventHandler
 
 class ModulePgSQL : public Module
 {
 private:
+ private:
        ConnMap connections;
        unsigned long currid;
        char* sqlsuccess;
        ReconnectTimer* retimer;
 
 public:
+ public:
        ModulePgSQL(InspIRCd* Me)
        : Module::Module(Me), currid(0)
        {
-               ServerInstance->UseInterface("SQLutils");
+               ServerInstance->Modules->UseInterface("SQLutils");
 
                sqlsuccess = new char[strlen(SQLSUCCESS)+1];
 
                strlcpy(sqlsuccess, SQLSUCCESS, strlen(SQLSUCCESS));
 
-               if (!ServerInstance->PublishFeature("SQL", this))
+               if (!ServerInstance->Modules->PublishFeature("SQL", this))
                {
                        throw ModuleException("BUG: PgSQL Unable to publish feature 'SQL'");
                }
 
                ReadConf();
 
-               ServerInstance->PublishInterface("SQL", this);
+               ServerInstance->Modules->PublishInterface("SQL", this);
+               Implementation eventlist[] = { I_OnUnloadModule, I_OnRequest, I_OnRehash, I_OnUserRegister, I_OnCheckReady, I_OnUserDisconnect };
+               ServerInstance->Modules->Attach(eventlist, this, 6);
        }
 
        virtual ~ModulePgSQL()
@@ -750,17 +747,13 @@ class ModulePgSQL : public Module
                        ServerInstance->Timers->DelTimer(retimer);
                ClearAllConnections();
                delete[] sqlsuccess;
-               ServerInstance->UnpublishInterface("SQL", this);
-               ServerInstance->UnpublishFeature("SQL");
-               ServerInstance->DoneWithInterface("SQLutils");
+               ServerInstance->Modules->UnpublishInterface("SQL", this);
+               ServerInstance->Modules->UnpublishFeature("SQL");
+               ServerInstance->Modules->DoneWithInterface("SQLutils");
        }
 
-       void Implements(char* List)
-       {
-               List[I_OnUnloadModule] = List[I_OnRequest] = List[I_OnRehash] = List[I_OnUserRegister] = List[I_OnCheckReady] = List[I_OnUserDisconnect] = 1;
-       }
 
-       virtual void OnRehash(userrec* user, const std::string &parameter)
+       virtual void OnRehash(User* user, const std::string &parameter)
        {
                ReadConf();
        }
@@ -803,7 +796,6 @@ class ModulePgSQL : public Module
                {
                        SQLhost host;
                        int ipvalid;
-                       insp_inaddr blargle;
 
                        host.id         = conf.ReadValue("database", "id", i);
                        host.host       = conf.ReadValue("database", "hostname", i);
@@ -816,7 +808,18 @@ class ModulePgSQL : public Module
                        if (HasHost(host))
                                continue;
 
-                       ipvalid = insp_aton(host.host.c_str(), &blargle);
+#ifdef IPV6
+                       if (strchr(host.host.c_str(),':'))
+                       {
+                               in6_addr blargle;
+                               ipvalid = inet_pton(AF_INET6, host.host.c_str(), &blargle);
+                       }
+                       else
+#endif
+                       {
+                               in_addr blargle;
+                               ipvalid = inet_aton(host.host.c_str(), &blargle);
+                       }
 
                        if(ipvalid > 0)
                        {
@@ -843,7 +846,7 @@ class ModulePgSQL : public Module
                        else
                        {
                                /* Invalid address family, die horribly. */
-                               ServerInstance->Log(DEBUG, "BUG: insp_aton failed returning -1, oh noes.");
+                               ServerInstance->Logs->Log("m_pgsql",DEBUG, "BUG: insp_aton failed returning -1, oh noes.");
                        }
                }
        }
@@ -855,7 +858,7 @@ class ModulePgSQL : public Module
                {
                        if (!HostInConf(iter->second->GetConfHost()))
                        {
-                               DELETE(iter->second);
+                               delete iter->second;
                                safei = iter;
                                --iter;
                                connections.erase(safei);
@@ -869,7 +872,7 @@ class ModulePgSQL : public Module
                while ((i = connections.begin()) != connections.end())
                {
                        connections.erase(i);
-                       DELETE(i->second);
+                       delete i->second;
                }
        }
 
@@ -877,7 +880,7 @@ class ModulePgSQL : public Module
        {
                if (HasHost(hi))
                {
-                       ServerInstance->Log(DEFAULT, "WARNING: A pgsql connection with id: %s already exists, possibly due to DNS delay. Aborting connection attempt.", hi.id.c_str());
+                       ServerInstance->Logs->Log("m_pgsql",DEFAULT, "WARNING: A pgsql connection with id: %s already exists, possibly due to DNS delay. Aborting connection attempt.", hi.id.c_str());
                        return;
                }
 
@@ -895,7 +898,7 @@ class ModulePgSQL : public Module
                {
                        if (conn == iter->second)
                        {
-                               DELETE(iter->second);
+                               delete iter->second;
                                connections.erase(iter);
                                break;
                        }
@@ -904,7 +907,7 @@ class ModulePgSQL : public Module
                ServerInstance->Timers->AddTimer(retimer);
        }
 
-       virtual char* OnRequest(Request* request)
+       virtual const char* OnRequest(Request* request)
        {
                if(strcmp(SQLREQID, request->GetId()) == 0)
                {
@@ -951,18 +954,21 @@ class ModulePgSQL : public Module
 
        virtual Version GetVersion()
        {
-               return Version(1, 1, 0, 0, VF_VENDOR|VF_SERVICEPROVIDER, API_VERSION);
+               return Version("$Id$", VF_VENDOR|VF_SERVICEPROVIDER, API_VERSION);
        }
 };
 
 /* move this here to use AddConn, rather that than having the whole
  * module above SQLConn, since this is buggin me right now :/
  */
-void SQLresolver::OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
+void SQLresolver::OnLookupComplete(const std::string &result, unsigned int ttl, bool cached, int resultnum)
 {
-       host.ip = result;
-       ((ModulePgSQL*)mod)->AddConn(host);
-       ((ModulePgSQL*)mod)->ClearOldConnections();
+       if (!resultnum)
+       {
+               host.ip = result;
+               ((ModulePgSQL*)mod)->AddConn(host);
+               ((ModulePgSQL*)mod)->ClearOldConnections();
+       }
 }
 
 void ReconnectTimer::Tick(time_t time)
@@ -975,26 +981,4 @@ void SQLConn::DelayReconnect()
        ((ModulePgSQL*)us)->ReconnectConn(this);
 }
 
-
-class ModulePgSQLFactory : public ModuleFactory
-{
- public:
-       ModulePgSQLFactory()
-       {
-       }
-
-       ~ModulePgSQLFactory()
-       {
-       }
-
-       virtual Module * CreateModule(InspIRCd* Me)
-       {
-               return new ModulePgSQL(Me);
-       }
-};
-
-
-extern "C" void * init_module( void )
-{
-       return new ModulePgSQLFactory;
-}
+MODULE_INIT(ModulePgSQL)