573 lines
14 KiB
C
Executable File
573 lines
14 KiB
C
Executable File
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <ctype.h>
|
||
#include <termios.h>
|
||
#include <errno.h>
|
||
#include <sys/types.h>
|
||
#include <pwd.h>
|
||
#include <sys/time.h>
|
||
#include <sys/file.h>
|
||
#include <sys/socket.h>
|
||
#include <netinet/in.h>
|
||
#include <arpa/inet.h>
|
||
#include <netdb.h>
|
||
#include <signal.h>
|
||
#include "config.h"
|
||
|
||
#ifdef USE_DCC
|
||
extern struct aDccClient MyClient[];
|
||
#endif
|
||
|
||
extern char UPLINK[];
|
||
u_short IRCPORT = DEFAULTPORT;
|
||
extern char sockbuf[],buf[];
|
||
extern int sevsck,botsck;
|
||
extern long N_TOTAL,D_TOTAL;
|
||
extern time_t NOWTIME,BotIdle,ServIdle;
|
||
extern char *token[];
|
||
|
||
int DccCtr=-1;
|
||
int BotStatus,ServStatus;
|
||
int MAXDCCONLINE=0;
|
||
|
||
int call_socket(hostname,port)
|
||
char *hostname;
|
||
int port;
|
||
{ struct sockaddr_in sa;
|
||
struct hostent *hp;
|
||
int a, s;
|
||
if((hp=gethostbyname(hostname))==NULL) {
|
||
errno=ECONNREFUSED;
|
||
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) port);
|
||
if((s=socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) return(-1);
|
||
/*
|
||
fcntl(s,F_SETFL,O_NONBLOCK);
|
||
*/
|
||
|
||
if(connect(s,(struct sockaddr *) &sa, sizeof(sa)) < 0) {
|
||
close(s);
|
||
return(-1); }
|
||
return(s);
|
||
}
|
||
|
||
int readln2(int sckfd)
|
||
{ int i=0,valid=1; char c;
|
||
if(sckfd<0) return 0;
|
||
while(valid) {
|
||
if(read(sckfd,&c,1)<1) return(0);
|
||
if(i<511 && (c != '\n') && (c != '
|
||
')) sockbuf[i++]=c; else valid=0; }
|
||
N_TOTAL++;
|
||
D_TOTAL += strlen(sockbuf);
|
||
sockbuf[i]='\0'; return(1);
|
||
}
|
||
|
||
int readln(int sckfd)
|
||
{ int i=0,valid=1; char c;
|
||
int length;
|
||
if(sckfd<0) return -1;
|
||
if((length=read(sckfd,sockbuf,MAXBUFSIZE-1))<1)
|
||
{
|
||
if(errno==EWOULDBLOCK || errno==EAGAIN) return(0);
|
||
else return -1;
|
||
}
|
||
D_TOTAL += length;
|
||
N_TOTAL++;
|
||
sockbuf[length]='\0';
|
||
return(length);
|
||
}
|
||
|
||
int writeln(sckfd,outbuf)
|
||
int sckfd;
|
||
char *outbuf;
|
||
{ int to=0;
|
||
if(sckfd <0) return 0;
|
||
if(write(sckfd, outbuf, strlen(outbuf)) < to )
|
||
return(0);
|
||
return(1);
|
||
}
|
||
|
||
int writeln_srv(sckfd,nick,outbuf)
|
||
int sckfd;
|
||
char *nick;
|
||
char *outbuf;
|
||
{ int to=0;
|
||
char templine[512];
|
||
if(sckfd <0) return 0;
|
||
strcpy(templine,":");
|
||
strcat(templine,nick);
|
||
strcat(templine," ");
|
||
strcat(templine,outbuf);
|
||
if(write(sckfd, templine, strlen(templine)) < to )
|
||
return(0);
|
||
return(1);
|
||
}
|
||
|
||
int login(char *hostname)
|
||
{int sckfd;
|
||
printf("*** trying port %d of %s\n\n\n",IRCPORT,hostname);
|
||
if ((sckfd=call_socket(hostname,IRCPORT))==-1) {
|
||
fprintf(stderr, "*** connection refused, aborting\n", hostname);
|
||
return -1;
|
||
}
|
||
sprintf(buf,"NICK %s\n",BOTNAME); writeln(sckfd,buf);
|
||
sprintf(buf, "USER %s 1 1 :%s\n",BOTNAME,BOTINFO);
|
||
writeln(sckfd,buf);
|
||
return( sckfd);
|
||
}
|
||
|
||
|
||
int bot_login(char *hostname)
|
||
{int sckfd;
|
||
printf("*** trying port %d of %s\n\n\n",IRCPORT,hostname);
|
||
if ((sckfd=call_socket(hostname,IRCPORT))==-1) {
|
||
fprintf(stderr, "*** connection refused, aborting\n", hostname);
|
||
BotStatus=S_FREE;
|
||
BotIdle=NOWTIME;
|
||
return -1;
|
||
}
|
||
sprintf(buf,"NICK %s\n",BOTNAME); writeln(sckfd,buf);
|
||
writeln(sckfd,buf);
|
||
sprintf(buf, "USER %s 1 1 :%s\n",BOTNAME,BOTINFO);
|
||
writeln(sckfd,buf);
|
||
BotStatus=S_ACTIVE;
|
||
return( sckfd);
|
||
}
|
||
|
||
|
||
int readin()
|
||
{
|
||
fd_set readfs;
|
||
struct timeval timeout;
|
||
char MyLocBuf[MAXBUFSIZE];
|
||
int dumb = 1;
|
||
static time_t last_squit=0;
|
||
static squit_loop=0;
|
||
int sok;
|
||
#ifdef USE_DCC
|
||
int mycnt;
|
||
#endif
|
||
static REFRESH=0;
|
||
|
||
while(1) {
|
||
timeout.tv_sec=5;
|
||
timeout.tv_usec=0;
|
||
|
||
FD_ZERO(&readfs);
|
||
|
||
if(ServStatus == S_ACTIVE) FD_SET(sevsck,&readfs);
|
||
else if (ServStatus == S_CLOSING)
|
||
{ close(sevsck);
|
||
ServStatus=S_FREE;
|
||
}
|
||
|
||
if(BotStatus == S_ACTIVE) FD_SET(botsck,&readfs);
|
||
else if (BotStatus == S_CLOSING)
|
||
{ close(botsck);
|
||
BotStatus = S_FREE;
|
||
}
|
||
|
||
if((BotStatus == S_FREE) && (NOWTIME-BotIdle > 60))
|
||
{ botsck=bot_login(UPLINK);
|
||
BotIdle=NOWTIME;
|
||
}
|
||
if((ServStatus == S_FREE) && (NOWTIME-ServIdle > 60))
|
||
{ sevsck=sev_login(UPLINK);
|
||
ServIdle=NOWTIME;
|
||
}
|
||
|
||
#ifdef USE_DCC
|
||
for(mycnt=0;mycnt<MAXDCCONLINE;mycnt++)
|
||
{ char outmsg[1024];
|
||
if(MyClient[mycnt].status == S_CLOSING)
|
||
{ close(MyClient[mycnt].fd);
|
||
MyClient[mycnt].fd=-1;
|
||
MyClient[mycnt].status=S_FREE;
|
||
sprintf(outmsg,"*** %s (%s) has hung up on us\n",
|
||
MyClient[mycnt].name,MyClient[mycnt].hostname);
|
||
DccGlobal(outmsg,DCC_ANY);
|
||
}
|
||
if(MyClient[mycnt].status == S_ACTIVE)
|
||
FD_SET(MyClient[mycnt].fd,&readfs);
|
||
}
|
||
#endif
|
||
|
||
if(select(FD_SETSIZE, &readfs, NULL, NULL,(dumb ? NULL : &timeout))) {
|
||
NOWTIME=time(NULL);
|
||
if(REFRESH < NOWTIME)
|
||
{ REFRESH = NOWTIME+600;
|
||
timeout_myuser();
|
||
}
|
||
if((ServStatus==S_ACTIVE) && (FD_ISSET(sevsck,&readfs))) {
|
||
DccCtr=-1;
|
||
sok = readln(sevsck);
|
||
ServIdle=NOWTIME;
|
||
if (sok>0) spitout(sevsck);
|
||
if (sok < 0)
|
||
{ close(sevsck);
|
||
sevsck = sev_login(UPLINK);
|
||
}
|
||
}
|
||
if((BotStatus == S_ACTIVE) && (FD_ISSET(botsck,&readfs))) {
|
||
DccCtr=-2;
|
||
sok = readln(botsck);
|
||
BotIdle=NOWTIME;
|
||
if (sok>0) spitout(botsck);
|
||
if (sok < 0)
|
||
{ close(botsck);
|
||
botsck = bot_login(UPLINK);
|
||
}
|
||
}
|
||
#ifdef USE_DCC
|
||
for(mycnt=0;mycnt<MAXDCCONLINE;mycnt++)
|
||
{ if(MyClient[mycnt].status == S_ACTIVE )
|
||
if(FD_ISSET(MyClient[mycnt].fd,&readfs)) {
|
||
DccCtr=mycnt;
|
||
MyClient[mycnt].lasttime=NOWTIME;
|
||
sok = readln(MyClient[mycnt].fd);
|
||
if(sok == -1)
|
||
{ MyClient[mycnt].status=S_CLOSING;
|
||
}
|
||
else if (sok>0)
|
||
{
|
||
if(sockbuf[0]== '\0') continue;
|
||
sprintf(MyLocBuf,":%s!%s DCC %s :%s",
|
||
MyClient[mycnt].name, MyClient[mycnt].hostname,
|
||
CHANSVR,sockbuf);
|
||
strcpy(sockbuf,MyLocBuf);
|
||
MyLocBuf[0]='\0';
|
||
spitout(botsck);
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
int sev_login(char hostname[])
|
||
{int sckfd;
|
||
if( (sckfd = call_socket(hostname,IRCPORT)) == -1) {
|
||
fprintf(stderr,"*** connection refused");
|
||
ServStatus=S_FREE;
|
||
ServIdle=NOWTIME;
|
||
return -1;
|
||
}
|
||
sprintf(buf,"PASS %s\n",PASSWORD);
|
||
writeln(sckfd,buf);
|
||
sprintf(buf,"SERVER %s 1 %ul %ul J09 :%s\n",SERVERNAME,time(NULL),time(NULL),
|
||
SERVERINFO);
|
||
ServStatus=S_ACTIVE;
|
||
|
||
writeln(sckfd,buf);
|
||
return( sckfd);
|
||
}
|
||
|
||
int sev_jupe(char hostname[],char *name)
|
||
{
|
||
sprintf(buf,"WALLOPS :%s is trying to jupe %s \n",name,hostname);
|
||
writeln(sevsck,buf);
|
||
sprintf(buf,":%s SQUIT %s JUPE TIME\n",CHANSVR,hostname);
|
||
writeln(sevsck,buf);
|
||
sprintf(buf,":%s SERVER %s 2 %ul %ul J09 :JUPE by %s \n",
|
||
SERVERNAME,hostname,time(NULL),time(NULL),name);
|
||
writeln(sevsck,buf);
|
||
}
|
||
makehelp(int sck,char *botname,char *botinfo)
|
||
{
|
||
sprintf(buf,"NICK %s 1 %ul %s %s %s :%s\n",botname,time(NULL)-86400,
|
||
botname,"undernet.org",SERVERNAME,botinfo);
|
||
writeln(sck,buf);
|
||
}
|
||
|
||
makedecoy(int sck,char *botname,char *bothost,char *botinfo)
|
||
{
|
||
sprintf(buf,"NICK %s 1 %ul %s %s %s :%s\n",botname,time(NULL)-86400,
|
||
botname,bothost,SERVERNAME,botinfo);
|
||
writeln(sck,buf);
|
||
}
|
||
|
||
makemybots(int j)
|
||
{ int i;
|
||
char mybot[10];
|
||
for(i=0;i<j;i++)
|
||
{
|
||
sprintf(mybot,"WT_%d",i);
|
||
sprintf(buf,"NICK %s 1 %ul %s %s %s :%s\n",mybot,time(NULL)-86400,
|
||
mybot,"it.happens.org",SERVERNAME,"Uworld Record Bot");
|
||
writeln(sevsck,buf);
|
||
sprintf(buf,":%s MODE %s +i\n",mybot,mybot);
|
||
writeln(sevsck,buf);
|
||
}
|
||
}
|
||
|
||
killmybots(int j)
|
||
{ int i=0;
|
||
char mybot[10];
|
||
for(i=0;i<j;i++)
|
||
{
|
||
sprintf(mybot,"WT_%d",i);
|
||
sprintf(buf,":%s QUIT %s\n",mybot,mybot);
|
||
writeln(sevsck,buf);
|
||
}
|
||
}
|
||
#ifdef USE_DCC
|
||
int accept_dcc(char *fromhost)
|
||
{ int myctr;
|
||
struct in_addr in;
|
||
int port,newfd;
|
||
char hostname[255];
|
||
port=(token[7] && *token[7])?atoi(token[7]):0;
|
||
if((port < 1024) || (port > 65535))
|
||
{
|
||
return 0;
|
||
}
|
||
if(token[6] && *token[6])
|
||
{ char mybufr[1024];
|
||
in.s_addr=ntohl(strtoul(token[6],NULL,0));
|
||
|
||
/* if the address is 0 then its bad...
|
||
*/
|
||
if(in.s_addr == 0) return 0;
|
||
strcpy(hostname,inet_ntoa(in));
|
||
|
||
for(myctr=0;myctr<MAXCLIENTS;myctr++)
|
||
{ if(MyClient[myctr].status == S_FREE)
|
||
{
|
||
if(myctr+1 > MAXDCCONLINE) MAXDCCONLINE=myctr+1;
|
||
sprintf(buf,":%s NOTICE %s :Received DCC Chat Request %s %d\n",
|
||
CHANSVR,token[0],hostname,port);
|
||
writeln(sevsck,buf);
|
||
MyClient[myctr].fd=call_socket(hostname,port);
|
||
if(MyClient[myctr].fd >=0)
|
||
{ int loopit;
|
||
char outmsg[1024];
|
||
strcpy(MyClient[myctr].hostname,fromhost);
|
||
strcpy(MyClient[myctr].name,token[0]);
|
||
MyClient[myctr].status = S_ACTIVE;
|
||
MyClient[myctr].lasttime = NOWTIME;
|
||
MyClient[myctr].umode = DCC_DEFAULT;
|
||
writeln(MyClient[myctr].fd,"Welcome to the Party Line\n");
|
||
sprintf(buf,"*** Known Usermodes: %s\n",USERMODES);
|
||
writeln(MyClient[myctr].fd,buf);
|
||
sprintf(buf,":%s PRIVMSG #uworld.floods :DCC %s %s %s\n",
|
||
CHANSVR,token[0],hostname,fromhost);
|
||
writeln(sevsck,buf);
|
||
sprintf(outmsg,"*** %s (%s) has joined the Party\n",
|
||
MyClient[myctr].name,MyClient[myctr].hostname);
|
||
DccGlobal(outmsg,DCC_ANY);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return MyClient[myctr].fd;
|
||
}
|
||
#endif
|
||
|
||
int DccWall()
|
||
{ int ctr,i;
|
||
char outmsg[1024];
|
||
|
||
if(!(MyClient[DccCtr].umode & DCC_WALLOPS))
|
||
{ writeln(MyClient[DccCtr].fd,
|
||
"*** You are not +w. Please set umode +w before you wallops\n");
|
||
return 1;
|
||
}
|
||
if(token[4])
|
||
{ sprintf(outmsg,"[%s]",token[0]);
|
||
for(i=4;token[i];i++)
|
||
{ strcat(outmsg," ");
|
||
strcat(outmsg,token[i]);
|
||
}
|
||
strcat(outmsg,"\n");
|
||
}
|
||
else return 0;
|
||
DccGlobal(outmsg,DCC_WALLOPS);
|
||
return 1;
|
||
}
|
||
|
||
int DccMessage(char *targ)
|
||
{ int ctr,i;
|
||
char outmsg[1024];
|
||
|
||
if(token[4] && token[5])
|
||
{ sprintf(outmsg,"*%s*",token[0]);
|
||
for(i=5;token[i];i++)
|
||
{ strcat(outmsg," ");
|
||
strcat(outmsg,token[i]);
|
||
}
|
||
strcat(outmsg,"\n");
|
||
}
|
||
else return 0;
|
||
for(ctr=0;ctr<MAXDCCONLINE;ctr++)
|
||
{
|
||
if((MyClient[ctr].status == S_ACTIVE) &&
|
||
(!strcasecmp(MyClient[ctr].name,targ)))
|
||
{ writeln(MyClient[ctr].fd,outmsg);
|
||
break;
|
||
}
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
int DccList()
|
||
{ int ctr;
|
||
int ct;
|
||
char outmsg[1024];
|
||
char tbuf[30];
|
||
|
||
ct=0;
|
||
strcpy(outmsg,"DLIST");
|
||
for(ctr=0;ctr<MAXDCCONLINE;ctr++)
|
||
{ if(MyClient[ctr].status == S_ACTIVE)
|
||
{
|
||
sprintf(tbuf," %s(%ld)",MyClient[ctr].name,NOWTIME-MyClient[ctr].lasttime);
|
||
strcat(outmsg,tbuf);
|
||
|
||
ct++;
|
||
if(ct>6)
|
||
{ strcat(outmsg,"\n");
|
||
writeln(MyClient[DccCtr].fd,outmsg);
|
||
strcpy(outmsg,"DLIST");
|
||
ct=0;
|
||
}
|
||
}
|
||
}
|
||
strcat(outmsg,"\n");
|
||
if(ct) writeln(MyClient[DccCtr].fd,outmsg);
|
||
return 1;
|
||
}
|
||
|
||
int DccWho(char *targ)
|
||
{ int ctr;
|
||
char outmsg[1024];
|
||
|
||
if(!token[4]) return 0;
|
||
for(ctr=0;ctr<MAXDCCONLINE;ctr++)
|
||
{ if(MyClient[ctr].status == S_ACTIVE)
|
||
{
|
||
if(!strcasecmp( targ,MyClient[ctr].name))
|
||
{ sprintf(outmsg,"DWHO %s is %s Idle %d\n",MyClient[ctr].name,
|
||
MyClient[ctr].hostname,NOWTIME-MyClient[ctr].lasttime);
|
||
writeln(MyClient[DccCtr].fd,outmsg);
|
||
}
|
||
}
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
|
||
int DccGlobal(char *buffer,int MODE)
|
||
{ int loopit;
|
||
for(loopit=0;loopit<MAXDCCONLINE;loopit++)
|
||
{ if((MyClient[loopit].status == S_ACTIVE) &&
|
||
(MyClient[loopit].umode & MODE))
|
||
{
|
||
writeln(MyClient[loopit].fd,buffer);
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int DccUmode(char *modes)
|
||
{
|
||
int flag=1; /* default to set */
|
||
char *pos,upos=0;
|
||
char unknown[1024];
|
||
|
||
if(!modes)
|
||
{ DccMode();
|
||
return 0;
|
||
}
|
||
|
||
pos=modes;
|
||
unknown[0]='\0';
|
||
|
||
for(;*pos;pos++)
|
||
{
|
||
if(*pos=='-') {flag=0; continue; }
|
||
if(*pos=='+') {flag=1; continue; }
|
||
switch(tolower(*pos))
|
||
{ case 'w':
|
||
if(flag)MyClient[DccCtr].umode |= DCC_WALLOPS;
|
||
else MyClient[DccCtr].umode &= ~DCC_WALLOPS;
|
||
break;
|
||
case 'a':
|
||
if(flag)MyClient[DccCtr].umode |= DCC_ANY;
|
||
else MyClient[DccCtr].umode &= ~DCC_ANY;
|
||
break;
|
||
case 't':
|
||
if(flag)MyClient[DccCtr].umode |= DCC_TSC;
|
||
else MyClient[DccCtr].umode &= ~DCC_TSC;
|
||
break;
|
||
case 'g':
|
||
if(flag)MyClient[DccCtr].umode |= DCC_GLN;
|
||
else MyClient[DccCtr].umode &= ~DCC_GLN;
|
||
break;
|
||
case 'c':
|
||
if(flag)MyClient[DccCtr].umode |= DCC_COMMAND;
|
||
else MyClient[DccCtr].umode &= ~DCC_COMMAND;
|
||
break;
|
||
case 'm':
|
||
if(flag)MyClient[DccCtr].umode |= DCC_MMG;
|
||
else MyClient[DccCtr].umode &= ~DCC_MMG;
|
||
break;
|
||
case 'l':
|
||
if(flag)MyClient[DccCtr].umode |= DCC_WALL;
|
||
else MyClient[DccCtr].umode &= ~DCC_WALL;
|
||
break;
|
||
default:
|
||
unknown[upos++]= *pos;
|
||
unknown[upos]='\0';
|
||
break;
|
||
}
|
||
}
|
||
if(unknown[0]!='\0')
|
||
{ sprintf(buf,"*** Unknown Umodes: %s\n",unknown);
|
||
writeln(MyClient[DccCtr].fd,buf);
|
||
}
|
||
DccMode();
|
||
return 0;
|
||
}
|
||
|
||
|
||
int DccMode()
|
||
{ char modes[10];
|
||
|
||
modes[0]='\0';
|
||
|
||
if( MyClient[DccCtr].umode & DCC_ANY) strcat(modes,"a");
|
||
if( MyClient[DccCtr].umode & DCC_WALLOPS) strcat(modes,"w");
|
||
if( MyClient[DccCtr].umode & DCC_GLN) strcat(modes,"g");
|
||
if( MyClient[DccCtr].umode & DCC_TSC) strcat(modes,"t");
|
||
if( MyClient[DccCtr].umode & DCC_COMMAND) strcat(modes,"c");
|
||
if( MyClient[DccCtr].umode & DCC_MMG) strcat(modes,"m");
|
||
if( MyClient[DccCtr].umode & DCC_WALL) strcat(modes,"l");
|
||
|
||
sprintf(buf,"*** Your Usermode is: %s\n",modes);
|
||
writeln(MyClient[DccCtr].fd,buf);
|
||
return 1;
|
||
}
|
||
|
||
int DccKill(char *name)
|
||
{ int loopit;
|
||
char mybuf[1024];
|
||
for(loopit=0;loopit<MAXDCCONLINE;loopit++)
|
||
{ if((MyClient[loopit].status == S_ACTIVE) &&
|
||
(!strcasecmp(MyClient[loopit].name,name)))
|
||
{ sprintf(mybuf,
|
||
"*** Your DCC PartyLine connection has been terminated by %s\n",
|
||
token[0]);
|
||
writeln(MyClient[loopit].fd,mybuf);
|
||
MyClient[loopit].status = S_CLOSING;
|
||
break;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|