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

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

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


Revision 1.40 - (show annotations) (download) (as text)
Sun Sep 22 01:25:19 2002 UTC (17 years ago) by stdarg
Branch: MAIN
CVS Tags: HEAD
Changes since 1.39: +1 -1 lines
File MIME type: text/x-chdr
FILE REMOVED
* Remove unnecessary files (botnet stuff)

1 /*
2 * botcmd.c --
3 *
4 * commands that comes across the botnet
5 * userfile transfer and update commands from sharebots
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 #ifndef lint
27 static const char rcsid[] = "$Id: botcmd.c,v 1.39 2002/06/18 06:12:32 guppy Exp $";
28 #endif
29
30 #include "main.h"
31 #include "tandem.h"
32 #include "users.h"
33 #include "chan.h"
34 #include "modules.h"
35 #include "logfile.h"
36 #include "misc.h"
37 #include "cmdt.h" /* cmd_t */
38 #include "botmsg.h" /* add_note */
39 #include "botnet.h" /* botlink, botunlink, in_chain,
40 updatebot, addbot, lastbot, unvia,
41 rembot */
42 #include "dccutil.h" /* dprintf_eggdrop, lostdcc, chatout
43 new_dcc, changeover_dcc, chanout_but */
44 #include "net.h" /* killsock */
45 #include "core_binds.h" /* check_bind_chat, check_bind_bcst,
46 check_bind_act, check_bind_link,
47 check_bind_bot, check_bind_chpt,
48 check_bind_chjn, check_bind_away */
49 #include "botcmd.h" /* prototypes */
50 #include "userrec.h" /* change_handle, touch_laston */
51
52 extern char botnetnick[], ver[], admin[], network[], motdfile[];
53 extern int dcc_total, remote_boots, noshare;
54 extern struct dcc_t *dcc;
55 extern struct chanset_t *chanset;
56 extern struct userrec *userlist;
57 extern time_t now, online_since;
58 extern party_t *party;
59 extern module_entry *module_list;
60
61 #ifndef MAKING_MODS
62 extern struct dcc_table DCC_BOT;
63 #endif /* MAKING_MODS */
64
65 static char TBUF[1024]; /* Static buffer for goofy bot stuff */
66
67 static char base64to[256] =
68 {
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0,
72 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
73 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 62, 0, 63, 0, 0, 0, 26, 27, 28,
74 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
75 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
82 };
83
84
85 int base64_to_int(char *buf)
86 {
87 int i = 0;
88
89 while (*buf) {
90 i = i << 6;
91 i += base64to[(int) *buf];
92 buf++;
93 }
94 return i;
95 }
96
97 /* Used for 1.0 compatibility: if a join message arrives with no sock#,
98 * i'll just grab the next "fakesock" # (incrementing to assure uniqueness)
99 */
100 static int fakesock = 2300;
101
102 static void fake_alert(int idx, char *item, char *extra)
103 {
104 static unsigned long lastfake; /* The last time fake_alert was used */
105
106 if (now - lastfake > 10) {
107 /* Don't fake_alert more than once every 10secs */
108 #ifndef NO_OLD_BOTNET
109 if (b_numver(idx) < NEAT_BOTNET)
110 dprintf(idx, "chat %s NOTICE: %s (%s != %s).\n",
111 botnetnick, _("Fake message rejected"), item, extra);
112 else
113 #endif
114 dprintf(idx, "ct %s NOTICE: %s (%s != %s).\n",
115 botnetnick, _("Fake message rejected"), item, extra);
116 putlog(LOG_BOTS, "*", "%s %s (%s != %s).", dcc[idx].nick, _("Fake message rejected"),
117 item, extra);
118 lastfake = now;
119 }
120 }
121
122 /* chan <from> <chan> <text>
123 */
124 static void bot_chan2(int idx, char *msg)
125 {
126 char *from, *p;
127 int i, chan;
128
129 if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
130 return;
131 from = newsplit(&msg);
132 p = newsplit(&msg);
133 #ifndef NO_OLD_BOTNET
134 if (b_numver(idx) < NEAT_BOTNET)
135 chan = atoi(p);
136 else
137 #endif
138 chan = base64_to_int(p);
139 /* Strip annoying control chars */
140 for (p = from; *p;) {
141 if ((*p < 32) || (*p == 127))
142 strcpy(p, p + 1);
143 else
144 p++;
145 }
146 p = strchr(from, '@');
147 if (p) {
148 sprintf(TBUF, "<%s> %s", from, msg);
149 *p = 0;
150 if (!partyidle(p + 1, from)) {
151 *p = '@';
152 fake_alert(idx, "user", from);
153 return;
154 }
155 *p = '@';
156 p++;
157 } else {
158 sprintf(TBUF, "*** (%s) %s", from, msg);
159 p = from;
160 }
161 i = nextbot(p);
162 if (i != idx) {
163 fake_alert(idx, "direction", p);
164 } else {
165 chanout_but(-1, chan, "%s\n", TBUF);
166 /* Send to new version bots */
167 if (i >= 0)
168 botnet_send_chan(idx, from, NULL, chan, msg);
169 if (strchr(from, '@') != NULL)
170 check_bind_chat(from, chan, msg);
171 else
172 check_bind_bcst(from, chan, msg);
173 }
174 }
175
176 /* chat <from> <notice> -- only from bots
177 */
178 static void bot_chat(int idx, char *par)
179 {
180 char *from;
181 int i;
182
183 if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
184 return;
185 from = newsplit(&par);
186 if (strchr(from, '@') != NULL) {
187 fake_alert(idx, "bot", from);
188 return;
189 }
190 /* Make sure the bot is valid */
191 i = nextbot(from);
192 if (i != idx) {
193 fake_alert(idx, "direction", from);
194 return;
195 }
196 chatout("*** (%s) %s\n", from, par);
197 botnet_send_chat(idx, from, par);
198 }
199
200 /* actchan <from> <chan> <text>
201 */
202 static void bot_actchan(int idx, char *par)
203 {
204 char *from, *p;
205 int i, chan;
206
207 if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
208 return;
209 from = newsplit(&par);
210 p = strchr(from, '@');
211 if (p == NULL) {
212 /* How can a bot do an action? */
213 fake_alert(idx, "user@bot", from);
214 return;
215 }
216 *p = 0;
217 if (!partyidle(p + 1, from)) {
218 *p = '@';
219 fake_alert(idx, "user", from);
220 }
221 *p = '@';
222 p++;
223 i = nextbot(p);
224 if (i != idx) {
225 fake_alert(idx, "direction", p);
226 return;
227 }
228 p = newsplit(&par);
229 #ifndef NO_OLD_BOTNET
230 if (b_numver(idx) < NEAT_BOTNET)
231 chan = atoi(p);
232 else
233 #endif
234 chan = base64_to_int(p);
235 for (p = from; *p;) {
236 if ((*p < 32) || (*p == 127))
237 strcpy(p, p + 1);
238 else
239 p++;
240 }
241 chanout_but(-1, chan, "* %s %s\n", from, par);
242 botnet_send_act(idx, from, NULL, chan, par);
243 check_bind_act(from, chan, par);
244 }
245
246 /* priv <from> <to> <message>
247 */
248 static void bot_priv(int idx, char *par)
249 {
250 char *from, *p, *to = TBUF, *tobot;
251 int i;
252
253 from = newsplit(&par);
254 tobot = newsplit(&par);
255 splitc(to, tobot, '@');
256 p = strchr(from, '@');
257 if (p != NULL)
258 p++;
259 else
260 p = from;
261 i = nextbot(p);
262 if (i != idx) {
263 fake_alert(idx, "direction", p);
264 return;
265 }
266 if (!to[0])
267 return; /* Silently ignore notes to '@bot' this
268 * is legacy code */
269 if (!strcasecmp(tobot, botnetnick)) { /* For me! */
270 if (p == from)
271 add_note(to, from, par, -2, 0);
272 else {
273 i = add_note(to, from, par, -1, 0);
274 if (from[0] != '@')
275 switch (i) {
276 case NOTE_ERROR:
277 botnet_send_priv(idx, botnetnick, from, NULL,
278 "%s %s.", _("No such user"), to);
279 break;
280 case NOTE_STORED:
281 botnet_send_priv(idx, botnetnick, from, NULL,
282 "%s", _("Not online; note stored."));
283 break;
284 case NOTE_FULL:
285 botnet_send_priv(idx, botnetnick, from, NULL,
286 "%s", _("Notebox is full, sorry."));
287 break;
288 case NOTE_AWAY:
289 botnet_send_priv(idx, botnetnick, from, NULL,
290 "%s %s", to, _("is away; note stored."));
291 break;
292 case NOTE_FWD:
293 botnet_send_priv(idx, botnetnick, from, NULL,
294 "%s %s", _("Not online; note forwarded to:"), to);
295 break;
296 case NOTE_REJECT:
297 botnet_send_priv(idx, botnetnick, from, NULL,
298 "%s %s", to, _("rejected your note."));
299 break;
300 case NOTE_TCL:
301 break; /* Do nothing */
302 case NOTE_OK:
303 botnet_send_priv(idx, botnetnick, from, NULL,
304 "%s %s.", _("Note sent to"), to);
305 break;
306 }
307 }
308 } else { /* Pass it on */
309 i = nextbot(tobot);
310 if (i >= 0)
311 botnet_send_priv(i, from, to, tobot, "%s", par);
312 }
313 }
314
315 static void bot_bye(int idx, char *par)
316 {
317 char s[1024];
318 int users, bots;
319
320 bots = bots_in_subtree(findbot(dcc[idx].nick));
321 users = users_in_subtree(findbot(dcc[idx].nick));
322 simple_sprintf(s, "%s %s. %s (lost %d bot%s and %d user%s)",
323 _("Disconnected from:"), dcc[idx].nick, par[0] ?
324 par : "No reason", bots, (bots != 1) ?
325 "s" : "", users, (users != 1) ? "s" : "");
326 putlog(LOG_BOTS, "*", "%s", s);
327 chatout("*** %s\n", s);
328 botnet_send_unlinked(idx, dcc[idx].nick, s);
329 dprintf(idx, "*bye\n");
330 killsock(dcc[idx].sock);
331 lostdcc(idx);
332 }
333
334 static void remote_tell_who(int idx, char *nick, int chan)
335 {
336 int i = 10, k, l, ok = 0;
337 char s[1024], *realnick;
338 struct chanset_t *c;
339
340 realnick = strchr(nick, ':');
341 if (realnick)
342 realnick++;
343 else
344 realnick = nick;
345 putlog(LOG_BOTS, "*", "#%s# who", realnick);
346 strcpy(s, "Channels: ");
347 for (c = chanset; c; c = c->next)
348 if (!channel_secret(c)) {
349 l = strlen(c->name);
350 if (i + l < 1021) {
351 if (i > 10)
352 sprintf(s, "%s, %s", s, c->name);
353 else {
354 strcpy(s, c->name);
355 i += (l + 2);
356 }
357 }
358 }
359 if (i > 10) {
360 botnet_send_priv(idx, botnetnick, nick, NULL, "%s (%s)", s, ver);
361 } else
362 botnet_send_priv(idx, botnetnick, nick, NULL, "%s (%s)", _("no channels"),
363 ver);
364 if (admin[0])
365 botnet_send_priv(idx, botnetnick, nick, NULL, "Admin: %s", admin);
366 if (chan == 0)
367 botnet_send_priv(idx, botnetnick, nick, NULL,
368 "%s (* = %s, + = %s, @ = %s)",
369 _("Party line members:"), _("owner"), _("master"), _("op"));
370 else {
371 botnet_send_priv(idx, botnetnick, nick, NULL,
372 "%s %s%d: (* = %s, + = %s, @ = %s)\n",
373 _("People on channel"),
374 (chan < GLOBAL_CHANS) ? "" : "*",
375 chan % GLOBAL_CHANS,
376 _("owner"), _("master"), _("op"));
377 }
378 for (i = 0; i < dcc_total; i++)
379 if (dcc[i].type->flags & DCT_REMOTEWHO)
380 if (dcc[i].u.chat->channel == chan) {
381 k = sprintf(s, " %c%-15s %s",
382 (geticon(dcc[i].user) == '-' ? ' ' : geticon(dcc[i].user)),
383 dcc[i].nick, dcc[i].host);
384 if (now - dcc[i].timeval > 300) {
385 unsigned long days, hrs, mins;
386
387 days = (now - dcc[i].timeval) / 86400;
388 hrs = ((now - dcc[i].timeval) - (days * 86400)) / 3600;
389 mins = ((now - dcc[i].timeval) - (hrs * 3600)) / 60;
390 if (days > 0)
391 sprintf(s + k, " (%s %lud%luh)",
392 _("idle"), days, hrs);
393 else if (hrs > 0)
394 sprintf(s + k, " (%s %luh%lum)",
395 _("idle"), hrs, mins);
396 else
397 sprintf(s + k, " (%s %lum)",
398 _("idle"), mins);
399 }
400 botnet_send_priv(idx, botnetnick, nick, NULL, "%s", s);
401 if (dcc[i].u.chat->away != NULL)
402 botnet_send_priv(idx, botnetnick, nick, NULL, " %s: %s",
403 _("AWAY"), dcc[i].u.chat->away);
404 }
405 for (i = 0; i < dcc_total; i++)
406 if (dcc[i].type == &DCC_BOT) {
407 if (!ok) {
408 ok = 1;
409 botnet_send_priv(idx, botnetnick, nick, NULL,
410 "%s:", _("Bots connected"));
411 }
412 sprintf(s, " %s%c%-15s %s",
413 dcc[i].status & STAT_CALLED ? "<-" : "->",
414 dcc[i].status & STAT_SHARE ? '+' : ' ',
415 dcc[i].nick, dcc[i].u.bot->version);
416 botnet_send_priv(idx, botnetnick, nick, NULL, "%s", s);
417 }
418 ok = 0;
419 for (i = 0; i < dcc_total; i++)
420 if (dcc[i].type->flags & DCT_REMOTEWHO)
421 if (dcc[i].u.chat->channel != chan) {
422 if (!ok) {
423 ok = 1;
424 botnet_send_priv(idx, botnetnick, nick, NULL, "%s:",
425 _("Other people on the bot"));
426 }
427 l = sprintf(s, " %c%-15s %s",
428 (geticon(dcc[i].user) == '-' ? ' ' : geticon(dcc[i].user)),
429 dcc[i].nick, dcc[i].host);
430 if (now - dcc[i].timeval > 300) {
431 k = (now - dcc[i].timeval) / 60;
432 if (k < 60)
433 sprintf(s + l, " (%s %dm)", _("idle"), k);
434 else
435 sprintf(s + l, " (%s %dh%dm)", _("idle"), k / 60, k % 60);
436 }
437 botnet_send_priv(idx, botnetnick, nick, NULL, "%s", s);
438 if (dcc[i].u.chat->away != NULL)
439 botnet_send_priv(idx, botnetnick, nick, NULL,
440 " %s: %s", _("AWAY"),
441 dcc[i].u.chat->away);
442 }
443 }
444
445 /* who <from@bot> <tobot> <chan#>
446 */
447 static void bot_who(int idx, char *par)
448 {
449 char *from, *to, *p;
450 int i, chan;
451
452 from = newsplit(&par);
453 p = strchr(from, '@');
454 if (!p) {
455 sprintf(TBUF, "%s@%s", from, dcc[idx].nick);
456 from = TBUF;
457 }
458 to = newsplit(&par);
459 if (!strcasecmp(to, botnetnick))
460 to[0] = 0; /* (for me) */
461 #ifndef NO_OLD_BOTNET
462 if (b_numver(idx) < NEAT_BOTNET)
463 chan = atoi(par);
464 else
465 #endif
466 chan = base64_to_int(par);
467 if (to[0]) { /* Pass it on */
468 i = nextbot(to);
469 if (i >= 0)
470 botnet_send_who(i, from, to, chan);
471 } else {
472 remote_tell_who(idx, from, chan);
473 }
474 }
475
476 static void bot_endlink(int idx, char *par)
477 {
478 dcc[idx].status &= ~STAT_LINKING;
479 }
480
481 /* info? <from@bot> -> send priv
482 */
483 static void bot_infoq(int idx, char *par)
484 {
485 char s[200], s2[32], *realnick;
486 struct chanset_t *chan;
487 time_t now2;
488 int hr, min;
489
490 /* Strip the idx from user@bot */
491 realnick = strchr(par, ':');
492 if (realnick)
493 realnick++;
494 else
495 realnick = par;
496 putlog(LOG_BOTS, "*", "#%s# botinfo", realnick);
497
498 now2 = now - online_since;
499 s2[0] = 0;
500 if (now2 > 86400) {
501 int days = now2 / 86400;
502
503 /* Days */
504 sprintf(s2, "%d day", days);
505 if (days >= 2)
506 strcat(s2, "s");
507 strcat(s2, ", ");
508 now2 -= days * 86400;
509 }
510 hr = (time_t) ((int) now2 / 3600);
511 now2 -= (hr * 3600);
512 min = (time_t) ((int) now2 / 60);
513 sprintf(&s2[strlen(s2)], "%02d:%02d", (int) hr, (int) min);
514 if (module_find("server", 0, 0)) {
515 s[0] = 0;
516 for (chan = chanset; chan; chan = chan->next) {
517 if (!channel_secret(chan)) {
518 if ((strlen(s) + strlen(chan->dname) + strlen(network)
519 + strlen(botnetnick) + strlen(ver) + 1) >= 200) {
520 strcat(s,"++ ");
521 break; /* Yegads..! */
522 }
523 strcat(s, chan->dname);
524 strcat(s, ", ");
525 }
526 }
527 if (s[0]) {
528 s[strlen(s) - 2] = 0;
529 botnet_send_priv(idx, botnetnick, par, NULL,
530 "%s <%s> (%s) [UP %s]", ver, network, s, s2);
531 } else
532 botnet_send_priv(idx, botnetnick, par, NULL,
533 "%s <%s> (%s) [UP %s]", ver, network, _("no channels"),
534 s2);
535 } else
536 botnet_send_priv(idx, botnetnick, par, NULL,
537 "%s <NO_IRC> [UP %s]", ver, s2);
538 botnet_send_infoq(idx, par);
539 }
540
541 static void bot_ping(int idx, char *par)
542 {
543 botnet_send_pong(idx);
544 }
545
546 static void bot_pong(int idx, char *par)
547 {
548 dcc[idx].status &= ~STAT_PINGED;
549 }
550
551 /* link <from@bot> <who> <to-whom>
552 */
553 static void bot_link(int idx, char *par)
554 {
555 char *from, *bot, *rfrom;
556 int i;
557
558 from = newsplit(&par);
559 bot = newsplit(&par);
560
561 if (!strcasecmp(bot, botnetnick)) {
562 if ((rfrom = strchr(from, ':')))
563 rfrom++;
564 else
565 rfrom = from;
566 putlog(LOG_CMDS, "*", "#%s# link %s", rfrom, par);
567 if (botlink(from, -1, par))
568 botnet_send_priv(idx, botnetnick, from, NULL, "%s %s ...",
569 _("Attempting to link"), par);
570 else
571 botnet_send_priv(idx, botnetnick, from, NULL, "%s.",
572 _("Cant link there"));
573 } else {
574 i = nextbot(bot);
575 if (i >= 0)
576 botnet_send_link(i, from, bot, par);
577 }
578 }
579
580 /* unlink <from@bot> <linking-bot> <undesired-bot> <reason>
581 */
582 static void bot_unlink(int idx, char *par)
583 {
584 char *from, *bot, *rfrom, *p, *undes;
585 int i;
586
587 from = newsplit(&par);
588 bot = newsplit(&par);
589 undes = newsplit(&par);
590 if (!strcasecmp(bot, botnetnick)) {
591 if ((rfrom = strchr(from, ':')))
592 rfrom++;
593 else
594 rfrom = from;
595 putlog(LOG_CMDS, "*", "#%s# unlink %s (%s)", rfrom, undes, par[0] ? par :
596 "No reason");
597 i = botunlink(-3, undes, par[0] ? par : NULL);
598 if (i == 1) {
599 p = strchr(from, '@');
600 if (p) {
601 /* idx will change after unlink -- get new idx
602 *
603 * TODO: This has changed with the new lostdcc() behaviour. Check
604 * if we can optimise the situation.
605 */
606 i = nextbot(p + 1);
607 if (i >= 0)
608 botnet_send_priv(i, botnetnick, from, NULL,
609 "Unlinked from %s.", undes);
610 }
611 } else if (i == 0) {
612 botnet_send_unlinked(-1, undes, "");
613 p = strchr(from, '@');
614 if (p) {
615 /* Ditto above, about idx */
616 i = nextbot(p + 1);
617 if (i >= 0)
618 botnet_send_priv(i, botnetnick, from, NULL,
619 "%s %s.", _("Cant unlink"), undes);
620 }
621 } else {
622 p = strchr(from, '@');
623 if (p) {
624 i = nextbot(p + 1);
625 if (i >= 0)
626 botnet_send_priv(i, botnetnick, from, NULL,
627 "Can't remotely unlink sharebots.");
628 }
629 }
630 } else {
631 i = nextbot(bot);
632 if (i >= 0)
633 botnet_send_unlink(i, from, bot, undes, par);
634 }
635 }
636
637 /* Bot next share?
638 */
639 static void bot_update(int idx, char *par)
640 {
641 char *bot, x;
642 int vnum;
643
644 bot = newsplit(&par);
645 x = par[0];
646 if (x)
647 par++;
648 #ifndef NO_OLD_BOTNET
649 if (b_numver(idx) < NEAT_BOTNET)
650 vnum = atoi(par);
651 else
652 #endif
653 vnum = base64_to_int(par);
654 if (in_chain(bot))
655 updatebot(idx, bot, x, vnum);
656 }
657
658 /* Newbot next share?
659 */
660 static void bot_nlinked(int idx, char *par)
661 {
662 char *newbot, *next, *p, s[1024], x;
663 int bogus = 0, i;
664 struct userrec *u;
665
666 newbot = newsplit(&par);
667 next = newsplit(&par);
668 s[0] = 0;
669 if (!next[0]) {
670 putlog(LOG_BOTS, "*", _("Invalid eggnet protocol from %s (zapfing)"),
671 dcc[idx].nick);
672 simple_sprintf(s, _("Disconnected %s (invalid bot)"), dcc[idx].nick);
673 dprintf(idx, "error invalid eggnet protocol for 'nlinked'\n");
674 } else if ((in_chain(newbot)) || (!strcasecmp(newbot, botnetnick))) {
675 /* Loop! */
676 putlog(LOG_BOTS, "*", _("Loop detected %1$s (mutual: %2$s)"), dcc[idx].nick, newbot);
677 simple_sprintf(s, _("Detected loop: two bots exist named %1$s: disconnecting %2$s"), newbot, dcc[idx].nick);
678 dprintf(idx, "error Loop (%s)\n", newbot);
679 }
680 if (!s[0]) {
681 for (p = newbot; *p; p++)
682 if ((*p < 32) || (*p == 127) || ((p - newbot) >= HANDLEN))
683 bogus = 1;
684 i = nextbot(next);
685 if (i != idx)
686 bogus = 1;
687 }
688 if (bogus) {
689 putlog(LOG_BOTS, "*", "%s %s! (%s -> %s)", _("Bogus link notice from"), dcc[idx].nick,
690 next, newbot);
691 simple_sprintf(s, _("Bogus link notice from: %s Disconnected"), dcc[idx].nick);
692 dprintf(idx, "error %s (%s -> %s)\n",
693 _("Bogus link notice from"), next, newbot);
694 }
695 if (bot_flags(dcc[idx].user) & BOT_LEAF) {
696 putlog(LOG_BOTS, "*", _("Disconnected left %1$s (Linked to %2$s)"),
697 dcc[idx].nick, newbot);
698 simple_sprintf(s, _("Illegal link by leaf %1$s (to %2$s): Disconnected"),
699 dcc[idx].nick, newbot);
700 dprintf(idx, "error %s\n", _("You are supposed to be a leaf!"));
701 }
702 if (s[0]) {
703 chatout("*** %s\n", s);
704 botnet_send_unlinked(idx, dcc[idx].nick, s);
705 dprintf(idx, "bye %s\n", _("Illegal link by leaf"));
706 killsock(dcc[idx].sock);
707 lostdcc(idx);
708 return;
709 }
710 x = par[0];
711 if (x)
712 par++;
713 else
714 x = '-';
715 #ifndef NO_OLD_BOTNET
716 if (b_numver(idx) < NEAT_BOTNET)
717 i = atoi(par);
718 else
719 #endif
720 i = base64_to_int(par);
721 botnet_send_nlinked(idx, newbot, next, x, i);
722 if (x == '!') {
723 chatout("*** (%s) %s %s.\n", next, _("Linked to"), newbot);
724 x = '-';
725 }
726 addbot(newbot, dcc[idx].nick, next, x, i);
727 check_bind_link(newbot, next);
728 u = get_user_by_handle(userlist, newbot);
729 if (bot_flags(u) & BOT_REJECT) {
730 botnet_send_reject(idx, botnetnick, NULL, newbot, NULL, NULL);
731 putlog(LOG_BOTS, "*", _("Rejecting bot %1$s from %2$s"), newbot,
732 dcc[idx].nick);
733 }
734 }
735
736 #ifndef NO_OLD_BOTNET
737 static void bot_linked(int idx, char *par)
738 {
739 char s[1024];
740 int bots, users;
741
742 bots = bots_in_subtree(findbot(dcc[idx].nick));
743 users = users_in_subtree(findbot(dcc[idx].nick));
744 putlog(LOG_BOTS, "*", _("Older bot detected (unsupported)"));
745 /* FIXME PLURAL: handle it properly */
746 simple_sprintf(s,
747 _("Disconnected %s (outdated) (lost %d bot%s and %d user%s"),
748 dcc[idx].nick,
749 bots, (bots != 1) ? "s" : "", users,
750 (users != 1) ? "s" : "");
751 chatout("*** %s\n", s);
752 botnet_send_unlinked(idx, dcc[idx].nick, s);
753 killsock(dcc[idx].sock);
754 lostdcc(idx);
755 }
756 #endif /* !NO_OLD_BOTNET */
757
758 static void bot_unlinked(int idx, char *par)
759 {
760 int i;
761 char *bot;
762
763 bot = newsplit(&par);
764 i = nextbot(bot);
765 if ((i >= 0) && (i != idx)) /* Bot is NOT downstream along idx, so
766 * BOGUS! */
767 fake_alert(idx, "direction", bot);
768 else if (i >= 0) { /* Valid bot downstream of idx */
769 if (par[0])
770 chatout("*** (%s) %s\n", lastbot(bot), par);
771 botnet_send_unlinked(idx, bot, par);
772 unvia(idx, findbot(bot));
773 rembot(bot);
774 }
775 /* Otherwise it's not even a valid bot, so just ignore! */
776 }
777
778 /* trace <from@bot> <dest> <chain:chain..>
779 */
780 static void bot_trace(int idx, char *par)
781 {
782 char *from, *dest;
783 int i;
784
785 from = newsplit(&par);
786 dest = newsplit(&par);
787 simple_sprintf(TBUF, "%s:%s", par, botnetnick);
788 botnet_send_traced(idx, from, TBUF);
789 if (strcasecmp(dest, botnetnick) && ((i = nextbot(dest)) > 0))
790 botnet_send_trace(i, from, dest, par);
791 }
792
793 /* traced <to@bot> <chain:chain..>
794 */
795 static void bot_traced(int idx, char *par)
796 {
797 char *to, *p;
798 int i, sock;
799
800 to = newsplit(&par);
801 p = strchr(to, '@');
802 if (p == NULL)
803 p = to;
804 else {
805 *p = 0;
806 p++;
807 }
808 if (!strcasecmp(p, botnetnick)) {
809 time_t t = 0;
810 char *p = par, *ss = TBUF;
811
812 splitc(ss, to, ':');
813 if (ss[0])
814 sock = atoi(ss);
815 else
816 sock = (-1);
817 if (par[0] == ':') {
818 t = atoi(par + 1);
819 p = strchr(par + 1, ':');
820 if (p)
821 p++;
822 else
823 p = par + 1;
824 }
825 for (i = 0; i < dcc_total; i++)
826 if ((dcc[i].type->flags & DCT_CHAT) &&
827 (!strcasecmp(dcc[i].nick, to)) &&
828 ((sock == (-1)) || (sock == dcc[i].sock))) {
829 if (t) {
830 dprintf(i, "%s -> %s (%lu secs)\n", _("Trace result"), p, now - t);
831 } else
832 dprintf(i, "%s -> %s\n", _("Trace result"), p);
833 }
834 } else {
835 i = nextbot(p);
836 if (p != to)
837 *--p = '@';
838 if (i >= 0)
839 botnet_send_traced(i, to, par);
840 }
841 }
842
843 /* reject <from> <bot>
844 */
845 static void bot_reject(int idx, char *par)
846 {
847 char *from, *who, *destbot, *frombot;
848 struct userrec *u;
849 int i;
850
851 if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
852 return;
853 from = newsplit(&par);
854 frombot = strchr(from, '@');
855 if (frombot)
856 frombot++;
857 else
858 frombot = from;
859 i = nextbot(frombot);
860 if (i != idx) {
861 fake_alert(idx, "direction", frombot);
862 return;
863 }
864 who = newsplit(&par);
865 if (!(destbot = strchr(who, '@'))) {
866 /* Rejecting a bot */
867 i = nextbot(who);
868 if (i < 0) {
869 botnet_send_priv(idx, botnetnick, from, NULL, "%s %s (%s)",
870 _("Cant unlink"), who, _("doesnt exist"));
871 } else if (!strcasecmp(dcc[i].nick, who)) {
872 char s[1024];
873
874 /* I'm the connection to the rejected bot */
875 putlog(LOG_BOTS, "*", "%s %s %s", from, _("rejected"), dcc[i].nick);
876 dprintf(i, "bye %s\n", par[0] ? par : _("rejected"));
877 simple_sprintf(s, "%s %s (%s: %s)",
878 _("Disconnected"), dcc[i].nick, from,
879 par[0] ? par : _("rejected"));
880 chatout("*** %s\n", s);
881 botnet_send_unlinked(i, dcc[i].nick, s);
882 killsock(dcc[i].sock);
883 lostdcc(i);
884 } else {
885 if (i >= 0)
886 botnet_send_reject(i, from, NULL, who, NULL, par);
887 }
888 } else { /* Rejecting user */
889 *destbot++ = 0;
890 if (!strcasecmp(destbot, botnetnick)) {
891 /* Kick someone here! */
892 int ok = 0;
893
894 if (remote_boots == 1) {
895 frombot = strchr(from, '@');
896 if (frombot == NULL)
897 frombot = from;
898 else
899 frombot++;
900 u = get_user_by_handle(userlist, frombot);
901 if (!(bot_flags(u) & BOT_SHARE)) {
902 add_note(from, botnetnick, "No non sharebot boots.", -1, 0);
903 ok = 1;
904 }
905 } else if (remote_boots == 0) {
906 botnet_send_priv(idx, botnetnick, from, NULL, "%s",
907 _("Remote boots are not allowed."));
908 ok = 1;
909 }
910 for (i = 0; (i < dcc_total) && (!ok); i++)
911 if ((!strcasecmp(who, dcc[i].nick)) &&
912 (dcc[i].type->flags & DCT_CHAT)) {
913 u = get_user_by_handle(userlist, dcc[i].nick);
914 if (u && (u->flags & USER_OWNER)) {
915 add_note(from, botnetnick, _("Cant boot the bot owner."), -1, 0);
916 return;
917 }
918 do_boot(i, from, par);
919 ok = 1;
920 putlog(LOG_CMDS, "*", "#%s# boot %s (%s)", from, dcc[i].nick, par);
921 }
922 } else {
923 i = nextbot(destbot);
924 *--destbot = '@';
925 if (i >= 0)
926 botnet_send_reject(i, from, NULL, who, NULL, par);
927 }
928 }
929 }
930
931 static void bot_thisbot(int idx, char *par)
932 {
933 if (strcasecmp(par, dcc[idx].nick)) {
934 char s[1024];
935
936 putlog(LOG_BOTS, "*", _("Wrong bot--wanted %s, got %s"), dcc[idx].nick, par);
937 dprintf(idx, "bye %s\n", _("imposter"));
938 simple_sprintf(s, "%s %s (%s)", _("Disconnected"), dcc[idx].nick,
939 _("imposter"));
940 chatout("*** %s\n", s);
941 botnet_send_unlinked(idx, dcc[idx].nick, s);
942 unvia(idx, findbot(dcc[idx].nick));
943 killsock(dcc[idx].sock);
944 lostdcc(idx);
945 return;
946 }
947 if (bot_flags(dcc[idx].user) & BOT_LEAF)
948 dcc[idx].status |= STAT_LEAF;
949 /* Set capitalization the way they want it */
950 noshare = 1;
951 change_handle(dcc[idx].user, par);
952 noshare = 0;
953 strcpy(dcc[idx].nick, par);
954 }
955
956 static void bot_handshake(int idx, char *par)
957 {
958 struct userrec *u = get_user_by_handle(userlist, dcc[idx].nick);
959
960 /* We *don't* want botnet passwords migrating */
961 noshare = 1;
962 set_user(&USERENTRY_PASS, u, par);
963 noshare = 0;
964 }
965
966 /* Used to send a direct msg from Tcl on one bot to Tcl on another
967 * zapf <frombot> <tobot> <code [param]>
968 */
969 static void bot_zapf(int idx, char *par)
970 {
971 char *from, *to;
972 int i;
973
974 from = newsplit(&par);
975 to = newsplit(&par);
976 i = nextbot(from);
977 if (i != idx) {
978 fake_alert(idx, "direction", from);
979 return;
980 }
981 if (!strcasecmp(to, botnetnick)) {
982 /* For me! */
983 char *opcode;
984
985 opcode = newsplit(&par);
986 check_bind_bot(from, opcode, par);
987 return;
988 }
989 i = nextbot(to);
990 if (i >= 0)
991 botnet_send_zapf(i, from, to, par);
992 }
993
994 /* Used to send a global msg from Tcl on one bot to every other bot
995 * zapf-broad <frombot> <code [param]>
996 */
997 static void bot_zapfbroad(int idx, char *par)
998 {
999 char *from, *opcode;
1000 int i;
1001
1002 from = newsplit(&par);
1003 opcode = newsplit(&par);
1004
1005 i = nextbot(from);
1006 if (i != idx) {
1007 fake_alert(idx, "direction", from);
1008 return;
1009 }
1010 check_bind_bot(from, opcode, par);
1011 botnet_send_zapf_broad(idx, from, opcode, par);
1012 }
1013
1014 /* Show motd to someone
1015 */
1016 static void bot_motd(int idx, char *par)
1017 {
1018 FILE *vv;
1019 char *s = TBUF, *who, *p;
1020 int i;
1021 struct flag_record fr = {FR_BOT, USER_BOT, 0, 0, 0, 0};
1022
1023 who = newsplit(&par);
1024 if (!par[0] || !strcasecmp(par, botnetnick)) {
1025 int irc = 0;
1026
1027 p = strchr(who, ':');
1028 if (p)
1029 p++;
1030 else
1031 p = who;
1032 if (who[0] == '!') {
1033 irc = HELP_IRC;
1034 who++;
1035 } else if (who[0] == '#') {
1036 who++;
1037 }
1038 putlog(LOG_CMDS, "*", "#%s# motd", p);
1039 vv = fopen(motdfile, "r");
1040 if (vv != NULL) {
1041 botnet_send_priv(idx, botnetnick, who, NULL, "--- %s\n", _("MOTD file:"));
1042 help_subst(NULL, NULL, 0, irc, NULL);
1043 while (!feof(vv)) {
1044 fgets(s, 120, vv);
1045 if (!feof(vv)) {
1046 if (s[strlen(s) - 1] == '\n')
1047 s[strlen(s) - 1] = 0;
1048 if (!s[0])
1049 strcpy(s, " ");
1050 help_subst(s, who, &fr, HELP_DCC, dcc[idx].nick);
1051 if (s[0])
1052 botnet_send_priv(idx, botnetnick, who, NULL, "%s", s);
1053 }
1054 }
1055 fclose(vv);
1056 } else
1057 botnet_send_priv(idx, botnetnick, who, NULL, "%s :(", _("No MOTD file."));
1058 } else {
1059 /* Pass it on */
1060 i = nextbot(par);
1061 if (i >= 0)
1062 botnet_send_motd(i, who, par);
1063 }
1064 }
1065
1066 /* These are still here, so that they will pass the relevant
1067 * requests through even if no filesys is loaded.
1068 *
1069 * filereject <bot:filepath> <sock:nick@bot> <reason...>
1070 */
1071 static void bot_filereject(int idx, char *par)
1072 {
1073 char *path, *to, *tobot, *p;
1074 int i;
1075
1076 path = newsplit(&par);
1077 to = newsplit(&par);
1078 if ((tobot = strchr(to, '@')))
1079 tobot++;
1080 else
1081 tobot = to; /* Bot wants a file?! :) */
1082 if (strcasecmp(tobot, botnetnick)) { /* for me! */
1083 p = strchr(to, ':');
1084 if (p != NULL) {
1085 *p = 0;
1086 for (i = 0; i < dcc_total; i++) {
1087 if (dcc[i].sock == atoi(to))
1088 dprintf(i, "%s (%s): %s\n", _("FILE TRANSFER REJECTED"), path, par);
1089 }
1090 *p = ':';
1091 }
1092 /* No ':'? malformed */
1093 putlog(LOG_FILES, "*", "%s %s: %s", path, _("rejected"), par);
1094 } else { /* Pass it on */
1095 i = nextbot(tobot);
1096 if (i >= 0)
1097 botnet_send_filereject(i, path, to, par);
1098 }
1099 }
1100
1101 /* filereq <sock:nick@bot> <bot:file>
1102 */
1103 static void bot_filereq(int idx, char *tobot)
1104 {
1105 char *from, *path;
1106 int i;
1107
1108 from = newsplit(&tobot);
1109 if ((path = strchr(tobot, ':'))) {
1110 *path++ = 0;
1111
1112 if (!strcasecmp(tobot, botnetnick)) { /* For me! */
1113 /* Process this */
1114 module_entry *fs = module_find("filesys", 0, 0);
1115
1116 if (fs == NULL)
1117 botnet_send_priv(idx, botnetnick, from, NULL, _("Filesys module not loaded."));
1118 else {
1119 Function f = fs->funcs[FILESYS_REMOTE_REQ];
1120
1121 f(idx, from, path);
1122 }
1123 } else { /* Pass it on */
1124 i = nextbot(tobot);
1125 if (i >= 0)
1126 botnet_send_filereq(i, from, tobot, path);
1127 }
1128 }
1129 }
1130
1131 /* filesend <bot:path> <sock:nick@bot> <IP#> <port> <size>
1132 */
1133 static void bot_filesend(int idx, char *par)
1134 {
1135 char *botpath, *to, *tobot, *nick;
1136 int i;
1137 char *nfn;
1138
1139 botpath = newsplit(&par);
1140 to = newsplit(&par);
1141 if ((tobot = strchr(to, '@'))) {
1142 *tobot = 0;
1143 tobot++;
1144 } else {
1145 tobot = to;
1146 }
1147 if (!strcasecmp(tobot, botnetnick)) { /* For me! */
1148 nfn = strrchr(botpath, '/');
1149 if (nfn == NULL) {
1150 nfn = strrchr(botpath, ':');
1151 if (nfn == NULL)
1152 nfn = botpath; /* That's odd. */
1153 else
1154 nfn++;
1155 } else
1156 nfn++;
1157 if ((nick = strchr(to, ':')))
1158 nick++;
1159 else
1160 nick = to;
1161 /* Send it to 'nick' as if it's from me */
1162 dprintf(DP_SERVER, "PRIVMSG %s :\001DCC SEND %s %s\001\n", nick, nfn, par);
1163 } else {
1164 i = nextbot(tobot);
1165 if (i >= 0) {
1166 *--tobot = '@';
1167 botnet_send_filesend(i, botpath, to, par);
1168 }
1169 }
1170 }
1171
1172 static void bot_error(int idx, char *par)
1173 {
1174 putlog(LOG_MISC | LOG_BOTS, "*", "%s: %s", dcc[idx].nick, par);
1175 }
1176
1177 /* nc <bot> <sock> <newnick>
1178 */
1179 static void bot_nickchange(int idx, char *par)
1180 {
1181 char *bot, *ssock, *newnick;
1182 int sock, i;
1183
1184 if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
1185 return;
1186 bot = newsplit(&par);
1187 #ifndef NO_OLD_BOTNET
1188 if (b_numver(idx) < NEAT_BOTNET) {
1189 fake_alert(idx, "botversion", "NEAT_BOTNET");
1190 return;
1191 }
1192 #endif
1193 i = nextbot(bot);
1194 if (i != idx) {
1195 fake_alert(idx, "direction", bot);
1196 return;
1197 }
1198 ssock = newsplit(&par);
1199 sock = base64_to_int(ssock);
1200 newnick = newsplit(&par);
1201 i = partynick(bot, sock, newnick);
1202 if (i < 0) {
1203 fake_alert(idx, "sock#", ssock);
1204 return;
1205 }
1206 chanout_but(-1, party[i].chan, "*** (%s) Nick change: %s -> %s\n",
1207 bot, newnick, party[i].nick);
1208 botnet_send_nkch_part(idx, i, newnick);
1209 }
1210
1211 /* join <bot> <nick> <chan> <flag><sock> <from>
1212 */
1213 static void bot_join(int idx, char *par)
1214 {
1215 char *bot, *nick, *x, *y;
1216 struct userrec *u;
1217 int i, sock, chan, i2, linking = 0;
1218
1219 if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
1220 return;
1221 bot = newsplit(&par);
1222 #ifndef NO_OLD_BOTNET
1223 if (b_numver(idx) >= NEAT_BOTNET)
1224 #endif
1225 if (bot[0] == '!') {
1226 linking = 1;
1227 bot++;
1228 }
1229 if (b_status(idx) & STAT_LINKING) {
1230 linking = 1;
1231 }
1232 nick = newsplit(&par);
1233 x = newsplit(&par);
1234 #ifndef NO_OLD_BOTNET
1235 if (b_numver(idx) < NEAT_BOTNET)
1236 chan = atoi(x);
1237 else
1238 #endif
1239 chan = base64_to_int(x);
1240 y = newsplit(&par);
1241 if ((chan < 0) || !y[0])
1242 return; /* Woops! pre 1.2.1's send .chat off'ers
1243 * too!! */
1244 if (!y[0]) {
1245 y[0] = '-';
1246 sock = 0;
1247 } else {
1248 #ifndef NO_OLD_BOTNET
1249 if (b_numver(idx) < NEAT_BOTNET)
1250 sock = atoi(y + 1);
1251 else
1252 #endif
1253 sock = base64_to_int(y + 1);
1254 }
1255 /* 1.1 bots always send a sock#, even on a channel change
1256 * so if sock# is 0, this is from an old bot and we must tread softly
1257 * grab old sock# if there is one, otherwise make up one.
1258 */
1259 if (sock == 0)
1260 sock = partysock(bot, nick);
1261 if (sock == 0)
1262 sock = fakesock++;
1263 i = nextbot(bot);
1264 if (i != idx) { /* Ok, garbage from a 1.0g (who uses that
1265 * now?) OR raistlin being evil :) */
1266 fake_alert(idx, "direction", bot);
1267 return;
1268 }
1269 u = get_user_by_handle(userlist, nick);
1270 if (u) {
1271 sprintf(TBUF, "@%s", bot);
1272 touch_laston(u, TBUF, now);
1273 }
1274 i = addparty(bot, nick, chan, y[0], sock, par, &i2);
1275 botnet_send_join_party(idx, linking, i2, i);
1276 if (i != chan) {
1277 if (i >= 0) {
1278 if (b_numver(idx) >= NEAT_BOTNET)
1279 chanout_but(-1, i, "*** (%s) %s %s %s.\n", bot, nick, _("has left the"),
1280 i ? "channel" : "party line");
1281 check_bind_chpt(bot, nick, sock, i);
1282 }
1283 if ((b_numver(idx) >= NEAT_BOTNET) && !linking)
1284 chanout_but(-1, chan, "*** (%s) %s %s %s.\n", bot, nick, _("has joined the"),
1285 chan ? "channel" : "party line");
1286 check_bind_chjn(bot, nick, chan, y[0], sock, par);
1287 }
1288 }
1289
1290 /* part <bot> <nick> <sock> [etc..]
1291 */
1292 static void bot_part(int idx, char *par)
1293 {
1294 char *bot, *nick, *etc;
1295 struct userrec *u;
1296 int sock, partyidx;
1297 int silent = 0;
1298
1299 if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
1300 return;
1301 bot = newsplit(&par);
1302 if (bot[0] == '!') {
1303 silent = 1;
1304 bot++;
1305 }
1306 nick = newsplit(&par);
1307 etc = newsplit(&par);
1308 #ifndef NO_OLD_BOTNET
1309 if (b_numver(idx) < NEAT_BOTNET) {
1310 sock = atoi(etc);
1311 silent = 1;
1312 } else
1313 #endif
1314 sock = base64_to_int(etc);
1315 if (sock == 0)
1316 sock = partysock(bot, nick);
1317 u = get_user_by_handle(userlist, nick);
1318 if (u) {
1319 sprintf(TBUF, "@%s", bot);
1320 touch_laston(u, TBUF, now);
1321 }
1322 if ((partyidx = getparty(bot, sock)) != -1) {
1323 if (party[partyidx].chan >= 0) {
1324 check_bind_chpt(bot, nick, sock, party[partyidx].chan);
1325 }
1326 if ((b_numver(idx) >= NEAT_BOTNET) && !silent) {
1327 register int chan = party[partyidx].chan;
1328
1329 if (par[0])
1330 chanout_but(-1, chan, "*** (%s) %s %s %s (%s).\n", bot, nick,
1331 _("has left the"),
1332 chan ? "channel" : "party line", par);
1333 else
1334 chanout_but(-1, chan, "*** (%s) %s %s %s.\n", bot, nick,
1335 _("has left the"),
1336 chan ? "channel" : "party line");
1337 }
1338 botnet_send_part_party(idx, partyidx, par, silent);
1339 remparty(bot, sock);
1340 }
1341 }
1342
1343 /* away <bot> <sock> <message>
1344 * null message = unaway
1345 */
1346 static void bot_away(int idx, char *par)
1347 {
1348 char *bot, *etc;
1349 int sock, partyidx, linking = 0;
1350
1351 if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
1352 return;
1353 bot = newsplit(&par);
1354 #ifndef NO_OLD_BOTNET
1355 if (b_numver(idx) >= NEAT_BOTNET)
1356 #endif
1357 if (bot[0] == '!') {
1358 linking = 1;
1359 bot++;
1360 }
1361 if (b_status(idx) & STAT_LINKING) {
1362 linking = 1;
1363 }
1364 etc = newsplit(&par);
1365 #ifndef NO_OLD_BOTNET
1366 if (b_numver(idx) < NEAT_BOTNET)
1367 sock = atoi(etc);
1368 else
1369 #endif
1370 sock = base64_to_int(etc);
1371 if (sock == 0)
1372 sock = partysock(bot, etc);
1373 check_bind_away(bot, sock, par);
1374 if (par[0]) {
1375 partystat(bot, sock, PLSTAT_AWAY, 0);
1376 partyaway(bot, sock, par);
1377 } else {
1378 partystat(bot, sock, 0, PLSTAT_AWAY);
1379 }
1380 partyidx = getparty(bot, sock);
1381 if ((b_numver(idx) >= NEAT_BOTNET) && !linking) {
1382 if (par[0])
1383 chanout_but(-1, party[partyidx].chan,
1384 "*** (%s) %s %s: %s.\n", bot,
1385 party[partyidx].nick, _("is now away"), par);
1386 else
1387 chanout_but(-1, party[partyidx].chan,
1388 "*** (%s) %s %s.\n", bot,
1389 party[partyidx].nick, _("is no longer away"));
1390 }
1391 botnet_send_away(idx, bot, sock, par, linking);
1392 }
1393
1394 /* (a courtesy info to help during connect bursts)
1395 * idle <bot> <sock> <#secs> [away msg]
1396 */
1397 static void bot_idle(int idx, char *par)
1398 {
1399 char *bot, *work;
1400 int sock, idle;
1401
1402 if (bot_flags(dcc[idx].user) & BOT_ISOLATE)
1403 return;
1404 bot = newsplit(&par);
1405 work = newsplit(&par);
1406 #ifndef NO_OLD_BOTNET
1407 if (b_numver(idx) < NEAT_BOTNET)
1408 sock = atoi(work);
1409 else
1410 #endif
1411 sock = base64_to_int(work);
1412 if (sock == 0)
1413 sock = partysock(bot, work);
1414 work = newsplit(&par);
1415 #ifndef NO_OLD_BOTNET
1416 if (b_numver(idx) < NEAT_BOTNET)
1417 idle = atoi(work);
1418 else
1419 #endif
1420 idle = base64_to_int(work);
1421 partysetidle(bot, sock, idle);
1422 if (par[0]) {
1423 partystat(bot, sock, PLSTAT_AWAY, 0);
1424 partyaway(bot, sock, par);
1425 }
1426 botnet_send_idle(idx, bot, sock, idle, par);
1427 }
1428
1429 #ifndef NO_OLD_BOTNET
1430
1431 static void bot_ufno(int idx, char *par)
1432 {
1433 putlog(LOG_BOTS, "*", "%s %s: %s", _("User file rejected by"), dcc[idx].nick, par);
1434 dcc[idx].status &= ~STAT_OFFERED;
1435 if (!(dcc[idx].status & STAT_GETTING))
1436 dcc[idx].status &= ~STAT_SHARE;
1437 }
1438
1439 static void bot_old_userfile(int idx, char *par)
1440 {
1441 putlog(LOG_BOTS, "*", "%s %s", _("Old style share request by"), dcc[idx].nick);
1442 dprintf(idx, "uf-no %s\n", _("Antiquated sharing request"));
1443 }
1444
1445 #endif /* !NO_OLD_BOTNET */
1446
1447 void bot_share(int idx, char *par)
1448 {
1449 sharein(idx, par);
1450 }
1451
1452 /* v <frombot> <tobot> <idx:nick>
1453 */
1454 static void bot_versions(int sock, char *par)
1455 {
1456 char *frombot = newsplit(&par), *tobot, *from;
1457 module_entry *me;
1458
1459 if (nextbot(frombot) != sock)
1460 fake_alert(sock, "versions-direction", frombot);
1461 else if (strcasecmp(tobot = newsplit(&par), botnetnick)) {
1462 if ((sock = nextbot(tobot)) >= 0)
1463 dprintf(sock, "v %s %s %s\n", frombot, tobot, par);
1464 } else {
1465 from = newsplit(&par);
1466 botnet_send_priv(sock, botnetnick, from, frombot, "Modules loaded:\n");
1467 for (me = module_list; me; me = me->next)
1468 botnet_send_priv(sock, botnetnick, from, frombot, " Module: %s (v%d.%d)\n",
1469 me->name, me->major, me->minor);
1470 botnet_send_priv(sock, botnetnick, from, frombot, "End of module list.\n");
1471 }
1472 }
1473
1474 /* BOT COMMANDS
1475 *
1476 * function call should be:
1477 * int bot_whatever(idx,"parameters");
1478 *
1479 * SORT these, dcc_bot uses a shortcut which requires them sorted
1480 *
1481 * yup, those are tokens there to allow a more efficient botnet as
1482 * time goes on (death to slowly upgrading llama's)
1483 */
1484 botcmd_t C_bot[] =
1485 {
1486 {"a", (Function) bot_actchan},
1487 #ifndef NO_OLD_BOTNET
1488 {"actchan", (Function) bot_actchan},
1489 #endif
1490 {"aw", (Function) bot_away},
1491 {"away", (Function) bot_away},
1492 {"bye", (Function) bot_bye},
1493 {"c", (Function) bot_chan2},
1494 #ifndef NO_OLD_BOTNET
1495 {"chan", (Function) bot_chan2},
1496 {"chat", (Function) bot_chat},
1497 #endif
1498 {"ct", (Function) bot_chat},
1499 {"e", (Function) bot_error},
1500 {"el", (Function) bot_endlink},
1501 #ifndef NO_OLD_BOTNET
1502 {"error", (Function) bot_error},
1503 #endif
1504 {"f!", (Function) bot_filereject},
1505 #ifndef NO_OLD_BOTNET
1506 {"filereject", (Function) bot_filereject},
1507 {"filereq", (Function) bot_filereq},
1508 {"filesend", (Function) bot_filesend},
1509 #endif
1510 {"fr", (Function) bot_filereq},
1511 {"fs", (Function) bot_filesend},
1512 {"h", (Function) bot_handshake},
1513 #ifndef NO_OLD_BOTNET
1514 {"handshake", (Function) bot_handshake},
1515 #endif
1516 {"i", (Function) bot_idle},
1517 {"i?", (Function) bot_infoq},
1518 #ifndef NO_OLD_BOTNET
1519 {"idle", (Function) bot_idle},
1520 {"info?", (Function) bot_infoq},
1521 #endif
1522 {"j", (Function) bot_join},
1523 #ifndef NO_OLD_BOTNET
1524 {"join", (Function) bot_join},
1525 #endif
1526 {"l", (Function) bot_link},
1527 #ifndef NO_OLD_BOTNET
1528 {"link", (Function) bot_link},
1529 {"linked", (Function) bot_linked},
1530 #endif
1531 {"m", (Function) bot_motd},
1532 #ifndef NO_OLD_BOTNET
1533 {"motd", (Function) bot_motd},
1534 #endif
1535 {"n", (Function) bot_nlinked},
1536 {"nc", (Function) bot_nickchange},
1537 #ifndef NO_OLD_BOTNET
1538 {"nlinked", (Function) bot_nlinked},
1539 #endif
1540 {"p", (Function) bot_priv},
1541 #ifndef NO_OLD_BOTNET
1542 {"part", (Function) bot_part},
1543 #endif
1544 {"pi", (Function) bot_ping},
1545 #ifndef NO_OLD_BOTNET
1546 {"ping", (Function) bot_ping},
1547 #endif
1548 {"po", (Function) bot_pong},
1549 #ifndef NO_OLD_BOTNET
1550 {"pong", (Function) bot_pong},
1551 {"priv", (Function) bot_priv},
1552 #endif
1553 {"pt", (Function) bot_part},
1554 {"r", (Function) bot_reject},
1555 #ifndef NO_OLD_BOTNET
1556 {"reject", (Function) bot_reject},
1557 #endif
1558 {"s", (Function) bot_share},
1559 {"t", (Function) bot_trace},
1560 {"tb", (Function) bot_thisbot},
1561 {"td", (Function) bot_traced},
1562 #ifndef NO_OLD_BOTNET
1563 {"thisbot", (Function) bot_thisbot},
1564 {"trace", (Function) bot_trace},
1565 {"traced", (Function) bot_traced},
1566 #endif
1567 {"u", (Function) bot_update},
1568 #ifndef NO_OLD_BOTNET
1569 {"uf-no", (Function) bot_ufno},
1570 #endif
1571 {"ul", (Function) bot_unlink},
1572 {"un", (Function) bot_unlinked},
1573 #ifndef NO_OLD_BOTNET
1574 {"unaway", (Function) bot_away},
1575 {"unlink", (Function) bot_unlink},
1576 {"unlinked", (Function) bot_unlinked},
1577 {"update", (Function) bot_update},
1578 {"userfile?", (Function) bot_old_userfile},
1579 #endif
1580 {"v", (Function) bot_versions},
1581 {"w", (Function) bot_who},
1582 #ifndef NO_OLD_BOTNET
1583 {"who", (Function) bot_who},
1584 #endif
1585 {"z", (Function) bot_zapf},
1586 #ifndef NO_OLD_BOTNET
1587 {"zapf", (Function) bot_zapf},
1588 {"zapf-broad", (Function) bot_zapfbroad},
1589 #endif
1590 {"zb", (Function) bot_zapfbroad},
1591 {NULL, NULL}
1592 };

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23