/[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.3 - (hide annotations) (download) (as text)
Tue Jul 13 14:26:11 1999 UTC (20 years, 6 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 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 poptix 1.3 char s[200], s2[32];
442 segfault 1.1 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 poptix 1.3 if ((strlen(s) + strlen(chan->name) + strlen(network)
469     + strlen(botnetnick) + strlen(ver) + 1) >= 200) {
470     strcat(s,"++ ");
471     break; /* yegads..! */
472     }
473 segfault 1.1 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