]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/commands.cpp
Remove do_log() prototypes
[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 "message.h"
43 #include "commands.h"
44 #include "mode.h"
45 #include "xline.h"
46 #include "inspstring.h"
47 #include "helperfuncs.h"
48 #include "hashcomp.h"
49 #include "socketengine.h"
50 #include "typedefs.h"
51 #include "command_parse.h"
52
53 extern InspIRCd* ServerInstance;
54
55 extern int MODCOUNT;
56 extern ModuleList modules;
57 extern FactoryList factory;
58 extern time_t TIME;
59
60 const long duration_m = 60;
61 const long duration_h = duration_m * 60;
62 const long duration_d = duration_h * 24;
63 const long duration_w = duration_d * 7;
64 const long duration_y = duration_w * 52;
65
66 extern user_hash clientlist;
67 extern chan_hash chanlist;
68
69 extern std::vector<userrec*> all_opers;
70 extern std::vector<userrec*> local_users;
71
72 // This table references users by file descriptor.
73 // its an array to make it VERY fast, as all lookups are referenced
74 // by an integer, meaning there is no need for a scan/search operation.
75 extern userrec* fd_ref_table[MAX_DESCRIPTORS];
76
77
78 void split_chlist(userrec* user, userrec* dest, const std::string &cl)
79 {
80         std::string line;
81         std::ostringstream prefix;
82         std::string::size_type start, pos, length;
83         
84         prefix << ":" << ServerInstance->Config->ServerName << " 319 " << user->nick << " " << dest->nick << " :";
85         line = prefix.str();
86         
87         for (start = 0; (pos = cl.find(' ', start)) != std::string::npos; start = pos+1)
88         {
89                 length = (pos == std::string::npos) ? cl.length() : pos;
90                 
91                 if (line.length() + length - start > 510)
92                 {
93                         user->Write(line);
94                         line = prefix.str();
95                 }
96                 
97                 if(pos == std::string::npos)
98                 {
99                         line += cl.substr(start, length - start);
100                         break;
101                 }
102                 else
103                 {
104                         line += cl.substr(start, length - start + 1);
105                 }
106         }
107         
108         if (line.length())
109         {
110                 user->Write(line);
111         }
112 }
113
114 /* XXX - these really belong in helperfuncs perhaps -- w00t */
115 bool is_uline(const char* server)
116 {
117         if (!server)
118                 return false;
119         if (!*server)
120                 return true;
121
122         return (find(ServerInstance->Config->ulines.begin(),ServerInstance->Config->ulines.end(),server) != ServerInstance->Config->ulines.end());
123 }
124
125 int operstrcmp(const char* data,const char* input)
126 {
127         int MOD_RESULT = 0;
128         FOREACH_RESULT(I_OnOperCompare,OnOperCompare(data,input))
129         log(DEBUG,"operstrcmp: %d",MOD_RESULT);
130         if (MOD_RESULT == 1)
131                 return 0;
132         if (MOD_RESULT == -1)
133                 return 1;
134         log(DEBUG,"strcmp fallback: '%s' '%s' %d",data,input,strcmp(data,input));
135         return strcmp(data,input);
136 }
137
138 long duration(const char* str)
139 {
140         char n_field[MAXBUF];
141         long total = 0;
142         n_field[0] = 0;
143
144         if ((!strchr(str,'s')) && (!strchr(str,'m')) && (!strchr(str,'h')) && (!strchr(str,'d')) && (!strchr(str,'w')) && (!strchr(str,'y')))
145         {
146                 std::string n = str;
147                 n += 's';
148                 return duration(n.c_str());
149         }
150         
151         for (char* i = (char*)str; *i; i++)
152         {
153                 // if we have digits, build up a string for the value in n_field,
154                 // up to 10 digits in size.
155                 if ((*i >= '0') && (*i <= '9'))
156                 {
157                         strlcat(n_field,i,10);
158                 }
159                 else
160                 {
161                         // we dont have a digit, check for numeric tokens
162                         switch (tolower(*i))
163                         {
164                                 case 's':
165                                         total += atoi(n_field);
166                                 break;
167
168                                 case 'm':
169                                         total += (atoi(n_field)*duration_m);
170                                 break;
171
172                                 case 'h':
173                                         total += (atoi(n_field)*duration_h);
174                                 break;
175
176                                 case 'd':
177                                         total += (atoi(n_field)*duration_d);
178                                 break;
179
180                                 case 'w':
181                                         total += (atoi(n_field)*duration_w);
182                                 break;
183
184                                 case 'y':
185                                         total += (atoi(n_field)*duration_y);
186                                 break;
187                         }
188                         n_field[0] = 0;
189                 }
190         }
191         // add trailing seconds
192         total += atoi(n_field);
193         
194         return total;
195 }
196
197 /* All other ircds when doing this check usually just look for a string of *@* or *. We're smarter than that, though. */
198
199 bool host_matches_everyone(const std::string &mask, userrec* user)
200 {
201         char buffer[MAXBUF];
202         char itrigger[MAXBUF];
203         long matches = 0;
204         
205         if (!ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "insane","trigger", 0, itrigger, MAXBUF))
206                 strlcpy(itrigger,"95.5",MAXBUF);
207         
208         if (ServerInstance->Config->ConfValueBool(ServerInstance->Config->config_data, "insane","hostmasks", 0))
209                 return false;
210         
211         for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
212         {
213                 strlcpy(buffer,u->second->ident,MAXBUF);
214                 charlcat(buffer,'@',MAXBUF);
215                 strlcat(buffer,u->second->host,MAXBUF);
216                 if (match(buffer,mask.c_str()))
217                         matches++;
218         }
219         float percent = ((float)matches / (float)clientlist.size()) * 100;
220         if (percent > (float)atof(itrigger))
221         {
222                 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);
223                 return true;
224         }
225         return false;
226 }
227
228 bool ip_matches_everyone(const std::string &ip, userrec* user)
229 {
230         char itrigger[MAXBUF];
231         long matches = 0;
232         
233         if (!ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "insane","trigger",0,itrigger,MAXBUF))
234                 strlcpy(itrigger,"95.5",MAXBUF);
235         
236         if (ServerInstance->Config->ConfValueBool(ServerInstance->Config->config_data, "insane","ipmasks",0))
237                 return false;
238         
239         for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
240         {
241                 if (match(u->second->GetIPString(),ip.c_str(),true))
242                         matches++;
243         }
244         
245         float percent = ((float)matches / (float)clientlist.size()) * 100;
246         if (percent > (float)atof(itrigger))
247         {
248                 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);
249                 return true;
250         }
251         return false;
252 }
253
254 bool nick_matches_everyone(const std::string &nick, userrec* user)
255 {
256         char itrigger[MAXBUF];
257         long matches = 0;
258         
259         if (!ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "insane","trigger",0,itrigger,MAXBUF))
260                 strlcpy(itrigger,"95.5",MAXBUF);
261         
262         if (ServerInstance->Config->ConfValueBool(ServerInstance->Config->config_data, "insane","nickmasks",0))
263                 return false;
264
265         for (user_hash::iterator u = clientlist.begin(); u != clientlist.end(); u++)
266         {
267                 if (match(u->second->nick,nick.c_str()))
268                         matches++;
269         }
270         
271         float percent = ((float)matches / (float)clientlist.size()) * 100;
272         if (percent > (float)atof(itrigger))
273         {
274                 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);
275                 return true;
276         }
277         return false;
278 }