/* tandcmd.c -- handles: commands that comes across the botnet userfile transfer and update commands from sharebots dprintf'ized, 10nov95 */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include "eggdrop.h" #include "tandem.h" #include "users.h" #include "chan.h" #include "proto.h" extern tand_t tand[]; extern int tands; extern char origbotname[]; extern int dcc_total; extern struct dcc_t dcc[]; extern int isolate; extern int noshare; extern int passive; extern int share_users; extern char motdfile[]; extern struct userrec *userlist; extern char ver[]; extern char os[]; extern struct chanset_t *chanset; extern int serv; /* static buffer for goofy bot stuff */ char TBUF[1024]; void fake_alert(idx) int idx; { tprintf(dcc[idx].sock,"chat %s NOTICE: Fake message rejected.\n", origbotname); } /* chan */ void tand_chan(idx,par) int idx; char *par; { char *from=TBUF,*s=TBUF+512,*p; int i,chan; nsplit(from,par); chan=atoi(par); nsplit(NULL,par); /* strip annoying control chars */ for (p=from; *p; ) { if ((*p<32) || (*p==127)) strcpy(p,p+1); else p++; } p=strchr(from,'@'); if (p==NULL) { sprintf(s,"*** (%s) %s",from,par); p=from; } else { sprintf(s,"<%s> %s",from,par); p++; } i=nextbot(p); if (i!=idx) { fake_alert(idx); return; } tandout_but(idx,"chan %s %d %s\n",from,chan,par); if (!isolate) { chanout(chan,"%s\n",s); if (strchr(from,'@')!=NULL) check_tcl_chat(from,chan,par); } } /* chat -- only from bots */ void tand_chat(idx,par) int idx; char *par; { char *from=TBUF; int i; nsplit(from,par); if (strchr(from,'@')!=NULL) { fake_alert(idx); return; } /* make sure the bot is valid */ i=nextbot(from); if (i!=idx) { fake_alert(idx); return; } if (!isolate) chatout("*** (%s) %s\n",from,par); tandout_but(idx,"chat %s %s\n",from,par); } /* actchan */ void tand_actchan(idx,par) int idx; char *par; { char *from=TBUF,*p; int i,chan; nsplit(from,par); p=strchr(from,'@'); if (p==NULL) { /* how can a bot do an action? */ fake_alert(idx); return; } p++; i=nextbot(p); if (i!=idx) { fake_alert(idx); return; } chan=atoi(par); nsplit(NULL,par); if (!isolate) chanout(chan,"* %s %s\n",from,par); tandout_but(idx,"actchan %s %d %s\n",from,chan,par); } /* priv */ void tand_priv(idx,par) int idx; char *par; { char *from=TBUF,*p,*to=TBUF+600,*tobot=TBUF+512; int i; nsplit(from,par); nsplit(tobot,par); tobot[40]=0; splitc(to,tobot,'@'); p=strchr(from,'@'); if (p!=NULL) p++; else p=from; i=nextbot(p); if ((i!=idx) || (!to[0])) { fake_alert(idx); return; } if (strcasecmp(tobot,origbotname)==0) { /* for me! */ if (p==from) add_note(to,from,par,-2,0); else { i=add_note(to,from,par,-1,0); if (i==0) /* failed */ tprintf(dcc[idx].sock,"priv %s %s No such user %s.\n",origbotname, from,to); else if (i==2) /* stored */ tprintf(dcc[idx].sock,"priv %s %s Not online; note stored.\n", origbotname,from); else /* success! */ tprintf(dcc[idx].sock,"priv %s %s Note sent to %s.\n",origbotname, from,to); } } else { /* pass it on */ i=nextbot(tobot); if (i<0) tandout_but(idx,"priv %s %s@%s %s\n",from,to,tobot,par); else tprintf(dcc[i].sock,"priv %s %s@%s %s\n",from,to,tobot,par); } } void tand_bye(idx,par) int idx; char *par; { putlog(LOG_BOTS,"*","Disconnected from: %s",dcc[idx].nick); chatout("*** Disconnected from: %s\n",dcc[idx].nick); tandout_but(idx,"unlinked %s\n",dcc[idx].nick); tandout_but(idx,"chat %s Disconnected from: %s\n",origbotname,dcc[idx].nick); cancel_user_xfer(idx); rembot(dcc[idx].nick,dcc[idx].nick); unvia(idx,dcc[idx].nick); tprintf(dcc[idx].sock,"*bye\n"); killsock(dcc[idx].sock); lostdcc(idx); } /* who */ void tand_who(idx,par) int idx; char *par; { char *p; char *from=TBUF,*to=TBUF+512; int i; nsplit(from,par); p=strchr(from,'@'); if (p==NULL) { sprintf(to,"%s@%s",from,dcc[idx].nick); strcpy(from,to); } nsplit(to,par); if (strcasecmp(to,origbotname)==0) to[0]=0; /* (for me) */ if (to[0]) { /* pass it on */ i=nextbot(to); if (i<0) tandout_but(idx,"who %s %s %s\n",from,to,par); else tprintf(dcc[i].sock,"who %s %s %s\n",from,to,par); } else { tell_tandem_who(dcc[idx].sock,from,atoi(par)); } } void tand_version(idx,par) int idx; char *par; { strcpy(dcc[idx].u.tand->version,par); if ((share_users) && (get_attr_handle(dcc[idx].nick)&BOT_SHARE)) { if (passive) { if (dcc[idx].u.tand->status&STAT_CALLED) { if (can_resync(dcc[idx].nick)) tprintf(dcc[idx].sock,"resync?\n"); else tprintf(dcc[idx].sock,"userfile?\n"); dcc[idx].u.tand->status|=STAT_OFFERED; } } else { if (can_resync(dcc[idx].nick)) tprintf(dcc[idx].sock,"resync?\n"); else tprintf(dcc[idx].sock,"userfile?\n"); dcc[idx].u.tand->status|=STAT_OFFERED; } } } /* who? -> whom */ void tand_whoq(idx,par) int idx; char *par; { char *to=TBUF; int chan; nsplit(to,par); chan=atoi(par); if (par[0]=='-') chan=(-1); answer_whom(dcc[idx].sock,to,chan); tandout_but(idx,"who? %s %d\n",to,chan); } /* info? -> send priv */ void tand_infoq(idx,par) int idx; char *par; { char s[161]; struct chanset_t *chan; chan=chanset; s[0]=0; while (chan!=NULL) { strcat(s,chan->name); strcat(s,", "); chan=chan->next; } if (s[0]) s[strlen(s)-2]=0; tprintf(dcc[idx].sock,"priv %s %s %s (%s)\n",origbotname,par,ver,s); tandout_but(idx,"info? %s\n",par); } /* whom */ void tand_whom(idx,par) int idx; char *par; { char *to=TBUF,*tobot,*nick=TBUF+40,*bot=TBUF+80,*ss=TBUF+120,plus=' '; int i,sock; nsplit(to,par); tobot=strchr(to,'@'); if (tobot==NULL) { fake_alert(idx); return; } tobot++; to[39]=0; nsplit(nick,par); nick[12]=0; nsplit(bot,par); bot[10]=0; i=nextbot(bot); if (i!=idx) { fake_alert(idx); return; } if (strcasecmp(tobot,origbotname)==0) { sock=(-1); splitc(ss,to,':'); if (ss[0]) sock=atoi(ss); if (nick[0]=='+') { plus='+'; strcpy(nick,&nick[1]); } if (nick[0]=='-') nick[0]=' '; tobot=strchr(to,'@'); *tobot=0; /* splice down to nick now */ for (i=0; istatus&=~STAT_PINGED; } /* link */ void tand_link_cmd(idx,par) int idx; char *par; { char *from=TBUF,*bot=TBUF+512,*rfrom=TBUF+41; int i; nsplit(from,par); nsplit(bot,par); from[40]=0; if (strcasecmp(bot,origbotname)==0) { strcpy(rfrom,from); splitc(NULL,rfrom,':'); putlog(LOG_CMDS,"*","#%s# link %s",rfrom,par); if (tandem_link(from,-2,par)) tprintf(dcc[idx].sock,"priv %s %s Attempting link to %s ...\n", origbotname,from,par); else tprintf(dcc[idx].sock,"priv %s %s Can't link there.\n",origbotname, from); } else { i=nextbot(bot); if (i<0) tandout_but(idx,"link %s %s %s\n",from,bot,par); else tprintf(dcc[i].sock,"link %s %s %s\n",from,bot,par); } } /* unlink */ void tand_unlink_cmd(idx,par) int idx; char *par; { char *from=TBUF,*bot=TBUF+512,*rfrom=TBUF+41; int i; char *p; nsplit(from,par); nsplit(bot,par); from[40]=0; if (strcasecmp(bot,origbotname)==0) { strcpy(rfrom,from); splitc(NULL,rfrom,':'); putlog(LOG_CMDS,"*","#%s# unlink %s",rfrom,par); if (tandem_unlink(-2,par)) { p=strchr(from,'@'); if (p!=NULL) { /* idx will change after unlink -- get new idx */ i=nextbot(p+1); if (i>=0) tprintf(dcc[i].sock,"priv %s %s Unlinked %s.\n",origbotname, from,par); } } else { tandout("unlinked %s\n",par); /* just to clear trash from link lists */ p=strchr(from,'@'); if (p!=NULL) { /* ditto above, about idx */ i=nextbot(p+1); if (i>=0) tprintf(dcc[i].sock,"priv %s %s Can't unlink %s.\n", origbotname,from,par); } } } else { i=nextbot(bot); if (i<0) tandout_but(idx,"unlink %s %s %s\n",from,bot,par); else tprintf(dcc[i].sock,"unlink %s %s %s\n",from,bot,par); } } void tand_ufno(idx,par) int idx; char *par; { putlog(LOG_BOTS,"*","User file rejected by %s: %s",dcc[idx].nick,par); dcc[idx].u.tand->status&=~STAT_OFFERED; if (!(dcc[idx].u.tand->status&STAT_GETTING)) dcc[idx].u.tand->status&=~STAT_SHARE; } void tand_ufyes(idx,par) int idx; char *par; { if (dcc[idx].u.tand->status&STAT_OFFERED) { dcc[idx].u.tand->status&=~STAT_OFFERED; dcc[idx].u.tand->status|=STAT_SHARE; dcc[idx].u.tand->status|=STAT_SENDING; start_sending_users(idx); putlog(LOG_BOTS,"*","Sending user file to %s",dcc[idx].nick); } } void tand_userfileq(idx,par) int idx; char *par; { int ok=1,i; flush_tbuf(dcc[idx].nick); if (!share_users) tprintf(dcc[idx].sock,"uf-no Not sharing userfile.\n"); else if (!passive) tprintf(dcc[idx].sock,"uf-no Aggressive mode active.\n"); else if (!(get_attr_handle(dcc[idx].nick) & BOT_SHARE)) tprintf(dcc[idx].sock,"uf-no You are not +s for me.\n"); else { for (i=0; istatus&STAT_SHARE) && (dcc[i].u.tand->status&STAT_GETTING)) ok=0; if (!ok) tprintf(dcc[idx].sock,"uf-no Already downloading a userfile.\n"); else { tprintf(dcc[idx].sock,"uf-yes\n"); dcc[idx].u.tand->status|=STAT_SHARE; putlog(LOG_BOTS,"*","Downloading user file from %s",dcc[idx].nick); } } } /* ufsend */ void tand_ufsend(idx,par) int idx; char *par; { char *ip=TBUF,*port=TBUF+512; int i; if (!(dcc[idx].u.tand->status & STAT_SHARE)) { tprintf(dcc[idx].sock,"error You didn't ask; you just started sending.\n"); tprintf(dcc[idx].sock,"error Ask before sending the userfile.\n"); return; } if (dcc_total==MAXDCC) { putlog(LOG_MISC,"*","NO MORE DCC CONNECTIONS -- can't grab userfile"); return; } nsplit(ip,par); nsplit(port,par); i=dcc_total; dcc[i].addr=atol(ip); dcc[i].port=atoi(port); dcc[i].sock=(-1); dcc[i].type=DCC_FORK; strcpy(dcc[i].nick,"*users"); strcpy(dcc[i].host,dcc[idx].nick); dcc[i].u.other=NULL; set_fork(i); get_xfer_ptr(&(dcc[i].u.fork->u.xfer)); strcpy(dcc[i].u.fork->u.xfer->filename,".share.users"); dcc[i].u.fork->u.xfer->dir[0]=0; /* this dir */ dcc[i].u.fork->u.xfer->length=atol(par); dcc[i].u.fork->u.xfer->sent=0; dcc[i].u.fork->u.xfer->sofar=0; dcc[i].u.fork->u.xfer->f=fopen(".share.users","w"); if (dcc[i].u.fork->u.xfer->f==NULL) { putlog(LOG_MISC,"*","CAN'T WRITE USERFILE DOWNLOAD FILE!"); nfree(dcc[i].u.fork->u.xfer); nfree(dcc[i].u.fork); return; } dcc[idx].u.tand->status|=STAT_GETTING; dcc[i].u.fork->type=DCC_SEND; dcc_total++; dcc[i].sock=getsock(0); if (open_telnet_dcc(dcc[i].sock,ip,port) < 0) { putlog(LOG_MISC,"*","Asynchronous connection failed!"); lostdcc(i); } } void tand_resyncq(idx,par) int idx; char *par; { if (!share_users) tprintf(dcc[idx].sock,"resync-no Not sharing userfile.\n"); else if (!(get_attr_handle(dcc[idx].nick) & BOT_SHARE)) tprintf(dcc[idx].sock,"resync-no You are not +s for me.\n"); else if (can_resync(dcc[idx].nick)) { tprintf(dcc[idx].sock,"resync!\n"); dump_resync(dcc[idx].sock,dcc[idx].nick); dcc[idx].u.tand->status&=~STAT_OFFERED; dcc[idx].u.tand->status|=STAT_SHARE; putlog(LOG_BOTS,"*","Resync'd user file with %s",dcc[idx].nick); } else if (passive) { tprintf(dcc[idx].sock,"resync!\n"); dcc[idx].u.tand->status&=~STAT_OFFERED; dcc[idx].u.tand->status|=STAT_SHARE; putlog(LOG_BOTS,"*","Resyncing user file from %s",dcc[idx].nick); } else tprintf(dcc[idx].sock,"resync-no No resync buffer.\n"); } void tand_resync(idx,par) int idx; char *par; { if (dcc[idx].u.tand->status&STAT_OFFERED) { if (can_resync(dcc[idx].nick)) { dump_resync(dcc[idx].sock,dcc[idx].nick); dcc[idx].u.tand->status&=~STAT_OFFERED; dcc[idx].u.tand->status|=STAT_SHARE; putlog(LOG_BOTS,"*","Resync'd user file with %s",dcc[idx].nick); } } } void tand_resync_no(idx,par) int idx; char *par; { putlog(LOG_BOTS,"*","Resync refused by %s: %s",dcc[idx].nick,par); flush_tbuf(dcc[idx].nick); tprintf(dcc[idx].sock,"userfile?\n"); } #define CHKSEND if (!(dcc[idx].u.tand->status&STAT_SENDING)) return #define CHKGET if (!(dcc[idx].u.tand->status&STAT_GETTING)) return #define CHKSHARE if (!(dcc[idx].u.tand->status&STAT_SHARE)) return void tand_chpass(idx,par) int idx; char *par; { char *hand=TBUF; CHKSHARE; shareout_but(idx,"chpass %s\n",par); noshare=1; nsplit(hand,par); change_pass_by_handle(hand,par); noshare=0; putlog(LOG_CMDS,"*","%s: newpass %s",dcc[idx].nick,hand); } void tand_chhand(idx,par) int idx; char *par; { char *hand=TBUF; int i; CHKSHARE; shareout_but(idx,"chhand %s\n",par); noshare=1; nsplit(hand,par); change_handle(hand,par); noshare=0; putlog(LOG_CMDS,"*","%s: handle %s->%s",dcc[idx].nick,hand,par); for (i=0; ichannel>=0)) chanout2(dcc[i].u.chat->channel,"Nick change: %s -> %s\n", dcc[i].nick,par); strcpy(dcc[i].nick,par); } } void tand_chattr(idx,par) int idx; char *par; { char *hand=TBUF,*s=TBUF+512; int oatr; CHKSHARE; shareout_but(idx,"chattr %s\n",par); noshare=1; nsplit(hand,par); /* don't let tandem flags be altered */ oatr=(get_attr_handle(hand) & ~BOT_MASK); set_attr_handle(hand,(atoi(par) & BOT_MASK)|oatr); noshare=0; flags2str(get_attr_handle(hand),s); putlog(LOG_CMDS,"*","%s: chattr %s %s",dcc[idx].nick,hand,s); } void tand_newuser(idx,par) int idx; char *par; { char *etc=TBUF,*etc2=TBUF+41,*etc3=TBUF+121; CHKSHARE; shareout_but(idx,"newuser %s\n",par); noshare=1; nsplit(etc,par); etc[40]=0; nsplit(etc2,par); etc2[80]=0; nsplit(etc3,par); userlist=adduser(userlist,etc,etc2,etc3,atoi(par)); noshare=0; putlog(LOG_CMDS,"*","%s: newuser %s",dcc[idx].nick,etc); } void tand_killuser(idx,par) int idx; char *par; { CHKSHARE; shareout_but(idx,"killuser %s\n",par); putlog(LOG_CMDS,"*","%s: killuser %s",dcc[idx].nick,par); noshare=1; deluser(par); noshare=0; } void tand_pls_host(idx,par) int idx; char *par; { char *hand=TBUF; CHKSHARE; shareout_but(idx,"+host %s\n",par); noshare=1; nsplit(hand,par); addhost_by_handle(hand,par); noshare=0; putlog(LOG_CMDS,"*","%s: +host %s %s",dcc[idx].nick,hand,par); } void tand_mns_host(idx,par) int idx; char *par; { char *hand=TBUF; CHKSHARE; shareout_but(idx,"-host %s\n",par); noshare=1; nsplit(hand,par); delhost_by_handle(hand,par); noshare=0; putlog(LOG_CMDS,"*","%s: -host %s %s",dcc[idx].nick,hand,par); } void tand_chemail(idx,par) int idx; char *par; { char *hand=TBUF; CHKSHARE; shareout_but(idx,"chemail %s\n",par); noshare=1; nsplit(hand,par); set_handle_email(userlist,hand,par); noshare=0; putlog(LOG_CMDS,"*","%s: change email %s",dcc[idx].nick,hand); } void tand_chdccdir(idx,par) int idx; char *par; { char *hand=TBUF; CHKSHARE; shareout_but(idx,"chdccdir %s\n",par); noshare=1; nsplit(hand,par); set_handle_dccdir(userlist,hand,par); noshare=0; } void tand_chcomment(idx,par) int idx; char *par; { char *hand=TBUF; CHKSHARE; shareout_but(idx,"chcomment %s\n",par); noshare=1; nsplit(hand,par); set_handle_comment(userlist,hand,par); noshare=0; putlog(LOG_CMDS,"*","%s: change comment %s",dcc[idx].nick,hand); } void tand_chinfo(idx,par) int idx; char *par; { char *hand=TBUF; CHKSHARE; shareout_but(idx,"chinfo %s\n",par); noshare=1; nsplit(hand,par); set_handle_info(userlist,hand,par); noshare=0; putlog(LOG_CMDS,"*","%s: change info %s",dcc[idx].nick,hand); } void tand_clrxtra(idx,par) int idx; char *par; { CHKSHARE; shareout_but(idx,"clrxtra %s\n",par); noshare=1; set_handle_xtra(userlist,par,""); noshare=0; } void tand_addxtra(idx,par) int idx; char *par; { char *hand=TBUF; CHKSHARE; shareout_but(idx,"addxtra %s\n",par); noshare=1; nsplit(hand,par); add_handle_xtra(userlist,hand,par); noshare=0; } void tand_mns_ban(idx,par) int idx; char *par; { CHKSHARE; shareout_but(idx,"-ban %s\n",par); putlog(LOG_CMDS,"*","%s: cancel ban %s",dcc[idx].nick,par); noshare=1; unprog_ban(par); noshare=0; } void tand_mns_banchan(idx,par) int idx; char *par; { char *chname=TBUF; struct chanset_t *chan; CHKSHARE; shareout_but(idx,"-banchan %s\n",par); nsplit(chname,par); putlog(LOG_CMDS,"*","%s: cancel ban %s on %s",dcc[idx].nick,par,chname); chan=findchan(chname); if (chan==NULL) return; noshare=1; u_unprog_ban(chan->bans,par); noshare=0; } void tand_mns_ignore(idx,par) int idx; char *par; { CHKSHARE; shareout_but(idx,"-ignore %s\n",par); putlog(LOG_CMDS,"*","%s: cancel ignore %s",dcc[idx].nick,par); noshare=1; unprog_ignore(par); noshare=0; } void tand_pls_ban(idx,par) int idx; char *par; { time_t now=time(NULL); char *ban=TBUF,*tm=TBUF+512; CHKSHARE; shareout_but(idx,"+ban %s\n",par); noshare=1; nsplit(ban,par); nsplit(tm,par); putlog(LOG_CMDS,"*","%s: ban %s (%s)",dcc[idx].nick,ban,par); if (atol(tm)==0) prog_ban(ban,0,par); else prog_ban(ban,now-atol(tm),par); noshare=0; } void tand_pls_banchan(idx,par) int idx; char *par; { time_t now=time(NULL); char *ban=TBUF,*tm=TBUF+512,*chname=TBUF+600; struct chanset_t *chan; CHKSHARE; shareout_but(idx,"+banchan %s\n",par); nsplit(ban,par); nsplit(tm,par); nsplit(chname,par); putlog(LOG_CMDS,"*","%s: ban %s on %s (%s)",dcc[idx].nick,ban,chname,par); chan=findchan(chname); if (chan==NULL) return; noshare=1; if (atol(tm)==0) u_prog_ban(chan->bans,ban,0,par); else u_prog_ban(chan->bans,ban,now-atol(tm),par); noshare=0; } void tand_pls_ignore(idx,par) int idx; char *par; { time_t now=time(NULL); char *ign=TBUF; CHKSHARE; shareout_but(idx,"+ignore %s\n",par); noshare=1; nsplit(ign,par); putlog(LOG_CMDS,"*","%s: ignore %s",dcc[idx].nick,ign); if (atol(par)==0) prog_ignore(ign,0,dcc[idx].nick); else prog_ignore(ign,now-atoi(par),dcc[idx].nick); noshare=0; } void tand_nlinked(idx,par) int idx; char *par; { char *newbot=TBUF,*next=TBUF+512,*p; int reject=0,bogus=0,atr,i; nsplit(newbot,par); nsplit(next,par); if (strlen(newbot)>9) newbot[9]=0; if (strlen(next)>9) next[9]=0; if (!next[0]) { putlog(LOG_BOTS,"*","Invalid eggnet protocol from %s (zapfing)", dcc[idx].nick); chatout("*** Disconnected %s (invalid bot)\n",dcc[idx].nick); tandout_but(idx,"chat %s Disconnected %s (invalid bot)\n",origbotname, dcc[idx].nick); tprintf(dcc[idx].sock,"error invalid eggnet protocol for 'nlinked'\n"); reject=1; } else if ((in_chain(newbot)) || (strcasecmp(newbot,origbotname)==0)) { /* loop! */ putlog(LOG_BOTS,"*","Detected loop: disconnecting %s (mutual: %s)", dcc[idx].nick,newbot); chatout("*** Loop (%s): disconnected %s\n",newbot,dcc[idx].nick); tandout_but(idx,"chat %s Loop (%s): disconnected %s\n",origbotname,newbot, dcc[idx].nick); tprintf(dcc[idx].sock,"error Loop (%s)\n",newbot); reject=1; } if (!reject) { for (p=newbot; *p; p++) if ((*p<32) || (*p==127)) bogus=1; i=nextbot(next); if (i!=idx) bogus=1; } if (bogus) { putlog(LOG_BOTS,"*","Bogus link notice from %s! (%s -> %s)",dcc[idx].nick, next,newbot); chatout("*** Bogus link notice: disconnecting %s\n",dcc[idx].nick); tandout_but(idx,"chat %s Bogus link notice: disconnecting %s\n", origbotname,dcc[idx].nick); tprintf(dcc[idx].sock,"error Bogus link notice (%s -> %s)\n",next,newbot); reject=1; } atr=get_attr_handle(dcc[idx].nick); if (atr & BOT_LEAF) { putlog(LOG_BOTS,"*","Disconnecting leaf %s (linked to %s)",dcc[idx].nick, newbot); chatout("*** Illegal link by leaf %s (to %s): disconnecting\n", dcc[idx].nick,newbot); tandout_but(idx,"chat %s Illegal link by leaf %s (to %s): disconnecting\n", origbotname,dcc[idx].nick,newbot); tprintf(dcc[idx].sock,"error You are supposed to be a leaf!\n"); reject=1; } if (reject) { tandout_but(idx,"unlinked %s\n",dcc[idx].nick); cancel_user_xfer(idx); rembot(dcc[idx].nick,dcc[idx].nick); unvia(idx,dcc[idx].nick); tprintf(dcc[idx].sock,"bye\n"); killsock(dcc[idx].sock); lostdcc(idx); return; } addbot(newbot,dcc[idx].nick); got_tand_next(newbot,next); tandout_but(idx,"nlinked %s %s %s\n",newbot,next,par); check_tcl_link(newbot,par); if (get_attr_handle(newbot) & BOT_REJECT) { tprintf(dcc[idx].sock,"reject %s %s\n",origbotname,newbot); putlog(LOG_BOTS,"*","Rejecting bot %s from %s",newbot,dcc[idx].nick); } } void tand_linked(idx,par) int idx; char *par; { putlog(LOG_BOTS,"*","Older bot detected (unsupported)"); chatout("*** Disconnected %s (outdated)\n",dcc[idx].nick); tandout_but(idx,"chat %s Disconnected %s (outdated)\n",origbotname, dcc[idx].nick); tandout_but(idx,"unlinked %s\n",dcc[idx].nick); cancel_user_xfer(idx); rembot(dcc[idx].nick,dcc[idx].nick); unvia(idx,dcc[idx].nick); killsock(dcc[idx].sock); lostdcc(idx); } void tand_unlinked(idx,par) int idx; char *par; { rembot(par,dcc[idx].nick); unvia(idx,par); tandout_but(idx,"unlinked %s\n",par); } void tand_trace(idx,par) int idx; char *par; { char *from=TBUF,*dest=TBUF+512; int i; /* trace */ nsplit(from,par); nsplit(dest,par); if (strcasecmp(dest,origbotname)==0) { tprintf(dcc[idx].sock,"traced %s %s:%s\n",from,par,origbotname); } else { i=nextbot(dest); if (i<0) tandout_but(idx,"trace %s %s %s:%s\n",from,dest,par,origbotname); else tprintf(dcc[i].sock,"trace %s %s %s:%s\n",from,dest,par,origbotname); } } void tand_traced(idx,par) int idx; char *par; { char *to=TBUF,*ss=TBUF+512,*p; int i,sock; /* traced */ nsplit(to,par); p=strchr(to,'@'); if (p==NULL) p=to; else { *p=0; p++; } if (strcasecmp(p,origbotname)==0) { splitc(ss,to,':'); if (ss[0]) sock=atoi(ss); else sock=(-1); for (i=0; i %s\n",par); } else { i=nextbot(p); if (i<0) tandout_but(idx,"traced %s@%s %s\n",to,p,par); else tprintf(dcc[i].sock,"traced %s@%s %s\n",to,p,par); } } /* reject */ void tand_reject(idx,par) int idx; char *par; { char *from=TBUF,*who=TBUF+81,*destbot=TBUF+41; int i; nsplit(from,par); from[40]=0; i=nextbot(from); if (i!=idx) { fake_alert(idx); return; } if (strchr(par,'@')==NULL) { i=nextbot(par); if (i<0) { tprintf(dcc[idx].sock,"priv %s %s Can't reject %s (doesn't exist)\n", origbotname,from,par); } else if (strcasecmp(dcc[i].nick,par)==0) { /* i'm the connection to the rejected bot */ putlog(LOG_BOTS,"*","%s rejected %s",from,dcc[i].nick); tprintf(dcc[i].sock,"bye\n"); tandout_but(i,"unlinked %s\n",dcc[i].nick); tandout_but(i,"chat %s Disconnected %s (rejected by %s)\n",origbotname, dcc[i].nick,from); chatout("*** Disconnected %s (rejected by %s)\n",dcc[i].nick,from); cancel_user_xfer(i); rembot(dcc[i].nick,dcc[i].nick); unvia(i,dcc[i].nick); killsock(dcc[i].sock); lostdcc(i); } else { if (i<0) tandout_but(idx,"reject %s %s\n",from,par); else tprintf(dcc[i].sock,"reject %s %s\n",from,par); } } else { /* rejecting user */ nsplit(destbot,par); destbot[40]=0; splitc(who,destbot,'@'); if (strcasecmp(destbot,origbotname)==0) { /* kick someone here! */ int ok=0; #ifdef SHAREBOT_BOOTS if (!(dcc[idx].u.tand->status&STAT_SHARE)) { add_note(from,origbotname,"Remote boots are not allowed.",-1,0); return; } #endif #ifdef REMOTE_BOOTS for (i=0; (istatus|=STAT_LEAF; /* set capitalization the way they want it */ noshare=1; change_handle(dcc[idx].nick,par); noshare=0; strcpy(dcc[idx].nick,par); } void tand_handshake(idx,par) int idx; char *par; { change_pass_by_handle(dcc[idx].nick,par); if ((dcc[idx].u.tand->status&STAT_SHARE) && (!(dcc[idx].u.tand->status&STAT_GETTING)) && (!(dcc[idx].u.tand->status&STAT_SENDING))) { noshare=1; change_pass_by_handle(origbotname,par); noshare=0; } } void tand_trying(idx,par) int idx; char *par; { tandout_but(idx,"trying %s\n",par); /* currently ignore */ } void tand_end_trying(idx,par) int idx; char *par; { tandout_but(idx,"*trying %s\n",par); /* currently ignore */ } /* used to send a direct msg from Tcl on one bot to Tcl on another */ /* zapf */ void tand_zapf(idx,par) int idx; char *par; { char *from=TBUF,*to=TBUF+512; int i; nsplit(from,par); nsplit(to,par); i=nextbot(from); if (i!=idx) { fake_alert(idx); return; } if (strcasecmp(to,origbotname)==0) { /* for me! */ char opcode[512]; nsplit(opcode,par); check_tcl_tand(from,opcode,par); return; } i=nextbot(to); if (i<0) tandout_but(idx,"zapf %s %s %s\n",from,to,par); else tprintf(dcc[i].sock,"zapf %s %s %s\n",from,to,par); } /* used to send a global msg from Tcl on one bot to every other bot */ /* zapf-broad */ void tand_zapfbroad(idx,par) int idx; char *par; { char *from=TBUF,*opcode=TBUF+512; int i; nsplit(from,par); nsplit(opcode,par); i=nextbot(from); if (i!=idx) { fake_alert(idx); return; } check_tcl_tand(from,opcode,par); tandout_but(idx,"zapf-broad %s %s %s\n",from,opcode,par); } /* show motd to someone */ void tand_motd(idx,par) int idx; char *par; { FILE *vv; char *s=TBUF,*who=TBUF+512,*p; int i; nsplit(who,par); if ((!par[0]) || (strcasecmp(par,origbotname)==0)) { p=strchr(who,':'); if (p==NULL) p=who; else p++; putlog(LOG_CMDS,"*","#%s# motd",p); vv=fopen(motdfile,"r"); if (vv!=NULL) { tprintf(dcc[idx].sock,"priv %s %s --- MOTD file:\n",origbotname,who); while (!feof(vv)) { fgets(s,120,vv); if (!feof(vv)) { if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (!s[0]) strcpy(s," "); help_subst(s,who,0,0); if (s[0]) tprintf(dcc[idx].sock,"priv %s %s %s\n",origbotname,who,s); } } fclose(vv); } else tprintf(dcc[idx].sock,"priv %s %s No MOTD file. :(\n",origbotname, who); } else { /* pass it on */ i=nextbot(par); if (i<0) tandout_but(idx,"motd %s %s\n",who,par); else tprintf(dcc[i].sock,"motd %s %s\n",who,par); } } /* assoc */ /* new killing algorithm that should probably be explained: */ /* when assocs were getting killed, usually bots would link in that */ /* still remembered the old assoc, and would re-propagate it across */ /* the botnet. now when an assoc is killed, its entry is just blanked */ /* and otherwise left intact. if another name is propagated for the */ /* channel while the entry is blanked, the entry is killed, and a */ /* kill-assoc message is sent back out to everyone (which will kill */ /* [blank] the assoc on the offending propagating bot, and will wipe */ /* the entries from everyone else. when a new assoc is made by a user, */ /* a kill-assoc message is propagated first, to wipe the entries. */ void tand_assoc(idx,par) int idx; char *par; { char *s=TBUF,*s1; nsplit(s,par); if ((atoi(s)<=0) || (atoi(s)>99999)) return; if (par[0]=='0') { s1=get_assoc_name(atoi(s)); if (s1!=NULL) { if (s1[0]==0) kill_assoc(atoi(s)); else add_assoc("",atoi(s)); } tandout_but(idx,"assoc %s 0\n",s); } else if (get_assoc(par)!=atoi(s)) { /* new one i didn't know about -- pass it on */ s1=get_assoc_name(atoi(s)); if (s1!=NULL) { if (s1[0]==0) { /* recently killed assoc */ tandout("assoc %s 0\n",s); kill_assoc(atoi(s)); return; } } add_assoc(par,atoi(s)); tandout_but(idx,"assoc %s %s\n",s,par); } } /* filereject */ void tand_filereject(idx,par) int idx; char *par; { char *path=TBUF,*tobot=TBUF+512,*to=TBUF+542,*p; int i; nsplit(path,par); nsplit(tobot,par); splitc(to,tobot,'@'); if (strcasecmp(tobot,origbotname)==0) { /* for me! */ p=strchr(to,':'); if (p!=NULL) { *p=0; for (i=0; i */ void tand_filereq(idx,par) int idx; char *par; { char *from=TBUF,*tobot=TBUF+41; int i; nsplit(from,par); splitc(tobot,par,':'); if (strcasecmp(tobot,origbotname)==0) { /* for me! */ /* process this */ remote_filereq(idx,from,par); } else { /* pass it on */ i=nextbot(tobot); if (i<0) tandout_but(idx,"filereq %s %s:%s\n",from,tobot,par); else tprintf(dcc[i].sock,"filereq %s %s:%s\n",from,tobot,par); } } /* filesend */ void tand_filesend(idx,par) int idx; char *par; { char *botpath=TBUF,*nick=TBUF+512,*tobot=TBUF+552,*sock=TBUF+692; int i; char *nfn; nsplit(botpath,par); nsplit(tobot,par); splitc(nick,tobot,'@'); splitc(sock,nick,':'); if (strcasecmp(tobot,origbotname)==0) { /* for me! */ nfn=strrchr(botpath,'/'); if (nfn==NULL) { nfn=strrchr(botpath,':'); if (nfn==NULL) nfn=botpath; /* that's odd. */ else nfn++; } else nfn++; /* send it to 'nick' as if it's from me */ mprintf(serv,"PRIVMSG %s :\001DCC SEND %s %s\001\n",nick,nfn,par); } else { i=nextbot(tobot); if (i<0) tandout_but(idx,"filesend %s %s:%s@%s %s\n",botpath,sock,nick,tobot,par); else tprintf(dcc[i].sock,"filesend %s %s:%s@%s %s\n",botpath,sock,nick, tobot,par); } } void tand_error(idx,par) int idx; char *par; { putlog(LOG_MISC|LOG_BOTS,"*","%s: %s",dcc[idx].nick,par); }