/[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.3 - (show annotations) (download) (as text)
Tue Jul 13 14:26:11 1999 UTC (20 years, 8 months ago) by poptix
Branch: MAIN
Changes since 1.2: +6 -1 lines
File MIME type: text/x-chdr
           Fixed some buffer overflows, fixed a duplication, moved text
     to language file, fixed some cosmetic stuff.

				-poptix

 Modified Files:
 	doc/UPDATES1.3 language/core.english.lang src/botcmd.c
 	src/cmds.c src/patch.h

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23