Anope IRC Services  Version 1.8
operserv.c
Go to the documentation of this file.
1 /* OperServ 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 #include "services.h"
15 #include "pseudo.h"
16 
17 /*************************************************************************/
18 
19 /* List of Services administrators */
21 /* List of Services operators */
23 /* AKILL, SGLINE, SQLINE and SZLINE lists */
25 
26 /*************************************************************************/
27 
28 static int compare_adminlist_entries(SList * slist, void *item1,
29  void *item2);
30 static int compare_operlist_entries(SList * slist, void *item1,
31  void *item2);
32 static void free_adminlist_entry(SList * slist, void *item);
33 static void free_operlist_entry(SList * slist, void *item);
34 
35 static int is_akill_entry_equal(SList * slist, void *item1, void *item2);
36 static void free_akill_entry(SList * slist, void *item);
37 static int is_sgline_entry_equal(SList * slist, void *item1, void *item2);
38 static void free_sgline_entry(SList * slist, void *item);
39 static int is_sqline_entry_equal(SList * slist, void *item1, void *item2);
40 static void free_sqline_entry(SList * slist, void *item);
41 static int is_szline_entry_equal(SList * slist, void *item1, void *item2);
42 static void free_szline_entry(SList * slist, void *item);
43 
44 time_t DefContimer;
46 char *defconReverseModes(const char *modes);
47 
48 uint32 DefConModesOn; /* Modes to be enabled during DefCon */
49 uint32 DefConModesOff; /* Modes to be disabled during DefCon */
50 ChannelInfo DefConModesCI; /* ChannelInfo containg params for locked modes
51  * during DefCon; I would've done this nicer if i
52  * could, but all damn mode functions require a
53  * ChannelInfo struct! --gdex
54  */
55 
56 
57 #ifdef DEBUG_COMMANDS
58 static int do_matchwild(User * u);
59 #endif
60 
61 void moduleAddOperServCmds(void);
62 /*************************************************************************/
63 
64 /* Options for the lists */
68 };
69 
76 
77 /*************************************************************************/
78 /* *INDENT-OFF* */
80 #ifdef DEBUG_COMMANDS
81  Command *c;
82 #endif
83 
85 
86 #ifdef DEBUG_COMMANDS
87  c = createCommand("LISTTIMERS", send_timeout_list, is_services_root, -1,-1,-1,-1,-1); addCoreCommand(OPERSERV,c);
88  c = createCommand("MATCHWILD", do_matchwild, is_services_root, -1,-1,-1,-1,-1); addCoreCommand(OPERSERV,c);
89 #endif
90 }
91 
92 /* *INDENT-ON* */
93 /*************************************************************************/
94 /*************************************************************************/
95 
96 /* OperServ initialization. */
97 
98 void os_init(void)
99 {
101 
102  /* Initialization of the lists */
103  slist_init(&servadmins);
104  servadmins.opts = &saopts;
105  slist_init(&servopers);
106  servopers.opts = &soopts;
107 
108  slist_init(&akills);
109  akills.opts = &akopts;
110 
111  if (ircd->sgline) {
112  slist_init(&sglines);
113  sglines.opts = &sgopts;
114  }
115  if (ircd->sqline) {
116  slist_init(&sqlines);
117  sqlines.opts = &sqopts;
118  }
119  if (ircd->szline) {
120  slist_init(&szlines);
121  szlines.opts = &szopts;
122  }
123 }
124 
125 /*************************************************************************/
126 
127 /* Main OperServ routine. */
128 
129 void operserv(User * u, char *buf)
130 {
131  char *cmd;
132  char *s;
133 
134  alog("%s: %s: %s", s_OperServ, u->nick, buf);
135 
136  cmd = strtok(buf, " ");
137  if (!cmd) {
138  return;
139  } else if (stricmp(cmd, "\1PING") == 0) {
140  if (!(s = strtok(NULL, ""))) {
141  s = "";
142  }
143  anope_cmd_ctcp(s_OperServ, u->nick, "PING %s", s);
144  } else {
145  mod_run_cmd(s_OperServ, u, OPERSERV, cmd);
146  }
147 }
148 
149 /*************************************************************************/
150 /**************************** Privilege checks ***************************/
151 /*************************************************************************/
152 
153 /* Load old AKILL data. */
154 
155 #define SAFE(x) do { \
156  if ((x) < 0) { \
157  if (!forceload) \
158  fatal("Read error on %s", AutokillDBName); \
159  break; \
160  } \
161 } while (0)
162 
163 static void load_old_akill(void)
164 {
165  dbFILE *f;
166  int i, j;
167  uint16 tmp16;
168  uint32 tmp32;
169  char buf[NICKMAX], mask2[BUFSIZE], *mask, *s;
170  Akill *ak, *entry;
171 
172  if (!
173  (f =
174  open_db("AKILL", AutokillDBName ? AutokillDBName : "akill.db",
175  "r", 9)))
176  return;
177 
178  get_file_version(f);
179 
180  read_int16(&tmp16, f);
181  slist_setcapacity(&akills, tmp16);
182 
183  for (j = 0; j < akills.capacity; j++) {
184  ak = scalloc(sizeof(Akill), 1);
185 
186  SAFE(read_string(&mask, f));
187  s = strchr(mask, '@');
188  *s = 0;
189  s++;
190  ak->user = sstrdup(mask);
191  ak->host = sstrdup(s);
192  SAFE(read_string(&ak->reason, f));
193  SAFE(read_buffer(buf, f));
194  if (!*buf)
195  ak->by = sstrdup("<unknown>");
196  else
197  ak->by = sstrdup(buf);
198  SAFE(read_int32(&tmp32, f));
199  ak->seton = tmp32 ? tmp32 : time(NULL);
200  SAFE(read_int32(&tmp32, f));
201  ak->expires = tmp32;
202 
203  /* Sanity checks *sigh* */
204 
205  /* No nicknames allowed! */
206  if (strchr(ak->user, '!')) {
207  anope_cmd_remove_akill(ak->user, ak->host);
208  free(ak);
209  continue;
210  }
211 
212  snprintf(mask2, sizeof(mask2), "%s@%s", ak->user, ak->host);
213 
214  /* Is the mask already in the AKILL list? */
215  if (slist_indexof(&akills, mask2) != -1) {
216  free(ak);
217  continue;
218  }
219 
220  /* Checks whether there is an AKILL that already covers
221  * the one we want to add, and whether there are AKILLs
222  * that would be covered by this one. Expiry time
223  * does *also* matter.
224  */
225 
226  if (akills.count > 0) {
227 
228  for (i = akills.count - 1; i >= 0; i--) {
229 
230  char amask[BUFSIZE];
231 
232  entry = akills.list[i];
233 
234  if (!entry)
235  continue;
236 
237  snprintf(amask, sizeof(amask), "%s@%s", entry->user,
238  entry->host);
239 
240  if (match_wild_nocase(amask, mask2)
241  && (entry->expires >= ak->expires
242  || entry->expires == 0)) {
243  anope_cmd_remove_akill(ak->user, ak->host);
244  free(ak);
245  ak = NULL;
246  break;
247  }
248 
249  if (match_wild_nocase(mask2, amask)
250  && (entry->expires <= ak->expires || ak->expires == 0))
251  slist_delete(&akills, i);
252  }
253 
254  }
255 
256  if (ak)
257  slist_add(&akills, ak);
258  }
259 
260  close_db(f);
261 }
262 
263 #undef SAFE
264 
265 /* Load OperServ data. */
266 
267 #define SAFE(x) do { \
268  if ((x) < 0) { \
269  if (!forceload) \
270  fatal("Read error on %s", OperDBName); \
271  failed = 1; \
272  break; \
273  } \
274 } while (0)
275 
276 void load_os_dbase(void)
277 {
278  dbFILE *f;
279  int16 i, ver;
280  uint16 tmp16, n;
281  uint32 tmp32;
282  char *s;
283  int failed = 0;
284 
285  if (!(f = open_db(s_OperServ, OperDBName, "r", OPER_VERSION)))
286  return;
287 
288  ver = get_file_version(f);
289 
290  if (ver <= 9) {
291  NickAlias *na;
292 
293  SAFE(read_int16(&n, f));
294  for (i = 0; i < n && !failed; i++) {
295  SAFE(read_string(&s, f));
296  if (s) {
297  na = findnick(s);
298  if (na) {
299  na->nc->flags |= NI_SERVICES_ADMIN;
300  if (slist_indexof(&servadmins, na) == -1)
301  slist_add(&servadmins, na);
302  }
303  free(s);
304  }
305  }
306  if (!failed)
307  SAFE(read_int16(&n, f));
308  for (i = 0; i < n && !failed; i++) {
309  SAFE(read_string(&s, f));
310  if (s) {
311  na = findnick(s);
312  if (na) {
313  na->nc->flags |= NI_SERVICES_OPER;
314  if (slist_indexof(&servopers, na) == -1)
315  slist_add(&servopers, na);
316  }
317  free(s);
318  }
319  }
320  }
321 
322  if (ver >= 7) {
323  uint32 tmp32;
324  SAFE(read_int32(&maxusercnt, f));
325  SAFE(read_int32(&tmp32, f));
326  maxusertime = tmp32;
327  }
328 
329  if (ver <= 10)
330  load_old_akill();
331  else {
332  Akill *ak;
333 
334  read_int16(&tmp16, f);
335  slist_setcapacity(&akills, tmp16);
336 
337  for (i = 0; i < akills.capacity; i++) {
338  ak = scalloc(sizeof(Akill), 1);
339 
340  SAFE(read_string(&ak->user, f));
341  SAFE(read_string(&ak->host, f));
342  SAFE(read_string(&ak->by, f));
343  SAFE(read_string(&ak->reason, f));
344  SAFE(read_int32(&tmp32, f));
345  ak->seton = tmp32;
346  SAFE(read_int32(&tmp32, f));
347  ak->expires = tmp32;
348 
349  slist_add(&akills, ak);
350  }
351  }
352 
353  if (ver >= 11) {
354  SXLine *sx;
355 
356  read_int16(&tmp16, f);
357  slist_setcapacity(&sglines, tmp16);
358 
359  for (i = 0; i < sglines.capacity; i++) {
360  sx = scalloc(sizeof(SXLine), 1);
361 
362  SAFE(read_string(&sx->mask, f));
363  SAFE(read_string(&sx->by, f));
364  SAFE(read_string(&sx->reason, f));
365  SAFE(read_int32(&tmp32, f));
366  sx->seton = tmp32;
367  SAFE(read_int32(&tmp32, f));
368  sx->expires = tmp32;
369 
370  slist_add(&sglines, sx);
371  }
372 
373  if (ver >= 13) {
374  read_int16(&tmp16, f);
375  slist_setcapacity(&sqlines, tmp16);
376 
377  for (i = 0; i < sqlines.capacity; i++) {
378  sx = scalloc(sizeof(SXLine), 1);
379 
380  SAFE(read_string(&sx->mask, f));
381  SAFE(read_string(&sx->by, f));
382  SAFE(read_string(&sx->reason, f));
383  SAFE(read_int32(&tmp32, f));
384  sx->seton = tmp32;
385  SAFE(read_int32(&tmp32, f));
386  sx->expires = tmp32;
387 
388  slist_add(&sqlines, sx);
389  }
390  }
391 
392  read_int16(&tmp16, f);
393  slist_setcapacity(&szlines, tmp16);
394 
395  for (i = 0; i < szlines.capacity; i++) {
396  sx = scalloc(sizeof(SXLine), 1);
397 
398  SAFE(read_string(&sx->mask, f));
399  SAFE(read_string(&sx->by, f));
400  SAFE(read_string(&sx->reason, f));
401  SAFE(read_int32(&tmp32, f));
402  sx->seton = tmp32;
403  SAFE(read_int32(&tmp32, f));
404  sx->expires = tmp32;
405 
406  slist_add(&szlines, sx);
407  }
408  }
409 
410  close_db(f);
411 
412 }
413 
414 #undef SAFE
415 
416 /*************************************************************************/
417 
418 /* Save OperServ data. */
419 
420 #define SAFE(x) do { \
421  if ((x) < 0) { \
422  restore_db(f); \
423  log_perror("Write error on %s", OperDBName); \
424  if (time(NULL) - lastwarn > WarningTimeout) { \
425  anope_cmd_global(NULL, "Write error on %s: %s", OperDBName, \
426  strerror(errno)); \
427  lastwarn = time(NULL); \
428  } \
429  return; \
430  } \
431 } while (0)
432 
433 void save_os_dbase(void)
434 {
435  int i;
436  dbFILE *f;
437  static time_t lastwarn = 0;
438  Akill *ak;
439  SXLine *sx;
440 
441  if (!(f = open_db(s_OperServ, OperDBName, "w", OPER_VERSION)))
442  return;
445 
446  SAFE(write_int16(akills.count, f));
447  for (i = 0; i < akills.count; i++) {
448  ak = akills.list[i];
449 
450  SAFE(write_string(ak->user, f));
451  SAFE(write_string(ak->host, f));
452  SAFE(write_string(ak->by, f));
453  SAFE(write_string(ak->reason, f));
454  SAFE(write_int32(ak->seton, f));
455  SAFE(write_int32(ak->expires, f));
456  }
457 
458  SAFE(write_int16(sglines.count, f));
459  for (i = 0; i < sglines.count; i++) {
460  sx = sglines.list[i];
461 
462  SAFE(write_string(sx->mask, f));
463  SAFE(write_string(sx->by, f));
464  SAFE(write_string(sx->reason, f));
465  SAFE(write_int32(sx->seton, f));
466  SAFE(write_int32(sx->expires, f));
467  }
468 
469  SAFE(write_int16(sqlines.count, f));
470  for (i = 0; i < sqlines.count; i++) {
471  sx = sqlines.list[i];
472 
473  SAFE(write_string(sx->mask, f));
474  SAFE(write_string(sx->by, f));
475  SAFE(write_string(sx->reason, f));
476  SAFE(write_int32(sx->seton, f));
477  SAFE(write_int32(sx->expires, f));
478  }
479 
480  SAFE(write_int16(szlines.count, f));
481  for (i = 0; i < szlines.count; i++) {
482  sx = szlines.list[i];
483 
484  SAFE(write_string(sx->mask, f));
485  SAFE(write_string(sx->by, f));
486  SAFE(write_string(sx->reason, f));
487  SAFE(write_int32(sx->seton, f));
488  SAFE(write_int32(sx->expires, f));
489  }
490 
491  close_db(f);
492 
493 }
494 
495 #undef SAFE
496 
497 /*************************************************************************/
498 
500 {
501 #ifdef USE_RDB
502  if (!rdb_open())
503  return;
504 
505  if (rdb_tag_table("anope_os_akills") == 0) {
506  alog("Unable to tag table 'anope_os_akills' - OperServ RDB save failed.");
507  rdb_close();
508  return;
509  }
510  if (rdb_tag_table("anope_os_sglines") == 0) {
511  alog("Unable to tag table 'anope_os_sglines' - OperServ RDB save failed.");
512  rdb_close();
513  return;
514  }
515  if (rdb_tag_table("anope_os_sqlines") == 0) {
516  alog("Unable to tag table 'anope_os_sqlines' - OperServ RDB save failed.");
517  rdb_close();
518  return;
519  }
520  if (rdb_tag_table("anope_os_szlines") == 0) {
521  alog("Unable to tag table 'anope_os_szlines' - OperServ RDB save failed.");
522  rdb_close();
523  return;
524  }
525  /* We empty anope_os_core as required */
526  if (rdb_empty_table("anope_os_core") == 0) {
527  alog("Unable to empty table 'anope_os_core' - OperServ RDB save failed");
528  rdb_close();
529  return;
530  }
531 
532  if (rdb_save_os_db
533  (maxusercnt, maxusertime, &akills, &sglines, &sqlines,
534  &szlines) == 0) {
535  alog("Unable to save OperServ data - OperServ RDB save failed");
536  rdb_close();
537  return;
538  }
539 
540  if (rdb_clean_table("anope_os_akills") == 0) {
541  alog("Unable to clean table 'anope_os_akills' - OperServ RDB save failed.");
542  rdb_close();
543  return;
544  }
545  if (rdb_clean_table("anope_os_sglines") == 0) {
546  alog("Unable to clean table 'anope_os_sglines' - OperServ RDB save failed.");
547  rdb_close();
548  return;
549  }
550  if (rdb_clean_table("anope_os_sqlines") == 0) {
551  alog("Unable to clean table 'anope_os_sqlines' - OperServ RDB save failed.");
552  rdb_close();
553  return;
554  }
555  if (rdb_clean_table("anope_os_szlines") == 0)
556  alog("Unable to clean table 'anope_os_szlines' - OperServ RDB save failed.");
557 
558  rdb_close();
559 #endif
560 }
561 
562 /*************************************************************************/
563 
564 /* Removes the nick structure from OperServ lists. */
565 
567 {
568  slist_remove(&servadmins, nc);
569  slist_remove(&servopers, nc);
570 }
571 
572 /*************************************************************************/
573 
574 /* Does the given user have Services root privileges?
575  Now enhanced. */
576 
578 {
579  if ((NSStrictPrivileges && !is_oper(u))
580  || (!skeleton && !nick_identified(u)))
581  return 0;
582  if (skeleton || (u->na->nc->flags & NI_SERVICES_ROOT))
583  return 1;
584  return 0;
585 }
586 
587 /*************************************************************************/
588 
589 /* Does the given user have Services admin privileges? */
590 
592 {
593  if ((NSStrictPrivileges && !is_oper(u))
594  || (!skeleton && !nick_identified(u)))
595  return 0;
596  if (skeleton
597  || (u->na->nc->flags & (NI_SERVICES_ADMIN | NI_SERVICES_ROOT)))
598  return 1;
599  return 0;
600 }
601 
602 /*************************************************************************/
603 
604 /* Does the given user have Services oper privileges? */
605 
607 {
608  if ((NSStrictPrivileges && !is_oper(u))
609  || (!skeleton && !nick_identified(u)))
610  return 0;
611  if (skeleton
612  || (u->na->nc->
615  return 1;
616  return 0;
617 }
618 
619 /*************************************************************************/
620 
621 /* Is the given nick a Services root nick? */
622 
624 {
625  if (nc) {
626  if (nc->flags & (NI_SERVICES_ROOT))
627  return 1;
628  }
629  return 0;
630 }
631 
632 /*************************************************************************/
633 
634 /* Is the given nick a Services admin/root nick? */
635 
637 {
638  if (nc) {
640  return 1;
641  }
642  return 0;
643 }
644 
645 /*************************************************************************/
646 
647 /* Is the given nick a Services oper/admin/root nick? */
648 
650 {
651  if (nc) {
652  if (nc->
655  return 1;
656  }
657  return 0;
658 }
659 
660 
661 /*************************************************************************/
662 /*********************** OperServ command functions **********************/
663 /*************************************************************************/
664 
665 /*************************************************************************/
666 
667 
668 Server *server_global(Server * s, char *msg)
669 {
670  Server *sl;
671 
672  while (s) {
673  /* Do not send the notice to ourselves our juped servers */
674  if (!(s->flags & (SERVER_ISME | SERVER_JUPED)))
675  notice_server(s_GlobalNoticer, s, "%s", msg);
676 
677  if (s->links) {
678  sl = server_global(s->links, msg);
679  if (sl)
680  s = sl;
681  else
682  s = s->next;
683  } else {
684  s = s->next;
685  }
686  }
687  return s;
688 
689 }
690 
691 void oper_global(char *nick, char *fmt, ...)
692 {
693  va_list args;
694  char msg[2048]; /* largest valid message is 512, this should cover any global */
695  char dmsg[2048]; /* largest valid message is 512, this should cover any global */
696 
697  va_start(args, fmt);
698  vsnprintf(msg, sizeof(msg), fmt, args);
699  va_end(args);
700 
701  /* I don't like the way this is coded... */
702  if ((nick) && (!AnonymousGlobal)) {
703  snprintf(dmsg, sizeof(dmsg), "[%s] %s", nick, msg);
704  server_global(servlist, dmsg);
705  } else {
706  server_global(servlist, msg);
707  }
708 
709 }
710 
711 /**************************************************************************/
712 
713 
714 /************************************************************************/
715 /*************************************************************************/
716 
717 /* Adds an AKILL to the list. Returns >= 0 on success, -1 if it fails, -2
718  * if only the expiry time was changed.
719  * The success result is the number of AKILLs that were deleted to successfully add one.
720  */
721 
722 int add_akill(User * u, char *mask, const char *by, const time_t expires,
723  const char *reason)
724 {
725  int deleted = 0, i;
726  char *user, *mask2, *host;
727  Akill *entry;
728 
729  if (!mask) {
730  return -1;
731  }
732 
733  /* Checks whether there is an AKILL that already covers
734  * the one we want to add, and whether there are AKILLs
735  * that would be covered by this one. The masks AND the
736  * expiry times are used to determine this, because some
737  * AKILLs may become useful when another one expires.
738  * If so, warn the user in the first case and cleanup
739  * the useless AKILLs in the second.
740  */
741 
742  if (akills.count > 0) {
743 
744  for (i = akills.count - 1; i >= 0; i--) {
745  char amask[BUFSIZE];
746 
747  entry = akills.list[i];
748 
749  if (!entry)
750  continue;
751 
752  snprintf(amask, sizeof(amask), "%s@%s", entry->user,
753  entry->host);
754 
755  if (!stricmp(amask, mask)) {
756  /* We change the AKILL expiry time if its current one is less than the new.
757  * This is preferable to be sure we don't change an important AKILL
758  * accidentely.
759  */
760  if (entry->expires >= expires || entry->expires == 0) {
761  if (u)
762  notice_lang(s_OperServ, u, OPER_AKILL_EXISTS,
763  mask);
764  return -1;
765  } else {
766  entry->expires = expires;
767  if (u)
768  notice_lang(s_OperServ, u, OPER_AKILL_CHANGED,
769  amask);
770  return -2;
771  }
772  }
773 
774  if (match_wild_nocase(amask, mask)
775  && (entry->expires >= expires || entry->expires == 0)) {
776  if (u)
777  notice_lang(s_OperServ, u, OPER_AKILL_ALREADY_COVERED,
778  mask, amask);
779  return -1;
780  }
781 
782  if (match_wild_nocase(mask, amask)
783  && (entry->expires <= expires || expires == 0)) {
784  slist_delete(&akills, i);
785  deleted++;
786  }
787  }
788 
789  }
790 
791  /* We can now check whether the list is full or not. */
792  if (slist_full(&akills)) {
793  if (u)
794  notice_lang(s_OperServ, u, OPER_AKILL_REACHED_LIMIT,
795  akills.limit);
796  return -1;
797  }
798 
799  /* We can now (really) add the AKILL. */
800  mask2 = sstrdup(mask);
801  host = strchr(mask2, '@');
802 
803  if (!host) {
804  free(mask2);
805  return -1;
806  }
807 
808  user = mask2;
809  *host = 0;
810  host++;
811 
812  if (!*host)
813  {
814  if (u)
815  notice_lang(s_OperServ, u, BAD_USERHOST_MASK);
816  free(mask2);
817  return -1;
818  }
819 
820  entry = scalloc(sizeof(Akill), 1);
821 
822  if (!entry) {
823  free(mask2);
824  return -1;
825  }
826 
827  entry->user = sstrdup(user);
828  entry->host = sstrdup(host);
829  entry->by = sstrdup(by);
830  entry->reason = sstrdup(reason);
831  entry->seton = time(NULL);
832  entry->expires = expires;
833 
834  slist_add(&akills, entry);
835 
836  if (AkillOnAdd)
837  anope_cmd_akill(entry->user, entry->host, entry->by, entry->seton,
838  entry->expires, entry->reason);
839 
840  free(mask2);
841 
842  return deleted;
843 }
844 
845 /* Does the user match any AKILLs? */
846 
847 int check_akill(char *nick, const char *username, const char *host,
848  const char *vhost, const char *ip)
849 {
850  int i;
851  Akill *ak;
852  time_t now = time(NULL);
853 
859  return 1;
860  }
861 
862  if (akills.count == 0)
863  return 0;
864 
865  for (i = 0; i < akills.count; i++) {
866  ak = akills.list[i];
867  if (!ak)
868  continue;
869  if (match_wild_nocase(ak->user, username)
870  && match_wild_nocase(ak->host, host)) {
871  if (!ak->expires || ak->expires > now) {
872  anope_cmd_akill(ak->user, ak->host, ak->by, ak->seton,
873  ak->expires, ak->reason);
874  return 1;
875  }
876  }
877  if (ircd->vhost) {
878  if (vhost) {
879  if (match_wild_nocase(ak->user, username)
880  && match_wild_nocase(ak->host, vhost)) {
881 
882  if (!ak->expires || ak->expires > now) {
883  anope_cmd_akill(ak->user, ak->host, ak->by, ak->seton,
884  ak->expires, ak->reason);
885 
886  return 1;
887  }
888  }
889  }
890  }
891  if (ircd->nickip) {
892  if (ip) {
893  if (match_wild_nocase(ak->user, username)
894  && match_wild_nocase(ak->host, ip)) {
895 
896  if (!ak->expires || ak->expires > now) {
897  anope_cmd_akill(ak->user, ak->host, ak->by, ak->seton,
898  ak->expires, ak->reason);
899  return 1;
900  }
901  }
902  }
903  }
904 
905  }
906 
907  return 0;
908 }
909 
910 /* Delete any expired autokills. */
911 
912 void expire_akills(void)
913 {
914  int i;
915  time_t now = time(NULL);
916  Akill *ak;
917 
918  for (i = akills.count - 1; i >= 0; i--) {
919  ak = akills.list[i];
920 
921  if (!ak->expires || ak->expires > now)
922  continue;
923 
924  if (WallAkillExpire)
925  anope_cmd_global(s_OperServ, "AKILL on %s@%s has expired",
926  ak->user, ak->host);
927  slist_delete(&akills, i);
928  }
929 }
930 
931 static void free_akill_entry(SList * slist, void *item)
932 {
933  Akill *ak = item;
934 
935  /* Remove the AKILLs from all the servers */
936  anope_cmd_remove_akill(ak->user, ak->host);
937 
938  /* Free the structure */
939  free(ak->user);
940  free(ak->host);
941  free(ak->by);
942  free(ak->reason);
943  free(ak);
944 }
945 
946 /* item1 is not an Akill pointer, but a char
947  */
948 
949 static int is_akill_entry_equal(SList * slist, void *item1, void *item2)
950 {
951  char *ak1 = item1, buf[BUFSIZE];
952  Akill *ak2 = item2;
953 
954  if (!ak1 || !ak2)
955  return 0;
956 
957  snprintf(buf, sizeof(buf), "%s@%s", ak2->user, ak2->host);
958 
959  if (!stricmp(ak1, buf))
960  return 1;
961  else
962  return 0;
963 }
964 
965 
966 /*************************************************************************/
967 
968 /* Adds an SGLINE to the list. Returns >= 0 on success, -1 if it failed, -2 if
969  * only the expiry time changed.
970  * The success result is the number of SGLINEs that were deleted to successfully add one.
971  */
972 
973 int add_sgline(User * u, char *mask, const char *by, const time_t expires,
974  const char *reason)
975 {
976  int deleted = 0, i;
977  SXLine *entry;
978  User *u2, *next;
979  char buf[BUFSIZE];
980  *buf = '\0';
981 
982  /* Checks whether there is an SGLINE that already covers
983  * the one we want to add, and whether there are SGLINEs
984  * that would be covered by this one.
985  * If so, warn the user in the first case and cleanup
986  * the useless SGLINEs in the second.
987  */
988 
989  if (!mask) {
990  return -1;
991  }
992 
993  if (sglines.count > 0) {
994 
995  for (i = sglines.count - 1; i >= 0; i--) {
996  entry = sglines.list[i];
997 
998  if (!entry)
999  continue;
1000 
1001  if (!stricmp(entry->mask, mask)) {
1002  if (entry->expires >= expires || entry->expires == 0) {
1003  if (u)
1004  notice_lang(s_OperServ, u, OPER_SGLINE_EXISTS,
1005  mask);
1006  return -1;
1007  } else {
1008  entry->expires = expires;
1009  if (u)
1010  notice_lang(s_OperServ, u, OPER_SGLINE_CHANGED,
1011  entry->mask);
1012  return -2;
1013  }
1014  }
1015 
1016  if (match_wild_nocase(entry->mask, mask)
1017  && (entry->expires >= expires || entry->expires == 0)) {
1018  if (u)
1019  notice_lang(s_OperServ, u, OPER_SGLINE_ALREADY_COVERED,
1020  mask, entry->mask);
1021  return -1;
1022  }
1023 
1024  if (match_wild_nocase(mask, entry->mask)
1025  && (entry->expires <= expires || expires == 0)) {
1026  slist_delete(&sglines, i);
1027  deleted++;
1028  }
1029  }
1030 
1031  }
1032 
1033  /* We can now check whether the list is full or not. */
1034  if (slist_full(&sglines)) {
1035  if (u)
1036  notice_lang(s_OperServ, u, OPER_SGLINE_REACHED_LIMIT,
1037  sglines.limit);
1038  return -1;
1039  }
1040 
1041  /* We can now (really) add the SGLINE. */
1042  entry = scalloc(sizeof(SXLine), 1);
1043  if (!entry)
1044  return -1;
1045 
1046  entry->mask = sstrdup(mask);
1047  entry->by = sstrdup(by);
1048  entry->reason = sstrdup(reason);
1049  entry->seton = time(NULL);
1050  entry->expires = expires;
1051 
1052  slist_add(&sglines, entry);
1053 
1054  anope_cmd_sgline(entry->mask, entry->reason);
1055 
1056  if (KillonSGline && !ircd->sglineenforce) {
1057  snprintf(buf, (BUFSIZE - 1), "G-Lined: %s", entry->reason);
1058  u2 = firstuser();
1059  while (u2) {
1060  next = nextuser();
1061  if (!is_oper(u2)) {
1062  if (match_wild_nocase(entry->mask, u2->realname)) {
1063  kill_user(ServerName, u2->nick, buf);
1064  }
1065  }
1066  u2 = next;
1067  }
1068  }
1069  return deleted;
1070 }
1071 
1072 /* Does the user match any SGLINEs? */
1073 
1074 int check_sgline(char *nick, const char *realname)
1075 {
1076  int i;
1077  SXLine *sx;
1078  time_t now = time(NULL);
1079 
1080  if (sglines.count == 0)
1081  return 0;
1082 
1083  for (i = 0; i < sglines.count; i++) {
1084  sx = sglines.list[i];
1085  if (!sx)
1086  continue;
1087 
1088  if (match_wild_nocase(sx->mask, realname)) {
1089  if (!sx->expires || sx->expires > now) {
1090  anope_cmd_sgline(sx->mask, sx->reason);
1091  /* We kill nick since s_sgline can't */
1092  anope_cmd_svskill(ServerName, nick, "G-Lined: %s", sx->reason);
1093  return 1;
1094  }
1095  }
1096  }
1097 
1098  return 0;
1099 }
1100 
1101 /* Delete any expired SGLINEs. */
1102 
1103 void expire_sglines(void)
1104 {
1105  int i;
1106  time_t now = time(NULL);
1107  SXLine *sx;
1108 
1109  for (i = sglines.count - 1; i >= 0; i--) {
1110  sx = sglines.list[i];
1111 
1112  if (!sx->expires || sx->expires > now)
1113  continue;
1114 
1115  if (WallSGLineExpire)
1116  anope_cmd_global(s_OperServ, "SGLINE on \2%s\2 has expired",
1117  sx->mask);
1118  slist_delete(&sglines, i);
1119  }
1120 }
1121 
1122 static void free_sgline_entry(SList * slist, void *item)
1123 {
1124  SXLine *sx = item;
1125 
1126  /* Remove the SGLINE from all the servers */
1127  anope_cmd_unsgline(sx->mask);
1128 
1129  /* Free the structure */
1130  free(sx->mask);
1131  free(sx->by);
1132  free(sx->reason);
1133  free(sx);
1134 }
1135 
1136 /* item1 is not an SXLine pointer, but a char */
1137 
1138 static int is_sgline_entry_equal(SList * slist, void *item1, void *item2)
1139 {
1140  char *sx1 = item1;
1141  SXLine *sx2 = item2;
1142 
1143  if (!sx1 || !sx2)
1144  return 0;
1145 
1146  if (!stricmp(sx1, sx2->mask))
1147  return 1;
1148  else
1149  return 0;
1150 }
1151 
1152 /*************************************************************************/
1153 
1154 /* Adds an SQLINE to the list. Returns >= 0 on success, -1 if it failed, -2 if
1155  * only the expiry time changed.
1156  * The success result is the number of SQLINEs that were deleted to successfully add one.
1157  */
1158 
1159 int add_sqline(User * u, char *mask, const char *by, const time_t expires,
1160  const char *reason)
1161 {
1162  int deleted = 0, i;
1163  User *u2, *next;
1164  SXLine *entry;
1165  char buf[BUFSIZE];
1166  *buf = '\0';
1167 
1168  /* Checks whether there is an SQLINE that already covers
1169  * the one we want to add, and whether there are SQLINEs
1170  * that would be covered by this one.
1171  * If so, warn the user in the first case and cleanup
1172  * the useless SQLINEs in the second.
1173  */
1174 
1175  if (!mask) {
1176  return -1;
1177  }
1178 
1179  if (sqlines.count > 0) {
1180 
1181  for (i = sqlines.count - 1; i >= 0; i--) {
1182  entry = sqlines.list[i];
1183 
1184  if (!entry)
1185  continue;
1186 
1187  if ((*mask == '#' && *entry->mask != '#') ||
1188  (*mask != '#' && *entry->mask == '#'))
1189  continue;
1190 
1191  if (!stricmp(entry->mask, mask)) {
1192  if (entry->expires >= expires || entry->expires == 0) {
1193  if (u)
1194  notice_lang(s_OperServ, u, OPER_SQLINE_EXISTS,
1195  mask);
1196  return -1;
1197  } else {
1198  entry->expires = expires;
1199  if (u)
1200  notice_lang(s_OperServ, u, OPER_SQLINE_CHANGED,
1201  entry->mask);
1202  return -2;
1203  }
1204  }
1205 
1206  if (match_wild_nocase(entry->mask, mask)
1207  && (entry->expires >= expires || entry->expires == 0)) {
1208  if (u)
1209  notice_lang(s_OperServ, u, OPER_SQLINE_ALREADY_COVERED,
1210  mask, entry->mask);
1211  return -1;
1212  }
1213 
1214  if (match_wild_nocase(mask, entry->mask)
1215  && (entry->expires <= expires || expires == 0)) {
1216  slist_delete(&sqlines, i);
1217  deleted++;
1218  }
1219  }
1220 
1221  }
1222 
1223  /* We can now check whether the list is full or not. */
1224  if (slist_full(&sqlines)) {
1225  if (u)
1226  notice_lang(s_OperServ, u, OPER_SQLINE_REACHED_LIMIT,
1227  sqlines.limit);
1228  return -1;
1229  }
1230 
1231  /* We can now (really) add the SQLINE. */
1232  entry = scalloc(sizeof(SXLine), 1);
1233  if (!entry)
1234  return -1;
1235 
1236  entry->mask = sstrdup(mask);
1237  entry->by = sstrdup(by);
1238  entry->reason = sstrdup(reason);
1239  entry->seton = time(NULL);
1240  entry->expires = expires;
1241 
1242  slist_add(&sqlines, entry);
1243 
1244  sqline(entry->mask, entry->reason);
1245 
1246  if (KillonSQline) {
1247  snprintf(buf, (BUFSIZE - 1), "Q-Lined: %s", entry->reason);
1248  u2 = firstuser();
1249  while (u2) {
1250  next = nextuser();
1251  if (!is_oper(u2)) {
1252  if (match_wild_nocase(entry->mask, u2->nick)) {
1253  kill_user(ServerName, u2->nick, buf);
1254  }
1255  }
1256  u2 = next;
1257  }
1258  }
1259 
1260  return deleted;
1261 }
1262 
1263 /* Does the user match any SQLINEs? */
1264 
1265 int check_sqline(char *nick, int nick_change)
1266 {
1267  int i;
1268  SXLine *sx;
1269  char reason[300];
1270 
1271  if (sqlines.count == 0)
1272  return 0;
1273 
1274  for (i = 0; i < sqlines.count; i++) {
1275  sx = sqlines.list[i];
1276  if (!sx)
1277  continue;
1278 
1279  if (ircd->chansqline) {
1280  if (*sx->mask == '#')
1281  continue;
1282  }
1283 
1284  if (match_wild_nocase(sx->mask, nick)) {
1285  sqline(sx->mask, sx->reason);
1286  /* We kill nick since s_sqline can't */
1287  snprintf(reason, sizeof(reason), "Q-Lined: %s", sx->reason);
1288  kill_user(s_OperServ, nick, reason);
1289  return 1;
1290  }
1291  }
1292 
1293  return 0;
1294 }
1295 
1296 int check_chan_sqline(const char *chan)
1297 {
1298  int i;
1299  SXLine *sx;
1300 
1301  if (sqlines.count == 0)
1302  return 0;
1303 
1304  for (i = 0; i < sqlines.count; i++) {
1305  sx = sqlines.list[i];
1306  if (!sx)
1307  continue;
1308 
1309  if (*sx->mask != '#')
1310  continue;
1311 
1312  if (match_wild_nocase(sx->mask, chan)) {
1313  sqline(sx->mask, sx->reason);
1314  return 1;
1315  }
1316  }
1317 
1318  return 0;
1319 }
1320 
1321 /* Delete any expired SQLINEs. */
1322 
1323 void expire_sqlines(void)
1324 {
1325  int i;
1326  time_t now = time(NULL);
1327  SXLine *sx;
1328 
1329  for (i = sqlines.count - 1; i >= 0; i--) {
1330  sx = sqlines.list[i];
1331 
1332  if (!sx->expires || sx->expires > now)
1333  continue;
1334 
1335  if (WallSQLineExpire)
1336  anope_cmd_global(s_OperServ, "SQLINE on \2%s\2 has expired",
1337  sx->mask);
1338 
1339  slist_delete(&sqlines, i);
1340  }
1341 }
1342 
1343 static void free_sqline_entry(SList * slist, void *item)
1344 {
1345  SXLine *sx = item;
1346 
1347  /* Remove the SQLINE from all the servers */
1348  anope_cmd_unsqline(sx->mask);
1349 
1350  /* Free the structure */
1351  free(sx->mask);
1352  free(sx->by);
1353  free(sx->reason);
1354  free(sx);
1355 }
1356 
1357 /* item1 is not an SXLine pointer, but a char */
1358 
1359 static int is_sqline_entry_equal(SList * slist, void *item1, void *item2)
1360 {
1361  char *sx1 = item1;
1362  SXLine *sx2 = item2;
1363 
1364  if (!sx1 || !sx2)
1365  return 0;
1366 
1367  if (!stricmp(sx1, sx2->mask))
1368  return 1;
1369  else
1370  return 0;
1371 }
1372 
1373 /*************************************************************************/
1374 
1375 /* Adds an SZLINE to the list. Returns >= 0 on success, -1 on error, -2 if
1376  * only the expiry time changed.
1377  * The success result is the number of SZLINEs that were deleted to successfully add one.
1378  */
1379 
1380 int add_szline(User * u, char *mask, const char *by, const time_t expires,
1381  const char *reason)
1382 {
1383  int deleted = 0, i;
1384  SXLine *entry;
1385 
1386  if (!mask) {
1387  return -1;
1388  }
1389 
1390  /* Checks whether there is an SZLINE that already covers
1391  * the one we want to add, and whether there are SZLINEs
1392  * that would be covered by this one.
1393  * If so, warn the user in the first case and cleanup
1394  * the useless SZLINEs in the second.
1395  */
1396 
1397  if (szlines.count > 0) {
1398 
1399  for (i = szlines.count - 1; i >= 0; i--) {
1400  entry = szlines.list[i];
1401 
1402  if (!entry)
1403  continue;
1404 
1405  if (!stricmp(entry->mask, mask)) {
1406  if (entry->expires >= expires || entry->expires == 0) {
1407  if (u)
1408  notice_lang(s_OperServ, u, OPER_SZLINE_EXISTS,
1409  mask);
1410  return -1;
1411  } else {
1412  entry->expires = expires;
1413  if (u)
1414  notice_lang(s_OperServ, u, OPER_SZLINE_EXISTS,
1415  mask);
1416  return -2;
1417  }
1418  }
1419 
1420  if (match_wild_nocase(entry->mask, mask)) {
1421  if (u)
1422  notice_lang(s_OperServ, u, OPER_SZLINE_ALREADY_COVERED,
1423  mask, entry->mask);
1424  return -1;
1425  }
1426 
1427  if (match_wild_nocase(mask, entry->mask)) {
1428  slist_delete(&szlines, i);
1429  deleted++;
1430  }
1431  }
1432 
1433  }
1434 
1435  /* We can now check whether the list is full or not. */
1436  if (slist_full(&szlines)) {
1437  if (u)
1438  notice_lang(s_OperServ, u, OPER_SZLINE_REACHED_LIMIT,
1439  szlines.limit);
1440  return -1;
1441  }
1442 
1443  /* We can now (really) add the SZLINE. */
1444  entry = scalloc(sizeof(SXLine), 1);
1445  if (!entry)
1446  return -1;
1447 
1448  entry->mask = sstrdup(mask);
1449  entry->by = sstrdup(by);
1450  entry->reason = sstrdup(reason);
1451  entry->seton = time(NULL);
1452  entry->expires = expires;
1453 
1454  slist_add(&szlines, entry);
1455  anope_cmd_szline(entry->mask, entry->reason, entry->by);
1456 
1457  return deleted;
1458 }
1459 
1460 /* Check and enforce any Zlines that we have */
1461 int check_szline(char *nick, char *ip)
1462 {
1463  int i;
1464  SXLine *sx;
1465  time_t now = time(NULL);
1466 
1467  if (szlines.count == 0) {
1468  return 0;
1469  }
1470 
1471  if (!ip) {
1472  return 0;
1473  }
1474 
1475  for (i = 0; i < szlines.count; i++) {
1476  sx = szlines.list[i];
1477  if (!sx) {
1478  continue;
1479  }
1480 
1481  if (match_wild_nocase(sx->mask, ip)) {
1482  if (!sx->expires || sx->expires > now) {
1483  anope_cmd_szline(sx->mask, sx->reason, sx->by);
1484  return 1;
1485  }
1486  }
1487  }
1488 
1489  return 0;
1490 }
1491 
1492 
1493 /* Delete any expired SZLINEs. */
1494 
1495 void expire_szlines(void)
1496 {
1497  int i;
1498  time_t now = time(NULL);
1499  SXLine *sx;
1500 
1501  for (i = szlines.count - 1; i >= 0; i--) {
1502  sx = szlines.list[i];
1503 
1504  if (!sx->expires || sx->expires > now)
1505  continue;
1506 
1507  if (WallSZLineExpire)
1508  anope_cmd_global(s_OperServ, "SZLINE on \2%s\2 has expired",
1509  sx->mask);
1510  slist_delete(&szlines, i);
1511  }
1512 }
1513 
1514 static void free_szline_entry(SList * slist, void *item)
1515 {
1516  SXLine *sx = item;
1517 
1518  /* Remove the SZLINE from all the servers */
1519  anope_cmd_unszline(sx->mask);
1520 
1521  /* Free the structure */
1522  free(sx->mask);
1523  free(sx->by);
1524  free(sx->reason);
1525  free(sx);
1526 }
1527 
1528 /* item1 is not an SXLine pointer, but a char
1529  */
1530 
1531 static int is_szline_entry_equal(SList * slist, void *item1, void *item2)
1532 {
1533  char *sx1 = item1;
1534  SXLine *sx2 = item2;
1535 
1536  if (!sx1 || !sx2)
1537  return 0;
1538 
1539  if (!stricmp(sx1, sx2->mask))
1540  return 1;
1541  else
1542  return 0;
1543 }
1544 
1545 /*************************************************************************/
1546 
1547 /* Callback function used to sort the admin list */
1548 
1549 static int compare_adminlist_entries(SList * slist, void *item1,
1550  void *item2)
1551 {
1552  NickCore *nc1 = item1, *nc2 = item2;
1553  if (!nc1 || !nc2)
1554  return -1; /* To tell to continue */
1555  return stricmp(nc1->display, nc2->display);
1556 }
1557 
1558 /* Callback function used when an admin list entry is deleted */
1559 
1560 static void free_adminlist_entry(SList * slist, void *item)
1561 {
1562  NickCore *nc = item;
1563  nc->flags &= ~NI_SERVICES_ADMIN;
1564 }
1565 
1566 /*************************************************************************/
1567 
1568 /* Callback function used to sort the oper list */
1569 
1570 static int compare_operlist_entries(SList * slist, void *item1,
1571  void *item2)
1572 {
1573  NickCore *nc1 = item1, *nc2 = item2;
1574  if (!nc1 || !nc2)
1575  return -1; /* To tell to continue */
1576  return stricmp(nc1->display, nc2->display);
1577 }
1578 
1579 /* Callback function used when an oper list entry is deleted */
1580 
1581 static void free_operlist_entry(SList * slist, void *item)
1582 {
1583  NickCore *nc = item;
1584  nc->flags &= ~NI_SERVICES_OPER;
1585 }
1586 
1587 /*************************************************************************/
1588 
1589 #ifdef DEBUG_COMMANDS
1590 
1591 static int do_matchwild(User * u)
1592 {
1593  char *pat = strtok(NULL, " ");
1594  char *str = strtok(NULL, " ");
1595  if (pat && str)
1596  notice_user(s_OperServ, u, "%d", match_wild(pat, str));
1597  else
1598  notice_user(s_OperServ, u, "Syntax error.");
1599  return MOD_CONT;
1600 }
1601 
1602 #endif /* DEBUG_COMMANDS */
1603 
1604 /*************************************************************************/
1608 int checkDefCon(int level)
1609 {
1610  return DefCon[DefConLevel] & level;
1611 }
1612 
1616 void resetDefCon(int level)
1617 {
1618  char strLevel[5];
1619  snprintf(strLevel, 4, "%d", level);
1620  if (DefConLevel != level) {
1621  if ((DefContimer)
1622  && (time(NULL) - DefContimer >= dotime(DefConTimeOut))) {
1623  DefConLevel = level;
1624  send_event(EVENT_DEFCON_LEVEL, 1, strLevel);
1625  alog("Defcon level timeout, returning to lvl %d", level);
1627  getstring2(NULL, OPER_DEFCON_WALL),
1628  s_OperServ, level);
1629  if (GlobalOnDefcon) {
1630  if (DefConOffMessage) {
1631  oper_global(NULL, "%s", DefConOffMessage);
1632  } else {
1633  oper_global(NULL, getstring(NULL, DEFCON_GLOBAL),
1634  DefConLevel);
1635  }
1636  }
1638  oper_global(NULL, "%s", DefconMessage);
1639  }
1640  runDefCon();
1641  }
1642  }
1643 }
1644 
1648 void runDefCon(void)
1649 {
1650  char *newmodes;
1652  if (DefConChanModes && !DefConModesSet) {
1653  if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-') {
1654  alog("DEFCON: setting %s on all channels", DefConChanModes);
1655  DefConModesSet = 1;
1657  }
1658  }
1659  } else {
1660  if (DefConChanModes && (DefConModesSet != 0)) {
1661  if (DefConChanModes[0] == '+' || DefConChanModes[0] == '-') {
1662  DefConModesSet = 0;
1663  if ((newmodes = defconReverseModes(DefConChanModes))) {
1664  alog("DEFCON: setting %s on all channels", newmodes);
1665  do_mass_mode(newmodes);
1666  free(newmodes);
1667  }
1668  }
1669  }
1670  }
1671 }
1672 
1676 char *defconReverseModes(const char *modes)
1677 {
1678  char *newmodes = NULL;
1679  int i = 0;
1680  if (!modes) {
1681  return NULL;
1682  }
1683  if (!(newmodes = malloc(sizeof(char) * strlen(modes) + 1))) {
1684  return NULL;
1685  }
1686  for (i = 0; i < strlen(modes); i++) {
1687  if (modes[i] == '+')
1688  newmodes[i] = '-';
1689  else if (modes[i] == '-')
1690  newmodes[i] = '+';
1691  else
1692  newmodes[i] = modes[i];
1693  }
1694  newmodes[i] = '\0';
1695  return newmodes;
1696 }
1697 
1698 /* Parse the defcon mlock mode string and set the correct global vars.
1699  *
1700  * @param str mode string to parse
1701  * @return 1 if accepted, 0 if failed
1702  */
1703 int defconParseModeString(const char *str)
1704 {
1705  int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
1706  unsigned char mode;
1707  CBMode *cbm;
1708  char *str_copy = sstrdup(str); /* We need this copy as str is const -GD */
1709  char *param; /* Store parameters during mode parsing */
1710 
1711  /* Reinitialize everything */
1712  DefConModesOn = 0;
1713  DefConModesOff = 0;
1714  DefConModesCI.mlock_limit = 0;
1715  DefConModesCI.mlock_key = NULL;
1716  DefConModesCI.mlock_flood = NULL;
1717  DefConModesCI.mlock_redirect = NULL;
1718 
1719  /* Initialize strtok() internal buffer */
1720  strtok(str_copy, " ");
1721 
1722  /* Loop while there are modes to set */
1723  while ((mode = *str++) && (mode != ' ')) {
1724  switch (mode) {
1725  case '+':
1726  add = 1;
1727  continue;
1728  case '-':
1729  add = 0;
1730  continue;
1731  default:
1732  if (add < 0)
1733  continue;
1734  }
1735 
1736  if ((int) mode < 128 && (cbm = &cbmodes[(int) mode])->flag != 0) {
1737  if (cbm->flags & CBM_NO_MLOCK) {
1738  alog("DefConChanModes mode character '%c' cannot be locked", mode);
1739  free(str_copy);
1740  return 0;
1741  } else if (add) {
1742  DefConModesOn |= cbm->flag;
1743  DefConModesOff &= ~cbm->flag;
1744  if (cbm->cssetvalue) {
1745  if (!(param = strtok(NULL, " "))) {
1746  alog("DefConChanModes mode character '%c' has no parameter while one is expected", mode);
1747  free(str_copy);
1748  return 0;
1749  }
1750  cbm->cssetvalue(&DefConModesCI, param);
1751  }
1752  } else {
1753  DefConModesOff |= cbm->flag;
1754  if (DefConModesOn & cbm->flag) {
1755  DefConModesOn &= ~cbm->flag;
1756  if (cbm->cssetvalue) {
1757  cbm->cssetvalue(&DefConModesCI, NULL);
1758  }
1759  }
1760  }
1761  } else {
1762  alog("DefConChanModes unknown mode character '%c'", mode);
1763  free(str_copy);
1764  return 0;
1765  }
1766  } /* while (*param) */
1767 
1768  free(str_copy);
1769 
1770  if (ircd->Lmode) {
1771  /* We can't mlock +L if +l is not mlocked as well. */
1772  if ((DefConModesOn & ircd->chan_lmode)
1773  && !(DefConModesOn & anope_get_limit_mode())) {
1775  free(DefConModesCI.mlock_redirect);
1776  DefConModesCI.mlock_redirect = NULL;
1777  alog("DefConChanModes must lock mode +l as well to lock mode +L");
1778  return 0;
1779  }
1780  }
1781 
1782  /* Some ircd we can't set NOKNOCK without INVITE */
1783  /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */
1784  if (ircd->noknock && ircd->knock_needs_i) {
1785  if ((DefConModesOn & ircd->noknock)
1787  DefConModesOn &= ~ircd->noknock;
1788  alog("DefConChanModes must lock mode +i as well to lock mode +K");
1789  return 0;
1790  }
1791  }
1792 
1793  /* Everything is set fine, return 1 */
1794  return 1;
1795 }
1796 
1797 /*************************************************************************/
E int is_oper(User *user)
Definition: users.c:937
E void E void E void notice_server(char *source, Server *s, char *fmt,...) FORMAT(printf
E time_t maxusertime
Definition: extern.h:1142
E CBMode cbmodes[128]
Definition: extern.h:47
E User * nextuser(void)
Definition: users.c:364
void(* cssetvalue)(ChannelInfo *ci, char *value)
Definition: services.h:925
#define NI_SERVICES_ROOT
Definition: services.h:1305
E char * DefConTimeOut
Definition: extern.h:566
#define SAFE(x)
Definition: operserv.c:420
int defconParseModeString(const char *str)
Definition: operserv.c:1703
int nickip
Definition: services.h:340
E int match_wild_nocase(const char *pattern, const char *str)
Definition: misc.c:268
static void free_operlist_entry(SList *slist, void *item)
Definition: operserv.c:1581
SListOpts saopts
Definition: operserv.c:66
char nick[NICKMAX]
Definition: services.h:875
E int snprintf(char *buf, size_t size, const char *fmt,...)
Definition: compat.c:37
int check_sqline(char *nick, int nick_change)
Definition: operserv.c:1265
E int WallSQLineExpire
Definition: extern.h:463
void save_os_rdb_dbase(void)
Definition: operserv.c:499
E NickAlias * findnick(const char *nick)
Definition: db-merger.c:1857
ChannelInfo DefConModesCI
Definition: operserv.c:50
uint32 flag
Definition: services.h:920
E int WallSGLineExpire
Definition: extern.h:462
E int OperServCoreNumber
Definition: extern.h:495
E void anope_cmd_szline(char *mask, char *reason, char *whom)
Definition: ircd.c:584
int Lmode
Definition: services.h:350
SListOpts akopts
Definition: operserv.c:65
time_t expires
Definition: services.h:1099
#define DEFCON_FORCE_CHAN_MODES
Definition: services.h:1257
char * by
Definition: services.h:1096
char * defconReverseModes(const char *modes)
Definition: operserv.c:1676
static int is_akill_entry_equal(SList *slist, void *item1, void *item2)
Definition: operserv.c:949
static int compare_operlist_entries(SList *slist, void *item1, void *item2)
Definition: operserv.c:1570
E IRCDVar * ircd
Definition: extern.h:39
E uint32 maxusercnt
Definition: extern.h:1141
char * mask
Definition: services.h:1095
SList szlines
Definition: operserv.c:24
E int WallSZLineExpire
Definition: extern.h:464
char * mlock_redirect
Definition: services.h:685
void load_os_dbase(void)
Definition: operserv.c:276
int check_szline(char *nick, char *ip)
Definition: operserv.c:1461
E int nick_identified(User *u)
Definition: nickserv.c:1111
int sglineenforce
Definition: services.h:364
char * host
Definition: services.h:1081
E void send_event(const char *name, int argc,...)
Definition: events.c:37
char * mlock_flood
Definition: services.h:684
#define CBM_NO_MLOCK
Definition: services.h:929
E int slist_setcapacity(SList *slist, int16 capacity)
Definition: slist.c:379
Server * server_global(Server *s, char *msg)
Definition: operserv.c:668
E int dotime(const char *s)
Definition: misc.c:364
void expire_szlines(void)
Definition: operserv.c:1495
int vhost
Definition: services.h:301
SList sglines
Definition: operserv.c:24
E char * OperDBName
Definition: extern.h:336
E int stricmp(const char *s1, const char *s2)
Definition: compat.c:58
E void E void E void E void notice_user(char *source, User *u, const char *fmt,...) FORMAT(printf
SListOpts soopts
Definition: operserv.c:71
int nick_is_services_oper(NickCore *nc)
Definition: operserv.c:649
#define read_buffer(buf, f)
Definition: datafiles.h:61
E void modules_core_init(int number, char **list)
Definition: modules.c:127
SList servadmins
Definition: operserv.c:20
time_t expires
Definition: services.h:1087
E int KillonSGline
Definition: extern.h:445
E int slist_full(SList *slist)
Definition: slist.c:287
char * reason
Definition: services.h:1084
uint16 flags
Definition: services.h:921
void moduleAddOperServCmds(void)
Definition: operserv.c:79
#define getstring(na, index)
Definition: extern.h:731
static int is_sgline_entry_equal(SList *slist, void *item1, void *item2)
Definition: operserv.c:1138
time_t DefContimer
Definition: operserv.c:44
E int DefConLevel
Definition: extern.h:561
#define getstring2(nc, index)
Definition: extern.h:733
int nick_is_services_admin(NickCore *nc)
Definition: operserv.c:636
E void anope_cmd_akill(char *user, char *host, char *who, time_t when, time_t expires, char *reason)
Definition: ircd.c:156
int szline
Definition: services.h:315
int rdb_save_os_db(unsigned int maxucnt, unsigned int maxutime, SList *ak, SList *sgl, SList *sql, SList *szl)
Definition: rdb.c:325
E int anope_get_limit_mode()
Definition: ircd.c:1241
SList sqlines
Definition: operserv.c:24
static int compare_adminlist_entries(SList *slist, void *item1, void *item2)
Definition: operserv.c:1549
SListOpts * opts
Definition: slist.h:27
static void free_sqline_entry(SList *slist, void *item)
Definition: operserv.c:1343
Server * links
Definition: services.h:861
int add_sqline(User *u, char *mask, const char *by, const time_t expires, const char *reason)
Definition: operserv.c:1159
void runDefCon(void)
Definition: operserv.c:1648
E char * DefConChanModes
Definition: extern.h:568
SListOpts sqopts
Definition: operserv.c:73
int DefConModesSet
Definition: operserv.c:45
E void notice_lang(char *source, User *dest, int message,...)
Definition: send.c:169
char * user
Definition: services.h:1080
static void free_sgline_entry(SList *slist, void *item)
Definition: operserv.c:1122
E int read_int16(uint16 *ret, dbFILE *f)
Definition: datafiles.c:405
E void kill_user(char *source, char *user, char *reason)
Definition: actions.c:51
E char * sstrdup(const char *s)
Definition: memory.c:105
NickCore * nc
Definition: services.h:533
void expire_sqlines(void)
Definition: operserv.c:1323
int rdb_close()
Definition: rdb.c:47
E void * scalloc(long elsize, long els)
Definition: memory.c:55
char * display
Definition: services.h:542
static void free_akill_entry(SList *slist, void *item)
Definition: operserv.c:931
#define OPERSERV
Definition: modules.h:62
E char * DefconMessage
Definition: extern.h:571
int knock_needs_i
Definition: services.h:354
void ** list
Definition: slist.h:21
E char * s_OperServ
Definition: extern.h:289
Server * next
Definition: services.h:852
time_t seton
Definition: services.h:1098
E int slist_delete(SList *slist, int index)
Definition: slist.c:97
static void free_szline_entry(SList *slist, void *item)
Definition: operserv.c:1514
int16 limit
Definition: slist.h:25
E int read_string(char **ret, dbFILE *f)
Definition: db-merger.c:1806
int16 count
Definition: slist.h:23
E int get_file_version(dbFILE *f)
Definition: datafiles.c:30
E int write_int16(uint16 val, dbFILE *f)
Definition: db-merger.c:1737
E void anope_cmd_svskill(char *source, char *user, const char *fmt,...)
Definition: ircd.c:162
uint32 noknock
Definition: services.h:345
SListOpts sgopts
Definition: operserv.c:70
E void close_db(dbFILE *f)
Definition: db-merger.c:1706
#define DEFCON_NO_NEW_CLIENTS
Definition: services.h:1259
void os_remove_nick(NickCore *nc)
Definition: operserv.c:566
E void anope_cmd_remove_akill(char *user, char *host)
Definition: ircd.c:140
E void sqline(char *mask, char *reason)
Definition: actions.c:82
int chansqline
Definition: services.h:325
Command * c
Definition: ns_recover.c:17
uint16 flags
Definition: services.h:857
char * by
Definition: services.h:1083
void operserv(User *u, char *buf)
Definition: operserv.c:129
u_int32_t uint32
Definition: db-merger.c:123
int checkDefCon(int level)
Definition: operserv.c:1608
E void anope_cmd_sgline(char *mask, char *reason)
Definition: ircd.c:589
E dbFILE * open_db(const char *service, const char *filename, const char *mode, uint32 version)
Definition: datafiles.c:295
void resetDefCon(int level)
Definition: operserv.c:1616
E int slist_indexof(SList *slist, void *item)
Definition: slist.c:317
E void alog(const char *fmt,...) FORMAT(printf
int sqline
Definition: services.h:314
#define EVENT_DEFCON_LEVEL
Definition: events.h:58
static void load_old_akill(void)
Definition: operserv.c:163
E void anope_cmd_unsqline(char *user)
Definition: ircd.c:357
#define MOD_CONT
Definition: modules.h:54
E char ** OperServCoreModules
Definition: extern.h:494
E int AnonymousGlobal
Definition: extern.h:431
uint32 mlock_limit
Definition: services.h:682
int16_t int16
Definition: db-merger.c:120
E User * firstuser(void)
Definition: users.c:352
SList servopers
Definition: operserv.c:22
int is_services_admin(User *u)
Definition: operserv.c:591
void save_os_dbase(void)
Definition: operserv.c:433
E int AkillOnAdd
Definition: extern.h:444
int is_services_oper(User *u)
Definition: operserv.c:606
int add_sgline(User *u, char *mask, const char *by, const time_t expires, const char *reason)
Definition: operserv.c:973
SListOpts szopts
Definition: operserv.c:75
void expire_sglines(void)
Definition: operserv.c:1103
static time_t lastwarn
Definition: datafiles.c:19
E int skeleton
Definition: extern.h:778
#define NI_SERVICES_OPER
Definition: services.h:1302
E void anope_cmd_unszline(char *mask)
Definition: ircd.c:579
E int KillonSQline
Definition: extern.h:446
E int NSStrictPrivileges
Definition: extern.h:395
static int is_sqline_entry_equal(SList *slist, void *item1, void *item2)
Definition: operserv.c:1359
int rdb_clean_table(char *table)
Definition: rdb.c:113
int add_akill(User *u, char *mask, const char *by, const time_t expires, const char *reason)
Definition: operserv.c:722
MDE int addCoreCommand(CommandHash *cmdTable[], Command *c)
Definition: modules.c:1063
Definition: slist.h:20
E int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
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 int GlobalOnDefcon
Definition: extern.h:569
E int WallAkillExpire
Definition: extern.h:461
#define NICKMAX
Definition: config.h:62
#define SERVER_JUPED
Definition: services.h:866
char * mlock_key
Definition: services.h:683
time_t seton
Definition: services.h:1086
static void free_adminlist_entry(SList *slist, void *item)
Definition: operserv.c:1560
int rdb_open()
Definition: rdb.c:31
E void anope_cmd_unsgline(char *mask)
Definition: ircd.c:574
E Server * servlist
Definition: extern.h:1051
E void slist_init(SList *slist)
Definition: slist.c:302
E char * AutokillDBName
Definition: extern.h:337
int rdb_empty_table(char *table)
Definition: rdb.c:100
uint32 flags
Definition: services.h:548
E char * DefConOffMessage
Definition: extern.h:573
uint32 DefConModesOn
Definition: operserv.c:48
int rdb_tag_table(char *table)
Definition: rdb.c:75
E char * ServerName
Definition: extern.h:274
#define NI_SERVICES_ADMIN
Definition: services.h:1303
void oper_global(char *nick, char *fmt,...)
Definition: operserv.c:691
int check_chan_sqline(const char *chan)
Definition: operserv.c:1296
E int slist_add(SList *slist, void *item)
Definition: slist.c:29
#define SERVER_ISME
Definition: services.h:865
E int match_wild(const char *pattern, const char *str)
Definition: misc.c:255
E int GlobalOnDefconMore
Definition: extern.h:570
int16 capacity
Definition: slist.h:24
void expire_akills(void)
Definition: operserv.c:912
E int read_int32(uint32 *ret, dbFILE *f)
Definition: datafiles.c:444
MDE void mod_run_cmd(char *service, User *u, CommandHash *cmdTable[], const char *cmd)
Definition: commands.c:67
SList akills
Definition: operserv.c:24
int sgline
Definition: services.h:313
int is_services_root(User *u)
Definition: operserv.c:577
E int write_string(const char *s, dbFILE *f)
Definition: db-merger.c:1826
#define OPER_VERSION
Definition: services.h:467
int add_szline(User *u, char *mask, const char *by, const time_t expires, const char *reason)
Definition: operserv.c:1380
E void anope_cmd_ctcp(char *source, char *dest, const char *fmt,...)
Definition: ircd.c:672
int check_sgline(char *nick, const char *realname)
Definition: operserv.c:1074
E int write_int32(uint32 val, dbFILE *f)
Definition: db-merger.c:1773
char * reason
Definition: services.h:1097
#define SLISTF_SORT
Definition: slist.h:41
E int slist_remove(SList *slist, void *item)
Definition: slist.c:362
E int DefCon[6]
Definition: extern.h:562
uint32 chan_lmode
Definition: services.h:352
uint32 DefConModesOff
Definition: operserv.c:49
static int is_szline_entry_equal(SList *slist, void *item1, void *item2)
Definition: operserv.c:1531
#define BUFSIZE
Definition: config.h:47
E int anope_get_invite_mode()
Definition: ircd.c:1221
void os_init(void)
Definition: operserv.c:98
E char * s_GlobalNoticer
Definition: extern.h:290
E char * DefConAkillReason
Definition: extern.h:572
char * realname
Definition: services.h:883
NickAlias * na
Definition: services.h:892
E void anope_cmd_global(char *source, const char *fmt,...)
Definition: ircd.c:506
E void do_mass_mode(char *modes)
Definition: channels.c:2044
int nick_is_services_root(NickCore *nc)
Definition: operserv.c:623
int check_akill(char *nick, const char *username, const char *host, const char *vhost, const char *ip)
Definition: operserv.c:847
u_int16_t uint16
Definition: db-merger.c:121