/* functions for dealing with a tandem bot */ #include #include #include #include "eggdrop.h" #include "tandem.h" /* share user file with tandem bots? */ int share_users=0; /* the ever-confusing passive flag */ int passive=1; /* set to isolate this bot's chat line */ int isolate=0; /* keep track of tandem bots on the botnet */ tand_t tand[MAXTAND]; /* number of bots on the botnet */ int tands=0; extern char origbotname[]; extern int serv; extern int dcc_total; extern struct dcc_t dcc[]; extern char botname[]; extern char curchan[]; extern char cx_file[]; extern int cx_line; /* add a tandem bot to our chain list */ void addbot(who,from) char *who,*from; { context; if (tands==MAXTAND) { log(LOG_TAND,"No more space in tandem-bot database!"); return; } strcpy(tand[tands].bot,who); strcpy(tand[tands].via,from); if (strcasecmp(who,from)==0) strcpy(tand[tands].next,origbotname); else tand[tands].next[0]=0; tands++; } /* remove a tandem bot from the chain list */ void rembot(who,from) char *who,*from; { int i,j; context; for (i=0; i */ void unvia(idx,who) int idx; char *who; { int i; context; for (i=0; i */ int nextbot(who) char *who; { int i,j; for (i=0; i1) tprintf(z," |--"); else tprintf(z," `--"); s[0]=0; i=0; while (!s[0]) { if (strcasecmp(tand[i].next,this)==0) strcpy(s,tand[i].bot); else i++; } tprintf(z,"%s\n",s); if (cnt>1) mark[lev]=1; else mark[lev]=0; strcpy(last[lev],this); strcpy(this,s); lev++; more=1; } else { while (cnt==0) { /* no subtrees from here */ if (lev==0) { tprintf(z,"(( tree error ))\n"); return; } ok=0; for (i=0; i1) tprintf(z," |--%s\n",this); else tprintf(z," `--%s\n",this); if (cnt>1) mark[lev-1]=1; else mark[lev-1]=0; } else { /* this was the last child */ lev--; if (lev==0) { more=0; cnt=999; } else { more=1; strcpy(this,last[lev]); } } } } } /* hop information: (9d) */ tprintf(z,"Average hops: %3.1f, total bots: %d\n", ((float)tothops)/((float)tands),tands+1); } /* dump list of links to a new bot */ void dump_links(z) int z; { int i; for (i=0; istatus&STAT_SHARE) { if (dcc[idx].u.tand->status&STAT_GETTING) { clear_userlist(dcc[idx].u.tand->user); dcc[idx].u.tand->user=NULL; log(LOG_TAND,"(Userlist download aborted.)"); } if (dcc[idx].u.tand->status&STAT_SENDING) { clear_userlist(dcc[idx].u.tand->user); dcc[idx].u.tand->user=NULL; log(LOG_TAND,"(Userlist transmit aborted.)"); } if ((!(dcc[idx].u.tand->status&STAT_GETTING)) && (!(dcc[idx].u.tand->status&STAT_SENDING))) new_tbuf(dcc[idx].nick); } } void reject_bot(who) char *who; { int i; i=nextbot(who); if (i<0) return; if (strcasecmp(dcc[i].nick,who)==0) { /* we're directly connected to the offending bot?! (shudder!) */ log(LOG_TAND,"Rejecting bot %s",dcc[i].nick); chatout("*** Rejected bot %s\n",dcc[i].nick); tandout_but(i,"chat %s Rejected bot %s\n",origbotname,dcc[i].nick); tandout_but(i,"unlinked %s\n",dcc[i].nick); rembot(dcc[i].nick,dcc[i].nick); unvia(i,dcc[i].nick); cancel_user_xfer(i); tprintf(dcc[i].sock,"bye\n"); close(dcc[i].sock); shutdown(dcc[i].sock,2); lostdcc(i); } else { tprintf(dcc[i].sock,"reject %s %s\n",origbotname,who); } } /* break link with a tandembot */ int tandem_unlink(z,nick) int z; char *nick; { int i,j; context; for (i=0; i=0) tprintf(z,"No longer trying to link.\n"); log(LOG_TAND,"Stopped trying to link %s at %s:%d",dcc[i].nick, dcc[i].host,dcc[i].port); close(dcc[i].sock); shutdown(dcc[i].sock,2); lostdcc(i); return 1; } if (dcc[i].type==DCC_TANDEM) { if (z>=0) tprintf(z,"Breaking link with %s.\n",dcc[i].nick); tprintf(dcc[i].sock,"bye\n"); chatout("*** Unlinked from: %s\n",dcc[i].nick); tandout_but(i,"chat %s Unlinked from: %s\n",origbotname,dcc[i].nick); tandout_but(i,"unlinked %s\n",dcc[i].nick); cancel_user_xfer(i); rembot(dcc[i].nick,dcc[i].nick); unvia(i,dcc[i].nick); close(dcc[i].sock); shutdown(dcc[i].sock,2); lostdcc(i); return 1; } } if (z>=0) tprintf(z,"Not connected to that bot.\n"); return 0; } /* link to another tandembot */ int tandem_link(z,nick) int z; char *nick; { char s[121],*p; int port,i; context; if (!(get_attr_handle(nick) & USER_TANDEM)) { if (z>=0) tprintf(z,"%s is not a listed tandem-bot.\n",nick); return 0; } if (strcasecmp(nick,origbotname)==0) { if (z>=0) tprintf(z,"Link to myself? Hoo boy. Freud would have a field day.\n"); return 0; } if (in_chain(nick)) { if (z>=0) tprintf(z,"That bot is already connected up.\n"); return 0; } /* address to connect to is in 'info' */ get_handle_info(nick,s); if (!s[0]) { if (z>=0) tprintf(z,"No telnet port stored for '%s'.\n",nick); if (z>=0) tprintf(z,"Use: .chaddr %s
:\n",nick); return 0; } p=strchr(s,':'); if (p==NULL) port=2222; else { *p=0; p++; port=atoi(p); } if (dcc_total==MAXDCC) { if (z>=0) tprintf("No more dcc entries left: dcc table is full.\n"); return 0; } correct_handle(nick); dcc_total++; i=dcc_total-1; dcc[i].port=port; dcc[i].addr=0L; strcpy(dcc[i].nick,nick); strcpy(dcc[i].host,s); dcc[i].type=DCC_TANDEM; dcc[i].sock=(-1); set_tand(i); dcc[i].u.tand->status=0; dcc[i].u.tand->timer=time(NULL); strcpy(dcc[i].u.tand->version,"(primitive bot)"); dcc[i].u.tand->user=NULL; if (z!=(-1)) log(LOG_TAND,"Linking to %s at %s ...",nick,s); set_fork(i); dcc[i].sock=z; tandout("trying %s %s\n",origbotname,dcc[i].nick); fork_link(s,dcc[i].port,i,dcc[i].port); return 1; } void cont_tandem_link(sk,idx,stport) int sk,idx,stport; { int z=dcc[idx].sock; char s[81]; struct tand_info *ti; context; if (sk>0) { if (dcc[idx].port >= stport+5) { if (z>=0) tprintf(z,"Could not link to %s.\n",dcc[idx].nick); if (z!=(-1)) log(LOG_TAND,"Failed link to %s.",dcc[idx].nick); tandout("*trying %s %s\n",origbotname,dcc[idx].nick); dcc[idx].sock=dcc[idx].type; dcc[idx].type=DCC_LOST; auto_link_tandem(dcc[idx].nick); /* check for more auto-connections */ return; } dcc[idx].port++; fork_link(dcc[idx].host,dcc[idx].port,idx,stport); return; } context; ti=dcc[idx].u.fork->u.tand; nfree(dcc[idx].u.fork); dcc[idx].u.tand=ti; dcc[idx].type=DCC_TANDEM_NEW; get_pass_by_handle(dcc[idx].nick,s); if (strcasecmp(s,"nopass")==0) tprintf(dcc[idx].sock,"%s\n",origbotname); else tprintf(dcc[idx].sock,"%s\n%s\n",origbotname,s); context; return; } /* relay to another tandembot */ void tandem_relay(idx,z,nick) int idx,z; char *nick; { char s[121],*p; int port,i; struct chat_info *ci; context; if (!(get_attr_handle(nick) & USER_TANDEM)) { tprintf(z,"%s is not a listed tandem-bot.\n",nick); return; } if (strcasecmp(nick,origbotname)==0) { tprintf(z,"Relay to myself? What on EARTH would be the point?!\n"); return; } /* address to connect to is in 'info' */ get_handle_info(nick,s); if (!s[0]) { tprintf(z,"No telnet port stored for '%s'.\n",nick); tprintf(z,"Use: .chaddr %s
:\n",nick); return; } p=strchr(s,':'); if (p==NULL) port=2222; else { *p=0; p++; port=atoi(p); } if (dcc_total==MAXDCC) { tprintf(z,"No more dcc table entries available.\n"); return; } dcc_total++; i=dcc_total-1; dcc[i].port=port; dcc[i].addr=0L; strcpy(dcc[i].nick,nick); strcpy(dcc[i].host,s); dcc[i].type=DCC_RELAY; dcc[i].sock=(-1); set_new_relay(i); dcc[i].u.relay->chat->away=NULL; dcc[i].u.relay->chat->status=0; dcc[i].u.relay->chat->timer=time(NULL); dcc[i].u.relay->chat->msgs_per_sec=0; dcc[i].u.relay->chat->con_flags=0; tprintf(z,"Connecting to %s at %s ...\n",nick,s); ci=dcc[idx].u.chat; set_relay(idx); dcc[idx].u.relay->chat=ci; dcc[idx].type=DCC_RELAY; set_fork(idx); set_fork(i); fork_relay(s,dcc[i].port,i,dcc[i].port,idx); } void cont_tandem_relay(sk,idx,stport,uidx) int sk,idx,stport,uidx; { int z=dcc[uidx].sock; char s[81]; struct relay_info *ri; context; if (sk>0) { if (dcc[idx].port >= stport+5) { struct chat_info *ci=dcc[uidx].u.fork->u.relay->chat; tprintf(z,"Could not link to %s.\n",dcc[idx].nick); nfree(dcc[uidx].u.fork->u.relay); nfree(dcc[uidx].u.fork); dcc[uidx].u.chat=ci; dcc[uidx].type=DCC_CHAT; dcc[idx].sock=dcc[idx].type; dcc[idx].type=DCC_LOST; return; } dcc[idx].port++; fork_relay(dcc[idx].host,dcc[idx].port,idx,stport,uidx); return; } tprintf(z,"Success!\n\n"); tprintf(z,"NOW CONNECTED TO RELAY BOT %s ...\n",dcc[idx].nick); tprintf(z,"(You can type *BYE* to prematurely close the connection.)\n\n"); ri=dcc[idx].u.fork->u.relay; nfree(dcc[idx].u.fork); dcc[idx].u.relay=ri; ri=dcc[uidx].u.fork->u.relay; nfree(dcc[uidx].u.fork); dcc[uidx].u.relay=ri; dcc[uidx].type=DCC_RELAYING; dcc[idx].type=DCC_RELAY; dcc[idx].u.relay->sock=dcc[uidx].sock; dcc[uidx].u.relay->sock=dcc[idx].sock; log(LOG_MISC,"Relay link: %s -> %s",dcc[uidx].nick,dcc[idx].nick); if (dcc[uidx].u.relay->chat->channel==0) { chanout(0,"*** %s left the party line.\n",dcc[uidx].nick); if (!isolate) tandout("chan %s 0 %s left the party line.\n",origbotname, dcc[uidx].nick); } else if (dcc[uidx].u.relay->chat->channel>0) { chanout(dcc[uidx].u.relay->chat->channel,"*** %s left the party line.\n", dcc[uidx].nick); if (!isolate) tandout("chan %s %d %s left the party line.\n",origbotname, dcc[uidx].u.chat->channel,dcc[uidx].nick); } } /* once a monute, send 'ping' to each bot -- no exceptions */ void check_for_loops() { int i,j; time_t now=time(NULL); context; for (i=0; istatus&STAT_PINGED) { log(LOG_TAND,"Ping timeout: %s",dcc[i].nick); chatout("*** Ping timeout: %s\n",dcc[i].nick); tandout_but(i,"chat %s Ping timeout: %s\n",origbotname,dcc[i].nick); tandout_but(i,"unlinked %s\n",dcc[i].nick); rembot(dcc[i].nick,dcc[i].nick); unvia(i,dcc[i].nick); cancel_user_xfer(i); close(dcc[i].sock); shutdown(dcc[i].sock,2); lostdcc(i); } for (i=0; istatus|=STAT_PINGED; } for (i=0; istatus&STAT_OFFERED) if (now-dcc[i].u.tand->timer > 120) { tprintf(dcc[i].sock,"userfile?\n"); flush_tbuf(dcc[i].nick); /* ^ send it again in case they missed it */ } for (i=0; istatus&STAT_WARNED) { log(LOG_TAND,"No longer tolerating %s acting like a hub.", dcc[i].nick); tprintf(dcc[i].sock,"bye\n"); chatout("*** Disconnected %s (unleaflike behavior)\n", dcc[i].nick); tandout_but(i,"chat %s Disconnected %s (unleaflike behavior)\n", origbotname,dcc[i].nick); tandout_but(i,"unlinked %s\n",dcc[i].nick); cancel_user_xfer(i); rembot(dcc[i].nick,dcc[i].nick); unvia(i,dcc[i].nick); close(dcc[i].sock); shutdown(dcc[i].sock,2); lostdcc(i); } else { tprintf(dcc[i].sock,"reject %s %s\n",origbotname,tand[j].bot); dcc[i].u.tand->status|=STAT_WARNED; } } else dcc[i].u.tand->status&=~STAT_WARNED; } } } void ask_tandem_for_ops() { char ver[120],chan[120]; int i; context; for (i=0; iversion); nsplit(chan,ver); if (strcasecmp(chan,curchan)==0) tprintf(dcc[i].sock,"op %s\n",botname); } }