/[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.62 - (hide annotations) (download) (as text)
Thu May 9 07:37:49 2002 UTC (17 years ago) by stdarg
Branch: MAIN
Changes since 1.61: +153 -185 lines
File MIME type: text/x-chdr
* Quickly converted the network functions to language neutrality
* script_listen_script() doesn't work, I think. I haven't tested it yet, but I'm 99.9% sure. I'll do it later.
* Sort of a cool little new function... script_export. It lets you define a function in tcl/perl/javascript, and make it available in the other scripting modules. It needs some tuning, but it's a start.

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23