/[cvs]/eggdrop1.8/src/tcldcc.c
ViewVC logotype

Contents of /eggdrop1.8/src/tcldcc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Thu Aug 5 18:12:05 2010 UTC (9 years, 3 months ago) by pseudo
Branch: MAIN
Changes since 1.1: +28 -25 lines
File MIME type: text/x-chdr
Added new, full IPv6 support to eggdrop.

1 /*
2 * tcldcc.c -- handles:
3 * Tcl stubs for the dcc commands
4 *
5 * $Id: tcldcc.c,v 1.1.1.1 2010/07/26 21:11:06 simple Exp $
6 */
7 /*
8 * Copyright (C) 1997 Robey Pointer
9 * Copyright (C) 1999 - 2010 Eggheads Development Team
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 */
25
26 #include "main.h"
27 #include "tandem.h"
28 #include "modules.h"
29 #include <errno.h>
30
31 extern Tcl_Interp *interp;
32 extern tcl_timer_t *timer, *utimer;
33 extern struct dcc_t *dcc;
34 extern char botnetnick[];
35 extern int dcc_total, backgrd, parties, make_userfile, do_restart, remote_boots, max_dcc;
36 extern party_t *party;
37 extern tand_t *tandbot;
38 extern time_t now;
39 extern unsigned long otraffic_irc, otraffic_irc_today, itraffic_irc,
40 itraffic_irc_today, otraffic_bn, otraffic_bn_today,
41 itraffic_bn, itraffic_bn_today, otraffic_dcc,
42 otraffic_dcc_today, itraffic_dcc, itraffic_dcc_today,
43 otraffic_trans, otraffic_trans_today, itraffic_trans,
44 itraffic_trans_today, otraffic_unknown, itraffic_unknown,
45 otraffic_unknown_today, itraffic_unknown_today;
46 static struct portmap *root = NULL;
47
48
49 int expmem_tcldcc(void)
50 {
51 int tot = 0;
52 struct portmap *pmap;
53
54 for (pmap = root; pmap; pmap = pmap->next)
55 tot += sizeof(struct portmap);
56
57 return tot;
58 }
59
60 static int tcl_putdcc STDVAR
61 {
62 int j;
63
64 BADARGS(3, 4, " idx text ?options?");
65
66 if ((argc == 4) && egg_strcasecmp(argv[3], "-raw")) {
67 Tcl_AppendResult(irp, "unknown putdcc option: should be ",
68 "-raw", NULL);
69 return TCL_ERROR;
70 }
71
72 j = findidx(atoi(argv[1]));
73 if (j < 0) {
74 Tcl_AppendResult(irp, "invalid idx", NULL);
75 return TCL_ERROR;
76 }
77 if (argc == 4)
78 tputs(dcc[j].sock, argv[2], strlen(argv[2]));
79 else
80 dumplots(j, "", argv[2]);
81
82 return TCL_OK;
83 }
84
85 /* Allows tcl scripts to send out raw data. Can be used for fast server write.
86 * The server idx is 0.
87 *
88 * Usage: putdccraw <idx> <size> <rawdata>
89 *
90 * Example: putdccraw 6 13 "eggdrop rulz\n"
91 *
92 * Added by <drummer@sophia.jpte.hu>.
93 */
94 static int tcl_putdccraw STDVAR
95 {
96 #if 0
97 int i, j = 0, z;
98
99 BADARGS(4, 4, " idx size text");
100
101 z = atoi(argv[1]);
102 for (i = 0; i < dcc_total; i++) {
103 if (!z && !strcmp(dcc[i].nick, "(server)")) {
104 j = dcc[i].sock;
105 break;
106 } else if (dcc[i].sock == z) {
107 j = dcc[i].sock;
108 break;
109 }
110 }
111 if (i == dcc_total) {
112 Tcl_AppendResult(irp, "invalid idx", NULL);
113 return TCL_ERROR;
114 }
115 tputs(j, argv[3], atoi(argv[2]));
116 return TCL_OK;
117 #endif
118
119 Tcl_AppendResult(irp, "putdccraw is deprecated. "
120 "Please use putdcc/putnow instead.", NULL);
121 return TCL_ERROR;
122 }
123
124 static int tcl_dccsimul STDVAR
125 {
126 int idx;
127
128 BADARGS(3, 3, " idx command");
129
130 idx = findidx(atoi(argv[1]));
131 if (idx >= 0 && (dcc[idx].type->flags & DCT_SIMUL)) {
132 int l = strlen(argv[2]);
133
134 if (l > 510) {
135 l = 510;
136 argv[2][510] = 0; /* Restrict length of cmd */
137 }
138 if (dcc[idx].type && dcc[idx].type->activity) {
139 dcc[idx].type->activity(idx, argv[2], l);
140 return TCL_OK;
141 }
142 } else {
143 Tcl_AppendResult(irp, "invalid idx", NULL);
144 }
145 return TCL_ERROR;
146 }
147
148
149 static int tcl_dccbroadcast STDVAR
150 {
151 char msg[401];
152
153 BADARGS(2, 2, " message");
154
155 strncpyz(msg, argv[1], sizeof msg);
156 chatout("*** %s\n", msg);
157 botnet_send_chat(-1, botnetnick, msg);
158 check_tcl_bcst(botnetnick, -1, msg);
159 return TCL_OK;
160 }
161
162 static int tcl_hand2idx STDVAR
163 {
164 int i;
165 char s[11];
166
167 BADARGS(2, 2, " nickname");
168
169 for (i = 0; i < dcc_total; i++)
170 if ((dcc[i].type->flags & (DCT_SIMUL | DCT_BOT)) &&
171 !egg_strcasecmp(argv[1], dcc[i].nick)) {
172 egg_snprintf(s, sizeof s, "%ld", dcc[i].sock);
173 Tcl_AppendResult(irp, s, NULL);
174 return TCL_OK;
175 }
176 Tcl_AppendResult(irp, "-1", NULL);
177 return TCL_OK;
178 }
179
180 static int tcl_getchan STDVAR
181 {
182 char s[7];
183 int idx;
184
185 BADARGS(2, 2, " idx");
186
187 idx = findidx(atoi(argv[1]));
188 if (idx < 0 || (dcc[idx].type != &DCC_CHAT &&
189 dcc[idx].type != &DCC_SCRIPT)) {
190 Tcl_AppendResult(irp, "invalid idx", NULL);
191 return TCL_ERROR;
192 }
193
194 if (dcc[idx].type == &DCC_SCRIPT)
195 egg_snprintf(s, sizeof s, "%d", dcc[idx].u.script->u.chat->channel);
196 else
197 egg_snprintf(s, sizeof s, "%d", dcc[idx].u.chat->channel);
198
199 Tcl_AppendResult(irp, s, NULL);
200 return TCL_OK;
201 }
202
203 static int tcl_setchan STDVAR
204 {
205 int idx, chan;
206 module_entry *me;
207
208 BADARGS(3, 3, " idx channel");
209
210 idx = findidx(atoi(argv[1]));
211 if (idx < 0 || (dcc[idx].type != &DCC_CHAT &&
212 dcc[idx].type != &DCC_SCRIPT)) {
213 Tcl_AppendResult(irp, "invalid idx", NULL);
214 return TCL_ERROR;
215 }
216 if (argv[2][0] < '0' || argv[2][0] > '9') {
217 if (!strcmp(argv[2], "-1") || !egg_strcasecmp(argv[2], "off"))
218 chan = -1;
219 else {
220 Tcl_SetVar(irp, "_chan", argv[2], 0);
221 if (Tcl_VarEval(irp, "assoc ", "$_chan", NULL) != TCL_OK ||
222 tcl_resultempty()) {
223 Tcl_AppendResult(irp, "channel name is invalid", NULL);
224 return TCL_ERROR;
225 }
226 chan = tcl_resultint();
227 }
228 } else
229 chan = atoi(argv[2]);
230 if ((chan < -1) || (chan > 199999)) {
231 Tcl_AppendResult(irp, "channel out of range; must be -1 through 199999",
232 NULL);
233 return TCL_ERROR;
234 }
235 if (dcc[idx].type == &DCC_SCRIPT)
236 dcc[idx].u.script->u.chat->channel = chan;
237 else {
238 int oldchan = dcc[idx].u.chat->channel;
239
240 if (dcc[idx].u.chat->channel >= 0) {
241 if ((chan >= GLOBAL_CHANS) && (oldchan < GLOBAL_CHANS))
242 botnet_send_part_idx(idx, "*script*");
243 check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock,
244 dcc[idx].u.chat->channel);
245 }
246 dcc[idx].u.chat->channel = chan;
247 if (chan < GLOBAL_CHANS)
248 botnet_send_join_idx(idx, oldchan);
249 check_tcl_chjn(botnetnick, dcc[idx].nick, chan, geticon(idx),
250 dcc[idx].sock, dcc[idx].host);
251 }
252 /* Console autosave. */
253 if ((me = module_find("console", 1, 1))) {
254 Function *func = me->funcs;
255
256 (func[CONSOLE_DOSTORE]) (idx);
257 }
258 return TCL_OK;
259 }
260
261 static int tcl_dccputchan STDVAR
262 {
263 int chan;
264 char msg[401];
265
266 BADARGS(3, 3, " channel message");
267
268 chan = atoi(argv[1]);
269 if ((chan < 0) || (chan > 199999)) {
270 Tcl_AppendResult(irp, "channel out of range; must be 0 through 199999", NULL);
271 return TCL_ERROR;
272 }
273 strncpyz(msg, argv[2], sizeof msg);
274
275 chanout_but(-1, chan, "*** %s\n", argv[2]);
276 botnet_send_chan(-1, botnetnick, NULL, chan, argv[2]);
277 check_tcl_bcst(botnetnick, chan, argv[2]);
278 return TCL_OK;
279 }
280
281 static int tcl_console STDVAR
282 {
283 int i, j, pls, arg;
284 module_entry *me;
285
286 BADARGS(2, 4, " idx ?channel? ?console-modes?");
287
288 i = findidx(atoi(argv[1]));
289 if (i < 0 || dcc[i].type != &DCC_CHAT) {
290 Tcl_AppendResult(irp, "invalid idx", NULL);
291 return TCL_ERROR;
292 }
293 pls = 1;
294
295 for (arg = 2; arg < argc; arg++) {
296 if (argv[arg][0] && ((strchr(CHANMETA, argv[arg][0]) != NULL) ||
297 (argv[arg][0] == '*'))) {
298 if ((argv[arg][0] != '*') && (!findchan_by_dname(argv[arg]))) {
299 /* If we dont find the channel, and it starts with a +, assume it
300 * should be the console flags to set. */
301 if (argv[arg][0] == '+')
302 goto do_console_flags;
303 Tcl_AppendResult(irp, "invalid channel", NULL);
304 return TCL_ERROR;
305 }
306 strncpyz(dcc[i].u.chat->con_chan, argv[arg], 81);
307 } else {
308 if ((argv[arg][0] != '+') && (argv[arg][0] != '-'))
309 dcc[i].u.chat->con_flags = 0;
310 do_console_flags:
311 for (j = 0; j < strlen(argv[arg]); j++) {
312 if (argv[arg][j] == '+')
313 pls = 1;
314 else if (argv[arg][j] == '-')
315 pls = -1;
316 else {
317 char s[2];
318
319 s[0] = argv[arg][j];
320 s[1] = 0;
321 if (pls == 1)
322 dcc[i].u.chat->con_flags |= logmodes(s);
323 else
324 dcc[i].u.chat->con_flags &= ~logmodes(s);
325 }
326 }
327 }
328 }
329 Tcl_AppendElement(irp, dcc[i].u.chat->con_chan);
330 Tcl_AppendElement(irp, masktype(dcc[i].u.chat->con_flags));
331 /* Console autosave. */
332 if (argc > 2 && (me = module_find("console", 1, 1))) {
333 Function *func = me->funcs;
334
335 (func[CONSOLE_DOSTORE]) (i);
336 }
337 return TCL_OK;
338 }
339
340 static int tcl_strip STDVAR
341 {
342 int i, j, pls, arg;
343 module_entry *me;
344
345 BADARGS(2, 4, " idx ?strip-flags?");
346
347 i = findidx(atoi(argv[1]));
348 if (i < 0 || dcc[i].type != &DCC_CHAT) {
349 Tcl_AppendResult(irp, "invalid idx", NULL);
350 return TCL_ERROR;
351 }
352 pls = 1;
353
354 for (arg = 2; arg < argc; arg++) {
355 if ((argv[arg][0] != '+') && (argv[arg][0] != '-'))
356 dcc[i].u.chat->strip_flags = 0;
357 for (j = 0; j < strlen(argv[arg]); j++) {
358 if (argv[arg][j] == '+')
359 pls = 1;
360 else if (argv[arg][j] == '-')
361 pls = -1;
362 else {
363 char s[2];
364
365 s[0] = argv[arg][j];
366 s[1] = 0;
367 if (pls == 1)
368 dcc[i].u.chat->strip_flags |= stripmodes(s);
369 else
370 dcc[i].u.chat->strip_flags &= ~stripmodes(s);
371 }
372 }
373 }
374 Tcl_AppendElement(irp, stripmasktype(dcc[i].u.chat->strip_flags));
375 /* Console autosave. */
376 if (argc > 2 && (me = module_find("console", 1, 1))) {
377 Function *func = me->funcs;
378
379 (func[CONSOLE_DOSTORE]) (i);
380 }
381 return TCL_OK;
382 }
383
384 static int tcl_echo STDVAR
385 {
386 int i;
387 module_entry *me;
388
389 BADARGS(2, 3, " idx ?status?");
390
391 i = findidx(atoi(argv[1]));
392 if (i < 0 || dcc[i].type != &DCC_CHAT) {
393 Tcl_AppendResult(irp, "invalid idx", NULL);
394 return TCL_ERROR;
395 }
396 if (argc == 3) {
397 if (atoi(argv[2]))
398 dcc[i].status |= STAT_ECHO;
399 else
400 dcc[i].status &= ~STAT_ECHO;
401 }
402 if (dcc[i].status & STAT_ECHO)
403 Tcl_AppendResult(irp, "1", NULL);
404 else
405 Tcl_AppendResult(irp, "0", NULL);
406 /* Console autosave. */
407 if (argc > 2 && (me = module_find("console", 1, 1))) {
408 Function *func = me->funcs;
409
410 (func[CONSOLE_DOSTORE]) (i);
411 }
412 return TCL_OK;
413 }
414
415 static int tcl_page STDVAR
416 {
417 int i;
418 char x[20];
419 module_entry *me;
420
421 BADARGS(2, 3, " idx ?status?");
422
423 i = findidx(atoi(argv[1]));
424 if (i < 0 || dcc[i].type != &DCC_CHAT) {
425 Tcl_AppendResult(irp, "invalid idx", NULL);
426 return TCL_ERROR;
427 }
428 if (argc == 3) {
429 int l = atoi(argv[2]);
430
431 if (!l)
432 dcc[i].status &= ~STAT_PAGE;
433 else {
434 dcc[i].status |= STAT_PAGE;
435 dcc[i].u.chat->max_line = l;
436 }
437 }
438 if (dcc[i].status & STAT_PAGE) {
439 egg_snprintf(x, sizeof x, "%d", dcc[i].u.chat->max_line);
440 Tcl_AppendResult(irp, x, NULL);
441 } else
442 Tcl_AppendResult(irp, "0", NULL);
443 /* Console autosave. */
444 if ((argc > 2) && (me = module_find("console", 1, 1))) {
445 Function *func = me->funcs;
446
447 (func[CONSOLE_DOSTORE]) (i);
448 }
449 return TCL_OK;
450 }
451
452 static int tcl_control STDVAR
453 {
454 int idx;
455 void *hold;
456
457 BADARGS(3, 3, " idx command");
458
459 idx = findidx(atoi(argv[1]));
460 if (idx < 0) {
461 Tcl_AppendResult(irp, "invalid idx", NULL);
462 return TCL_ERROR;
463 }
464 if (dcc[idx].type->flags & DCT_CHAT) {
465 if (dcc[idx].u.chat->channel >= 0) {
466 chanout_but(idx, dcc[idx].u.chat->channel, "*** %s has gone.\n",
467 dcc[idx].nick);
468 check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock,
469 dcc[idx].u.chat->channel);
470 botnet_send_part_idx(idx, "gone");
471 }
472 check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
473 }
474 hold = dcc[idx].u.other;
475 dcc[idx].u.script = get_data_ptr(sizeof(struct script_info));
476 dcc[idx].u.script->u.other = hold;
477 dcc[idx].u.script->type = dcc[idx].type;
478 dcc[idx].type = &DCC_SCRIPT;
479 /* Do not buffer data anymore. All received and stored data is passed
480 * over to the dcc functions from now on. */
481 sockoptions(dcc[idx].sock, EGG_OPTION_UNSET, SOCK_BUFFER);
482 strncpyz(dcc[idx].u.script->command, argv[2], 120);
483 return TCL_OK;
484 }
485
486 static int tcl_valididx STDVAR
487 {
488 int idx;
489
490 BADARGS(2, 2, " idx");
491
492 idx = findidx(atoi(argv[1]));
493 if (idx < 0 || !(dcc[idx].type->flags & DCT_VALIDIDX))
494 Tcl_AppendResult(irp, "0", NULL);
495 else
496 Tcl_AppendResult(irp, "1", NULL);
497 return TCL_OK;
498 }
499
500 static int tcl_killdcc STDVAR
501 {
502 int idx;
503
504 BADARGS(2, 3, " idx ?reason?");
505
506 idx = findidx(atoi(argv[1]));
507 if (idx < 0) {
508 Tcl_AppendResult(irp, "invalid idx", NULL);
509 return TCL_ERROR;
510 }
511
512 if ((dcc[idx].sock == STDOUT) && !backgrd) /* Don't kill terminal socket */
513 return TCL_OK;
514
515
516 if (dcc[idx].type->flags & DCT_CHAT) { /* Make sure 'whom' info is updated */
517 chanout_but(idx, dcc[idx].u.chat->channel, "*** %s has left the %s%s%s\n",
518 dcc[idx].nick, dcc[idx].u.chat ? "channel" : "partyline",
519 argc == 3 ? ": " : "", argc == 3 ? argv[2] : "");
520 botnet_send_part_idx(idx, argc == 3 ? argv[2] : "");
521 if ((dcc[idx].u.chat->channel >= 0) &&
522 (dcc[idx].u.chat->channel < GLOBAL_CHANS))
523 check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock,
524 dcc[idx].u.chat->channel);
525 check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
526 }
527 killsock(dcc[idx].sock);
528 killtransfer(idx);
529 lostdcc(idx);
530 return TCL_OK;
531 }
532
533 static int tcl_putbot STDVAR
534 {
535 int i;
536 char msg[401];
537
538 BADARGS(3, 3, " botnick message");
539
540 i = nextbot(argv[1]);
541 if (i < 0) {
542 Tcl_AppendResult(irp, "bot is not on the botnet", NULL);
543 return TCL_ERROR;
544 }
545 strncpyz(msg, argv[2], sizeof msg);
546
547 botnet_send_zapf(i, botnetnick, argv[1], msg);
548 return TCL_OK;
549 }
550
551 static int tcl_putallbots STDVAR
552 {
553 char msg[401];
554
555 BADARGS(2, 2, " message");
556
557 strncpyz(msg, argv[1], sizeof msg);
558 botnet_send_zapf_broad(-1, botnetnick, NULL, msg);
559 return TCL_OK;
560 }
561
562 static int tcl_idx2hand STDVAR
563 {
564 int idx;
565
566 BADARGS(2, 2, " idx");
567
568 idx = findidx(atoi(argv[1]));
569 if (idx < 0) {
570 Tcl_AppendResult(irp, "invalid idx", NULL);
571 return TCL_ERROR;
572 }
573
574 Tcl_AppendResult(irp, dcc[idx].nick, NULL);
575 return TCL_OK;
576 }
577
578 static int tcl_islinked STDVAR
579 {
580 int i;
581
582 BADARGS(2, 2, " bot");
583
584 i = nextbot(argv[1]);
585 if (i < 0)
586 Tcl_AppendResult(irp, "0", NULL);
587 else
588 Tcl_AppendResult(irp, "1", NULL);
589 return TCL_OK;
590 }
591
592 static int tcl_bots STDVAR
593 {
594 tand_t *bot;
595
596 BADARGS(1, 1, "");
597
598 for (bot = tandbot; bot; bot = bot->next)
599 Tcl_AppendElement(irp, bot->bot);
600 return TCL_OK;
601 }
602
603 static int tcl_botlist STDVAR
604 {
605 char *p, sh[2], string[20];
606 EGG_CONST char *list[4];
607 tand_t *bot;
608
609 BADARGS(1, 1, "");
610
611 sh[1] = 0;
612 list[3] = sh;
613 list[2] = string;
614 for (bot = tandbot; bot; bot = bot->next) {
615 list[0] = bot->bot;
616 list[1] = (bot->uplink == (tand_t *) 1) ? botnetnick : bot->uplink->bot;
617 strncpyz(string, int_to_base10(bot->ver), sizeof string);
618 sh[0] = bot->share;
619 p = Tcl_Merge(4, list);
620 Tcl_AppendElement(irp, p);
621 Tcl_Free((char *) p);
622 }
623 return TCL_OK;
624 }
625
626 static int tcl_dcclist STDVAR
627 {
628 int i;
629 char *p, idxstr[10], timestamp[11], other[160];
630 long tv;
631 EGG_CONST char *list[6];
632
633 BADARGS(1, 2, " ?type?");
634
635 for (i = 0; i < dcc_total; i++) {
636 if (argc == 1 || ((argc == 2) && (dcc[i].type &&
637 !egg_strcasecmp(dcc[i].type->name, argv[1])))) {
638 egg_snprintf(idxstr, sizeof idxstr, "%ld", dcc[i].sock);
639 tv = dcc[i].timeval;
640 egg_snprintf(timestamp, sizeof timestamp, "%ld", tv);
641 if (dcc[i].type && dcc[i].type->display)
642 dcc[i].type->display(i, other);
643 else {
644 egg_snprintf(other, sizeof other, "?:%lX !! ERROR !!",
645 (long) dcc[i].type);
646 break;
647 }
648 list[0] = idxstr;
649 list[1] = dcc[i].nick;
650 list[2] = dcc[i].host;
651 list[3] = dcc[i].type ? dcc[i].type->name : "*UNKNOWN*";
652 list[4] = other;
653 list[5] = timestamp;
654 p = Tcl_Merge(6, list);
655 Tcl_AppendElement(irp, p);
656 Tcl_Free((char *) p);
657 }
658 }
659 return TCL_OK;
660 }
661
662 static int tcl_whom STDVAR
663 {
664 int chan, i;
665 char c[2], idle[11], work[20], *p;
666 long tv = 0;
667 EGG_CONST char *list[7];
668
669 BADARGS(2, 2, " chan");
670
671 if (argv[1][0] == '*')
672 chan = -1;
673 else {
674 if ((argv[1][0] < '0') || (argv[1][0] > '9')) {
675 Tcl_SetVar(interp, "_chan", argv[1], 0);
676 if ((Tcl_VarEval(interp, "assoc ", "$_chan", NULL) != TCL_OK) ||
677 tcl_resultempty()) {
678 Tcl_AppendResult(irp, "channel name is invalid", NULL);
679 return TCL_ERROR;
680 }
681 chan = tcl_resultint();
682 } else
683 chan = atoi(argv[1]);
684 if ((chan < 0) || (chan > 199999)) {
685 Tcl_AppendResult(irp, "channel out of range; must be 0 through 199999",
686 NULL);
687 return TCL_ERROR;
688 }
689 }
690 for (i = 0; i < dcc_total; i++)
691 if (dcc[i].type == &DCC_CHAT) {
692 if (dcc[i].u.chat->channel == chan || chan == -1) {
693 c[0] = geticon(i);
694 c[1] = 0;
695 tv = (now - dcc[i].timeval) / 60;
696 egg_snprintf(idle, sizeof idle, "%li", tv);
697 list[0] = dcc[i].nick;
698 list[1] = botnetnick;
699 list[2] = dcc[i].host;
700 list[3] = c;
701 list[4] = idle;
702 list[5] = dcc[i].u.chat->away ? dcc[i].u.chat->away : "";
703 if (chan == -1) {
704 egg_snprintf(work, sizeof work, "%d", dcc[i].u.chat->channel);
705 list[6] = work;
706 }
707 p = Tcl_Merge((chan == -1) ? 7 : 6, list);
708 Tcl_AppendElement(irp, p);
709 Tcl_Free((char *) p);
710 }
711 }
712 for (i = 0; i < parties; i++) {
713 if (party[i].chan == chan || chan == -1) {
714 c[0] = party[i].flag;
715 c[1] = 0;
716 if (party[i].timer == 0L)
717 strcpy(idle, "0");
718 else {
719 tv = (now - party[i].timer) / 60;
720 egg_snprintf(idle, sizeof idle, "%li", tv);
721 }
722 list[0] = party[i].nick;
723 list[1] = party[i].bot;
724 list[2] = party[i].from ? party[i].from : "";
725 list[3] = c;
726 list[4] = idle;
727 list[5] = party[i].status & PLSTAT_AWAY ? party[i].away : "";
728 if (chan == -1) {
729 egg_snprintf(work, sizeof work, "%d", party[i].chan);
730 list[6] = work;
731 }
732 p = Tcl_Merge((chan == -1) ? 7 : 6, list);
733 Tcl_AppendElement(irp, p);
734 Tcl_Free((char *) p);
735 }
736 }
737 return TCL_OK;
738 }
739
740 static int tcl_dccused STDVAR
741 {
742 char s[20];
743
744 BADARGS(1, 1, "");
745
746 egg_snprintf(s, sizeof s, "%d", dcc_total);
747 Tcl_AppendResult(irp, s, NULL);
748 return TCL_OK;
749 }
750
751 static int tcl_getdccidle STDVAR
752 {
753 int x, idx;
754 char s[21];
755
756 BADARGS(2, 2, " idx");
757
758 idx = findidx(atoi(argv[1]));
759 if (idx < 0) {
760 Tcl_AppendResult(irp, "invalid idx", NULL);
761 return TCL_ERROR;
762 }
763 x = (now - dcc[idx].timeval);
764
765 egg_snprintf(s, sizeof s, "%d", x);
766 Tcl_AppendElement(irp, s);
767 return TCL_OK;
768 }
769
770 static int tcl_getdccaway STDVAR
771 {
772 int idx;
773
774 BADARGS(2, 2, " idx");
775
776 idx = findidx(atol(argv[1]));
777 if (idx < 0 || dcc[idx].type != &DCC_CHAT) {
778 Tcl_AppendResult(irp, "invalid idx", NULL);
779 return TCL_ERROR;
780 }
781 if (dcc[idx].u.chat->away == NULL)
782 return TCL_OK;
783
784 Tcl_AppendResult(irp, dcc[idx].u.chat->away, NULL);
785 return TCL_OK;
786 }
787
788 static int tcl_setdccaway STDVAR
789 {
790 int idx;
791
792 BADARGS(3, 3, " idx message");
793
794 idx = findidx(atol(argv[1]));
795 if (idx < 0 || dcc[idx].type != &DCC_CHAT) {
796 Tcl_AppendResult(irp, "invalid idx", NULL);
797 return TCL_ERROR;
798 }
799 if (!argv[2][0]) {
800 if (dcc[idx].u.chat->away != NULL)
801 not_away(idx);
802 return TCL_OK;
803 }
804 set_away(idx, argv[2]);
805 return TCL_OK;
806 }
807
808 static int tcl_link STDVAR
809 {
810 int x, i;
811 char bot[HANDLEN + 1], bot2[HANDLEN + 1];
812
813 BADARGS(2, 3, " ?via-bot? bot");
814
815 strncpyz(bot, argv[1], sizeof bot);
816 if (argc == 3) {
817 x = 1;
818 strncpyz(bot2, argv[2], sizeof bot2);
819 i = nextbot(bot);
820 if (i < 0)
821 x = 0;
822 else
823 botnet_send_link(i, botnetnick, bot, bot2);
824 } else
825 x = botlink("", -2, bot);
826
827 egg_snprintf(bot, sizeof bot, "%d", x);
828 Tcl_AppendResult(irp, bot, NULL);
829 return TCL_OK;
830 }
831
832 static int tcl_unlink STDVAR
833 {
834 int i, x;
835 char bot[HANDLEN + 1];
836
837 BADARGS(2, 3, " bot ?comment?");
838
839 strncpyz(bot, argv[1], sizeof bot);
840 i = nextbot(bot);
841 if (i < 0)
842 x = 0;
843 else {
844 x = 1;
845 if (!egg_strcasecmp(bot, dcc[i].nick))
846 x = botunlink(-2, bot, argv[2], botnetnick);
847 else
848 botnet_send_unlink(i, botnetnick, lastbot(bot), bot, argv[2]);
849 }
850 egg_snprintf(bot, sizeof bot, "%d", x);
851
852 Tcl_AppendResult(irp, bot, NULL);
853 return TCL_OK;
854 }
855
856 static int tcl_connect STDVAR
857 {
858 int i, z, sock;
859 char s[81];
860
861 BADARGS(3, 3, " hostname port");
862
863 if (dcc_total == max_dcc && increase_socks_max()) {
864 Tcl_AppendResult(irp, "out of dcc table space", NULL);
865 return TCL_ERROR;
866 }
867 sock = z = open_telnet(argv[1], atoi(argv[2]));
868 if (sock < 0) {
869 switch (sock) {
870 case -3:
871 Tcl_AppendResult(irp, MISC_NOFREESOCK, NULL);
872 break;
873 case -2:
874 Tcl_AppendResult(irp, "DNS lookup failed", NULL);
875 break;
876 default:
877 Tcl_AppendResult(irp, strerror(errno), NULL);
878 }
879 return TCL_ERROR;
880 }
881 i = new_dcc(&DCC_SOCKET, 0);
882 dcc[i].sock = sock;
883 dcc[i].port = atoi(argv[2]);
884 strcpy(dcc[i].nick, "*");
885 strncpyz(dcc[i].host, argv[1], UHOSTMAX);
886 egg_snprintf(s, sizeof s, "%d", sock);
887 Tcl_AppendResult(irp, s, NULL);
888 return TCL_OK;
889 }
890
891 /* Create a new listening port (or destroy one)
892 *
893 * listen <port> bots/all/users [mask]
894 * listen <port> script <proc> [flag]
895 * listen <port> off
896 */
897 static int tcl_listen STDVAR
898 {
899 int i, j, idx = -1, port, realport;
900 char s[11], msg[256];
901 struct portmap *pmap = NULL, *pold = NULL;
902
903 BADARGS(3, 5, " port type ?mask?/?proc ?flag??");
904
905 port = realport = atoi(argv[1]);
906 for (pmap = root; pmap; pold = pmap, pmap = pmap->next)
907 if (pmap->realport == port) {
908 port = pmap->mappedto;
909 break;
910 }
911 for (i = 0; i < dcc_total; i++)
912 if ((dcc[i].type == &DCC_TELNET) && (dcc[i].port == port))
913 idx = i;
914 if (!egg_strcasecmp(argv[2], "off")) {
915 if (pmap) {
916 if (pold)
917 pold->next = pmap->next;
918 else
919 root = pmap->next;
920 nfree(pmap);
921 }
922 /* Remove */
923 if (idx < 0) {
924 Tcl_AppendResult(irp, "no such listen port is open", NULL);
925 return TCL_ERROR;
926 }
927 killsock(dcc[idx].sock);
928 lostdcc(idx);
929 return TCL_OK;
930 }
931 if (idx < 0) {
932 /* Make new one */
933 if (dcc_total >= max_dcc && increase_socks_max()) {
934 Tcl_AppendResult(irp, "No more DCC slots available.", NULL);
935 return TCL_ERROR;
936 }
937 /* Try to grab port */
938 j = port + 20;
939 i = -2;
940 while (port < j && i < 0) {
941 i = open_listen(&port);
942 if (i == -1)
943 break;
944 else if (i == -2)
945 port++;
946 }
947
948 if (i == -1) {
949 egg_snprintf(msg, sizeof msg, "Couldn't listen on port '%d' on the given "
950 "address: %s", realport, strerror(errno));
951 Tcl_AppendResult(irp, msg, NULL);
952 return TCL_ERROR;
953 } else if (i == -2) {
954 egg_snprintf(msg, sizeof msg, "Couldn't listen on port '%d' on the given "
955 "address. Please make sure 'listen-addr' is set properly"
956 " or try choosing a different port.", realport);
957 Tcl_AppendResult(irp, msg, NULL);
958 return TCL_ERROR;
959 }
960 idx = new_dcc(&DCC_TELNET, 0);
961 dcc[idx].sockname.addrlen = sizeof(dcc[idx].sockname.addr);
962 getsockname(i, &dcc[idx].sockname.addr.sa, &dcc[idx].sockname.addrlen);
963 dcc[idx].sockname.family = dcc[idx].sockname.addr.sa.sa_family;
964 dcc[idx].port = port;
965 dcc[idx].sock = i;
966 dcc[idx].timeval = now;
967 }
968 /* script? */
969 if (!strcmp(argv[2], "script")) {
970 strcpy(dcc[idx].nick, "(script)");
971 if (argc < 4) {
972 Tcl_AppendResult(irp, "a proc name must be specified for a script listen", NULL);
973 killsock(dcc[idx].sock);
974 lostdcc(idx);
975 return TCL_ERROR;
976 }
977 if (argc == 5) {
978 if (strcmp(argv[4], "pub")) {
979 Tcl_AppendResult(irp, "unknown flag: ", argv[4], ". allowed flags: pub",
980 NULL);
981 killsock(dcc[idx].sock);
982 lostdcc(idx);
983 return TCL_ERROR;
984 }
985 dcc[idx].status = LSTN_PUBLIC;
986 }
987 strncpyz(dcc[idx].host, argv[3], UHOSTMAX);
988 egg_snprintf(s, sizeof s, "%d", port);
989 Tcl_AppendResult(irp, s, NULL);
990 return TCL_OK;
991 }
992 /* bots/users/all */
993 if (!strcmp(argv[2], "bots"))
994 strcpy(dcc[idx].nick, "(bots)");
995 else if (!strcmp(argv[2], "users"))
996 strcpy(dcc[idx].nick, "(users)");
997 else if (!strcmp(argv[2], "all"))
998 strcpy(dcc[idx].nick, "(telnet)");
999 if (!dcc[idx].nick[0]) {
1000 Tcl_AppendResult(irp, "invalid listen type: must be one of ",
1001 "bots, users, all, off, script", NULL);
1002 killsock(dcc[idx].sock);
1003 dcc_total--;
1004 return TCL_ERROR;
1005 }
1006 if (argc == 4)
1007 strncpyz(dcc[idx].host, argv[3], UHOSTMAX);
1008 else
1009 strcpy(dcc[idx].host, "*");
1010 egg_snprintf(s, sizeof s, "%d", port);
1011 Tcl_AppendResult(irp, s, NULL);
1012 if (!pmap) {
1013 pmap = nmalloc(sizeof(struct portmap));
1014 pmap->next = root;
1015 root = pmap;
1016 }
1017 pmap->realport = realport;
1018 pmap->mappedto = port;
1019 putlog(LOG_MISC, "*", "Listening at telnet port %d (%s).", port, argv[2]);
1020 return TCL_OK;
1021 }
1022
1023 static int tcl_boot STDVAR
1024 {
1025 char who[NOTENAMELEN + 1];
1026 int i, ok = 0;
1027
1028 BADARGS(2, 3, " user@bot ?reason?");
1029
1030 strncpyz(who, argv[1], sizeof who);
1031
1032 if (strchr(who, '@') != NULL) {
1033 char whonick[HANDLEN + 1];
1034
1035 splitc(whonick, who, '@');
1036 whonick[HANDLEN] = 0;
1037 if (!egg_strcasecmp(who, botnetnick))
1038 strncpyz(who, whonick, sizeof who);
1039 else if (remote_boots > 0) {
1040 i = nextbot(who);
1041 if (i < 0)
1042 return TCL_OK;
1043 botnet_send_reject(i, botnetnick, NULL, whonick, who,
1044 argv[2] ? argv[2] : "");
1045 } else
1046 return TCL_OK;
1047 }
1048 for (i = 0; i < dcc_total; i++)
1049 if (!ok && (dcc[i].type->flags & DCT_CANBOOT) &&
1050 !egg_strcasecmp(dcc[i].nick, who)) {
1051 do_boot(i, botnetnick, argv[2] ? argv[2] : "");
1052 ok = 1;
1053 }
1054 return TCL_OK;
1055 }
1056
1057 static int tcl_rehash STDVAR
1058 {
1059 BADARGS(1, 1, "");
1060
1061 if (make_userfile) {
1062 putlog(LOG_MISC, "*", USERF_NONEEDNEW);
1063 make_userfile = 0;
1064 }
1065 write_userfile(-1);
1066
1067 putlog(LOG_MISC, "*", USERF_REHASHING);
1068 do_restart = -2;
1069 return TCL_OK;
1070 }
1071
1072 static int tcl_restart STDVAR
1073 {
1074 BADARGS(1, 1, "");
1075
1076 if (!backgrd) {
1077 Tcl_AppendResult(interp, "You can't restart a -n bot", NULL);
1078 return TCL_ERROR;
1079 }
1080 if (make_userfile) {
1081 putlog(LOG_MISC, "*", USERF_NONEEDNEW);
1082 make_userfile = 0;
1083 }
1084 write_userfile(-1);
1085 putlog(LOG_MISC, "*", MISC_RESTARTING);
1086 wipe_timers(interp, &utimer);
1087 wipe_timers(interp, &timer);
1088 do_restart = -1;
1089 return TCL_OK;
1090 }
1091
1092 static int tcl_traffic STDVAR
1093 {
1094 char buf[1024];
1095 unsigned long out_total_today, out_total;
1096 unsigned long in_total_today, in_total;
1097
1098 /* IRC traffic */
1099 sprintf(buf, "irc %ld %ld %ld %ld", itraffic_irc_today, itraffic_irc +
1100 itraffic_irc_today, otraffic_irc_today,
1101 otraffic_irc + otraffic_irc_today);
1102 Tcl_AppendElement(irp, buf);
1103
1104 /* Botnet traffic */
1105 sprintf(buf, "botnet %ld %ld %ld %ld", itraffic_bn_today, itraffic_bn +
1106 itraffic_bn_today, otraffic_bn_today,
1107 otraffic_bn + otraffic_bn_today);
1108 Tcl_AppendElement(irp, buf);
1109
1110 /* Partyline */
1111 sprintf(buf, "partyline %ld %ld %ld %ld", itraffic_dcc_today, itraffic_dcc +
1112 itraffic_dcc_today, otraffic_dcc_today,
1113 otraffic_dcc + otraffic_dcc_today);
1114 Tcl_AppendElement(irp, buf);
1115
1116 /* Transfer */
1117 sprintf(buf, "transfer %ld %ld %ld %ld", itraffic_trans_today,
1118 itraffic_trans + itraffic_trans_today, otraffic_trans_today,
1119 otraffic_trans + otraffic_trans_today);
1120 Tcl_AppendElement(irp, buf);
1121
1122 /* Misc traffic */
1123 sprintf(buf, "misc %ld %ld %ld %ld", itraffic_unknown_today,
1124 itraffic_unknown + itraffic_unknown_today, otraffic_unknown_today,
1125 otraffic_unknown + otraffic_unknown_today);
1126 Tcl_AppendElement(irp, buf);
1127
1128 /* Totals */
1129 in_total_today = itraffic_irc_today + itraffic_bn_today +
1130 itraffic_dcc_today + itraffic_trans_today +
1131 itraffic_unknown_today;
1132 in_total = in_total_today + itraffic_irc + itraffic_bn + itraffic_dcc +
1133 itraffic_trans + itraffic_unknown;
1134 out_total_today = otraffic_irc_today + otraffic_bn_today +
1135 otraffic_dcc_today + itraffic_trans_today +
1136 otraffic_unknown_today;
1137 out_total = out_total_today + otraffic_irc + otraffic_bn + otraffic_dcc +
1138 otraffic_trans + otraffic_unknown;
1139 sprintf(buf, "total %ld %ld %ld %ld", in_total_today, in_total,
1140 out_total_today, out_total);
1141 Tcl_AppendElement(irp, buf);
1142 return TCL_OK;
1143 }
1144
1145 tcl_cmds tcldcc_cmds[] = {
1146 {"putdcc", tcl_putdcc},
1147 {"putdccraw", tcl_putdccraw},
1148 {"putidx", tcl_putdcc},
1149 {"dccsimul", tcl_dccsimul},
1150 {"dccbroadcast", tcl_dccbroadcast},
1151 {"hand2idx", tcl_hand2idx},
1152 {"getchan", tcl_getchan},
1153 {"setchan", tcl_setchan},
1154 {"dccputchan", tcl_dccputchan},
1155 {"console", tcl_console},
1156 {"strip", tcl_strip},
1157 {"echo", tcl_echo},
1158 {"page", tcl_page},
1159 {"control", tcl_control},
1160 {"valididx", tcl_valididx},
1161 {"killdcc", tcl_killdcc},
1162 {"putbot", tcl_putbot},
1163 {"putallbots", tcl_putallbots},
1164 {"idx2hand", tcl_idx2hand},
1165 {"bots", tcl_bots},
1166 {"botlist", tcl_botlist},
1167 {"dcclist", tcl_dcclist},
1168 {"whom", tcl_whom},
1169 {"dccused", tcl_dccused},
1170 {"getdccidle", tcl_getdccidle},
1171 {"getdccaway", tcl_getdccaway},
1172 {"setdccaway", tcl_setdccaway},
1173 {"islinked", tcl_islinked},
1174 {"link", tcl_link},
1175 {"unlink", tcl_unlink},
1176 {"connect", tcl_connect},
1177 {"listen", tcl_listen},
1178 {"boot", tcl_boot},
1179 {"rehash", tcl_rehash},
1180 {"restart", tcl_restart},
1181 {"traffic", tcl_traffic},
1182 {NULL, NULL}
1183 };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23