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