/* (c) 2007 Christopher Olsen $Id: tuve.c,v 1.60 2008/10/07 12:59:56 reddawg Exp $ */ #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) { memset(&userConnection->data,0x0,1024); userConnection->recLen = sReadSocket(userConnection->fd,&userConnection->data,1024); if (userConnection->recLen <= 0) 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 *data2 = 0x0; char *data_tok = 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); data = strtok_r(userConnection->data,"\n",&data_tok); data2 = strtok_r(NULL,"\n",&data_tok); Head: if (data == 0x0) { data = data2; data2 = strtok_r(NULL,"\n",&data_tok); } cmd = data; if (cmd == NULL) { // MrOlsen 2017-11-17 TEMP return(0); } if (cmd[userConnection->recLen - 1] == '\n') cmd[userConnection->recLen - 1] = '\0'; if (cmd[userConnection->recLen - 2] == 13) cmd[userConnection->recLen - 2] = '\0'; if (strstr(cmd," ")) { cmd = strtok_r(cmd," ",&tok_last); data = strtok_r(NULL,"\n",&tok_last); tok_last = 0x0; writeLog(3,"DATA: (%s)CMD: [%s], Data: [%s]\n",userConnection->userInfo.username,cmd,data); } else writeLog(3,"DATA: (%s)CMD: [%s]\n",userConnection->userInfo.username,cmd); 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, "%s", nick); if (msg == 0x0) userConnection->userInfo.uid = time(NULL); 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."); } goto Tail; } 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(2,"Sent CROSSDOMAIN\n"); return(0x0); } else if (strcasecmp(cmd,"PONG!") == 0x0) { /* Command Checked Test And Approved */ userConnection->userInfo.pfailed = 0x0; goto Tail; } else if (strcasecmp(cmd,"CLIENT") == 0x0) { /* Verify Version */ if (data == 0x0) sSendData(userConnection,"CLIENT:1:Invalid CLIENT"); else if (atof(data) < MIN_VER) sSendData(userConnection,"CLIENT:1:You are running client version %4.2f, our current version is %4.2f. Please upgrade to get the latest features.",atof(data),MIN_VER); else { sSendData(userConnection,"CLIENT:0:SUCCESSFUL"); userConnection->userInfo.version = atof(data); } goto Tail; } else if (userConnection->userInfo.ident == 0x0) { /* Command Checked Tested And Approved */ sSendData(userConnection,"Please Auth"); goto Tail; } 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) goto Tail; if (chan[0] != '#') { tmpConnection = findNick(chan); if (tmpConnection != 0x0) { sSendData(tmpConnection,"MSG:%s:PRIVMSG:%s",userConnection->userInfo.username,msg); } else sSendData(userConnection,"MSG:%s:PRIVMSG:Is Not Available.",chan); } 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); tuveSendAllInChan(chan,userConnection,"MSG:%s:%s:%s",userConnection->userInfo.username,chan,buffer); } } } } else if (strcasecmp(cmd,"VIDC") == 0x0) { if (data != 0x0) { chan = strtok_r(data,":",&tok_last); msg = strtok_r(NULL,"\n",&tok_last); if (msg == 0x0) goto Tail; tmpConnection = findNick(chan); if (tmpConnection != 0x0) sSendData(tmpConnection,"VIDC:%s:%s",userConnection->userInfo.username,msg); else sSendData(tmpConnection,"MSG:%s:PRIVMSG:Is Not Available.",chan); } } else if (strcasecmp(cmd,"MODE") == 0x0) { if (data == 0x0) { sSendData(userConnection,"MODE:FAILED"); goto Tail; } chan = strtok_r(data,":",&tok_last); msg = strtok_r(NULL,"\n",&tok_last); if (msg == 0x0) goto Tail; tuveCMD_CMD(userConnection,chan,msg); } 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 known as %s",userConnection->userInfo.username,data); tuveSendAllInUsersChans(userConnection,output); sprintf(userConnection->userInfo.username, "%s", 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,":",&tok_last); nick = strtok_r(NULL,"\n",&tok_last); if (msg[0] == '0') { tuveSendAllInChan(chan,0x0,"LIVE:0:DONE"); if (tuveChanResume(chan) == 0x1) sSendData(userConnection,"MSG:TUveD:STATUS:Sorry Invalid Live Parameters"); } else { if (tuveChanLive(chan,msg,nick) == 0x1) sSendData(userConnection,"MSG:TUveD:STATUS:Sorry Invalid Live Parameters."); } } } else if (strcasecmp(cmd,"QUIT") == 0x0) { if (strlen(data) > 0) tuveDelUserChans(userConnection,data); else tuveDelUserChans(userConnection,"Leaving"); close(userConnection->fd); sRemoveConnection(userConnection->fd); } else { sSendData(userConnection,"invalid command"); writeLog(1,"Invalid CMD: [%s]\n",cmd); } Tail: if (data2 != 0x0) { data = 0x0; goto Head; } return(0x0); }