/[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.36 - (hide annotations) (download) (as text)
Fri Oct 19 01:55:05 2001 UTC (17 years, 7 months ago) by tothwolf
Branch: MAIN
Changes since 1.35: +26 -26 lines
File MIME type: text/x-chdr
* removed obsolete EGG_CHECK_FUNC_VSPRINTF autoconf macro
* removed obsolete EGG_HEADER_STDC autoconf macro
* added EGG_C_LONG_LONG autoconf macro
* added EGG_FUNC_C99_VSNPRINTF autoconf macro
* added EGG_REPLACE_SNPRINTF autoconf macro
* added EGG_TYPE_32BIT autoconf macro

* removed unused dlfcn.h header check from configure.ac
* removed AC_CHECK_SIZEOF long and int from configure.ac
* added many required autoconf macros to configure.ac
* added AC_REPLACE_FUNCS to configure.ac for compat functions
* many configure.ac cleanups

* updated compat/snprintf.c with latest version from Samba
* added code to link libm with compat library for snprintf.c
* added support for LIBOBJS to compat/Makefile.am
* added memset back to compat
* added memcpy back to compat
* many compat cleanups

* renamed egg_strcasecmp() to strcasecmp()
* renamed egg_strncasecmp() to strncasecmp()
* renamed egg_snprintf() to snprintf()
* renamed egg_vsnprintf() to vsnprintf()
* renamed egg_strftime() to strftime()
* renamed egg_inet_aton() to inet_aton()
* renamed egg_inet_ntop() to inet_ntop()
* renamed egg_inet_pton() to inet_pton()

* exported strftime() for modules
* exported inet_ntop() for modules
* exported inet_pton() for modules
* exported vasprintf() for modules
* exported asprintf() for modules

* renamed u_32bit_t typedef to u_32int_t
* extended stat.h to support standard bits and checks

* major function changes:
  + egg_strcasecmp -> strcasecmp
  + egg_strncasecmp -> strncasecmp
  + egg_snprintf -> snprintf
  + egg_vsnprintf -> vsnprintf
  + egg_strftime -> strftime
  + egg_inet_aton -> inet_aton
  + egg_inet_ntop -> inet_ntop
  + egg_inet_pton -> inet_pton

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23