/*
(c) 2007 Christopher Olsen
$Id$
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include "tuved.h"
int tuveProcessData(myConnections_t *userConnection);
int tuveGetData(myConnections_t *userConnection) {
writeLog(2,"Getting Data\n");
memset(&userConnection->data,0x0,1024);
userConnection->recLen = sReadSocket(userConnection->fd,&userConnection->data,1024);
if (userConnection->recLen == 0x0)
return(-1);
userConnection->userInfo.pong = time(NULL); // Reset the pong time of the socket
tuveProcessData(userConnection);
return(0x0);
} /* End int tuveGetDatga(myConnections_t *); */
int tuveSendAll(const char *data,int fd) {
myConnections_t *tmpConnection = 0x0;
for (tmpConnection = connections;tmpConnection != 0x0;tmpConnection = tmpConnection->next) {
if (tmpConnection->fd != fd)
sSendData(tmpConnection,data);
}
return(0x0);
} /* End int tuveSendAll(const char *data,int fd); */
int tuveProcessData(myConnections_t *userConnection) {
char *chan = 0x0;
char *nick = 0x0;
char *cmd = 0x0;
char *msg = 0x0;
char *data = 0x0;
char *tok_last = 0x0;
char output[1280];
char buffer[1024];
myConnections_t *tmpConnection = 0x0;
memset(&output,0x0,1024);
memset(&buffer,0x0,1024);
assert(userConnection);
cmd = userConnection->data;
if (cmd[userConnection->recLen - 1] == '\n')
cmd[userConnection->recLen - 1] = '\0';
if (cmd[userConnection->recLen - 2] == 13)
cmd[userConnection->recLen - 2] = '\0';
writeLog(3,"DATA: (%s)[%s]\n",userConnection->userInfo.username,cmd);
if (strstr(userConnection->data," ")) {
cmd = strtok_r(userConnection->data," ",&tok_last);
data = strtok_r(NULL,"\n",&tok_last);
tok_last = 0x0;
}
if (!strcasecmp(cmd,"IDENT")) {
writeLog(2,"(ident)\n");
if (data != 0x0) {
tok_last = 0x0;
nick = strtok_r(data,":",&tok_last);
msg = strtok_r(NULL,"\n",&tok_last);
if (tuveVerifyNick(nick) == 0) {
sprintf(userConnection->userInfo.username,nick); //strtok_r(data,":",&tok_last));
if (msg == 0x0)
userConnection->userInfo.uid = time(NULL); //atoi(strtok_r(NULL,"\n",&tok_last));
else
userConnection->userInfo.uid = atoll(msg);
userConnection->userInfo.ident = 0x1;
sSendData(userConnection,"IDENT:0:Success");
}
else
sSendData(userConnection,"IDENT:1:Nick In Use.");
}
else {
sSendData(userConnection,"IDENT:1:Invalid Ident.");
}
return(0x0);
}
else if (strcasecmp(cmd,"<policy-file-request/>") == 0x0) {
/* Command Checked Tested And Approved */
sprintf(output,"<?xml version=\"1.0\"?>\n<cross-domain-policy>\n<allow-access-from domain=\"*\" to-ports=\"*\" />\n</cross-domain-policy>\n");
send(userConnection->fd,output,strlen(output)+1,MSG_NOSIGNAL);
writeLog(1,"Sent CROSSDOMAIN\n");
return(0x0);
}
else if (strcasecmp(cmd,"PONG!") == 0x0) {
/* Command Checked Test And Approved */
userConnection->userInfo.pfailed = 0x0;
return(0x0);
}
else if (strcasecmp(cmd,"CLIENT") == 0x0) {
/* Verify Version */
if (data == 0x0)
sSendData(userConnection,"CLIENT:1:Invalid CLIENT");
else if (atoi(data) < MIN_VER)
sSendData(userConnection,"CLIENT:1:You are running client version %i, our current version is %i. Please upgrade to get the latest features.",atoi(data),MIN_VER);
else
sSendData(userConnection,"CLIENT:0:SUCCESSFUL");
}
else if (userConnection->userInfo.ident == 0x0) {
/* Command Checked Tested And Approved */
sSendData(userConnection,"Please Auth");
return(0x0);
}
userConnection->userInfo.idle = time(NULL);
if (!strcasecmp(cmd,"LIST")) {
return(tuveChanList(userConnection));
}
else if (!strcasecmp(cmd,"JOIN")) {
/* Function Checked Tested And Approved */
if (data == 0x0) {
sSendData(userConnection,"JOIN:ERROR:Invalid Channel Information");
}
else if (!strstr(data,"#") || strlen(data) > MAX_CHAN_LEN)
sSendData(userConnection,"JOIN:ERROR:Invalid channel.");
else
tuveChanJoin(data,userConnection);
}
else if (strcasecmp(cmd,"MSG") == 0x0) {
if (data != 0x0) {
chan = strtok_r(data,":",&tok_last);
msg = strtok_r(NULL,"\n",&tok_last);
if (msg == 0x0)
return(0x0);
if (chan[0] != '#') {
if ((strlen(msg) > 2) && (msg[0] == '.' && msg[1] == 't' && msg[2] == 'v'))
tuveCMD_CMD(userConnection,chan,msg+3);
else {
tmpConnection = findNick(chan);
if (tmpConnection != 0x0) {
/*
sprintf(output,"MSG:%s:PRIVMSG:",userConnection->userInfo.username);
strcpy((char *)&output + strlen(output),msg);
output[strlen(output)+1] = '\n';
*/
//%s\n",userConnection->userInfo.username,msg);
sSendData(tmpConnection,"MSG:%s:PRIVMSG:%s",userConnection->userInfo.username,msg);
}
}
}
else if (tuveVerifyBan(chan,userConnection->userInfo.username) == 0x1) {
sprintf(output,"MSG:TUveD:%s:You can not send text to the channel.",chan);
sSendData(userConnection,output);
}
else if (msg != 0x0) {
if ((strlen(msg) > 2) && (msg[0] == '.' && msg[1] == 't' && msg[2] == 'v'))
tuveCMD_CMD(userConnection,chan,msg+3);
else {
strncpy(buffer,msg,1024);
//sprintf(output,"MSG:%s:%s:%s\n",userConnection->userInfo.username,chan,buffer);
tuveSendAllInChan(chan,userConnection,"MSG:%s:%s:%s",userConnection->userInfo.username,chan,buffer);
}
}
}
}
else if (strcasecmp(cmd,"EMOTE") == 0x0) {
if (data != 0x0) {
chan = strtok_r(data,":",&tok_last);
msg = strtok_r(NULL,"\n",&tok_last);
if (tuveVerifyBan(chan,userConnection->userInfo.username) == 0x1) {
sprintf(output,"MSG:TUveD:%s:You can not send text to the channel.",chan);
sSendData(userConnection,output);
}
else if (msg != 0x0) {
strncpy(buffer,msg,1024);
sprintf(output,"EMOTE:%s:%s:%s",userConnection->userInfo.username,chan,buffer);
tuveSendAllInChan(chan,userConnection,output);
}
}
}
else if (strcasecmp(cmd,"topic") == 0x0) {
if (data != 0x0) {
tok_last = 0x0;
chan = strtok_r(data,":",&tok_last);
msg = strtok_r(NULL,"\n",&tok_last);
if (tuveVerifyBan(chan,userConnection->userInfo.username) == 0x1) {
sSendData(userConnection,"MSG:TUveD:STATUS:You can not set topic to this channel.");
}
else {
tuveSetTopic(userConnection,chan,msg);
}
}
}
else if (strcasecmp(cmd,"NICK") == 0x0) {
if (data != 0x0) {
if (tuveVerifyNick(data) == 0x0) {
sprintf(output,"NICK:%s:%s",userConnection->userInfo.username,data);
sSendData(userConnection,output);
tuveSendAllInUsersChans(userConnection,output);
sprintf(output,"MSG:TUveD:STATUS:%s is now know as %s\n",userConnection->userInfo.username,data);
tuveSendAllInUsersChans(userConnection,output);
sprintf(userConnection->userInfo.username,data);
}
else
sSendData(userConnection,"MSG:TUveD:STATUS:Nick In Use");
}
else {
sSendData(userConnection,"MSG:TUveD:STATUS:Invalid Nick");
}
}
else if (strcasecmp(cmd,"KICK") == 0x0) {
tok_last = 0x0;
if (userConnection->userInfo.modes[USER_OVERLORD] != 1) {
sSendData(userConnection,"MSG:TUveD:KICK:You do not have permission to kick!");
}
else {
if (data == 0x0)
sSendData(userConnection,"KICK:Invalid Information");
else {
chan = strtok_r(data,":",&tok_last);
nick = strtok_r(NULL,":",&tok_last);
msg = strtok_r(NULL,"\n",&tok_last);
if ((chan != 0x0) && (nick != 0x0) && (msg != 0x0))
if (msg[0] != '\n')
tuveKick(userConnection,chan,nick,msg);
else
tuveKick(userConnection,chan,nick,"I'm Too Lame To Give A Good Reason!");
else
sSendData(userConnection,"KICK:Invalid Information.");
}
}
}
else if (strcasecmp(cmd,"VIDEO") == 0x0) {
if (data != 0x0) {
tok_last = 0x0;
chan = strtok_r(data,":",&tok_last);
msg = strtok_r(NULL,"\n",&tok_last);
if (msg == 0x0)
sSendData(userConnection,"MSG:TuveD:STATUS:Missing VID");
else
tuveBotSetVideo(chan,userConnection->userInfo.username,atoi(msg));
}
else
sSendData(userConnection,"MSG:TUveD:STATUS:Invalid VIDEO syntax.");
}
else if (strcasecmp(cmd,"PART") == 0x0) {
if (data != 0x0) {
if (tuveChanPart(data,userConnection) == 0x1) {
writeLog(0,"ERROR: Unable to remove user from channel: %s list\n",data);
sSendData(userConnection,"PART:Not In Chan");
}
}
else
sSendData(userConnection,"PART:Not In Chan");
}
else if (strcasecmp(cmd,"WHOIS") == 0x0) {
if (data != 0x0)
tuveWhois(userConnection,data);
}
else if (strcasecmp(cmd,"STATUS") == 0x0) {
tuveStatus(userConnection);
}
else if (strcasecmp(cmd,"BAN") == 0x0) {
if (data != 0x0) {
tok_last = 0x0;
chan = strtok_r(data,":",&tok_last);
nick = strtok_r(NULL,":",&tok_last);
msg = strtok_r(NULL,"\n",&tok_last);
if (msg != 0x0)
tuveBan(userConnection,chan,nick,atoi(msg));
else
tuveBan(userConnection,chan,nick,600);
}
}
else if (strcasecmp(cmd,"UNBAN") == 0x0) {
if (userConnection->userInfo.modes[USER_OVERLORD] != 1) {
sSendData(userConnection,"MSG:TUveD:STATUS:You do not have permission to unban.");
}
else if (data != 0x0) {
tok_last = 0x0;
chan = strtok_r(data,":",&tok_last);
nick = strtok_r(NULL,"\n",&tok_last);
tuveUnBan(chan,nick);
}
}
else if (strcasecmp(cmd,"QUEUE") == 0x0) {
if (data != 0x0) {
if (strcasecmp(data,"FULL") == 0x0)
userConnection->userInfo.queue = 1;
else
userConnection->userInfo.queue = 0;
}
}
else if (strcasecmp(cmd,"LIVE") == 0x0) {
if (data != 0x0) {
tok_last = 0x0;
chan = strtok_r(data,":",&tok_last);
msg = strtok_r(NULL,"\n",&tok_last);
if (msg[0] == '0') {
if (tuveChanResume(chan) == 0x1)
sSendData(userConnection,"MSG:TUveD:STATUS:Sorry Invalid Live Parameters");
}
else {
if (tuveChanLive(chan,msg) == 0x1)
sSendData(userConnection,"MSG:TUveD:STATUS:Sorry Invalid Live Parameters.");
}
}
}
else {
sSendData(userConnection,"invalid command");
writeLog(1,"Invalid CMD: [%s]\n",cmd);
}
return(0x0);
}