/* dcc.c -- handles: activity on a dcc socket disconnect on a dcc socket ...and that's it! (but it's a LOT) dprintf'ized, 27oct95 */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include /* hpux needs for ntohl */ #include "eggdrop.h" #include "chan.h" #include "proto.h" /* dcc list */ struct dcc_t dcc[MAXDCC]; /* total dcc's */ int dcc_total=0; /* root dcc directory */ char dccdir[121]=""; /* directory to put incoming dcc's into */ char dccin[121]=""; /* temporary directory (default: current dir) */ char tempdir[121]=""; /* if non-zero, accept telnets at this port */ int telnet_port=0; /* require 'p' access to get on the party line? */ int require_p=0; /* let all uploads go to the user's current directory? */ int upload_to_cd=0; /* allow people to introduce themselves via telnet */ int allow_new_telnets=0; /* how many bytes should we send at once? */ int dcc_block=512; extern int serv; extern int cx_line; extern char cx_file[]; extern char ver[]; extern char version[]; extern char botname[]; extern char realbotname[]; extern char origbotname[]; extern char notify_new[]; extern int conmask; extern int isolate; extern int require_x; extern int default_flags; extern int online; extern struct userrec *userlist; extern struct chanset_t *chanset; /* main loop calls here when activity is found on a dcc socket */ void dcc_activity(z,buf,len) int z,len; char *buf; { int idx; char s[121],s1[81],*bf; unsigned long netint,l,cmp; context; for (idx=0; ((dcc[idx].sock!=z) || (dcc[idx].type==DCC_FORK)) && (idx=dcc_total) return; if ((dcc[idx].type!=DCC_SEND) && (dcc[idx].type!=DCC_GET) && (dcc[idx].type!=DCC_GET_PENDING) && (dcc[idx].type!=DCC_TELNET) && (dcc[idx].type!=DCC_RELAY) && (dcc[idx].type!=DCC_RELAYING)) { /* interpret embedded telnet codes */ strip_telnet(z,buf,&len); } context; if (dcc[idx].type==DCC_CHAT_PASS) { if (pass_match_by_handle(buf,dcc[idx].nick)) { if (get_attr_handle(dcc[idx].nick) & USER_BOT) { nfree(dcc[idx].u.chat); dcc[idx].type=DCC_TANDEM; set_tand(idx); dcc[idx].u.tand->status=STAT_CALLED; dcc[idx].u.tand->timer=time(NULL); dcc[idx].u.tand->version[0]=0; if (get_attr_handle(dcc[idx].nick) & BOT_LEAF) dcc[idx].u.tand->status|=STAT_LEAF; tprintf(z,"*hello!\n"); tprintf(z,"version %s\n",ver); tprintf(z,"thisbot %s\n",origbotname); stop_auto(dcc[idx].nick); putlog(LOG_TAND,"*","Linked to %s",dcc[idx].nick); chatout("*** Linked to %s\n",dcc[idx].nick); tandout_but(idx,"nlinked %s %s\n",dcc[idx].nick,origbotname); tandout_but(idx,"chat %s Linked to %s\n",origbotname,dcc[idx].nick); dump_links(z); addbot(dcc[idx].nick,dcc[idx].nick); check_tcl_link(dcc[idx].nick,origbotname); } else { dcc[idx].type=DCC_CHAT; dcc[idx].u.chat->status&=~STAT_CHAT; if (dcc[idx].u.chat->status&STAT_MASTER) dcc[idx].u.chat->con_flags=conmask; if (dcc[idx].u.chat->status&STAT_TELNET) tprintf(dcc[idx].sock,"\377\374\001\n"); /* turn echo back on */ dcc_chatter(idx); } } else { if (get_attr_handle(dcc[idx].nick) & USER_BOT) tprintf(z,"badpass\n"); else dprintf(idx,"Authentification failed.\n"); putlog(LOG_MISC,"*","Bad password: DCC chat [%s]%s",dcc[idx].nick, dcc[idx].host); close(z); lostdcc(idx); } } else if (dcc[idx].type==DCC_FILES_PASS) { if (pass_match_by_handle(buf,dcc[idx].nick)) { if (too_many_filers()) { dprintf(idx,"Too many people are in the file system right now.\n"); dprintf(idx,"Please try again later.\n"); putlog(LOG_MISC,"*","File area full: DCC chat [%s]%s",dcc[idx].nick, dcc[idx].host); close(z); lostdcc(idx); } else { dcc[idx].type=DCC_FILES; if (dcc[idx].u.file->chat->status&STAT_TELNET) tprintf(dcc[idx].sock,"\377\374\001\n"); /* turn echo back on */ putlog(LOG_FILES,"*","File system: [%s]%s/%d",dcc[idx].nick, dcc[idx].host,dcc[idx].port); if (!welcome_to_files(idx,z)) { putlog(LOG_FILES,"*","File system broken."); close(z); lostdcc(idx); } } } else { dprintf(idx,"Authentification failed.\n"); putlog(LOG_MISC,"*","Bad password: DCC chat [%s]%s",dcc[idx].nick, dcc[idx].host); close(z); lostdcc(idx); } } else if (dcc[idx].type==DCC_TANDEM_NEW) { if (strcasecmp(buf,"*hello!")==0) { dcc[idx].type=DCC_TANDEM; stop_auto(dcc[idx].nick); putlog(LOG_TAND,"*","Linked to %s",dcc[idx].nick); chatout("*** Linked to %s\n",dcc[idx].nick); tprintf(dcc[idx].sock,"version %s\n",ver); tprintf(dcc[idx].sock,"thisbot %s\n",origbotname); tandout_but(idx,"nlinked %s %s\n",dcc[idx].nick,origbotname); tandout_but(idx,"chat %s Linked to %s\n",origbotname,dcc[idx].nick); dump_links(dcc[idx].sock); addbot(dcc[idx].nick,dcc[idx].nick); check_tcl_link(dcc[idx].nick,origbotname); } if (strcasecmp(buf,"badpass")==0) { /* we entered the wrong password */ putlog(LOG_TAND,"*","Bad password on connect attempt to %s.", dcc[idx].nick); } if (strcasecmp(buf,"passreq")==0) { if (pass_match_by_handle("nopass",dcc[idx].nick)) { putlog(LOG_TAND,"*","Password required for connection to %s.", dcc[idx].nick); tprintf(z,"nopass\n"); } } if (strncmp(buf,"error",5)==0) { split(NULL,buf); putlog(LOG_TAND,"*","ERROR linking %s: %s",dcc[idx].nick,buf); } /* ignore otherwise */ } else if (dcc[idx].type==DCC_TANDEM) { got_tandem(idx,buf); } else if (dcc[idx].type==DCC_CHAT) { int i; if ((!detect_dcc_flood(dcc[idx].u.chat,idx)) && (!check_tcl_filt(idx,buf))) { int nathan=0; char *v=buf; /* check for beeps and cancel annoying ones */ while (*v != 0) switch(*v) { case 7: /* beep - no more than 3 */ nathan++; if (nathan>3) strcpy(v,v+1); else v++; break; case 27: /* ESC - ansi code? */ case '\r': /* weird pseudo-linefeed */ strcpy(v,v+1); break; default: v++; } if ((buf[0]=='.') || (dcc[idx].u.chat->channel<0)) { if (buf[0]=='.') strcpy(buf,&buf[1]); if (got_dcc_cmd(idx,buf)) { check_tcl_chof(dcc[idx].nick,dcc[idx].sock); dprintf(idx,"*** Ja mata!\n"); putlog(LOG_MISC,"*","DCC connection closed (%s!%s)",dcc[idx].nick, dcc[idx].host); if (dcc[idx].u.chat->channel>=0) chanout2(dcc[idx].u.chat->channel,"%s left the party line.\n", dcc[idx].nick); if (dcc[idx].sock!=STDOUT) { close(dcc[idx].sock); lostdcc(idx); } else { tprintf(STDOUT,"\n### SIMULATION RESET\n\n"); dcc_chatter(idx); } } } else if (buf[0]==',') { for (i=0; istatus&STAT_MASTER) && (dcc[i].u.chat->channel>=0) && ((i!=idx) || (dcc[idx].u.chat->status&STAT_ECHO))) dprintf(i,"-%s- %s\n",dcc[idx].nick,&buf[1]); if ((dcc[i].type==DCC_FILES) && (dcc[i].u.file->chat->status&STAT_MASTER) && ((i!=idx) || (dcc[idx].u.chat->status&STAT_ECHO))) dprintf(i,"-%s- %s\n",dcc[idx].nick,&buf[1]); } } else { if (dcc[idx].u.chat->away!=NULL) not_away(idx); if (dcc[idx].u.chat->status&STAT_ECHO) chanout(dcc[idx].u.chat->channel,"<%s> %s\n",dcc[idx].nick,buf); else chanout_but(idx,dcc[idx].u.chat->channel,"<%s> %s\n",dcc[idx].nick, buf); if (!isolate) tandout("chan %s@%s %d %s\n",dcc[idx].nick,origbotname, dcc[idx].u.chat->channel,buf); check_tcl_chat(dcc[idx].nick,dcc[idx].u.chat->channel,buf); } } } else if (dcc[idx].type==DCC_FILES) { int i; if (!detect_dcc_flood(dcc[idx].u.file->chat,idx)) { if (buf[0]==',') { for (i=0; istatus&STAT_MASTER) && (dcc[i].u.chat->channel>=0) && ((i!=idx) || (dcc[idx].u.chat->status&STAT_ECHO))) dprintf(i,"-%s- %s\n",dcc[idx].nick,&buf[1]); if ((dcc[i].type==DCC_FILES) && (dcc[i].u.file->chat->status&STAT_MASTER) && ((i!=idx) || (dcc[idx].u.chat->status&STAT_ECHO))) dprintf(i,"-%s- %s\n",dcc[idx].nick,&buf[1]); } } else if (got_files_cmd(idx,buf)) { dprintf(idx,"*** Ja mata!\n"); putlog(LOG_FILES,"*","DCC user [%s]%s left file system",dcc[idx].nick, dcc[idx].host); set_handle_dccdir(userlist,dcc[idx].nick,dcc[idx].u.file->dir); if (dcc[idx].u.file->chat->status&STAT_CHAT) { struct chat_info *ci; dprintf(idx,"Returning you to command mode...\n"); ci=dcc[idx].u.file->chat; nfree(dcc[idx].u.file); dcc[idx].u.chat=ci; if (dcc[idx].u.chat->channel>=0) chanout2(dcc[idx].u.chat->channel,"%s joined the party line\n", dcc[idx].nick); dcc[idx].u.chat->status&=(~STAT_CHAT); dcc[idx].type=DCC_CHAT; } else { dprintf(idx,"Dropping connection now.\n"); putlog(LOG_FILES,"*","Left files: [%s]%s/%d",dcc[idx].nick, dcc[idx].host,dcc[idx].port); close(dcc[idx].sock); lostdcc(idx); } } } } else if (dcc[idx].type==DCC_SEND) { fwrite(buf,len,1,dcc[idx].u.xfer->f); dcc[idx].u.xfer->sent+=len; netint=htonl(dcc[idx].u.xfer->sent); write(dcc[idx].sock,&netint,4); dcc[idx].u.xfer->pending=time(NULL); if ((dcc[idx].u.xfer->sent > dcc[idx].u.xfer->length) && (dcc[idx].u.xfer->length > 0)) { mprintf(serv,"NOTICE %s :Bogus file length.\n",dcc[idx].nick); putlog(LOG_FILES,"*","File too long: dropping dcc send %s from %s!%s", dcc[idx].u.xfer->filename,dcc[idx].nick,dcc[idx].host); fclose(dcc[idx].u.xfer->f); sprintf(s,"%s%s",tempdir,dcc[idx].u.xfer->filename); unlink(s); close(dcc[idx].sock); lostdcc(idx); } } else if (dcc[idx].type==DCC_GET_PENDING) { unsigned long ip; int i; i=answer(dcc[idx].sock,s,&ip); close(dcc[idx].sock); dcc[idx].sock=i; dcc[idx].addr=ip; if (dcc[idx].sock==-1) { neterror(s); mprintf(serv,"NOTICE %s :Bad connection (%s)\n",dcc[idx].nick, s); putlog(LOG_FILES,"*","DCC bad connection: GET %s (%s!%s)", dcc[idx].u.xfer->filename,dcc[idx].nick,dcc[idx].host); lostdcc(idx); } else { /* file was already opened */ if (dcc[idx].u.xfer->length < dcc_block) dcc[idx].u.xfer->sent=dcc[idx].u.xfer->length; else dcc[idx].u.xfer->sent = dcc_block; dcc[idx].type=DCC_GET; bf=(char *)nmalloc(dcc[idx].u.xfer->sent+1); fread(bf,dcc[idx].u.xfer->sent,1,dcc[idx].u.xfer->f); write(dcc[idx].sock,bf,dcc[idx].u.xfer->sent); nfree(bf); dcc[idx].u.xfer->pending=time(NULL); /* leave f open until file transfer is complete */ } } else if (dcc[idx].type==DCC_GET) { unsigned char bbuf[41]; /* prepend any previous partial-acks: */ my_memcpy(bbuf,buf,len); if (dcc[idx].u.xfer->sofar) { my_memcpy(&dcc[idx].u.xfer->buf[dcc[idx].u.xfer->sofar],bbuf,len); my_memcpy(bbuf,dcc[idx].u.xfer->buf,dcc[idx].u.xfer->sofar+len); len+=dcc[idx].u.xfer->sofar; dcc[idx].u.xfer->sofar=0; } /* toss previous pent-up acks */ while (len>4) { len-=4; my_memcpy(bbuf,&bbuf[4],len); } if (len<4) { /* not a full answer */ dcc[idx].u.xfer->sofar=len; my_memcpy(dcc[idx].u.xfer->buf,bbuf,len); } else { /* this is more compatable than ntohl for machines where an int */ /* is more than 4 bytes: */ cmp=((unsigned int)(bbuf[0])<<24)+((unsigned int)(bbuf[1])<<16)+ ((unsigned int)(bbuf[2])<<8)+bbuf[3]; if ((cmp>dcc[idx].u.xfer->sent) && (cmp<=dcc[idx].u.xfer->length)) { /* attempt to resume I guess */ fseek(dcc[idx].u.xfer->f,cmp,SEEK_SET); dcc[idx].u.xfer->sent=cmp; putlog(LOG_FILES,"*","Resuming file transfer at %dk for %s to %s", (int)(cmp/1024),dcc[idx].u.xfer->filename,dcc[idx].nick); } if (cmp==dcc[idx].u.xfer->sent) { if (dcc[idx].u.xfer->sent==dcc[idx].u.xfer->length) { /* successful send, we're done */ char xnick[10]; close(dcc[idx].sock); fclose(dcc[idx].u.xfer->f); if (strcmp(dcc[idx].nick,"*users")==0) { int x,y=0; putlog(LOG_FILES,"*","Completed userfile transfer."); for (x=0; xstatus&=~STAT_SENDING; unlink(dcc[idx].u.xfer->filename); xnick[0]=0; } else { check_tcl_sent(dcc[idx].u.xfer->from,dcc[idx].nick, dcc[idx].u.xfer->dir); incr_file_gots(dcc[idx].u.xfer->dir); putlog(LOG_FILES,"*","Finished dcc send %s to %s", dcc[idx].u.xfer->filename,dcc[idx].nick); wipe_tmp_file(idx); strcpy(xnick,dcc[idx].nick); } lostdcc(idx); /* any to dequeue? */ if (!at_limit(xnick)) send_next_file(xnick); } else { fseek(dcc[idx].u.xfer->f,dcc[idx].u.xfer->sent,0); l=dcc_block; if (dcc[idx].u.xfer->sent+dcc_block > dcc[idx].u.xfer->length) l=dcc[idx].u.xfer->length - dcc[idx].u.xfer->sent; bf=(char *)nmalloc(l+1); fread(bf,l,1,dcc[idx].u.xfer->f); write(dcc[idx].sock,bf,l); nfree(bf); dcc[idx].u.xfer->sent+=l; dcc[idx].u.xfer->pending=time(NULL); } } } } else if (dcc[idx].type==DCC_TELNET) { unsigned long ip; int i,j; i=dcc_total; if (i+1>MAXDCC) { j=answer(dcc[idx].sock,s,&ip); if (j!=-1) { tprintf(j,"Sorry, too many connections already.\r\n"); close(j); } } else { dcc[i].sock=answer(dcc[idx].sock,s,&ip); while ((dcc[i].sock==(-1)) && (errno==EAGAIN)) dcc[i].sock=answer(dcc[idx].sock,s,&ip); if (dcc[i].sock!=-1) { sprintf(dcc[i].host,"telnet!telnet@%s",s); if (match_ignore(dcc[i].host)) { tprintf(dcc[i].sock,"\r\nSorry, your site is being ignored.\r\n\n"); close(dcc[i].sock); } else { dcc[i].addr=ip; dcc[i].port=dcc[idx].port; sprintf(dcc[i].host,"telnet from %s",s); dcc[i].type=DCC_TELNET_ID; strcpy(dcc[i].nick,"???"); set_chat(i); dcc[i].u.chat->away=NULL; dcc[i].u.chat->status=STAT_TELNET|STAT_ECHO; dcc[i].u.chat->timer=time(NULL); dcc[i].u.chat->msgs_per_sec=0; dcc[i].u.chat->con_flags=0; strcpy(dcc[i].u.chat->con_chan,chanset->name); dcc[i].u.chat->channel=0; /* party line */ tprintf(dcc[i].sock,"\r\n\r\n"); telltext(i,"banner",0,0); tprintf(dcc[i].sock,"\r\nPlease enter your nickname.\r\n"); if (allow_new_telnets) tprintf(dcc[i].sock,"(If you are new, enter 'NEW' here.)\r\n"); dcc_total++; putlog(LOG_MISC,"*","Telnet connection: %s",s); } } else { neterror(s1); putlog(LOG_MISC,"*","Failed TELNET incoming (%s)",s1); } } } else if (dcc[idx].type==DCC_TELNET_ID) { int ok=0,atr; buf[10]=0; atr=get_attr_handle(buf); if (atr & USER_OP) { if (!require_p) ok=1; if ((!require_x) && (dccdir[0])) ok=1; } if (atr & (USER_MASTER|USER_BOT|USER_PARTY)) ok=1; if ((atr&USER_XFER) && (dccdir[0])) ok=1; if ((strcasecmp(buf,"NEW")==0) && (allow_new_telnets)) { dcc[idx].type=DCC_TELNET_NEW; dcc[idx].u.chat->timer=time(NULL); tprintf(dcc[idx].sock,"\r\n"); telltext(idx,"newuser",0,0); tprintf(dcc[idx].sock,"\r\nEnter the nickname you would like to use.\r\n"); } else if (!ok) { tprintf(dcc[idx].sock,"You don't have access.\r\n"); putlog(LOG_TAND,"*","Refused %s (invalid handle: %s)", dcc[idx].host,buf); close(dcc[idx].sock); lostdcc(idx); } else if ((atr & USER_BOT) && (in_chain(buf))) { tprintf(dcc[idx].sock,"error Already connected.\n"); putlog(LOG_TAND,"*","Refused telnet connection from %s (duplicate)",buf); close(dcc[idx].sock); lostdcc(idx); } else if ((atr & USER_BOT) && (!online)) { tprintf(dcc[idx].sock,"error Not accepting links yet.\n"); putlog(LOG_TAND,"*","Refused telnet connection from %s (premature)",buf); close(dcc[idx].sock); lostdcc(idx); } else if (pass_match_by_handle("nopass",buf)) { if (atr & USER_BOT) { char ps[20]; makepass(ps); change_pass_by_handle(buf,ps); correct_handle(buf); strcpy(dcc[idx].nick,buf); nfree(dcc[idx].u.chat); set_tand(idx); dcc[idx].u.tand->status=STAT_CALLED; dcc[idx].u.tand->timer=time(NULL); dcc[idx].u.tand->version[0]=0; if (atr & BOT_LEAF) dcc[idx].u.tand->status|=BOT_LEAF; dcc[idx].type=DCC_TANDEM; tprintf(dcc[idx].sock,"*hello!\n"); tprintf(dcc[idx].sock,"thisbot %s\n",origbotname); tprintf(dcc[idx].sock,"version %s\n",ver); tprintf(dcc[idx].sock,"handshake %s\n",ps); stop_auto(dcc[idx].nick); putlog(LOG_TAND,"*","Linked to %s",dcc[idx].nick); chatout("*** Linked to %s\n",dcc[idx].nick); tandout_but(idx,"nlinked %s %s\n",dcc[idx].nick,origbotname); tandout_but(idx,"chat %s Linked to %s\n",origbotname,dcc[idx].nick); dump_links(dcc[idx].sock); addbot(dcc[idx].nick,dcc[idx].nick); dcc[idx].type=DCC_TANDEM; check_tcl_link(dcc[idx].nick,dcc[idx].nick); } else { tprintf(dcc[idx].sock,"Can't telnet until you have a password set.\r\n"); putlog(LOG_MISC,"*","Refused [%s]%s (no password)",buf, dcc[idx].host); close(dcc[idx].sock); lostdcc(idx); } } else { int ok=0; dcc[idx].type=DCC_CHAT_PASS; dcc[idx].u.chat->timer=time(NULL); if (atr & USER_XFER) dcc[idx].u.chat->status|=STAT_XFER; if (atr & USER_MASTER) { dcc[idx].u.chat->status|=STAT_MASTER; ok=1; } else if (atr & USER_OP) { if (!require_p) ok=1; else if (atr & USER_PARTY) ok=1; } else if (atr & USER_PARTY) { ok=1; dcc[idx].u.chat->status|=STAT_PARTY; } if (atr & USER_BOT) ok=1; if (!ok) { set_files(idx); dcc[idx].type=DCC_FILES_PASS; } correct_handle(buf); strcpy(dcc[idx].nick,buf); if (atr & USER_BOT) tprintf(dcc[idx].sock,"passreq\n"); else { dprintf(idx,"\nEnter your password.\377\373\001\n"); /* turn off remote telnet echo: IAC WILL ECHO */ } } } else if (dcc[idx].type==DCC_RELAY) { int j; for (j=0; (dcc[j].sock!=dcc[idx].u.relay->sock) || (dcc[j].type!=DCC_RELAYING); j++); /* if redirecting to a non-telnet user, swallow telnet codes */ if (!(dcc[j].u.relay->chat->status&STAT_TELNET)) { swallow_telnet_codes(buf); if (!buf[0]) tprintf(dcc[idx].u.relay->sock," \n"); else tprintf(dcc[idx].u.relay->sock,"%s\n",buf); } else { /* telnet user */ if (!buf[0]) tprintf(dcc[idx].u.relay->sock," \r\n"); else tprintf(dcc[idx].u.relay->sock,"%s\r\n",buf); } } else if (dcc[idx].type==DCC_RELAYING) { int j; if (strcasecmp(buf,"*BYE*")==0) { struct chat_info *ci; for (j=0; (dcc[j].sock!=dcc[idx].u.relay->sock) || (dcc[j].type!=DCC_RELAY); j++); /* in case echo was off, turn it back on: */ if (dcc[idx].u.relay->chat->status&STAT_TELNET) tprintf(dcc[idx].sock,"\377\374\001\n"); dprintf(idx,"\n(Breaking connection to %s.)\n",dcc[j].nick); dprintf(idx,"You are now back on %s.\n\n",origbotname); putlog(LOG_MISC,"*","Relay broken: %s -> %s",dcc[idx].nick,dcc[j].nick); if (dcc[idx].u.relay->chat->channel >= 0) chanout2(dcc[idx].u.relay->chat->channel, "%s joined the party line.\n",dcc[idx].nick); ci=dcc[idx].u.relay->chat; nfree(dcc[idx].u.relay); dcc[idx].u.chat=ci; dcc[idx].type=DCC_CHAT; notes_read(dcc[idx].nick,"",-1,idx); close(dcc[j].sock); lostdcc(j); } else tprintf(dcc[idx].u.relay->sock,"%s\n",buf); } else if (dcc[idx].type==DCC_TELNET_NEW) { int x,ok=1; buf[9]=0; strcpy(dcc[idx].nick,buf); dcc[idx].u.chat->timer=time(NULL); for (x=0; x=127)) ok=0; if (!ok) { dprintf(idx,"\nYou can't use weird symbols in your nick.\n"); dprintf(idx,"Try another one please:\n"); } else if (is_user(buf)) { dprintf(idx,"\nSorry, that nickname is taken already.\n"); dprintf(idx,"Try another one please:\n"); } else { userlist=adduser(userlist,buf,"none","nopass",USER_PARTY|default_flags); dcc[idx].u.chat->status=STAT_ECHO; dcc[idx].type=DCC_CHAT; /* just so next line will work */ check_dcc_attrs(buf,USER_PARTY|default_flags,USER_PARTY|default_flags); dcc[idx].type=DCC_TELNET_PW; dprintf(idx,"\nOkay, now choose and enter a password:\n"); dprintf(idx,"(Only the first 9 letters are significant.)\n"); } } else if (dcc[idx].type==DCC_TELNET_PW) { buf[10]=0; putlog(LOG_MISC,"*","New user via telnet: [%s]%s/%d",dcc[idx].nick, dcc[idx].host,dcc[idx].port); if (notify_new[0]) { char s[121],s1[121],*p1; sprintf(s,"Introduced to %s, %s",dcc[idx].nick,dcc[idx].host); strcpy(s1,notify_new); while (s1[0]) { p1=strchr(s1,','); if (p1!=NULL) { *p1=0; p1++; rmspace(p1); } rmspace(s1); add_note(s1,origbotname,s,-1,0); if (p1==NULL) s1[0]=0; else strcpy(s1,p1); } } change_pass_by_handle(dcc[idx].nick,buf); dprintf(idx,"\nRemember that! You'll need it next time you log in.\n"); dprintf(idx,"You now have an account on %s...\n\n\n",origbotname); dcc[idx].type=DCC_CHAT; dcc_chatter(idx); } else if (dcc[idx].type==DCC_SCRIPT) { if (buf[0]) { set_tcl_vars(); if (call_tcl_func(dcc[idx].u.script->command,dcc[idx].sock,buf)) { void *old; old=dcc[idx].u.script->u.other; dcc[idx].type=dcc[idx].u.script->type; nfree(dcc[idx].u.script); dcc[idx].u.other=old; notes_read(dcc[idx].nick,"",-1,idx); if ((dcc[idx].type==DCC_CHAT) && (dcc[idx].u.chat->channel >= 0)) chanout2(dcc[idx].u.chat->channel,"%s has joined the party line.\n", dcc[idx].nick); } } } } /* eof from dcc goes here from I/O... */ void eof_dcc(z) int z; { int idx; char s[121]; context; for (idx=0; (dcc[idx].sock!=z) || (dcc[idx].type==DCC_FORK) || (dcc[idx].type==DCC_LOST); idx++); if (idx>=dcc_total) { putlog(LOG_MISC,"*","(@) EOF socket %d, not a dcc socket, not anything.", z); return; } if (dcc[idx].type==DCC_SCRIPT) { void *old; /* tell the script they're gone: */ call_tcl_func(dcc[idx].u.script->command,dcc[idx].sock,""); old=dcc[idx].u.script->u.other; dcc[idx].type=dcc[idx].u.script->type; nfree(dcc[idx].u.script); dcc[idx].u.other=old; /* then let it fall thru to the real one */ } if ((dcc[idx].type==DCC_CHAT) || (dcc[idx].type==DCC_CHAT_PASS) || (dcc[idx].type==DCC_FILES) || (dcc[idx].type==DCC_FILES_PASS)) { if (dcc[idx].type==DCC_CHAT) dcc[idx].u.chat->con_flags=0; putlog(LOG_MISC,"*","Lost dcc connection to %s!%s/%d",dcc[idx].nick, dcc[idx].host,dcc[idx].port); if (dcc[idx].type==DCC_CHAT) { if (dcc[idx].u.chat->channel>=0) chanout2_but(idx,dcc[idx].u.chat->channel,"%s lost dcc link.\n", dcc[idx].nick); check_tcl_chof(dcc[idx].nick,dcc[idx].sock); } close(z); lostdcc(idx); } else if (dcc[idx].type==DCC_TANDEM) { putlog(LOG_TAND,"*","Lost bot: %s",dcc[idx].nick,dcc[idx].port); tandout_but(idx,"chat %s Lost bot: %s\n",origbotname,dcc[idx].nick); tandout_but(idx,"unlinked %s\n",dcc[idx].nick); rembot(dcc[idx].nick,dcc[idx].nick); unvia(idx,dcc[idx].nick); cancel_user_xfer(idx); close(z); lostdcc(idx); } else if (dcc[idx].type==DCC_TANDEM_NEW) { putlog(LOG_TAND,"*","Lost bot: %s",dcc[idx].nick,dcc[idx].port); close(z); lostdcc(idx); } else if (dcc[idx].type==DCC_TELNET_ID) { putlog(LOG_MISC,"*","Lost telnet connection to %s/%d",dcc[idx].host, dcc[idx].port); close(z); lostdcc(idx); } else if (dcc[idx].type==DCC_SEND) { if (dcc[idx].u.xfer->length==dcc[idx].u.xfer->sent) { /* success */ int ok=0,j; char ofn[121],nfn[121],hand[41],s[161]; fclose(dcc[idx].u.xfer->f); if (strcmp(dcc[idx].nick,"*users")==0) { finish_share(idx); } else { putlog(LOG_FILES,"*","Completed dcc send %s from %s!%s", dcc[idx].u.xfer->filename,dcc[idx].nick,dcc[idx].host); sprintf(s,"%s!%s",dcc[idx].nick,dcc[idx].host); get_handle_by_host(hand,s); /* move the file from /tmp */ sprintf(ofn,"%s%s",tempdir,dcc[idx].u.xfer->filename); sprintf(nfn,"%s%s",dcc[idx].u.xfer->dir,dcc[idx].u.xfer->filename); if (movefile(ofn,nfn)) putlog(LOG_MISC|LOG_FILES,"*","FAILED move %s from %s ! File lost!", dcc[idx].u.xfer->filename,tempdir); else { /* add to file database */ add_file(dcc[idx].u.xfer->dir,dcc[idx].u.xfer->filename,hand); check_tcl_rcvd(hand,dcc[idx].nick,nfn); } for (j=0; jf); if (strcmp(dcc[idx].nick,"*users")==0) { int x,y=0; for (x=0; xstatus&=~STAT_GETTING; dcc[y].u.tand->status&=~STAT_SHARE; } putlog(LOG_MISC,"*","Lost userfile transfer; aborting."); unlink(dcc[idx].u.xfer->filename); } else { putlog(LOG_FILES,"*","Lost dcc send %s from %s!%s (%lu/%lu)", dcc[idx].u.xfer->filename,dcc[idx].nick,dcc[idx].host, dcc[idx].u.xfer->sent,dcc[idx].u.xfer->length); sprintf(s,"%s%s",tempdir,dcc[idx].u.xfer->filename); unlink(s); } close(z); lostdcc(idx); } } else if ((dcc[idx].type==DCC_GET_PENDING) || (dcc[idx].type==DCC_GET)) { char xnick[10]; fclose(dcc[idx].u.xfer->f); if (strcmp(dcc[idx].nick,"*users")==0) { int x,y=0; for (x=0; xstatus&=~STAT_SENDING; dcc[y].u.tand->status&=~STAT_SHARE; } putlog(LOG_MISC,"*","Lost userfile transfer; aborting."); unlink(dcc[idx].u.xfer->filename); xnick[0]=0; } else { putlog(LOG_FILES,"*","Lost dcc get %s from %s!%s", dcc[idx].u.xfer->filename,dcc[idx].nick,dcc[idx].host); wipe_tmp_file(idx); strcpy(xnick,dcc[idx].nick); } close(z); lostdcc(idx); /* send next queued file if there is one */ if (!at_limit(xnick)) send_next_file(xnick); } else if (dcc[idx].type==DCC_RELAY) { int j; struct chat_info *ci; for (j=0; dcc[j].sock!=dcc[idx].u.relay->sock; j++); /* in case echo was off, turn it back on: */ if (dcc[idx].u.relay->chat->status&STAT_TELNET) tprintf(dcc[idx].sock,"\377\374\001\n"); putlog(LOG_MISC,"*","Ended relay link: %s -> %s",dcc[j].nick, dcc[idx].nick); dprintf(j,"\n\n*** RELAY CONNECTION DROPPED.\n"); dprintf(j,"You are now back on %s.\n",origbotname); if (dcc[j].u.chat->channel>=0) chanout2(dcc[j].u.relay->chat->channel,"%s rejoined the party line.\n", dcc[j].nick); ci=dcc[j].u.relay->chat; nfree(dcc[j].u.relay); dcc[j].u.chat=ci; dcc[j].type=DCC_CHAT; notes_read(dcc[j].nick,"",-1,j); close(dcc[idx].sock); lostdcc(idx); } else if (dcc[idx].type==DCC_RELAYING) { int j,x=dcc[idx].u.relay->sock; putlog(LOG_MISC,"*","Lost dcc connection to [%s]%s/%d",dcc[idx].nick, dcc[idx].host,dcc[idx].port); close(dcc[idx].sock); lostdcc(idx); for (j=0; (dcc[j].sock!=x) || (dcc[j].type==DCC_FORK) || (dcc[j].type==DCC_LOST); j++); putlog(LOG_MISC,"*","(Dropping relay link to %s)",dcc[j].nick); close(dcc[j].sock); lostdcc(j); /* drop connection to the bot */ } else if (dcc[idx].type==DCC_TELNET_NEW) { putlog(LOG_MISC,"*","Lost new telnet user (%s/%d)",dcc[idx].host, dcc[idx].port); close(dcc[idx].sock); lostdcc(idx); } else if (dcc[idx].type==DCC_TELNET_PW) { putlog(LOG_MISC,"*","Lost new telnet user %s (%s/%d)",dcc[idx].nick, dcc[idx].host,dcc[idx].port); deluser(dcc[idx].nick); close(dcc[idx].sock); lostdcc(idx); } else { putlog(LOG_MISC,"*","*** ATTENTION: DEAD SOCKET (%d) OF TYPE %d UNTRAPPED", z,dcc[idx].type); close(z); lostdcc(idx); } }