]> jfr.im git - irc/quakenet/newserv.git/blob - noperserv/noperserv_commands.c
Parser help is now an sstring.
[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: spew <pattern>\nShows all userss which are matched by the given pattern");
39
40 /* doesnt seem to work for me + pointless command?(paul)
41 registercontrolhelpcmd("resync", NO_OPER, 1, &controlresync, "Usage: resync <channel>\nResyncs a desynched channel"); */
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).");
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).");
48 }
49
50 void _fini() {
51 deregistercontrolcmd("obroadcast", controlobroadcast);
52 deregistercontrolcmd("sbroadcast", controlsbroadcast);
53 deregistercontrolcmd("mbroadcast", controlmbroadcast);
54 deregistercontrolcmd("broadcast", controlbroadcast);
55
56 /* deregistercontrolcmd("resync", controlresync); */
57 deregistercontrolcmd("spew", controlspew);
58 deregistercontrolcmd("spewchan", controlspewchan);
59
60 /* deregistercontrolcmd("kill", controlkill); */
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
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");
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
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");
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
126 controlwall(NO_OPER, NL_MISC, "%s/%s RESYNC'ed %s", np->nick, np->authname, cp->index->name->content);
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) {
134 nick *np2 = getnickbynumeric(cp->users->content[a]);
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;
139 else if (!IsService(np2)) /* if the user wasn't opped before and is not a service we don't care about him */
140 continue;
141
142 /* now reop him */
143 localdosetmode_nick(&changes, np2, MC_OP);
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) {
155 searchASTExpr *tree;
156
157 if(cargc < 1)
158 return CMD_USAGE;
159
160 tree = NSASTNode(match_parse, NSASTNode(hostmask_parse), NSASTLiteral(cargv[0]));
161 return ast_nicksearch(tree, controlreply, sender, controlnswall, printnick, NULL, NULL, 500);
162 }
163
164 /* this function is the definition of horrible */
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
302 int controlcbroadcast(void *sender, int cargc, char **cargv) {
303 nick *np = (nick *)sender, *nip;
304 int i, ext, target;
305 GeoIP_LookupCode l;
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
316 l = ndlsym("geoip", "geoip_lookupcode");
317 target = l(cargv[0]);
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 }