Files
uworld/socket.c
2023-12-22 22:53:54 -05:00

573 lines
14 KiB
C
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}