/* socket.c ** The socket's core of this code has been made by wildthang ** . You can modify it but not distribute it ** modified. This file is part of MudBot and is (C) 1997 by Drow ** All rights reserved. */ #define MAXBUFSIZE 512 #include #include #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "vars.h" u_short IRCPORT; /*= DEFAULTPORT;*/ extern long NOW; int mail_socket(hostname,port,sck) char *hostname; u_short port; int sck; { struct sockaddr_in sa; struct hostent *hp; int a, s; if((hp=gethostbyname(hostname))==NULL) { sprintf(buf,"NOTICE %s :Hostname %s not valid!\n",token[0],hostname); writeln(sck,buf); return(-2); } bzero(&sa, sizeof(sa)); bcopy(hp->h_addr, (char *)&sa.sin_addr, hp->h_length); sa.sin_family = hp->h_addrtype; sa.sin_port = htons((u_short)port); if((s=socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) return(-1); if(connect(s,(struct sockaddr *) &sa, sizeof(sa)) < 0) { return(-1); } return(s); } int update_socket(hostname,IRCPORT,sck) char *hostname; u_short IRCPORT; int sck; { struct sockaddr_in sa; struct hostent *hp; int a, s; if((hp=gethostbyname(hostname))==NULL) { return(-1); } bzero(&sa, sizeof(sa)); bcopy(hp->h_addr, (char *)&sa.sin_addr, hp->h_length); sa.sin_family = hp->h_addrtype; sa.sin_port = htons((u_short)IRCPORT); if((s=socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) return(-1); if(connect(s,(struct sockaddr *) &sa, sizeof(sa)) < 0) { return(-1); } return(s); } int call_socket(hostname,IRCPORT) char *hostname; u_short IRCPORT; { struct sockaddr_in sa; #ifdef VIRTUAL struct in_addr vir; struct sockaddr_in la; struct hostent *virhp; #endif struct hostent *hp; int a, s; if((hp=gethostbyname(hostname))==NULL) { errno=ECONNREFUSED; printf("\n*** Can't find hostname: %s\n",hostname); #ifdef LOGERRORS logerr("Can't find hostname"); #endif #ifdef JUMPONERROR do_jump(botsck[0],NULL,0); #endif exit(0); return(-1); } bzero(&sa, sizeof(sa)); bcopy(hp->h_addr, (char *)&sa.sin_addr, hp->h_length); sa.sin_family = hp->h_addrtype; sa.sin_port = htons((u_short)IRCPORT); if((s=socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) return(-1); #ifdef VIRTUAL memset((void *)&vir, 0, sizeof(vir)); virhp=gethostbyname(VIRTUAL); memcpy((void *)&vir, virhp->h_addr, sizeof(vir)); memset(&la, 0, sizeof(struct sockaddr_in)); la.sin_family = AF_INET; la.sin_addr = vir; la.sin_port = 0; bind(s, (struct sockaddr *)&la, sizeof(la)); #endif if(connect(s,(struct sockaddr *) &sa, sizeof(sa)) < 0) { close(s); printf("\n*** Connect failed\n"); #ifdef LOGERRORS logerr("Connect failed"); #endif #ifdef JUMPONERROR do_jump(botsck[0],NULL,0); #endif exit(0); } return(s); } int readln(int sckfd) { int i=0,valid=1; char c; int length; strcpy(sockbuf,"dummy"); if((length=read(sckfd,sockbuf,MAXBUFSIZE))<1) { if(errno==EWOULDBLOCK || errno==EAGAIN) return(0); else return -1; } sockbuf[length]='\0'; return(length); } int readln2(int sckfd) { int i=0,valid=1; char c; int length; strcpy(servbuf,"dummy"); if((length=read(sckfd,servbuf,MAXBUFSIZE))<1) { if(errno==EWOULDBLOCK || errno==EAGAIN) return(0); else return -1; } servbuf[length]='\0'; return(length); } int readln3(int sckfdd) { int i=0,valid=1; char c; int length; strcpy(chanbuf,"dummy"); if((length=read(sckfdd,chanbuf,MAXBUFSIZE))<1) { if(errno==EWOULDBLOCK || errno==EAGAIN) return(0); else return -1; } chanbuf[length]='\0'; return(length); } int writeln(sckfd,outbuf) int sckfd; char *outbuf; { int to=0; FILE *fp; char temp[255]; if(sckfd < 0) return; #ifdef INTER_WEB if(global_write_html==1) { strcpy(temp,HTMLDIR); strcat(temp,"/command.results"); fp=fopen(temp,"a"); fputs(lrange(outbuf,2),fp); fputs("\n\n",fp); if(fp!=NULL) fclose(fp); } else { #endif write(sckfd, outbuf, strlen(outbuf)); if(sckfd!=servsck && sckfd!=chansck) { #ifdef DEBUG_OUT printf("[OUT] %s\n",outbuf); #endif sleep(SLEEP_TIME); if(FLOOD_PROTECT>1) { if(strlen(outbuf)>20) sleep(1); } if(FLOOD_PROTECT>0) { if(strlen(outbuf)>30) sleep(1); } if(strlen(outbuf)>50) sleep(1); if(FLOOD_PROTECT>2) { if(strlen(outbuf)>60) sleep(1); } if(strlen(outbuf)>100) sleep(1); if(FLOOD_PROTECT>2) { if(strlen(outbuf)>120) sleep(1); } if(FLOOD_PROTECT>0) { if(strlen(outbuf)>150) sleep(1); } } #ifdef DEBUG_OUT printf("[OUT] %s\n",sockbuf); #endif #ifdef INTER_WEB } #endif return(0); } int bot_login(char *botname,char *hostname,u_short port) { int sckfd; int i; printf("*** Trying %s\n\n",hostname); for (i=1;i < 10;i++) { sckfd=call_socket(hostname,port); if (sckfd == -1) continue; else break; } printf("*** Connection made (socket: %d)\n",sckfd); sprintf(buf,"NICK %s\n",botname); writeln(sckfd,buf); #ifdef PASS sprintf(buf,"PASS %s\n",PASS); writeln(sckfd,buf); #endif sprintf(buf, "USER %s 1 1 :%s\n",ACCOUNTNAME,BOTDESC); writeln(sckfd,buf); strcpy(reports_names,"."); strcpy(spying,"dummy"); servsck=-1; chansck=-1; global_stats_lines=0; #ifdef SERVICE for(i=1;i<20;i++) { servsck=call_socket(SERVICE_UPLINK,SERVICE_PORT); if(servsck==-1) continue; else break; } printf("*** Service linked (socket: %d)\n",servsck); sprintf(buff,"PASS %s\n",SERVICE_PASS); writeln(servsck,buff); #ifdef IRCU_2_10 sprintf(buff,"SERVER %s 1 %ld %ld P09 :%s\n",SERVICE_SERVER_NAME,time(NULL),time(NULL),SERVICE_DESC); #else sprintf(buff,"SERVER %s 1 :%s\n",SERVICE_SERVER_NAME,SERVICE_DESC); #endif writeln(servsck,buff); #endif #ifdef CHANSERV for(i=1;i<20;i++) { chansck=call_socket(CHANSERV_UPLINK,CHANSERV_PORT); if(chansck==-1) continue; else break; } printf("*** Channel Service linked (socket: %d)\n",chansck); sprintf(bufc,"PASS %s\n",CHANSERV_PASS); writeln(chansck,bufc); #ifdef IRCU_2_10 sprintf(bufc,"SERVER %s 1 %ld %ld P09 :%s\n",CHANSERV_SERVER_NAME,time(NULL),time(NULL),CHANSERV_DESC); #else sprintf(bufc,"SERVER %s 1 :%s\n",CHANSERV_SERVER_NAME,CHANSERV_DESC); #endif writeln(chansck,bufc); #endif return( sckfd); } int readin() { time_t timer; FILE *fperr; struct tm *tblock; struct timeval timeout; fd_set readfs; fd_set readfss; fd_set readass; int i,timin=0,dumb=0,gotdumped=0,resulting,gotdumped2=0; int DONTCHECKFLAG; int retries; char mycommand[512]; char *tmpstring; int sok,sok2,sok3; int maxwhiler = 0; token[0]++; while(CONNECT) { timeout.tv_sec=TIMEOUT_VALUE; timeout.tv_usec=0; do_timer(); FD_ZERO(&readfs); FD_ZERO(&readfss); FD_ZERO(&readass); for(i=0;i<1;i++) FD_SET(botsck[i],&readfs); #ifdef VIEW FD_SET(fileno(stdin),&readfs); #endif #ifdef SERVICE FD_SET(servsck,&readfss); if(select(FD_SETSIZE, &readfss, NULL, NULL, 120)) { if(FD_ISSET(servsck,&readfss)) { sok2 = readln2(servsck); if (sok2) { serv_in(servsck); } if(sok2==-1) { service_off = 1; close(servsck); } } } #endif /* service */ #ifdef CHANSERV FD_SET(chansck,&readass); if(select(FD_SETSIZE, &readass, NULL, NULL, 120)) { if(FD_ISSET(chansck,&readass)) { sok3 = readln3(chansck); if (sok3) { chanserv_read(chansck); } if (sok3==-1) close(chansck); } } #endif resulting=select(FD_SETSIZE, &readfs, NULL, NULL,&timeout); if(resulting) { gotdumped2=0; NOW=time(NULL); for(i=0;i<1;i++) { if(FD_ISSET(botsck[i],&readfs)) { sok = readln(botsck[i]); if (sok) { spitout(botsck[i]); check_timers(botsck[i]); #ifdef INTER_WEB check_cgi(botsck[i]); global_write_html=0; #endif } #ifdef LOGERRORS #ifdef LOG_ERRNO fperr=fopen(LOGERRORS,"a"); if(errno!=0 && errno!=22) fprintf(fperr,"ERRNO %d\n",errno); if(fperr!=NULL) fclose(fperr); #endif #endif if (sok==-1) { printf("*** Socket closed from server\n"); #ifdef LOGERRORS logerr("Socket closed from server"); #endif #ifdef JUMPONERROR do_jump(botsck[i],NULL,0); #else exit(0); #endif } } #ifdef VIEW if(FD_ISSET(fileno(stdin),&readfs)) { fgets(mycommand,511,stdin); client_cmds(mycommand,botsck[i]); } #endif } } else { if(resulting==0) { gotdumped2++; if(gotdumped2==5) { gotdumped=1; resulting=-1; } } if(resulting==-1) { gotdumped++; if(gotdumped>1) { #ifdef LOGERRORS logerr("Timeout: Jumping"); #endif printf("Timeout\n"); #ifdef JUMPONERROR do_jump(botsck[0],NULL,0); #endif exit(0); } } } } }