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