/[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.55 - (hide annotations) (download) (as text)
Mon Apr 1 13:33:33 2002 UTC (17 years, 1 month ago) by ite
Branch: MAIN
Changes since 1.54: +9 -9 lines
File MIME type: text/x-chdr
* Got rid of strncpyz() in favour of BSD's strlcpy(). Fallback function provided.
* BSD's strlcat() provided as fallback function.
* Fallback functions weren't linked as expected when needed.

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 ite 1.55 * $Id: tcldcc.c,v 1.54 2002/03/26 01:06:22 ite Exp $
6 segfault 1.1 */
7 guppy 1.27 /*
8     * Copyright (C) 1997 Robey Pointer
9 wcc 1.50 * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
10 guppy 1.27 *
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 ite 1.47 #include "logfile.h"
30     #include "misc.h"
31 segfault 1.1
32 fabian 1.13 extern struct dcc_t *dcc;
33     extern int dcc_total, backgrd, parties, make_userfile,
34     do_restart, remote_boots, max_dcc;
35     extern char botnetnick[];
36     extern party_t *party;
37     extern tand_t *tandbot;
38     extern time_t now;
39    
40 ite 1.48 /* Traffic stuff. */
41     extern unsigned long otraffic_irc, otraffic_irc_today, itraffic_irc, itraffic_irc_today, otraffic_bn, otraffic_bn_today, itraffic_bn, itraffic_bn_today, otraffic_dcc, otraffic_dcc_today, itraffic_dcc, itraffic_dcc_today, otraffic_trans, otraffic_trans_today, itraffic_trans, itraffic_trans_today, otraffic_unknown, otraffic_unknown_today, itraffic_unknown, itraffic_unknown_today;
42 fabian 1.13
43     static struct portmap *root = NULL;
44    
45 segfault 1.1
46     /***********************************************************************/
47    
48 stdarg 1.39 static int script_putdcc(int idx, char *text)
49 segfault 1.1 {
50 stdarg 1.39 if (idx < 0 || idx >= dcc_total || !dcc[idx].type) return(1);
51     dumplots(-(dcc[idx].sock), "", text);
52     return(0);
53 segfault 1.1 }
54    
55 fabian 1.13 /* Allows tcl scripts to send out raw data. Can be used for fast server
56 stdarg 1.37 * write (idx=-1)
57 guppy 1.27 *
58 fabian 1.13 * usage:
59 guppy 1.27 * putdccraw <idx> <size> <rawdata>
60 fabian 1.13 * example:
61     * putdccraw 6 13 "eggdrop rulz\n"
62     *
63     * (added by drummer@sophia.jpte.hu)
64     */
65 guppy 1.23
66 stdarg 1.39 static int script_putdccraw(int idx, int len, char *text)
67 segfault 1.1 {
68 stdarg 1.39 int i;
69 segfault 1.1
70 stdarg 1.37 if (idx == -1) {
71     /* -1 means search for the server's idx. */
72     for (i = 0; i < dcc_total; i++) {
73     if (!strcmp(dcc[i].nick, "(server)")) {
74     idx = i;
75     break;
76     }
77 fabian 1.17 }
78 segfault 1.1 }
79 stdarg 1.39 if (idx < 0 || idx >= dcc_total || !dcc[idx].type) return(1);
80     tputs(dcc[idx].sock, text, len);
81     return(0);
82 segfault 1.1 }
83    
84 stdarg 1.39 static int script_dccsimul(int idx, char *cmd)
85 segfault 1.1 {
86 stdarg 1.39 int len;
87     if (idx < 0 || !dcc->type || !(dcc[idx].type->flags & DCT_SIMUL)
88     || !(dcc[idx].type->activity)) return(1);
89 fabian 1.19
90 stdarg 1.39 len = strlen(cmd);
91     if (len > 510) len = 510;
92 segfault 1.1
93 stdarg 1.39 dcc[idx].type->activity(idx, cmd, len);
94     return(0);
95 segfault 1.1 }
96    
97 stdarg 1.39 static int script_dccbroadcast(char *msg)
98 segfault 1.1 {
99     chatout("*** %s\n", msg);
100     botnet_send_chat(-1, botnetnick, msg);
101 stdarg 1.39 return(0);
102 segfault 1.1 }
103    
104 stdarg 1.39 static int script_hand2idx(char *nick)
105 segfault 1.1 {
106     int i;
107    
108 stdarg 1.39 for (i = 0; i < dcc_total; i++) {
109     if ((dcc[i].type) && (dcc[i].type->flags & DCT_SIMUL) &&
110     !strcasecmp(nick, dcc[i].nick)) {
111     return(i);
112 segfault 1.1 }
113 stdarg 1.39 }
114     return(-1);
115 segfault 1.1 }
116    
117 stdarg 1.39 static int script_getchan(int idx)
118 segfault 1.1 {
119 stdarg 1.39 if (idx < 0 || !(dcc[idx].type) ||
120 guppy 1.23 (dcc[idx].type != &DCC_CHAT && dcc[idx].type != &DCC_SCRIPT)) {
121 stdarg 1.39 return(-2);
122 segfault 1.1 }
123     if (dcc[idx].type == &DCC_SCRIPT)
124 stdarg 1.39 return(dcc[idx].u.script->u.chat->channel);
125 segfault 1.1 else
126 stdarg 1.39 return(dcc[idx].u.chat->channel);
127 segfault 1.1 }
128    
129 stdarg 1.39 static int script_setchan(int idx, int chan)
130 segfault 1.1 {
131 stdarg 1.39 int oldchan;
132 segfault 1.1
133 stdarg 1.39 if (idx < 0 || !(dcc[idx].type) ||
134 guppy 1.23 (dcc[idx].type != &DCC_CHAT && dcc[idx].type != &DCC_SCRIPT)) {
135 stdarg 1.39 return(1);
136 segfault 1.1 }
137 stdarg 1.39
138 segfault 1.1 if ((chan < -1) || (chan > 199999)) {
139 stdarg 1.39 return(1);
140 segfault 1.1 }
141 stdarg 1.39 if (dcc[idx].type == &DCC_SCRIPT) {
142 segfault 1.1 dcc[idx].u.script->u.chat->channel = chan;
143 stdarg 1.39 return(0);
144     }
145 segfault 1.1
146 stdarg 1.39 oldchan = dcc[idx].u.chat->channel;
147 guppy 1.24
148 stdarg 1.39 if (oldchan >= 0) {
149     if ((chan >= GLOBAL_CHANS) && (oldchan < GLOBAL_CHANS)) botnet_send_part_idx(idx, "*script*");
150     check_tcl_chpt(botnetnick, dcc[idx].nick, idx, oldchan);
151 fabian 1.3 }
152 stdarg 1.39 dcc[idx].u.chat->channel = chan;
153     if (chan < GLOBAL_CHANS) botnet_send_join_idx(idx, oldchan);
154 ite 1.49 check_tcl_chjn(botnetnick, dcc[idx].nick, chan, geticon(dcc[idx].user),
155 stdarg 1.39 idx, dcc[idx].host);
156     return(0);
157 segfault 1.1 }
158    
159 stdarg 1.39 static int script_dccputchan(int chan, char *msg)
160 segfault 1.1 {
161 stdarg 1.39 if ((chan < 0) || (chan > 199999)) return(1);
162     chanout_but(-1, chan, "*** %s\n", msg);
163     botnet_send_chan(-1, botnetnick, NULL, chan, msg);
164     check_tcl_bcst(botnetnick, chan, msg);
165     return(0);
166 segfault 1.1 }
167    
168 stdarg 1.41 static int script_console(script_var_t *retval, int nargs, int idx, char *what)
169 segfault 1.1 {
170 stdarg 1.41 static char *view[2];
171     char str[2];
172     int plus;
173    
174     str[1] = 0;
175    
176     if (idx < 0 || idx >= dcc_total || !dcc[idx].type || dcc[idx].type != &DCC_CHAT) {
177     retval->value = "invalid idx";
178     retval->len = 10;
179     retval->type = SCRIPT_ERROR | SCRIPT_STRING;
180     }
181    
182     retval->type = SCRIPT_ARRAY | SCRIPT_STRING;
183     retval->len = 2;
184     view[0] = dcc[idx].u.chat->con_chan;
185     view[1] = masktype(dcc[idx].u.chat->con_flags);
186     retval->value = (void *)view;
187    
188     if (nargs != 2) {
189     view[1] = masktype(dcc[idx].u.chat->con_flags);
190     return(0); /* Done. */
191     }
192 segfault 1.1
193 stdarg 1.41 /* They want to change something. */
194     if (strchr(CHANMETA, what[0]) != NULL) {
195     /* The channel. */
196 ite 1.55 strlcpy(dcc[idx].u.chat->con_chan, what, 80);
197 stdarg 1.41 return(0);
198 segfault 1.1 }
199 guppy 1.24
200 stdarg 1.41 /* The flags. */
201     if (*what != '+' && *what != '-') dcc[idx].u.chat->con_flags = 0;
202     for (plus = 1; *what; what++) {
203     if (*what == '-') plus = 0;
204     else if (*what == '+') plus = 1;
205     else {
206     str[0] = *what;
207     if (plus) dcc[idx].u.chat->con_flags |= logmodes(str);
208     else dcc[idx].u.chat->con_flags &= (~logmodes(str));
209     }
210     }
211     view[1] = masktype(dcc[idx].u.chat->con_flags);
212     return(0);
213 segfault 1.1 }
214    
215 stdarg 1.41 static int script_strip(script_var_t *retval, int nargs, int idx, char *what)
216 segfault 1.1 {
217 stdarg 1.41 char str[2];
218     int plus;
219 segfault 1.1
220 stdarg 1.41 str[1] = 0;
221 segfault 1.1
222 stdarg 1.41 if (idx < 0 || idx >= dcc_total || !dcc[idx].type || dcc[idx].type != &DCC_CHAT) {
223     retval->value = "invalid idx";
224     retval->len = 10;
225     retval->type = SCRIPT_ERROR | SCRIPT_STRING;
226     }
227 guppy 1.24
228 stdarg 1.41 retval->len = -1;
229     retval->type = SCRIPT_STRING;
230 segfault 1.1
231 stdarg 1.41 if (nargs == 1) {
232     retval->value = stripmasktype(dcc[idx].u.chat->strip_flags);
233     return(0);
234     }
235 segfault 1.1
236 stdarg 1.41 /* The flags. */
237     if (*what != '+' && *what != '-') dcc[idx].u.chat->strip_flags = 0;
238     for (plus = 1; *what; what++) {
239     if (*what == '-') plus = 0;
240     else if (*what == '+') plus = 1;
241     else {
242     str[0] = *what;
243     if (plus) dcc[idx].u.chat->con_flags |= stripmodes(str);
244     else dcc[idx].u.chat->con_flags &= (~stripmodes(str));
245     }
246     }
247 guppy 1.24
248 stdarg 1.41 retval->value = stripmasktype(dcc[idx].u.chat->strip_flags);
249     return(0);
250 segfault 1.1 }
251    
252 stdarg 1.41 static int script_echo(int nargs, int idx, int status)
253 segfault 1.1 {
254 stdarg 1.41 if (idx < 0 || idx >= dcc_total || !dcc[idx].type || dcc[idx].type != &DCC_CHAT) return(0);
255     if (nargs == 2) {
256     if (status) dcc[idx].status |= STAT_ECHO;
257     else dcc[idx].status &= (~STAT_ECHO);
258     }
259 segfault 1.1
260 stdarg 1.41 if (dcc[idx].status & STAT_ECHO) return(1);
261     return(0);
262     }
263 segfault 1.1
264 stdarg 1.41 static int script_page(int nargs, int idx, int status)
265     {
266     if (idx < 0 || idx >= dcc_total || !dcc[idx].type || dcc[idx].type != &DCC_CHAT) return(0);
267 guppy 1.24
268 stdarg 1.41 if (nargs == 2) {
269     if (status) {
270     dcc[idx].status |= STAT_PAGE;
271     dcc[idx].u.chat->max_line = status;
272     }
273     else dcc[idx].status &= (~STAT_PAGE);
274     }
275     if (dcc[idx].status & STAT_PAGE) return(dcc[idx].u.chat->max_line);
276     return(0);
277 segfault 1.1 }
278    
279     static int tcl_control STDVAR
280     {
281 fabian 1.19 int idx;
282 segfault 1.1 void *hold;
283    
284     BADARGS(3, 3, " idx command");
285 stdarg 1.53 idx = atoi(argv[1]);
286 segfault 1.1 if (idx < 0) {
287     Tcl_AppendResult(irp, "invalid idx", NULL);
288     return TCL_ERROR;
289     }
290 stdarg 1.52 if (dcc[idx].type && dcc[idx].type->flags & DCT_CHAT) {
291 segfault 1.1 if (dcc[idx].u.chat->channel >= 0) {
292     chanout_but(idx, dcc[idx].u.chat->channel, "*** %s has gone.\n",
293     dcc[idx].nick);
294     check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock,
295     dcc[idx].u.chat->channel);
296     botnet_send_part_idx(idx, "gone");
297     }
298     check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
299     }
300     hold = dcc[idx].u.other;
301 tothwolf 1.34 dcc[idx].u.script = calloc(1, sizeof(struct script_info));
302 segfault 1.1 dcc[idx].u.script->u.other = hold;
303     dcc[idx].u.script->type = dcc[idx].type;
304     dcc[idx].type = &DCC_SCRIPT;
305 fabian 1.22 /* Do not buffer data anymore. All received and stored data is passed
306     over to the dcc functions from now on. */
307     sockoptions(dcc[idx].sock, EGG_OPTION_UNSET, SOCK_BUFFER);
308 ite 1.55 strlcpy(dcc[idx].u.script->command, argv[2], 120);
309 segfault 1.1 return TCL_OK;
310     }
311    
312 stdarg 1.41 static int script_valididx(int idx)
313 segfault 1.1 {
314 stdarg 1.41 if (idx < 0 || idx >= dcc_total || !dcc[idx].type || !(dcc[idx].type->flags & DCT_VALIDIDX)) return(0);
315     return(1);
316 segfault 1.1 }
317    
318     static int tcl_killdcc STDVAR
319     {
320 fabian 1.19 int idx;
321 segfault 1.1
322     BADARGS(2, 3, " idx ?reason?");
323 stdarg 1.53 idx = atoi(argv[1]);
324 segfault 1.1 if (idx < 0) {
325     Tcl_AppendResult(irp, "invalid idx", NULL);
326     return TCL_ERROR;
327     }
328 fabian 1.13 /* Don't kill terminal socket */
329 segfault 1.1 if ((dcc[idx].sock == STDOUT) && !backgrd)
330     return TCL_OK;
331 fabian 1.13 /* Make sure 'whom' info is updated for other bots */
332 segfault 1.1 if (dcc[idx].type->flags & DCT_CHAT) {
333     chanout_but(idx, dcc[idx].u.chat->channel, "*** %s has left the %s%s%s\n",
334     dcc[idx].nick, dcc[idx].u.chat ? "channel" : "partyline",
335     argc == 3 ? ": " : "", argc == 3 ? argv[2] : "");
336     botnet_send_part_idx(idx, argc == 3 ? argv[2] : "");
337 stdarg 1.31 if ((dcc[idx].u.chat->channel >= 0) && (dcc[idx].u.chat->channel < GLOBAL_CHANS)) {
338     check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock, dcc[idx].u.chat->channel);
339     }
340 segfault 1.1 check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
341 fabian 1.13 /* Notice is sent to the party line, the script can add a reason. */
342 segfault 1.1 }
343     killsock(dcc[idx].sock);
344     lostdcc(idx);
345     return TCL_OK;
346     }
347    
348 stdarg 1.42 static int script_putbot(char *target, char *text)
349 segfault 1.1 {
350     int i;
351    
352 stdarg 1.42 i = nextbot(target);
353     if (i < 0) return(1);
354     botnet_send_zapf(i, botnetnick, target, text);
355     return(0);
356 segfault 1.1 }
357    
358 stdarg 1.42 static int script_putallbots(char *text)
359 segfault 1.1 {
360 stdarg 1.42 botnet_send_zapf_broad(-1, botnetnick, NULL, text);
361     return(0);
362     }
363 segfault 1.1
364 stdarg 1.42 static char *script_idx2hand(int idx)
365     {
366     if (idx < 0 || idx >= dcc_total || !(dcc[idx].type) || !(dcc[idx].nick)) return("");
367     return(dcc[idx].nick);
368 segfault 1.1 }
369    
370 stdarg 1.42 static int script_islinked(char *bot)
371 segfault 1.1 {
372 stdarg 1.42 return nextbot(bot);
373 segfault 1.1 }
374    
375 stdarg 1.42 static int script_bots(script_var_t *retval)
376 segfault 1.1 {
377 stdarg 1.42 char **botlist = NULL;
378     int nbots = 0;
379     tand_t *bot;
380 segfault 1.1
381 stdarg 1.42 for (bot = tandbot; bot; bot = bot->next) {
382     nbots++;
383     botlist = (char **)realloc(botlist, sizeof(char *) * nbots);
384     botlist[nbots-1] = strdup(bot->bot);
385     }
386     retval->type = SCRIPT_ARRAY | SCRIPT_FREE | SCRIPT_STRING;
387     retval->value = (void *)botlist;
388     retval->len = nbots;
389     return(0);
390 segfault 1.1 }
391    
392 stdarg 1.42 static int script_botlist(script_var_t *retval)
393 segfault 1.1 {
394 stdarg 1.42 tand_t *bot;
395     script_var_t *sublist, *nick, *uplink, *version, *share;
396     char sharestr[2];
397    
398     retval->type = SCRIPT_ARRAY | SCRIPT_FREE | SCRIPT_VAR;
399     retval->len = 0;
400     retval->value = NULL;
401     sharestr[1] = 0;
402     for (bot = tandbot; bot; bot = bot->next) {
403     nick = script_string(bot->bot, -1);
404     uplink = script_string((bot->uplink == (tand_t *)1) ? botnetnick : bot->uplink->bot, -1);
405     version = script_int(bot->ver);
406     sharestr[0] = bot->share;
407     share = script_string(strdup(sharestr), -1);
408 segfault 1.1
409 stdarg 1.42 sublist = script_list(4, nick, uplink, version, share);
410     script_list_append(retval, sublist);
411     }
412     return(0);
413 segfault 1.1 }
414    
415 fabian 1.13 /* list of { idx nick host type {other} timestamp}
416     */
417 stdarg 1.42 static int script_dcclist(script_var_t *retval, char *match)
418 segfault 1.1 {
419 stdarg 1.42 int i;
420     script_var_t *sublist, *idx, *nick, *host, *type, *othervar, *timestamp;
421     char other[160];
422    
423     retval->type = SCRIPT_ARRAY | SCRIPT_FREE | SCRIPT_VAR;
424     retval->len = 0;
425     retval->value = NULL;
426     for (i = 0; i < dcc_total; i++) {
427     if (!(dcc[i].type)) continue;
428     if (match && strcasecmp(dcc[i].type->name, match)) continue;
429    
430     idx = script_int(i);
431     nick = script_string(dcc[i].nick, -1);
432     host = script_string(dcc[i].host, -1);
433     type = script_string(dcc[i].type->name, -1);
434     if (dcc[i].type->display) dcc[i].type->display(i, other);
435     else sprintf(other, "?:%X !! ERROR !!", (int) dcc[i].type);
436     othervar = script_string(strdup(other), -1);
437     othervar->type |= SCRIPT_FREE;
438     timestamp = script_int(dcc[i].timeval);
439 segfault 1.1
440 stdarg 1.42 sublist = script_list(6, idx, nick, host, type, othervar, timestamp);
441     script_list_append(retval, sublist);
442     }
443     return(0);
444 segfault 1.1 }
445    
446 stdarg 1.45 static void whom_entry(script_var_t *retval, char *nick, char *bot, char *host ,char icon, int idletime, char *away, int chan)
447     {
448     script_var_t *sublist, *vnick, *vbot, *vhost, *vflag, *vidle, *vaway, *vchan;
449     char flag[2];
450    
451     vnick = script_string(nick, -1);
452     vbot = script_string(bot, -1);
453     vhost = script_string(host, -1);
454    
455     flag[0] = icon;
456     flag[1] = 0;
457     vflag = script_string(strdup(flag), 1);
458     vflag->type |= SCRIPT_FREE;
459    
460     vidle = script_int((now - idletime) / 60);
461     vaway = script_string(away ? away : "", -1);
462     vchan = script_int(chan);
463    
464     sublist = script_list(7, vnick, vbot, vhost, vflag, vidle, vaway, vchan);
465     script_list_append(retval, sublist);
466     }
467    
468     /* list of {nick bot host flag idletime awaymsg channel}
469 fabian 1.13 */
470 stdarg 1.45 static int script_whom(script_var_t *retval, int nargs, int which_chan)
471 segfault 1.1 {
472 stdarg 1.45 int i;
473 segfault 1.1
474 stdarg 1.45 retval->type = SCRIPT_ARRAY | SCRIPT_FREE | SCRIPT_VAR;
475     retval->len = 0;
476     retval->value = NULL;
477    
478     if (nargs == 0) which_chan = -1;
479    
480     for (i = 0; i < dcc_total; i++) {
481     if (dcc[i].type != &DCC_CHAT) continue;
482     if (which_chan != -1 && dcc[i].u.chat->channel != which_chan) continue;
483 ite 1.49 whom_entry(retval, dcc[i].nick, botnetnick, dcc[i].host,
484     geticon(dcc[i].user), dcc[i].timeval, dcc[i].u.chat->away,
485     dcc[i].u.chat->channel);
486 stdarg 1.45 }
487     for (i = 0; i < parties; i++) {
488     if (which_chan != -1 && party[i].chan != which_chan) continue;
489     whom_entry(retval, party[i].nick, party[i].bot, party[i].from, party[i].flag, party[i].timer, party[i].status & PLSTAT_AWAY ? party[i].away : "", party[i].chan);
490     }
491     return(0);
492 segfault 1.1 }
493    
494 stdarg 1.42 static int script_dccused()
495 segfault 1.1 {
496 stdarg 1.42 return(dcc_total);
497 segfault 1.1 }
498    
499 stdarg 1.42 static int script_getdccidle(int idx)
500 segfault 1.1 {
501 stdarg 1.42 if (idx < 0 || idx >= dcc_total || !(dcc->type)) return(-1);
502     return(now - dcc[idx].timeval);
503 segfault 1.1 }
504    
505 stdarg 1.42 static char *script_getdccaway(int idx)
506 segfault 1.1 {
507 stdarg 1.42 if (idx < 0 || idx >= dcc_total || !(dcc[idx].type) || dcc[idx].type != &DCC_CHAT) return("");
508     if (dcc[idx].u.chat->away == NULL) return("");
509     return(dcc[idx].u.chat->away);
510 segfault 1.1 }
511    
512 stdarg 1.42 static int script_setdccaway(int idx, char *text)
513 segfault 1.1 {
514 stdarg 1.42 if (idx < 0 || idx >= dcc_total || !(dcc[idx].type) || dcc[idx].type != &DCC_CHAT) return(1);
515     if (!text || !text[0]) {
516     /* un-away */
517     if (dcc[idx].u.chat->away != NULL) not_away(idx);
518     }
519     else set_away(idx, text);
520     return(0);
521 segfault 1.1 }
522    
523 stdarg 1.42 static int script_link(char *via, char *target)
524 segfault 1.1 {
525 stdarg 1.42 int x, i;
526 segfault 1.1
527 stdarg 1.42 if (!via) x = botlink("", -2, target);
528     else {
529     x = 1;
530     i = nextbot(via);
531     if (i < 0) x = 0;
532     else botnet_send_link(i, botnetnick, via, target);
533     }
534     return(x);
535 segfault 1.1 }
536    
537 stdarg 1.42 static int script_unlink(char *bot, char *comment)
538 segfault 1.1 {
539 stdarg 1.42 int i, x;
540 segfault 1.1
541 stdarg 1.42 i = nextbot(bot);
542     if (i < 0) return(0);
543     if (!strcasecmp(bot, dcc[i].nick)) x = botunlink(-2, bot, comment);
544     else {
545     x = 1;
546     botnet_send_unlink(i, botnetnick, lastbot(bot), bot, comment);
547     }
548     return(x);
549 segfault 1.1 }
550    
551     static int tcl_connect STDVAR
552     {
553     int i, z, sock;
554     char s[81];
555    
556     BADARGS(3, 3, " hostname port");
557     if (dcc_total == max_dcc) {
558     Tcl_AppendResult(irp, "out of dcc table space", NULL);
559     return TCL_ERROR;
560     }
561     sock = getsock(0);
562 fabian 1.21 if (sock < 0) {
563 ite 1.30 Tcl_AppendResult(irp, _("No free sockets available."), NULL);
564 fabian 1.21 return TCL_ERROR;
565     }
566 segfault 1.1 z = open_telnet_raw(sock, argv[1], atoi(argv[2]));
567     if (z < 0) {
568 fabian 1.3 killsock(sock);
569 segfault 1.1 if (z == (-2))
570 ite 1.55 strlcpy(s, "DNS lookup failed", sizeof s);
571 segfault 1.1 else
572     neterror(s);
573     Tcl_AppendResult(irp, s, NULL);
574     return TCL_ERROR;
575     }
576 fabian 1.13 /* Well well well... it worked! */
577 segfault 1.1 i = new_dcc(&DCC_SOCKET, 0);
578     dcc[i].sock = sock;
579     dcc[i].port = atoi(argv[2]);
580     strcpy(dcc[i].nick, "*");
581 ite 1.55 strlcpy(dcc[i].host, argv[1], UHOSTMAX);
582 stdarg 1.52 snprintf(s, sizeof s, "%d", i);
583 segfault 1.1 Tcl_AppendResult(irp, s, NULL);
584     return TCL_OK;
585     }
586    
587 fabian 1.13 /* Create a new listening port (or destroy one)
588     *
589     * listen <port> bots/all/users [mask]
590 fabian 1.10 * listen <port> script <proc> [flag]
591 fabian 1.13 * listen <port> off
592     */
593 segfault 1.1 static int tcl_listen STDVAR
594     {
595     int i, j, idx = (-1), port, realport;
596 guppy 1.28 char s[11];
597 segfault 1.1 struct portmap *pmap = NULL, *pold = NULL;
598 drummer 1.29 int af = AF_INET /* af_preferred */;
599    
600     BADARGS(3, 6, " ?-4/-6? port type ?mask?/?proc ?flag??");
601     if (!strcmp(argv[1], "-4") || !strcmp(argv[1], "-6")) {
602     if (argv[1][1] == '4')
603     af = AF_INET;
604     else
605     af = AF_INET6;
606     argv[1] = argv[0]; /* UGLY! */
607     argv++;
608     argc--;
609     }
610     BADARGS(3, 6, " ?-4/-6? port type ?mask?/?proc ?flag??");
611 segfault 1.1
612     port = realport = atoi(argv[1]);
613     for (pmap = root; pmap; pold = pmap, pmap = pmap->next)
614     if (pmap->realport == port) {
615     port = pmap->mappedto;
616     break;
617     }
618     for (i = 0; i < dcc_total; i++)
619     if ((dcc[i].type == &DCC_TELNET) && (dcc[i].port == port))
620     idx = i;
621 tothwolf 1.36 if (!strcasecmp(argv[2], "off")) {
622 segfault 1.1 if (pmap) {
623     if (pold)
624     pold->next = pmap->next;
625     else
626     root = pmap->next;
627 tothwolf 1.33 free(pmap);
628 segfault 1.1 }
629 fabian 1.13 /* Remove */
630 segfault 1.1 if (idx < 0) {
631     Tcl_AppendResult(irp, "no such listen port is open", NULL);
632     return TCL_ERROR;
633     }
634     killsock(dcc[idx].sock);
635     lostdcc(idx);
636     return TCL_OK;
637     }
638     if (idx < 0) {
639 fabian 1.13 /* Make new one */
640 segfault 1.1 if (dcc_total >= max_dcc) {
641     Tcl_AppendResult(irp, "no more DCC slots available", NULL);
642     return TCL_ERROR;
643     }
644 fabian 1.13 /* Try to grab port */
645 segfault 1.1 j = port + 20;
646     i = (-1);
647 guppy 1.24 while (port < j && i < 0) {
648 drummer 1.29 i = open_listen(&port, af);
649 guppy 1.25 if (i == -1)
650 segfault 1.1 port++;
651 guppy 1.25 else if (i == -2)
652     break;
653 segfault 1.1 }
654 guppy 1.25 if (i == -1) {
655     Tcl_AppendResult(irp, "Couldn't grab nearby port", NULL);
656     return TCL_ERROR;
657     } else if (i == -2) {
658 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);
659 segfault 1.1 return TCL_ERROR;
660     }
661     idx = new_dcc(&DCC_TELNET, 0);
662 drummer 1.29 strcpy(dcc[idx].addr, "*"); /* who cares? */
663 segfault 1.1 dcc[idx].port = port;
664     dcc[idx].sock = i;
665 fabian 1.2 dcc[idx].timeval = now;
666 segfault 1.1 }
667     /* script? */
668 guppy 1.24 if (!strcmp(argv[2], "script")) {
669 segfault 1.1 strcpy(dcc[idx].nick, "(script)");
670     if (argc < 4) {
671     Tcl_AppendResult(irp, "must give proc name for script listen", NULL);
672     killsock(dcc[idx].sock);
673 fabian 1.10 lostdcc(idx);
674 segfault 1.1 return TCL_ERROR;
675 fabian 1.10 }
676     if (argc == 5) {
677 guppy 1.24 if (strcmp(argv[4], "pub")) {
678 fabian 1.10 Tcl_AppendResult(irp, "unknown flag: ", argv[4], ". allowed flags: pub",
679     NULL);
680     killsock(dcc[idx].sock);
681     lostdcc(idx);
682     return TCL_ERROR;
683     }
684     dcc[idx].status = LSTN_PUBLIC;
685 segfault 1.1 }
686 ite 1.55 strlcpy(dcc[idx].host, argv[3], UHOSTMAX);
687 tothwolf 1.36 snprintf(s, sizeof s, "%d", port);
688 segfault 1.1 Tcl_AppendResult(irp, s, NULL);
689     return TCL_OK;
690     }
691     /* bots/users/all */
692 guppy 1.24 if (!strcmp(argv[2], "bots"))
693 segfault 1.1 strcpy(dcc[idx].nick, "(bots)");
694 guppy 1.24 else if (!strcmp(argv[2], "users"))
695 segfault 1.1 strcpy(dcc[idx].nick, "(users)");
696 guppy 1.24 else if (!strcmp(argv[2], "all"))
697 segfault 1.1 strcpy(dcc[idx].nick, "(telnet)");
698     if (!dcc[idx].nick[0]) {
699     Tcl_AppendResult(irp, "illegal listen type: must be one of ",
700     "bots, users, all, off, script", NULL);
701     killsock(dcc[idx].sock);
702     dcc_total--;
703     return TCL_ERROR;
704     }
705     if (argc == 4) {
706 ite 1.55 strlcpy(dcc[idx].host, argv[3], UHOSTMAX);
707 segfault 1.1 } else
708     strcpy(dcc[idx].host, "*");
709 tothwolf 1.36 snprintf(s, sizeof s, "%d", port);
710 segfault 1.1 Tcl_AppendResult(irp, s, NULL);
711     if (!pmap) {
712 tothwolf 1.33 pmap = malloc(sizeof(struct portmap));
713 segfault 1.1 pmap->next = root;
714     root = pmap;
715     }
716     pmap->realport = realport;
717     pmap->mappedto = port;
718     putlog(LOG_MISC, "*", "Listening at telnet port %d (%s)", port, argv[2]);
719     return TCL_OK;
720     }
721    
722 stdarg 1.42 static int script_boot(char *user_bot, char *reason)
723 segfault 1.1 {
724 fabian 1.16 char who[NOTENAMELEN + 1];
725 stdarg 1.42 int i;
726 segfault 1.1
727 ite 1.55 strlcpy(who, user_bot, sizeof who);
728 segfault 1.1 if (strchr(who, '@') != NULL) {
729 fabian 1.16 char whonick[HANDLEN + 1];
730    
731     splitc(whonick, who, '@');
732     whonick[HANDLEN] = 0;
733 tothwolf 1.36 if (!strcasecmp(who, botnetnick))
734 ite 1.55 strlcpy(who, whonick, sizeof who);
735 guppy 1.26 else if (remote_boots > 0) {
736 segfault 1.1 i = nextbot(who);
737 stdarg 1.42 if (i < 0) return(0);
738 guppy 1.44 botnet_send_reject(i, botnetnick, NULL, whonick, who, reason ? reason : "");
739 segfault 1.1 }
740 stdarg 1.42 else return(0);
741 segfault 1.1 }
742     for (i = 0; i < dcc_total; i++)
743 stdarg 1.42 if ((dcc[i].type) && (dcc[i].type->flags & DCT_CANBOOT) &&
744 tothwolf 1.36 !strcasecmp(dcc[i].nick, who)) {
745 stdarg 1.42 do_boot(i, botnetnick, reason ? reason : "");
746     break;
747 segfault 1.1 }
748 stdarg 1.42 return(0);
749 segfault 1.1 }
750    
751 stdarg 1.42 static int script_rehash()
752 segfault 1.1 {
753     if (make_userfile) {
754 ite 1.30 putlog(LOG_MISC, "*", _("Userfile creation not necessary--skipping"));
755 segfault 1.1 make_userfile = 0;
756     }
757     write_userfile(-1);
758 ite 1.30 putlog(LOG_MISC, "*", _("Rehashing..."));
759 segfault 1.1 do_restart = -2;
760 stdarg 1.42 return(0);
761 segfault 1.1 }
762    
763 stdarg 1.42 static int script_restart()
764 segfault 1.1 {
765 stdarg 1.42 if (!backgrd) return(1);
766 segfault 1.1 if (make_userfile) {
767 ite 1.30 putlog(LOG_MISC, "*", _("Userfile creation not necessary--skipping"));
768 segfault 1.1 make_userfile = 0;
769     }
770     write_userfile(-1);
771 ite 1.30 putlog(LOG_MISC, "*", _("Restarting..."));
772 segfault 1.1 do_restart = -1;
773 stdarg 1.42 return(0);
774 segfault 1.1 }
775    
776 ite 1.48 static int tcl_traffic STDVAR
777     {
778     char buf[1024];
779     unsigned long out_total_today, out_total;
780     unsigned long in_total_today, in_total;
781    
782     /* IRC traffic */
783     sprintf(buf, "irc %ld %ld %ld %ld", itraffic_irc_today,
784     itraffic_irc + itraffic_irc_today, otraffic_irc_today,
785     otraffic_irc + otraffic_irc_today);
786     Tcl_AppendElement(irp, buf);
787    
788     /* Botnet traffic */
789     sprintf(buf, "botnet %ld %ld %ld %ld", itraffic_bn_today,
790     itraffic_bn + itraffic_bn_today, otraffic_bn_today,
791     otraffic_bn + otraffic_bn_today);
792     Tcl_AppendElement(irp, buf);
793    
794     /* Partyline */
795     sprintf(buf, "partyline %ld %ld %ld %ld", itraffic_dcc_today,
796     itraffic_dcc + itraffic_dcc_today, otraffic_dcc_today,
797     otraffic_dcc + otraffic_dcc_today);
798     Tcl_AppendElement(irp, buf);
799    
800     /* Transfer */
801     sprintf(buf, "transfer %ld %ld %ld %ld", itraffic_trans_today,
802     itraffic_trans + itraffic_trans_today, otraffic_trans_today,
803     otraffic_trans + otraffic_trans_today);
804     Tcl_AppendElement(irp, buf);
805    
806     /* Misc traffic */
807     sprintf(buf, "misc %ld %ld %ld %ld", itraffic_unknown_today,
808     itraffic_unknown + itraffic_unknown_today, otraffic_unknown_today,
809     otraffic_unknown + otraffic_unknown_today);
810     Tcl_AppendElement(irp, buf);
811    
812     /* Totals */
813     in_total_today = itraffic_irc_today + itraffic_bn_today + itraffic_dcc_today
814     + itraffic_trans_today + itraffic_unknown_today,
815     in_total = in_total_today + itraffic_irc + itraffic_bn + itraffic_dcc
816     + itraffic_trans + itraffic_unknown;
817     out_total_today = otraffic_irc_today + otraffic_bn_today + otraffic_dcc_today
818     + itraffic_trans_today + otraffic_unknown_today,
819     out_total = out_total_today + otraffic_irc + otraffic_bn + otraffic_dcc
820     + otraffic_trans + otraffic_unknown;
821     sprintf(buf, "total %ld %ld %ld %ld",
822     in_total_today, in_total, out_total_today, out_total);
823     Tcl_AppendElement(irp, buf);
824     return(TCL_OK);
825     }
826    
827 stdarg 1.39 script_simple_command_t script_dcc_cmds[] = {
828     {"", NULL, NULL, NULL, 0},
829     {"putdcc", script_putdcc, "is", "idx text", SCRIPT_INTEGER},
830     {"putdccraw", script_putdccraw, "iis", "idx len text", SCRIPT_INTEGER},
831     {"dccsimul", script_dccsimul, "is", "idx command", SCRIPT_INTEGER},
832     {"dccbroadcast", script_dccbroadcast, "s", "text", SCRIPT_INTEGER},
833     {"hand2idx", script_hand2idx, "s", "handle", SCRIPT_INTEGER},
834     {"getchan", script_getchan, "i", "idx", SCRIPT_INTEGER},
835     {"setchan", script_setchan, "ii", "idx chan", SCRIPT_INTEGER},
836     {"dccputchan", script_dccputchan, "is", "chan text", SCRIPT_INTEGER},
837 stdarg 1.41 {"valididx", script_valididx, "i", "idx", SCRIPT_INTEGER},
838 stdarg 1.42 {"putbot", script_putbot, "ss", "bot text", SCRIPT_INTEGER},
839     {"putallbots", script_putallbots, "s", "text", SCRIPT_INTEGER},
840     {"idx2hand", (Function) script_idx2hand, "i", "idx", SCRIPT_INTEGER},
841     {"islinked", script_islinked, "s", "bot", SCRIPT_INTEGER},
842     {"dccused", script_dccused, "", "", SCRIPT_INTEGER},
843     {"getdccidle", script_getdccidle, "i", "idx", SCRIPT_INTEGER},
844     {"getdccaway", (Function) script_getdccaway, "i", "idx", SCRIPT_STRING},
845     {"setdccaway", script_setdccaway, "is", "idx msg", SCRIPT_INTEGER},
846     {"unlink", script_unlink, "ss", "bot comment", SCRIPT_INTEGER},
847     {"boot", script_boot, "ss", "user@bot reason", SCRIPT_INTEGER},
848     {"rehash", script_rehash, "", "", SCRIPT_INTEGER},
849     {"restart", script_restart, "", "", SCRIPT_INTEGER},
850 stdarg 1.41 {0}
851     };
852    
853     script_command_t script_full_dcc_cmds[] = {
854     {"", "console", script_console, NULL, 1, "is", "idx ?changes?", 0, SCRIPT_PASS_RETVAL|SCRIPT_PASS_COUNT|SCRIPT_VAR_ARGS},
855     {"", "strip", script_strip, NULL, 1, "is", "idx ?change?", 0, SCRIPT_PASS_RETVAL|SCRIPT_PASS_COUNT|SCRIPT_VAR_ARGS},
856     {"", "echo", script_echo, NULL, 1, "ii", "idx ?status?", SCRIPT_INTEGER, SCRIPT_PASS_COUNT|SCRIPT_VAR_ARGS},
857     {"", "page", script_page, NULL, 1, "ii", "idx ?status?", SCRIPT_INTEGER, SCRIPT_PASS_COUNT|SCRIPT_VAR_ARGS},
858 stdarg 1.42 {"", "bots", script_bots, NULL, 0, "", "", 0, SCRIPT_PASS_RETVAL},
859     {"", "botlist", script_botlist, NULL, 0, "", "", 0, SCRIPT_PASS_RETVAL},
860     {"", "dcclist", script_dcclist, NULL, 0, "s", "?match?", 0, SCRIPT_PASS_RETVAL|SCRIPT_VAR_ARGS},
861     {"", "link", script_link, NULL, 1, "ss", "?via-bot? target-bot", 0, SCRIPT_VAR_ARGS | SCRIPT_VAR_FRONT},
862 stdarg 1.45 {"", "whom", script_whom, NULL, 0, "i", "?channel?", 0, SCRIPT_PASS_RETVAL|SCRIPT_PASS_COUNT|SCRIPT_VAR_ARGS},
863 stdarg 1.39 {0}
864     };
865    
866 segfault 1.1 tcl_cmds tcldcc_cmds[] =
867     {
868 fabian 1.13 {"control", tcl_control},
869     {"killdcc", tcl_killdcc},
870     {"connect", tcl_connect},
871     {"listen", tcl_listen},
872 ite 1.48 {"traffic", tcl_traffic},
873 fabian 1.13 {NULL, NULL}
874 segfault 1.1 };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23