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