]>
Commit | Line | Data |
---|---|---|
3e3692bf CP |
1 | #include <stdio.h>\r |
2 | #include <stdlib.h>\r | |
3 | #include <stdarg.h>\r | |
4 | #include <string.h>\r | |
cc3768c4 | 5 | #include <strings.h>\r |
3e3692bf CP |
6 | #include <time.h>\r |
7 | \r | |
8 | #include "../control/control.h"\r | |
9 | #include "../nick/nick.h"\r | |
c86f8e4a CP |
10 | #include "../lib/irc_string.h"\r |
11 | #include "../lib/strlfunc.h"\r | |
3e3692bf | 12 | #include "../localuser/localuserchannel.h"\r |
cc3768c4 | 13 | #include "../geoip/geoip.h"\r |
3e3692bf CP |
14 | \r |
15 | int controlkill(void *sender, int cargc, char **cargv);\r | |
16 | int controlopchan(void *sender, int cargc, char **cargv);\r | |
17 | int controlkick(void *sender, int cargc, char **cargv);\r | |
c86f8e4a CP |
18 | int controlspewchan(void *sender, int cargc, char **cargv);\r |
19 | int controlspew(void *sender, int cargc, char **cargv);\r | |
20 | int controlresync(void *sender, int cargc, char **cargv);\r | |
21 | int controlbroadcast(void *sender, int cargc, char **cargv);\r | |
22 | int controlobroadcast(void *sender, int cargc, char **cargv);\r | |
23 | int controlmbroadcast(void *sender, int cargc, char **cargv);\r | |
24 | int controlsbroadcast(void *sender, int cargc, char **cargv);\r | |
cc3768c4 | 25 | int controlcbroadcast(void *sender, int cargc, char **cargv);\r |
3e3692bf CP |
26 | \r |
27 | void _init() {\r | |
2e5faaa2 CP |
28 | registercontrolhelpcmd("kill", NO_OPER, 2, &controlkill, "Usage: kill <nick> ?reason?\nKill specified user with given reason (or 'Killed').");\r |
29 | registercontrolhelpcmd("kick", NO_OPER, 3, &controlkick, "Usage: kick <channel> <user> ?reason?\nKick a user from the given channel, with given reason (or 'Kicked').");\r | |
c86f8e4a CP |
30 | \r |
31 | registercontrolhelpcmd("spewchan", NO_OPER, 1, &controlspewchan, "Usage: spewchan <pattern>\nShows all channels which are matched by the given pattern");\r | |
32 | \r | |
33 | /* registercontrolhelpcmd("spew", NO_OPER, 1, &controlspew, "Usage: spewchan <pattern>\nShows all userss which are matched by the given pattern"); */\r | |
34 | \r | |
35 | registercontrolhelpcmd("resync", NO_OPER, 1, &controlresync, "Usage: resync <channel>\nResyncs a desynched channel");\r | |
36 | \r | |
37 | registercontrolhelpcmd("broadcast", NO_OPER, 1, &controlbroadcast, "Usage: broadcast <text>\nSends a message to all users.");\r | |
38 | registercontrolhelpcmd("obroadcast", NO_OPER, 1, &controlobroadcast, "Usage: obroadcast <text>\nSends a message to all IRC operators.");\r | |
cc3768c4 | 39 | registercontrolhelpcmd("mbroadcast", NO_OPER, 2, &controlmbroadcast, "Usage: mbroadcast <mask> <text>\nSends a message to all users matching the mask");\r |
c86f8e4a | 40 | registercontrolhelpcmd("sbroadcast", NO_OPER, 2, &controlsbroadcast, "Usage: sbroadcast <mask> <text>\nSends a message to all users on specific server(s).");\r |
cc3768c4 | 41 | registercontrolhelpcmd("cbroadcast", NO_OPER, 2, &controlcbroadcast, "Usage: sbroadcast <2 letter country> <text>\nSends a message to all users in the specified country (GeoIP must be loaded) .");\r |
3e3692bf CP |
42 | }\r |
43 | \r | |
44 | void _fini() {\r | |
c86f8e4a CP |
45 | deregistercontrolcmd("obroadcast", controlobroadcast);\r |
46 | deregistercontrolcmd("sbroadcast", controlsbroadcast);\r | |
47 | deregistercontrolcmd("mbroadcast", controlmbroadcast);\r | |
48 | deregistercontrolcmd("broadcast", controlbroadcast);\r | |
49 | \r | |
50 | deregistercontrolcmd("resync", controlresync);\r | |
51 | /* deregistercontrolcmd("spew", controlspew); */\r | |
52 | deregistercontrolcmd("spewchan", controlspewchan);\r | |
53 | \r | |
2e5faaa2 CP |
54 | deregistercontrolcmd("kill", controlkill); \r |
55 | deregistercontrolcmd("kick", controlkick);\r | |
3e3692bf CP |
56 | }\r |
57 | \r | |
58 | int controlkick(void *sender, int cargc, char **cargv) {\r | |
59 | nick *np=(nick *)sender;\r | |
3e3692bf | 60 | channel *cp;\r |
3e3692bf CP |
61 | nick *target;\r |
62 | \r | |
2e5faaa2 CP |
63 | if (cargc<2)\r |
64 | return CMD_USAGE;\r | |
3e3692bf | 65 | \r |
2e5faaa2 CP |
66 | if ((cp=findchannel(cargv[0]))==NULL) {\r |
67 | controlreply(np,"Couldn't find that channel.");\r | |
68 | return CMD_ERROR;\r | |
3e3692bf CP |
69 | }\r |
70 | \r | |
2e5faaa2 CP |
71 | if ((target=getnickbynick(cargv[1]))==NULL) {\r |
72 | controlreply(np,"Sorry, couldn't find that user");\r | |
3e3692bf CP |
73 | return CMD_ERROR;\r |
74 | }\r | |
3e3692bf | 75 | \r |
2e5faaa2 CP |
76 | controlwall(NO_OPER, NL_KICKS, "%s/%s sent KICK for %s!%s@%s on %s (%s)", np->nick, np->authname, target->nick, target->ident, target->host->name->content,cp->index->name->content, (cargc>2)?cargv[2]:"Kicked");\r |
77 | localkickuser(NULL, cp, target, (cargc>2)?cargv[2]:"Kicked");\r | |
78 | controlreply(sender, "KICK sent.");\r | |
3e3692bf | 79 | \r |
3e3692bf CP |
80 | return CMD_OK;\r |
81 | }\r | |
82 | \r | |
2e5faaa2 | 83 | /* NO checking to see if it's us or anyone important */\r |
3e3692bf CP |
84 | int controlkill(void *sender, int cargc, char **cargv) {\r |
85 | nick *target;\r | |
3e3692bf CP |
86 | nick *np = (nick *)sender;\r |
87 | \r | |
2e5faaa2 CP |
88 | if (cargc<1)\r |
89 | return CMD_USAGE; \r | |
90 | \r | |
91 | if ((target=getnickbynick(cargv[0]))==NULL) {\r | |
92 | controlreply(np,"Sorry, couldn't find that user.");\r | |
3e3692bf CP |
93 | return CMD_ERROR;\r |
94 | }\r | |
3e3692bf | 95 | \r |
2e5faaa2 | 96 | controlwall(NO_OPER, NL_KILLS, "%s/%s sent KILL for %s!%s@%s (%s)", np->nick, np->authname, target->nick, target->ident, target->host->name->content, (cargc>1)?cargv[1]:"Killed");\r |
3e3692bf | 97 | killuser(NULL, target, (cargc>1)?cargv[1]:"Killed");\r |
2e5faaa2 | 98 | controlreply(np, "KILL sent.");\r |
3e3692bf CP |
99 | \r |
100 | return CMD_OK;\r | |
101 | }\r | |
c86f8e4a CP |
102 | \r |
103 | int controlresync(void *sender, int cargc, char **cargv) {\r | |
104 | nick *np = (nick*)sender;\r | |
105 | channel *cp;\r | |
106 | modechanges changes;\r | |
107 | int a;\r | |
108 | \r | |
109 | if (cargc < 1)\r | |
110 | return CMD_USAGE;\r | |
111 | \r | |
112 | cp = findchannel(cargv[0]);\r | |
113 | \r | |
114 | if (cp == NULL) {\r | |
115 | controlreply(np, "No such channel.");\r | |
116 | \r | |
117 | return CMD_ERROR;\r | |
118 | }\r | |
119 | \r | |
cc3768c4 CP |
120 | controlwall(NO_OPER, NL_KICKS, "%s/%s RESYNC'ed %s", np->nick, np->authname, cp->index->name->content);\r |
121 | \r | |
c86f8e4a CP |
122 | irc_send("%s CM %s o", mynumeric->content, cp->index->name->content);\r |
123 | \r | |
124 | localsetmodeinit(&changes, cp, mynick);\r | |
125 | \r | |
126 | for(a=0;a<cp->users->hashsize;a++) {\r | |
127 | if (cp->users->content[a] != nouser) {\r | |
128 | np = getnickbynumeric(cp->users->content[a]);\r | |
129 | \r | |
130 | /* make newserv believe that this user is not opped */\r | |
131 | if (cp->users->content[a] & CUMODE_OP)\r | |
132 | cp->users->content[a] &= ~CUMODE_OP;\r | |
133 | else if (!IsService(np)) /* if the user wasn't opped before and is not a service we don't care about him */\r | |
134 | continue;\r | |
135 | \r | |
136 | /* now reop him */\r | |
137 | localdosetmode_nick(&changes, np, MC_OP);\r | |
138 | }\r | |
139 | }\r | |
140 | \r | |
141 | localsetmodeflush(&changes, 1);\r | |
142 | \r | |
143 | controlreply(np, "Done.");\r | |
144 | \r | |
145 | return CMD_OK;\r | |
146 | }\r | |
147 | \r | |
148 | int controlspew(void *sender, int cargc, char **cargv) {\r | |
149 | nick *np = (nick *)sender;\r | |
150 | \r | |
151 | return CMD_OK;\r | |
152 | }\r | |
153 | \r | |
154 | int controlspewchan(void *sender, int cargc, char **cargv) {\r | |
155 | nick *np = (nick*)sender;\r | |
156 | nick *np2;\r | |
157 | int i, a, ccount = 0, morecservices, ucount, cscount;\r | |
158 | chanindex *cip;\r | |
159 | channel *cp;\r | |
160 | char cservices[300];\r | |
161 | char strcscount[40];\r | |
162 | \r | |
163 | if (cargc < 1)\r | |
164 | return CMD_USAGE;\r | |
165 | \r | |
166 | for (i=0; i<CHANNELHASHSIZE; i++) {\r | |
167 | for (cip=chantable[i]; cip; cip=cip->next) {\r | |
168 | if ((cp = cip->channel) != NULL && match2strings(cargv[0], cip->name->content)) {\r | |
169 | /* find channel services */\r | |
170 | cservices[0] = '\0';\r | |
171 | cscount = ucount = morecservices = 0;\r | |
172 | \r | |
173 | for (a=0;a<cp->users->hashsize;a++) {\r | |
174 | if (cp->users->content[a] != nouser) {\r | |
175 | np2 = getnickbynumeric(cp->users->content[a]);\r | |
176 | \r | |
177 | if (IsService(np2)) {\r | |
178 | cscount++;\r | |
179 | \r | |
180 | if (strlen(cservices) < 100) {\r | |
181 | if (cservices[0])\r | |
182 | strlcat(cservices, ", ", sizeof(cservices));\r | |
183 | \r | |
184 | strlcat(cservices, np2->nick, sizeof(cservices));\r | |
185 | } else {\r | |
186 | morecservices++;\r | |
187 | }\r | |
188 | }\r | |
189 | \r | |
190 | ucount++;\r | |
191 | }\r | |
192 | }\r | |
193 | \r | |
194 | if (morecservices)\r | |
195 | snprintf(cservices + strlen(cservices), sizeof(cservices), " and %d more", morecservices);\r | |
196 | \r | |
197 | snprintf(strcscount, sizeof(strcscount), "%d", cscount);\r | |
198 | \r | |
199 | /* TODO: print this channel ;; @slug -- WTF? */\r | |
200 | controlreply(np, "%-30s %5ld %-8s%s%s%-11s%s%s%s",\r | |
201 | cip->name->content,\r | |
202 | ucount,\r | |
203 | ucount != 1 ? "users" : "user",\r | |
204 | *cservices ? "- found " : "",\r | |
205 | *cservices ? strcscount : "",\r | |
206 | *cservices ? (strchr(cservices, ',') ? " chanservs" : " chanserv") : "",\r | |
207 | *cservices ? "(" : "",\r | |
208 | *cservices ? cservices : "",\r | |
209 | *cservices ? ")" : "");\r | |
210 | \r | |
211 | ccount++;\r | |
212 | \r | |
213 | if (ccount > 1000)\r | |
214 | break; /* Don't ever list more than 1000 channels */\r | |
215 | }\r | |
216 | }\r | |
217 | }\r | |
218 | \r | |
219 | if (ccount > 1000)\r | |
220 | controlreply(np, "More than 1000 matching channels were found. Please use a more specific pattern.");\r | |
221 | else\r | |
222 | controlreply(np, "Found %d channels matching specified pattern.", ccount);\r | |
223 | \r | |
224 | return CMD_OK;\r | |
225 | }\r | |
226 | \r | |
227 | int controlbroadcast(void *sender, int cargc, char **cargv) {\r | |
228 | nick *np = (nick*)sender;\r | |
229 | \r | |
230 | if (cargc<1)\r | |
231 | return CMD_USAGE;\r | |
232 | \r | |
233 | controlwall(NO_OPER, NL_BROADCASTS, "%s/%s sent a broadcast: %s", np->nick, np->authname, cargv[0]);\r | |
234 | \r | |
235 | irc_send("%s O $* :(Broadcast) %s", longtonumeric(mynick->numeric,5), cargv[0]);\r | |
236 | \r | |
237 | controlreply(np, "Message broadcasted.");\r | |
238 | \r | |
239 | return CMD_OK;\r | |
240 | }\r | |
241 | \r | |
242 | int controlmbroadcast(void *sender, int cargc, char **cargv) {\r | |
243 | nick *np = (nick*)sender;\r | |
244 | \r | |
245 | if (cargc<2)\r | |
246 | return CMD_USAGE;\r | |
247 | \r | |
248 | controlwall(NO_OPER, NL_BROADCASTS, "%s/%s sent an mbroadcast to %s: %s", np->nick, np->authname, cargv[0], cargv[1]);\r | |
249 | \r | |
250 | irc_send("%s O $@%s :(mBroadcast) %s", longtonumeric(mynick->numeric,5), cargv[0], cargv[1]);\r | |
251 | \r | |
252 | controlreply(np, "Message mbroadcasted.");\r | |
253 | \r | |
254 | return CMD_OK;\r | |
255 | }\r | |
256 | \r | |
257 | int controlsbroadcast(void *sender, int cargc, char **cargv) {\r | |
258 | nick *np = (nick *)sender;\r | |
259 | \r | |
260 | if(cargc<2)\r | |
261 | return CMD_USAGE;\r | |
262 | \r | |
cc3768c4 | 263 | controlwall(NO_OPER, NL_BROADCASTS, "%s/%s sent an sbroadcast to %s: %s", np->nick, np->authname, cargv[0], cargv[1]);\r |
c86f8e4a CP |
264 | \r |
265 | irc_send("%s O $%s :(sBroadcast) %s", longtonumeric(mynick->numeric,5), cargv[0], cargv[1]);\r | |
266 | \r | |
267 | controlreply(np, "Message sbroadcasted.");\r | |
268 | \r | |
269 | return CMD_OK;\r | |
270 | }\r | |
271 | \r | |
272 | int controlobroadcast(void *sender, int cargc, char **cargv) {\r | |
273 | nick *np = (nick *)sender, *nip;\r | |
274 | int i;\r | |
275 | \r | |
276 | if(cargc<1)\r | |
277 | return CMD_USAGE;\r | |
278 | \r | |
279 | controlwall(NO_OPER, NL_BROADCASTS, "%s/%s sent an obroadcast: %s", np->nick, np->authname, cargv[0]);\r | |
280 | \r | |
281 | for(i=0;i<NICKHASHSIZE;i++)\r | |
282 | for(nip=nicktable[i];nip;nip=nip->next)\r | |
283 | if(nip && IsOper(nip))\r | |
284 | controlnotice(nip, "(oBroadcast) %s", cargv[0]);\r | |
285 | \r | |
286 | controlreply(np, "Message obroadcasted.");\r | |
287 | \r | |
288 | return CMD_OK;\r | |
289 | }\r | |
cc3768c4 CP |
290 | \r |
291 | const char GeoIP_country_code[247][3] = { "--","AP","EU","AD","AE","AF","AG","AI","AL","AM","AN","AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB","BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO","BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD","CF","CG","CH","CI","CK","CL","CM","CN","CO","CR","CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO","DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ","FK","FM","FO","FR","FX","GA","GB","GD","GE","GF","GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT","GU","GW","GY","HK","HM","HN","HR","HT","HU","ID","IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO","JP","KE","KG","KH","KI","KM","KN","KP","KR","KW","KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT","LU","LV","LY","MA","MC","MD","MG","MH","MK","ML","MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV","MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI","NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF","PG","PH","PK","PL","PM","PN","PR","PS","PT","PW","PY","QA","RE","RO","RU","RW","SA","SB","SC","SD","SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO","SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH","TJ","TK","TM","TN","TO","TP","TR","TT","TV","TW","TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE","VG","VI","VN","VU","WF","WS","YE","YT","YU","ZA","ZM","ZR","ZW","A1","A2","O1"};\r | |
292 | \r | |
293 | int controlcbroadcast(void *sender, int cargc, char **cargv) {\r | |
294 | nick *np = (nick *)sender, *nip;\r | |
295 | int i, ext, target;\r | |
296 | \r | |
297 | if(cargc < 2)\r | |
298 | return CMD_USAGE;\r | |
299 | \r | |
300 | ext = findnickext("geoip");\r | |
301 | if(ext == -1)\r | |
302 | controlreply(np, "Geoip module not loaded.");\r | |
303 | \r | |
304 | target = COUNTRY_MIN - 1;\r | |
305 | for(i=COUNTRY_MIN;i<COUNTRY_MAX;i++) {\r | |
306 | if(!strcasecmp(cargv[0], GeoIP_country_code[i])) {\r | |
307 | target = i;\r | |
308 | break;\r | |
309 | }\r | |
310 | }\r | |
311 | \r | |
312 | if(target == -1) {\r | |
313 | controlreply(np, "Invalid country.");\r | |
314 | return CMD_ERROR;\r | |
315 | }\r | |
316 | \r | |
317 | controlwall(NO_OPER, NL_BROADCASTS, "%s/%s sent a cbroadcast %s: %s", np->nick, np->authname, cargv[0], cargv[1]);\r | |
318 | \r | |
319 | for(i=0;i<NICKHASHSIZE;i++)\r | |
320 | for(nip=nicktable[i];nip;nip=nip->next)\r | |
321 | if(nip && ((int)((long)nip->exts[ext]) == target))\r | |
322 | controlnotice(nip, "(cBroadcast) %s", cargv[1]);\r | |
323 | \r | |
324 | controlreply(np, "Message cbroadcasted.");\r | |
325 | \r | |
326 | return CMD_OK;\r | |
327 | }\r |