PageRenderTime 51ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/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
Possible License(s): GPL-2.0

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

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