Anope IRC Services  Version 1.8
cs_clear.c
Go to the documentation of this file.
1 /* ChanServ core functions
2  *
3  * (C) 2003-2014 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Please read COPYING and README for further details.
7  *
8  * Based on the original code of Epona by Lara.
9  * Based on the original code of Services by Andy Church.
10  *
11  *
12  */
13 /*************************************************************************/
14 
15 #include "module.h"
16 
17 static int do_clear(User * u);
18 static void myChanServHelp(User * u);
19 
26 int AnopeInit(int argc, char **argv)
27 {
28  Command *c;
29 
30  moduleAddAuthor("Anope");
31  moduleAddVersion(VERSION_STRING);
33 
34  c = createCommand("CLEAR", do_clear, NULL, CHAN_HELP_CLEAR, -1, -1, -1,
35  -1);
37 
39 
40  return MOD_CONT;
41 }
42 
46 void AnopeFini(void)
47 {
48 
49 }
50 
51 
52 
57 static void myChanServHelp(User * u)
58 {
59  notice_lang(s_ChanServ, u, CHAN_HELP_CMD_CLEAR);
60 }
61 
67 static int do_clear(User * u)
68 {
69  char *chan = strtok(NULL, " ");
70  char *what = strtok(NULL, " ");
71  Channel *c;
72  ChannelInfo *ci;
73 
74  if (!what) {
75  syntax_error(s_ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX);
76  } else if (!(c = findchan(chan))) {
77  notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
78  } else if (!(ci = c->ci)) {
79  notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
80  } else if (ci->flags & CI_VERBOTEN) {
81  notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
82  } else if (!u || !check_access(u, ci, CA_CLEAR)) {
83  notice_lang(s_ChanServ, u, PERMISSION_DENIED);
84  } else if (stricmp(what, "bans") == 0) {
85  char *av[2];
86  Entry *ban, *next;
87 
88  if (c->bans && c->bans->count) {
89  for (ban = c->bans->entries; ban; ban = next) {
90  next = ban->next;
91  av[0] = sstrdup("-b");
92  av[1] = sstrdup(ban->mask);
93  anope_cmd_mode(whosends(ci), chan, "-b %s", ban->mask);
94  chan_set_modes(whosends(ci), c, 2, av, 0);
95  free(av[0]);
96  free(av[1]);
97  }
98  }
99 
100  alog("%s: %s!%s@%s cleared bans on %s",
101  s_ChanServ, u->nick, u->username, u->host, ci->name);
102  notice_lang(s_ChanServ, u, CHAN_CLEARED_BANS, chan);
103  } else if (ircd->except && stricmp(what, "excepts") == 0) {
104  char *av[2];
105  Entry *except, *next;
106 
107  if (c->excepts && c->excepts->count) {
108  for (except = c->excepts->entries; except; except = next) {
109  next = except->next;
110  av[0] = sstrdup("-e");
111  av[1] = sstrdup(except->mask);
112  anope_cmd_mode(whosends(ci), chan, "-e %s", except->mask);
113  chan_set_modes(whosends(ci), c, 2, av, 0);
114  free(av[0]);
115  free(av[1]);
116  }
117  }
118 
119  alog("%s: %s!%s@%s cleared excepts on %s",
120  s_ChanServ, u->nick, u->username, u->host, ci->name);
121  notice_lang(s_ChanServ, u, CHAN_CLEARED_EXCEPTS, chan);
122  } else if (ircd->invitemode && stricmp(what, "invites") == 0) {
123  char *av[2];
124  Entry *invite, *next;
125 
126  if (c->invites && c->invites->count) {
127  for (invite = c->invites->entries; invite; invite = next) {
128  next = invite->next;
129  av[0] = sstrdup("-I");
130  av[1] = sstrdup(invite->mask);
131  anope_cmd_mode(whosends(ci), chan, "-I %s", invite->mask);
132  chan_set_modes(whosends(ci), c, 2, av, 0);
133  free(av[0]);
134  free(av[1]);
135  }
136  }
137  alog("%s: %s!%s@%s cleared invites on %s",
138  s_ChanServ, u->nick, u->username, u->host, ci->name);
139  notice_lang(s_ChanServ, u, CHAN_CLEARED_INVITES, chan);
140 
141  } else if (stricmp(what, "modes") == 0) {
142  char *argv[2];
143 
144  if (c->mode) {
145  /* Clear modes the bulk of the modes */
146  anope_cmd_mode(whosends(ci), c->name, "%s",
148  argv[0] = sstrdup(ircd->modestoremove);
149  chan_set_modes(whosends(ci), c, 1, argv, 0);
150  free(argv[0]);
151 
152  /* to prevent the internals from complaining send -k, -L, -f by themselves if we need
153  to send them - TSL */
154  if (c->key) {
155  anope_cmd_mode(whosends(ci), c->name, "-k %s", c->key);
156  argv[0] = sstrdup("-k");
157  argv[1] = c->key;
158  chan_set_modes(whosends(ci), c, 2, argv, 0);
159  free(argv[0]);
160  }
161  if (ircd->Lmode && c->redirect) {
162  anope_cmd_mode(whosends(ci), c->name, "-L %s",
163  c->redirect);
164  argv[0] = sstrdup("-L");
165  argv[1] = c->redirect;
166  chan_set_modes(whosends(ci), c, 2, argv, 0);
167  free(argv[0]);
168  }
169  if (ircd->fmode && c->flood) {
171  anope_cmd_mode(whosends(ci), c->name, "%s %s",
173  argv[0] = sstrdup(flood_mode_char_remove);
174  argv[1] = c->flood;
175  chan_set_modes(whosends(ci), c, 2, argv, 0);
176  free(argv[0]);
177  } else {
178  if (debug) {
179  alog("debug: flood_mode_char_remove was not set unable to remove flood/throttle modes");
180  }
181  }
182  }
183  check_modes(c);
184  }
185 
186  alog("%s: %s!%s@%s cleared modes on %s",
187  s_ChanServ, u->nick, u->username, u->host, ci->name);
188  notice_lang(s_ChanServ, u, CHAN_CLEARED_MODES, chan);
189  } else if (stricmp(what, "ops") == 0) {
190  char *av[6]; /* The max we have to hold: chan, ts, modes(max3), nick, nick, nick */
191  int ac, isop, isadmin, isown, count, i;
192  char buf[BUFSIZE], tmp[BUFSIZE], tmp2[BUFSIZE];
193  struct c_userlist *cu, *next;
194 
195  if (ircd->svsmode_ucmode) {
196  av[0] = chan;
197  anope_cmd_svsmode_chan(av[0], "-o", NULL);
198  if (ircd->owner) {
199  anope_cmd_svsmode_chan(av[0], ircd->ownerunset, NULL);
200  }
201  if (ircd->protect || ircd->admin) {
202  anope_cmd_svsmode_chan(av[0], ircd->adminunset, NULL);
203  }
204  /* No need to do anything here - we will receive the mode changes from the IRCd and process them then */
205  } else {
206  for (cu = c->users; cu; cu = next) {
207  next = cu->next;
208  isop = chan_has_user_status(c, cu->user, CUS_OP);
209  isadmin = chan_has_user_status(c, cu->user, CUS_PROTECT);
210  isown = chan_has_user_status(c, cu->user, CUS_OWNER);
211  count = (isop ? 1 : 0) + (isadmin ? 1 : 0) + (isown ? 1 : 0);
212 
213  if (!isop && !isadmin && !isown)
214  continue;
215 
216  snprintf(tmp, BUFSIZE, "-%s%s%s", (isop ? "o" : ""), (isadmin ?
217  ircd->adminunset+1 : ""), (isown ? ircd->ownerunset+1 : ""));
218  /* We need to send the IRCd a nick for every mode.. - Viper */
219  snprintf(tmp2, BUFSIZE, "%s %s %s", (isop ? GET_USER(cu->user) : ""),
220  (isadmin ? GET_USER(cu->user) : ""), (isown ? GET_USER(cu->user) : ""));
221 
222  av[0] = chan;
223  if (ircdcap->tsmode) {
224  snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
225  av[1] = buf;
226  av[2] = tmp;
227  /* We have to give as much nicks as modes.. - Viper */
228  for (i = 0; i < count; i++)
229  av[i+3] = GET_USER(cu->user);
230  ac = 3 + i;
231 
232  anope_cmd_mode(whosends(ci), av[0], "%s %s", av[2], tmp2);
233  } else {
234  av[1] = tmp;
235  /* We have to give as much nicks as modes.. - Viper */
236  for (i = 0; i < count; i++)
237  av[i+2] = GET_USER(cu->user);
238  ac = 2 + i;
239 
240  anope_cmd_mode(whosends(ci), av[0], "%s %s", av[1], tmp2);
241  }
242 
243  do_cmode(s_ChanServ, ac, av);
244  }
245  }
246 
247  alog("%s: %s!%s@%s cleared ops on %s",
248  s_ChanServ, u->nick, u->username, u->host, ci->name);
249  notice_lang(s_ChanServ, u, CHAN_CLEARED_OPS, chan);
250  } else if (ircd->halfop && stricmp(what, "hops") == 0) {
251  char *av[4];
252  int ac;
253  char buf[BUFSIZE];
254  struct c_userlist *cu, *next;
255 
256  if (ircd->svsmode_ucmode) {
257  anope_cmd_svsmode_chan(chan, "-h", NULL);
258  /* No need to do anything here - we will receive the mode changes from the IRCd and process them then */
259  }
260  else {
261  for (cu = c->users; cu; cu = next) {
262  next = cu->next;
263  if (!chan_has_user_status(c, cu->user, CUS_HALFOP))
264  continue;
265 
266  if (ircdcap->tsmode) {
267  snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
268  av[0] = sstrdup(chan);
269  av[1] = buf;
270  av[2] = sstrdup("-h");
271  av[3] = sstrdup(GET_USER(cu->user));
272  ac = 4;
273  } else {
274  av[0] = sstrdup(chan);
275  av[1] = sstrdup("-h");
276  av[2] = sstrdup(GET_USER(cu->user));
277  ac = 3;
278  }
279 
280  if (ircdcap->tsmode)
281  anope_cmd_mode(whosends(ci), av[0], "%s %s", av[2], av[3]);
282  else
283  anope_cmd_mode(whosends(ci), av[0], "%s %s", av[1], av[2]);
284 
285  do_cmode(s_ChanServ, ac, av);
286 
287  if (ircdcap->tsmode) {
288  free(av[3]);
289  free(av[2]);
290  free(av[0]);
291  } else {
292  free(av[2]);
293  free(av[1]);
294  free(av[0]);
295  }
296  }
297  }
298  alog("%s: %s!%s@%s cleared halfops on %s",
299  s_ChanServ, u->nick, u->username, u->host, ci->name);
300  notice_lang(s_ChanServ, u, CHAN_CLEARED_HOPS, chan);
301  } else if (stricmp(what, "voices") == 0) {
302  char *av[4];
303  int ac;
304  char buf[BUFSIZE];
305  struct c_userlist *cu, *next;
306 
307  if (ircd->svsmode_ucmode) {
308  anope_cmd_svsmode_chan(chan, "-v", NULL);
309  /* No need to do anything here - we will receive the mode changes from the IRCd and process them then */
310  }
311  else {
312  for (cu = c->users; cu; cu = next) {
313  next = cu->next;
314  if (!chan_has_user_status(c, cu->user, CUS_VOICE))
315  continue;
316 
317  if (ircdcap->tsmode) {
318  snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
319  av[0] = sstrdup(chan);
320  av[1] = buf;
321  av[2] = sstrdup("-v");
322  av[3] = sstrdup(GET_USER(cu->user));
323  ac = 4;
324  } else {
325  av[0] = sstrdup(chan);
326  av[1] = sstrdup("-v");
327  av[2] = sstrdup(GET_USER(cu->user));
328  ac = 3;
329  }
330 
331  if (ircdcap->tsmode) {
332  anope_cmd_mode(whosends(ci), av[0], "%s %s", av[2], av[3]);
333  } else {
334  anope_cmd_mode(whosends(ci), av[0], "%s %s", av[1], av[2]);
335  }
336 
337  do_cmode(s_ChanServ, ac, av);
338 
339  if (ircdcap->tsmode) {
340  free(av[3]);
341  free(av[2]);
342  free(av[0]);
343  } else {
344  free(av[2]);
345  free(av[1]);
346  free(av[0]);
347  }
348  }
349  }
350  alog("%s: %s!%s@%s cleared voices on %s",
351  s_ChanServ, u->nick, u->username, u->host, ci->name);
352  notice_lang(s_ChanServ, u, CHAN_CLEARED_VOICES, chan);
353  } else if (stricmp(what, "users") == 0) {
354  char *av[3];
355  struct c_userlist *cu, *next;
356  char buf[256];
357 
358  snprintf(buf, sizeof(buf), "CLEAR USERS command from %s", u->nick);
359 
360  for (cu = c->users; cu; cu = next) {
361  next = cu->next;
362  av[0] = sstrdup(chan);
363  av[1] = sstrdup(GET_USER(cu->user));
364  av[2] = sstrdup(buf);
365  anope_cmd_kick(whosends(ci), av[0], av[1], av[2]);
366  do_kick(s_ChanServ, 3, av);
367  free(av[2]);
368  free(av[1]);
369  free(av[0]);
370  }
371  alog("%s: %s!%s@%s cleared users on %s",
372  s_ChanServ, u->nick, u->username, u->host, ci->name);
373  notice_lang(s_ChanServ, u, CHAN_CLEARED_USERS, chan);
374  } else {
375  syntax_error(s_ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX);
376  }
377  return MOD_CONT;
378 }
EList * invites
Definition: services.h:1014
E IRCDCAPAB * ircdcap
Definition: extern.h:40
char nick[NICKMAX]
Definition: services.h:875
E int snprintf(char *buf, size_t size, const char *fmt,...)
Definition: compat.c:37
E int chan_has_user_status(Channel *chan, User *user, int16 status)
Definition: channels.c:124
int Lmode
Definition: services.h:350
static int do_clear(User *u)
Definition: cs_clear.c:67
E IRCDVar * ircd
Definition: extern.h:39
E void do_kick(const char *source, int ac, char **av)
Definition: channels.c:638
int AnopeInit(int argc, char **argv)
Definition: cs_clear.c:26
#define CA_CLEAR
Definition: services.h:758
E int check_access(User *user, ChannelInfo *ci, int what)
Definition: chanserv.c:1974
Entry * next
Definition: services.h:1038
E int stricmp(const char *s1, const char *s2)
Definition: compat.c:58
char * redirect
Definition: services.h:1009
int32 count
Definition: services.h:1034
#define CI_VERBOTEN
Definition: services.h:725
E void chan_set_modes(const char *source, Channel *chan, int ac, char **av, int check)
Definition: channels.c:161
char * host
Definition: services.h:878
#define CUS_VOICE
Definition: services.h:1342
MDE void moduleAddAuthor(const char *author)
Definition: modules.c:1772
ChannelInfo * ci
Definition: services.h:1001
E void syntax_error(char *service, User *u, const char *command, int msgnum)
Definition: language.c:295
char name[CHANMAX]
Definition: services.h:654
char * modestoremove
Definition: services.h:298
int except
Definition: services.h:320
E void notice_lang(char *source, User *dest, int message,...)
Definition: send.c:169
MDE void moduleSetType(MODType type)
Definition: modules.c:818
char * ownerunset
Definition: services.h:304
E Channel * findchan(const char *chan)
Definition: channels.c:394
E char * sstrdup(const char *s)
Definition: memory.c:105
E void anope_cmd_kick(char *source, char *chan, char *user, const char *fmt,...)
Definition: ircd.c:230
E void anope_cmd_svsmode_chan(char *name, char *mode, char *nick)
Definition: ircd.c:599
uint32 flags
Definition: services.h:669
int invitemode
Definition: services.h:359
EList * excepts
Definition: services.h:1013
Definition: services.h:1037
char * key
Definition: services.h:1008
uint32 mode
Definition: services.h:1006
static void myChanServHelp(User *u)
Definition: cs_clear.c:57
void AnopeFini(void)
Definition: cs_clear.c:46
MDE void moduleAddVersion(const char *version)
Definition: modules.c:1760
#define CUS_HALFOP
Definition: services.h:1343
E char * flood_mode_char_remove
Definition: extern.h:42
int svsmode_ucmode
Definition: services.h:363
MDE void moduleSetChanHelp(void(*func)(User *u))
Definition: modules.c:2090
#define CUS_PROTECT
Definition: services.h:1345
Command * c
Definition: ns_recover.c:17
#define CHANSERV
Definition: modules.h:60
int protect
Definition: services.h:333
E void alog(const char *fmt,...) FORMAT(printf
#define MOD_CONT
Definition: modules.h:54
E void check_modes(Channel *c)
Definition: chanserv.c:1081
E int debug
Definition: extern.h:775
char * adminunset
Definition: services.h:306
#define CUS_OWNER
Definition: services.h:1344
#define whosends(ci)
Definition: extern.h:163
char * username
Definition: services.h:877
EList * bans
Definition: services.h:1012
E void anope_cmd_mode(char *source, char *dest, const char *fmt,...)
Definition: ircd.c:211
Definition: modules.h:99
MDE Command * createCommand(const char *name, int(*func)(User *u), int(*has_priv)(User *u), int help_all, int help_reg, int help_oper, int help_admin, int help_root)
Definition: modules.c:987
E void do_cmode(const char *source, int ac, char **av)
Definition: channels.c:1183
char * flood
Definition: services.h:1010
uint32 tsmode
Definition: services.h:381
Entry * entries
Definition: services.h:1033
int admin
Definition: services.h:324
char name[CHANMAX]
Definition: services.h:1000
#define GET_USER(u)
Definition: services.h:270
int owner
Definition: services.h:302
E char * s_ChanServ
Definition: extern.h:285
char * mask
Definition: services.h:1042
MDE int moduleAddCommand(CommandHash *cmdTable[], Command *c, int pos)
Definition: modules.c:1082
int halfop
Definition: services.h:316
#define BUFSIZE
Definition: config.h:47
#define CUS_OP
Definition: services.h:1341
int fmode
Definition: services.h:349
#define MOD_UNIQUE
Definition: module.h:11
struct channel_::c_userlist * users