/[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.10 - (hide annotations) (download) (as text)
Wed Dec 15 02:32:57 1999 UTC (20 years ago) by guppy
Branch: MAIN
Changes since 1.9: +24 -9 lines
File MIME type: text/x-chdr
id-header patch, finally, we have id tags for each file

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23