/[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.30 - (show annotations) (download) (as text)
Fri Aug 10 23:51:20 2001 UTC (18 years, 10 months ago) by ite
Branch: MAIN
Changes since 1.29: +6 -6 lines
File MIME type: text/x-chdr
Gettext phase 1: created a dummy _() macro, replaced old get_lang #defines with the respective string entries in english.*.lang and removed them.

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23