]>
Commit | Line | Data |
---|---|---|
15642ba8 CP |
1 | #include <stdio.h> |
2 | #include <stdlib.h> | |
3 | #include <stdarg.h> | |
4 | #include <string.h> | |
5 | #include <strings.h> | |
6 | #include <time.h> | |
7 | ||
8 | #include "../control/control.h" | |
9 | #include "../nick/nick.h" | |
10 | #include "../lib/irc_string.h" | |
11 | #include "../lib/strlfunc.h" | |
12 | #include "../localuser/localuserchannel.h" | |
13 | #include "../geoip/geoip.h" | |
87698d77 CP |
14 | #include "../lib/version.h" |
15 | ||
70b0a4e5 | 16 | MODULE_VERSION(""); |
15642ba8 CP |
17 | |
18 | int controlkill(void *sender, int cargc, char **cargv); | |
19 | int controlopchan(void *sender, int cargc, char **cargv); | |
20 | int controlkick(void *sender, int cargc, char **cargv); | |
21 | int controlspewchan(void *sender, int cargc, char **cargv); | |
22 | int controlspew(void *sender, int cargc, char **cargv); | |
23 | int controlresync(void *sender, int cargc, char **cargv); | |
24 | int controlbroadcast(void *sender, int cargc, char **cargv); | |
25 | int controlobroadcast(void *sender, int cargc, char **cargv); | |
26 | int controlmbroadcast(void *sender, int cargc, char **cargv); | |
27 | int controlsbroadcast(void *sender, int cargc, char **cargv); | |
28 | int controlcbroadcast(void *sender, int cargc, char **cargv); | |
29 | ||
30 | void _init() { | |
778e4bcd | 31 | /* registercontrolhelpcmd("kill", NO_OPER, 2, &controlkill, "Usage: kill <nick> ?reason?\nKill specified user with given reason (or 'Killed').");*/ |
15642ba8 CP |
32 | registercontrolhelpcmd("kick", NO_OPER, 3, &controlkick, "Usage: kick <channel> <user> ?reason?\nKick a user from the given channel, with given reason (or 'Kicked')."); |
33 | ||
34 | registercontrolhelpcmd("spewchan", NO_OPER, 1, &controlspewchan, "Usage: spewchan <pattern>\nShows all channels which are matched by the given pattern"); | |
35 | ||
36 | /* registercontrolhelpcmd("spew", NO_OPER, 1, &controlspew, "Usage: spewchan <pattern>\nShows all userss which are matched by the given pattern"); */ | |
37 | ||
38 | registercontrolhelpcmd("resync", NO_OPER, 1, &controlresync, "Usage: resync <channel>\nResyncs a desynched channel"); | |
39 | ||
40 | registercontrolhelpcmd("broadcast", NO_OPER, 1, &controlbroadcast, "Usage: broadcast <text>\nSends a message to all users."); | |
41 | registercontrolhelpcmd("obroadcast", NO_OPER, 1, &controlobroadcast, "Usage: obroadcast <text>\nSends a message to all IRC operators."); | |
42 | registercontrolhelpcmd("mbroadcast", NO_OPER, 2, &controlmbroadcast, "Usage: mbroadcast <mask> <text>\nSends a message to all users matching the mask"); | |
43 | registercontrolhelpcmd("sbroadcast", NO_OPER, 2, &controlsbroadcast, "Usage: sbroadcast <mask> <text>\nSends a message to all users on specific server(s)."); | |
a50e1bf1 | 44 | registercontrolhelpcmd("cbroadcast", NO_OPER, 2, &controlcbroadcast, "Usage: cbroadcast <2 letter country> <text>\nSends a message to all users in the specified country (GeoIP must be loaded)."); |
15642ba8 CP |
45 | } |
46 | ||
47 | void _fini() { | |
48 | deregistercontrolcmd("obroadcast", controlobroadcast); | |
49 | deregistercontrolcmd("sbroadcast", controlsbroadcast); | |
50 | deregistercontrolcmd("mbroadcast", controlmbroadcast); | |
51 | deregistercontrolcmd("broadcast", controlbroadcast); | |
52 | ||
53 | deregistercontrolcmd("resync", controlresync); | |
54 | /* deregistercontrolcmd("spew", controlspew); */ | |
55 | deregistercontrolcmd("spewchan", controlspewchan); | |
56 | ||
778e4bcd | 57 | /* deregistercontrolcmd("kill", controlkill); */ |
15642ba8 CP |
58 | deregistercontrolcmd("kick", controlkick); |
59 | } | |
60 | ||
61 | int controlkick(void *sender, int cargc, char **cargv) { | |
62 | nick *np=(nick *)sender; | |
63 | channel *cp; | |
64 | nick *target; | |
65 | ||
66 | if (cargc<2) | |
67 | return CMD_USAGE; | |
68 | ||
69 | if ((cp=findchannel(cargv[0]))==NULL) { | |
70 | controlreply(np,"Couldn't find that channel."); | |
71 | return CMD_ERROR; | |
72 | } | |
73 | ||
74 | if ((target=getnickbynick(cargv[1]))==NULL) { | |
75 | controlreply(np,"Sorry, couldn't find that user"); | |
76 | return CMD_ERROR; | |
77 | } | |
78 | ||
a50e1bf1 | 79 | controlwall(NO_OPER, NL_KICKKILLS, "%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"); |
15642ba8 CP |
80 | localkickuser(NULL, cp, target, (cargc>2)?cargv[2]:"Kicked"); |
81 | controlreply(sender, "KICK sent."); | |
82 | ||
83 | return CMD_OK; | |
84 | } | |
85 | ||
86 | /* NO checking to see if it's us or anyone important */ | |
87 | int controlkill(void *sender, int cargc, char **cargv) { | |
88 | nick *target; | |
89 | nick *np = (nick *)sender; | |
90 | ||
91 | if (cargc<1) | |
92 | return CMD_USAGE; | |
93 | ||
94 | if ((target=getnickbynick(cargv[0]))==NULL) { | |
95 | controlreply(np,"Sorry, couldn't find that user."); | |
96 | return CMD_ERROR; | |
97 | } | |
98 | ||
a50e1bf1 | 99 | controlwall(NO_OPER, NL_KICKKILLS, "%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"); |
15642ba8 CP |
100 | killuser(NULL, target, (cargc>1)?cargv[1]:"Killed"); |
101 | controlreply(np, "KILL sent."); | |
102 | ||
103 | return CMD_OK; | |
104 | } | |
105 | ||
106 | int controlresync(void *sender, int cargc, char **cargv) { | |
107 | nick *np = (nick*)sender; | |
108 | channel *cp; | |
109 | modechanges changes; | |
110 | int a; | |
111 | ||
112 | if (cargc < 1) | |
113 | return CMD_USAGE; | |
114 | ||
115 | cp = findchannel(cargv[0]); | |
116 | ||
117 | if (cp == NULL) { | |
118 | controlreply(np, "No such channel."); | |
119 | ||
120 | return CMD_ERROR; | |
121 | } | |
122 | ||
a50e1bf1 | 123 | controlwall(NO_OPER, NL_MISC, "%s/%s RESYNC'ed %s", np->nick, np->authname, cp->index->name->content); |
15642ba8 CP |
124 | |
125 | irc_send("%s CM %s o", mynumeric->content, cp->index->name->content); | |
126 | ||
127 | localsetmodeinit(&changes, cp, mynick); | |
128 | ||
129 | for(a=0;a<cp->users->hashsize;a++) { | |
130 | if (cp->users->content[a] != nouser) { | |
a50e1bf1 | 131 | nick *np2 = getnickbynumeric(cp->users->content[a]); |
15642ba8 CP |
132 | |
133 | /* make newserv believe that this user is not opped */ | |
134 | if (cp->users->content[a] & CUMODE_OP) | |
135 | cp->users->content[a] &= ~CUMODE_OP; | |
a50e1bf1 | 136 | else if (!IsService(np2)) /* if the user wasn't opped before and is not a service we don't care about him */ |
15642ba8 CP |
137 | continue; |
138 | ||
139 | /* now reop him */ | |
a50e1bf1 | 140 | localdosetmode_nick(&changes, np2, MC_OP); |
15642ba8 CP |
141 | } |
142 | } | |
143 | ||
144 | localsetmodeflush(&changes, 1); | |
145 | ||
146 | controlreply(np, "Done."); | |
147 | ||
148 | return CMD_OK; | |
149 | } | |
150 | ||
151 | int controlspew(void *sender, int cargc, char **cargv) { | |
4ad1cf7a | 152 | /* nick *np = (nick *)sender; */ |
15642ba8 CP |
153 | |
154 | return CMD_OK; | |
155 | } | |
156 | ||
157 | int controlspewchan(void *sender, int cargc, char **cargv) { | |
158 | nick *np = (nick*)sender; | |
159 | nick *np2; | |
160 | int i, a, ccount = 0, morecservices, ucount, cscount; | |
161 | chanindex *cip; | |
162 | channel *cp; | |
163 | char cservices[300]; | |
164 | char strcscount[40]; | |
165 | ||
166 | if (cargc < 1) | |
167 | return CMD_USAGE; | |
168 | ||
169 | for (i=0; i<CHANNELHASHSIZE; i++) { | |
170 | for (cip=chantable[i]; cip; cip=cip->next) { | |
171 | if ((cp = cip->channel) != NULL && match2strings(cargv[0], cip->name->content)) { | |
172 | /* find channel services */ | |
173 | cservices[0] = '\0'; | |
174 | cscount = ucount = morecservices = 0; | |
175 | ||
176 | for (a=0;a<cp->users->hashsize;a++) { | |
177 | if (cp->users->content[a] != nouser) { | |
178 | np2 = getnickbynumeric(cp->users->content[a]); | |
179 | ||
180 | if (IsService(np2)) { | |
181 | cscount++; | |
182 | ||
183 | if (strlen(cservices) < 100) { | |
184 | if (cservices[0]) | |
185 | strlcat(cservices, ", ", sizeof(cservices)); | |
186 | ||
187 | strlcat(cservices, np2->nick, sizeof(cservices)); | |
188 | } else { | |
189 | morecservices++; | |
190 | } | |
191 | } | |
192 | ||
193 | ucount++; | |
194 | } | |
195 | } | |
196 | ||
197 | if (morecservices) | |
198 | snprintf(cservices + strlen(cservices), sizeof(cservices), " and %d more", morecservices); | |
199 | ||
200 | snprintf(strcscount, sizeof(strcscount), "%d", cscount); | |
201 | ||
202 | /* TODO: print this channel ;; @slug -- WTF? */ | |
203 | controlreply(np, "%-30s %5ld %-8s%s%s%-11s%s%s%s", | |
204 | cip->name->content, | |
205 | ucount, | |
206 | ucount != 1 ? "users" : "user", | |
207 | *cservices ? "- found " : "", | |
208 | *cservices ? strcscount : "", | |
209 | *cservices ? (strchr(cservices, ',') ? " chanservs" : " chanserv") : "", | |
210 | *cservices ? "(" : "", | |
211 | *cservices ? cservices : "", | |
212 | *cservices ? ")" : ""); | |
213 | ||
214 | ccount++; | |
215 | ||
216 | if (ccount > 1000) | |
217 | break; /* Don't ever list more than 1000 channels */ | |
218 | } | |
219 | } | |
220 | } | |
221 | ||
222 | if (ccount > 1000) | |
223 | controlreply(np, "More than 1000 matching channels were found. Please use a more specific pattern."); | |
224 | else | |
225 | controlreply(np, "Found %d channels matching specified pattern.", ccount); | |
226 | ||
227 | return CMD_OK; | |
228 | } | |
229 | ||
230 | int controlbroadcast(void *sender, int cargc, char **cargv) { | |
231 | nick *np = (nick*)sender; | |
232 | ||
233 | if (cargc<1) | |
234 | return CMD_USAGE; | |
235 | ||
236 | controlwall(NO_OPER, NL_BROADCASTS, "%s/%s sent a broadcast: %s", np->nick, np->authname, cargv[0]); | |
237 | ||
238 | irc_send("%s O $* :(Broadcast) %s", longtonumeric(mynick->numeric,5), cargv[0]); | |
239 | ||
240 | controlreply(np, "Message broadcasted."); | |
241 | ||
242 | return CMD_OK; | |
243 | } | |
244 | ||
245 | int controlmbroadcast(void *sender, int cargc, char **cargv) { | |
246 | nick *np = (nick*)sender; | |
247 | ||
248 | if (cargc<2) | |
249 | return CMD_USAGE; | |
250 | ||
251 | controlwall(NO_OPER, NL_BROADCASTS, "%s/%s sent an mbroadcast to %s: %s", np->nick, np->authname, cargv[0], cargv[1]); | |
252 | ||
253 | irc_send("%s O $@%s :(mBroadcast) %s", longtonumeric(mynick->numeric,5), cargv[0], cargv[1]); | |
254 | ||
255 | controlreply(np, "Message mbroadcasted."); | |
256 | ||
257 | return CMD_OK; | |
258 | } | |
259 | ||
260 | int controlsbroadcast(void *sender, int cargc, char **cargv) { | |
261 | nick *np = (nick *)sender; | |
262 | ||
263 | if(cargc<2) | |
264 | return CMD_USAGE; | |
265 | ||
266 | controlwall(NO_OPER, NL_BROADCASTS, "%s/%s sent an sbroadcast to %s: %s", np->nick, np->authname, cargv[0], cargv[1]); | |
267 | ||
268 | irc_send("%s O $%s :(sBroadcast) %s", longtonumeric(mynick->numeric,5), cargv[0], cargv[1]); | |
269 | ||
270 | controlreply(np, "Message sbroadcasted."); | |
271 | ||
272 | return CMD_OK; | |
273 | } | |
274 | ||
275 | int controlobroadcast(void *sender, int cargc, char **cargv) { | |
276 | nick *np = (nick *)sender, *nip; | |
277 | int i; | |
278 | ||
279 | if(cargc<1) | |
280 | return CMD_USAGE; | |
281 | ||
282 | controlwall(NO_OPER, NL_BROADCASTS, "%s/%s sent an obroadcast: %s", np->nick, np->authname, cargv[0]); | |
283 | ||
284 | for(i=0;i<NICKHASHSIZE;i++) | |
285 | for(nip=nicktable[i];nip;nip=nip->next) | |
286 | if(nip && IsOper(nip)) | |
287 | controlnotice(nip, "(oBroadcast) %s", cargv[0]); | |
288 | ||
289 | controlreply(np, "Message obroadcasted."); | |
290 | ||
291 | return CMD_OK; | |
292 | } | |
293 | ||
294 | 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"}; | |
295 | ||
296 | int controlcbroadcast(void *sender, int cargc, char **cargv) { | |
297 | nick *np = (nick *)sender, *nip; | |
298 | int i, ext, target; | |
299 | ||
300 | if(cargc < 2) | |
301 | return CMD_USAGE; | |
302 | ||
303 | ext = findnickext("geoip"); | |
304 | if(ext == -1) { | |
305 | controlreply(np, "Geoip module not loaded."); | |
306 | return CMD_ERROR; | |
307 | } | |
308 | ||
309 | target = COUNTRY_MIN - 1; | |
310 | for(i=COUNTRY_MIN;i<COUNTRY_MAX;i++) { | |
311 | if(!strcasecmp(cargv[0], GeoIP_country_code[i])) { | |
312 | target = i; | |
313 | break; | |
314 | } | |
315 | } | |
316 | ||
317 | if(target == -1) { | |
318 | controlreply(np, "Invalid country."); | |
319 | return CMD_ERROR; | |
320 | } | |
321 | ||
322 | controlwall(NO_OPER, NL_BROADCASTS, "%s/%s sent a cbroadcast %s: %s", np->nick, np->authname, cargv[0], cargv[1]); | |
323 | ||
324 | for(i=0;i<NICKHASHSIZE;i++) | |
325 | for(nip=nicktable[i];nip;nip=nip->next) | |
326 | if(nip && ((int)((long)nip->exts[ext]) == target)) | |
327 | controlnotice(nip, "(cBroadcast) %s", cargv[1]); | |
328 | ||
329 | controlreply(np, "Message cbroadcasted."); | |
330 | ||
331 | return CMD_OK; | |
332 | } |