/[cvs]/eggdrop1.9/src/tcldcc.c
ViewVC logotype

Contents of /eggdrop1.9/src/tcldcc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.60 - (show annotations) (download) (as text)
Sun May 5 15:19:11 2002 UTC (17 years ago) by wingman
Branch: MAIN
Changes since 1.59: +18 -2 lines
File MIME type: text/x-chdr
Changes:

 * removed patch.h
 * added proper <filename>.h to (nearly) all <filename.h>
 * moved fixcolon to server.mod and irc.mod
 * moved ip2long to net.h
 * removed some unused function (forgot the name :-P)

Todo:

 * move config.h #include's away from main.h to files which
   needs them
 * clean up lib/eggdrop/module.h
   (now not just main.h is included but nearly all .h files from
    the core, but i guess this fixes itself when the global func
    table is abandon - then the modules must be revised too and
    we can clean up module.h)

And i'll bet i forgot something... ;-)

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23