/[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.1.1.1 - (hide annotations) (download) (as text) (vendor branch)
Wed Jun 23 19:51:26 1999 UTC (20 years, 7 months ago) by segfault
Branch: eggdev
CVS Tags: start
Changes since 1.1: +0 -0 lines
File MIME type: text/x-chdr
Eggdrop 1.3.28 CVS Code

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23