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