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

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

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


Revision 1.31 - (show annotations) (download) (as text)
Fri Sep 28 03:15:34 2001 UTC (18 years, 9 months ago) by stdarg
Branch: MAIN
Changes since 1.30: +8 -5 lines
File MIME type: text/x-chdr

This is a big patch!
Created several new bind tables (raw, msg, msgm, pub, pubm) to see how it
would work. Seems to work well so far, although there could be bugs.
Added most of the new important bind table functions to the global table.

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23