PageRenderTime 342ms CodeModel.GetById 101ms app.highlight 184ms RepoModel.GetById 37ms app.codeStats 1ms

/src/mod/channels.mod/tclchan.c

https://github.com/eggheads/eggdrop-1.8
C | 2379 lines | 2110 code | 197 blank | 72 comment | 771 complexity | c437212badc04d68b47227fb7974a2e3 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * tclchan.c -- part of channels.mod
   3 *
   4 * $Id: tclchan.c,v 1.4 2014/09/06 23:49:32 thommey Exp $
   5 */
   6/*
   7 * Copyright (C) 1997 Robey Pointer
   8 * Copyright (C) 1999 - 2010 Eggheads Development Team
   9 *
  10 * This program is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU General Public License
  12 * as published by the Free Software Foundation; either version 2
  13 * of the License, or (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  23 */
  24
  25static int tcl_killban STDVAR
  26{
  27  struct chanset_t *chan;
  28
  29  BADARGS(2, 2, " ban");
  30
  31  if (u_delban(NULL, argv[1], 1) > 0) {
  32    for (chan = chanset; chan; chan = chan->next)
  33      add_mode(chan, '-', 'b', argv[1]);
  34    Tcl_AppendResult(irp, "1", NULL);
  35  } else
  36    Tcl_AppendResult(irp, "0", NULL);
  37  return TCL_OK;
  38}
  39
  40static int tcl_killchanban STDVAR
  41{
  42  struct chanset_t *chan;
  43
  44  BADARGS(3, 3, " channel ban");
  45
  46  chan = findchan_by_dname(argv[1]);
  47  if (!chan) {
  48    Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
  49    return TCL_ERROR;
  50  }
  51  if (u_delban(chan, argv[2], 1) > 0) {
  52    add_mode(chan, '-', 'b', argv[2]);
  53    Tcl_AppendResult(irp, "1", NULL);
  54  } else
  55    Tcl_AppendResult(irp, "0", NULL);
  56  return TCL_OK;
  57}
  58
  59static int tcl_killexempt STDVAR
  60{
  61  struct chanset_t *chan;
  62
  63  BADARGS(2, 2, " exempt");
  64
  65  if (u_delexempt(NULL, argv[1], 1) > 0) {
  66    for (chan = chanset; chan; chan = chan->next)
  67      add_mode(chan, '-', 'e', argv[1]);
  68    Tcl_AppendResult(irp, "1", NULL);
  69  } else
  70    Tcl_AppendResult(irp, "0", NULL);
  71  return TCL_OK;
  72}
  73
  74static int tcl_killchanexempt STDVAR
  75{
  76  struct chanset_t *chan;
  77
  78  BADARGS(3, 3, " channel exempt");
  79
  80  chan = findchan_by_dname(argv[1]);
  81  if (!chan) {
  82    Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
  83    return TCL_ERROR;
  84  }
  85  if (u_delexempt(chan, argv[2], 1) > 0) {
  86    add_mode(chan, '-', 'e', argv[2]);
  87    Tcl_AppendResult(irp, "1", NULL);
  88  } else
  89    Tcl_AppendResult(irp, "0", NULL);
  90  return TCL_OK;
  91}
  92
  93static int tcl_killinvite STDVAR
  94{
  95  struct chanset_t *chan;
  96
  97  BADARGS(2, 2, " invite");
  98
  99  if (u_delinvite(NULL, argv[1], 1) > 0) {
 100    for (chan = chanset; chan; chan = chan->next)
 101      add_mode(chan, '-', 'I', argv[1]);
 102    Tcl_AppendResult(irp, "1", NULL);
 103  } else
 104    Tcl_AppendResult(irp, "0", NULL);
 105  return TCL_OK;
 106}
 107
 108static int tcl_killchaninvite STDVAR
 109{
 110  struct chanset_t *chan;
 111
 112  BADARGS(3, 3, " channel invite");
 113
 114  chan = findchan_by_dname(argv[1]);
 115  if (!chan) {
 116    Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
 117    return TCL_ERROR;
 118  }
 119  if (u_delinvite(chan, argv[2], 1) > 0) {
 120    add_mode(chan, '-', 'I', argv[2]);
 121    Tcl_AppendResult(irp, "1", NULL);
 122  } else
 123    Tcl_AppendResult(irp, "0", NULL);
 124  return TCL_OK;
 125}
 126
 127static int tcl_stick STDVAR
 128{
 129  struct chanset_t *chan;
 130  int ok = 0;
 131
 132  BADARGS(2, 3, " ban ?channel?");
 133
 134  if (argc == 3) {
 135    chan = findchan_by_dname(argv[2]);
 136    if (!chan) {
 137      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 138      return TCL_ERROR;
 139    }
 140    if (u_setsticky_ban(chan, argv[1], !strncmp(argv[0], "un", 2) ? 0 : 1))
 141      ok = 1;
 142  }
 143  if (!ok && u_setsticky_ban(NULL, argv[1], !strncmp(argv[0], "un", 2) ?
 144      0 : 1))
 145    ok = 1;
 146  if (ok)
 147    Tcl_AppendResult(irp, "1", NULL);
 148  else
 149    Tcl_AppendResult(irp, "0", NULL);
 150  return TCL_OK;
 151}
 152
 153static int tcl_stickinvite STDVAR
 154{
 155  struct chanset_t *chan;
 156  int ok = 0;
 157
 158  BADARGS(2, 3, " invite ?channel?");
 159
 160  if (argc == 3) {
 161    chan = findchan_by_dname(argv[2]);
 162    if (!chan) {
 163      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 164      return TCL_ERROR;
 165    }
 166    if (u_setsticky_invite(chan, argv[1], !strncmp(argv[0], "un", 2) ? 0 : 1))
 167      ok = 1;
 168  }
 169  if (!ok && u_setsticky_invite(NULL, argv[1], !strncmp(argv[0], "un", 2) ?
 170      0 : 1))
 171    ok = 1;
 172  if (ok)
 173    Tcl_AppendResult(irp, "1", NULL);
 174  else
 175    Tcl_AppendResult(irp, "0", NULL);
 176  return TCL_OK;
 177}
 178
 179static int tcl_stickexempt STDVAR
 180{
 181  struct chanset_t *chan;
 182  int ok = 0;
 183
 184  BADARGS(2, 3, " exempt ?channel?");
 185
 186  if (argc == 3) {
 187    chan = findchan_by_dname(argv[2]);
 188    if (!chan) {
 189      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 190      return TCL_ERROR;
 191    }
 192    if (u_setsticky_exempt(chan, argv[1], !strncmp(argv[0], "un", 2) ? 0 : 1))
 193      ok = 1;
 194  }
 195  if (!ok && u_setsticky_exempt(NULL, argv[1], !strncmp(argv[0], "un", 2) ?
 196      0 : 1))
 197    ok = 1;
 198  if (ok)
 199    Tcl_AppendResult(irp, "1", NULL);
 200  else
 201    Tcl_AppendResult(irp, "0", NULL);
 202  return TCL_OK;
 203}
 204
 205static int tcl_isban STDVAR
 206{
 207  struct chanset_t *chan;
 208  int ok = 0;
 209
 210  BADARGS(2, 3, " ban ?channel?");
 211
 212  if (argc == 3) {
 213    chan = findchan_by_dname(argv[2]);
 214    if (!chan) {
 215      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 216      return TCL_ERROR;
 217    }
 218    if (u_equals_mask(chan->bans, argv[1]))
 219      ok = 1;
 220  }
 221  if (u_equals_mask(global_bans, argv[1]))
 222    ok = 1;
 223  if (ok)
 224    Tcl_AppendResult(irp, "1", NULL);
 225  else
 226    Tcl_AppendResult(irp, "0", NULL);
 227  return TCL_OK;
 228}
 229
 230static int tcl_isexempt STDVAR
 231{
 232  struct chanset_t *chan;
 233  int ok = 0;
 234
 235  BADARGS(2, 3, " exempt ?channel?");
 236
 237  if (argc == 3) {
 238    chan = findchan_by_dname(argv[2]);
 239    if (!chan) {
 240      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 241      return TCL_ERROR;
 242    }
 243    if (u_equals_mask(chan->exempts, argv[1]))
 244      ok = 1;
 245  }
 246  if (u_equals_mask(global_exempts, argv[1]))
 247    ok = 1;
 248  if (ok)
 249    Tcl_AppendResult(irp, "1", NULL);
 250  else
 251    Tcl_AppendResult(irp, "0", NULL);
 252  return TCL_OK;
 253}
 254
 255static int tcl_isinvite STDVAR
 256{
 257  struct chanset_t *chan;
 258  int ok = 0;
 259
 260  BADARGS(2, 3, " invite ?channel?");
 261
 262  if (argc == 3) {
 263    chan = findchan_by_dname(argv[2]);
 264    if (!chan) {
 265      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 266      return TCL_ERROR;
 267    }
 268    if (u_equals_mask(chan->invites, argv[1]))
 269      ok = 1;
 270  }
 271  if (u_equals_mask(global_invites, argv[1]))
 272    ok = 1;
 273  if (ok)
 274    Tcl_AppendResult(irp, "1", NULL);
 275  else
 276    Tcl_AppendResult(irp, "0", NULL);
 277  return TCL_OK;
 278}
 279
 280
 281static int tcl_isbansticky STDVAR
 282{
 283  struct chanset_t *chan;
 284  int ok = 0;
 285
 286  BADARGS(2, 3, " ban ?channel?");
 287
 288  if (argc == 3) {
 289    chan = findchan_by_dname(argv[2]);
 290    if (!chan) {
 291      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 292      return TCL_ERROR;
 293    }
 294    if (u_sticky_mask(chan->bans, argv[1]))
 295      ok = 1;
 296  }
 297  if (u_sticky_mask(global_bans, argv[1]))
 298    ok = 1;
 299  if (ok)
 300    Tcl_AppendResult(irp, "1", NULL);
 301  else
 302    Tcl_AppendResult(irp, "0", NULL);
 303  return TCL_OK;
 304}
 305
 306static int tcl_isexemptsticky STDVAR
 307{
 308  struct chanset_t *chan;
 309  int ok = 0;
 310
 311  BADARGS(2, 3, " exempt ?channel?");
 312
 313  if (argc == 3) {
 314    chan = findchan_by_dname(argv[2]);
 315    if (!chan) {
 316      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 317      return TCL_ERROR;
 318    }
 319    if (u_sticky_mask(chan->exempts, argv[1]))
 320      ok = 1;
 321  }
 322  if (u_sticky_mask(global_exempts, argv[1]))
 323    ok = 1;
 324  if (ok)
 325    Tcl_AppendResult(irp, "1", NULL);
 326  else
 327    Tcl_AppendResult(irp, "0", NULL);
 328  return TCL_OK;
 329}
 330
 331static int tcl_isinvitesticky STDVAR
 332{
 333  struct chanset_t *chan;
 334  int ok = 0;
 335
 336  BADARGS(2, 3, " invite ?channel?");
 337
 338  if (argc == 3) {
 339    chan = findchan_by_dname(argv[2]);
 340    if (!chan) {
 341      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 342      return TCL_ERROR;
 343    }
 344    if (u_sticky_mask(chan->invites, argv[1]))
 345      ok = 1;
 346  }
 347  if (u_sticky_mask(global_invites, argv[1]))
 348    ok = 1;
 349  if (ok)
 350    Tcl_AppendResult(irp, "1", NULL);
 351  else
 352    Tcl_AppendResult(irp, "0", NULL);
 353  return TCL_OK;
 354}
 355
 356static int tcl_ispermban STDVAR
 357{
 358  struct chanset_t *chan;
 359  int ok = 0;
 360
 361  BADARGS(2, 3, " ban ?channel?");
 362
 363  if (argc == 3) {
 364    chan = findchan_by_dname(argv[2]);
 365    if (chan == NULL) {
 366      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 367      return TCL_ERROR;
 368    }
 369    if (u_equals_mask(chan->bans, argv[1]) == 2)
 370      ok = 1;
 371  }
 372  if (u_equals_mask(global_bans, argv[1]) == 2)
 373    ok = 1;
 374  if (ok)
 375    Tcl_AppendResult(irp, "1", NULL);
 376  else
 377    Tcl_AppendResult(irp, "0", NULL);
 378  return TCL_OK;
 379}
 380
 381static int tcl_ispermexempt STDVAR
 382{
 383  struct chanset_t *chan;
 384  int ok = 0;
 385
 386  BADARGS(2, 3, " exempt ?channel?");
 387
 388  if (argc == 3) {
 389    chan = findchan_by_dname(argv[2]);
 390    if (chan == NULL) {
 391      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 392      return TCL_ERROR;
 393    }
 394    if (u_equals_mask(chan->exempts, argv[1]) == 2)
 395      ok = 1;
 396  }
 397  if (u_equals_mask(global_exempts, argv[1]) == 2)
 398    ok = 1;
 399  if (ok)
 400    Tcl_AppendResult(irp, "1", NULL);
 401  else
 402    Tcl_AppendResult(irp, "0", NULL);
 403  return TCL_OK;
 404}
 405
 406static int tcl_isperminvite STDVAR
 407{
 408  struct chanset_t *chan;
 409  int ok = 0;
 410
 411  BADARGS(2, 3, " invite ?channel?");
 412
 413  if (argc == 3) {
 414    chan = findchan_by_dname(argv[2]);
 415    if (chan == NULL) {
 416      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 417      return TCL_ERROR;
 418    }
 419    if (u_equals_mask(chan->invites, argv[1]) == 2)
 420      ok = 1;
 421  }
 422  if (u_equals_mask(global_invites, argv[1]) == 2)
 423    ok = 1;
 424  if (ok)
 425    Tcl_AppendResult(irp, "1", NULL);
 426  else
 427    Tcl_AppendResult(irp, "0", NULL);
 428  return TCL_OK;
 429}
 430
 431static int tcl_matchban STDVAR
 432{
 433  struct chanset_t *chan;
 434  int ok = 0;
 435
 436  BADARGS(2, 3, " user!nick@host ?channel?");
 437
 438  if (argc == 3) {
 439    chan = findchan_by_dname(argv[2]);
 440    if (chan == NULL) {
 441      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 442      return TCL_ERROR;
 443    }
 444    if (u_match_mask(chan->bans, argv[1]))
 445      ok = 1;
 446  }
 447  if (u_match_mask(global_bans, argv[1]))
 448    ok = 1;
 449  if (ok)
 450    Tcl_AppendResult(irp, "1", NULL);
 451  else
 452    Tcl_AppendResult(irp, "0", NULL);
 453  return TCL_OK;
 454}
 455
 456static int tcl_matchexempt STDVAR
 457{
 458  struct chanset_t *chan;
 459  int ok = 0;
 460
 461  BADARGS(2, 3, " user!nick@host ?channel?");
 462
 463  if (argc == 3) {
 464    chan = findchan_by_dname(argv[2]);
 465    if (chan == NULL) {
 466      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 467      return TCL_ERROR;
 468    }
 469    if (u_match_mask(chan->exempts, argv[1]))
 470      ok = 1;
 471  }
 472  if (u_match_mask(global_exempts, argv[1]))
 473    ok = 1;
 474  if (ok)
 475    Tcl_AppendResult(irp, "1", NULL);
 476  else
 477    Tcl_AppendResult(irp, "0", NULL);
 478  return TCL_OK;
 479}
 480
 481static int tcl_matchinvite STDVAR
 482{
 483  struct chanset_t *chan;
 484  int ok = 0;
 485
 486  BADARGS(2, 3, " user!nick@host ?channel?");
 487
 488  if (argc == 3) {
 489    chan = findchan_by_dname(argv[2]);
 490    if (chan == NULL) {
 491      Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
 492      return TCL_ERROR;
 493    }
 494    if (u_match_mask(chan->invites, argv[1]))
 495      ok = 1;
 496  }
 497  if (u_match_mask(global_invites, argv[1]))
 498    ok = 1;
 499  if (ok)
 500    Tcl_AppendResult(irp, "1", NULL);
 501  else
 502    Tcl_AppendResult(irp, "0", NULL);
 503  return TCL_OK;
 504}
 505
 506static int tcl_newchanban STDVAR
 507{
 508  time_t expire_time;
 509  struct chanset_t *chan;
 510  char ban[161], cmt[MASKREASON_LEN], from[HANDLEN + 1];
 511  int sticky = 0;
 512  module_entry *me;
 513
 514  BADARGS(5, 7, " channel ban creator comment ?lifetime? ?options?");
 515
 516  chan = findchan_by_dname(argv[1]);
 517  if (chan == NULL) {
 518    Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
 519    return TCL_ERROR;
 520  }
 521  if (argc == 7) {
 522    if (!egg_strcasecmp(argv[6], "none"));
 523    else if (!egg_strcasecmp(argv[6], "sticky"))
 524      sticky = 1;
 525    else {
 526      Tcl_AppendResult(irp, "invalid option ", argv[6], " (must be one of: ",
 527                       "sticky, none)", NULL);
 528      return TCL_ERROR;
 529    }
 530  }
 531  strncpyz(ban, argv[2], sizeof ban);
 532  strncpyz(from, argv[3], sizeof from);
 533  strncpyz(cmt, argv[4], sizeof cmt);
 534  if (argc == 5) {
 535    if (chan->ban_time == 0)
 536      expire_time = 0L;
 537    else
 538      expire_time = now + (60 * chan->ban_time);
 539  } else {
 540    if (atoi(argv[5]) == 0)
 541      expire_time = 0L;
 542    else
 543      expire_time = now + (atoi(argv[5]) * 60);
 544  }
 545  if (u_addban(chan, ban, from, cmt, expire_time, sticky))
 546    if ((me = module_find("irc", 0, 0)))
 547      (me->funcs[IRC_CHECK_THIS_BAN]) (chan, ban, sticky);
 548  return TCL_OK;
 549}
 550
 551static int tcl_newban STDVAR
 552{
 553  time_t expire_time;
 554  struct chanset_t *chan;
 555  char ban[UHOSTLEN], cmt[MASKREASON_LEN], from[HANDLEN + 1];
 556  int sticky = 0;
 557  module_entry *me;
 558
 559  BADARGS(4, 6, " ban creator comment ?lifetime? ?options?");
 560
 561  if (argc == 6) {
 562    if (!egg_strcasecmp(argv[5], "none"));
 563    else if (!egg_strcasecmp(argv[5], "sticky"))
 564      sticky = 1;
 565    else {
 566      Tcl_AppendResult(irp, "invalid option ", argv[5], " (must be one of: ",
 567                       "sticky, none)", NULL);
 568      return TCL_ERROR;
 569    }
 570  }
 571  strncpyz(ban, argv[1], sizeof ban);
 572  strncpyz(from, argv[2], sizeof from);
 573  strncpyz(cmt, argv[3], sizeof cmt);
 574  if (argc == 4) {
 575    if (global_ban_time == 0)
 576      expire_time = 0L;
 577    else
 578      expire_time = now + (60 * global_ban_time);
 579  } else {
 580    if (atoi(argv[4]) == 0)
 581      expire_time = 0L;
 582    else
 583      expire_time = now + (atoi(argv[4]) * 60);
 584  }
 585  if (u_addban(NULL, ban, from, cmt, expire_time, sticky))
 586    if ((me = module_find("irc", 0, 0)))
 587      for (chan = chanset; chan != NULL; chan = chan->next)
 588        (me->funcs[IRC_CHECK_THIS_BAN]) (chan, ban, sticky);
 589  return TCL_OK;
 590}
 591
 592static int tcl_newchanexempt STDVAR
 593{
 594  time_t expire_time;
 595  struct chanset_t *chan;
 596  char exempt[161], cmt[MASKREASON_LEN], from[HANDLEN + 1];
 597  int sticky = 0;
 598
 599  BADARGS(5, 7, " channel exempt creator comment ?lifetime? ?options?");
 600
 601  chan = findchan_by_dname(argv[1]);
 602  if (chan == NULL) {
 603    Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
 604    return TCL_ERROR;
 605  }
 606  if (argc == 7) {
 607    if (!egg_strcasecmp(argv[6], "none"));
 608    else if (!egg_strcasecmp(argv[6], "sticky"))
 609      sticky = 1;
 610    else {
 611      Tcl_AppendResult(irp, "invalid option ", argv[6], " (must be one of: ",
 612                       "sticky, none)", NULL);
 613      return TCL_ERROR;
 614    }
 615  }
 616  strncpyz(exempt, argv[2], sizeof exempt);
 617  strncpyz(from, argv[3], sizeof from);
 618  strncpyz(cmt, argv[4], sizeof cmt);
 619  if (argc == 5) {
 620    if (chan->exempt_time == 0)
 621      expire_time = 0L;
 622    else
 623      expire_time = now + (60 * chan->exempt_time);
 624  } else {
 625    if (atoi(argv[5]) == 0)
 626      expire_time = 0L;
 627    else
 628      expire_time = now + (atoi(argv[5]) * 60);
 629  }
 630  if (u_addexempt(chan, exempt, from, cmt, expire_time, sticky))
 631    add_mode(chan, '+', 'e', exempt);
 632  return TCL_OK;
 633}
 634
 635static int tcl_newexempt STDVAR
 636{
 637  time_t expire_time;
 638  struct chanset_t *chan;
 639  char exempt[UHOSTLEN], cmt[MASKREASON_LEN], from[HANDLEN + 1];
 640  int sticky = 0;
 641
 642  BADARGS(4, 6, " exempt creator comment ?lifetime? ?options?");
 643
 644  if (argc == 6) {
 645    if (!egg_strcasecmp(argv[5], "none"));
 646    else if (!egg_strcasecmp(argv[5], "sticky"))
 647      sticky = 1;
 648    else {
 649      Tcl_AppendResult(irp, "invalid option ", argv[5], " (must be one of: ",
 650                       "sticky, none)", NULL);
 651      return TCL_ERROR;
 652    }
 653  }
 654  strncpyz(exempt, argv[1], sizeof exempt);
 655  strncpyz(from, argv[2], sizeof from);
 656  strncpyz(cmt, argv[3], sizeof cmt);
 657  if (argc == 4) {
 658    if (global_exempt_time == 0)
 659      expire_time = 0L;
 660    else
 661      expire_time = now + (60 * global_exempt_time);
 662  } else {
 663    if (atoi(argv[4]) == 0)
 664      expire_time = 0L;
 665    else
 666      expire_time = now + (atoi(argv[4]) * 60);
 667  }
 668  u_addexempt(NULL, exempt, from, cmt, expire_time, sticky);
 669  for (chan = chanset; chan; chan = chan->next)
 670    add_mode(chan, '+', 'e', exempt);
 671  return TCL_OK;
 672}
 673
 674static int tcl_newchaninvite STDVAR
 675{
 676  time_t expire_time;
 677  struct chanset_t *chan;
 678  char invite[161], cmt[MASKREASON_LEN], from[HANDLEN + 1];
 679  int sticky = 0;
 680
 681  BADARGS(5, 7, " channel invite creator comment ?lifetime? ?options?");
 682
 683  chan = findchan_by_dname(argv[1]);
 684  if (chan == NULL) {
 685    Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
 686    return TCL_ERROR;
 687  }
 688  if (argc == 7) {
 689    if (!egg_strcasecmp(argv[6], "none"));
 690    else if (!egg_strcasecmp(argv[6], "sticky"))
 691      sticky = 1;
 692    else {
 693      Tcl_AppendResult(irp, "invalid option ", argv[6], " (must be one of: ",
 694                       "sticky, none)", NULL);
 695      return TCL_ERROR;
 696    }
 697  }
 698  strncpyz(invite, argv[2], sizeof invite);
 699  strncpyz(from, argv[3], sizeof from);
 700  strncpyz(cmt, argv[4], sizeof cmt);
 701  if (argc == 5) {
 702    if (chan->invite_time == 0)
 703      expire_time = 0L;
 704    else
 705      expire_time = now + (60 * chan->invite_time);
 706  } else {
 707    if (atoi(argv[5]) == 0)
 708      expire_time = 0L;
 709    else
 710      expire_time = now + (atoi(argv[5]) * 60);
 711  }
 712  if (u_addinvite(chan, invite, from, cmt, expire_time, sticky))
 713    add_mode(chan, '+', 'I', invite);
 714  return TCL_OK;
 715}
 716
 717static int tcl_newinvite STDVAR
 718{
 719  time_t expire_time;
 720  struct chanset_t *chan;
 721  char invite[UHOSTLEN], cmt[MASKREASON_LEN], from[HANDLEN + 1];
 722  int sticky = 0;
 723
 724  BADARGS(4, 6, " invite creator comment ?lifetime? ?options?");
 725
 726  if (argc == 6) {
 727    if (!egg_strcasecmp(argv[5], "none"));
 728    else if (!egg_strcasecmp(argv[5], "sticky"))
 729      sticky = 1;
 730    else {
 731      Tcl_AppendResult(irp, "invalid option ", argv[5], " (must be one of: ",
 732                       "sticky, none)", NULL);
 733      return TCL_ERROR;
 734    }
 735  }
 736  strncpyz(invite, argv[1], sizeof invite);
 737  strncpyz(from, argv[2], sizeof from);
 738  strncpyz(cmt, argv[3], sizeof cmt);
 739  if (argc == 4) {
 740    if (global_invite_time == 0)
 741      expire_time = 0L;
 742    else
 743      expire_time = now + (60 * global_invite_time);
 744  } else {
 745    if (atoi(argv[4]) == 0)
 746      expire_time = 0L;
 747    else
 748      expire_time = now + (atoi(argv[4]) * 60);
 749  }
 750  u_addinvite(NULL, invite, from, cmt, expire_time, sticky);
 751  for (chan = chanset; chan; chan = chan->next)
 752    add_mode(chan, '+', 'I', invite);
 753  return TCL_OK;
 754}
 755
 756static int tcl_channel_info(Tcl_Interp *irp, struct chanset_t *chan)
 757{
 758  char a[121], b[121], s[121];
 759  EGG_CONST char *args[2];
 760  struct udef_struct *ul;
 761
 762  get_mode_protect(chan, s);
 763  Tcl_AppendElement(irp, s);
 764  simple_sprintf(s, "%d", chan->idle_kick);
 765  Tcl_AppendElement(irp, s);
 766  simple_sprintf(s, "%d", chan->stopnethack_mode);
 767  Tcl_AppendElement(irp, s);
 768  simple_sprintf(s, "%d", chan->revenge_mode);
 769  Tcl_AppendElement(irp, s);
 770  Tcl_AppendElement(irp, chan->need_op);
 771  Tcl_AppendElement(irp, chan->need_invite);
 772  Tcl_AppendElement(irp, chan->need_key);
 773  Tcl_AppendElement(irp, chan->need_unban);
 774  Tcl_AppendElement(irp, chan->need_limit);
 775  simple_sprintf(s, "%d:%d", chan->flood_pub_thr, chan->flood_pub_time);
 776  Tcl_AppendElement(irp, s);
 777  simple_sprintf(s, "%d:%d", chan->flood_ctcp_thr, chan->flood_ctcp_time);
 778  Tcl_AppendElement(irp, s);
 779  simple_sprintf(s, "%d:%d", chan->flood_join_thr, chan->flood_join_time);
 780  Tcl_AppendElement(irp, s);
 781  simple_sprintf(s, "%d:%d", chan->flood_kick_thr, chan->flood_kick_time);
 782  Tcl_AppendElement(irp, s);
 783  simple_sprintf(s, "%d:%d", chan->flood_deop_thr, chan->flood_deop_time);
 784  Tcl_AppendElement(irp, s);
 785  simple_sprintf(s, "%d:%d", chan->flood_nick_thr, chan->flood_nick_time);
 786  Tcl_AppendElement(irp, s);
 787  simple_sprintf(s, "%d:%d", chan->aop_min, chan->aop_max);
 788  Tcl_AppendElement(irp, s);
 789  simple_sprintf(s, "%d", chan->ban_type);
 790  Tcl_AppendElement(irp, s);
 791  simple_sprintf(s, "%d", chan->ban_time);
 792  Tcl_AppendElement(irp, s);
 793  simple_sprintf(s, "%d", chan->exempt_time);
 794  Tcl_AppendElement(irp, s);
 795  simple_sprintf(s, "%d", chan->invite_time);
 796  Tcl_AppendElement(irp, s);
 797  if (chan->status & CHAN_ENFORCEBANS)
 798    Tcl_AppendElement(irp, "+enforcebans");
 799  else
 800    Tcl_AppendElement(irp, "-enforcebans");
 801  if (chan->status & CHAN_DYNAMICBANS)
 802    Tcl_AppendElement(irp, "+dynamicbans");
 803  else
 804    Tcl_AppendElement(irp, "-dynamicbans");
 805  if (chan->status & CHAN_NOUSERBANS)
 806    Tcl_AppendElement(irp, "-userbans");
 807  else
 808    Tcl_AppendElement(irp, "+userbans");
 809  if (chan->status & CHAN_OPONJOIN)
 810    Tcl_AppendElement(irp, "+autoop");
 811  else
 812    Tcl_AppendElement(irp, "-autoop");
 813  if (chan->status & CHAN_AUTOHALFOP)
 814    Tcl_AppendElement(irp, "+autohalfop");
 815  else
 816    Tcl_AppendElement(irp, "-autohalfop");
 817  if (chan->status & CHAN_BITCH)
 818    Tcl_AppendElement(irp, "+bitch");
 819  else
 820    Tcl_AppendElement(irp, "-bitch");
 821  if (chan->status & CHAN_GREET)
 822    Tcl_AppendElement(irp, "+greet");
 823  else
 824    Tcl_AppendElement(irp, "-greet");
 825  if (chan->status & CHAN_PROTECTOPS)
 826    Tcl_AppendElement(irp, "+protectops");
 827  else
 828    Tcl_AppendElement(irp, "-protectops");
 829  if (chan->status & CHAN_PROTECTHALFOPS)
 830    Tcl_AppendElement(irp, "+protecthalfops");
 831  else
 832    Tcl_AppendElement(irp, "-protecthalfops");
 833  if (chan->status & CHAN_PROTECTFRIENDS)
 834    Tcl_AppendElement(irp, "+protectfriends");
 835  else
 836    Tcl_AppendElement(irp, "-protectfriends");
 837  if (chan->status & CHAN_DONTKICKOPS)
 838    Tcl_AppendElement(irp, "+dontkickops");
 839  else
 840    Tcl_AppendElement(irp, "-dontkickops");
 841  if (chan->status & CHAN_INACTIVE)
 842    Tcl_AppendElement(irp, "+inactive");
 843  else
 844    Tcl_AppendElement(irp, "-inactive");
 845  if (chan->status & CHAN_LOGSTATUS)
 846    Tcl_AppendElement(irp, "+statuslog");
 847  else
 848    Tcl_AppendElement(irp, "-statuslog");
 849  if (chan->status & CHAN_REVENGE)
 850    Tcl_AppendElement(irp, "+revenge");
 851  else
 852    Tcl_AppendElement(irp, "-revenge");
 853  if (chan->status & CHAN_REVENGEBOT)
 854    Tcl_AppendElement(irp, "+revengebot");
 855  else
 856    Tcl_AppendElement(irp, "-revengebot");
 857  if (chan->status & CHAN_SECRET)
 858    Tcl_AppendElement(irp, "+secret");
 859  else
 860    Tcl_AppendElement(irp, "-secret");
 861  if (chan->status & CHAN_SHARED)
 862    Tcl_AppendElement(irp, "+shared");
 863  else
 864    Tcl_AppendElement(irp, "-shared");
 865  if (chan->status & CHAN_AUTOVOICE)
 866    Tcl_AppendElement(irp, "+autovoice");
 867  else
 868    Tcl_AppendElement(irp, "-autovoice");
 869  if (chan->status & CHAN_CYCLE)
 870    Tcl_AppendElement(irp, "+cycle");
 871  else
 872    Tcl_AppendElement(irp, "-cycle");
 873  if (chan->status & CHAN_SEEN)
 874    Tcl_AppendElement(irp, "+seen");
 875  else
 876    Tcl_AppendElement(irp, "-seen");
 877  if (chan->ircnet_status & CHAN_DYNAMICEXEMPTS)
 878    Tcl_AppendElement(irp, "+dynamicexempts");
 879  else
 880    Tcl_AppendElement(irp, "-dynamicexempts");
 881  if (chan->ircnet_status & CHAN_NOUSEREXEMPTS)
 882    Tcl_AppendElement(irp, "-userexempts");
 883  else
 884    Tcl_AppendElement(irp, "+userexempts");
 885  if (chan->ircnet_status & CHAN_DYNAMICINVITES)
 886    Tcl_AppendElement(irp, "+dynamicinvites");
 887  else
 888    Tcl_AppendElement(irp, "-dynamicinvites");
 889  if (chan->ircnet_status & CHAN_NOUSERINVITES)
 890    Tcl_AppendElement(irp, "-userinvites");
 891  else
 892    Tcl_AppendElement(irp, "+userinvites");
 893  if (chan->status & CHAN_NODESYNCH)
 894    Tcl_AppendElement(irp, "+nodesynch");
 895  else
 896    Tcl_AppendElement(irp, "-nodesynch");
 897  if (chan->status & CHAN_STATIC)
 898    Tcl_AppendElement(irp, "+static");
 899  else
 900    Tcl_AppendElement(irp, "-static");
 901  for (ul = udef; ul; ul = ul->next) {
 902    /* If it's undefined, skip it. */
 903    if (!ul->defined || !ul->name)
 904      continue;
 905
 906    if (ul->type == UDEF_FLAG) {
 907      simple_sprintf(s, "%c%s", getudef(ul->values, chan->dname) ? '+' : '-',
 908                     ul->name);
 909      Tcl_AppendElement(irp, s);
 910    } else if (ul->type == UDEF_INT) {
 911      char *x;
 912
 913      egg_snprintf(a, sizeof a, "%s", ul->name);
 914      egg_snprintf(b, sizeof b, "%d", getudef(ul->values, chan->dname));
 915      args[0] = a;
 916      args[1] = b;
 917      x = Tcl_Merge(2, args);
 918      egg_snprintf(s, sizeof s, "%s", x);
 919      Tcl_Free((char *) x);
 920      Tcl_AppendElement(irp, s);
 921    } else if (ul->type == UDEF_STR) {
 922      char *p = (char *) getudef(ul->values, chan->dname), *buf;
 923
 924      if (!p)
 925        p = "{}";
 926
 927      buf = nmalloc(strlen(ul->name) + strlen(p) + 2);
 928      simple_sprintf(buf, "%s %s", ul->name, p);
 929      Tcl_AppendElement(irp, buf);
 930      nfree(buf);
 931    } else
 932      debug1("UDEF-ERROR: unknown type %d", ul->type);
 933  }
 934  return TCL_OK;
 935}
 936
 937#define APPEND_KEYVAL(x, y) {	\
 938  Tcl_AppendElement(irp, x);	\
 939  Tcl_AppendElement(irp, y);	\
 940}
 941
 942static int tcl_channel_getlist(Tcl_Interp *irp, struct chanset_t *chan)
 943{
 944  char s[121], *str;
 945  EGG_CONST char **argv = NULL;
 946  int argc = 0;
 947  struct udef_struct *ul;
 948
 949  /* String values first */
 950  get_mode_protect(chan, s);
 951  APPEND_KEYVAL("chanmode", s);
 952  APPEND_KEYVAL("need-op", chan->need_op);
 953  APPEND_KEYVAL("need-invite", chan->need_invite);
 954  APPEND_KEYVAL("need-key", chan->need_key);
 955  APPEND_KEYVAL("need-unban", chan->need_unban);
 956  APPEND_KEYVAL("need-limit", chan->need_limit);
 957  
 958  /* Integers now */
 959  simple_sprintf(s, "%d", chan->idle_kick);
 960  APPEND_KEYVAL("idle-kick", s);
 961  simple_sprintf(s, "%d", chan->stopnethack_mode);
 962  APPEND_KEYVAL("stopnethack-mode", s);
 963  simple_sprintf(s, "%d", chan->revenge_mode);
 964  APPEND_KEYVAL("revenge-mode", s);
 965  simple_sprintf(s, "%d", chan->ban_type);
 966  APPEND_KEYVAL("ban-type", s);
 967  simple_sprintf(s, "%d", chan->ban_time);
 968  APPEND_KEYVAL("ban-time", s);
 969  simple_sprintf(s, "%d", chan->exempt_time);
 970  APPEND_KEYVAL("exempt-time", s);
 971  simple_sprintf(s, "%d", chan->invite_time);
 972  APPEND_KEYVAL("invite-time", s);
 973  simple_sprintf(s, "%d %d", chan->flood_pub_thr, chan->flood_pub_time);
 974  APPEND_KEYVAL("flood-chan", s);
 975  simple_sprintf(s, "%d %d", chan->flood_ctcp_thr, chan->flood_ctcp_time);
 976  APPEND_KEYVAL("flood-ctcp", s);
 977  simple_sprintf(s, "%d %d", chan->flood_join_thr, chan->flood_join_time);
 978  APPEND_KEYVAL("flood-join", s);
 979  simple_sprintf(s, "%d %d", chan->flood_kick_thr, chan->flood_kick_time);
 980  APPEND_KEYVAL("flood-kick", s);
 981  simple_sprintf(s, "%d %d", chan->flood_deop_thr, chan->flood_deop_time);
 982  APPEND_KEYVAL("flood-deop", s);
 983  simple_sprintf(s, "%d %d", chan->flood_nick_thr, chan->flood_nick_time);
 984  APPEND_KEYVAL("flood-nick", s);
 985  simple_sprintf(s, "%d %d", chan->aop_min, chan->aop_max);
 986  APPEND_KEYVAL("aop-delay", s);
 987
 988  /* Last, but not least - flags */
 989  APPEND_KEYVAL("enforcebans",
 990               channel_enforcebans(chan) ?  "1" : "0");
 991  APPEND_KEYVAL("dynamicbans",
 992               channel_dynamicbans(chan) ?  "1" : "0");
 993  APPEND_KEYVAL("userbans",
 994               channel_nouserbans(chan) ?  "1" : "0");
 995  APPEND_KEYVAL("autoop",
 996               channel_autoop(chan) ?  "1" : "0");
 997  APPEND_KEYVAL("autohalfop",
 998               channel_autohalfop(chan) ?  "1" : "0");
 999  APPEND_KEYVAL("bitch",
1000               channel_bitch(chan) ?  "1" : "0");
1001  APPEND_KEYVAL("greet",
1002               channel_greet(chan) ?  "1" : "0");
1003  APPEND_KEYVAL("protectops",
1004               channel_protectops(chan) ?  "1" : "0");
1005  APPEND_KEYVAL("protecthalfops",
1006               channel_protecthalfops(chan) ?  "1" : "0");
1007  APPEND_KEYVAL("protectfriends",
1008               channel_protectfriends(chan) ?  "1" : "0");
1009  APPEND_KEYVAL("dontkickops",
1010               channel_dontkickops(chan) ?  "1" : "0");
1011  APPEND_KEYVAL("inactive",
1012               channel_inactive(chan) ?  "1" : "0");
1013  APPEND_KEYVAL("statuslog",
1014               channel_logstatus(chan) ?  "1" : "0");
1015  APPEND_KEYVAL("revenge",
1016               channel_revenge(chan) ?  "1" : "0");
1017  APPEND_KEYVAL("revengebot",
1018               channel_revengebot(chan) ?  "1" : "0");
1019  APPEND_KEYVAL("secret",
1020               channel_secret(chan) ?  "1" : "0");
1021  APPEND_KEYVAL("shared",
1022               channel_shared(chan) ?  "1" : "0");
1023  APPEND_KEYVAL("autovoice",
1024               channel_autovoice(chan) ?  "1" : "0");
1025  APPEND_KEYVAL("cycle",
1026               channel_cycle(chan) ?  "1" : "0");
1027  APPEND_KEYVAL("seen",
1028               channel_seen(chan) ?  "1" : "0");
1029  APPEND_KEYVAL("nodesynch",
1030               channel_nodesynch(chan) ?  "1" : "0");
1031  APPEND_KEYVAL("static",
1032               channel_static(chan) ?  "1" : "0");
1033  APPEND_KEYVAL("dynamicexempts",
1034               channel_dynamicexempts(chan) ?  "1" : "0");
1035  APPEND_KEYVAL("userexempts",
1036               channel_nouserexempts(chan) ?  "1" : "0");
1037  APPEND_KEYVAL("dynamicinvites",
1038               channel_dynamicinvites(chan) ?  "1" : "0");
1039  APPEND_KEYVAL("userinvites",
1040               channel_nouserinvites(chan) ?  "1" : "0");
1041  
1042  /* User defined settings */
1043  for (ul = udef; ul && ul->name; ul = ul->next) {
1044    if (ul->type == UDEF_STR) {
1045      str = (char *) getudef(ul->values, chan->dname);
1046      if (!str)
1047        str = "{}";
1048      Tcl_SplitList(irp, str, &argc, &argv);
1049      if (argc > 0)
1050        APPEND_KEYVAL(ul->name, argv[0]);
1051      Tcl_Free((char *) argv);
1052    } else {
1053      simple_sprintf(s, "%d", getudef(ul->values, chan->dname));
1054      APPEND_KEYVAL(ul->name, s);
1055    }
1056  }
1057
1058  return TCL_OK;
1059}
1060
1061static int tcl_channel_get(Tcl_Interp *irp, struct chanset_t *chan,
1062                           char *setting)
1063{
1064  char s[121], *str = NULL;
1065  EGG_CONST char **argv = NULL;
1066  int argc = 0;
1067  struct udef_struct *ul;
1068
1069  if (!strcmp(setting, "chanmode"))
1070    get_mode_protect(chan, s);
1071  else if (!strcmp(setting, "need-op")) {
1072    strncpy(s, chan->need_op, 120);
1073    s[120] = 0;
1074  } else if (!strcmp(setting, "need-invite")) {
1075    strncpy(s, chan->need_invite, 120);
1076    s[120] = 0;
1077  } else if (!strcmp(setting, "need-key")) {
1078    strncpy(s, chan->need_key, 120);
1079    s[120] = 0;
1080  } else if (!strcmp(setting, "need-unban")) {
1081    strncpy(s, chan->need_unban, 120);
1082    s[120] = 0;
1083  } else if (!strcmp(setting, "need-limit")) {
1084    strncpy(s, chan->need_limit, 120);
1085    s[120] = 0;
1086  } else if (!strcmp(setting, "idle-kick"))
1087    simple_sprintf(s, "%d", chan->idle_kick);
1088  else if (!strcmp(setting, "stopnethack-mode") || !strcmp(setting, "stop-net-hack"))
1089    simple_sprintf(s, "%d", chan->stopnethack_mode);
1090  else if (!strcmp(setting, "revenge-mode"))
1091    simple_sprintf(s, "%d", chan->revenge_mode);
1092  else if (!strcmp(setting, "ban-type"))
1093    simple_sprintf(s, "%d", chan->ban_type);
1094  else if (!strcmp(setting, "ban-time"))
1095    simple_sprintf(s, "%d", chan->ban_time);
1096  else if (!strcmp(setting, "exempt-time"))
1097    simple_sprintf(s, "%d", chan->exempt_time);
1098  else if (!strcmp(setting, "invite-time"))
1099    simple_sprintf(s, "%d", chan->invite_time);
1100  else if (!strcmp(setting, "flood-chan"))
1101    simple_sprintf(s, "%d %d", chan->flood_pub_thr, chan->flood_pub_time);
1102  else if (!strcmp(setting, "flood-ctcp"))
1103    simple_sprintf(s, "%d %d", chan->flood_ctcp_thr, chan->flood_ctcp_time);
1104  else if (!strcmp(setting, "flood-join"))
1105    simple_sprintf(s, "%d %d", chan->flood_join_thr, chan->flood_join_time);
1106  else if (!strcmp(setting, "flood-kick"))
1107    simple_sprintf(s, "%d %d", chan->flood_kick_thr, chan->flood_kick_time);
1108  else if (!strcmp(setting, "flood-deop"))
1109    simple_sprintf(s, "%d %d", chan->flood_deop_thr, chan->flood_deop_time);
1110  else if (!strcmp(setting, "flood-nick"))
1111    simple_sprintf(s, "%d %d", chan->flood_nick_thr, chan->flood_nick_time);
1112  else if (!strcmp(setting, "aop-delay"))
1113    simple_sprintf(s, "%d %d", chan->aop_min, chan->aop_max);
1114  else if CHKFLAG_POS(CHAN_ENFORCEBANS, "enforcebans", chan->status)
1115  else if CHKFLAG_POS(CHAN_DYNAMICBANS, "dynamicbans", chan->status)
1116  else if CHKFLAG_NEG(CHAN_NOUSERBANS, "userbans", chan->status)
1117  else if CHKFLAG_POS(CHAN_OPONJOIN, "autoop", chan->status)
1118  else if CHKFLAG_POS(CHAN_AUTOHALFOP, "autohalfop", chan->status)
1119  else if CHKFLAG_POS(CHAN_BITCH, "bitch", chan->status)
1120  else if CHKFLAG_POS(CHAN_GREET, "greet", chan->status)
1121  else if CHKFLAG_POS(CHAN_PROTECTOPS, "protectops", chan->status)
1122  else if CHKFLAG_POS(CHAN_PROTECTHALFOPS, "protecthalfops", chan->status)
1123  else if CHKFLAG_POS(CHAN_PROTECTFRIENDS, "protectfriends", chan->status)
1124  else if CHKFLAG_POS(CHAN_DONTKICKOPS, "dontkickops", chan->status)
1125  else if CHKFLAG_POS(CHAN_INACTIVE, "inactive", chan->status)
1126  else if CHKFLAG_POS(CHAN_LOGSTATUS, "statuslog", chan->status)
1127  else if CHKFLAG_POS(CHAN_REVENGE, "revenge", chan->status)
1128  else if CHKFLAG_POS(CHAN_REVENGEBOT, "revengebot", chan->status)
1129  else if CHKFLAG_POS(CHAN_SECRET, "secret", chan->status)
1130  else if CHKFLAG_POS(CHAN_SHARED, "shared", chan->status)
1131  else if CHKFLAG_POS(CHAN_AUTOVOICE, "autovoice", chan->status)
1132  else if CHKFLAG_POS(CHAN_CYCLE, "cycle", chan->status)
1133  else if CHKFLAG_POS(CHAN_SEEN, "seen", chan->status)
1134  else if CHKFLAG_POS(CHAN_NODESYNCH, "nodesynch", chan->status)
1135  else if CHKFLAG_POS(CHAN_STATIC, "static", chan->status)
1136  else if CHKFLAG_POS(CHAN_DYNAMICEXEMPTS, "dynamicexempts",
1137                      chan->ircnet_status)
1138  else if CHKFLAG_NEG(CHAN_NOUSEREXEMPTS, "userexempts",
1139                      chan->ircnet_status)
1140  else if CHKFLAG_POS(CHAN_DYNAMICINVITES, "dynamicinvites",
1141                      chan->ircnet_status)
1142  else if CHKFLAG_NEG(CHAN_NOUSERINVITES, "userinvites",
1143                      chan->ircnet_status)
1144  else {
1145    /* Hopefully it's a user-defined flag. */
1146    for (ul = udef; ul && ul->name; ul = ul->next) {
1147      if (!strcmp(setting, ul->name))
1148        break;
1149    }
1150    if (!ul || !ul->name) {
1151      /* Error if it wasn't found. */
1152      Tcl_AppendResult(irp, "Unknown channel setting.", NULL);
1153      return TCL_ERROR;
1154    }
1155
1156    if (ul->type == UDEF_STR) {
1157      str = (char *) getudef(ul->values, chan->dname);
1158      if (!str)
1159        str = "{}";
1160      Tcl_SplitList(irp, str, &argc, &argv);
1161      if (argc > 0)
1162        Tcl_AppendResult(irp, argv[0], NULL);
1163      Tcl_Free((char *) argv);
1164    } else {
1165      /* Flag or int, all the same. */
1166      simple_sprintf(s, "%d", getudef(ul->values, chan->dname));
1167      Tcl_AppendResult(irp, s, NULL);
1168    }
1169    return TCL_OK;
1170  }
1171
1172  /* Ok, if we make it this far, the result is "s". */
1173  Tcl_AppendResult(irp, s, NULL);
1174  return TCL_OK;
1175}
1176
1177static int tcl_channel STDVAR
1178{
1179  struct chanset_t *chan;
1180
1181  BADARGS(2, -1, " command ?options?");
1182
1183  if (!strcmp(argv[1], "add")) {
1184    BADARGS(3, 4, " add channel-name ?options-list?");
1185
1186    if (argc == 3)
1187      return tcl_channel_add(irp, argv[2], "");
1188    return tcl_channel_add(irp, argv[2], argv[3]);
1189  }
1190  if (!strcmp(argv[1], "set")) {
1191    BADARGS(3, -1, " set channel-name ?options?");
1192
1193    chan = findchan_by_dname(argv[2]);
1194    if (chan == NULL) {
1195      if (chan_hack == 1)
1196        return TCL_OK;          /* Ignore channel settings for a static
1197                                 * channel which has been removed from
1198                                 * the config */
1199      Tcl_AppendResult(irp, "no such channel record", NULL);
1200      return TCL_ERROR;
1201    }
1202    return tcl_channel_modify(irp, chan, argc - 3, &argv[3]);
1203  }
1204  if (!strcmp(argv[1], "get")) {
1205    BADARGS(3, 4, " get channel-name ?setting-name?");
1206
1207    chan = findchan_by_dname(argv[2]);
1208    if (chan == NULL) {
1209      Tcl_AppendResult(irp, "no such channel record", NULL);
1210      return TCL_ERROR;
1211    }
1212    if (argc == 4)
1213      return tcl_channel_get(irp, chan, argv[3]);
1214    else
1215      return tcl_channel_getlist(irp, chan);
1216  }
1217  if (!strcmp(argv[1], "info")) {
1218    BADARGS(3, 3, " info channel-name");
1219
1220    chan = findchan_by_dname(argv[2]);
1221    if (chan == NULL) {
1222      Tcl_AppendResult(irp, "no such channel record", NULL);
1223      return TCL_ERROR;
1224    }
1225    return tcl_channel_info(irp, chan);
1226  }
1227  if (!strcmp(argv[1], "remove")) {
1228    BADARGS(3, 3, " remove channel-name");
1229
1230    chan = findchan_by_dname(argv[2]);
1231    if (chan == NULL) {
1232      Tcl_AppendResult(irp, "no such channel record", NULL);
1233      return TCL_ERROR;
1234    }
1235    remove_channel(chan);
1236    return TCL_OK;
1237  }
1238  Tcl_AppendResult(irp, "unknown channel command: should be one of: ",
1239                   "add, set, get, info, remove", NULL);
1240  return TCL_ERROR;
1241}
1242
1243/* Parse options for a channel. */
1244static int tcl_channel_modify(Tcl_Interp *irp, struct chanset_t *chan,
1245                              int items, char **item)
1246{
1247  int i, x = 0, found, old_status = chan->status,
1248      old_mode_mns_prot = chan->mode_mns_prot,
1249      old_mode_pls_prot = chan->mode_pls_prot;
1250  struct udef_struct *ul = udef;
1251  char s[121];
1252  module_entry *me;
1253
1254  for (i = 0; i < items; i++) {
1255    if (!strcmp(item[i], "need-op")) {
1256      i++;
1257      if (i >= items) {
1258        if (irp)
1259          Tcl_AppendResult(irp, "channel need-op needs argument", NULL);
1260        return TCL_ERROR;
1261      }
1262      strncpy(chan->need_op, item[i], 120);
1263      chan->need_op[120] = 0;
1264    } else if (!strcmp(item[i], "need-invite")) {
1265      i++;
1266      if (i >= items) {
1267        if (irp)
1268          Tcl_AppendResult(irp, "channel need-invite needs argument", NULL);
1269        return TCL_ERROR;
1270      }
1271      strncpy(chan->need_invite, item[i], 120);
1272      chan->need_invite[120] = 0;
1273    } else if (!strcmp(item[i], "need-key")) {
1274      i++;
1275      if (i >= items) {
1276        if (irp)
1277          Tcl_AppendResult(irp, "channel need-key needs argument", NULL);
1278        return TCL_ERROR;
1279      }
1280      strncpy(chan->need_key, item[i], 120);
1281      chan->need_key[120] = 0;
1282    } else if (!strcmp(item[i], "need-limit")) {
1283      i++;
1284      if (i >= items) {
1285        if (irp)
1286          Tcl_AppendResult(irp, "channel need-limit needs argument", NULL);
1287        return TCL_ERROR;
1288      }
1289      strncpy(chan->need_limit, item[i], 120);
1290      chan->need_limit[120] = 0;
1291    } else if (!strcmp(item[i], "need-unban")) {
1292      i++;
1293      if (i >= items) {
1294        if (irp)
1295          Tcl_AppendResult(irp, "channel need-unban needs argument", NULL);
1296        return TCL_ERROR;
1297      }
1298      strncpy(chan->need_unban, item[i], 120);
1299      chan->need_unban[120] = 0;
1300    } else if (!strcmp(item[i], "chanmode")) {
1301      i++;
1302      if (i >= items) {
1303        if (irp)
1304          Tcl_AppendResult(irp, "channel chanmode needs argument", NULL);
1305        return TCL_ERROR;
1306      }
1307      strncpy(s, item[i], 120);
1308      s[120] = 0;
1309      set_mode_protect(chan, s);
1310    } else if (!strcmp(item[i], "idle-kick")) {
1311      i++;
1312      if (i >= items) {
1313        if (irp)
1314          Tcl_AppendResult(irp, "channel idle-kick needs argument", NULL);
1315        return TCL_ERROR;
1316      }
1317      chan->idle_kick = atoi(item[i]);
1318    } else if (!strcmp(item[i], "dont-idle-kick"))
1319      chan->idle_kick = 0;
1320    else if (!strcmp(item[i], "stopnethack-mode")) {
1321      i++;
1322      if (i >= items) {
1323        if (irp)
1324          Tcl_AppendResult(irp, "channel stopnethack-mode needs argument",
1325                           NULL);
1326        return TCL_ERROR;
1327      }
1328      chan->stopnethack_mode = atoi(item[i]);
1329    } else if (!strcmp(item[i], "revenge-mode")) {
1330      i++;
1331      if (i >= items) {
1332        if (irp)
1333          Tcl_AppendResult(irp, "channel revenge-mode needs argument", NULL);
1334        return TCL_ERROR;
1335      }
1336      chan->revenge_mode = atoi(item[i]);
1337    } else if (!strcmp(item[i], "ban-type")) {
1338      i++;
1339      if (i >= items) {
1340        if (irp)
1341          Tcl_AppendResult(irp, "channel ban-type needs argument", NULL);
1342        return TCL_ERROR;
1343      }
1344      chan->ban_type = atoi(item[i]);
1345    } else if (!strcmp(item[i], "ban-time")) {
1346      i++;
1347      if (i >= items) {
1348        if (irp)
1349          Tcl_AppendResult(irp, "channel ban-time needs argument", NULL);
1350        return TCL_ERROR;
1351      }
1352      chan->ban_time = atoi(item[i]);
1353    } else if (!strcmp(item[i], "exempt-time")) {
1354      i++;
1355      if (i >= items) {
1356        if (irp)
1357          Tcl_AppendResult(irp, "channel exempt-time needs argument", NULL);
1358        return TCL_ERROR;
1359      }
1360      chan->exempt_time = atoi(item[i]);
1361    } else if (!strcmp(item[i], "invite-time")) {
1362      i++;
1363      if (i >= items) {
1364        if (irp)
1365          Tcl_AppendResult(irp, "channel invite-time needs argument", NULL);
1366        return TCL_ERROR;
1367      }
1368      chan->invite_time = atoi(item[i]);
1369    } else if (!strcmp(item[i], "+enforcebans"))
1370      chan->status |= CHAN_ENFORCEBANS;
1371    else if (!strcmp(item[i], "-enforcebans"))
1372      chan->status &= ~CHAN_ENFORCEBANS;
1373    else if (!strcmp(item[i], "+dynamicbans"))
1374      chan->status |= CHAN_DYNAMICBANS;
1375    else if (!strcmp(item[i], "-dynamicbans"))
1376      chan->status &= ~CHAN_DYNAMICBANS;
1377    else if (!strcmp(item[i], "-userbans"))
1378      chan->status |= CHAN_NOUSERBANS;
1379    else if (!strcmp(item[i], "+userbans"))
1380      chan->status &= ~CHAN_NOUSERBANS;
1381    else if (!strcmp(item[i], "+autoop"))
1382      chan->status |= CHAN_OPONJOIN;
1383    else if (!strcmp(item[i], "-autoop"))
1384      chan->status &= ~CHAN_OPONJOIN;
1385    else if (!strcmp(item[i], "+autohalfop"))
1386      chan->status |= CHAN_AUTOHALFOP;
1387    else if (!strcmp(item[i], "-autohalfop"))
1388      chan->status &= ~CHAN_AUTOHALFOP;
1389    else if (!strcmp(item[i], "+bitch"))
1390      chan->status |= CHAN_BITCH;
1391    else if (!strcmp(item[i], "-bitch"))
1392      chan->status &= ~CHAN_BITCH;
1393    else if (!strcmp(item[i], "+nodesynch"))
1394      chan->status |= CHAN_NODESYNCH;
1395    else if (!strcmp(item[i], "-nodesynch"))
1396      chan->status &= ~CHAN_NODESYNCH;
1397    else if (!strcmp(item[i], "+greet"))
1398      chan->status |= CHAN_GREET;
1399    else if (!strcmp(item[i], "-greet"))
1400      chan->status &= ~CHAN_GREET;
1401    else if (!strcmp(item[i], "+protectops"))
1402      chan->status |= CHAN_PROTECTOPS;
1403    else if (!strcmp(item[i], "-protectops"))
1404      chan->status &= ~CHAN_PROTECTOPS;
1405    else if (!strcmp(item[i], "+protecthalfops"))
1406      chan->status |= CHAN_PROTECTHALFOPS;
1407    else if (!strcmp(item[i], "-protecthalfops"))
1408      chan->status &= ~CHAN_PROTECTHALFOPS;
1409    else if (!strcmp(item[i], "+protectfriends"))
1410      chan->status |= CHAN_PROTECTFRIENDS;
1411    else if (!strcmp(item[i], "-protectfriends"))
1412      chan->status &= ~CHAN_PROTECTFRIENDS;
1413    else if (!strcmp(item[i], "+dontkickops"))
1414      chan->status |= CHAN_DONTKICKOPS;
1415    else if (!strcmp(item[i], "-dontkickops"))
1416      chan->status &= ~CHAN_DONTKICKOPS;
1417    else if (!strcmp(item[i], "+inactive"))
1418      chan->status |= CHAN_INACTIVE;
1419    else if (!strcmp(item[i], "-inactive"))
1420      chan->status &= ~CHAN_INACTIVE;
1421    else if (!strcmp(item[i], "+statuslog"))
1422      chan->status |= CHAN_LOGSTATUS;
1423    else if (!strcmp(item[i], "-statuslog"))
1424      chan->status &= ~CHAN_LOGSTATUS;
1425    else if (!strcmp(item[i], "+revenge"))
1426      chan->status |= CHAN_REVENGE;
1427    else if (!strcmp(item[i], "-revenge"))
1428      chan->status &= ~CHAN_REVENGE;
1429    else if (!strcmp(item[i], "+revengebot"))
1430      chan->status |= CHAN_REVENGEBOT;
1431    else if (!strcmp(item[i], "-revengebot"))
1432      chan->status &= ~CHAN_REVENGEBOT;
1433    else if (!strcmp(item[i], "+secret"))
1434      chan->status |= CHAN_SECRET;
1435    else if (!strcmp(item[i], "-secret"))
1436      chan->status &= ~CHAN_SECRET;
1437    else if (!strcmp(item[i], "+shared"))
1438      chan->status |= CHAN_SHARED;
1439    else if (!strcmp(item[i], "-shared"))
1440      chan->status &= ~CHAN_SHARED;
1441    else if (!strcmp(item[i], "+autovoice"))
1442      chan->status |= CHAN_AUTOVOICE;
1443    else if (!strcmp(item[i], "-autovoice"))
1444      chan->status &= ~CHAN_AUTOVOICE;
1445    else if (!strcmp(item[i], "+cycle"))
1446      chan->status |= CHAN_CYCLE;
1447    else if (!strcmp(item[i], "-cycle"))
1448      chan->status &= ~CHAN_CYCLE;
1449    else if (!strcmp(item[i], "+seen"))
1450      chan->status |= CHAN_SEEN;
1451    else if (!strcmp(item[i], "-seen"))
1452      chan->status &= ~CHAN_SEEN;
1453    else if (!strcmp(item[i], "+static"))
1454      chan->status |= CHAN_STATIC;
1455    else if (!strcmp(item[i], "-static"))
1456      chan->status &= ~CHAN_STATIC;
1457    else if (!strcmp(item[i], "+dynamicexempts"))
1458      chan->ircnet_status |= CHAN_DYNAMICEXEMPTS;
1459    else if (!strcmp(item[i], "-dynamicexempts"))
1460      chan->ircnet_status &= ~CHAN_DYNAMICEXEMPTS;
1461    else if (!strcmp(item[i], "-userexempts"))
1462      chan->ircnet_status |= CHAN_NOUSEREXEMPTS;
1463    else if (!strcmp(item[i], "+userexempts"))
1464      chan->ircnet_status &= ~CHAN_NOUSEREXEMPTS;
1465    else if (!strcmp(item[i], "+dynamicinvites"))
1466      chan->ircnet_status |= CHAN_DYNAMICINVITES;
1467    else if (!strcmp(item[i], "-dynamicinvites"))
1468      chan->ircnet_status &= ~CHAN_DYNAMICINVITES;
1469    else if (!strcmp(item[i], "-userinvites"))
1470      chan->ircnet_status |= CHAN_NOUSERINVITES;
1471    else if (!strcmp(item[i], "+userinvites"))
1472      chan->ircnet_status &= ~CHAN_NOUSERINVITES;
1473    /* ignore wasoptest, stopnethack and clearbans in chanfile, remove
1474     * this later */
1475    else if (!strcmp(item[i], "-stopnethack"));
1476    else if (!strcmp(item[i], "+stopnethack"));
1477    else if (!strcmp(item[i], "-wasoptest"));
1478    else if (!strcmp(item[i], "+wasoptest")); /* Eule 01.2000 */
1479    else if (!strcmp(item[i], "+clearbans"));
1480    else if (!strcmp(item[i], "-clearbans"));
1481    else if (!strncmp(item[i], "flood-", 6)) {
1482      int *pthr = 0, *ptime;
1483      char *p;
1484
1485      if (!strcmp(item[i] + 6, "chan")) {
1486        pthr = &chan->flood_pub_thr;
1487        ptime = &chan->flood_pub_time;
1488      } else if (!strcmp(item[i] + 6, "join")) {
1489        pthr = &chan->flood_join_thr;
1490        ptime = &chan->flood_join_time;
1491      } else if (!strcmp(item[i] + 6, "ctcp")) {
1492        pthr = &chan->flood_ctcp_thr;
1493        ptime = &chan->flood_ctcp_time;
1494      } else if (!strcmp(item[i] + 6, "kick")) {
1495        pthr = &chan->flood_kick_thr;
1496        ptime = &chan->flood_kick_time;
1497      } else if (!strcmp(item[i] + 6, "deop")) {
1498        pthr = &chan->flood_deop_thr;
1499        ptime = &chan->flood_deop_time;
1500      } else if (!strcmp(item[i] + 6, "nick")) {
1501        pthr = &chan->flood_nick_thr;
1502        ptime = &chan->flood_nick_time;
1503      } else {
1504        if (irp)
1505          Tcl_AppendResult(irp, "illegal channel flood type: ", item[i], NULL);
1506        return TCL_ERROR;
1507      }
1508      i++;
1509      if (i >= items) {
1510        if (irp)
1511          Tcl_AppendResult(irp, item[i - 1], " needs argument", NULL);
1512        return TCL_ERROR;
1513      }
1514      p = strchr(item[i], ':');
1515      if (p) {
1516        *p++ = 0;
1517        *pthr = atoi(item[i]);
1518        *ptime = atoi(p);
1519        *--p = ':';
1520      } else {
1521        *pthr = atoi(item[i]);
1522        *ptime = 1;
1523      }
1524    } else if (!strncmp(item[i], "aop-delay", 9)) {
1525      char *p;
1526
1527      i++;
1528      if (i >= items) {
1529        if (irp)
1530          Tcl_AppendResult(irp, item[i - 1], " needs argument", NULL);
1531        return TCL_ERROR;
1532      }
1533      p = strchr(item[i], ':');
1534      if (p) {
1535        p++;
1536        chan->aop_min = atoi(item[i]);
1537        chan->aop_max = atoi(p);
1538      } else {
1539        chan->aop_min = atoi(item[i]);
1540        chan->aop_max = chan->aop_min;
1541      }
1542    } else {
1543      if (!strncmp(item[i] + 1, "udef-flag-", 10))
1544        /* 10th position for the +/- sign */
1545        initudef(UDEF_FLAG, item[i] + 11, 0);
1546      else if (!strncmp(item[i], "udef-int-", 9))
1547        initudef(UDEF_INT, item[i] + 9, 0);
1548      else if (!strncmp(item[i], "udef-str-", 9))
1549        initudef(UDEF_STR, item[i] + 9, 0);
1550      found = 0;
1551      for (ul = udef; ul; ul = ul->next) {
1552        if (ul->type == UDEF_FLAG && (!egg_strcasecmp(item[i] + 1, ul->name) ||
1553            (!strncmp(item[i] + 1, "udef-flag-", 10) &&
1554            !egg_strcasecmp(item[i] + 11, ul->name)))) {
1555          if (item[i][0] == '+')
1556            setudef(ul, chan->dname, 1);
1557          else
1558            setudef(ul, chan->dname, 0);
1559          found = 1;
1560          break;
1561        } else if (ul->type == UDEF_INT && (!egg_strcasecmp(item[i], ul->name) ||
1562                   (!strncmp(item[i], "udef-int-", 9) &&
1563                   !egg_strcasecmp(item[i] + 9, ul->name)))) {
1564          i++;
1565          if (i >= items) {
1566            if (irp)
1567              Tcl_AppendResult(irp, "this setting needs an argument", NULL);
1568            return TCL_ERROR;
1569          }
1570          setudef(ul, chan->dname, atoi(item[i]));
1571          found = 1;
1572          break;
1573        } else if (ul->type == UDEF_STR &&
1574                   (!egg_strcasecmp(item[i], ul->name) ||
1575                   (!strncmp(item[i], "udef-str-", 9) &&
1576                   !egg_strcasecmp(item[i] + 9, ul->name)))) {
1577          char *val;
1578
1579          i++;
1580          if (i >= items) {
1581            if (irp)
1582              Tcl_AppendResult(irp, "this setting needs an argument", NULL);
1583            return TCL_ERROR;
1584          }
1585          val = (char *) getudef(ul->values, chan->dname);
1586          if (val)
1587            nfree(val);
1588
1589          /* Get extra room for new braces, etc */
1590          val = nmalloc(3 * strlen(item[i]) + 10);
1591          convert_element(item[i], val);
1592          val = nrealloc(val, strlen(val) + 1);
1593          setudef(ul, chan->dname, (intptr_t) val);
1594          found = 1;
1595          break;
1596        }
1597      }
1598      if (!found) {
1599        if (irp && item[i][0])  /* ignore "" */
1600          Tcl_AppendResult(irp, "illegal channel option: ", item[i], "\n", NULL);
1601        x++;
1602      }
1603    }
1604  }
1605  /* If protect_readonly == 0 and chan_hack == 0 then
1606   * bot is now processing the configfile, so dont do anything,
1607   * we've to wait the channelfile that maybe override these settings
1608   * (note: it may cause problems if there is no chanfile!)
1609   * <drummer/1999/10/21>
1610   */
1611  if (protect_readonly || chan_hack) {
1612    if (((old_status ^ chan->status) & CHAN_INACTIVE) &&
1613        module_find("irc", 0, 0)) {
1614      if (channel_inactive(chan) && (chan->status & (CHAN_ACTIVE | CHAN_PEND)))
1615        dprintf(DP_SERVER, "PART %s\n", chan->name);
1616      if (!channel_inactive(chan) &&
1617          !(chan->status & (CHAN_ACTIVE | CHAN_PEND))) {
1618        char *key;
1619
1620        key = chan->channel.key[0] ? chan->channel.key : chan->key_prot;
1621        if (key[0])
1622          dprintf(DP_SERVER, "JOIN %s %s\n",
1623                  chan->name[0] ? chan->name : chan->dname, key);
1624        else
1625          dprintf(DP_SERVER, "JOIN %s\n",
1626                  chan->name[0] ? chan->name : chan->dname);
1627      }
1628    }
1629    if ((old_status ^ chan->status) & (CHAN_ENFORCEBANS | CHAN_OPONJOIN |
1630                                       CHAN_BITCH | CHAN_AUTOVOICE |
1631                                       CHAN_AUTOHALFOP)) {
1632      if ((me = module_find("irc", 0, 0)))
1633        (me->funcs[IRC_RECHECK_CHANNEL]) (chan, 1);
1634    } else if (old_mode_pls_p

Large files files are truncated, but you can click here to view the full file