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

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

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


Revision 1.2 - (hide annotations) (download) (as text)
Sun Jun 27 21:02:38 1999 UTC (20 years, 7 months ago) by guppy
Branch: MAIN
Changes since 1.1: +0 -2 lines
File MIME type: text/x-chdr
*** empty log message ***

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23