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

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

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


Revision 1.6 - (show annotations) (download) (as text)
Wed Oct 20 01:00:03 1999 UTC (20 years, 1 month ago) by guppy
Branch: MAIN
Changes since 1.5: +2 -1 lines
File MIME type: text/x-chdr
more patches

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23