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