/[cvs]/eggdrop1.8/src/botcmd.c
ViewVC logotype

Annotation of /eggdrop1.8/src/botcmd.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2.2.1 - (hide annotations) (download) (as text)
Wed Nov 10 13:39:19 2010 UTC (8 years, 11 months ago) by pseudo
Branch: gettext
Changes since 1.2: +139 -123 lines
File MIME type: text/x-chdr
Converted remaining lang #defines in the core to english strings from core.english.lang. Gettextified most of the hardcoded strings.

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23