]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/extra/m_sqllog.cpp
03501265095640fe8653fab2802a5887db9d77fd
[user/henk/code/inspircd.git] / src / modules / extra / m_sqllog.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 #include <stdio.h>
18 #include <string>
19 #include <stdlib.h>
20 #include <time.h>
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/time.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <poll.h>
29 #include "users.h"
30 #include "channels.h"
31 #include "modules.h"
32 #include "inspircd.h"
33 #include "m_sql.h"
34
35 #define LT_OPER         1
36 #define LT_KILL         2
37 #define LT_SERVLINK     3
38 #define LT_XLINE        4
39 #define LT_CONNECT      5
40 #define LT_DISCONNECT   6
41 #define LT_FLOOD        7
42 #define LT_LOADMODULE   8
43
44 /* $ModDesc: Logs network-wide data to an SQL database */
45
46 Server *Srv;
47
48 class ModuleSQLLog : public Module
49 {
50         ConfigReader* Conf;
51         unsigned long dbid;
52         Module* SQLModule;
53
54  public:
55         bool ReadConfig()
56         {
57                 Conf = new ConfigReader();
58                 dbid = Conf->ReadInteger("sqllog","dbid",0,true);       // database id of a database configured in m_sql (see m_sql config)
59                 delete Conf;
60                 SQLModule = Srv->FindModule("m_sql.so");
61                 if (!SQLModule)
62                         Srv->Log(DEFAULT,"WARNING: m_SQLLog.so could not initialize because m_sql.so is not loaded. Load the module and rehash your server.");
63                 return (SQLModule);
64         }
65
66         ModuleSQLLog()
67         {
68                 Srv = new Server;
69                 ReadConfig();
70         }
71
72         virtual void OnRehash()
73         {
74                 ReadConfig();
75         }
76
77         long InsertNick(std::string nick)
78         {
79                 long nid = -1;
80                 SQLRequest* query = new SQLRequest(SQL_RESULT,dbid,"SELECT id,actor FROM ircd_log_actors WHERE actor='"+nick+"'");
81                 Request queryrequest((char*)query, this, SQLModule);
82                 SQLResult* result = (SQLResult*)queryrequest.Send();
83                 if (result->GetType() == SQL_OK)
84                 {
85                         SQLRequest* rowrequest = new SQLRequest(SQL_ROW,dbid,"");
86                         Request rowquery((char*)rowrequest, this, SQLModule);
87                         SQLResult* rowresult = (SQLResult*)rowquery.Send();
88                         if (rowresult->GetType() == SQL_ROW)
89                         {
90                                 nid = atoi(rowresult->GetField("id").c_str());
91                                 delete rowresult;
92                         }
93                         delete rowrequest;
94                         delete result;
95                 }
96                 query->SetQueryType(SQL_DONE);
97                 query->SetConnID(dbid);
98                 Request donerequest((char*)query, this, SQLModule);
99                 donerequest.Send();
100                 delete query;
101                 if (nid < 1)
102                 {
103                         SQLRequest* query2 = new SQLRequest(SQL_COUNT,dbid,"INSERT INTO ircd_log_actors VALUES('','"+nick+"')");
104                         Request queryrequest2((char*)query2, this, SQLModule);
105                         SQLResult* result2 = (SQLResult*)queryrequest2.Send();
106                         if (result2->GetType() == SQL_ERROR)
107                         {
108                                 Srv->Log(DEFAULT,"SQL log error: " + result2->GetError());
109                         }
110                         if (result2)
111                                 delete result;
112                         if (query2)
113                                 delete query2;
114                         nid = InsertNick(nick);
115                 }
116                 return nid;
117         }
118
119         void InsertEntry(unsigned long category,unsigned long nickid,unsigned long hostid,unsigned long sourceid,unsigned long date)
120         {
121                 char querybuffer[MAXBUF];
122                 snprintf(querybuffer,MAXBUF,"INSERT INTO ircd_log VALUES('',%lu,%lu,%lu,%lu,%lu)",(unsigned long)category,(unsigned long)nickid,(unsigned long)hostid,(unsigned long)sourceid,(unsigned long)date);
123                 SQLRequest* query = new SQLRequest(SQL_COUNT,dbid,querybuffer);
124                 Request queryrequest((char*)query, this, SQLModule);
125                 SQLResult* result = (SQLResult*)queryrequest.Send();
126                 if (result->GetType() == SQL_ERROR)
127                 {
128                         Srv->Log(DEFAULT,"SQL log error: " + result->GetError());
129                 }
130                 if (result)
131                         delete result;
132                 if (query)
133                         delete query;
134                 return;
135         }
136
137         long InsertHost(std::string host)
138         {
139                 long hid = -1;
140                 SQLRequest* query = new SQLRequest(SQL_RESULT,dbid,"SELECT id,hostname FROM ircd_log_hosts WHERE hostname='"+host+"'");
141                 Request queryrequest((char*)query, this, SQLModule);
142                 SQLResult* result = (SQLResult*)queryrequest.Send();
143                 if (result->GetType() == SQL_OK)
144                 {
145                         SQLRequest* rowrequest = new SQLRequest(SQL_ROW,dbid,"");
146                         Request rowquery((char*)rowrequest, this, SQLModule);
147                         SQLResult* rowresult = (SQLResult*)rowquery.Send();
148                         if (rowresult->GetType() == SQL_ROW)
149                         {
150                                 hid = atoi(rowresult->GetField("id").c_str());
151                                 delete rowresult;
152                         }
153                         delete rowrequest;
154                         delete result;
155                 }
156                 query->SetQueryType(SQL_DONE);
157                 query->SetConnID(dbid);
158                 Request donerequest((char*)query, this, SQLModule);
159                 donerequest.Send();
160                 delete query;
161                 if (hid < 1)
162                 {
163                         SQLRequest* query2 = new SQLRequest(SQL_COUNT,dbid,"INSERT INTO ircd_log_hosts VALUES('','"+host+"')");
164                         Request queryrequest2((char*)query2, this, SQLModule);
165                         SQLResult* result2 = (SQLResult*)queryrequest2.Send();
166                         if (result2->GetType() == SQL_ERROR)
167                         {
168                                 Srv->Log(DEFAULT,"SQL log error: " + result2->GetError());
169                         }
170                         if (result)
171                                 delete result2;
172                         if (query)
173                                 delete query2;
174                         hid = InsertHost(host);
175                 }
176                 return hid;
177         }
178
179         void AddLogEntry(int category, std::string nick, std::string host, std::string source)
180         {
181                 // is the sql module loaded? If not, we don't attempt to do anything.
182                 if (!SQLModule)
183                         return;
184
185                 long nickid = InsertNick(nick);
186                 long sourceid = InsertNick(source);
187                 long hostid = InsertHost(host);
188                 InsertEntry((unsigned)category,(unsigned)nickid,(unsigned)hostid,(unsigned)sourceid,(unsigned long)time(NULL));
189         }
190
191         virtual void OnOper(userrec* user)
192         {
193                 AddLogEntry(LT_OPER,user->nick,user->host,user->server);
194         }
195
196         virtual void OnGlobalOper(userrec* user)
197         {
198                 AddLogEntry(LT_OPER,user->nick,user->host,user->server);
199         }
200
201         virtual int OnKill(userrec* source, userrec* dest, std::string reason)
202         {
203                 AddLogEntry(LT_KILL,dest->nick,dest->host,source->nick);
204                 return 0;
205         }
206
207         virtual int OnMeshToken(char token,string_list params,serverrec* source,serverrec* reply, std::string tcp_host,std::string ipaddr,int port)
208         {
209                 if ((token == 'U') || (token == 's') || (token == 'S'))
210                         AddLogEntry(LT_SERVLINK,tcp_host,ipaddr,Srv->GetServerName());
211                 return 0;
212         }
213
214         virtual int OnPreCommand(std::string command, char **parameters, int pcnt, userrec *user)
215         {
216                 if ((command == "GLINE") || (command == "KLINE") || (command == "ELINE") || (command == "ZLINE"))
217                 {
218                         AddLogEntry(LT_XLINE,user->nick,command[0]+std::string(":")+std::string(parameters[0]),user->server);
219                 }
220                 return 0;
221         }
222
223         virtual void OnUserConnect(userrec* user)
224         {
225                 AddLogEntry(LT_CONNECT,user->nick,user->host,user->server);
226         }
227
228         virtual void OnGlobalConnect(userrec* user)
229         {
230                 AddLogEntry(LT_CONNECT,user->nick,user->host,user->server);
231         }
232
233         virtual void OnUserQuit(userrec* user)
234         {
235                 AddLogEntry(LT_DISCONNECT,user->nick,user->host,user->server);
236         }
237
238         virtual void OnLoadModule(Module* mod,std::string name)
239         {
240                 AddLogEntry(LT_LOADMODULE,name,Srv->GetServerName(),Srv->GetServerName());
241         }
242
243         virtual ~ModuleSQLLog()
244         {
245                 delete Srv;
246         }
247         
248         virtual Version GetVersion()
249         {
250                 return Version(1,0,0,1,VF_VENDOR);
251         }
252         
253 };
254
255 class ModuleSQLLogFactory : public ModuleFactory
256 {
257  public:
258         ModuleSQLLogFactory()
259         {
260         }
261         
262         ~ModuleSQLLogFactory()
263         {
264         }
265         
266         virtual Module * CreateModule()
267         {
268                 return new ModuleSQLLog;
269         }
270         
271 };
272
273
274 extern "C" void * init_module( void )
275 {
276         return new ModuleSQLLogFactory;
277 }
278