Anope IRC Services  Version 1.8
cs_akick.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 
18 static int do_akick(User * u);
19 static void myChanServHelp(User * u);
20 static int get_access_nc(NickCore *nc, ChannelInfo *ci);
21 
28 int AnopeInit(int argc, char **argv)
29 {
30  Command *c;
31 
32  moduleAddAuthor("Anope");
33  moduleAddVersion(VERSION_STRING);
35 
36  c = createCommand("AKICK", do_akick, NULL, CHAN_HELP_AKICK, -1, -1, -1,
37  -1);
39 
41 
42  return MOD_CONT;
43 }
44 
48 void AnopeFini(void)
49 {
50 
51 }
52 
53 
54 
59 static void myChanServHelp(User * u)
60 {
61  notice_lang(s_ChanServ, u, CHAN_HELP_CMD_AKICK);
62 }
63 
69  /* `last' is set to the last index this routine was called with */
70 static int akick_del(User * u, AutoKick * akick)
71 {
72  if (!(akick->flags & AK_USED))
73  return 0;
74  if (akick->flags & AK_ISNICK) {
75  akick->u.nc = NULL;
76  } else {
77  free(akick->u.mask);
78  akick->u.mask = NULL;
79  }
80  if (akick->reason) {
81  free(akick->reason);
82  akick->reason = NULL;
83  }
84  if (akick->creator) {
85  free(akick->creator);
86  akick->creator = NULL;
87  }
88  akick->addtime = 0;
89  akick->flags = 0;
90  return 1;
91 }
92 
93 static int akick_del_callback(User * u, int num, va_list args)
94 {
95  ChannelInfo *ci = va_arg(args, ChannelInfo *);
96  int *last = va_arg(args, int *);
97 
98  *last = num;
99 
100  if (num < 1 || num > ci->akickcount)
101  return 0;
102 
103  return akick_del(u, &ci->akick[num - 1]);
104 }
105 
106 
107 static int akick_list(User * u, int index, ChannelInfo * ci, int *sent_header)
108 {
109  AutoKick *akick = &ci->akick[index];
110 
111  if (!(akick->flags & AK_USED))
112  return 0;
113  if (!*sent_header) {
114  notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name);
115  *sent_header = 1;
116  }
117 
118  notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_FORMAT, index + 1,
119  ((akick->flags & AK_ISNICK) ? akick->u.nc->
120  display : akick->u.mask),
121  (akick->reason ? akick->
122  reason : getstring(u->na, NO_REASON)));
123  return 1;
124 }
125 
126 static int akick_list_callback(User * u, int num, va_list args)
127 {
128  ChannelInfo *ci = va_arg(args, ChannelInfo *);
129  int *sent_header = va_arg(args, int *);
130  if (num < 1 || num > ci->akickcount)
131  return 0;
132  return akick_list(u, num - 1, ci, sent_header);
133 }
134 
135 static int akick_view(User * u, int index, ChannelInfo * ci, int *sent_header)
136 {
137  AutoKick *akick = &ci->akick[index];
138  char timebuf[64];
139  struct tm tm;
140 
141  if (!(akick->flags & AK_USED))
142  return 0;
143  if (!*sent_header) {
144  notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name);
145  *sent_header = 1;
146  }
147 
148  if (akick->addtime) {
149  tm = *localtime(&akick->addtime);
150  strftime_lang(timebuf, sizeof(timebuf), u,
151  STRFTIME_SHORT_DATE_FORMAT, &tm);
152  } else {
153  snprintf(timebuf, sizeof(timebuf), getstring(u->na, UNKNOWN));
154  }
155 
157  ((akick->
158  flags & AK_STUCK) ? CHAN_AKICK_VIEW_FORMAT_STUCK :
159  CHAN_AKICK_VIEW_FORMAT), index + 1,
160  ((akick->flags & AK_ISNICK) ? akick->u.nc->
161  display : akick->u.mask),
162  akick->creator ? akick->creator : getstring(u->na,
163  UNKNOWN),
164  timebuf,
165  (akick->reason ? akick->
166  reason : getstring(u->na, NO_REASON)));
167  return 1;
168 }
169 
170 static int akick_view_callback(User * u, int num, va_list args)
171 {
172  ChannelInfo *ci = va_arg(args, ChannelInfo *);
173  int *sent_header = va_arg(args, int *);
174  if (num < 1 || num > ci->akickcount)
175  return 0;
176  return akick_view(u, num - 1, ci, sent_header);
177 }
178 
179 
180 
181 static int do_akick(User * u)
182 {
183  char *chan = strtok(NULL, " ");
184  char *cmd = strtok(NULL, " ");
185  char *mask = strtok(NULL, " ");
186  char *reason = strtok(NULL, "");
187  ChannelInfo *ci;
188  AutoKick *akick;
189  int i;
190  Channel *c;
191  struct c_userlist *cu = NULL;
192  struct c_userlist *next;
193  User *u2;
194  char *argv[3];
195  int count = 0;
196 
197  if (!cmd || (!mask && (!stricmp(cmd, "ADD") || !stricmp(cmd, "STICK")
198  || !stricmp(cmd, "UNSTICK")
199  || !stricmp(cmd, "DEL")))) {
200 
201  syntax_error(s_ChanServ, u, "AKICK", CHAN_AKICK_SYNTAX);
202  } else if (!(ci = cs_findchan(chan))) {
203  notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
204  } else if (ci->flags & CI_VERBOTEN) {
205  notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
206  } else if (!check_access(u, ci, CA_AKICK) && !is_services_admin(u)) {
207  notice_lang(s_ChanServ, u, ACCESS_DENIED);
208  } else if (stricmp(cmd, "ADD") == 0) {
209  NickAlias *na = findnick(mask), *na2;
210  NickCore *nc = NULL;
211  char *nick, *user, *host;
212  int freemask = 0;
213 
214  if (readonly) {
215  notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
216  return MOD_CONT;
217  }
218 
219  if (!na) {
220  split_usermask(mask, &nick, &user, &host);
221  mask =
222  scalloc(strlen(nick) + strlen(user) + strlen(host) + 3, 1);
223  freemask = 1;
224  sprintf(mask, "%s!%s@%s", nick, user, host);
225  free(nick);
226  free(user);
227  free(host);
228  } else {
229  if (na->status & NS_VERBOTEN) {
230  notice_lang(s_ChanServ, u, NICK_X_FORBIDDEN, mask);
231  return MOD_CONT;
232  }
233  nc = na->nc;
234  }
235 
236  /* Check excepts BEFORE we get this far */
237  if (ircd->except) {
238  if (is_excepted_mask(ci, mask) == 1) {
239  notice_lang(s_ChanServ, u, CHAN_EXCEPTED, mask, chan);
240  if (freemask)
241  free(mask);
242  return MOD_CONT;
243  }
244  }
245 
246  /* Check whether target nick has equal/higher access
247  * or whether the mask matches a user with higher/equal access - Viper */
248  if ((ci->flags & CI_PEACE) && nc) {
249  if ((nc == ci->founder) || (get_access_nc(nc, ci) >= get_access(u, ci))) {
250  notice_lang(s_ChanServ, u, PERMISSION_DENIED);
251  if (freemask)
252  free(mask);
253  return MOD_CONT;
254  }
255  } else if ((ci->flags & CI_PEACE)) {
256  char buf[BUFSIZE];
257  /* Match against all currently online users with equal or
258  * higher access. - Viper */
259  for (i = 0; i < 1024; i++) {
260  for (u2 = userlist[i]; u2; u2 = u2->next) {
261  if (is_founder(u2, ci) || (get_access(u2, ci) >= get_access(u, ci))) {
262  if (match_usermask(mask, u2)) {
263  notice_lang(s_ChanServ, u, PERMISSION_DENIED);
264  free(mask);
265  return MOD_CONT;
266  }
267  }
268  }
269  }
270 
271  /* Match against the lastusermask of all nickalias's with equal
272  * or higher access. - Viper */
273  for (i = 0; i < 1024; i++) {
274  for (na2 = nalists[i]; na2; na2 = na2->next) {
275  if (na2->status & NS_VERBOTEN)
276  continue;
277 
278  if (na2->nc && ((na2->nc == ci->founder) || (get_access_nc(na2->nc, ci)
279  >= get_access(u, ci)))) {
280  snprintf(buf, BUFSIZE, "%s!%s", na2->nick, na2->last_usermask);
281  if (match_wild_nocase(mask, buf)) {
282  notice_lang(s_ChanServ, u, PERMISSION_DENIED);
283  free(mask);
284  return MOD_CONT;
285  }
286  }
287  }
288  }
289  }
290 
291  for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
292  if (!(akick->flags & AK_USED))
293  continue;
294  if ((akick->flags & AK_ISNICK) ? akick->u.nc == nc
295  : stricmp(akick->u.mask, mask) == 0) {
296  notice_lang(s_ChanServ, u, CHAN_AKICK_ALREADY_EXISTS,
297  (akick->flags & AK_ISNICK) ? akick->u.nc->
298  display : akick->u.mask, chan);
299  if (freemask)
300  free(mask);
301  return MOD_CONT;
302  }
303  }
304 
305  /* All entries should be in use so we don't have to go over
306  * the entire list. We simply add new entries at the end. */
307  if (ci->akickcount >= CSAutokickMax) {
308  notice_lang(s_ChanServ, u, CHAN_AKICK_REACHED_LIMIT, CSAutokickMax);
309  if (freemask)
310  free(mask);
311  return MOD_CONT;
312  }
313  ci->akickcount++;
314  ci->akick =
315  srealloc(ci->akick, sizeof(AutoKick) * ci->akickcount);
316  akick = &ci->akick[i];
317  akick->flags = AK_USED;
318  if (nc) {
319  akick->flags |= AK_ISNICK;
320  akick->u.nc = nc;
321  } else {
322  akick->u.mask = sstrdup(mask);
323  }
324  akick->creator = sstrdup(u->nick);
325  akick->addtime = time(NULL);
326  if (reason) {
327  if (strlen(reason) > 200)
328  reason[200] = '\0';
329  akick->reason = sstrdup(reason);
330  } else {
331  akick->reason = NULL;
332  }
333 
334  /* Auto ENFORCE #63 */
335  c = findchan(ci->name);
336  if (c) {
337  cu = c->users;
338  while (cu) {
339  next = cu->next;
340  if (check_kick(cu->user, c->name, c->creation_time)) {
341  argv[0] = sstrdup(c->name);
342  argv[1] = sstrdup(cu->user->nick);
343  if (akick->reason)
344  argv[2] = sstrdup(akick->reason);
345  else
346  argv[2] = sstrdup("none");
347 
348  do_kick(s_ChanServ, 3, argv);
349 
350  free(argv[2]);
351  free(argv[1]);
352  free(argv[0]);
353  count++;
354 
355  }
356  cu = next;
357  }
358  }
359  alog("%s: %s!%s@%s added akick for %s to %s",
360  s_ChanServ, u->nick, u->username, u->host, mask, chan);
361  notice_lang(s_ChanServ, u, CHAN_AKICK_ADDED, mask, chan);
362 
363  if (count)
364  notice_lang(s_ChanServ, u, CHAN_AKICK_ENFORCE_DONE, chan,
365  count);
366 
367  if (freemask)
368  free(mask);
369 
370  } else if (stricmp(cmd, "STICK") == 0) {
371 
372  if (readonly) {
373  notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
374  return MOD_CONT;
375  }
376 
377  if (ci->akickcount == 0) {
378  notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name);
379  return MOD_CONT;
380  }
381 
382  for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
383  if (!(akick->flags & AK_USED) || (akick->flags & AK_ISNICK))
384  continue;
385  if (!stricmp(akick->u.mask, mask))
386  break;
387  }
388 
389  if (i == ci->akickcount) {
390  notice_lang(s_ChanServ, u, CHAN_AKICK_NOT_FOUND, mask,
391  ci->name);
392  return MOD_CONT;
393  }
394 
395  akick->flags |= AK_STUCK;
396  alog("%s: %s!%s@%s set STICK on akick %s on %s",
397  s_ChanServ, u->nick, u->username, u->host, akick->u.mask, ci->name);
398  notice_lang(s_ChanServ, u, CHAN_AKICK_STUCK, akick->u.mask,
399  ci->name);
400 
401  if (ci->c)
402  stick_mask(ci, akick);
403  } else if (stricmp(cmd, "UNSTICK") == 0) {
404  if (readonly) {
405  notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
406  return MOD_CONT;
407  }
408 
409  if (ci->akickcount == 0) {
410  notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name);
411  return MOD_CONT;
412  }
413 
414  for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
415  if (!(akick->flags & AK_USED) || (akick->flags & AK_ISNICK))
416  continue;
417  if (!stricmp(akick->u.mask, mask))
418  break;
419  }
420 
421  if (i == ci->akickcount) {
422  notice_lang(s_ChanServ, u, CHAN_AKICK_NOT_FOUND, mask,
423  ci->name);
424  return MOD_CONT;
425  }
426 
427  akick->flags &= ~AK_STUCK;
428  alog("%s: %s!%s@%s unset STICK on akick %s on %s",
429  s_ChanServ, u->nick, u->username, u->host, akick->u.mask, ci->name);
430  notice_lang(s_ChanServ, u, CHAN_AKICK_UNSTUCK, akick->u.mask,
431  ci->name);
432 
433  } else if (stricmp(cmd, "DEL") == 0) {
434  int deleted, a, b;
435 
436  if (readonly) {
437  notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
438  return MOD_CONT;
439  }
440 
441  if (ci->akickcount == 0) {
442  notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, chan);
443  return MOD_CONT;
444  }
445 
446  /* Special case: is it a number/list? Only do search if it isn't. */
447  if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
448  int count, last = -1;
449  deleted = process_numlist(mask, &count, akick_del_callback, u,
450  ci, &last);
451  if (!deleted) {
452  if (count == 1) {
453  notice_lang(s_ChanServ, u, CHAN_AKICK_NO_SUCH_ENTRY,
454  last, ci->name);
455  } else {
456  notice_lang(s_ChanServ, u, CHAN_AKICK_NO_MATCH,
457  ci->name);
458  }
459  } else if (deleted == 1) {
460  alog("%s: %s!%s@%s deleted 1 akick on %s",
461  s_ChanServ, u->nick, u->username, u->host, ci->name);
462  notice_lang(s_ChanServ, u, CHAN_AKICK_DELETED_ONE,
463  ci->name);
464  } else {
465  alog("%s: %s!%s@%s deleted %d akicks on %s",
466  s_ChanServ, u->nick, u->username, u->host, deleted,
467  ci->name);
468  notice_lang(s_ChanServ, u, CHAN_AKICK_DELETED_SEVERAL,
469  deleted, ci->name);
470  }
471  } else {
472  NickAlias *na = findnick(mask);
473  NickCore *nc = (na ? na->nc : NULL);
474 
475  for (akick = ci->akick, i = 0; i < ci->akickcount;
476  akick++, i++) {
477  if (!(akick->flags & AK_USED))
478  continue;
479  if (((akick->flags & AK_ISNICK) && akick->u.nc == nc)
480  || (!(akick->flags & AK_ISNICK)
481  && stricmp(akick->u.mask, mask) == 0))
482  break;
483  }
484  if (i == ci->akickcount) {
485  notice_lang(s_ChanServ, u, CHAN_AKICK_NOT_FOUND, mask,
486  chan);
487  return MOD_CONT;
488  }
489  alog("%s: %s!%s@%s deleted akick %s on %s",
490  s_ChanServ, u->nick, u->username, u->host, mask, chan);
491  notice_lang(s_ChanServ, u, CHAN_AKICK_DELETED, mask, chan);
492  akick_del(u, akick);
493  deleted = 1;
494  }
495  if (deleted) {
496  /* Reordering - DrStein */
497  for (b = 0; b < ci->akickcount; b++) {
498  if (ci->akick[b].flags & AK_USED) {
499  for (a = 0; a < ci->akickcount; a++) {
500  if (a > b)
501  break;
502  if (!(ci->akick[a].flags & AK_USED)) {
503  ci->akick[a].flags = ci->akick[b].flags;
504  if (ci->akick[b].flags & AK_ISNICK) {
505  ci->akick[a].u.nc = ci->akick[b].u.nc;
506  } else {
507  ci->akick[a].u.mask =
508  sstrdup(ci->akick[b].u.mask);
509  }
510  /* maybe we should first check whether there
511  is a reason before we sstdrup it -Certus */
512  if (ci->akick[b].reason)
513  ci->akick[a].reason =
514  sstrdup(ci->akick[b].reason);
515  else
516  ci->akick[a].reason = NULL;
517  ci->akick[a].creator =
518  sstrdup(ci->akick[b].creator);
519  ci->akick[a].addtime = ci->akick[b].addtime;
520 
521  akick_del(u, &ci->akick[b]);
522  break;
523  }
524  }
525  }
526  }
527  /* After reordering only the entries at the end could still be empty.
528  * We ll free the places no longer in use... - Viper */
529  for (i = ci->akickcount - 1; i >= 0; i--) {
530  if (ci->akick[i].flags & AK_USED)
531  break;
532 
533  ci->akickcount--;
534  }
535  ci->akick =
536  srealloc(ci->akick,sizeof(AutoKick) * ci->akickcount);
537  }
538  } else if (stricmp(cmd, "LIST") == 0) {
539  int sent_header = 0;
540 
541  if (ci->akickcount == 0) {
542  notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, chan);
543  return MOD_CONT;
544  }
545  if (mask && isdigit(*mask) &&
546  strspn(mask, "1234567890,-") == strlen(mask)) {
547  process_numlist(mask, NULL, akick_list_callback, u, ci,
548  &sent_header);
549  } else {
550  for (akick = ci->akick, i = 0; i < ci->akickcount;
551  akick++, i++) {
552  if (!(akick->flags & AK_USED))
553  continue;
554  if (mask) {
555  if (!(akick->flags & AK_ISNICK)
556  && !match_wild_nocase(mask, akick->u.mask))
557  continue;
558  if ((akick->flags & AK_ISNICK)
559  && !match_wild_nocase(mask, akick->u.nc->display))
560  continue;
561  }
562  akick_list(u, i, ci, &sent_header);
563  }
564  }
565  if (!sent_header)
566  notice_lang(s_ChanServ, u, CHAN_AKICK_NO_MATCH, chan);
567 
568  } else if (stricmp(cmd, "VIEW") == 0) {
569  int sent_header = 0;
570 
571  if (ci->akickcount == 0) {
572  notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, chan);
573  return MOD_CONT;
574  }
575  if (mask && isdigit(*mask) &&
576  strspn(mask, "1234567890,-") == strlen(mask)) {
577  process_numlist(mask, NULL, akick_view_callback, u, ci,
578  &sent_header);
579  } else {
580  for (akick = ci->akick, i = 0; i < ci->akickcount;
581  akick++, i++) {
582  if (!(akick->flags & AK_USED))
583  continue;
584  if (mask) {
585  if (!(akick->flags & AK_ISNICK)
586  && !match_wild_nocase(mask, akick->u.mask))
587  continue;
588  if ((akick->flags & AK_ISNICK)
589  && !match_wild_nocase(mask, akick->u.nc->display))
590  continue;
591  }
592  akick_view(u, i, ci, &sent_header);
593  }
594  }
595  if (!sent_header)
596  notice_lang(s_ChanServ, u, CHAN_AKICK_NO_MATCH, chan);
597 
598  } else if (stricmp(cmd, "ENFORCE") == 0) {
599  Channel *c = findchan(ci->name);
600  struct c_userlist *cu = NULL;
601  struct c_userlist *next;
602  char *argv[3];
603  int count = 0;
604 
605  if (!c) {
606  notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, ci->name);
607  return MOD_CONT;
608  }
609 
610  cu = c->users;
611 
612  while (cu) {
613  next = cu->next;
614  if (check_kick(cu->user, c->name, c->creation_time)) {
615  argv[0] = sstrdup(c->name);
616  argv[1] = sstrdup(cu->user->nick);
617  argv[2] = sstrdup(CSAutokickReason);
618 
619  do_kick(s_ChanServ, 3, argv);
620 
621  free(argv[2]);
622  free(argv[1]);
623  free(argv[0]);
624 
625  count++;
626  }
627  cu = next;
628  }
629 
630  notice_lang(s_ChanServ, u, CHAN_AKICK_ENFORCE_DONE, chan, count);
631 
632  } else if (stricmp(cmd, "CLEAR") == 0) {
633 
634  if (readonly) {
635  notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
636  return MOD_CONT;
637  }
638 
639  for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
640  if (!(akick->flags & AK_USED))
641  continue;
642  akick_del(u, akick);
643  }
644 
645  free(ci->akick);
646  ci->akick = NULL;
647  ci->akickcount = 0;
648 
649  alog("%s: %s!%s@%s cleared akicks on %s",
650  s_ChanServ, u->nick, u->username, u->host, ci->name);
651  notice_lang(s_ChanServ, u, CHAN_AKICK_CLEAR, ci->name);
652 
653  } else {
654  syntax_error(s_ChanServ, u, "AKICK", CHAN_AKICK_SYNTAX);
655  }
656  return MOD_CONT;
657 }
658 
659 
660 static int get_access_nc(NickCore *nc, ChannelInfo *ci)
661 {
662  ChanAccess *access;
663  if (!ci || !nc)
664  return 0;
665 
666  if ((access = get_access_entry(nc, ci)))
667  return access->level;
668  return 0;
669 }
670 
671 /* EOF */
void AnopeFini(void)
Definition: cs_akick.c:48
E size_t strspn(const char *s, const char *accept)
Definition: compat.c:106
E void split_usermask(const char *mask, char **nick, char **user, char **host)
Definition: users.c:1085
E int process_numlist(const char *numstr, int *count_ret, range_callback_t callback, User *u,...)
Definition: misc.c:292
static int get_access_nc(NickCore *nc, ChannelInfo *ci)
Definition: cs_akick.c:660
uint16 akickcount
Definition: services.h:678
E int readonly
Definition: extern.h:776
E int match_wild_nocase(const char *pattern, const char *str)
Definition: misc.c:268
char nick[NICKMAX]
Definition: services.h:875
E int snprintf(char *buf, size_t size, const char *fmt,...)
Definition: compat.c:37
E NickAlias * findnick(const char *nick)
Definition: db-merger.c:1857
E IRCDVar * ircd
Definition: extern.h:39
E void do_kick(const char *source, int ac, char **av)
Definition: channels.c:638
E int check_access(User *user, ChannelInfo *ci, int what)
Definition: chanserv.c:1974
#define AK_STUCK
Definition: services.h:636
E int stricmp(const char *s1, const char *s2)
Definition: compat.c:58
int16 level
Definition: services.h:594
#define NS_VERBOTEN
Definition: services.h:1273
#define CI_VERBOTEN
Definition: services.h:725
NickAlias * next
Definition: services.h:525
#define getstring(na, index)
Definition: extern.h:731
E char * CSAutokickReason
Definition: extern.h:408
char * host
Definition: services.h:878
E void stick_mask(ChannelInfo *ci, AutoKick *akick)
Definition: chanserv.c:2694
#define CA_AKICK
Definition: services.h:750
union AutoKick::@1 u
static int akick_del(User *u, AutoKick *akick)
Definition: cs_akick.c:70
E int CSAutokickMax
Definition: extern.h:407
#define AK_USED
Definition: services.h:634
MDE void moduleAddAuthor(const char *author)
Definition: modules.c:1772
E void syntax_error(char *service, User *u, const char *command, int msgnum)
Definition: language.c:295
E int is_excepted_mask(ChannelInfo *ci, char *mask)
Definition: users.c:964
char name[CHANMAX]
Definition: services.h:654
int except
Definition: services.h:320
#define AK_ISNICK
Definition: services.h:635
E void notice_lang(char *source, User *dest, int message,...)
Definition: send.c:169
MDE void moduleSetType(MODType type)
Definition: modules.c:818
static int akick_del_callback(User *u, int num, va_list args)
Definition: cs_akick.c:93
static void myChanServHelp(User *u)
Definition: cs_akick.c:59
E Channel * findchan(const char *chan)
Definition: channels.c:394
E char * sstrdup(const char *s)
Definition: memory.c:105
static int akick_list(User *u, int index, ChannelInfo *ci, int *sent_header)
Definition: cs_akick.c:107
NickCore * nc
Definition: services.h:533
E void * scalloc(long elsize, long els)
Definition: memory.c:55
#define CI_PEACE
Definition: services.h:721
static int akick_view(User *u, int index, ChannelInfo *ci, int *sent_header)
Definition: cs_akick.c:135
char * display
Definition: services.h:542
static int akick_view_callback(User *u, int num, va_list args)
Definition: cs_akick.c:170
uint32 flags
Definition: services.h:669
int AnopeInit(int argc, char **argv)
Definition: cs_akick.c:28
uint16 status
Definition: services.h:532
time_t creation_time
Definition: services.h:1002
char * reason
Definition: services.h:628
MDE void moduleAddVersion(const char *version)
Definition: modules.c:1760
struct channel_ * c
Definition: services.h:692
static int akick_list_callback(User *u, int num, va_list args)
Definition: cs_akick.c:126
static int do_akick(User *u)
Definition: cs_akick.c:181
MDE void moduleSetChanHelp(void(*func)(User *u))
Definition: modules.c:2090
Command * c
Definition: ns_recover.c:17
#define CHANSERV
Definition: modules.h:60
User * next
Definition: services.h:873
NickCore * nc
Definition: services.h:626
E void alog(const char *fmt,...) FORMAT(printf
E int check_kick(User *user, char *chan, time_t chants)
Definition: chanserv.c:1500
#define MOD_CONT
Definition: modules.h:54
E int is_founder(User *user, ChannelInfo *ci)
Definition: chanserv.c:2255
E int is_services_admin(User *u)
Definition: operserv.c:591
char * mask
Definition: services.h:625
struct c_userlist * next
Definition: services.h:1016
E NickAlias * nalists[1024]
Definition: extern.h:923
char * username
Definition: services.h:877
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
char name[CHANMAX]
Definition: services.h:1000
E ChannelInfo * cs_findchan(const char *chan)
Definition: db-merger.c:2000
E void * srealloc(void *oldptr, long newsize)
Definition: memory.c:80
time_t addtime
Definition: services.h:631
E ChanAccess * get_access_entry(NickCore *nc, ChannelInfo *ci)
Definition: chanserv.c:2310
AutoKick * akick
Definition: services.h:679
char * creator
Definition: services.h:630
uint16 flags
Definition: services.h:623
E char * s_ChanServ
Definition: extern.h:285
E int get_access(User *user, ChannelInfo *ci)
Definition: chanserv.c:2332
E int strftime_lang(char *buf, int size, User *u, int format, struct tm *tm)
Definition: language.c:240
E User * userlist[1024]
Definition: extern.h:1138
E int match_usermask(const char *mask, User *user)
Definition: users.c:1024
MDE int moduleAddCommand(CommandHash *cmdTable[], Command *c, int pos)
Definition: modules.c:1082
NickCore * founder
Definition: services.h:655
#define BUFSIZE
Definition: config.h:47
NickAlias * na
Definition: services.h:892
#define MOD_UNIQUE
Definition: module.h:11
struct channel_::c_userlist * users