/[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.20 - (hide annotations) (download) (as text)
Wed Sep 27 19:40:43 2000 UTC (18 years, 7 months ago) by fabian
Branch: MAIN
Changes since 1.19: +1 -2 lines
File MIME type: text/x-chdr
fabian: applied new_dcc_fixes patch

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23