/[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.1.1.1 - (show annotations) (download) (as text) (vendor branch)
Mon Jul 26 21:11:06 2010 UTC (8 years, 10 months ago) by simple
Branch: eggheads
CVS Tags: v1
Changes since 1.1: +0 -0 lines
File MIME type: text/x-chdr
Imported Eggdrop 1.6.20

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23