/[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.64 - (show annotations) (download) (as text)
Sun May 12 06:23:39 2002 UTC (17 years, 6 months ago) by stdarg
Branch: MAIN
Changes since 1.63: +2 -2 lines
File MIME type: text/x-chdr
* Overlooked name changes

1 /*
2 * tcldcc.c --
3 *
4 * Tcl stubs for the dcc commands
5 */
6 /*
7 * Copyright (C) 1997 Robey Pointer
8 * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
9 *
10 * 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 *
15 * 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 *
20 * 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 */
24
25 #ifndef lint
26 static const char rcsid[] = "$Id: tcldcc.c,v 1.63 2002/05/12 05:59:52 stdarg Exp $";
27 #endif
28
29 #include "main.h"
30 #include "tandem.h"
31 #include "modules.h"
32 #include "logfile.h"
33 #include "misc.h"
34 #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
48 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 /* Traffic stuff. */
57 extern egg_traffic_t traffic;
58
59 #ifndef MAKING_MODS
60 extern struct dcc_table DCC_CHAT, DCC_SCRIPT, DCC_TELNET, DCC_SOCKET;
61 #endif /* MAKING_MODS */
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 script_control(int idx, script_callback_t *callback)
297 {
298 void *hold;
299
300 if (idx < 0 || idx >= max_dcc) {
301 callback->syntax = strdup("");
302 callback->del(callback);
303 return(-1);
304 }
305
306 if (dcc[idx].type && dcc[idx].type->flags & DCT_CHAT) {
307 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
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 }
342
343 static int script_valididx(int idx)
344 {
345 if (idx < 0 || idx >= dcc_total || !dcc[idx].type || !(dcc[idx].type->flags & DCT_VALIDIDX)) return(0);
346 return(1);
347 }
348
349 /*
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 {
355 if (idx < 0 || idx >= dcc_total || !dcc[idx].type || !(dcc[idx].type->flags & DCT_VALIDIDX)) return(-1);
356
357 /* Don't kill terminal socket */
358 if ((dcc[idx].sock == STDOUT) && !backgrd) return(0);
359
360 /* Make sure 'whom' info is updated for other bots */
361 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 reason ? ": " : "", reason ? reason : "");
365 botnet_send_part_idx(idx, reason ? reason : "");
366 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 check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
370 /* Notice is sent to the party line, the script can add a reason. */
371 }
372 killsock(dcc[idx].sock);
373 lostdcc(idx);
374 return TCL_OK;
375 }
376
377 static int script_putbot(char *target, char *text)
378 {
379 int i;
380
381 i = nextbot(target);
382 if (i < 0) return(1);
383 botnet_send_zapf(i, botnetnick, target, text);
384 return(0);
385 }
386
387 static int script_putallbots(char *text)
388 {
389 botnet_send_zapf_broad(-1, botnetnick, NULL, text);
390 return(0);
391 }
392
393 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 }
398
399 static int script_islinked(char *bot)
400 {
401 return nextbot(bot);
402 }
403
404 static int script_bots(script_var_t *retval)
405 {
406 char **botlist = NULL;
407 int nbots = 0;
408 tand_t *bot;
409
410 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 }
420
421 static int script_botlist(script_var_t *retval)
422 {
423 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 share = script_copy_string(sharestr, -1);
437
438 sublist = script_list(4, nick, uplink, version, share);
439 script_list_append(retval, sublist);
440 }
441 return(0);
442 }
443
444 /* list of { idx nick host type {other} timestamp}
445 */
446 static int script_dcclist(script_var_t *retval, char *match)
447 {
448 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 othervar = script_copy_string(other, -1);
466 othervar->type |= SCRIPT_FREE;
467 timestamp = script_int(dcc[i].timeval);
468
469 sublist = script_list(6, idx, nick, host, type, othervar, timestamp);
470 script_list_append(retval, sublist);
471 }
472 return(0);
473 }
474
475 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 vflag = script_copy_string(flag, 1);
487
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 */
498 static int script_whom(script_var_t *retval, int nargs, int which_chan)
499 {
500 int i;
501
502 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 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 }
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 }
521
522 static int script_dccused()
523 {
524 return(dcc_total);
525 }
526
527 static int script_getdccidle(int idx)
528 {
529 if (idx < 0 || idx >= dcc_total || !(dcc->type)) return(-1);
530 return(now - dcc[idx].timeval);
531 }
532
533 static char *script_getdccaway(int idx)
534 {
535 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 }
539
540 static int script_setdccaway(int idx, char *text)
541 {
542 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 }
550
551 static int script_link(char *via, char *target)
552 {
553 int x, i;
554
555 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 }
564
565 static int script_unlink(char *bot, char *comment)
566 {
567 int i, x;
568
569 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 }
578
579 static int script_connect(char *hostname, int port)
580 {
581 int i, z, sock;
582
583 sock = getsock(0);
584 if (sock < 0) return(-1);
585 z = open_telnet_raw(sock, hostname, port);
586 if (z < 0) {
587 killsock(sock);
588 return(-1);
589 }
590
591 /* Well well well... it worked! */
592 i = new_dcc(&DCC_SOCKET, 0);
593 dcc[i].sock = sock;
594 dcc[i].port = port;
595 strcpy(dcc[i].nick, "*");
596 strlcpy(dcc[i].host, hostname, UHOSTMAX);
597 return(i);
598 }
599
600 /* Create a new listening port (or destroy one)
601 *
602 * listen <port> bots/all/users [mask]
603 * listen <port> script <proc> [flag]
604 * listen <port> off
605 */
606 /* 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 {
620 int idx;
621
622 idx = find_idx_by_port(port);
623 if (idx < 0) return(-1);
624 killsock(dcc[idx].sock);
625 lostdcc(idx);
626 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 }
706
707 static int script_boot(char *user_bot, char *reason)
708 {
709 char who[NOTENAMELEN + 1];
710 int i;
711
712 strlcpy(who, user_bot, sizeof who);
713 if (strchr(who, '@') != NULL) {
714 char whonick[HANDLEN + 1];
715
716 splitc(whonick, who, '@');
717 whonick[HANDLEN] = 0;
718 if (!strcasecmp(who, botnetnick))
719 strlcpy(who, whonick, sizeof who);
720 else if (remote_boots > 0) {
721 i = nextbot(who);
722 if (i < 0) return(0);
723 botnet_send_reject(i, botnetnick, NULL, whonick, who, reason ? reason : "");
724 }
725 else return(0);
726 }
727 for (i = 0; i < dcc_total; i++)
728 if ((dcc[i].type) && (dcc[i].type->flags & DCT_CANBOOT) &&
729 !strcasecmp(dcc[i].nick, who)) {
730 do_boot(i, botnetnick, reason ? reason : "");
731 break;
732 }
733 return(0);
734 }
735
736 static int script_rehash()
737 {
738 if (make_userfile) {
739 putlog(LOG_MISC, "*", _("Userfile creation not necessary--skipping"));
740 make_userfile = 0;
741 }
742 write_userfile(-1);
743 putlog(LOG_MISC, "*", _("Rehashing..."));
744 do_restart = -2;
745 return(0);
746 }
747
748 static int script_restart()
749 {
750 if (!backgrd) return(1);
751 if (make_userfile) {
752 putlog(LOG_MISC, "*", _("Userfile creation not necessary--skipping"));
753 make_userfile = 0;
754 }
755 write_userfile(-1);
756 putlog(LOG_MISC, "*", _("Restarting..."));
757 do_restart = -1;
758 return(0);
759 }
760
761 static int script_traffic(script_var_t *retval)
762 {
763 unsigned long out_total_today, out_total;
764 unsigned long in_total_today, in_total;
765 script_var_t *sublist;
766
767 retval->type = SCRIPT_ARRAY | SCRIPT_FREE | SCRIPT_VAR;
768 retval->len = 0;
769 retval->value = NULL;
770
771 sublist = script_list(5, script_string("irc", -1),
772 script_int(traffic.in_today.irc),
773 script_int(traffic.in_today.irc + traffic.in_total.irc),
774 script_int(traffic.out_today.irc),
775 script_int(traffic.out_today.irc + traffic.out_total.irc));
776 script_list_append(retval, sublist);
777
778 sublist = script_list(5, script_string("botnet", -1),
779 script_int(traffic.in_today.bn),
780 script_int(traffic.in_today.bn + traffic.in_total.bn),
781 script_int(traffic.out_today.bn),
782 script_int(traffic.out_today.bn + traffic.out_total.bn));
783 script_list_append(retval, sublist);
784
785 sublist = script_list(5, script_string("dcc", -1),
786 script_int(traffic.in_today.dcc),
787 script_int(traffic.in_today.dcc + traffic.in_total.dcc),
788 script_int(traffic.out_today.dcc),
789 script_int(traffic.out_today.dcc + traffic.out_total.dcc));
790 script_list_append(retval, sublist);
791
792 sublist = script_list(5, script_string("transfer", -1),
793 script_int(traffic.in_today.trans),
794 script_int(traffic.in_today.trans + traffic.in_total.trans),
795 script_int(traffic.out_today.trans),
796 script_int(traffic.out_today.trans + traffic.out_total.trans));
797 script_list_append(retval, sublist);
798
799 sublist = script_list(5, script_string("filesys", -1),
800 script_int(traffic.in_today.filesys),
801 script_int(traffic.in_today.filesys + traffic.in_total.filesys),
802 script_int(traffic.out_today.filesys),
803 script_int(traffic.out_today.filesys + traffic.out_total.filesys));
804 script_list_append(retval, sublist);
805
806 sublist = script_list(5, script_string("unknown", -1),
807 script_int(traffic.in_today.unknown),
808 script_int(traffic.in_today.unknown + traffic.in_total.unknown),
809 script_int(traffic.out_today.unknown),
810 script_int(traffic.out_today.unknown + traffic.out_total.unknown));
811 script_list_append(retval, sublist);
812
813 /* Totals */
814 in_total_today = traffic.in_today.irc + traffic.in_today.bn + traffic.in_today.dcc + traffic.in_today.trans + traffic.in_today.unknown;
815
816 in_total = in_total_today + traffic.in_total.irc + traffic.in_total.bn + traffic.in_total.dcc + traffic.in_total.trans + traffic.in_total.unknown;
817
818 out_total_today = traffic.out_today.irc + traffic.out_today.bn + traffic.out_today.dcc + traffic.in_today.trans + traffic.out_today.unknown;
819
820 out_total = out_total_today + traffic.out_total.irc + traffic.out_total.bn + traffic.out_total.dcc + traffic.out_total.trans + traffic.out_total.unknown;
821
822 sublist = script_list(5, script_string("total", -1),
823 script_int(in_total_today),
824 script_int(in_total),
825 script_int(out_total_today),
826 script_int(out_total));
827 script_list_append(retval, sublist);
828
829 return(0);
830 }
831
832 script_command_t script_dcc_cmds[] = {
833 {"", "putdcc", script_putdcc, NULL, 2, "is", "idx text", SCRIPT_INTEGER, 0},
834 {"", "putdccraw", script_putdccraw, NULL, 3, "iis", "idx len text", SCRIPT_INTEGER, 0},
835 {"", "dccsimul", script_dccsimul, NULL, 2, "is", "idx command", SCRIPT_INTEGER, 0},
836 {"", "dccbroadcast", script_dccbroadcast, NULL, 1, "s", "text", SCRIPT_INTEGER, 0},
837 {"", "hand2idx", script_hand2idx, NULL, 1, "s", "handle", SCRIPT_INTEGER, 0},
838 {"", "getchan", script_getchan, NULL, 2, "i", "idx", SCRIPT_INTEGER, 0},
839 {"", "setchan", script_setchan, NULL, 2, "ii", "idx chan", SCRIPT_INTEGER, 0},
840 {"", "dccputchan", script_dccputchan, NULL, 2, "is", "chan text", SCRIPT_INTEGER, 0},
841 {"", "valididx", script_valididx, NULL, 1, "i", "idx", SCRIPT_INTEGER, 0},
842 {"", "putbot", script_putbot, NULL, 2, "ss", "bot text", SCRIPT_INTEGER, 0},
843 {"", "putallbots", script_putallbots, NULL, 1, "s", "text", SCRIPT_INTEGER, 0},
844 {"", "idx2hand", script_idx2hand, NULL, 1, "i", "idx", SCRIPT_INTEGER, 0},
845 {"", "islinked", script_islinked, NULL, 1, "s", "bot", SCRIPT_INTEGER, 0},
846 {"", "dccused", script_dccused, NULL, 0, "", "", SCRIPT_INTEGER, 0},
847 {"", "getdccidle", script_getdccidle, NULL, 1, "i", "idx", SCRIPT_INTEGER, 0},
848 {"", "getdccaway", script_getdccaway, NULL, 1, "i", "idx", SCRIPT_STRING, 0},
849 {"", "setdccaway", script_setdccaway, NULL, 2, "is", "idx msg", SCRIPT_INTEGER, 0},
850 {"", "unlink", script_unlink, NULL, 2, "ss", "bot comment", SCRIPT_INTEGER, 0},
851 {"", "boot", script_boot, NULL, 2,"ss", "user@bot reason", SCRIPT_INTEGER, 0},
852 {"", "rehash", script_rehash, NULL, 0,"", "", SCRIPT_INTEGER, 0},
853 {"", "restart", script_restart, NULL, 0, "", "", SCRIPT_INTEGER, 0},
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 {"", "control", script_control, NULL, 1, "ic", "idx ?callback?", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
864 {"", "killdcc", script_killdcc, NULL, 1, "i", "idx", SCRIPT_INTEGER, 0},
865 {"", "connect", script_connect, NULL, 2, "si", "host port", SCRIPT_INTEGER, 0},
866 {"", "listen_off", script_listen_off, NULL, 1, "i", "port", SCRIPT_INTEGER, 0},
867 {"", "listen_script", script_listen_script, NULL, 2, "scs", "port callback ?flags?", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
868 {"", "listen", script_listen, NULL, 2, "sss", "port type ?mask?", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
869 {"", "traffic", script_traffic, NULL, 0, "", "", 0, SCRIPT_PASS_RETVAL},
870 {0}
871 };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23