/[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.9 - (hide annotations) (download) (as text)
Thu Dec 30 23:23:45 1999 UTC (19 years, 8 months ago) by guppy
Branch: MAIN
Changes since 1.8: +13 -14 lines
File MIME type: text/x-chdr
patches

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23