/[cvs]/eggdrop1.4/src/botnet.c
ViewVC logotype

Annotation of /eggdrop1.4/src/botnet.c

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


Revision 1.12 - (hide annotations) (download) (as text)
Mon May 22 18:37:30 2000 UTC (19 years, 3 months ago) by guppy
Branch: MAIN
Changes since 1.11: +15 -2 lines
File MIME type: text/x-chdr
added fabian's patches, including a small bugfix for the ghostbug workaround

1 segfault 1.1 /*
2     * botnet.c -- handles:
3 guppy 1.7 * keeping track of which bot's connected where in the chain
4     * dumping a list of bots or a bot tree to a user
5     * channel name associations on the party line
6     * rejecting a bot
7     * linking, unlinking, and relaying to another bot
8     * pinging the bots periodically and checking leaf status
9     *
10 segfault 1.1 * dprintf'ized, 28nov1995
11 guppy 1.7 *
12 guppy 1.12 * $Id: botnet.c,v 1.11 2000/01/17 16:14:44 per Exp $
13 segfault 1.1 */
14 guppy 1.7 /*
15     * Copyright (C) 1997 Robey Pointer
16 per 1.10 * Copyright (C) 1999, 2000 Eggheads
17 guppy 1.7 *
18     * This program is free software; you can redistribute it and/or
19     * modify it under the terms of the GNU General Public License
20     * as published by the Free Software Foundation; either version 2
21     * of the License, or (at your option) any later version.
22     *
23     * This program is distributed in the hope that it will be useful,
24     * but WITHOUT ANY WARRANTY; without even the implied warranty of
25     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26     * GNU General Public License for more details.
27     *
28     * You should have received a copy of the GNU General Public License
29     * along with this program; if not, write to the Free Software
30     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 segfault 1.1 */
32    
33     #include "main.h"
34     #include "tandem.h"
35    
36 per 1.11 extern char spaces[], spaces2[];
37     extern int dcc_total, backgrd, connect_timeout, max_dcc, egg_numver;
38     extern struct userrec *userlist;
39 segfault 1.1 extern struct dcc_t *dcc;
40     extern time_t now;
41     extern Tcl_Interp *interp;
42    
43     tand_t *tandbot; /* keep track of tandem bots on the botnet */
44     party_t *party; /* keep track of people on the botnet */
45     static int maxparty = 50; /* maximum space for party line members
46     * currently */
47     int tands = 0; /* number of bots on the botnet */
48     int parties = 0; /* number of people on the botnet */
49     char botnetnick[HANDLEN + 1] = ""; /* botnet nickname */
50     int share_unlinks = 0; /* allow remote unlinks of my sharebots ? */
51    
52     int expmem_botnet()
53     {
54     int size = 0, i;
55     tand_t *bot;
56    
57     for (bot = tandbot; bot; bot = bot->next)
58     size += sizeof(tand_t);
59 guppy 1.6 Context;
60 segfault 1.1 size += (maxparty * sizeof(party_t));
61     for (i = 0; i < parties; i++) {
62     if (party[i].away)
63     size += strlen(party[i].away) + 1;
64     if (party[i].from)
65     size += strlen(party[i].from) + 1;
66     }
67     return size;
68     }
69    
70     void init_bots()
71     {
72     tandbot = NULL;
73     /* grab space for 50 bots for now -- expand later as needed */
74     maxparty = 50;
75     party = (party_t *) nmalloc(maxparty * sizeof(party_t));
76     }
77    
78     tand_t *findbot(char *who)
79     {
80     tand_t *ptr = tandbot;
81    
82     while (ptr) {
83     if (!strcasecmp(ptr->bot, who))
84     return ptr;
85     ptr = ptr->next;
86     }
87     return NULL;
88     }
89    
90     /* add a tandem bot to our chain list */
91     void addbot(char *who, char *from, char *next, char flag, int vernum)
92     {
93     tand_t **ptr = &tandbot, *ptr2;
94    
95 guppy 1.6 Context;
96 segfault 1.1 while (*ptr) {
97     if (!strcasecmp((*ptr)->bot, who))
98     putlog(LOG_BOTS, "*", "!!! Duplicate botnet bot entry!!");
99     ptr = &((*ptr)->next);
100     }
101     ptr2 = nmalloc(sizeof(tand_t));
102     strncpy(ptr2->bot, who, HANDLEN);
103     ptr2->bot[HANDLEN] = 0;
104     ptr2->share = flag;
105     ptr2->ver = vernum;
106     ptr2->next = *ptr;
107     *ptr = ptr2;
108     /* may be via itself */
109     ptr2->via = findbot(from);
110     if (!strcasecmp(next, botnetnick))
111     ptr2->uplink = (tand_t *) 1;
112     else
113     ptr2->uplink = findbot(next);
114     tands++;
115     }
116    
117     void updatebot(int idx, char *who, char share, int vernum)
118     {
119     tand_t *ptr = findbot(who);
120    
121 guppy 1.6 Context;
122 segfault 1.1 if (ptr) {
123     if (share)
124     ptr->share = share;
125     if (vernum)
126     ptr->ver = vernum;
127     botnet_send_update(idx, ptr);
128     }
129     }
130    
131     /* for backward 1.0 compatibility: */
132     /* grab the (first) sock# for a user on another bot */
133     int partysock(char *bot, char *nick)
134     {
135     int i;
136    
137     for (i = 0; i < parties; i++) {
138     if ((!strcasecmp(party[i].bot, bot)) &&
139     (!strcasecmp(party[i].nick, nick)))
140     return party[i].sock;
141     }
142     return 0;
143     }
144    
145     /* new botnet member */
146     int addparty(char *bot, char *nick, int chan, char flag, int sock,
147     char *from, int *idx)
148     {
149     int i;
150    
151 guppy 1.6 Context;
152 segfault 1.1 for (i = 0; i < parties; i++) {
153     /* just changing the channel of someone already on? */
154     if (!strcasecmp(party[i].bot, bot) &&
155     (party[i].sock == sock)) {
156     int oldchan = party[i].chan;
157    
158     party[i].chan = chan;
159     party[i].timer = now;
160     if (from[0]) {
161     if (flag == ' ')
162     flag = '-';
163     party[i].flag = flag;
164     if (party[i].from)
165     nfree(party[i].from);
166     party[i].from = nmalloc(strlen(from) + 1);
167     strcpy(party[i].from, from);
168     }
169     *idx = i;
170     return oldchan;
171     }
172     }
173     /* new member */
174     if (parties == maxparty) {
175     maxparty += 50;
176     party = (party_t *) nrealloc((void *) party, maxparty * sizeof(party_t));
177     }
178     strncpy(party[parties].nick, nick, HANDLEN);
179     party[parties].nick[HANDLEN] = 0;
180     strncpy(party[parties].bot, bot, HANDLEN);
181     party[parties].bot[HANDLEN] = 0;
182     party[parties].chan = chan;
183     party[parties].sock = sock;
184     party[parties].status = 0;
185     party[parties].away = 0;
186     party[parties].timer = now; /* cope. */
187     if (from[0]) {
188     if (flag == ' ')
189     flag = '-';
190     party[parties].flag = flag;
191     party[parties].from = nmalloc(strlen(from) + 1);
192     strcpy(party[parties].from, from);
193     } else {
194     party[parties].flag = ' ';
195     party[parties].from = nmalloc(10);
196     strcpy(party[parties].from, "(unknown)");
197     }
198     *idx = parties;
199     parties++;
200     return -1;
201     }
202    
203     /* alter status flags for remote party-line user */
204     void partystat(char *bot, int sock, int add, int rem)
205     {
206     int i;
207    
208     for (i = 0; i < parties; i++) {
209     if ((!strcasecmp(party[i].bot, bot)) &&
210     (party[i].sock == sock)) {
211     party[i].status |= add;
212     party[i].status &= ~rem;
213     }
214     }
215     }
216    
217     /* other bot is sharing idle info */
218     void partysetidle(char *bot, int sock, int secs)
219     {
220     int i;
221    
222     for (i = 0; i < parties; i++) {
223     if ((!strcasecmp(party[i].bot, bot)) &&
224     (party[i].sock == sock)) {
225     party[i].timer = (now - (time_t) secs);
226     }
227     }
228     }
229    
230     /* return someone's chat channel */
231     int getparty(char *bot, int sock)
232     {
233     int i;
234    
235     for (i = 0; i < parties; i++) {
236     if (!strcasecmp(party[i].bot, bot) &&
237     (party[i].sock == sock)) {
238     return i;
239     }
240     }
241     return -1;
242     }
243    
244     /* un-idle someone */
245     int partyidle(char *bot, char *nick)
246     {
247     int i, ok = 0;
248    
249     for (i = 0; i < parties; i++) {
250     if ((!strcasecmp(party[i].bot, bot)) &&
251     (!strcasecmp(party[i].nick, nick))) {
252     party[i].timer = now;
253     ok = 1;
254     }
255     }
256     return ok;
257     }
258    
259     /* change someone's nick */
260     int partynick(char *bot, int sock, char *nick)
261     {
262     char work[HANDLEN + 1];
263     int i;
264    
265     for (i = 0; i < parties; i++) {
266     if (!strcasecmp(party[i].bot, bot) && (party[i].sock == sock)) {
267     strcpy(work, party[i].nick);
268     strncpy(party[i].nick, nick, HANDLEN);
269     party[i].nick[HANDLEN] = 0;
270     strcpy(nick, work);
271     return i;
272     }
273     }
274     return -1;
275     }
276    
277     /* set away message */
278     void partyaway(char *bot, int sock, char *msg)
279     {
280     int i;
281    
282     for (i = 0; i < parties; i++) {
283     if ((!strcasecmp(party[i].bot, bot)) &&
284     (party[i].sock == sock)) {
285     if (party[i].away)
286     nfree(party[i].away);
287     if (msg[0]) {
288     party[i].away = nmalloc(strlen(msg) + 1);
289     strcpy(party[i].away, msg);
290     } else
291     party[i].away = 0;
292     }
293     }
294     }
295    
296     /* remove a tandem bot from the chain list */
297     void rembot(char *who)
298     {
299     tand_t **ptr = &tandbot, *ptr2;
300    
301 guppy 1.6 Context;
302 segfault 1.1 while (*ptr) {
303     if (!strcasecmp((*ptr)->bot, who))
304     break;
305     ptr = &((*ptr)->next);
306     }
307     if (!*ptr)
308     /* may have just .unlink *'d */
309     return;
310     check_tcl_disc(who);
311    
312     ptr2 = *ptr;
313     *ptr = ptr2->next;
314     nfree(ptr2);
315     tands--;
316     }
317    
318     void remparty(char *bot, int sock)
319     {
320     int i;
321    
322 guppy 1.6 Context;
323 segfault 1.1 for (i = 0; i < parties; i++)
324     if ((!strcasecmp(party[i].bot, bot)) &&
325     (party[i].sock == sock)) {
326     parties--;
327     if (party[i].from)
328     nfree(party[i].from);
329     if (party[i].away)
330     nfree(party[i].away);
331     if (i < parties) {
332     strcpy(party[i].bot, party[parties].bot);
333     strcpy(party[i].nick, party[parties].nick);
334     party[i].chan = party[parties].chan;
335     party[i].sock = party[parties].sock;
336     party[i].flag = party[parties].flag;
337     party[i].status = party[parties].status;
338     party[i].timer = party[parties].timer;
339     party[i].from = party[parties].from;
340     party[i].away = party[parties].away;
341     }
342     }
343     }
344    
345     /* cancel every user that was on a certain bot */
346     void rempartybot(char *bot)
347     {
348     int i;
349    
350     for (i = 0; i < parties; i++)
351     if (!strcasecmp(party[i].bot, bot)) {
352 guppy 1.3 if (party[i].chan >= 0)
353     check_tcl_chpt(bot, party[i].nick, party[i].sock, party[i].chan);
354 segfault 1.1 remparty(bot, party[i].sock);
355     i--;
356     }
357     }
358    
359     /* remove every bot linked 'via' bot <x> */
360     void unvia(int idx, tand_t * who)
361     {
362     tand_t *bot, *bot2;
363    
364     if (!who)
365     return; /* safety */
366     rempartybot(who->bot);
367     bot = tandbot;
368     while (bot) {
369     if (bot->uplink == who) {
370     unvia(idx, bot);
371     bot2 = bot->next;
372     rembot(bot->bot);
373     bot = bot2;
374     } else
375     bot = bot->next;
376     }
377     #ifndef NO_OLD_BOTNET
378     /* every bot unvia's bots behind anyway, so why send msg's for
379     * EVERY one? - will this break things?! */
380     tandout_but(idx, "unlinked %s\n", who->bot);
381     #endif
382     }
383    
384     /* return index into dcc list of the bot that connects us to bot <x> */
385     int nextbot(char *who)
386     {
387     int j;
388     tand_t *bot = findbot(who);
389    
390     if (!bot)
391     return -1;
392    
393     for (j = 0; j < dcc_total; j++)
394     if (bot->via && !strcasecmp(bot->via->bot, dcc[j].nick) &&
395     (dcc[j].type == &DCC_BOT))
396     return j;
397     return -1; /* we're not connected to 'via' */
398     }
399    
400     /* return name of the bot that is directly connected to bot X */
401     char *lastbot(char *who)
402     {
403     tand_t *bot = findbot(who);
404    
405     if (!bot)
406     return "*";
407     else if (bot->uplink == (tand_t *) 1)
408     return botnetnick;
409     else
410     return bot->uplink->bot;
411     }
412    
413     /* modern version of 'whom' (use local data) */
414     void answer_local_whom(int idx, int chan)
415     {
416     char c, idle[40], spaces2[33] = " ";
417     int i, len, len2;
418    
419 guppy 1.6 Context;
420 segfault 1.1 if (chan == (-1))
421     dprintf(idx, "%s (+: %s, *: %s)\n", BOT_BOTNETUSERS, BOT_PARTYLINE,
422     BOT_LOCALCHAN);
423     else if (chan > 0) {
424     simple_sprintf(idle, "assoc %d", chan);
425     if ((Tcl_Eval(interp, idle) != TCL_OK) || !interp->result[0])
426     dprintf(idx, "%s %s%d:\n", BOT_USERSONCHAN,
427     (chan < 100000) ? "" : "*", chan % 100000);
428     else
429     dprintf(idx, "%s '%s%s' (%s%d):\n", BOT_USERSONCHAN,
430     (chan < 100000) ? "" : "*", interp->result,
431     (chan < 100000) ? "" : "*", chan % 100000);
432     }
433     spaces[HANDLEN - 9] = 0;
434     dprintf(idx, " Nick %s Bot %s Host\n", spaces, spaces);
435     dprintf(idx, "----------%s ---------%s --------------------\n",
436     spaces, spaces);
437     spaces[HANDLEN - 9] = ' ';
438     for (i = 0; i < dcc_total; i++)
439     if (dcc[i].type == &DCC_CHAT) {
440     if ((chan == (-1)) || ((chan >= 0) && (dcc[i].u.chat->channel == chan))) {
441     c = geticon(i);
442     if (c == '-')
443     c = ' ';
444     if (now - dcc[i].timeval > 300) {
445     unsigned long days, hrs, mins;
446    
447     days = (now - dcc[i].timeval) / 86400;
448     hrs = ((now - dcc[i].timeval) - (days * 86400)) / 3600;
449     mins = ((now - dcc[i].timeval) - (hrs * 3600)) / 60;
450     if (days > 0)
451     sprintf(idle, " [idle %lud%luh]", days, hrs);
452     else if (hrs > 0)
453     sprintf(idle, " [idle %luh%lum]", hrs, mins);
454     else
455     sprintf(idle, " [idle %lum]", mins);
456     } else
457     idle[0] = 0;
458     spaces[len = HANDLEN - strlen(dcc[i].nick)] = 0;
459     spaces2[len2 = HANDLEN - strlen(botnetnick)] = 0;
460     dprintf(idx, "%c%s%s %c %s%s %s%s\n", c, dcc[i].nick, spaces,
461     (dcc[i].u.chat->channel == 0) && (chan == (-1)) ? '+' :
462     (dcc[i].u.chat->channel > 100000) &&
463     (chan == (-1)) ? '*' : ' ',
464     botnetnick, spaces2, dcc[i].host, idle);
465     spaces[len] = ' ';
466     spaces2[len2] = ' ';
467     if (dcc[i].u.chat->away != NULL)
468     dprintf(idx, " AWAY: %s\n", dcc[i].u.chat->away);
469     }
470     }
471     for (i = 0; i < parties; i++) {
472     if ((chan == (-1)) || ((chan >= 0) && (party[i].chan == chan))) {
473     c = party[i].flag;
474     if (c == '-')
475     c = ' ';
476     if (party[i].timer == 0L)
477     strcpy(idle, " [idle?]");
478     else if (now - party[i].timer > 300) {
479     unsigned long days, hrs, mins;
480    
481     days = (now - party[i].timer) / 86400;
482     hrs = ((now - party[i].timer) - (days * 86400)) / 3600;
483     mins = ((now - party[i].timer) - (hrs * 3600)) / 60;
484     if (days > 0)
485     sprintf(idle, " [idle %lud%luh]", days, hrs);
486     else if (hrs > 0)
487     sprintf(idle, " [idle %luh%lum]", hrs, mins);
488     else
489     sprintf(idle, " [idle %lum]", mins);
490     } else
491     idle[0] = 0;
492     spaces[len = HANDLEN - strlen(party[i].nick)] = 0;
493     spaces2[len2 = HANDLEN - strlen(party[i].bot)] = 0;
494     dprintf(idx, "%c%s%s %c %s%s %s%s\n", c, party[i].nick, spaces,
495     (party[i].chan == 0) && (chan == (-1)) ? '+' : ' ',
496     party[i].bot, spaces2, party[i].from, idle);
497     spaces[len] = ' ';
498     spaces2[len2] = ' ';
499     if (party[i].status & PLSTAT_AWAY)
500     dprintf(idx, " %s: %s\n", MISC_AWAY, safe_str(party[i].away));
501     }
502     }
503     }
504    
505     /* show z a list of all bots connected */
506     void tell_bots(int idx)
507     {
508     char s[512];
509     int i;
510     tand_t *bot;
511    
512     if (!tands) {
513     dprintf(idx, "%s\n", BOT_NOBOTSLINKED);
514     return;
515     }
516     strcpy(s, botnetnick);
517     i = strlen(botnetnick);
518    
519     for (bot = tandbot; bot; bot = bot->next) {
520     if (i > (500 - HANDLEN)) {
521     dprintf(idx, "Bots: %s\n", s);
522     s[0] = 0;
523     i = 0;
524     }
525     if (i) {
526     s[i++] = ',';
527     s[i++] = ' ';
528     }
529     strcpy(s + i, bot->bot);
530     i += strlen(bot->bot);
531     }
532     if (s[0])
533     dprintf(idx, "Bots: %s\n", s);
534     dprintf(idx, "(%s: %d)\n", MISC_TOTAL, tands + 1);
535     }
536    
537     /* show a simpleton bot tree */
538     void tell_bottree(int idx, int showver)
539     {
540     char s[161];
541     tand_t *last[20], *this, *bot, *bot2 = NULL;
542     int lev = 0, more = 1, mark[20], ok, cnt, i, imark;
543     char work[1024];
544     int tothops = 0;
545    
546     if (tands == 0) {
547     dprintf(idx, "%s\n", BOT_NOBOTSLINKED);
548     return;
549     }
550     s[0] = 0;
551     i = 0;
552    
553     for (bot = tandbot; bot; bot = bot->next)
554     if (!bot->uplink) {
555     if (i) {
556     s[i++] = ',';
557     s[i++] = ' ';
558     }
559     strcpy(s + i, bot->bot);
560     i += strlen(bot->bot);
561     }
562     if (s[0])
563     dprintf(idx, "(%s %s)\n", BOT_NOTRACEINFO, s);
564     if (showver)
565     dprintf(idx, "%s (%d.%d.%d.%d)\n", botnetnick,
566     egg_numver / 1000000,
567     egg_numver % 1000000 / 10000,
568     egg_numver % 10000 / 100,
569     egg_numver % 100);
570     else
571     dprintf(idx, "%s\n", botnetnick);
572     this = (tand_t *) 1;
573     work[0] = 0;
574     while (more) {
575     if (lev == 20) {
576     dprintf(idx, "\n%s\n", BOT_COMPLEXTREE);
577     return;
578     }
579     cnt = 0;
580     tothops += lev;
581     for (bot = tandbot; bot; bot = bot->next)
582     if (bot->uplink == this)
583     cnt++;
584     if (cnt) {
585     imark = 0;
586     for (i = 0; i < lev; i++) {
587     if (mark[i])
588     strcpy(work + imark, " | ");
589     else
590     strcpy(work + imark, " ");
591     imark += 5;
592     }
593     if (cnt > 1)
594     strcpy(work + imark, " |-");
595     else
596     strcpy(work + imark, " `-");
597     s[0] = 0;
598     bot = tandbot;
599     while (!s[0]) {
600     if (bot->uplink == this) {
601     if (bot->ver) {
602     i = sprintf(s, "%c%s", bot->share, bot->bot);
603     if (showver)
604     sprintf(s + i, " (%d.%d.%d.%d)",
605     bot->ver / 1000000,
606     bot->ver % 1000000 / 10000,
607     bot->ver % 10000 / 100,
608     bot->ver % 100);
609     } else {
610     sprintf(s, "-%s", bot->bot);
611     }
612     } else
613     bot = bot->next;
614     }
615     dprintf(idx, "%s%s\n", work, s);
616     if (cnt > 1)
617     mark[lev] = 1;
618     else
619     mark[lev] = 0;
620     work[0] = 0;
621     last[lev] = this;
622     this = bot;
623     lev++;
624     more = 1;
625     } else {
626     while (cnt == 0) {
627     /* no subtrees from here */
628     if (lev == 0) {
629     dprintf(idx, "(( tree error ))\n");
630     return;
631     }
632     ok = 0;
633     for (bot = tandbot; bot; bot = bot->next) {
634     if (bot->uplink == last[lev - 1]) {
635     if (this == bot)
636     ok = 1;
637     else if (ok) {
638     cnt++;
639     if (cnt == 1) {
640     bot2 = bot;
641     if (bot->ver) {
642     i = sprintf(s, "%c%s", bot->share, bot->bot);
643     if (showver)
644     sprintf(s + i, " (%d.%d.%d.%d)",
645     bot->ver / 1000000,
646     bot->ver % 1000000 / 10000,
647     bot->ver % 10000 / 100,
648     bot->ver % 100);
649     } else {
650     sprintf(s, "-%s", bot->bot);
651     }
652     }
653     }
654     }
655     }
656     if (cnt) {
657     imark = 0;
658     for (i = 1; i < lev; i++) {
659     if (mark[i - 1])
660     strcpy(work + imark, " | ");
661     else
662     strcpy(work + imark, " ");
663     imark += 5;
664     }
665     more = 1;
666     if (cnt > 1)
667     dprintf(idx, "%s |-%s\n", work, s);
668     else
669     dprintf(idx, "%s `-%s\n", work, s);
670     this = bot2;
671     work[0] = 0;
672     if (cnt > 1)
673     mark[lev - 1] = 1;
674     else
675     mark[lev - 1] = 0;
676     } else {
677     /* this was the last child */
678     lev--;
679     if (lev == 0) {
680     more = 0;
681     cnt = 999;
682     } else {
683     more = 1;
684     this = last[lev];
685     }
686     }
687     }
688     }
689     }
690     /* hop information: (9d) */
691     dprintf(idx, "Average hops: %3.1f, total bots: %d\n",
692     ((float) tothops) / ((float) tands), tands + 1);
693     }
694    
695     /* dump list of links to a new bot */
696     void dump_links(int z)
697     {
698 guppy 1.9 register int i, l;
699 segfault 1.1 char x[1024];
700     tand_t *bot;
701    
702 guppy 1.6 Context;
703 segfault 1.1 for (bot = tandbot; bot; bot = bot->next) {
704     char *p;
705    
706     if (bot->uplink == (tand_t *) 1)
707     p = botnetnick;
708     else
709     p = bot->uplink->bot;
710     #ifndef NO_OLD_BOTNET
711     if (b_numver(z) < NEAT_BOTNET)
712     l = simple_sprintf(x, "nlinked %s %s %c%d\n", bot->bot,
713     p, bot->share, bot->ver);
714     else
715     #endif
716     l = simple_sprintf(x, "n %s %s %c%D\n", bot->bot, p,
717     bot->share, bot->ver);
718     tputs(dcc[z].sock, x, l);
719     }
720 guppy 1.6 Context;
721 segfault 1.1 if (!(bot_flags(dcc[z].user) & BOT_ISOLATE)) {
722     /* dump party line members */
723     for (i = 0; i < dcc_total; i++) {
724     if (dcc[i].type == &DCC_CHAT) {
725     if ((dcc[i].u.chat->channel >= 0) &&
726     (dcc[i].u.chat->channel < 100000)) {
727     #ifndef NO_OLD_BOTNET
728     if (b_numver(z) < NEAT_BOTNET)
729     l = simple_sprintf(x, "join %s %s %d %c%d %s\n",
730     botnetnick, dcc[i].nick,
731     dcc[i].u.chat->channel, geticon(i),
732     dcc[i].sock, dcc[i].host);
733     else
734     #endif
735     l = simple_sprintf(x, "j !%s %s %D %c%D %s\n",
736     botnetnick, dcc[i].nick,
737     dcc[i].u.chat->channel, geticon(i),
738     dcc[i].sock, dcc[i].host);
739     tputs(dcc[z].sock, x, l);
740     #ifndef NO_OLD_BOTNET
741     if (b_numver(z) < NEAT_BOTNET) {
742     if (dcc[i].u.chat->away) {
743     l = simple_sprintf(x, "away %s %d %s\n", botnetnick,
744     dcc[i].sock, dcc[i].u.chat->away);
745     tputs(dcc[z].sock, x, l);
746     }
747     l = simple_sprintf(x, "idle %s %d %d\n", botnetnick,
748     dcc[i].sock, now - dcc[i].timeval);
749     } else
750     #endif
751     l = simple_sprintf(x, "i %s %D %D %s\n", botnetnick,
752     dcc[i].sock, now - dcc[i].timeval,
753     dcc[i].u.chat->away ? dcc[i].u.chat->away : "");
754     tputs(dcc[z].sock, x, l);
755     }
756     }
757     }
758 guppy 1.6 Context;
759 segfault 1.1 for (i = 0; i < parties; i++) {
760     #ifndef NO_OLD_BOTNET
761     if (b_numver(z) < NEAT_BOTNET)
762     l = simple_sprintf(x, "join %s %s %d %c%d %s\n",
763     party[i].bot, party[i].nick,
764     party[i].chan, party[i].flag,
765     party[i].sock, party[i].from);
766     else
767     #endif
768     l = simple_sprintf(x, "j %s %s %D %c%D %s\n",
769     party[i].bot, party[i].nick,
770     party[i].chan, party[i].flag,
771     party[i].sock, party[i].from);
772     tputs(dcc[z].sock, x, l);
773     if ((party[i].status & PLSTAT_AWAY) || (party[i].timer != 0)) {
774     #ifndef NO_OLD_BOTNET
775     if (b_numver(z) < NEAT_BOTNET) {
776     if (party[i].status & PLSTAT_AWAY) {
777     l = simple_sprintf(x, "away %s %d %s\n", party[i].bot,
778     party[i].sock, party[i].away);
779     tputs(dcc[z].sock, x, l);
780     }
781     l = simple_sprintf(x, "idle %s %d %d\n", party[i].bot,
782     party[i].sock, now - party[i].timer);
783     } else
784     #endif
785     l = simple_sprintf(x, "i %s %D %D %s\n", party[i].bot,
786     party[i].sock, now - party[i].timer,
787     party[i].away ? party[i].away : "");
788     tputs(dcc[z].sock, x, l);
789     }
790     }
791     }
792 guppy 1.6 Context;
793 segfault 1.1 }
794    
795     int in_chain(char *who)
796     {
797     if (findbot(who))
798     return 1;
799     if (!strcasecmp(who, botnetnick))
800     return 1;
801     return 0;
802     }
803    
804     /* break link with a tandembot */
805     int botunlink(int idx, char *nick, char *reason)
806     {
807     char s[20];
808 guppy 1.9 register int i;
809 guppy 1.12 tand_t *bot;
810 segfault 1.1
811 guppy 1.6 Context;
812 segfault 1.1 if (nick[0] == '*')
813     dprintf(idx, "%s\n", BOT_UNLINKALL);
814     for (i = 0; i < dcc_total; i++) {
815     if ((nick[0] == '*') || !strcasecmp(dcc[i].nick, nick)) {
816     if (dcc[i].type == &DCC_FORK_BOT) {
817     if (idx >= 0)
818     dprintf(idx, "%s: %s -> %s.\n", BOT_KILLLINKATTEMPT,
819     dcc[i].nick, dcc[i].host);
820     putlog(LOG_BOTS, "*", "%s: %s -> %s:%d",
821     BOT_KILLLINKATTEMPT, dcc[i].nick,
822     dcc[i].host, dcc[i].port);
823     killsock(dcc[i].sock);
824     lostdcc(i);
825     if (nick[0] != '*')
826     return 1;
827     } else if (dcc[i].type == &DCC_BOT_NEW) {
828     if (idx >= 0)
829     dprintf(idx, "%s %s.\n", BOT_ENDLINKATTEMPT,
830     dcc[i].nick);
831     putlog(LOG_BOTS, "*", "%s %s @ %s:%d",
832     "Stopped trying to link", dcc[i].nick,
833     dcc[i].host, dcc[i].port);
834     killsock(dcc[i].sock);
835     lostdcc(i);
836     if (nick[0] != '*')
837     return 1;
838     else
839     i--;
840     } else if (dcc[i].type == &DCC_BOT) {
841     char s[1024];
842    
843 guppy 1.6 Context;
844 segfault 1.1
845     if (idx >= 0)
846     dprintf(idx, "%s %s.\n", BOT_BREAKLINK, dcc[i].nick);
847     else if ((idx == -3) && (b_status(i) & STAT_SHARE) && !share_unlinks)
848     return -1;
849     dprintf(i, "bye\n");
850     if (reason && reason[0]) {
851     simple_sprintf(s, "%s %s (%s)", BOT_UNLINKEDFROM,
852     dcc[i].nick, reason);
853     } else {
854     simple_sprintf(s, "%s %s", BOT_UNLINKEDFROM, dcc[i].nick);
855     }
856     chatout("*** %s\n", s);
857     botnet_send_unlinked(i, dcc[i].nick, s);
858     killsock(dcc[i].sock);
859     lostdcc(i);
860     if (nick[0] != '*')
861     return 1;
862     else
863     i--;
864     }
865     }
866     }
867 guppy 1.6 Context;
868 guppy 1.12 if ((idx >= 0) && (nick[0] != '*')) {
869 segfault 1.1 dprintf(idx, "%s\n", BOT_NOTCONNECTED);
870 guppy 1.12
871     /* The internal bot list is desynched from the dcc list
872     * sometimes. While we still search for the bug, provide
873     * an easy way to clear out those `ghost'-bots. -FK
874     */
875     bot = findbot(nick);
876     if (bot) {
877     dprintf(idx, "BUG: Found bot `%s' in internal bot list! Removing.\n",
878     nick);
879     rembot(bot->bot);
880     }
881     }
882 segfault 1.1 if (nick[0] == '*') {
883     dprintf(idx, "%s\n", BOT_WIPEBOTTABLE);
884     while (tandbot)
885     rembot(tandbot->bot);
886     while (parties) {
887     parties--;
888 guppy 1.6 /* Assert? */
889 guppy 1.3 if (party[i].chan >= 0)
890     check_tcl_chpt(party[i].bot, party[i].nick, party[i].sock,
891     party[i].chan);
892 segfault 1.1 }
893     strcpy(s, "killassoc &");
894     Tcl_Eval(interp, s);
895     }
896     return 0;
897     }
898    
899     /* link to another bot */
900     int botlink(char *linker, int idx, char *nick)
901     {
902     struct bot_addr *bi;
903     struct userrec *u;
904 guppy 1.9 register int i;
905 segfault 1.1
906 guppy 1.6 Context;
907 segfault 1.1 u = get_user_by_handle(userlist, nick);
908     if (!u || !(u->flags & USER_BOT)) {
909     if (idx >= 0)
910     dprintf(idx, "%s %s\n", nick, BOT_BOTUNKNOWN);
911     } else if (!strcasecmp(nick, botnetnick)) {
912     if (idx >= 0)
913     dprintf(idx, "%s\n", BOT_CANTLINKMYSELF);
914     } else if (in_chain(nick) && (idx != -3)) {
915     if (idx >= 0)
916     dprintf(idx, "%s\n", BOT_ALREADYLINKED);
917     } else {
918     for (i = 0; i < dcc_total; i++)
919     if ((dcc[i].user == u) &&
920     ((dcc[i].type == &DCC_FORK_BOT) ||
921     (dcc[i].type == &DCC_BOT_NEW))) {
922     if (idx >= 0)
923     dprintf(idx, "%s\n", BOT_ALREADYLINKING);
924     return 0;
925     }
926     /* address to connect to is in 'info' */
927     bi = (struct bot_addr *) get_user(&USERENTRY_BOTADDR, u);
928 guppy 1.2 if (!bi || !strlen(bi->address) || !bi->telnet_port) {
929 segfault 1.1 if (idx >= 0) {
930     dprintf(idx, "%s '%s'.\n", BOT_NOTELNETADDY, nick);
931     dprintf(idx, "%s .chaddr %s %s\n",
932     MISC_USEFORMAT, nick, MISC_CHADDRFORMAT);
933     }
934     } else if (dcc_total == max_dcc) {
935     if (idx >= 0)
936     dprintf(idx, "%s\n", DCC_TOOMANYDCCS1);
937     } else {
938 guppy 1.6 Context;
939 segfault 1.1 correct_handle(nick);
940     i = new_dcc(&DCC_FORK_BOT, sizeof(struct bot_info));
941    
942     dcc[i].port = bi->telnet_port;
943     strcpy(dcc[i].nick, nick);
944     strcpy(dcc[i].host, bi->address);
945     dcc[i].timeval = now;
946     strcpy(dcc[i].u.bot->linker, linker);
947     strcpy(dcc[i].u.bot->version, "(primitive bot)");
948     if (idx > -2)
949     putlog(LOG_BOTS, "*", "%s %s at %s:%d ...", BOT_LINKING, nick,
950     bi->address, bi->telnet_port);
951     dcc[i].u.bot->numver = idx;
952     dcc[i].timeval = now;
953     dcc[i].u.bot->port = dcc[i].port; /* remember where i started */
954     dcc[i].sock = getsock(SOCK_STRONGCONN);
955     dcc[i].user = u;
956 guppy 1.5 if (open_telnet_raw(dcc[i].sock, bi->address, dcc[i].port) < 0)
957     failed_link(i);
958     return 1;
959 segfault 1.1 }
960     }
961     return 0;
962     }
963    
964     static void failed_tandem_relay(int idx)
965     {
966     int uidx = (-1), i;
967    
968 guppy 1.6 Context;
969 segfault 1.1 for (i = 0; i < dcc_total; i++)
970     if ((dcc[i].type == &DCC_PRE_RELAY) &&
971     (dcc[i].u.relay->sock == dcc[idx].sock))
972     uidx = i;
973     if (uidx < 0) {
974     putlog(LOG_MISC, "*", "%s %d -> %d", BOT_CANTFINDRELAYUSER,
975     dcc[idx].sock, dcc[idx].u.relay->sock);
976     killsock(dcc[idx].sock);
977     lostdcc(idx);
978     return;
979     }
980     if (dcc[idx].port >= dcc[idx].u.relay->port + 3) {
981     struct chat_info *ci = dcc[uidx].u.relay->chat;
982    
983     dprintf(uidx, "%s %s.\n", BOT_CANTLINKTO, dcc[idx].nick);
984     nfree(dcc[uidx].u.relay);
985     dcc[uidx].u.chat = ci;
986     dcc[uidx].type = &DCC_CHAT;
987     dcc[uidx].status = dcc[uidx].u.relay->old_status;
988     killsock(dcc[idx].sock);
989     lostdcc(idx);
990     return;
991     }
992     killsock(dcc[idx].sock);
993     dcc[idx].sock = getsock(SOCK_STRONGCONN);
994     dcc[uidx].u.relay->sock = dcc[idx].sock;
995     dcc[idx].port++;
996     dcc[idx].timeval = now;
997     if (open_telnet_raw(dcc[idx].sock, dcc[idx].host, dcc[idx].port) < 0)
998     failed_tandem_relay(idx);
999     }
1000    
1001     /* relay to another tandembot */
1002 guppy 1.9 void tandem_relay(int idx, char *nick, register int i)
1003 segfault 1.1 {
1004     struct chat_info *ci;
1005     struct userrec *u;
1006     struct bot_addr *bi;
1007    
1008 guppy 1.6 Context;
1009 segfault 1.1 u = get_user_by_handle(userlist, nick);
1010     if (!u || !(u->flags & USER_BOT)) {
1011     dprintf(idx, "%s %s\n", nick, BOT_BOTUNKNOWN);
1012     return;
1013     }
1014     if (!strcasecmp(nick, botnetnick)) {
1015     dprintf(idx, "%s\n", BOT_CANTRELAYMYSELF);
1016     return;
1017     }
1018     /* address to connect to is in 'info' */
1019     bi = (struct bot_addr *) get_user(&USERENTRY_BOTADDR, u);
1020     if (!bi) {
1021     dprintf(idx, "%s '%s'.\n", BOT_NOTELNETADDY, nick);
1022     dprintf(idx, "%s .chaddr %s %s\n",
1023     MISC_USEFORMAT, nick, MISC_CHADDRFORMAT);
1024    
1025     return;
1026     }
1027     if (dcc_total == max_dcc) {
1028     dprintf(idx, "%s\n", DCC_TOOMANYDCCS1);
1029     return;
1030     }
1031     i = new_dcc(&DCC_FORK_RELAY, sizeof(struct relay_info));
1032     dcc[i].u.relay->chat = get_data_ptr(sizeof(struct chat_info));
1033    
1034     dcc[i].port = bi->relay_port;
1035     dcc[i].u.relay->port = dcc[i].port;
1036     dcc[i].addr = 0L;
1037     strcpy(dcc[i].nick, nick);
1038     dcc[i].user = u;
1039     strcpy(dcc[i].host, bi->address);
1040     dcc[i].u.relay->chat->away = NULL;
1041     dcc[i].u.relay->old_status = dcc[i].status;
1042     dcc[i].status = 0;
1043     dcc[i].timeval = now;
1044     dcc[i].u.relay->chat->msgs_per_sec = 0;
1045     dcc[i].u.relay->chat->con_flags = 0;
1046     dcc[i].u.relay->chat->buffer = NULL;
1047     dcc[i].u.relay->chat->max_line = 0;
1048     dcc[i].u.relay->chat->line_count = 0;
1049     dcc[i].u.relay->chat->current_lines = 0;
1050     dprintf(idx, "%s %s @ %s:%d ...\n", BOT_CONNECTINGTO, nick,
1051     bi->address, bi->relay_port);
1052     dprintf(idx, "%s\n", BOT_BYEINFO1);
1053     ci = dcc[idx].u.chat;
1054     dcc[idx].u.relay = get_data_ptr(sizeof(struct relay_info));
1055    
1056     dcc[idx].u.relay->chat = ci;
1057     dcc[idx].type = &DCC_PRE_RELAY;
1058     dcc[i].sock = getsock(SOCK_STRONGCONN);
1059     dcc[idx].u.relay->sock = dcc[i].sock;
1060     dcc[i].u.relay->sock = dcc[idx].sock;
1061     dcc[i].timeval = now;
1062     if (open_telnet_raw(dcc[i].sock, dcc[i].host, dcc[i].port) < 0)
1063     failed_tandem_relay(i);
1064     }
1065    
1066     /* input from user before connect is ready */
1067 guppy 1.9 static void pre_relay(int idx, char *buf, register int i)
1068 segfault 1.1 {
1069 guppy 1.9 register int tidx = (-1);
1070 segfault 1.1
1071 guppy 1.6 Context;
1072 segfault 1.1 for (i = 0; i < dcc_total; i++)
1073     if ((dcc[i].type == &DCC_FORK_RELAY) &&
1074     (dcc[i].u.relay->sock == dcc[idx].sock))
1075     tidx = i;
1076     if (tidx < 0) {
1077     putlog(LOG_MISC, "*", "%s %d -> %d", BOT_CANTFINDRELAYUSER,
1078     dcc[i].sock, dcc[i].u.relay->sock);
1079     killsock(dcc[i].sock);
1080     lostdcc(i);
1081     return;
1082     }
1083 guppy 1.6 Context;
1084 segfault 1.1 if (!strcasecmp(buf, "*bye*")) {
1085     /* disconnect */
1086     struct chat_info *ci = dcc[idx].u.relay->chat;
1087    
1088     dprintf(idx, "%s %s.\n", BOT_ABORTRELAY1, dcc[tidx].nick);
1089     dprintf(idx, "%s %s.\n\n", BOT_ABORTRELAY2, botnetnick);
1090     putlog(LOG_MISC, "*", "%s %s -> %s", BOT_ABORTRELAY3, dcc[idx].nick,
1091     dcc[tidx].nick);
1092     nfree(dcc[idx].u.relay);
1093     dcc[idx].u.chat = ci;
1094     dcc[idx].status = dcc[idx].u.relay->old_status;
1095     dcc[idx].type = &DCC_CHAT;
1096     killsock(dcc[tidx].sock);
1097     lostdcc(tidx);
1098     return;
1099     }
1100 guppy 1.6 Context;
1101 segfault 1.1 }
1102    
1103     /* user disconnected before her relay had finished connecting */
1104     static void failed_pre_relay(int idx)
1105     {
1106 guppy 1.9 register int tidx = (-1), i;
1107 segfault 1.1
1108 guppy 1.6 Context;
1109 segfault 1.1 for (i = 0; i < dcc_total; i++)
1110     if ((dcc[i].type == &DCC_FORK_RELAY) &&
1111     (dcc[i].u.relay->sock == dcc[idx].sock))
1112     tidx = i;
1113     if (tidx < 0) {
1114     putlog(LOG_MISC, "*", "%s %d -> %d", BOT_CANTFINDRELAYUSER,
1115     dcc[i].sock, dcc[i].u.relay->sock);
1116     killsock(dcc[i].sock);
1117     lostdcc(i);
1118     return;
1119     }
1120 arthur2 1.4 putlog(LOG_MISC, "*", "%s [%s]%s/%d", BOT_LOSTDCCUSER, dcc[idx].nick,
1121 segfault 1.1 dcc[idx].host, dcc[idx].port);
1122 arthur2 1.4 putlog(LOG_MISC, "*", "(%s %s)", BOT_DROPPINGRELAY, dcc[tidx].nick);
1123 segfault 1.1 if ((dcc[tidx].sock != STDOUT) || backgrd) {
1124     if (idx > tidx) {
1125     int t = tidx;
1126    
1127     tidx = idx;
1128     idx = t;
1129     }
1130     killsock(dcc[tidx].sock);
1131     lostdcc(tidx);
1132     } else {
1133     fatal("Lost my terminal??!?!?!", 0);
1134     }
1135     killsock(dcc[idx].sock);
1136     lostdcc(idx);
1137     }
1138    
1139 guppy 1.9 static void cont_tandem_relay(int idx, char *buf, register int i)
1140 segfault 1.1 {
1141 guppy 1.9 register int uidx = (-1);
1142 segfault 1.1 struct relay_info *ri;
1143    
1144 guppy 1.6 Context;
1145 segfault 1.1 for (i = 0; i < dcc_total; i++)
1146     if ((dcc[i].type == &DCC_PRE_RELAY) &&
1147     (dcc[i].u.relay->sock == dcc[idx].sock))
1148     uidx = i;
1149     if (uidx < 0) {
1150     putlog(LOG_MISC, "*", "%s %d -> %d", BOT_CANTFINDRELAYUSER,
1151     dcc[i].sock, dcc[i].u.relay->sock);
1152     killsock(dcc[i].sock);
1153     lostdcc(i);
1154     return;
1155     }
1156     dcc[idx].type = &DCC_RELAY;
1157     dcc[idx].u.relay->sock = dcc[uidx].sock;
1158     dcc[uidx].u.relay->sock = dcc[idx].sock;
1159     dprintf(uidx, "%s %s ...\n", BOT_RELAYSUCCESS, dcc[idx].nick);
1160     dprintf(uidx, "%s\n\n", BOT_BYEINFO2);
1161     putlog(LOG_MISC, "*", "%s %s -> %s", BOT_RELAYLINK,
1162     dcc[uidx].nick, dcc[idx].nick);
1163     ri = dcc[uidx].u.relay; /* YEAH */
1164     dcc[uidx].type = &DCC_CHAT;
1165     dcc[uidx].u.chat = ri->chat;
1166     if (dcc[uidx].u.chat->channel >= 0) {
1167     chanout_but(-1, dcc[uidx].u.chat->channel, "*** %s %s\n",
1168     dcc[uidx].nick, BOT_PARTYLEFT);
1169     if (dcc[uidx].u.chat->channel < 100000)
1170     botnet_send_part_idx(uidx, NULL);
1171     check_tcl_chpt(botnetnick, dcc[uidx].nick, dcc[uidx].sock,
1172     dcc[uidx].u.chat->channel);
1173     }
1174     check_tcl_chof(dcc[uidx].nick, dcc[uidx].sock);
1175     dcc[uidx].type = &DCC_RELAYING;
1176     dcc[uidx].u.relay = ri;
1177     }
1178    
1179     static void eof_dcc_relay(int idx)
1180     {
1181 guppy 1.9 register int j;
1182 segfault 1.1 struct chat_info *ci;
1183    
1184     for (j = 0; dcc[j].sock != dcc[idx].u.relay->sock; j++);
1185     /* in case echo was off, turn it back on: */
1186     if (dcc[j].status & STAT_TELNET)
1187     dprintf(j, "\377\374\001\r\n");
1188     putlog(LOG_MISC, "*", "%s: %s -> %s", BOT_ENDRELAY1, dcc[j].nick,
1189     dcc[idx].nick);
1190     dprintf(j, "\n\n*** %s %s\n", BOT_ENDRELAY2, botnetnick);
1191     ci = dcc[j].u.relay->chat;
1192     nfree(dcc[j].u.relay);
1193     dcc[j].u.chat = ci;
1194     dcc[j].type = &DCC_CHAT;
1195     if (dcc[j].u.chat->channel >= 0) {
1196     chanout_but(-1, dcc[j].u.chat->channel, "*** %s %s.\n",
1197     dcc[j].nick, BOT_PARTYREJOINED);
1198 guppy 1.6 Context;
1199 segfault 1.1 if (dcc[j].u.chat->channel < 100000)
1200     botnet_send_join_idx(j, -1);
1201     }
1202     dcc[j].status = dcc[j].u.relay->old_status;
1203     check_tcl_chon(dcc[j].nick, dcc[j].sock);
1204     check_tcl_chjn(botnetnick, dcc[j].nick, dcc[j].u.chat->channel,
1205     geticon(j), dcc[j].sock, dcc[j].host);
1206     killsock(dcc[idx].sock);
1207     lostdcc(idx);
1208     }
1209    
1210     static void eof_dcc_relaying(int idx)
1211     {
1212 guppy 1.9 register int j, x = dcc[idx].u.relay->sock;
1213 segfault 1.1
1214     putlog(LOG_MISC, "*", "%s [%s]%s/%d", BOT_LOSTDCCUSER, dcc[idx].nick,
1215     dcc[idx].host, dcc[idx].port);
1216     killsock(dcc[idx].sock);
1217     lostdcc(idx);
1218 guppy 1.9 for (j = 0; (dcc[j].sock != x) || (dcc[j].type == &DCC_FORK_RELAY); j++);
1219 segfault 1.1 putlog(LOG_MISC, "*", "(%s %s)", BOT_DROPPEDRELAY, dcc[j].nick);
1220     killsock(dcc[j].sock);
1221     lostdcc(j); /* drop connection to the bot */
1222     }
1223    
1224     static void dcc_relay(int idx, char *buf, int j)
1225     {
1226     unsigned char *p = (unsigned char *) buf;
1227     int mark;
1228    
1229     for (j = 0; (dcc[j].sock != dcc[idx].u.relay->sock) ||
1230     (dcc[j].type != &DCC_RELAYING); j++);
1231     /* if redirecting to a non-telnet user, swallow telnet codes */
1232     if (!(dcc[j].status & STAT_TELNET)) {
1233     while (*p != 0) {
1234     while ((*p != 255) && (*p != 0))
1235     p++; /* search for IAC */
1236     if (*p == 255) {
1237     mark = 2;
1238     if (!*(p + 1))
1239     mark = 1; /* bogus */
1240     if ((*(p + 1) >= 251) || (*(p + 1) <= 254)) {
1241     mark = 3;
1242     if (!*(p + 2))
1243     mark = 2; /* bogus */
1244     }
1245     strcpy((char *) p, (char *) (p + mark));
1246     }
1247     }
1248     if (!buf[0])
1249     dprintf(-dcc[idx].u.relay->sock, " \n");
1250     else
1251     dprintf(-dcc[idx].u.relay->sock, "%s\n", buf);
1252     return;
1253     }
1254     /* telnet user */
1255     if (!buf[0])
1256     dprintf(-dcc[idx].u.relay->sock, " \r\n");
1257     else
1258     dprintf(-dcc[idx].u.relay->sock, "%s\r\n", buf);
1259     }
1260    
1261     static void dcc_relaying(int idx, char *buf, int j)
1262     {
1263     struct chat_info *ci;
1264    
1265     if (strcasecmp(buf, "*bye*")) {
1266     dprintf(-dcc[idx].u.relay->sock, "%s\n", buf);
1267     return;
1268     }
1269     for (j = 0; (dcc[j].sock != dcc[idx].u.relay->sock) ||
1270     (dcc[j].type != &DCC_RELAY); j++);
1271     /* in case echo was off, turn it back on: */
1272     if (dcc[idx].status & STAT_TELNET)
1273     dprintf(idx, "\377\374\001\r\n");
1274     dprintf(idx, "\n(%s %s.)\n", BOT_BREAKRELAY, dcc[j].nick);
1275     dprintf(idx, "%s %s.\n\n", BOT_ABORTRELAY2, botnetnick);
1276     putlog(LOG_MISC, "*", "%s: %s -> %s", BOT_RELAYBROKEN,
1277     dcc[idx].nick, dcc[j].nick);
1278     if (dcc[idx].u.relay->chat->channel >= 0) {
1279     chanout_but(-1, dcc[idx].u.relay->chat->channel,
1280     "*** %s joined the party line.\n", dcc[idx].nick);
1281 guppy 1.6 Context;
1282 segfault 1.1 if (dcc[idx].u.relay->chat->channel < 100000)
1283     botnet_send_join_idx(idx, -1);
1284     }
1285     ci = dcc[idx].u.relay->chat;
1286     nfree(dcc[idx].u.relay);
1287     dcc[idx].u.chat = ci;
1288     dcc[idx].type = &DCC_CHAT;
1289     dcc[idx].status = dcc[idx].u.relay->old_status;
1290     check_tcl_chon(dcc[idx].nick, dcc[idx].sock);
1291     if (dcc[idx].u.chat->channel >= 0)
1292     check_tcl_chjn(botnetnick, dcc[idx].nick, dcc[idx].u.chat->channel,
1293     geticon(idx), dcc[idx].sock, dcc[idx].host);
1294     killsock(dcc[j].sock);
1295     lostdcc(j);
1296     }
1297    
1298     static void display_relay(int i, char *other)
1299     {
1300     sprintf(other, "rela -> sock %d", dcc[i].u.relay->sock);
1301     }
1302    
1303     static void display_relaying(int i, char *other)
1304     {
1305     sprintf(other, ">rly -> sock %d", dcc[i].u.relay->sock);
1306     }
1307    
1308     static void display_tandem_relay(int i, char *other)
1309     {
1310     strcpy(other, "other rela");
1311     }
1312    
1313     static void display_pre_relay(int i, char *other)
1314     {
1315     strcpy(other, "other >rly");
1316     }
1317    
1318     static int expmem_relay(void *x)
1319     {
1320     register struct relay_info *p = (struct relay_info *) x;
1321     int tot = sizeof(struct relay_info);
1322    
1323     if (p->chat)
1324     tot += DCC_CHAT.expmem(p->chat);
1325     return tot;
1326     }
1327    
1328     static void kill_relay(int idx, void *x)
1329     {
1330     register struct relay_info *p = (struct relay_info *) x;
1331    
1332     if (p->chat)
1333     DCC_CHAT.kill(idx, p->chat);
1334     nfree(p);
1335     }
1336    
1337     struct dcc_table DCC_RELAY =
1338     {
1339     "RELAY",
1340     0, /* flags */
1341     eof_dcc_relay,
1342     dcc_relay,
1343     0,
1344     0,
1345     display_relay,
1346     expmem_relay,
1347     kill_relay,
1348     0
1349     };
1350    
1351     static void out_relay(int idx, char *buf, void *x)
1352     {
1353     register struct relay_info *p = (struct relay_info *) x;
1354    
1355     if (p && p->chat)
1356     DCC_CHAT.output(idx, buf, p->chat);
1357     else
1358     tputs(dcc[idx].sock, buf, strlen(buf));
1359     }
1360    
1361     struct dcc_table DCC_RELAYING =
1362     {
1363     "RELAYING",
1364     0, /* flags */
1365     eof_dcc_relaying,
1366     dcc_relaying,
1367     0,
1368     0,
1369     display_relaying,
1370     expmem_relay,
1371     kill_relay,
1372     out_relay
1373     };
1374    
1375     struct dcc_table DCC_FORK_RELAY =
1376     {
1377     "FORK_RELAY",
1378     0, /* flags */
1379     failed_tandem_relay,
1380     cont_tandem_relay,
1381     &connect_timeout,
1382     failed_tandem_relay,
1383     display_tandem_relay,
1384     expmem_relay,
1385     kill_relay,
1386     0
1387     };
1388    
1389     struct dcc_table DCC_PRE_RELAY =
1390     {
1391     "PRE_RELAY",
1392     0, /* flags */
1393     failed_pre_relay,
1394     pre_relay,
1395     0,
1396     0,
1397     display_pre_relay,
1398     expmem_relay,
1399     kill_relay,
1400     0
1401     };
1402    
1403     /* once a minute, send 'ping' to each bot -- no exceptions */
1404     void check_botnet_pings()
1405     {
1406     int i;
1407    
1408 guppy 1.6 Context;
1409 segfault 1.1 for (i = 0; i < dcc_total; i++)
1410     if (dcc[i].type == &DCC_BOT)
1411     if (dcc[i].status & STAT_PINGED) {
1412     char s[1024];
1413    
1414     putlog(LOG_BOTS, "*", "%s: %s", BOT_PINGTIMEOUT, dcc[i].nick);
1415     simple_sprintf(s, "%s: %s", BOT_PINGTIMEOUT, dcc[i].nick);
1416     chatout("*** %s\n", s);
1417     botnet_send_unlinked(i, dcc[i].nick, s);
1418     killsock(dcc[i].sock);
1419     lostdcc(i);
1420     }
1421 guppy 1.6 Context;
1422 segfault 1.1 for (i = 0; i < dcc_total; i++)
1423     if (dcc[i].type == &DCC_BOT) {
1424     botnet_send_ping(i);
1425     dcc[i].status |= STAT_PINGED;
1426     }
1427 guppy 1.6 Context;
1428 segfault 1.1 for (i = 0; i < dcc_total; i++)
1429     if ((dcc[i].type == &DCC_BOT) && (dcc[i].status & STAT_LEAF)) {
1430     tand_t *bot, *via = findbot(dcc[i].nick);
1431    
1432     for (bot = tandbot; bot; bot = bot->next) {
1433     if ((via == bot->via) && (bot != via)) {
1434     /* not leaflike behavior */
1435     if (dcc[i].status & STAT_WARNED) {
1436     char s[1024];
1437    
1438     putlog(LOG_BOTS, "*", "%s %s (%s).", BOT_DISCONNECTED,
1439     dcc[i].nick, BOT_BOTNOTLEAFLIKE);
1440     dprintf(i, "bye\n");
1441     simple_sprintf(s, "%s %s (%s)", BOT_DISCONNECTED, dcc[i].nick,
1442     BOT_BOTNOTLEAFLIKE);
1443     chatout("*** %s\n", s);
1444     botnet_send_unlinked(i, dcc[i].nick, s);
1445     killsock(dcc[i].sock);
1446     lostdcc(i);
1447     } else {
1448     botnet_send_reject(i, botnetnick, NULL, bot->bot,
1449     NULL, NULL);
1450     dcc[i].status |= STAT_WARNED;
1451     }
1452     } else
1453     dcc[i].status &= ~STAT_WARNED;
1454     }
1455     }
1456 guppy 1.6 Context;
1457 segfault 1.1 }
1458    
1459     void zapfbot(int idx)
1460     {
1461     char s[1024];
1462    
1463     simple_sprintf(s, "%s: %s", BOT_BOTDROPPED, dcc[idx].nick);
1464     chatout("*** %s\n", s);
1465     botnet_send_unlinked(idx, dcc[idx].nick, s);
1466     killsock(dcc[idx].sock);
1467 guppy 1.8 lostdcc(idx);
1468 segfault 1.1 }
1469    
1470     void restart_chons()
1471     {
1472     int i;
1473    
1474     /* dump party line members */
1475 guppy 1.6 Context;
1476 segfault 1.1 for (i = 0; i < dcc_total; i++) {
1477     if (dcc[i].type == &DCC_CHAT) {
1478     check_tcl_chon(dcc[i].nick, dcc[i].sock);
1479     check_tcl_chjn(botnetnick, dcc[i].nick, dcc[i].u.chat->channel,
1480     geticon(i), dcc[i].sock, dcc[i].host);
1481     }
1482     }
1483     for (i = 0; i < parties; i++) {
1484     check_tcl_chjn(party[i].bot, party[i].nick, party[i].chan,
1485     party[i].flag, party[i].sock, party[i].from);
1486     }
1487 guppy 1.6 Context;
1488 segfault 1.1 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23