/[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.49 - (hide annotations) (download) (as text)
Tue Jan 22 01:17:16 2002 UTC (17 years, 4 months ago) by ite
Branch: MAIN
Changes since 1.48: +5 -3 lines
File MIME type: text/x-chdr
geticon() didn't really need to care about dcc table

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23