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

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

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


Revision 1.19 - (show annotations) (download) (as text)
Wed Mar 29 14:56:08 2000 UTC (19 years, 4 months ago) by guppy
Branch: MAIN
CVS Tags: eggdrop104030RC2, eggdrop10404, eggdrop10403, HEAD
Changes since 1.18: +3 -3 lines
File MIME type: text/x-chdr
1.4.3 here I come

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23