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

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23