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

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

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


Revision 1.11 - (hide annotations) (download) (as text)
Mon Jan 17 21:59:11 2000 UTC (19 years, 4 months ago) by fabian
Branch: MAIN
Changes since 1.10: +4 -8 lines
File MIME type: text/x-chdr
resync with 1.4, 17Jan2000

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23