]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/commands.cpp
Move tons more stuff into class InspIRCd*, make signal handler functions static members
[user/henk/code/inspircd.git] / src / commands.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd is copyright (C) 2002-2006 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 "inspircd_config.h"
18 #include "inspircd.h"
19 #include "configreader.h"
20 #include <unistd.h>
21 #include <sys/errno.h>
22 #include <sys/ioctl.h>
23 #include <sys/utsname.h>
24 #include <cstdio>
25 #include <time.h>
26 #include <string>
27 #include <sstream>
28 #include <vector>
29 #include <sys/types.h>
30 #include <sys/time.h>
31 #include <sys/resource.h>
32 #ifndef RUSAGE_SELF
33 #define   RUSAGE_SELF     0
34 #define   RUSAGE_CHILDREN     -1
35 #endif
36 #include "users.h"
37 #include "ctables.h"
38 #include "globals.h"
39 #include "modules.h"
40 #include "dynamic.h"
41 #include "wildcard.h"
42 #include "commands.h"
43 #include "mode.h"
44 #include "xline.h"
45 #include "inspstring.h"
46 #include "helperfuncs.h"
47 #include "hashcomp.h"
48 #include "socketengine.h"
49 #include "typedefs.h"
50 #include "command_parse.h"
51
52 extern InspIRCd* ServerInstance;
53
54 extern int MODCOUNT;
55 extern ModuleList modules;
56 extern FactoryList factory;
57 extern time_t TIME;
58
59 const long duration_m = 60;
60 const long duration_h = duration_m * 60;
61 const long duration_d = duration_h * 24;
62 const long duration_w = duration_d * 7;
63 const long duration_y = duration_w * 52;
64
65 extern std::vector<userrec*> all_opers;
66
67 void split_chlist(userrec* user, userrec* dest, const std::string &cl)
68 {
69         std::string line;
70         std::ostringstream prefix;
71         std::string::size_type start, pos, length;
72         
73         prefix << ":" << ServerInstance->Config->ServerName << " 319 " << user->nick << " " << dest->nick << " :";
74         line = prefix.str();
75         
76         for (start = 0; (pos = cl.find(' ', start)) != std::string::npos; start = pos+1)
77         {
78                 length = (pos == std::string::npos) ? cl.length() : pos;
79                 
80                 if (line.length() + length - start > 510)
81                 {
82                         user->Write(line);
83                         line = prefix.str();
84                 }
85                 
86                 if(pos == std::string::npos)
87                 {
88                         line += cl.substr(start, length - start);
89                         break;
90                 }
91                 else
92                 {
93                         line += cl.substr(start, length - start + 1);
94                 }
95         }
96         
97         if (line.length())
98         {
99                 user->Write(line);
100         }
101 }
102
103 /* XXX - these really belong in helperfuncs perhaps -- w00t */
104 bool is_uline(const char* server)
105 {
106         if (!server)
107                 return false;
108         if (!*server)
109                 return true;
110
111         return (find(ServerInstance->Config->ulines.begin(),ServerInstance->Config->ulines.end(),server) != ServerInstance->Config->ulines.end());
112 }
113
114 int operstrcmp(const char* data,const char* input)
115 {
116         int MOD_RESULT = 0;
117         FOREACH_RESULT(I_OnOperCompare,OnOperCompare(data,input))
118         log(DEBUG,"operstrcmp: %d",MOD_RESULT);
119         if (MOD_RESULT == 1)
120                 return 0;
121         if (MOD_RESULT == -1)
122                 return 1;
123         log(DEBUG,"strcmp fallback: '%s' '%s' %d",data,input,strcmp(data,input));
124         return strcmp(data,input);
125 }
126
127 long duration(const char* str)
128 {
129         char n_field[MAXBUF];
130         long total = 0;
131         n_field[0] = 0;
132
133         if ((!strchr(str,'s')) && (!strchr(str,'m')) && (!strchr(str,'h')) && (!strchr(str,'d')) && (!strchr(str,'w')) && (!strchr(str,'y')))
134         {
135                 std::string n = str;
136                 n += 's';
137                 return duration(n.c_str());
138         }
139         
140         for (char* i = (char*)str; *i; i++)
141         {
142                 // if we have digits, build up a string for the value in n_field,
143                 // up to 10 digits in size.
144                 if ((*i >= '0') && (*i <= '9'))
145                 {
146                         strlcat(n_field,i,10);
147                 }
148                 else
149                 {
150                         // we dont have a digit, check for numeric tokens
151                         switch (tolower(*i))
152                         {
153                                 case 's':
154                                         total += atoi(n_field);
155                                 break;
156
157                                 case 'm':
158                                         total += (atoi(n_field)*duration_m);
159                                 break;
160
161                                 case 'h':
162                                         total += (atoi(n_field)*duration_h);
163                                 break;
164
165                                 case 'd':
166                                         total += (atoi(n_field)*duration_d);
167                                 break;
168
169                                 case 'w':
170                                         total += (atoi(n_field)*duration_w);
171                                 break;
172
173                                 case 'y':
174                                         total += (atoi(n_field)*duration_y);
175                                 break;
176                         }
177                         n_field[0] = 0;
178                 }
179         }
180         // add trailing seconds
181         total += atoi(n_field);
182         
183         return total;
184 }
185
186 /* All other ircds when doing this check usually just look for a string of *@* or *. We're smarter than that, though. */
187
188 bool host_matches_everyone(const std::string &mask, userrec* user)
189 {
190         char buffer[MAXBUF];
191         char itrigger[MAXBUF];
192         long matches = 0;
193         
194         if (!ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "insane","trigger", 0, itrigger, MAXBUF))
195                 strlcpy(itrigger,"95.5",MAXBUF);
196         
197         if (ServerInstance->Config->ConfValueBool(ServerInstance->Config->config_data, "insane","hostmasks", 0))
198                 return false;
199         
200         for (user_hash::iterator u = ServerInstance->clientlist.begin(); u != ServerInstance->clientlist.end(); u++)
201         {
202                 strlcpy(buffer,u->second->ident,MAXBUF);
203                 charlcat(buffer,'@',MAXBUF);
204                 strlcat(buffer,u->second->host,MAXBUF);
205                 if (match(buffer,mask.c_str()))
206                         matches++;
207         }
208         float percent = ((float)matches / (float)ServerInstance->clientlist.size()) * 100;
209         if (percent > (float)atof(itrigger))
210         {
211                 ServerInstance->WriteOpers("*** \2WARNING\2: %s tried to set a G/K/E line mask of %s, which covers %.2f%% of the network!",user->nick,mask.c_str(),percent);
212                 return true;
213         }
214         return false;
215 }
216
217 bool ip_matches_everyone(const std::string &ip, userrec* user)
218 {
219         char itrigger[MAXBUF];
220         long matches = 0;
221         
222         if (!ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "insane","trigger",0,itrigger,MAXBUF))
223                 strlcpy(itrigger,"95.5",MAXBUF);
224         
225         if (ServerInstance->Config->ConfValueBool(ServerInstance->Config->config_data, "insane","ipmasks",0))
226                 return false;
227         
228         for (user_hash::iterator u = ServerInstance->clientlist.begin(); u != ServerInstance->clientlist.end(); u++)
229         {
230                 if (match(u->second->GetIPString(),ip.c_str(),true))
231                         matches++;
232         }
233         
234         float percent = ((float)matches / (float)ServerInstance->clientlist.size()) * 100;
235         if (percent > (float)atof(itrigger))
236         {
237                 ServerInstance->WriteOpers("*** \2WARNING\2: %s tried to set a Z line mask of %s, which covers %.2f%% of the network!",user->nick,ip.c_str(),percent);
238                 return true;
239         }
240         return false;
241 }
242
243 bool nick_matches_everyone(const std::string &nick, userrec* user)
244 {
245         char itrigger[MAXBUF];
246         long matches = 0;
247         
248         if (!ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "insane","trigger",0,itrigger,MAXBUF))
249                 strlcpy(itrigger,"95.5",MAXBUF);
250         
251         if (ServerInstance->Config->ConfValueBool(ServerInstance->Config->config_data, "insane","nickmasks",0))
252                 return false;
253
254         for (user_hash::iterator u = ServerInstance->clientlist.begin(); u != ServerInstance->clientlist.end(); u++)
255         {
256                 if (match(u->second->nick,nick.c_str()))
257                         matches++;
258         }
259         
260         float percent = ((float)matches / (float)ServerInstance->clientlist.size()) * 100;
261         if (percent > (float)atof(itrigger))
262         {
263                 ServerInstance->WriteOpers("*** \2WARNING\2: %s tried to set a Q line mask of %s, which covers %.2f%% of the network!",user->nick,nick.c_str(),percent);
264                 return true;
265         }
266         return false;
267 }