00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 static int tcl_killban STDVAR
00026 {
00027 struct chanset_t *chan;
00028
00029 BADARGS(2, 2, " ban");
00030
00031 if (u_delban(NULL, argv[1], 1) > 0) {
00032 for (chan = chanset; chan; chan = chan->next)
00033 add_mode(chan, '-', 'b', argv[1]);
00034 Tcl_AppendResult(irp, "1", NULL);
00035 } else
00036 Tcl_AppendResult(irp, "0", NULL);
00037 return TCL_OK;
00038 }
00039
00040 static int tcl_killchanban STDVAR
00041 {
00042 struct chanset_t *chan;
00043
00044 BADARGS(3, 3, " channel ban");
00045
00046 chan = findchan_by_dname(argv[1]);
00047 if (!chan) {
00048 Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
00049 return TCL_ERROR;
00050 }
00051 if (u_delban(chan, argv[2], 1) > 0) {
00052 add_mode(chan, '-', 'b', argv[2]);
00053 Tcl_AppendResult(irp, "1", NULL);
00054 } else
00055 Tcl_AppendResult(irp, "0", NULL);
00056 return TCL_OK;
00057 }
00058
00059 static int tcl_killexempt STDVAR
00060 {
00061 struct chanset_t *chan;
00062
00063 BADARGS(2, 2, " exempt");
00064
00065 if (u_delexempt(NULL, argv[1], 1) > 0) {
00066 for (chan = chanset; chan; chan = chan->next)
00067 add_mode(chan, '-', 'e', argv[1]);
00068 Tcl_AppendResult(irp, "1", NULL);
00069 } else
00070 Tcl_AppendResult(irp, "0", NULL);
00071 return TCL_OK;
00072 }
00073
00074 static int tcl_killchanexempt STDVAR
00075 {
00076 struct chanset_t *chan;
00077
00078 BADARGS(3, 3, " channel exempt");
00079
00080 chan = findchan_by_dname(argv[1]);
00081 if (!chan) {
00082 Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
00083 return TCL_ERROR;
00084 }
00085 if (u_delexempt(chan, argv[2], 1) > 0) {
00086 add_mode(chan, '-', 'e', argv[2]);
00087 Tcl_AppendResult(irp, "1", NULL);
00088 } else
00089 Tcl_AppendResult(irp, "0", NULL);
00090 return TCL_OK;
00091 }
00092
00093 static int tcl_killinvite STDVAR
00094 {
00095 struct chanset_t *chan;
00096
00097 BADARGS(2, 2, " invite");
00098
00099 if (u_delinvite(NULL, argv[1], 1) > 0) {
00100 for (chan = chanset; chan; chan = chan->next)
00101 add_mode(chan, '-', 'I', argv[1]);
00102 Tcl_AppendResult(irp, "1", NULL);
00103 } else
00104 Tcl_AppendResult(irp, "0", NULL);
00105 return TCL_OK;
00106 }
00107
00108 static int tcl_killchaninvite STDVAR
00109 {
00110 struct chanset_t *chan;
00111
00112 BADARGS(3, 3, " channel invite");
00113
00114 chan = findchan_by_dname(argv[1]);
00115 if (!chan) {
00116 Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
00117 return TCL_ERROR;
00118 }
00119 if (u_delinvite(chan, argv[2], 1) > 0) {
00120 add_mode(chan, '-', 'I', argv[2]);
00121 Tcl_AppendResult(irp, "1", NULL);
00122 } else
00123 Tcl_AppendResult(irp, "0", NULL);
00124 return TCL_OK;
00125 }
00126
00127 static int tcl_stick STDVAR
00128 {
00129 struct chanset_t *chan;
00130 int ok = 0;
00131
00132 BADARGS(2, 3, " ban ?channel?");
00133
00134 if (argc == 3) {
00135 chan = findchan_by_dname(argv[2]);
00136 if (!chan) {
00137 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00138 return TCL_ERROR;
00139 }
00140 if (u_setsticky_ban(chan, argv[1], !strncmp(argv[0], "un", 2) ? 0 : 1))
00141 ok = 1;
00142 }
00143 if (!ok && u_setsticky_ban(NULL, argv[1], !strncmp(argv[0], "un", 2) ?
00144 0 : 1))
00145 ok = 1;
00146 if (ok)
00147 Tcl_AppendResult(irp, "1", NULL);
00148 else
00149 Tcl_AppendResult(irp, "0", NULL);
00150 return TCL_OK;
00151 }
00152
00153 static int tcl_stickinvite STDVAR
00154 {
00155 struct chanset_t *chan;
00156 int ok = 0;
00157
00158 BADARGS(2, 3, " ban ?channel?");
00159
00160 if (argc == 3) {
00161 chan = findchan_by_dname(argv[2]);
00162 if (!chan) {
00163 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00164 return TCL_ERROR;
00165 }
00166 if (u_setsticky_invite(chan, argv[1], !strncmp(argv[0], "un", 2) ? 0 : 1))
00167 ok = 1;
00168 }
00169 if (!ok && u_setsticky_invite(NULL, argv[1], !strncmp(argv[0], "un", 2) ?
00170 0 : 1))
00171 ok = 1;
00172 if (ok)
00173 Tcl_AppendResult(irp, "1", NULL);
00174 else
00175 Tcl_AppendResult(irp, "0", NULL);
00176 return TCL_OK;
00177 }
00178
00179 static int tcl_stickexempt STDVAR
00180 {
00181 struct chanset_t *chan;
00182 int ok = 0;
00183
00184 BADARGS(2, 3, " ban ?channel?");
00185
00186 if (argc == 3) {
00187 chan = findchan_by_dname(argv[2]);
00188 if (!chan) {
00189 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00190 return TCL_ERROR;
00191 }
00192 if (u_setsticky_exempt(chan, argv[1], !strncmp(argv[0], "un", 2) ? 0 : 1))
00193 ok = 1;
00194 }
00195 if (!ok && u_setsticky_exempt(NULL, argv[1], !strncmp(argv[0], "un", 2) ?
00196 0 : 1))
00197 ok = 1;
00198 if (ok)
00199 Tcl_AppendResult(irp, "1", NULL);
00200 else
00201 Tcl_AppendResult(irp, "0", NULL);
00202 return TCL_OK;
00203 }
00204
00205 static int tcl_isban STDVAR
00206 {
00207 struct chanset_t *chan;
00208 int ok = 0;
00209
00210 BADARGS(2, 3, " ban ?channel?");
00211
00212 if (argc == 3) {
00213 chan = findchan_by_dname(argv[2]);
00214 if (!chan) {
00215 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00216 return TCL_ERROR;
00217 }
00218 if (u_equals_mask(chan->bans, argv[1]))
00219 ok = 1;
00220 }
00221 if (u_equals_mask(global_bans, argv[1]))
00222 ok = 1;
00223 if (ok)
00224 Tcl_AppendResult(irp, "1", NULL);
00225 else
00226 Tcl_AppendResult(irp, "0", NULL);
00227 return TCL_OK;
00228 }
00229
00230 static int tcl_isexempt STDVAR
00231 {
00232 struct chanset_t *chan;
00233 int ok = 0;
00234
00235 BADARGS(2, 3, " exempt ?channel?");
00236
00237 if (argc == 3) {
00238 chan = findchan_by_dname(argv[2]);
00239 if (!chan) {
00240 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00241 return TCL_ERROR;
00242 }
00243 if (u_equals_mask(chan->exempts, argv[1]))
00244 ok = 1;
00245 }
00246 if (u_equals_mask(global_exempts, argv[1]))
00247 ok = 1;
00248 if (ok)
00249 Tcl_AppendResult(irp, "1", NULL);
00250 else
00251 Tcl_AppendResult(irp, "0", NULL);
00252 return TCL_OK;
00253 }
00254
00255 static int tcl_isinvite STDVAR
00256 {
00257 struct chanset_t *chan;
00258 int ok = 0;
00259
00260 BADARGS(2, 3, " invite ?channel?");
00261
00262 if (argc == 3) {
00263 chan = findchan_by_dname(argv[2]);
00264 if (!chan) {
00265 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00266 return TCL_ERROR;
00267 }
00268 if (u_equals_mask(chan->invites, argv[1]))
00269 ok = 1;
00270 }
00271 if (u_equals_mask(global_invites, argv[1]))
00272 ok = 1;
00273 if (ok)
00274 Tcl_AppendResult(irp, "1", NULL);
00275 else
00276 Tcl_AppendResult(irp, "0", NULL);
00277 return TCL_OK;
00278 }
00279
00280
00281 static int tcl_isbansticky STDVAR
00282 {
00283 struct chanset_t *chan;
00284 int ok = 0;
00285
00286 BADARGS(2, 3, " ban ?channel?");
00287
00288 if (argc == 3) {
00289 chan = findchan_by_dname(argv[2]);
00290 if (!chan) {
00291 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00292 return TCL_ERROR;
00293 }
00294 if (u_sticky_mask(chan->bans, argv[1]))
00295 ok = 1;
00296 }
00297 if (u_sticky_mask(global_bans, argv[1]))
00298 ok = 1;
00299 if (ok)
00300 Tcl_AppendResult(irp, "1", NULL);
00301 else
00302 Tcl_AppendResult(irp, "0", NULL);
00303 return TCL_OK;
00304 }
00305
00306 static int tcl_isexemptsticky STDVAR
00307 {
00308 struct chanset_t *chan;
00309 int ok = 0;
00310
00311 BADARGS(2, 3, " exempt ?channel?");
00312
00313 if (argc == 3) {
00314 chan = findchan_by_dname(argv[2]);
00315 if (!chan) {
00316 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00317 return TCL_ERROR;
00318 }
00319 if (u_sticky_mask(chan->exempts, argv[1]))
00320 ok = 1;
00321 }
00322 if (u_sticky_mask(global_exempts, argv[1]))
00323 ok = 1;
00324 if (ok)
00325 Tcl_AppendResult(irp, "1", NULL);
00326 else
00327 Tcl_AppendResult(irp, "0", NULL);
00328 return TCL_OK;
00329 }
00330
00331 static int tcl_isinvitesticky STDVAR
00332 {
00333 struct chanset_t *chan;
00334 int ok = 0;
00335
00336 BADARGS(2, 3, " invite ?channel?");
00337
00338 if (argc == 3) {
00339 chan = findchan_by_dname(argv[2]);
00340 if (!chan) {
00341 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00342 return TCL_ERROR;
00343 }
00344 if (u_sticky_mask(chan->invites, argv[1]))
00345 ok = 1;
00346 }
00347 if (u_sticky_mask(global_invites, argv[1]))
00348 ok = 1;
00349 if (ok)
00350 Tcl_AppendResult(irp, "1", NULL);
00351 else
00352 Tcl_AppendResult(irp, "0", NULL);
00353 return TCL_OK;
00354 }
00355
00356 static int tcl_ispermban STDVAR
00357 {
00358 struct chanset_t *chan;
00359 int ok = 0;
00360
00361 BADARGS(2, 3, " ban ?channel?");
00362
00363 if (argc == 3) {
00364 chan = findchan_by_dname(argv[2]);
00365 if (chan == NULL) {
00366 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00367 return TCL_ERROR;
00368 }
00369 if (u_equals_mask(chan->bans, argv[1]) == 2)
00370 ok = 1;
00371 }
00372 if (u_equals_mask(global_bans, argv[1]) == 2)
00373 ok = 1;
00374 if (ok)
00375 Tcl_AppendResult(irp, "1", NULL);
00376 else
00377 Tcl_AppendResult(irp, "0", NULL);
00378 return TCL_OK;
00379 }
00380
00381 static int tcl_ispermexempt STDVAR
00382 {
00383 struct chanset_t *chan;
00384 int ok = 0;
00385
00386 BADARGS(2, 3, " exempt ?channel?");
00387
00388 if (argc == 3) {
00389 chan = findchan_by_dname(argv[2]);
00390 if (chan == NULL) {
00391 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00392 return TCL_ERROR;
00393 }
00394 if (u_equals_mask(chan->exempts, argv[1]) == 2)
00395 ok = 1;
00396 }
00397 if (u_equals_mask(global_exempts, argv[1]) == 2)
00398 ok = 1;
00399 if (ok)
00400 Tcl_AppendResult(irp, "1", NULL);
00401 else
00402 Tcl_AppendResult(irp, "0", NULL);
00403 return TCL_OK;
00404 }
00405
00406 static int tcl_isperminvite STDVAR
00407 {
00408 struct chanset_t *chan;
00409 int ok = 0;
00410
00411 BADARGS(2, 3, " invite ?channel?");
00412
00413 if (argc == 3) {
00414 chan = findchan_by_dname(argv[2]);
00415 if (chan == NULL) {
00416 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00417 return TCL_ERROR;
00418 }
00419 if (u_equals_mask(chan->invites, argv[1]) == 2)
00420 ok = 1;
00421 }
00422 if (u_equals_mask(global_invites, argv[1]) == 2)
00423 ok = 1;
00424 if (ok)
00425 Tcl_AppendResult(irp, "1", NULL);
00426 else
00427 Tcl_AppendResult(irp, "0", NULL);
00428 return TCL_OK;
00429 }
00430
00431 static int tcl_matchban STDVAR
00432 {
00433 struct chanset_t *chan;
00434 int ok = 0;
00435
00436 BADARGS(2, 3, " user!nick@host ?channel?");
00437
00438 if (argc == 3) {
00439 chan = findchan_by_dname(argv[2]);
00440 if (chan == NULL) {
00441 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00442 return TCL_ERROR;
00443 }
00444 if (u_match_mask(chan->bans, argv[1]))
00445 ok = 1;
00446 }
00447 if (u_match_mask(global_bans, argv[1]))
00448 ok = 1;
00449 if (ok)
00450 Tcl_AppendResult(irp, "1", NULL);
00451 else
00452 Tcl_AppendResult(irp, "0", NULL);
00453 return TCL_OK;
00454 }
00455
00456 static int tcl_matchexempt STDVAR
00457 {
00458 struct chanset_t *chan;
00459 int ok = 0;
00460
00461 BADARGS(2, 3, " user!nick@host ?channel?");
00462
00463 if (argc == 3) {
00464 chan = findchan_by_dname(argv[2]);
00465 if (chan == NULL) {
00466 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00467 return TCL_ERROR;
00468 }
00469 if (u_match_mask(chan->exempts, argv[1]))
00470 ok = 1;
00471 }
00472 if (u_match_mask(global_exempts, argv[1]))
00473 ok = 1;
00474 if (ok)
00475 Tcl_AppendResult(irp, "1", NULL);
00476 else
00477 Tcl_AppendResult(irp, "0", NULL);
00478 return TCL_OK;
00479 }
00480
00481 static int tcl_matchinvite STDVAR
00482 {
00483 struct chanset_t *chan;
00484 int ok = 0;
00485
00486 BADARGS(2, 3, " user!nick@host ?channel?");
00487
00488 if (argc == 3) {
00489 chan = findchan_by_dname(argv[2]);
00490 if (chan == NULL) {
00491 Tcl_AppendResult(irp, "invalid channel: ", argv[2], NULL);
00492 return TCL_ERROR;
00493 }
00494 if (u_match_mask(chan->invites, argv[1]))
00495 ok = 1;
00496 }
00497 if (u_match_mask(global_invites, argv[1]))
00498 ok = 1;
00499 if (ok)
00500 Tcl_AppendResult(irp, "1", NULL);
00501 else
00502 Tcl_AppendResult(irp, "0", NULL);
00503 return TCL_OK;
00504 }
00505
00506 static int tcl_newchanban STDVAR
00507 {
00508 time_t expire_time;
00509 struct chanset_t *chan;
00510 char ban[161], cmt[MASKREASON_LEN], from[HANDLEN + 1];
00511 int sticky = 0;
00512 module_entry *me;
00513
00514 BADARGS(5, 7, " channel ban creator comment ?lifetime? ?options?");
00515
00516 chan = findchan_by_dname(argv[1]);
00517 if (chan == NULL) {
00518 Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
00519 return TCL_ERROR;
00520 }
00521 if (argc == 7) {
00522 if (!egg_strcasecmp(argv[6], "none"));
00523 else if (!egg_strcasecmp(argv[6], "sticky"))
00524 sticky = 1;
00525 else {
00526 Tcl_AppendResult(irp, "invalid option ", argv[6], " (must be one of: ",
00527 "sticky, none)", NULL);
00528 return TCL_ERROR;
00529 }
00530 }
00531 strncpyz(ban, argv[2], sizeof ban);
00532 strncpyz(from, argv[3], sizeof from);
00533 strncpyz(cmt, argv[4], sizeof cmt);
00534 if (argc == 5) {
00535 if (chan->ban_time == 0)
00536 expire_time = 0L;
00537 else
00538 expire_time = now + (60 * chan->ban_time);
00539 } else {
00540 if (atoi(argv[5]) == 0)
00541 expire_time = 0L;
00542 else
00543 expire_time = now + (atoi(argv[5]) * 60);
00544 }
00545 if (u_addban(chan, ban, from, cmt, expire_time, sticky))
00546 if ((me = module_find("irc", 0, 0)))
00547 (me->funcs[IRC_CHECK_THIS_BAN]) (chan, ban, sticky);
00548 return TCL_OK;
00549 }
00550
00551 static int tcl_newban STDVAR
00552 {
00553 time_t expire_time;
00554 struct chanset_t *chan;
00555 char ban[UHOSTLEN], cmt[MASKREASON_LEN], from[HANDLEN + 1];
00556 int sticky = 0;
00557 module_entry *me;
00558
00559 BADARGS(4, 6, " ban creator comment ?lifetime? ?options?");
00560
00561 if (argc == 6) {
00562 if (!egg_strcasecmp(argv[5], "none"));
00563 else if (!egg_strcasecmp(argv[5], "sticky"))
00564 sticky = 1;
00565 else {
00566 Tcl_AppendResult(irp, "invalid option ", argv[5], " (must be one of: ",
00567 "sticky, none)", NULL);
00568 return TCL_ERROR;
00569 }
00570 }
00571 strncpyz(ban, argv[1], sizeof ban);
00572 strncpyz(from, argv[2], sizeof from);
00573 strncpyz(cmt, argv[3], sizeof cmt);
00574 if (argc == 4) {
00575 if (global_ban_time == 0)
00576 expire_time = 0L;
00577 else
00578 expire_time = now + (60 * global_ban_time);
00579 } else {
00580 if (atoi(argv[4]) == 0)
00581 expire_time = 0L;
00582 else
00583 expire_time = now + (atoi(argv[4]) * 60);
00584 }
00585 if (u_addban(NULL, ban, from, cmt, expire_time, sticky))
00586 if ((me = module_find("irc", 0, 0)))
00587 for (chan = chanset; chan != NULL; chan = chan->next)
00588 (me->funcs[IRC_CHECK_THIS_BAN]) (chan, ban, sticky);
00589 return TCL_OK;
00590 }
00591
00592 static int tcl_newchanexempt STDVAR
00593 {
00594 time_t expire_time;
00595 struct chanset_t *chan;
00596 char exempt[161], cmt[MASKREASON_LEN], from[HANDLEN + 1];
00597 int sticky = 0;
00598
00599 BADARGS(5, 7, " channel exempt creator comment ?lifetime? ?options?");
00600
00601 chan = findchan_by_dname(argv[1]);
00602 if (chan == NULL) {
00603 Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
00604 return TCL_ERROR;
00605 }
00606 if (argc == 7) {
00607 if (!egg_strcasecmp(argv[6], "none"));
00608 else if (!egg_strcasecmp(argv[6], "sticky"))
00609 sticky = 1;
00610 else {
00611 Tcl_AppendResult(irp, "invalid option ", argv[6], " (must be one of: ",
00612 "sticky, none)", NULL);
00613 return TCL_ERROR;
00614 }
00615 }
00616 strncpyz(exempt, argv[2], sizeof exempt);
00617 strncpyz(from, argv[3], sizeof from);
00618 strncpyz(cmt, argv[4], sizeof cmt);
00619 if (argc == 5) {
00620 if (chan->exempt_time == 0)
00621 expire_time = 0L;
00622 else
00623 expire_time = now + (60 * chan->exempt_time);
00624 } else {
00625 if (atoi(argv[5]) == 0)
00626 expire_time = 0L;
00627 else
00628 expire_time = now + (atoi(argv[5]) * 60);
00629 }
00630 if (u_addexempt(chan, exempt, from, cmt, expire_time, sticky))
00631 add_mode(chan, '+', 'e', exempt);
00632 return TCL_OK;
00633 }
00634
00635 static int tcl_newexempt STDVAR
00636 {
00637 time_t expire_time;
00638 struct chanset_t *chan;
00639 char exempt[UHOSTLEN], cmt[MASKREASON_LEN], from[HANDLEN + 1];
00640 int sticky = 0;
00641
00642 BADARGS(4, 6, " exempt creator comment ?lifetime? ?options?");
00643
00644 if (argc == 6) {
00645 if (!egg_strcasecmp(argv[5], "none"));
00646 else if (!egg_strcasecmp(argv[5], "sticky"))
00647 sticky = 1;
00648 else {
00649 Tcl_AppendResult(irp, "invalid option ", argv[5], " (must be one of: ",
00650 "sticky, none)", NULL);
00651 return TCL_ERROR;
00652 }
00653 }
00654 strncpyz(exempt, argv[1], sizeof exempt);
00655 strncpyz(from, argv[2], sizeof from);
00656 strncpyz(cmt, argv[3], sizeof cmt);
00657 if (argc == 4) {
00658 if (global_exempt_time == 0)
00659 expire_time = 0L;
00660 else
00661 expire_time = now + (60 * global_exempt_time);
00662 } else {
00663 if (atoi(argv[4]) == 0)
00664 expire_time = 0L;
00665 else
00666 expire_time = now + (atoi(argv[4]) * 60);
00667 }
00668 u_addexempt(NULL, exempt, from, cmt, expire_time, sticky);
00669 for (chan = chanset; chan; chan = chan->next)
00670 add_mode(chan, '+', 'e', exempt);
00671 return TCL_OK;
00672 }
00673
00674 static int tcl_newchaninvite STDVAR
00675 {
00676 time_t expire_time;
00677 struct chanset_t *chan;
00678 char invite[161], cmt[MASKREASON_LEN], from[HANDLEN + 1];
00679 int sticky = 0;
00680
00681 BADARGS(5, 7, " channel invite creator comment ?lifetime? ?options?");
00682
00683 chan = findchan_by_dname(argv[1]);
00684 if (chan == NULL) {
00685 Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
00686 return TCL_ERROR;
00687 }
00688 if (argc == 7) {
00689 if (!egg_strcasecmp(argv[6], "none"));
00690 else if (!egg_strcasecmp(argv[6], "sticky"))
00691 sticky = 1;
00692 else {
00693 Tcl_AppendResult(irp, "invalid option ", argv[6], " (must be one of: ",
00694 "sticky, none)", NULL);
00695 return TCL_ERROR;
00696 }
00697 }
00698 strncpyz(invite, argv[2], sizeof invite);
00699 strncpyz(from, argv[3], sizeof from);
00700 strncpyz(cmt, argv[4], sizeof cmt);
00701 if (argc == 5) {
00702 if (chan->invite_time == 0)
00703 expire_time = 0L;
00704 else
00705 expire_time = now + (60 * chan->invite_time);
00706 } else {
00707 if (atoi(argv[5]) == 0)
00708 expire_time = 0L;
00709 else
00710 expire_time = now + (atoi(argv[5]) * 60);
00711 }
00712 if (u_addinvite(chan, invite, from, cmt, expire_time, sticky))
00713 add_mode(chan, '+', 'I', invite);
00714 return TCL_OK;
00715 }
00716
00717 static int tcl_newinvite STDVAR
00718 {
00719 time_t expire_time;
00720 struct chanset_t *chan;
00721 char invite[UHOSTLEN], cmt[MASKREASON_LEN], from[HANDLEN + 1];
00722 int sticky = 0;
00723
00724 BADARGS(4, 6, " invite creator comment ?lifetime? ?options?");
00725
00726 if (argc == 6) {
00727 if (!egg_strcasecmp(argv[5], "none"));
00728 else if (!egg_strcasecmp(argv[5], "sticky"))
00729 sticky = 1;
00730 else {
00731 Tcl_AppendResult(irp, "invalid option ", argv[5], " (must be one of: ",
00732 "sticky, none)", NULL);
00733 return TCL_ERROR;
00734 }
00735 }
00736 strncpyz(invite, argv[1], sizeof invite);
00737 strncpyz(from, argv[2], sizeof from);
00738 strncpyz(cmt, argv[3], sizeof cmt);
00739 if (argc == 4) {
00740 if (global_invite_time == 0)
00741 expire_time = 0L;
00742 else
00743 expire_time = now + (60 * global_invite_time);
00744 } else {
00745 if (atoi(argv[4]) == 0)
00746 expire_time = 0L;
00747 else
00748 expire_time = now + (atoi(argv[4]) * 60);
00749 }
00750 u_addinvite(NULL, invite, from, cmt, expire_time, sticky);
00751 for (chan = chanset; chan; chan = chan->next)
00752 add_mode(chan, '+', 'I', invite);
00753 return TCL_OK;
00754 }
00755
00756 static int tcl_channel_info(Tcl_Interp *irp, struct chanset_t *chan)
00757 {
00758 char a[121], b[121], s[121];
00759 EGG_CONST char *args[2];
00760 struct udef_struct *ul;
00761
00762 get_mode_protect(chan, s);
00763 Tcl_AppendElement(irp, s);
00764 simple_sprintf(s, "%d", chan->idle_kick);
00765 Tcl_AppendElement(irp, s);
00766 simple_sprintf(s, "%d", chan->stopnethack_mode);
00767 Tcl_AppendElement(irp, s);
00768 simple_sprintf(s, "%d", chan->revenge_mode);
00769 Tcl_AppendElement(irp, s);
00770 Tcl_AppendElement(irp, chan->need_op);
00771 Tcl_AppendElement(irp, chan->need_invite);
00772 Tcl_AppendElement(irp, chan->need_key);
00773 Tcl_AppendElement(irp, chan->need_unban);
00774 Tcl_AppendElement(irp, chan->need_limit);
00775 simple_sprintf(s, "%d:%d", chan->flood_pub_thr, chan->flood_pub_time);
00776 Tcl_AppendElement(irp, s);
00777 simple_sprintf(s, "%d:%d", chan->flood_ctcp_thr, chan->flood_ctcp_time);
00778 Tcl_AppendElement(irp, s);
00779 simple_sprintf(s, "%d:%d", chan->flood_join_thr, chan->flood_join_time);
00780 Tcl_AppendElement(irp, s);
00781 simple_sprintf(s, "%d:%d", chan->flood_kick_thr, chan->flood_kick_time);
00782 Tcl_AppendElement(irp, s);
00783 simple_sprintf(s, "%d:%d", chan->flood_deop_thr, chan->flood_deop_time);
00784 Tcl_AppendElement(irp, s);
00785 simple_sprintf(s, "%d:%d", chan->flood_nick_thr, chan->flood_nick_time);
00786 Tcl_AppendElement(irp, s);
00787 simple_sprintf(s, "%d:%d", chan->aop_min, chan->aop_max);
00788 Tcl_AppendElement(irp, s);
00789 simple_sprintf(s, "%d", chan->ban_type);
00790 Tcl_AppendElement(irp, s);
00791 simple_sprintf(s, "%d", chan->ban_time);
00792 Tcl_AppendElement(irp, s);
00793 simple_sprintf(s, "%d", chan->exempt_time);
00794 Tcl_AppendElement(irp, s);
00795 simple_sprintf(s, "%d", chan->invite_time);
00796 Tcl_AppendElement(irp, s);
00797 if (chan->status & CHAN_ENFORCEBANS)
00798 Tcl_AppendElement(irp, "+enforcebans");
00799 else
00800 Tcl_AppendElement(irp, "-enforcebans");
00801 if (chan->status & CHAN_DYNAMICBANS)
00802 Tcl_AppendElement(irp, "+dynamicbans");
00803 else
00804 Tcl_AppendElement(irp, "-dynamicbans");
00805 if (chan->status & CHAN_NOUSERBANS)
00806 Tcl_AppendElement(irp, "-userbans");
00807 else
00808 Tcl_AppendElement(irp, "+userbans");
00809 if (chan->status & CHAN_OPONJOIN)
00810 Tcl_AppendElement(irp, "+autoop");
00811 else
00812 Tcl_AppendElement(irp, "-autoop");
00813 if (chan->status & CHAN_AUTOHALFOP)
00814 Tcl_AppendElement(irp, "+autohalfop");
00815 else
00816 Tcl_AppendElement(irp, "-autohalfop");
00817 if (chan->status & CHAN_BITCH)
00818 Tcl_AppendElement(irp, "+bitch");
00819 else
00820 Tcl_AppendElement(irp, "-bitch");
00821 if (chan->status & CHAN_GREET)
00822 Tcl_AppendElement(irp, "+greet");
00823 else
00824 Tcl_AppendElement(irp, "-greet");
00825 if (chan->status & CHAN_PROTECTOPS)
00826 Tcl_AppendElement(irp, "+protectops");
00827 else
00828 Tcl_AppendElement(irp, "-protectops");
00829 if (chan->status & CHAN_PROTECTHALFOPS)
00830 Tcl_AppendElement(irp, "+protecthalfops");
00831 else
00832 Tcl_AppendElement(irp, "-protecthalfops");
00833 if (chan->status & CHAN_PROTECTFRIENDS)
00834 Tcl_AppendElement(irp, "+protectfriends");
00835 else
00836 Tcl_AppendElement(irp, "-protectfriends");
00837 if (chan->status & CHAN_DONTKICKOPS)
00838 Tcl_AppendElement(irp, "+dontkickops");
00839 else
00840 Tcl_AppendElement(irp, "-dontkickops");
00841 if (chan->status & CHAN_INACTIVE)
00842 Tcl_AppendElement(irp, "+inactive");
00843 else
00844 Tcl_AppendElement(irp, "-inactive");
00845 if (chan->status & CHAN_LOGSTATUS)
00846 Tcl_AppendElement(irp, "+statuslog");
00847 else
00848 Tcl_AppendElement(irp, "-statuslog");
00849 if (chan->status & CHAN_REVENGE)
00850 Tcl_AppendElement(irp, "+revenge");
00851 else
00852 Tcl_AppendElement(irp, "-revenge");
00853 if (chan->status & CHAN_REVENGEBOT)
00854 Tcl_AppendElement(irp, "+revengebot");
00855 else
00856 Tcl_AppendElement(irp, "-revengebot");
00857 if (chan->status & CHAN_SECRET)
00858 Tcl_AppendElement(irp, "+secret");
00859 else
00860 Tcl_AppendElement(irp, "-secret");
00861 if (chan->status & CHAN_SHARED)
00862 Tcl_AppendElement(irp, "+shared");
00863 else
00864 Tcl_AppendElement(irp, "-shared");
00865 if (chan->status & CHAN_AUTOVOICE)
00866 Tcl_AppendElement(irp, "+autovoice");
00867 else
00868 Tcl_AppendElement(irp, "-autovoice");
00869 if (chan->status & CHAN_CYCLE)
00870 Tcl_AppendElement(irp, "+cycle");
00871 else
00872 Tcl_AppendElement(irp, "-cycle");
00873 if (chan->status & CHAN_SEEN)
00874 Tcl_AppendElement(irp, "+seen");
00875 else
00876 Tcl_AppendElement(irp, "-seen");
00877 if (chan->ircnet_status & CHAN_DYNAMICEXEMPTS)
00878 Tcl_AppendElement(irp, "+dynamicexempts");
00879 else
00880 Tcl_AppendElement(irp, "-dynamicexempts");
00881 if (chan->ircnet_status & CHAN_NOUSEREXEMPTS)
00882 Tcl_AppendElement(irp, "-userexempts");
00883 else
00884 Tcl_AppendElement(irp, "+userexempts");
00885 if (chan->ircnet_status & CHAN_DYNAMICINVITES)
00886 Tcl_AppendElement(irp, "+dynamicinvites");
00887 else
00888 Tcl_AppendElement(irp, "-dynamicinvites");
00889 if (chan->ircnet_status & CHAN_NOUSERINVITES)
00890 Tcl_AppendElement(irp, "-userinvites");
00891 else
00892 Tcl_AppendElement(irp, "+userinvites");
00893 if (chan->status & CHAN_NODESYNCH)
00894 Tcl_AppendElement(irp, "+nodesynch");
00895 else
00896 Tcl_AppendElement(irp, "-nodesynch");
00897 if (chan->status & CHAN_STATIC)
00898 Tcl_AppendElement(irp, "+static");
00899 else
00900 Tcl_AppendElement(irp, "-static");
00901 for (ul = udef; ul; ul = ul->next) {
00902
00903 if (!ul->defined || !ul->name)
00904 continue;
00905
00906 if (ul->type == UDEF_FLAG) {
00907 simple_sprintf(s, "%c%s", getudef(ul->values, chan->dname) ? '+' : '-',
00908 ul->name);
00909 Tcl_AppendElement(irp, s);
00910 } else if (ul->type == UDEF_INT) {
00911 char *x;
00912
00913 egg_snprintf(a, sizeof a, "%s", ul->name);
00914 egg_snprintf(b, sizeof b, "%d", getudef(ul->values, chan->dname));
00915 args[0] = a;
00916 args[1] = b;
00917 x = Tcl_Merge(2, args);
00918 egg_snprintf(s, sizeof s, "%s", x);
00919 Tcl_Free((char *) x);
00920 Tcl_AppendElement(irp, s);
00921 } else if (ul->type == UDEF_STR) {
00922 char *p = (char *) getudef(ul->values, chan->dname), *buf;
00923
00924 if (!p)
00925 p = "{}";
00926
00927 buf = nmalloc(strlen(ul->name) + strlen(p) + 2);
00928 simple_sprintf(buf, "%s %s", ul->name, p);
00929 Tcl_AppendElement(irp, buf);
00930 nfree(buf);
00931 } else
00932 debug1("UDEF-ERROR: unknown type %d", ul->type);
00933 }
00934 return TCL_OK;
00935 }
00936
00937 static int tcl_channel_get(Tcl_Interp *irp, struct chanset_t *chan,
00938 char *setting)
00939 {
00940 char s[121], *str = NULL;
00941 EGG_CONST char **argv = NULL;
00942 int argc = 0;
00943 struct udef_struct *ul;
00944
00945 if (!strcmp(setting, "chanmode"))
00946 get_mode_protect(chan, s);
00947 else if (!strcmp(setting, "need-op")) {
00948 strncpy(s, chan->need_op, 120);
00949 s[120] = 0;
00950 } else if (!strcmp(setting, "need-invite")) {
00951 strncpy(s, chan->need_invite, 120);
00952 s[120] = 0;
00953 } else if (!strcmp(setting, "need-key")) {
00954 strncpy(s, chan->need_key, 120);
00955 s[120] = 0;
00956 } else if (!strcmp(setting, "need-unban")) {
00957 strncpy(s, chan->need_unban, 120);
00958 s[120] = 0;
00959 } else if (!strcmp(setting, "need-limit")) {
00960 strncpy(s, chan->need_limit, 120);
00961 s[120] = 0;
00962 } else if (!strcmp(setting, "idle-kick"))
00963 simple_sprintf(s, "%d", chan->idle_kick);
00964 else if (!strcmp(setting, "stopnethack-mode") || !strcmp(setting, "stop-net-hack"))
00965 simple_sprintf(s, "%d", chan->stopnethack_mode);
00966 else if (!strcmp(setting, "revenge-mode"))
00967 simple_sprintf(s, "%d", chan->revenge_mode);
00968 else if (!strcmp(setting, "ban-type"))
00969 simple_sprintf(s, "%d", chan->ban_type);
00970 else if (!strcmp(setting, "ban-time"))
00971 simple_sprintf(s, "%d", chan->ban_time);
00972 else if (!strcmp(setting, "exempt-time"))
00973 simple_sprintf(s, "%d", chan->exempt_time);
00974 else if (!strcmp(setting, "invite-time"))
00975 simple_sprintf(s, "%d", chan->invite_time);
00976 else if (!strcmp(setting, "flood-chan"))
00977 simple_sprintf(s, "%d %d", chan->flood_pub_thr, chan->flood_pub_time);
00978 else if (!strcmp(setting, "flood-ctcp"))
00979 simple_sprintf(s, "%d %d", chan->flood_ctcp_thr, chan->flood_ctcp_time);
00980 else if (!strcmp(setting, "flood-join"))
00981 simple_sprintf(s, "%d %d", chan->flood_join_thr, chan->flood_join_time);
00982 else if (!strcmp(setting, "flood-kick"))
00983 simple_sprintf(s, "%d %d", chan->flood_kick_thr, chan->flood_kick_time);
00984 else if (!strcmp(setting, "flood-deop"))
00985 simple_sprintf(s, "%d %d", chan->flood_deop_thr, chan->flood_deop_time);
00986 else if (!strcmp(setting, "flood-nick"))
00987 simple_sprintf(s, "%d %d", chan->flood_nick_thr, chan->flood_nick_time);
00988 else if (!strcmp(setting, "aop-delay"))
00989 simple_sprintf(s, "%d %d", chan->aop_min, chan->aop_max);
00990 else if CHKFLAG_POS(CHAN_ENFORCEBANS, "enforcebans", chan->status)
00991 else if CHKFLAG_POS(CHAN_DYNAMICBANS, "dynamicbans", chan->status)
00992 else if CHKFLAG_NEG(CHAN_NOUSERBANS, "userbans", chan->status)
00993 else if CHKFLAG_POS(CHAN_OPONJOIN, "autoop", chan->status)
00994 else if CHKFLAG_POS(CHAN_AUTOHALFOP, "autohalfop", chan->status)
00995 else if CHKFLAG_POS(CHAN_BITCH, "bitch", chan->status)
00996 else if CHKFLAG_POS(CHAN_GREET, "greet", chan->status)
00997 else if CHKFLAG_POS(CHAN_PROTECTOPS, "protectops", chan->status)
00998 else if CHKFLAG_POS(CHAN_PROTECTHALFOPS, "protecthalfops", chan->status)
00999 else if CHKFLAG_POS(CHAN_PROTECTFRIENDS, "protectfriends", chan->status)
01000 else if CHKFLAG_POS(CHAN_DONTKICKOPS, "dontkickops", chan->status)
01001 else if CHKFLAG_POS(CHAN_INACTIVE, "inactive", chan->status)
01002 else if CHKFLAG_POS(CHAN_LOGSTATUS, "statuslog", chan->status)
01003 else if CHKFLAG_POS(CHAN_REVENGE, "revenge", chan->status)
01004 else if CHKFLAG_POS(CHAN_REVENGEBOT, "revengebot", chan->status)
01005 else if CHKFLAG_POS(CHAN_SECRET, "secret", chan->status)
01006 else if CHKFLAG_POS(CHAN_SHARED, "shared", chan->status)
01007 else if CHKFLAG_POS(CHAN_AUTOVOICE, "autovoice", chan->status)
01008 else if CHKFLAG_POS(CHAN_CYCLE, "cycle", chan->status)
01009 else if CHKFLAG_POS(CHAN_SEEN, "seen", chan->status)
01010 else if CHKFLAG_POS(CHAN_NODESYNCH, "nodesynch", chan->status)
01011 else if CHKFLAG_POS(CHAN_STATIC, "static", chan->status)
01012 else if CHKFLAG_POS(CHAN_DYNAMICEXEMPTS, "dynamicexempts",
01013 chan->ircnet_status)
01014 else if CHKFLAG_NEG(CHAN_NOUSEREXEMPTS, "userexempts",
01015 chan->ircnet_status)
01016 else if CHKFLAG_POS(CHAN_DYNAMICINVITES, "dynamicinvites",
01017 chan->ircnet_status)
01018 else if CHKFLAG_NEG(CHAN_NOUSERINVITES, "userinvites",
01019 chan->ircnet_status)
01020 else {
01021
01022 for (ul = udef; ul && ul->name; ul = ul->next) {
01023 if (!strcmp(setting, ul->name))
01024 break;
01025 }
01026 if (!ul || !ul->name) {
01027
01028 Tcl_AppendResult(irp, "Unknown channel setting.", NULL);
01029 return TCL_ERROR;
01030 }
01031
01032 if (ul->type == UDEF_STR) {
01033 str = (char *) getudef(ul->values, chan->dname);
01034 if (!str)
01035 str = "{}";
01036 Tcl_SplitList(irp, str, &argc, &argv);
01037 if (argc > 0)
01038 Tcl_AppendResult(irp, argv[0], NULL);
01039 Tcl_Free((char *) argv);
01040 } else {
01041
01042 simple_sprintf(s, "%d", getudef(ul->values, chan->dname));
01043 Tcl_AppendResult(irp, s, NULL);
01044 }
01045 return TCL_OK;
01046 }
01047
01048
01049 Tcl_AppendResult(irp, s, NULL);
01050 return TCL_OK;
01051 }
01052
01053
01054 static int tcl_channel STDVAR
01055 {
01056 struct chanset_t *chan;
01057
01058 BADARGS(2, -1, " command ?options?");
01059
01060 if (!strcmp(argv[1], "add")) {
01061 BADARGS(3, 4, " add channel-name ?options-list?");
01062
01063 if (argc == 3)
01064 return tcl_channel_add(irp, argv[2], "");
01065 return tcl_channel_add(irp, argv[2], argv[3]);
01066 }
01067 if (!strcmp(argv[1], "set")) {
01068 BADARGS(3, -1, " set channel-name ?options?");
01069
01070 chan = findchan_by_dname(argv[2]);
01071 if (chan == NULL) {
01072 if (chan_hack == 1)
01073 return TCL_OK;
01074
01075
01076 Tcl_AppendResult(irp, "no such channel record", NULL);
01077 return TCL_ERROR;
01078 }
01079 return tcl_channel_modify(irp, chan, argc - 3, &argv[3]);
01080 }
01081 if (!strcmp(argv[1], "get")) {
01082 BADARGS(4, 4, " get channel-name setting-name");
01083
01084 chan = findchan_by_dname(argv[2]);
01085 if (chan == NULL) {
01086 Tcl_AppendResult(irp, "no such channel record", NULL);
01087 return TCL_ERROR;
01088 }
01089 return (tcl_channel_get(irp, chan, argv[3]));
01090 }
01091 if (!strcmp(argv[1], "info")) {
01092 BADARGS(3, 3, " info channel-name");
01093
01094 chan = findchan_by_dname(argv[2]);
01095 if (chan == NULL) {
01096 Tcl_AppendResult(irp, "no such channel record", NULL);
01097 return TCL_ERROR;
01098 }
01099 return tcl_channel_info(irp, chan);
01100 }
01101 if (!strcmp(argv[1], "remove")) {
01102 BADARGS(3, 3, " remove channel-name");
01103
01104 chan = findchan_by_dname(argv[2]);
01105 if (chan == NULL) {
01106 Tcl_AppendResult(irp, "no such channel record", NULL);
01107 return TCL_ERROR;
01108 }
01109 remove_channel(chan);
01110 return TCL_OK;
01111 }
01112 Tcl_AppendResult(irp, "unknown channel command: should be one of: ",
01113 "add, set, get, info, remove", NULL);
01114 return TCL_ERROR;
01115 }
01116
01117
01118 static int tcl_channel_modify(Tcl_Interp *irp, struct chanset_t *chan,
01119 int items, char **item)
01120 {
01121 int i, x = 0, found, old_status = chan->status,
01122 old_mode_mns_prot = chan->mode_mns_prot,
01123 old_mode_pls_prot = chan->mode_pls_prot;
01124 struct udef_struct *ul = udef;
01125 char s[121];
01126 module_entry *me;
01127
01128 for (i = 0; i < items; i++) {
01129 if (!strcmp(item[i], "need-op")) {
01130 i++;
01131 if (i >= items) {
01132 if (irp)
01133 Tcl_AppendResult(irp, "channel need-op needs argument", NULL);
01134 return TCL_ERROR;
01135 }
01136 strncpy(chan->need_op, item[i], 120);
01137 chan->need_op[120] = 0;
01138 } else if (!strcmp(item[i], "need-invite")) {
01139 i++;
01140 if (i >= items) {
01141 if (irp)
01142 Tcl_AppendResult(irp, "channel need-invite needs argument", NULL);
01143 return TCL_ERROR;
01144 }
01145 strncpy(chan->need_invite, item[i], 120);
01146 chan->need_invite[120] = 0;
01147 } else if (!strcmp(item[i], "need-key")) {
01148 i++;
01149 if (i >= items) {
01150 if (irp)
01151 Tcl_AppendResult(irp, "channel need-key needs argument", NULL);
01152 return TCL_ERROR;
01153 }
01154 strncpy(chan->need_key, item[i], 120);
01155 chan->need_key[120] = 0;
01156 } else if (!strcmp(item[i], "need-limit")) {
01157 i++;
01158 if (i >= items) {
01159 if (irp)
01160 Tcl_AppendResult(irp, "channel need-limit needs argument", NULL);
01161 return TCL_ERROR;
01162 }
01163 strncpy(chan->need_limit, item[i], 120);
01164 chan->need_limit[120] = 0;
01165 } else if (!strcmp(item[i], "need-unban")) {
01166 i++;
01167 if (i >= items) {
01168 if (irp)
01169 Tcl_AppendResult(irp, "channel need-unban needs argument", NULL);
01170 return TCL_ERROR;
01171 }
01172 strncpy(chan->need_unban, item[i], 120);
01173 chan->need_unban[120] = 0;
01174 } else if (!strcmp(item[i], "chanmode")) {
01175 i++;
01176 if (i >= items) {
01177 if (irp)
01178 Tcl_AppendResult(irp, "channel chanmode needs argument", NULL);
01179 return TCL_ERROR;
01180 }
01181 strncpy(s, item[i], 120);
01182 s[120] = 0;
01183 set_mode_protect(chan, s);
01184 } else if (!strcmp(item[i], "idle-kick")) {
01185 i++;
01186 if (i >= items) {
01187 if (irp)
01188 Tcl_AppendResult(irp, "channel idle-kick needs argument", NULL);
01189 return TCL_ERROR;
01190 }
01191 chan->idle_kick = atoi(item[i]);
01192 } else if (!strcmp(item[i], "dont-idle-kick"))
01193 chan->idle_kick = 0;
01194 else if (!strcmp(item[i], "stopnethack-mode")) {
01195 i++;
01196 if (i >= items) {
01197 if (irp)
01198 Tcl_AppendResult(irp, "channel stopnethack-mode needs argument",
01199 NULL);
01200 return TCL_ERROR;
01201 }
01202 chan->stopnethack_mode = atoi(item[i]);
01203 } else if (!strcmp(item[i], "revenge-mode")) {
01204 i++;
01205 if (i >= items) {
01206 if (irp)
01207 Tcl_AppendResult(irp, "channel revenge-mode needs argument", NULL);
01208 return TCL_ERROR;
01209 }
01210 chan->revenge_mode = atoi(item[i]);
01211 } else if (!strcmp(item[i], "ban-type")) {
01212 i++;
01213 if (i >= items) {
01214 if (irp)
01215 Tcl_AppendResult(irp, "channel ban-type needs argument", NULL);
01216 return TCL_ERROR;
01217 }
01218 chan->ban_type = atoi(item[i]);
01219 } else if (!strcmp(item[i], "ban-time")) {
01220 i++;
01221 if (i >= items) {
01222 if (irp)
01223 Tcl_AppendResult(irp, "channel ban-time needs argument", NULL);
01224 return TCL_ERROR;
01225 }
01226 chan->ban_time = atoi(item[i]);
01227 } else if (!strcmp(item[i], "exempt-time")) {
01228 i++;
01229 if (i >= items) {
01230 if (irp)
01231 Tcl_AppendResult(irp, "channel exempt-time needs argument", NULL);
01232 return TCL_ERROR;
01233 }
01234 chan->exempt_time = atoi(item[i]);
01235 } else if (!strcmp(item[i], "invite-time")) {
01236 i++;
01237 if (i >= items) {
01238 if (irp)
01239 Tcl_AppendResult(irp, "channel invite-time needs argument", NULL);
01240 return TCL_ERROR;
01241 }
01242 chan->invite_time = atoi(item[i]);
01243 } else if (!strcmp(item[i], "+enforcebans"))
01244 chan->status |= CHAN_ENFORCEBANS;
01245 else if (!strcmp(item[i], "-enforcebans"))
01246 chan->status &= ~CHAN_ENFORCEBANS;
01247 else if (!strcmp(item[i], "+dynamicbans"))
01248 chan->status |= CHAN_DYNAMICBANS;
01249 else if (!strcmp(item[i], "-dynamicbans"))
01250 chan->status &= ~CHAN_DYNAMICBANS;
01251 else if (!strcmp(item[i], "-userbans"))
01252 chan->status |= CHAN_NOUSERBANS;
01253 else if (!strcmp(item[i], "+userbans"))
01254 chan->status &= ~CHAN_NOUSERBANS;
01255 else if (!strcmp(item[i], "+autoop"))
01256 chan->status |= CHAN_OPONJOIN;
01257 else if (!strcmp(item[i], "-autoop"))
01258 chan->status &= ~CHAN_OPONJOIN;
01259 else if (!strcmp(item[i], "+autohalfop"))
01260 chan->status |= CHAN_AUTOHALFOP;
01261 else if (!strcmp(item[i], "-autohalfop"))
01262 chan->status &= ~CHAN_AUTOHALFOP;
01263 else if (!strcmp(item[i], "+bitch"))
01264 chan->status |= CHAN_BITCH;
01265 else if (!strcmp(item[i], "-bitch"))
01266 chan->status &= ~CHAN_BITCH;
01267 else if (!strcmp(item[i], "+nodesynch"))
01268 chan->status |= CHAN_NODESYNCH;
01269 else if (!strcmp(item[i], "-nodesynch"))
01270 chan->status &= ~CHAN_NODESYNCH;
01271 else if (!strcmp(item[i], "+greet"))
01272 chan->status |= CHAN_GREET;
01273 else if (!strcmp(item[i], "-greet"))
01274 chan->status &= ~CHAN_GREET;
01275 else if (!strcmp(item[i], "+protectops"))
01276 chan->status |= CHAN_PROTECTOPS;
01277 else if (!strcmp(item[i], "-protectops"))
01278 chan->status &= ~CHAN_PROTECTOPS;
01279 else if (!strcmp(item[i], "+protecthalfops"))
01280 chan->status |= CHAN_PROTECTHALFOPS;
01281 else if (!strcmp(item[i], "-protecthalfops"))
01282 chan->status &= ~CHAN_PROTECTHALFOPS;
01283 else if (!strcmp(item[i], "+protectfriends"))
01284 chan->status |= CHAN_PROTECTFRIENDS;
01285 else if (!strcmp(item[i], "-protectfriends"))
01286 chan->status &= ~CHAN_PROTECTFRIENDS;
01287 else if (!strcmp(item[i], "+dontkickops"))
01288 chan->status |= CHAN_DONTKICKOPS;
01289 else if (!strcmp(item[i], "-dontkickops"))
01290 chan->status &= ~CHAN_DONTKICKOPS;
01291 else if (!strcmp(item[i], "+inactive"))
01292 chan->status |= CHAN_INACTIVE;
01293 else if (!strcmp(item[i], "-inactive"))
01294 chan->status &= ~CHAN_INACTIVE;
01295 else if (!strcmp(item[i], "+statuslog"))
01296 chan->status |= CHAN_LOGSTATUS;
01297 else if (!strcmp(item[i], "-statuslog"))
01298 chan->status &= ~CHAN_LOGSTATUS;
01299 else if (!strcmp(item[i], "+revenge"))
01300 chan->status |= CHAN_REVENGE;
01301 else if (!strcmp(item[i], "-revenge"))
01302 chan->status &= ~CHAN_REVENGE;
01303 else if (!strcmp(item[i], "+revengebot"))
01304 chan->status |= CHAN_REVENGEBOT;
01305 else if (!strcmp(item[i], "-revengebot"))
01306 chan->status &= ~CHAN_REVENGEBOT;
01307 else if (!strcmp(item[i], "+secret"))
01308 chan->status |= CHAN_SECRET;
01309 else if (!strcmp(item[i], "-secret"))
01310 chan->status &= ~CHAN_SECRET;
01311 else if (!strcmp(item[i], "+shared"))
01312 chan->status |= CHAN_SHARED;
01313 else if (!strcmp(item[i], "-shared"))
01314 chan->status &= ~CHAN_SHARED;
01315 else if (!strcmp(item[i], "+autovoice"))
01316 chan->status |= CHAN_AUTOVOICE;
01317 else if (!strcmp(item[i], "-autovoice"))
01318 chan->status &= ~CHAN_AUTOVOICE;
01319 else if (!strcmp(item[i], "+cycle"))
01320 chan->status |= CHAN_CYCLE;
01321 else if (!strcmp(item[i], "-cycle"))
01322 chan->status &= ~CHAN_CYCLE;
01323 else if (!strcmp(item[i], "+seen"))
01324 chan->status |= CHAN_SEEN;
01325 else if (!strcmp(item[i], "-seen"))
01326 chan->status &= ~CHAN_SEEN;
01327 else if (!strcmp(item[i], "+static"))
01328 chan->status |= CHAN_STATIC;
01329 else if (!strcmp(item[i], "-static"))
01330 chan->status &= ~CHAN_STATIC;
01331 else if (!strcmp(item[i], "+dynamicexempts"))
01332 chan->ircnet_status |= CHAN_DYNAMICEXEMPTS;
01333 else if (!strcmp(item[i], "-dynamicexempts"))
01334 chan->ircnet_status &= ~CHAN_DYNAMICEXEMPTS;
01335 else if (!strcmp(item[i], "-userexempts"))
01336 chan->ircnet_status |= CHAN_NOUSEREXEMPTS;
01337 else if (!strcmp(item[i], "+userexempts"))
01338 chan->ircnet_status &= ~CHAN_NOUSEREXEMPTS;
01339 else if (!strcmp(item[i], "+dynamicinvites"))
01340 chan->ircnet_status |= CHAN_DYNAMICINVITES;
01341 else if (!strcmp(item[i], "-dynamicinvites"))
01342 chan->ircnet_status &= ~CHAN_DYNAMICINVITES;
01343 else if (!strcmp(item[i], "-userinvites"))
01344 chan->ircnet_status |= CHAN_NOUSERINVITES;
01345 else if (!strcmp(item[i], "+userinvites"))
01346 chan->ircnet_status &= ~CHAN_NOUSERINVITES;
01347
01348
01349 else if (!strcmp(item[i], "-stopnethack"));
01350 else if (!strcmp(item[i], "+stopnethack"));
01351 else if (!strcmp(item[i], "-wasoptest"));
01352 else if (!strcmp(item[i], "+wasoptest"));
01353 else if (!strcmp(item[i], "+clearbans"));
01354 else if (!strcmp(item[i], "-clearbans"));
01355 else if (!strncmp(item[i], "flood-", 6)) {
01356 int *pthr = 0, *ptime;
01357 char *p;
01358
01359 if (!strcmp(item[i] + 6, "chan")) {
01360 pthr = &chan->flood_pub_thr;
01361 ptime = &chan->flood_pub_time;
01362 } else if (!strcmp(item[i] + 6, "join")) {
01363 pthr = &chan->flood_join_thr;
01364 ptime = &chan->flood_join_time;
01365 } else if (!strcmp(item[i] + 6, "ctcp")) {
01366 pthr = &chan->flood_ctcp_thr;
01367 ptime = &chan->flood_ctcp_time;
01368 } else if (!strcmp(item[i] + 6, "kick")) {
01369 pthr = &chan->flood_kick_thr;
01370 ptime = &chan->flood_kick_time;
01371 } else if (!strcmp(item[i] + 6, "deop")) {
01372 pthr = &chan->flood_deop_thr;
01373 ptime = &chan->flood_deop_time;
01374 } else if (!strcmp(item[i] + 6, "nick")) {
01375 pthr = &chan->flood_nick_thr;
01376 ptime = &chan->flood_nick_time;
01377 } else {
01378 if (irp)
01379 Tcl_AppendResult(irp, "illegal channel flood type: ", item[i], NULL);
01380 return TCL_ERROR;
01381 }
01382 i++;
01383 if (i >= items) {
01384 if (irp)
01385 Tcl_AppendResult(irp, item[i - 1], " needs argument", NULL);
01386 return TCL_ERROR;
01387 }
01388 p = strchr(item[i], ':');
01389 if (p) {
01390 *p++ = 0;
01391 *pthr = atoi(item[i]);
01392 *ptime = atoi(p);
01393 *--p = ':';
01394 } else {
01395 *pthr = atoi(item[i]);
01396 *ptime = 1;
01397 }
01398 } else if (!strncmp(item[i], "aop-delay", 9)) {
01399 char *p;
01400
01401 i++;
01402 if (i >= items) {
01403 if (irp)
01404 Tcl_AppendResult(irp, item[i - 1], " needs argument", NULL);
01405 return TCL_ERROR;
01406 }
01407 p = strchr(item[i], ':');
01408 if (p) {
01409 p++;
01410 chan->aop_min = atoi(item[i]);
01411 chan->aop_max = atoi(p);
01412 } else {
01413 chan->aop_min = atoi(item[i]);
01414 chan->aop_max = chan->aop_min;
01415 }
01416 } else {
01417 if (!strncmp(item[i] + 1, "udef-flag-", 10))
01418 initudef(UDEF_FLAG, item[i] + 11, 0);
01419 else if (!strncmp(item[i], "udef-int-", 9))
01420 initudef(UDEF_INT, item[i] + 9, 0);
01421 else if (!strncmp(item[i], "udef-str-", 9))
01422 initudef(UDEF_STR, item[i] + 9, 0);
01423 found = 0;
01424 for (ul = udef; ul; ul = ul->next) {
01425 if (ul->type == UDEF_FLAG && (!egg_strcasecmp(item[i] + 1, ul->name) ||
01426 (!strncmp(item[i] + 1, "udef-flag-", 10) &&
01427 !egg_strcasecmp(item[i] + 11, ul->name)))) {
01428 if (item[i][0] == '+')
01429 setudef(ul, chan->dname, 1);
01430 else
01431 setudef(ul, chan->dname, 0);
01432 found = 1;
01433 break;
01434 } else if (ul->type == UDEF_INT && (!egg_strcasecmp(item[i], ul->name) ||
01435 (!strncmp(item[i], "udef-int-", 9) &&
01436 !egg_strcasecmp(item[i] + 9, ul->name)))) {
01437 i++;
01438 if (i >= items) {
01439 if (irp)
01440 Tcl_AppendResult(irp, "this setting needs an argument", NULL);
01441 return TCL_ERROR;
01442 }
01443 setudef(ul, chan->dname, atoi(item[i]));
01444 found = 1;
01445 break;
01446 } else if (ul->type == UDEF_STR &&
01447 (!egg_strcasecmp(item[i], ul->name) ||
01448 (!strncmp(item[i], "udef-str-", 9) &&
01449 !egg_strcasecmp(item[i] + 9, ul->name)))) {
01450 char *val;
01451
01452 i++;
01453 if (i >= items) {
01454 if (irp)
01455 Tcl_AppendResult(irp, "this setting needs an argument", NULL);
01456 return TCL_ERROR;
01457 }
01458 val = (char *) getudef(ul->values, chan->dname);
01459 if (val)
01460 nfree(val);
01461
01462
01463 val = nmalloc(3 * strlen(item[i]) + 10);
01464 convert_element(item[i], val);
01465 val = nrealloc(val, strlen(val) + 1);
01466 setudef(ul, chan->dname, (intptr_t) val);
01467 found = 1;
01468 break;
01469 }
01470 }
01471 if (!found) {
01472 if (irp && item[i][0])
01473 Tcl_AppendResult(irp, "illegal channel option: ", item[i], "\n", NULL);
01474 x++;
01475 }
01476 }
01477 }
01478
01479
01480
01481
01482
01483
01484 if (protect_readonly || chan_hack) {
01485 if (((old_status ^ chan->status) & CHAN_INACTIVE) &&
01486 module_find("irc", 0, 0)) {
01487 if (channel_inactive(chan) && (chan->status & (CHAN_ACTIVE | CHAN_PEND)))
01488 dprintf(DP_SERVER, "PART %s\n", chan->name);
01489 if (!channel_inactive(chan) &&
01490 !(chan->status & (CHAN_ACTIVE | CHAN_PEND))) {
01491 char *key;
01492
01493 key = chan->channel.key[0] ? chan->channel.key : chan->key_prot;
01494 if (key[0])
01495 dprintf(DP_SERVER, "JOIN %s %s\n",
01496 chan->name[0] ? chan->name : chan->dname, key);
01497 else
01498 dprintf(DP_SERVER, "JOIN %s\n",
01499 chan->name[0] ? chan->name : chan->dname);
01500 }
01501 }
01502 if ((old_status ^ chan->status) & (CHAN_ENFORCEBANS | CHAN_OPONJOIN |
01503 CHAN_BITCH | CHAN_AUTOVOICE |
01504 CHAN_AUTOHALFOP)) {
01505 if ((me = module_find("irc", 0, 0)))
01506 (me->funcs[IRC_RECHECK_CHANNEL]) (chan, 1);
01507 } else if (old_mode_pls_prot != chan->mode_pls_prot ||
01508 old_mode_mns_prot != chan->mode_mns_prot)
01509 if ((me = module_find("irc", 1, 2)))
01510 (me->funcs[IRC_RECHECK_CHANNEL_MODES]) (chan);
01511 }
01512 if (x > 0)
01513 return TCL_ERROR;
01514 return TCL_OK;
01515 }
01516
01517 static int tcl_do_masklist(maskrec *m, Tcl_Interp *irp)
01518 {
01519 char ts[21], ts1[21], ts2[21], *p;
01520 long tv;
01521 EGG_CONST char *list[6];
01522
01523 for (; m; m = m->next) {
01524 list[0] = m->mask;
01525 list[1] = m->desc;
01526
01527 tv = m->expire;
01528 sprintf(ts, "%lu", tv);
01529 list[2] = ts;
01530
01531 tv = m->added;
01532 sprintf(ts1, "%lu", tv);
01533 list[3] = ts1;
01534
01535 tv = m->lastactive;
01536 sprintf(ts2, "%lu", tv);
01537 list[4] = ts2;
01538
01539 list[5] = m->user;
01540 p = Tcl_Merge(6, list);
01541 Tcl_AppendElement(irp, p);
01542 Tcl_Free((char *) p);
01543 }
01544 return TCL_OK;
01545 }
01546
01547 static int tcl_banlist STDVAR
01548 {
01549 struct chanset_t *chan;
01550
01551 BADARGS(1, 2, " ?channel?");
01552
01553 if (argc == 2) {
01554 chan = findchan_by_dname(argv[1]);
01555 if (chan == NULL) {
01556 Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
01557 return TCL_ERROR;
01558 }
01559 return tcl_do_masklist(chan->bans, irp);
01560 }
01561
01562 return tcl_do_masklist(global_bans, irp);
01563 }
01564
01565 static int tcl_exemptlist STDVAR
01566 {
01567 struct chanset_t *chan;
01568
01569 BADARGS(1, 2, " ?channel?");
01570
01571 if (argc == 2) {
01572 chan = findchan_by_dname(argv[1]);
01573 if (chan == NULL) {
01574 Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
01575 return TCL_ERROR;
01576 }
01577 return tcl_do_masklist(chan->exempts, irp);
01578 }
01579
01580 return tcl_do_masklist(global_exempts, irp);
01581 }
01582
01583 static int tcl_invitelist STDVAR
01584 {
01585 struct chanset_t *chan;
01586
01587 BADARGS(1, 2, " ?channel?");
01588
01589 if (argc == 2) {
01590 chan = findchan_by_dname(argv[1]);
01591 if (chan == NULL) {
01592 Tcl_AppendResult(irp, "invalid channel: ", argv[1], NULL);
01593 return TCL_ERROR;
01594 }
01595 return tcl_do_masklist(chan->invites, irp);
01596 }
01597 return tcl_do_masklist(global_invites, irp);
01598 }
01599
01600 static int tcl_channels STDVAR
01601 {
01602 struct chanset_t *chan;
01603
01604 BADARGS(1, 1, "");
01605
01606 for (chan = chanset; chan; chan = chan->next)
01607 Tcl_AppendElement(irp, chan->dname);
01608 return TCL_OK;
01609 }
01610
01611 static int tcl_savechannels STDVAR
01612 {
01613 BADARGS(1, 1, "");
01614
01615 if (!chanfile[0]) {
01616 Tcl_AppendResult(irp, "no channel file", NULL);
01617 return TCL_ERROR;
01618 }
01619 write_channels();
01620 return TCL_OK;
01621 }
01622
01623 static int tcl_loadchannels STDVAR
01624 {
01625 BADARGS(1, 1, "");
01626
01627 if (!chanfile[0]) {
01628 Tcl_AppendResult(irp, "no channel file", NULL);
01629 return TCL_ERROR;
01630 }
01631 read_channels(1, 1);
01632 return TCL_OK;
01633 }
01634
01635 static int tcl_validchan STDVAR
01636 {
01637 struct chanset_t *chan;
01638
01639 BADARGS(2, 2, " channel");
01640
01641 chan = findchan_by_dname(argv[1]);
01642 if (chan == NULL)
01643 Tcl_AppendResult(irp, "0", NULL);
01644 else
01645 Tcl_AppendResult(irp, "1", NULL);
01646 return TCL_OK;
01647 }
01648
01649 static int tcl_isdynamic STDVAR
01650 {
01651 struct chanset_t *chan;
01652
01653 BADARGS(2, 2, " channel");
01654
01655 chan = findchan_by_dname(argv[1]);
01656 if (chan != NULL)
01657 if (!channel_static(chan)) {
01658 Tcl_AppendResult(irp, "1", NULL);
01659 return TCL_OK;
01660 }
01661 Tcl_AppendResult(irp, "0", NULL);
01662 return TCL_OK;
01663 }
01664
01665 static int tcl_getchaninfo STDVAR
01666 {
01667 char s[161];
01668 struct userrec *u;
01669
01670 BADARGS(3, 3, " handle channel");
01671
01672 u = get_user_by_handle(userlist, argv[1]);
01673 if (!u || (u->flags & USER_BOT))
01674 return TCL_OK;
01675 get_handle_chaninfo(argv[1], argv[2], s);
01676 Tcl_AppendResult(irp, s, NULL);
01677 return TCL_OK;
01678 }
01679
01680 static int tcl_setchaninfo STDVAR
01681 {
01682 struct chanset_t *chan;
01683
01684 BADARGS(4, 4, " handle channel info");
01685
01686 chan = findchan_by_dname(argv[2]);
01687 if (chan == NULL) {
01688 Tcl_AppendResult(irp, "illegal channel: ", argv[2], NULL);
01689 return TCL_ERROR;
01690 }
01691 if (!egg_strcasecmp(argv[3], "none")) {
01692 set_handle_chaninfo(userlist, argv[1], argv[2], NULL);
01693 return TCL_OK;
01694 }
01695 set_handle_chaninfo(userlist, argv[1], argv[2], argv[3]);
01696 return TCL_OK;
01697 }
01698
01699 static int tcl_setlaston STDVAR
01700 {
01701 time_t t = now;
01702 struct userrec *u;
01703
01704 BADARGS(2, 4, " handle ?channel? ?timestamp?");
01705
01706 u = get_user_by_handle(userlist, argv[1]);
01707 if (!u) {
01708 Tcl_AppendResult(irp, "No such user: ", argv[1], NULL);
01709 return TCL_ERROR;
01710 }
01711 if (argc == 4)
01712 t = (time_t) atoi(argv[3]);
01713 if (argc == 3 && ((argv[2][0] != '#') && (argv[2][0] != '&')))
01714 t = (time_t) atoi(argv[2]);
01715 if (argc == 2 || (argc == 3 && ((argv[2][0] != '#') && (argv[2][0] != '&'))))
01716 set_handle_laston("*", u, t);
01717 else
01718 set_handle_laston(argv[2], u, t);
01719 return TCL_OK;
01720 }
01721
01722 static int tcl_addchanrec STDVAR
01723 {
01724 struct userrec *u;
01725
01726 BADARGS(3, 3, " handle channel");
01727
01728 u = get_user_by_handle(userlist, argv[1]);
01729 if (!u) {
01730 Tcl_AppendResult(irp, "0", NULL);
01731 return TCL_OK;
01732 }
01733 if (!findchan_by_dname(argv[2])) {
01734 Tcl_AppendResult(irp, "0", NULL);
01735 return TCL_OK;
01736 }
01737 if (get_chanrec(u, argv[2]) != NULL) {
01738 Tcl_AppendResult(irp, "0", NULL);
01739 return TCL_OK;
01740 }
01741 add_chanrec(u, argv[2]);
01742 Tcl_AppendResult(irp, "1", NULL);
01743 return TCL_OK;
01744 }
01745
01746 static int tcl_delchanrec STDVAR
01747 {
01748 struct userrec *u;
01749
01750 BADARGS(3, 3, " handle channel");
01751
01752 u = get_user_by_handle(userlist, argv[1]);
01753 if (!u) {
01754 Tcl_AppendResult(irp, "0", NULL);
01755 return TCL_OK;
01756 }
01757 if (get_chanrec(u, argv[2]) == NULL) {
01758 Tcl_AppendResult(irp, "0", NULL);
01759 return TCL_OK;
01760 }
01761 del_chanrec(u, argv[2]);
01762 Tcl_AppendResult(irp, "1", NULL);
01763 return TCL_OK;
01764 }
01765
01766 static int tcl_haschanrec STDVAR
01767 {
01768 struct userrec *u;
01769 struct chanset_t *chan;
01770 struct chanuserrec *chanrec;
01771
01772 BADARGS(3, 3, " handle channel");
01773
01774 chan = findchan_by_dname(argv[2]);
01775 if (chan == NULL) {
01776 Tcl_AppendResult(irp, "illegal channel: ", argv[2], NULL);
01777 return TCL_ERROR;
01778 }
01779 u = get_user_by_handle(userlist, argv[1]);
01780 if (!u) {
01781 Tcl_AppendResult(irp, "No such user: ", argv[1], NULL);
01782 return TCL_ERROR;
01783 }
01784 chanrec = get_chanrec(u, chan->dname);
01785 if (chanrec) {
01786 Tcl_AppendResult(irp, "1", NULL);
01787 return TCL_OK;
01788 }
01789 Tcl_AppendResult(irp, "0", NULL);
01790 return TCL_OK;
01791 }
01792
01793 static void init_masklist(masklist *m)
01794 {
01795 m->mask = nmalloc(1);
01796 m->mask[0] = 0;
01797 m->who = NULL;
01798 m->next = NULL;
01799 }
01800
01801
01802
01803 static void init_channel(struct chanset_t *chan, int reset)
01804 {
01805 int flags = reset ? reset : CHAN_RESETALL;
01806
01807 if (!reset) {
01808 chan->channel.key = nmalloc(1);
01809 chan->channel.key[0] = 0;
01810 chan->channel.members = 0;
01811 chan->channel.member = nmalloc(sizeof(memberlist));
01812 chan->channel.member->nick[0] = 0;
01813 chan->channel.member->next = NULL;
01814 }
01815 if (flags & CHAN_RESETMODES) {
01816 if (!reset)
01817 chan->channel.mode = 0;
01818 chan->channel.maxmembers = 0;
01819 }
01820 if (flags & CHAN_RESETBANS) {
01821 chan->channel.ban = nmalloc(sizeof(masklist));
01822 init_masklist(chan->channel.ban);
01823 }
01824 if (flags & CHAN_RESETEXEMPTS) {
01825 chan->channel.exempt = nmalloc(sizeof(masklist));
01826 init_masklist(chan->channel.exempt);
01827 }
01828 if (flags & CHAN_RESETINVITED) {
01829 chan->channel.invite = nmalloc(sizeof(masklist));
01830 init_masklist(chan->channel.invite);
01831 }
01832 if (flags & CHAN_RESETTOPIC)
01833 chan->channel.topic = NULL;
01834 }
01835
01836 static void clear_masklist(masklist *m)
01837 {
01838 masklist *temp;
01839
01840 for (; m; m = temp) {
01841 temp = m->next;
01842 if (m->mask)
01843 nfree(m->mask);
01844 if (m->who)
01845 nfree(m->who);
01846 nfree(m);
01847 }
01848 }
01849
01850
01851
01852 static void clear_channel(struct chanset_t *chan, int reset)
01853 {
01854 int flags = reset ? reset : CHAN_RESETALL;
01855 memberlist *m, *m1;
01856
01857 if (flags & CHAN_RESETWHO) {
01858 for (m = chan->channel.member; m; m = m1) {
01859 m1 = m->next;
01860 if (reset)
01861 m->flags &= ~WHO_SYNCED;
01862 else
01863 nfree(m);
01864 }
01865 }
01866 if (flags & CHAN_RESETBANS) {
01867 clear_masklist(chan->channel.ban);
01868 chan->channel.ban = NULL;
01869 }
01870 if (flags & CHAN_RESETEXEMPTS) {
01871 clear_masklist(chan->channel.exempt);
01872 chan->channel.exempt = NULL;
01873 }
01874 if (flags & CHAN_RESETINVITED) {
01875 clear_masklist(chan->channel.invite);
01876 chan->channel.invite = NULL;
01877 }
01878 if ((flags & CHAN_RESETTOPIC) && chan->channel.topic)
01879 nfree(chan->channel.topic);
01880 if (reset)
01881 init_channel(chan, reset);
01882 }
01883
01884
01885
01886 static int tcl_channel_add(Tcl_Interp *irp, char *newname, char *options)
01887 {
01888 int items;
01889 int ret = TCL_OK;
01890 int join = 0;
01891 char buf[2048], buf2[256];
01892 EGG_CONST char **item;
01893 struct chanset_t *chan;
01894
01895 if (!newname || !newname[0] || (strchr(CHANMETA, newname[0]) == NULL)) {
01896 if (irp)
01897 Tcl_AppendResult(irp, "invalid channel prefix", NULL);
01898 return TCL_ERROR;
01899 }
01900
01901 if (strchr(newname, ',') != NULL) {
01902 if (irp)
01903 Tcl_AppendResult(irp, "invalid channel name", NULL);
01904 return TCL_ERROR;
01905 }
01906
01907 convert_element(glob_chanmode, buf2);
01908 simple_sprintf(buf, "chanmode %s ", buf2);
01909 strncat(buf, glob_chanset, 2047 - strlen(buf));
01910 strncat(buf, options, 2047 - strlen(buf));
01911 buf[2047] = 0;
01912
01913 if (Tcl_SplitList(NULL, buf, &items, &item) != TCL_OK)
01914 return TCL_ERROR;
01915 if ((chan = findchan_by_dname(newname))) {
01916
01917 chan->status &= ~CHAN_FLAGGED;
01918 } else {
01919 chan = nmalloc(sizeof *chan);
01920
01921
01922 egg_bzero(chan, sizeof(struct chanset_t));
01923
01924 chan->limit_prot = 0;
01925 chan->limit = 0;
01926 chan->flood_pub_thr = gfld_chan_thr;
01927 chan->flood_pub_time = gfld_chan_time;
01928 chan->flood_ctcp_thr = gfld_ctcp_thr;
01929 chan->flood_ctcp_time = gfld_ctcp_time;
01930 chan->flood_join_thr = gfld_join_thr;
01931 chan->flood_join_time = gfld_join_time;
01932 chan->flood_deop_thr = gfld_deop_thr;
01933 chan->flood_deop_time = gfld_deop_time;
01934 chan->flood_kick_thr = gfld_kick_thr;
01935 chan->flood_kick_time = gfld_kick_time;
01936 chan->flood_nick_thr = gfld_nick_thr;
01937 chan->flood_nick_time = gfld_nick_time;
01938 chan->stopnethack_mode = global_stopnethack_mode;
01939 chan->revenge_mode = global_revenge_mode;
01940 chan->ban_type = global_ban_type;
01941 chan->ban_time = global_ban_time;
01942 chan->exempt_time = global_exempt_time;
01943 chan->invite_time = global_invite_time;
01944 chan->idle_kick = global_idle_kick;
01945 chan->aop_min = global_aop_min;
01946 chan->aop_max = global_aop_max;
01947
01948
01949
01950
01951
01952 strncpy(chan->dname, newname, 81);
01953 chan->dname[80] = 0;
01954
01955
01956 init_channel(chan, 0);
01957 egg_list_append((struct list_type **) &chanset, (struct list_type *) chan);
01958
01959 join = 1;
01960 }
01961
01962
01963
01964
01965
01966 if ((tcl_channel_modify(irp, chan, items, (char **) item) != TCL_OK) &&
01967 !chan_hack) {
01968 ret = TCL_ERROR;
01969 }
01970 Tcl_Free((char *) item);
01971 if (join && !channel_inactive(chan) && module_find("irc", 0, 0)) {
01972 if (chan->key_prot[0])
01973 dprintf(DP_SERVER, "JOIN %s %s\n", chan->dname, chan->key_prot);
01974 else
01975 dprintf(DP_SERVER, "JOIN %s\n", chan->dname);
01976 }
01977 return ret;
01978 }
01979
01980 static int tcl_setudef STDVAR
01981 {
01982 int type;
01983
01984 BADARGS(3, 3, " type name");
01985
01986 if (!egg_strcasecmp(argv[1], "flag"))
01987 type = UDEF_FLAG;
01988 else if (!egg_strcasecmp(argv[1], "int"))
01989 type = UDEF_INT;
01990 else if (!egg_strcasecmp(argv[1], "str"))
01991 type = UDEF_STR;
01992 else {
01993 Tcl_AppendResult(irp, "invalid type. Must be one of: flag, int, str",
01994 NULL);
01995 return TCL_ERROR;
01996 }
01997 initudef(type, argv[2], 1);
01998 return TCL_OK;
01999 }
02000
02001 static int tcl_renudef STDVAR
02002 {
02003 struct udef_struct *ul;
02004 int type, found = 0;
02005
02006 BADARGS(4, 4, " type oldname newname");
02007
02008 if (!egg_strcasecmp(argv[1], "flag"))
02009 type = UDEF_FLAG;
02010 else if (!egg_strcasecmp(argv[1], "int"))
02011 type = UDEF_INT;
02012 else if (!egg_strcasecmp(argv[1], "str"))
02013 type = UDEF_STR;
02014 else {
02015 Tcl_AppendResult(irp, "invalid type. Must be one of: flag, int, str",
02016 NULL);
02017 return TCL_ERROR;
02018 }
02019 for (ul = udef; ul; ul = ul->next) {
02020 if (ul->type == type && !egg_strcasecmp(ul->name, argv[2])) {
02021 nfree(ul->name);
02022 ul->name = nmalloc(strlen(argv[3]) + 1);
02023 strcpy(ul->name, argv[3]);
02024 found = 1;
02025 }
02026 }
02027 if (!found) {
02028 Tcl_AppendResult(irp, "not found", NULL);
02029 return TCL_ERROR;
02030 } else
02031 return TCL_OK;
02032 }
02033
02034 static int tcl_deludef STDVAR
02035 {
02036 struct udef_struct *ul, *ull;
02037 int type, found = 0;
02038
02039 BADARGS(3, 3, " type name");
02040
02041 if (!egg_strcasecmp(argv[1], "flag"))
02042 type = UDEF_FLAG;
02043 else if (!egg_strcasecmp(argv[1], "int"))
02044 type = UDEF_INT;
02045 else if (!egg_strcasecmp(argv[1], "str"))
02046 type = UDEF_STR;
02047 else {
02048 Tcl_AppendResult(irp, "invalid type. Must be one of: flag, int, str",
02049 NULL);
02050 return TCL_ERROR;
02051 }
02052 for (ul = udef; ul; ul = ul->next) {
02053 ull = ul->next;
02054 if (!ull)
02055 break;
02056 if (ull->type == type && !egg_strcasecmp(ull->name, argv[2])) {
02057 ul->next = ull->next;
02058 nfree(ull->name);
02059 free_udef_chans(ull->values, ull->type);
02060 nfree(ull);
02061 found = 1;
02062 }
02063 }
02064 if (udef) {
02065 if (udef->type == type && !egg_strcasecmp(udef->name, argv[2])) {
02066 ul = udef->next;
02067 nfree(udef->name);
02068 free_udef_chans(udef->values, udef->type);
02069 nfree(udef);
02070 udef = ul;
02071 found = 1;
02072 }
02073 }
02074 if (!found) {
02075 Tcl_AppendResult(irp, "not found", NULL);
02076 return TCL_ERROR;
02077 } else
02078 return TCL_OK;
02079 }
02080
02081 static tcl_cmds channels_cmds[] = {
02082 {"killban", tcl_killban},
02083 {"killchanban", tcl_killchanban},
02084 {"isbansticky", tcl_isbansticky},
02085 {"isban", tcl_isban},
02086 {"ispermban", tcl_ispermban},
02087 {"matchban", tcl_matchban},
02088 {"newchanban", tcl_newchanban},
02089 {"newban", tcl_newban},
02090 {"killexempt", tcl_killexempt},
02091 {"killchanexempt", tcl_killchanexempt},
02092 {"isexemptsticky", tcl_isexemptsticky},
02093 {"isexempt", tcl_isexempt},
02094 {"ispermexempt", tcl_ispermexempt},
02095 {"matchexempt", tcl_matchexempt},
02096 {"newchanexempt", tcl_newchanexempt},
02097 {"newexempt", tcl_newexempt},
02098 {"killinvite", tcl_killinvite},
02099 {"killchaninvite", tcl_killchaninvite},
02100 {"isinvitesticky", tcl_isinvitesticky},
02101 {"isinvite", tcl_isinvite},
02102 {"isperminvite", tcl_isperminvite},
02103 {"matchinvite", tcl_matchinvite},
02104 {"newchaninvite", tcl_newchaninvite},
02105 {"newinvite", tcl_newinvite},
02106 {"channel", tcl_channel},
02107 {"channels", tcl_channels},
02108 {"exemptlist", tcl_exemptlist},
02109 {"invitelist", tcl_invitelist},
02110 {"banlist", tcl_banlist},
02111 {"savechannels", tcl_savechannels},
02112 {"loadchannels", tcl_loadchannels},
02113 {"validchan", tcl_validchan},
02114 {"isdynamic", tcl_isdynamic},
02115 {"getchaninfo", tcl_getchaninfo},
02116 {"setchaninfo", tcl_setchaninfo},
02117 {"setlaston", tcl_setlaston},
02118 {"addchanrec", tcl_addchanrec},
02119 {"delchanrec", tcl_delchanrec},
02120 {"stick", tcl_stick},
02121 {"unstick", tcl_stick},
02122 {"stickinvite", tcl_stickinvite},
02123 {"unstickinvite", tcl_stickinvite},
02124 {"stickexempt", tcl_stickexempt},
02125 {"unstickexempt", tcl_stickexempt},
02126 {"setudef", tcl_setudef},
02127 {"renudef", tcl_renudef},
02128 {"deludef", tcl_deludef},
02129 {"haschanrec", tcl_haschanrec},
02130 {NULL, NULL}
02131 };