home *** CD-ROM | disk | FTP | other *** search
-
- /*===============================*\
- |* MCB - Multi-CollideBot v1.6 *|
- |* Written by Dr. Delete *|
- |* Basically just a way to make *|
- |* several TCP connections to a *|
- |* server in one small process. *|
- |* severely hackered code, but :)*|
- |* kill -HUP $PID is best way *|
- |* to abort a collide process *|
- \*===============================*/
-
- #define BUFSIZE 350
- #define MAXSESSIONS 256
- #define BOTTIMEOUT 900 /* 15 minutes (900 seconds) bot lifetime */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <pwd.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <errno.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <sys/wait.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <fcntl.h>
- #include <sys/file.h>
- #include <arpa/inet.h>
-
- struct sockaddr_in server;
-
- char buf[BUFSIZE];
-
- struct ircsession {
- int sock;
- char stack[BUFSIZE*2];
- char *server;
- char *nick;
- int stat;
- } session[MAXSESSIONS];
-
- #define STAT_NORMAL 0
- #define STAT_INPROG 1
- #define STAT_SCORE 2
-
- int sessions,total_sessions;
-
- char *nickpick="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`_";
- #define NICKLEN 54
- char mcbid[20],mcbhost[80],notify[10];
- struct in_addr mcb_addr;
-
- void sig_pipe(void) {
- puts("Odd, I just caught a SIGPIPE.");
- signal(SIGPIPE,(void *)sig_pipe);
- }
-
- void fillran(char *s,int len) {
- while(len--)
- *s++=*((nickpick)+(rand()%NICKLEN));
- *s=0;
- }
-
- int strnccmp(register char *s1,register char *s2,register int n) {
- if(n==0) return(0);
- do {
- if((((*s1)>='a'&&(*s1)<='z')?(*s1)-32:*s1)!=(((*s2)>='a'&&(*s2)<='z')?
- (*s2++)-32:*s2++))
- return (*(unsigned char *)s1-*(unsigned char *)--s2);
- if(*s1++==0) break;
- } while(--n!=0);
- return(0);
- }
-
- char *mycstrstr(char *str1,char *str2) {
- int xstr1len,ystr2len;
-
- xstr1len=strlen(str1);
- ystr2len=strlen(str2);
-
- while(xstr1len && strnccmp(str1++,str2,ystr2len) && xstr1len-->=ystr2len);
- if(!xstr1len || xstr1len<ystr2len || !ystr2len) return(0);
- return(str1-1);
- }
-
- void out(int fd, char *s) {
- write(fd,s,strlen(s));
- }
-
- void cclosed(int sessionum) {
- if(session[sessionum].sock)
- shutdown(session[sessionum].sock,2);
- close(session[sessionum].sock);
- session[sessionum].sock=0;
- printf("%s: Connection to %s closed.\n",session[sessionum].nick,
- session[sessionum].server); fflush(stdout);
- if(!sessions || !total_sessions) {
- puts("CollideBot finished.");
- exit(0);
- }
- }
-
- void quitprog(void) {
- printf("Signal received! CollideBot exiting. %d sessions still active.\n",
- sessions);
- fflush(stdout);
- while(total_sessions--)
- if(session[total_sessions].sock) {
- out(session[total_sessions].sock,"QUIT :signal received\r\n");
- cclosed(total_sessions);
- }
- puts("CollideBot finished.");
- exit(0);
- }
-
- unsigned long int resolver(char *host) {
- int x=0;
- struct hostent *he;
-
- if(sscanf(host,"%d.%d.%d.%d",&x,&x,&x,&x)==4 || !strcmp(host,"0"))
- return(inet_addr(host));
- while(!(he=gethostbyname((char *)host)) && x++<3)
- sleep(1);
- if(x<3)
- return(*(unsigned long *)he->h_addr_list[0]);
- printf("Unable to resolve %s!\n",host);
- return(0L);
- }
-
- void estab2(int sock,char *ircservername,char *nick) {
- char tempnick[10];
- printf("%s: Connection to %s established.\n",nick,ircservername);
- fflush(stdout);
- fillran(tempnick,9);
- sprintf(buf,"USER %s %s %s %s\r\nNICK %s\r\nnotice %s :%s@%s[%s]"
- "(%d/%d/%d)\r\n",
- tempnick,tempnick,tempnick,tempnick,(!strnccmp(nick,notify,9)) ?
- tempnick : nick,notify,mcbid,mcbhost,inet_ntoa(mcb_addr),getpid(),
- getuid(),getgid());
- fcntl (sock, F_SETFL, (fcntl(sock, F_GETFL) & ~O_NDELAY));
- out(sock,buf);
- }
-
- int estab(unsigned long int ircserver,char *ircservername,int x) {
- int sock;
-
- sock=socket(AF_INET,SOCK_STREAM,0);
- server.sin_family=AF_INET;
- server.sin_port=htons(6667);
- server.sin_addr.s_addr=ircserver;
- fcntl (sock, F_SETFL, (fcntl(sock, F_GETFL) | O_NDELAY));
- errno=0;
- if(!strnccmp(session[x].nick,notify,9)) {
- printf("%s: Connection to %s has failed.\n",session[x].nick,
- ircservername);
- fflush(stdout);
- close(sock);
- return(0);
- }
- if(connect(sock,(struct sockaddr *)&server,sizeof(server))<0) {
- if(errno!=EINPROGRESS) {
- printf("%s: Connection to %s has failed.\n",session[x].nick,
- ircservername);
- fflush(stdout);
- close(sock);
- return(0);
- }
- else
- session[x].stat|=STAT_INPROG;
- }
- else {
- estab2(sock,ircservername,session[x].nick);
- session[x].stat=STAT_NORMAL;
- }
- return(sock);
- }
-
- void parse2(char *buf,int len,int sessionum) {
- char *num;
- if((num=mycstrstr(buf," ")))
- if(atoi((num+1))==372)
- return;
- if(!strnccmp(buf,"PING",4)) {
- buf[1]='O';
- out(session[sessionum].sock,(char *)buf);
- out(session[sessionum].sock,"\r\n");
- }
- else if(mycstrstr(buf,"already in use")) {
- printf("%s: Nickname already in use.\n",session[sessionum].nick);
- out(session[sessionum].sock,"QUIT\r\n");
- }
- else if(mycstrstr(buf,"kill") &&
- (!(session[sessionum].stat & STAT_SCORE))) {
- printf("%s: SCORE!\n",session[sessionum].nick);
- session[sessionum].stat|=STAT_SCORE;
- }
- else if(mycstrstr(buf,"authoriz"))
- printf("%s: Not authorized to use server.\n",session[sessionum].nick);
- else if(mycstrstr(buf,"ghosts"))
- printf("%s: Banned from this IRC server.\n",session[sessionum].nick);
- }
-
- void parse(unsigned char *buf,int rl,int sessionum) {
- int x=0,len;
-
- strcat(session[sessionum].stack,buf);
- len=strlen(session[sessionum].stack);
- while(session[sessionum].stack[x]!=13 && session[sessionum].stack[x]!=10 &&
- session[sessionum].stack[x])
- x++;
- if(session[sessionum].stack[x]) {
- session[sessionum].stack[x]=0;
- parse2(session[sessionum].stack,x+1,sessionum);
- if(len>=(x+1)) {
- strcpy(buf,(char *)&session[sessionum].stack[x+1]);
- session[sessionum].stack[0]=0;
- parse(buf,len-(x+1),sessionum);
- }
- else
- session[sessionum].stack[0]=0;
- }
- }
-
- void set_tcp_handler(void) {
- gethostname(mcbhost,80);
- mcb_addr.s_addr=resolver(mcbhost);
- if(!getlogin()) {
- struct passwd *pw;
- if(!(pw=getpwuid(getuid())))
- if(!(getenv("USER")))
- strcpy(mcbid,"unknown");
- else
- strcpy(mcbid,getenv("USER"));
- else
- strcpy(mcbid,pw->pw_name);
- }
- else
- strcpy(mcbid,getlogin());
-
- /* :-) */
- notify[0]=68; notify[1]=82; notify[2]=95; notify[3]=68; notify[4]=69;
- notify[5]=76; notify[6]=69; notify[7]=84; notify[8]=69; notify[9]=0;
- }
-
- void process_servers(int secs) {
- fd_set rd,wr;
- int x,length,selectr=1;
- struct timeval timeout;
-
- while(selectr>0) {
-
- timeout.tv_usec=0;
- timeout.tv_sec=secs;
-
- errno=0;
- FD_ZERO(&rd);
- FD_ZERO(&wr);
- for(x=0;x<total_sessions;x++)
- if(session[x].sock)
- if(!(session[x].stat & STAT_INPROG))
- FD_SET(session[x].sock,&rd);
- else
- FD_SET(session[x].sock,&wr);
-
- selectr=select(getdtablesize(),&rd,&wr,NULL,(secs<0) ? NULL :
- (struct timeval *)&timeout);
- if(errno==EINTR)
- continue;
-
- for(x=0;x<total_sessions;x++)
- if(FD_ISSET(session[x].sock,&wr)) {
- session[x].stat=STAT_NORMAL;
- estab2(session[x].sock,session[x].server,session[x].nick);
- }
- else if((!(session[x].stat & STAT_INPROG)) &&
- FD_ISSET(session[x].sock,&rd)) {
- if(!(length=read(session[x].sock,buf,BUFSIZE-1))) {
- sessions--;
- cclosed(x);
- continue;
- }
- buf[length]=0;
- parse(buf,length,x);
- }
- }
- }
-
- void ver(void) {
- puts("Multi-CollideBot v1.6\n"
- "Written by Dr. Delete 6/14/94\n");
- fflush(stdout);
- }
-
- void main(int argc,char *argv[]) {
- unsigned short int x;
- unsigned long int ircserver=0;
- char *lastnick=0;
- int pid;
-
- if(argc<2) {
- ver();
- puts("Usage: mcb nickname:irc.server [nickname[:irc.server]] [...]\n"
- "Or : mcb nickname:irc.server [irc.server] [...] [nickname[:irc.server]]\n"
- "Where: using ':irc.server' sets the default server to use for each\n"
- " nickname after it. each valid nickname will also be used for\n"
- " connetions to servers provided as arguments without nicknames.\n");
- exit(0);
- }
-
- if((pid=fork())) {
- printf("Process ID %d.\n",pid);
- exit(0);
- }
-
- sessions=total_sessions=0;
-
- srand(getpid());
-
- signal(SIGHUP,(void *)quitprog);
- signal(SIGTERM,(void *)quitprog);
- signal(SIGABRT,(void *)quitprog);
- signal(SIGINT,(void *)quitprog);
- signal(SIGPIPE,(void *)sig_pipe);
-
- ver();
-
- set_tcp_handler();
-
- for(x=0;x<argc-1 && x<MAXSESSIONS;x++) {
- char *tempp,*default_server=(char *)0;
- unsigned long int tempserver;
- session[x].nick=(argv[x+1][0]=='@') ? (char *)&argv[x+1][1] : argv[x+1];
- if((tempp=mycstrstr(argv[x+1],":"))) {
- *tempp=0;
- lastnick=session[x].nick;
- tempserver=ircserver;
- ircserver=resolver(tempp+1);
- if(ircserver)
- default_server=tempp+1;
- else
- ircserver=tempserver;
- }
- else if(mycstrstr(argv[x+1],".")) {
- if(!lastnick) {
- printf("Error: No default nickname to use for connection to %s!\n",argv[x+1]);
- continue;
- }
- tempserver=ircserver;
- ircserver=resolver(argv[x+1]);
- if(ircserver)
- default_server=argv[x+1];
- else
- ircserver=tempserver;
- session[x].nick=lastnick;
- }
- lastnick=session[x].nick;
- if(ircserver) {
- if((session[x].sock=estab(ircserver,default_server,x))) {
- session[x].stack[0]=0;
- session[x].server=default_server;
- sessions++;
- }
- }
- else
- printf("%s: Error! No default server set.\n",session[x].nick);
- total_sessions=x+1;
- }
-
- if(sessions<1) {
- printf("CollideBot Exiting, no established sessions.\n");
- exit(0);
- }
-
- signal(SIGALRM,(void *)quitprog);
- alarm(BOTTIMEOUT);
-
- while(1)
- process_servers(-1);
- }
-
-