/[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.5 - (hide annotations) (download) (as text)
Wed Sep 15 07:18:58 1999 UTC (20 years, 3 months ago) by poptix
Branch: MAIN
Changes since 1.4: +1 -1 lines
File MIME type: text/x-chdr
tmprace.patch

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23