/[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.5 - (show annotations) (download) (as text)
Thu Nov 10 22:07:25 2011 UTC (7 years, 5 months ago) by thommey
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +7 -7 lines
File MIME type: text/x-chdr
Fixed the format specifier for the Tcl [traffic] command.

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23