]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/commands.cpp
6bb169f0a5634100e19eb816a3a6834950a81d67
[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 const long duration_m = 60;
55 const long duration_h = duration_m * 60;
56 const long duration_d = duration_h * 24;
57 const long duration_w = duration_d * 7;
58 const long duration_y = duration_w * 52;
59
60 /* XXX - these really belong in helperfuncs perhaps -- w00t */
61 bool is_uline(const char* server)
62 {
63         if (!server)
64                 return false;
65         if (!*server)
66                 return true;
67
68         return (find(ServerInstance->Config->ulines.begin(),ServerInstance->Config->ulines.end(),server) != ServerInstance->Config->ulines.end());
69 }
70
71 int operstrcmp(const char* data,const char* input)
72 {
73         int MOD_RESULT = 0;
74         FOREACH_RESULT(I_OnOperCompare,OnOperCompare(data,input))
75         ServerInstance->Log(DEBUG,"operstrcmp: %d",MOD_RESULT);
76         if (MOD_RESULT == 1)
77                 return 0;
78         if (MOD_RESULT == -1)
79                 return 1;
80         ServerInstance->Log(DEBUG,"strcmp fallback: '%s' '%s' %d",data,input,strcmp(data,input));
81         return strcmp(data,input);
82 }
83
84 long duration(const char* str)
85 {
86         char n_field[MAXBUF];
87         long total = 0;
88         n_field[0] = 0;
89
90         if ((!strchr(str,'s')) && (!strchr(str,'m')) && (!strchr(str,'h')) && (!strchr(str,'d')) && (!strchr(str,'w')) && (!strchr(str,'y')))
91         {
92                 std::string n = str;
93                 n += 's';
94                 return duration(n.c_str());
95         }
96         
97         for (char* i = (char*)str; *i; i++)
98         {
99                 // if we have digits, build up a string for the value in n_field,
100                 // up to 10 digits in size.
101                 if ((*i >= '0') && (*i <= '9'))
102                 {
103                         strlcat(n_field,i,10);
104                 }
105                 else
106                 {
107                         // we dont have a digit, check for numeric tokens
108                         switch (tolower(*i))
109                         {
110                                 case 's':
111                                         total += atoi(n_field);
112                                 break;
113
114                                 case 'm':
115                                         total += (atoi(n_field)*duration_m);
116                                 break;
117
118                                 case 'h':
119                                         total += (atoi(n_field)*duration_h);
120                                 break;
121
122                                 case 'd':
123                                         total += (atoi(n_field)*duration_d);
124                                 break;
125
126                                 case 'w':
127                                         total += (atoi(n_field)*duration_w);
128                                 break;
129
130                                 case 'y':
131                                         total += (atoi(n_field)*duration_y);
132                                 break;
133                         }
134                         n_field[0] = 0;
135                 }
136         }
137         // add trailing seconds
138         total += atoi(n_field);
139         
140         return total;
141 }
142
143 /* All other ircds when doing this check usually just look for a string of *@* or *. We're smarter than that, though. */
144
145 bool host_matches_everyone(const std::string &mask, userrec* user)
146 {
147         char buffer[MAXBUF];
148         char itrigger[MAXBUF];
149         long matches = 0;
150         
151         if (!ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "insane","trigger", 0, itrigger, MAXBUF))
152                 strlcpy(itrigger,"95.5",MAXBUF);
153         
154         if (ServerInstance->Config->ConfValueBool(ServerInstance->Config->config_data, "insane","hostmasks", 0))
155                 return false;
156         
157         for (user_hash::iterator u = ServerInstance->clientlist.begin(); u != ServerInstance->clientlist.end(); u++)
158         {
159                 strlcpy(buffer,u->second->ident,MAXBUF);
160                 charlcat(buffer,'@',MAXBUF);
161                 strlcat(buffer,u->second->host,MAXBUF);
162                 if (match(buffer,mask.c_str()))
163                         matches++;
164         }
165         float percent = ((float)matches / (float)ServerInstance->clientlist.size()) * 100;
166         if (percent > (float)atof(itrigger))
167         {
168                 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);
169                 return true;
170         }
171         return false;
172 }
173
174 bool ip_matches_everyone(const std::string &ip, userrec* user)
175 {
176         char itrigger[MAXBUF];
177         long matches = 0;
178         
179         if (!ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "insane","trigger",0,itrigger,MAXBUF))
180                 strlcpy(itrigger,"95.5",MAXBUF);
181         
182         if (ServerInstance->Config->ConfValueBool(ServerInstance->Config->config_data, "insane","ipmasks",0))
183                 return false;
184         
185         for (user_hash::iterator u = ServerInstance->clientlist.begin(); u != ServerInstance->clientlist.end(); u++)
186         {
187                 if (match(u->second->GetIPString(),ip.c_str(),true))
188                         matches++;
189         }
190         
191         float percent = ((float)matches / (float)ServerInstance->clientlist.size()) * 100;
192         if (percent > (float)atof(itrigger))
193         {
194                 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);
195                 return true;
196         }
197         return false;
198 }
199
200 bool nick_matches_everyone(const std::string &nick, userrec* user)
201 {
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","nickmasks",0))
209                 return false;
210
211         for (user_hash::iterator u = ServerInstance->clientlist.begin(); u != ServerInstance->clientlist.end(); u++)
212         {
213                 if (match(u->second->nick,nick.c_str()))
214                         matches++;
215         }
216         
217         float percent = ((float)matches / (float)ServerInstance->clientlist.size()) * 100;
218         if (percent > (float)atof(itrigger))
219         {
220                 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);
221                 return true;
222         }
223         return false;
224 }