/[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.14 - (hide annotations) (download) (as text)
Mon Jan 17 16:14:44 2000 UTC (19 years, 11 months ago) by per
Branch: MAIN
Changes since 1.13: +4 -10 lines
File MIME type: text/x-chdr
relayfix, extern_cleanup

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23