diff --git a/.gitignore b/.gitignore index 3d6bfd8..0b764f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.o *.core logs/*.log +bin diff --git a/Makefile b/Makefile index a5e4a8a..c728552 100644 --- a/Makefile +++ b/Makefile @@ -14,18 +14,20 @@ #Delete Program REMOVE = rm -f -#Objects -OBJS = lib.o mysql.o server.o nick.o botthread.o main.o socket.o tuve.o channel.o config.o +OBJS = src/lib.o src/mysql.o src/server.o src/nick.o src/botthread.o src/main.o src/socket.o src/tuve.o src/channel.o src/config.o LIBRARIES = -lthr -L/usr/local/lib/mysql -lmysqlclient -L/usr/local/lib -lconfig CFLAGS = -Wall -W -ggdb INCLUDES = -I/usr/local/include -# Link The Binary -$(BINARY) : $(OBJS) - $(CC) $(CFLAGS) -o $@ $(LIBRARIES) $(OBJS) +all: $(BINARY) # Compile the source files +$(BINARY): $(OBJS) +.if !exists(bin) + @mkdir bin +.endif + $(CC) $(CFLAGS) -o bin/$@ $(LIBRARIES) $(OBJS) .cc.o: $(CXX) $(CFLAGS) $(INCLUDES) -c -o $@ $< @@ -45,13 +47,12 @@ # Install install: cp tuved /usr/local/bin - if test -d /usr/local/etc/tuve; \ - then echo exists; \ - else mkdir /usr/local/etc/tuve; \ - fi - cp tuved.cfg /usr/local/etc/tuve +.if !exists(/usr/local/etc/tuve) + mkdir /usr/local/etc/tuve +.endif + cp extra/tuved.cfg /usr/local/etc/tuve cp extra/tuved /usr/local/etc/rc.d # Clean Up The junk clean: - $(REMOVE) $(OBJS) $(BINARY) *.core + $(REMOVE) $(OBJS) bin/$(BINARY) *.core diff --git a/botthread.c b/botthread.c deleted file mode 100644 index ccc765e..0000000 --- a/botthread.c +++ /dev/null @@ -1,579 +0,0 @@ -#include -#include -#include - -#include "tuved.h" - -int playCnt = 0; - -int nextSong(); -int chanMaint(); - -int tuveCMD_CMD(myConnections_t *userConnection,char *chan,char *data) { - char output[512]; - char dMS[2] = {'-','+'}; - char *cmd = 0x0; - char *cmdData = 0x0; - char *modeString = 0x0; - char *tmp = 0x0; - char *tmp2 = 0x0; - char *tok_last = 0x0; - tuveChanList_t *tmpChan = 0x0; - tuveUserList_t *tmpUser = 0x0; - MYSQL_RES *res = 0x0; - MYSQL_ROW row; - short dM = 0x0; - unsigned int i = 0x0; - - if (data == 0x0) - return(0x1); - - cmd = strtok_r(data," ",&tok_last); - cmdData = strtok_r(NULL,"\n",&tok_last); - - if (cmd == 0x0) - return(0x1); - - if (strcasecmp(cmd,"login") == 0x0) { - tok_last = 0x0; - tmp = strtok_r(cmdData," ",&tok_last); - tmp2 = strtok_r(NULL,"\n",&tok_last); - if ((tmp != 0x0) & (tmp2 != 0x0)) { - sprintf(output,"SELECT username,gid,uid FROM users WHERE username = '%s' AND password = '%s'",tmp,tmp2); - res = dbQuery(output,1); - if (res == 0x0) { - sSendData(userConnection,"MSG:TUveD:STATUS:Sorry I'm Having MySQL Troubles."); - } - else if (mysql_num_rows(res) == 1) { - sSendData(userConnection,"MSG:TUveD:%s:You have successfully logged in.",chan); - row = mysql_fetch_row(res); - sprintf(output,"INSERT INTO active (gid,uid,userid) VALUES(%s,%s,%lld)",row[1],row[2],userConnection->userInfo.uid); - dbQuery(output,0); - sSendData(findNick("TUveBOT"),"LOGIN:%s:%lld",userConnection->userInfo.username,userConnection->userInfo.uid); - if (atoi(row[1]) == 1) { - sprintf(output,"EMOTE:%s:STATUS:Is now an Evil Overlord!",userConnection->userInfo.username); - tuveSendAllInUsersChans(userConnection,output); - userConnection->userInfo.modes[USER_OVERLORD] = 1; - } - userConnection->userInfo.ident = 2; - } - else { - sSendData(userConnection,"MSG:TUveD:%s:You have failed login.",chan); - } - if (res != 0x0) - mysql_free_result(res); - } - } /* End login */ - else if (tuveFindChanLevel(chan,userConnection,0) == 0) { - sSendData(userConnection,"MSG:TUveD:STATUS:You do not have permission to set channel mode."); - return(0x0); - } /* Commands Stop Here If You Channel Level Isn't >= 1 */ - else if (strcasecmp(cmd,"pause") == 0x0) { - tuveSendAllInChan(chan,0x0,"PAUSE"); - } - else if (strcasecmp(cmd,"resume") == 0x0) { - tuveSendAllInChan(chan,0x0,"RESUME\n"); - } - else if (strcasecmp(cmd,"skip") == 0x0) { - if (cmdData != 0x0) - tmpChan = findChan(cmdData); - else - tmpChan = findChan(chan); - if (tmpChan != 0x0) { - if (tmpChan->vidClass != 7) { - tmpChan->videoEnd = 0x0; - tmpChan->count = MAX_COUNT; - } - } - } - else if (strcasecmp(cmd,"mode") == 0x0) { - tmpChan = findChan(chan); - - if (cmdData != 0x0) { - tok_last = 0x0; - modeString = strtok_r(cmdData," ",&tok_last); - - if (modeString[0] == '-') - dM = 0; - else if (modeString[0] == '+') - dM = 1; - else { - sSendData(userConnection,"MSG:TUveD:STATUS:Invalid Mode String."); - return(0x0); - } - - - for (i = 1;i < strlen(modeString);i++) { - switch(modeString[i]) { - case '-': - dM = 0; - break; - case '+': - dM = 1; - break; - case 'o': - case 'O': - tmp = strtok_r(NULL," ",&tok_last); - if (tmp != 0x0) { - if (tuveChanOp(chan,tmp,dM) == 0x0) { - sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cO %s",chan,userConnection->userInfo.username,dMS[dM],tmp); - tuveSendAllInChan(chan,0x0,output); - } - } - else { - sSendData(userConnection,"MSG:TUveD:STATUS:Missing +O Opperators"); - } - break; - case 'a': - case 'A': - tmp = strtok_r(NULL," ",&tok_last); - if (tmp != 0x0) { - tmpChan->modes[CHAN_RATING] = atoi(tmp); - sprintf(output,"MODE:%s:A:%i",tmpChan->channel,tmpChan->modes[CHAN_RATING]); - tuveSendAllInChan(chan,0x0,output); - } - break; - case 'c': - case 'C': - tmp = strtok_r(NULL," ",&tok_last); - if (tmp != 0x0) { - tmpChan->modes[CHAN_CLASS] = atoi(tmp); - sprintf(output,"MODE:%s:C:%i",tmpChan->channel,tmpChan->modes[CHAN_CLASS]); - tuveSendAllInChan(chan,0x0,output); - } - break; - case 'e': - case 'E': - if (dM == 0) { - tmpChan->modes[CHAN_EXCLUSIVE] = 0; - sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cExclusive",chan,userConnection->userInfo.username,dMS[dM]); - tuveSendAllInChan(chan,0x0,output); - } - else { - sprintf(output,"SELECT oid FROM channels WHERE channel LIKE '%s'",tmpChan->channel); - res = dbQuery(output,1); - if (res == 0x0) { - sprintf(output,"MSG:TUveD:%s:Sorry I'm having SQL troubles today.",tmpChan->channel); - tuveSendAllInChan(tmpChan->channel,0x0,output); - } - else if (mysql_num_rows(res) == 0x0) { - sprintf(output,"MSG:TUveD:%s:Sorry this channel is not registered.",tmpChan->channel); - tuveSendAllInChan(tmpChan->channel,0x0,output); - } - else { - row = mysql_fetch_row(res); - tmpChan->modes[CHAN_EXCLUSIVE] = 1; - tmpChan->oid = atoi(row[0]); - sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cExclusive",chan,userConnection->userInfo.username,dMS[1]); - tuveSendAllInChan(chan,0x0,output); - } - if (res != 0x0) - mysql_free_result(res); - } - sprintf(output,"MODE:%s:E:%i",tmpChan->channel,tmpChan->modes[CHAN_EXCLUSIVE]); - tuveSendAllInChan(chan,0x0,output); - break; - case 'r': - case 'R': - tmpChan->modes[CHAN_RANDOM] = dM; - sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cRandom",chan,userConnection->userInfo.username,dMS[dM]); - tuveSendAllInChan(chan,0x0,output); - sprintf(output,"MODE:%s:R:%i",tmpChan->channel,dM); - tuveSendAllInChan(chan,0x0,output); - break; - case 'q': - case 'Q': - tmpChan->modes[CHAN_QUEUE] = dM; - sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cQueue",chan,userConnection->userInfo.username,dMS[dM]); - tuveSendAllInChan(chan,0x0,output); - sprintf(output,"MODE:%s:Q:%i",tmpChan->channel,dM); - tuveSendAllInChan(chan,0x0,output); - break; - case 'X': - tmpChan->modes[CHAN_NOADS] = dM; - sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cNo Advertisements",chan,userConnection->userInfo.username,dMS[dM]); - tuveSendAllInChan(chan,0x0,output); - sprintf(output,"MODE:%s:X:%i",tmpChan->channel,dM); - tuveSendAllInChan(chan,0x0,output); - break; - case 't': - case 'T': - if (dM == 1) { - tmp = strtok_r(NULL," ",&tok_last); - if (tmp != 0x0) { - tmpChan->modes[CHAN_TIME] = dM; - tmpChan->maxTime = atoi(tmp); - sprintf(output,"MSG:TUveD:%s:%s Sets Mode +Time Limit %s",chan,userConnection->userInfo.username,tmp); - tuveSendAllInChan(chan,0x0,output); - sprintf(output,"MODE:%s:T:%i:%s",tmpChan->channel,dM,tmp); - tuveSendAllInChan(chan,0x0,output); - } - } - else { - tmpChan->modes[CHAN_TIME] = dM; - sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cTime Limit",chan,userConnection->userInfo.username,dMS[dM]); - tuveSendAllInChan(chan,0x0,output); - sprintf(output,"MODE:%s:T:%i",tmpChan->channel,dM); - tuveSendAllInChan(chan,0x0,output); - } - break; - case 'S': - if (dM == 0x1) { - for (tmpUser = tmpChan->users;tmpUser != 0x0;tmpUser = tmpUser->next) { - if (tmpUser->user == userConnection) { - tmpChan->nextUser = tmpUser; - } - } - } - else - tmpChan->nextUser = tmpChan->users; - - tmpChan->modes[CHAN_SCHEDULED] = dM; - sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cScheduled",chan,userConnection->userInfo.username,dMS[dM]); - tuveSendAllInChan(chan,0x0,output); - sprintf(output,"MODE:%s:S:%i",tmpChan->channel,dM); - tuveSendAllInChan(chan,0x0,output); - break; - default: - sSendData(userConnection,"MSG:TUveD:STATUS:Invalid Channel Mode"); - break; - } - } - - - } - } - else if (strcasecmp(cmd,"queue") == 0x0) { - tmpChan = findChan(chan); - if (tmpChan == 0x0) - return(0x0); - sprintf(output,"MSG:TUveD:%s:Queue Order - ",userConnection->userInfo.username); - for (tmpUser = tmpChan->users;tmpUser != 0x0;tmpUser = tmpUser->next) { - if (tmpUser == tmpChan->nextUser) - sprintf(output,"%s(%s),",output,tmpUser->user->userInfo.username); - else if (tmpUser == tmpChan->nextUser->next) - sprintf(output,"%s[%s],",output,tmpUser->user->userInfo.username); - else - sprintf(output,"%s%s,",output,tmpUser->user->userInfo.username); - } - sSendData(userConnection,output); - } - else if (strcasecmp(cmd,"random") == 0x0) { - tmpChan = findChan(chan); - if (tmpChan == 0x0) - return(0x0); - if ((tmpChan->modes[CHAN_LIVE] == 0x1) || (tmpChan->vidClass == 7)) - return(0x0); - - sprintf(output,"SELECT artist,title,file,length,vid,classification,rating FROM videos WHERE status = 0 AND rating <= %i",tmpChan->modes[CHAN_RATING]); - if (tmpChan->modes[CHAN_EXCLUSIVE]) - sprintf(output,"%s AND oid = %i",output,tmpChan->modes[CHAN_EXCLUSIVE]); - if (tmpChan->modes[CHAN_CLASS]) - sprintf(output,"%s AND classification = %i",output,tmpChan->modes[CHAN_CLASS]); - - res = dbQuery(output,1); - if (res == 0x0) { - sprintf(output,"MSG:TUveD:%s:Sorry I'm Have SQL Troubles Today.",chan); - tuveSendAllInChan(chan,0x0,output); - } - else if (mysql_num_rows(res) == 0x0) { - sprintf(output,"MSG:TUveD:%s:Sorry There Are No Videos Available At The Current Channel Settings.",chan); - tuveSendAllInChan(chan,0x0,output); - } - else { - mysql_data_seek(res,(random() % mysql_num_rows(res))); - row = mysql_fetch_row(res); - //sprintf(output,"UPDATE videos SET count = %i WHERE vid = %s",atoi(row[7])+1,row[4]); - //dbQuery(output,0); - tuveBotSetSong(chan,userConnection->userInfo.username,row[0],row[1],atoi(row[3]),row[2],atoi(row[5]),atoi(row[6]),atoi(row[4])); - } - if (res != 0x0) - mysql_free_result(res); - } - else if (strcasecmp(cmd,"rotatelog") == 0x0) { - writeLog(0,"Rotating Log File"); - fclose(logFile); - sprintf(logFileName,"./logs/tuved.%i.log",time(NULL)); - logFile = fopen(logFileName,"a"); - writeLog(0,"Log Rotated"); - } - else if (strcasecmp(cmd,"nextuser") == 0x0) { - sprintf(output,"MSG:TUveD:%s:The Next User is %s",chan,tmpChan->nextUser->user->userInfo.username); - tuveSendAllInChan(chan,0x0,output); - } - return(0x0); - } - -void *tuveCMD_Thread(void *threadid) { - int tid; - MYSQL_RES *res = 0x0; - MYSQL_ROW row; - - tid = (int)threadid; - writeLog(0,"Starting Bot Thread: [%d]\n", tid); - - res = dbQuery("SELECT count FROM videos ORDER BY count ASC LIMIT 1",1); - row = mysql_fetch_row(res); - if (row) - playCnt = atoi(row[0]); - mysql_free_result(res); - - while (1) { - sleep(5); - nextSong(); - chanMaint(); - } - pthread_exit(NULL); - } /* End tuveCMD_Thread() */ - -int chanMaint() { - tuveChanList_t *tmpChans; - time_t curTime = time(NULL); - int i = 0x0; - - pthread_mutex_lock(&chanMutex); - for (tmpChans = channels;tmpChans != 0x0;tmpChans = tmpChans->next) { - for (i = 0;i < CHAN_MAX_BANS;i++) { - if ((tmpChans->bans[i][0] != 0x0) && (tmpChans->bans[i][1] < curTime)) - tmpChans->bans[i][0] = 0x0; - } - } - pthread_mutex_unlock(&chanMutex); - return(0x0); - } - -int tuveBotSetVideo(char *chan,char *nick,int vid) { - MYSQL_RES *res = 0x0; - MYSQL_ROW row; - char output[256]; - - sprintf(output,"SELECT artist,title,file,length,classification,rating,count FROM videos WHERE vid = %i",vid); - - res = dbQuery(output,1); - - if ((res == 0x0) || (mysql_num_rows(res) == 0x0)) { - sprintf(output,"MSG:TUveD:%s:Sorry I'm Have SQL Troubles Today.",chan); - tuveSendAllInChan(chan,0x0,output); - } - else { - row = mysql_fetch_row(res); - sprintf(output,"UPDATE videos SET count = %i WHERE vid = %i",atoi(row[6])+1,vid); - dbQuery(output,0); - tuveBotSetSong(chan,nick,row[0],row[1],atoi(row[3]),row[2],atoi(row[4]),atoi(row[5]),vid); - } - - if (res != 0x0) - mysql_free_result(res); - return(0x0); - } - -int -tuveBotSetSong(char *channel,char *nick,char *artist,char *title,int length,char *file,int class,int rating,int vid) { - tuveChanList_t *tmpChan; - - char output[1024]; - int min, sec; - - songCount++; - playCount += length; - - tmpChan = findChan(channel); - - if (tmpChan->modes[CHAN_SCHEDULED] == 0x1) - goto jmpAhd; - - if (tmpChan->modes[CHAN_TIME] == 0x1) { - if (length > tmpChan->maxTime) { - return(0x0); - } - } - if (tmpChan->modes[CHAN_RATING] < rating) - return(0x0); - - if ((tmpChan->modes[CHAN_CLASS] != class) && (tmpChan->modes[CHAN_CLASS] != 0x0) && (class != 7)) - return(0x0); - - jmpAhd: - - tmpChan->comDelay -= length; - tmpChan->vidClass = class; - - min = length / 60; - sec = length % 60; - - tmpChan->videoTime = length; - tmpChan->videoEnd = length + time(NULL) + VIDE_PAD_TIME; - tmpChan->vid = vid; - sprintf(tmpChan->videoFile,file); - if (nick[strlen(nick)-1] == 's') - sprintf(tmpChan->videoChanTitle,"%s' Pick -> [%s - %s]",nick,vid,artist,title); - else - sprintf(tmpChan->videoChanTitle,"%s's Pick -> [%s - %s]",nick,vid,artist,title); - sprintf(tmpChan->videoTitle,"%s - %s",artist,title); - - sprintf(output,"CURPOS:%s:0:%s:%s:%i:%i",tmpChan->channel,file,tmpChan->videoTitle,length,vid); - writeLog(0,"[%s][%s]\n",output,channel); - tuveSendAllInChan(channel,0x0,output); - - sprintf(output,"MSG:TUveD:%s:Playing %s (%d:%.2d)",channel,tmpChan->videoChanTitle,min,sec); - tuveSendAllInChan(channel,0x0,output); -/* - - if (tmpChan->count != -1) { - if (tmpChan->nextUser != 0x0) - tmpChan->nextUser = tmpChan->nextUser->next; - if (tmpChan->nextUser == 0x0) - tmpChan->nextUser = tmpChan->users; - } -*/ - - tmpChan->count = MAX_COUNT; - - return(0x0); - } // tuveBotSetSong() - -int nextSong() { - char output[1024]; - tuveChanList_t *tmpChans; - MYSQL_RES *res = 0x0; - MYSQL_ROW row; - time_t curTime; - short lC; - - curTime = time(NULL); - - pthread_mutex_lock(&chanMutex); - - for (tmpChans = channels;tmpChans != 0x0;tmpChans = tmpChans->next) { - if ((tmpChans->modes[CHAN_LIVE] == 0x0) && (tmpChans->videoEnd < curTime)) { - /* Set point to starting user */ - - findUser: - if (tmpChans->modes[CHAN_SCHEDULED] == 0x1) - goto gotUser; - - if ((tmpChans->modes[CHAN_NOADS] == 0) && (tmpChans->comDelay <= 0)) - goto getCommercial; - - - //if (tmpChans->modes[CHAN_QUEUE] == 0x0) /* If Channel Has Queues Disabled Jump Right To Random */ - // goto getRandom; - - if (tmpChans->count == MAX_COUNT) { - lC = 0; - while (lC <= tmpChans->userCount) { - /* Reset Chan Counter */ - tmpChans->count = 0x0; - - if (tmpChans->nextUser == 0x0) - goto getRandom; - - tmpChans->nextUser = tmpChans->nextUser->next; - - /* Make sure we didn't go beyond the list */ - if (tmpChans->nextUser == 0x0) - tmpChans->nextUser = tmpChans->users; - - if (tmpChans->nextUser == 0x0) - goto sE; - - if (((tmpChans->modes[CHAN_QUEUE] == 0x0) && (tmpChans->nextUser->chanLevel >= 1)) || (tmpChans->modes[CHAN_QUEUE] == 0x1)) - if (tmpChans->nextUser->user->userInfo.queue == 0x1) - goto gotUser; - - lC++; - } - } - else if (tmpChans->nextUser != 0x0) - goto gotUser; - - - /* Find A Random Song */ - getRandom: - if (tmpChans->modes[CHAN_RANDOM] == 0x1) { - sprintf(output,"SELECT artist,title,file,length,vid,classification,rating,count,random_count FROM videos WHERE status = 0 AND rating <= %i",tmpChans->modes[CHAN_RATING]); - if (tmpChans->modes[CHAN_EXCLUSIVE]) - sprintf(output,"%s AND oid = %i",output,tmpChans->oid); //tmpChans->modes[CHAN_EXCLUSIVE]); - if (tmpChans->modes[CHAN_CLASS]) - sprintf(output,"%s AND classification = %i",output,tmpChans->modes[CHAN_CLASS]); - - sprintf(output,"%s ORDER BY random_count ASC, RAND() LIMIT 1", output); - - res = dbQuery(output,1); - if (res == 0x0) { - sprintf(output,"MSG:TUveD:%s:Sorry I'm Having SQL Troubles Today.",tmpChans->channel); - tuveSendAllInChan(tmpChans->channel,0x0,output); - } - else if (mysql_num_rows(res) == 0x0) { - sprintf(output,"MSG:TUveD:%s:Sorry Videos Matching The Channels Settings.",tmpChans->channel); - tuveSendAllInChan(tmpChans->channel,0x0,output); - } - else { - //mysql_data_seek(res,(random() % mysql_num_rows(res))); - row = mysql_fetch_row(res); - sprintf(output,"UPDATE videos SET random_count = %i WHERE vid = %s\n",atoi(row[8])+1,row[4]); - dbQuery(output,0); - tmpChans->count = MAX_COUNT; - tuveBotSetSong(tmpChans->channel,"TUveD",row[0],row[1],atoi(row[3]),row[2],atoi(row[5]),atoi(row[6]),atoi(row[4])); - } - if (res != 0x0) - mysql_free_result(res); - } - goto sE; - - getCommercial: - tmpChans->comDelay = COM_DELAY; - - getComAgain: - sprintf(output,"SELECT artist,title,file,length,vid,classification,rating,count FROM videos WHERE rating <= %i AND classification = 7 AND count <= %i",tmpChans->modes[CHAN_RATING],playCnt); - res = dbQuery(output,1); - - if (res == 0x0) { - sprintf(output,"MSG:TUveD:%s:Sorry I'm Having SQL Troubles Today.",tmpChans->channel); - tuveSendAllInChan(tmpChans->channel,0x0,output); - } - else if (mysql_num_rows(res) == 0x0) { - playCnt++; - mysql_free_result(res); - goto getComAgain; - } - else { - mysql_data_seek(res,(random() % mysql_num_rows(res))); - row = mysql_fetch_row(res); - sprintf(output,"UPDATE videos SET count = %i WHERE vid = %s\n",atoi(row[7])+1,row[4]); - dbQuery(output,0); - tmpChans->count = MAX_COUNT; - tuveBotSetSong(tmpChans->channel,"TUveD",row[0],row[1],atoi(row[3]),row[2],atoi(row[5]),atoi(row[6]),atoi(row[4])); - } - if (res != 0x0) - mysql_free_result(res); - goto sE; - - - gotUser: - if (tmpChans->nextUser->user->userInfo.queue == 0x1) { - if (((tmpChans->modes[CHAN_QUEUE] == 0x0) && (tmpChans->nextUser->chanLevel >= 1)) || (tmpChans->modes[CHAN_QUEUE] == 0x1)) { - sSendData(tmpChans->nextUser->user,"GETVIDEO"); - writeLog(0,"Need To Find Next Song For: %s, From User: %s\n",tmpChans->channel,tmpChans->nextUser->user->userInfo.username); - tmpChans->count++; - } - else if (tmpChans->modes[CHAN_SCHEDULED] == 0) { - tmpChans->count = MAX_COUNT; - goto findUser; - } - } - else if (tmpChans->modes[CHAN_SCHEDULED] == 0) { - tmpChans->count = MAX_COUNT; - goto findUser; - } - - sE: - asm("nop"); - } - } - - pthread_mutex_unlock(&chanMutex); - - return(0x0); - } /* End nextSong() */ - diff --git a/channel.c b/channel.c deleted file mode 100644 index fa1953b..0000000 --- a/channel.c +++ /dev/null @@ -1,758 +0,0 @@ -/* - (c) 2007 Christopher Olsen - $Id: channel.c,v 1.65 2009/02/18 19:37:34 reddawg Exp $ -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "tuved.h" - -tuveChanList_t *channels = 0x0; - -tuveChanList_t *addChan(const char *channel); - -/* - * This function will send the current channel list to the user specified w/ userConnection - * Information provided to that user is channel,user count,current song - * - * We traverse the channel list however there is no need to lock it because the other - * thread just reads this list and does not modify it. - * - */ -int tuveChanList(myConnections_t *userConnection) { - char data[512]; - tuveChanList_t *tmpChan = 0x0; - - /* The first line is header information for the data set */ - sSendData(userConnection,"LIST:Channel:users:Topic"); - - for (tmpChan = channels;tmpChan != 0x0;tmpChan = tmpChan->next) { - sprintf(data,"LIST:%s:%i:%s:%s",tmpChan->channel,tmpChan->userCount,tmpChan->topic,tmpChan->videoTitle); - sSendData(userConnection,data); - } - - return(0x0); - } /* End tuveChanList */ - -int tuveChanPart(const char *channel,myConnections_t *userConnection) { - char output[512]; - short inChan = 0x0; - - if (tuveRemoveFromChanList(channel,userConnection) == 0x1) { - writeLog(0,"ERROR: Can not remove %s from %s\n",userConnection->userInfo.username,channel); - inChan = 1; - } - if (tuveDelChan(channel,userConnection) == 0x1) { - writeLog(0,"ERROR: Can not remove %s from %s's List\n",channel,userConnection->userInfo.username); - inChan = 1; - } - - if (inChan == 0x0) { - sprintf(output,"MSG:TUveD:%s:%s Part (Left Channel)",channel,userConnection->userInfo.username); - tuveSendAllInChan(channel,0x0,output); - sprintf(output,"PART:%s:%s",channel,userConnection->userInfo.username); - tuveSendAllInChan(channel,0x0,output); - return(0x0); - } - - return(0x1); - } /* End tuveChanPart(); */ - -int tuveChanLive(const char *channel,const char *stream,const char *location) { - tuveChanList_t *tmpChan = 0x0; - char output[256]; - - if (stream == 0x0) - return(0x1); - - /* Find The Channel */ - tmpChan = findChan(channel); - if (tmpChan == 0x0) - return(0x1); - - strcpy(tmpChan->liveStream,stream); - - tmpChan->modes[CHAN_LIVE] = 0x1; - - //sprintf(output,"CURPOS:%s:-1:%s:Live Stream:0:0",tmpChan->channel,stream); - sprintf(output,"LIVE:%s:%s",location,stream); - tuveSendAllInChan(channel,0x0,output); - return(0x0); - } /* End int tuveChanLive(channel,stream) */ - -int tuveChanResume(const char *channel) { - char output[256]; - tuveChanList_t *tmpChan = 0x0; - tmpChan = findChan(channel); - - if (tmpChan == 0x0) - return(0x1); - - tmpChan->modes[CHAN_LIVE] = 0x0; - - sprintf(output,"CURPOS:%s:%i:%s:%s:%i:%i",tmpChan->channel,tmpChan->videoTime - (tmpChan->videoEnd - (time(NULL) + VIDE_PAD_TIME)),tmpChan->videoFile,tmpChan->videoTitle,tmpChan->videoTime,tmpChan->vid); - tuveSendAllInChan(channel,0x0,output); - return(0x0); - } - -/* - * Joins A User To A Channel - */ -int -tuveChanJoin(const char *channel,myConnections_t *userConnection) { - char output[256]; - tuveChanList_t *tmpChan = 0x0; - int min, sec; - int i = 0x0; - - tmpChan = findChan(channel); - - if (tmpChan != 0x0) { - for (i = 0x0;i < CHAN_MAX_BANS;i++) { - if (tmpChan->bans[i][0] == userConnection->userInfo.uid) { - sprintf(output,"MSG:TUveD:%s:You are banned from %s",channel,channel); - sSendData(userConnection,output); - return(0x1); - } - } - } - - if (tuveAddChanToUser(channel,userConnection) != 0x0) return(0x1); - - /* Send JOIN to all users in the channel */ - sprintf(output,"JOIN:%s:%s:%lld",channel,userConnection->userInfo.username,userConnection->userInfo.uid); - tuveSendAllInChan(channel,userConnection,output); - - tmpChan = findChan(channel); - assert(tmpChan); - - if (tmpChan->modes[CHAN_LIVE] == 1) { - //sSendData(userConnection,"CURPOS:%s:-1:%s:Live Stream:0:0",tmpChan->channel,tmpChan->liveStream); - sSendData(userConnection,"LIVE:1:%s\n",tmpChan->liveStream); - } - else { - sSendData(userConnection,"CURPOS:%s:%i:%s:%s:%i:%i",tmpChan->channel,tmpChan->videoTime - (tmpChan->videoEnd - (time(NULL) + VIDE_PAD_TIME)),tmpChan->videoFile,tmpChan->videoTitle,tmpChan->videoTime,tmpChan->vid); - - min = tmpChan->videoTime / 60; - sec = tmpChan->videoTime % 60; - - sSendData(userConnection,"MSG:TUveD:%s:Playing %s (%i:%.2i)",channel,tmpChan->videoChanTitle,min,sec); - } - - /* Notify people in the channel that someone has joined */ - sprintf(output,"MSG:TUveD:%s:%s (%s) has joined the channel.",channel,userConnection->userInfo.username,userConnection->host); - tuveSendAllInChan(channel,userConnection,output); - - return(0x0); - } - -int tuveDelUserChans(myConnections_t *userConnection,char *msg) { - tuveUserChans_t *tmpChan = 0x0; - tuveUserChans_t *tmpChan2 = 0x0; - - tmpChan = userConnection->userInfo.chans; - tmpChan2 = tmpChan; - - for (;tmpChan != 0x0;tmpChan = tmpChan->next) { - tuveSendAllInChan(tmpChan->channel,userConnection,"MSG:TUveD:%s:%s Quit (%s)",tmpChan->channel,userConnection->userInfo.username,msg); - tuveSendAllInChan(tmpChan->channel,userConnection,"PART:%s:%s",tmpChan->channel,userConnection->userInfo.username); - tuveRemoveFromChanList(tmpChan->channel,userConnection); - free(tmpChan2); - tmpChan2 = tmpChan->next; - } - - if (tmpChan2 != 0x0) { - free(tmpChan2); - } - - return(0x0); - } - -int tuveAddChanToUser(const char *channel,myConnections_t *userConnection) { - tuveUserChans_t *tmpChan = 0x0; - - if (userConnection->userInfo.chans == 0x0) { - userConnection->userInfo.chans = (tuveUserChans_t *)calloc(1,sizeof(tuveUserChans_t)); - userConnection->userInfo.chans->prev = 0x0; - userConnection->userInfo.chans->next = 0x0; - sprintf(userConnection->userInfo.chans->channel,channel); - } - else { - tmpChan = (tuveUserChans_t *)calloc(1,sizeof(tuveUserChans_t)); - tmpChan->prev = 0x0; - sprintf(tmpChan->channel,channel); - tmpChan->next = userConnection->userInfo.chans; - userConnection->userInfo.chans->prev = tmpChan; - userConnection->userInfo.chans = tmpChan; - } - - tuveAddToChanList(channel,userConnection); - - return(0x0); - } - -int tuveDelChan(const char *channel,myConnections_t *userConnection) { - tuveUserChans_t *tmpChan = 0x0; - - if (channel == 0x0) - return(0x1); - - for (tmpChan = userConnection->userInfo.chans;tmpChan != 0x0;tmpChan = tmpChan->next) { - if (!strcasecmp(tmpChan->channel,channel)) { - writeLog(2,"Found %s On %s And Removed\n",tmpChan->channel,userConnection->userInfo.username); - if (tmpChan->prev != 0x0) - tmpChan->prev->next = tmpChan->next; - else - userConnection->userInfo.chans = tmpChan->next; - if (tmpChan->next != 0x0) - tmpChan->next->prev = tmpChan->prev; - free(tmpChan); - return(0x0); - } - } - return(0x1); - } - -int tuveRemoveFromChanList(const char *channel,myConnections_t *userConnection) { - tuveChanList_t *tmpChannel = 0x0; - tuveUserList_t *tmpUsers = 0x0; - - tmpChannel = findChan(channel); - - if (tmpChannel == 0x0) { - writeLog(1,"tuveRemoveFromChanList: findChan failed!\n"); - return(0x1); - } - - tmpUsers = tmpChannel->users; - - writeLog(2,"Freeing User From Chan: %s\n",channel); - - pthread_mutex_lock(&chanMutex); - - for (;tmpUsers != 0x0;tmpUsers = tmpUsers->next) { - if (!strcasecmp(tmpUsers->user->userInfo.username,userConnection->userInfo.username)) { - writeLog(3,"Found and removed user: %s\n",tmpUsers->user->userInfo.username); - - if (tmpUsers->prev != 0x0) - tmpUsers->prev->next = tmpUsers->next; - else - tmpChannel->users = tmpUsers->next; - - if (tmpUsers->next != 0x0) - tmpUsers->next->prev = tmpUsers->prev; - -/* Undo Live - if (tmpChannel->modes[CHAN_LIVE] != 0) && (tmpChannel->d -*/ - - if (tmpChannel->nextUser == tmpUsers) { - if (tmpChannel->modes[CHAN_SCHEDULED] == 1) - tmpChannel->modes[CHAN_SCHEDULED] = 0; - - if (tmpUsers->next != 0x0) - tmpChannel->nextUser = tmpUsers->next; - else if (tmpChannel->users != 0x0) - tmpChannel->nextUser = tmpChannel->users; - else - tmpChannel->nextUser = 0x0; - } - tmpChannel->count = 0x0; - - tmpChannel->userCount--; - - free(tmpUsers); - writeLog(3,"User Freed\n"); - - if (tmpChannel->users == 0x0) { - writeLog(3,"Channel %s Has No More Users Freeing.\n",tmpChannel->channel); - - if (tmpChannel->prev != 0x0) - tmpChannel->prev->next = tmpChannel->next; - else - channels = tmpChannel->next; - - if (tmpChannel->next != 0x0) - tmpChannel->next->prev = tmpChannel->prev; - - channelCount--; - free(tmpChannel); - - writeLog(3,"Channel Freed.\n"); - } - pthread_mutex_unlock(&chanMutex); - return(0x0); - } - } - - pthread_mutex_unlock(&chanMutex); - return(0x1); - } - -int -tuveAddToChanList(const char *channel,myConnections_t *userConnection) { - tuveChanList_t *tmpChannel = 0x0; - tuveUserList_t *tmpUser = 0x0; - - char output[1024]; - char nick[MAX_USER_LEN + 1]; - - int len = 0; - - tmpChannel = findChan(channel); - - // tmpChannel is okay to be null here - - if (tmpChannel == 0x0) { - writeLog(2,"Channel %s does not exist creating now.\n",channel); - tmpChannel = addChan(channel); - } - - for (tmpUser = tmpChannel->users;tmpUser != 0x0;tmpUser = tmpUser->next) { - if (!strcasecmp(tmpUser->user->userInfo.username,userConnection->userInfo.username)) { - writeLog(2,"User: %s already in channel %s\n",userConnection->userInfo.username,channel); - return(0x0); - } - } - - tmpUser = (tuveUserList_t *)calloc(1,sizeof(tuveUserList_t)); - - tmpUser->user = userConnection; - tmpUser->prev = 0x0; - - pthread_mutex_lock(&chanMutex); - - if (tmpChannel->users == 0x0) { - tmpUser->next = 0x0; - tmpUser->chanLevel = 0x1; - tmpChannel->users = tmpUser; - } - else { - tmpUser->next = tmpChannel->users; - tmpUser->chanLevel = 0x0; - tmpChannel->users->prev = tmpUser; - tmpChannel->users = tmpUser; - } - - if (tmpChannel->nextUser == 0x0) { - tmpChannel->nextUser = tmpUser; - tmpChannel->count = 0x0; - } - - tmpChannel->userCount++; - - memset(output,0x0,256); - - /* Send the new user the channel list */ - for (tmpUser = tmpChannel->users;tmpUser != 0x0;tmpUser = tmpUser->next) { - if (tmpUser->chanLevel == 0) - strcpy(nick,tmpUser->user->userInfo.username); - else - sprintf(nick,"&%s",tmpUser->user->userInfo.username); - - if (strlen(output) > 0) - sprintf(output,"%s:%s:%lld",output,nick,tmpUser->user->userInfo.uid); //tmpUser->user->userInfo.username); - else - sprintf(output,"JOIN:%s:%s:%lld",tmpChannel->channel,nick,tmpUser->user->userInfo.uid); //tmpUser->user->userInfo.username); - } - - if (strlen(output) > 0) { - sprintf(output,"%s",output); - sSendData(userConnection,output); - } - - sprintf(output,"TOPIC:%s:%s",tmpChannel->channel,tmpChannel->topic); - sSendData(userConnection,output); - sSendData(userConnection,"MSG:TUveD:%s:Topic for %s: %s",tmpChannel->channel,tmpChannel->channel,tmpChannel->topic); - - len = sprintf(output,"MSG:TUveD:%s:Topic was set by %s on %s",tmpChannel->channel,tmpChannel->topicSetBy, ctime(&tmpChannel->topicSet)); - output[len-1] = '\0'; - sSendData(userConnection,output); - - if (tmpChannel->modes[CHAN_TIME] == 1) { - sSendData(userConnection,"MSG:TUveD:%s:This channel has a time limit of %i seconds for media.",tmpChannel->channel,tmpChannel->maxTime); - sSendData(userConnection,"MODE:%s:T:1:%i",tmpChannel->channel,tmpChannel->maxTime); - } - else { - sprintf(output,"MODE:%s:T:0",tmpChannel->channel); - sSendData(userConnection,output); - } - - if (tmpChannel->modes[CHAN_QUEUE] == 1) - sprintf(output,"MODE:%s:Q:1",tmpChannel->channel); - else - sprintf(output,"MODE:%s:Q:0",tmpChannel->channel); - sSendData(userConnection,output); - - if (tmpChannel->modes[CHAN_RANDOM] == 1) - sprintf(output,"MODE:%s:R:1",tmpChannel->channel); - else - sprintf(output,"MODE:%s:R:0",tmpChannel->channel); - sSendData(userConnection,output); - - sprintf(output,"MODE:%s:A:%i",tmpChannel->channel,tmpChannel->modes[CHAN_RATING]); - sSendData(userConnection,output); - - sprintf(output,"MODE:%s:C:%i",tmpChannel->channel,tmpChannel->modes[CHAN_CLASS]); - sSendData(userConnection,output); - - if (tmpChannel->modes[CHAN_EXCLUSIVE] != 0) - sprintf(output,"MODE:%s:E:%i",tmpChannel->channel,tmpChannel->oid); - else - sprintf(output,"MODE:%s:E:0",tmpChannel->channel); - sSendData(userConnection,output); - - - writeLog(2,"Added user: %s to Channel: %s\n",userConnection->userInfo.username,channel); - pthread_mutex_unlock(&chanMutex); - - return(0x0); - } - -tuveChanList_t *findChan(const char *channel) { - tuveChanList_t *tmpChannel = 0x0; - - assert(channel); - - pthread_mutex_lock(&chanMutex); - - for (tmpChannel = channels;tmpChannel != 0x0;tmpChannel = tmpChannel->next) { - - if (!strcasecmp(tmpChannel->channel,channel)) { - pthread_mutex_unlock(&chanMutex); - return(tmpChannel); - } - } - - pthread_mutex_unlock(&chanMutex); - return(0x0); - } - -/* - * Add A Channel To The Global Channel List - */ -tuveChanList_t *addChan(const char *channel) { - tuveChanList_t *tmpChannel = 0x0; - - pthread_mutex_lock(&chanMutex); - - channelCount++; - - if (channels == 0x0) { - channels = (tuveChanList_t *)calloc(1,sizeof(tuveChanList_t)); - channels->next = 0x0; - channels->prev = 0x0; - channels->users = 0x0; - channels->modes[CHAN_QUEUE] = 0x1; - channels->modes[CHAN_RATING] = 0x2; - channels->modes[CHAN_CLASS] = 0x1; - sprintf(channels->channel,channel); - sprintf(channels->topic,"No Topic Set"); - sprintf(channels->topicSetBy,"TUveD"); - channels->topicSet = time(NULL); - sprintf(channels->videoChanTitle,"No Video"); - sprintf(channels->videoFile,"NA"); - channels->videoEnd = 0x0; - channels->comDelay = COM_DELAY; - writeLog(2,"ADDED CHAN1\n"); - tmpChannel = channels; - } - else { - tmpChannel = (tuveChanList_t *)calloc(1,sizeof(tuveChanList_t)); - sprintf(tmpChannel->channel,channel); - sprintf(tmpChannel->topic,"No Topic Set"); - sprintf(tmpChannel->topicSetBy,"TUveD"); - tmpChannel->topicSet = time(NULL); - sprintf(tmpChannel->videoChanTitle,"NoVideo"); - sprintf(tmpChannel->videoFile,"NA"); - tmpChannel->videoEnd = 0x0; - tmpChannel->next = channels; - tmpChannel->prev = 0x0; - tmpChannel->users = 0x0; - tmpChannel->modes[CHAN_QUEUE] = 0x1; - tmpChannel->modes[CHAN_RATING] = 0x2; - tmpChannel->modes[CHAN_CLASS] = 0x1; - tmpChannel->comDelay = COM_DELAY; - channels->prev = tmpChannel; - channels = tmpChannel; - writeLog(2,"ADDED CHAN2\n"); - } - - pthread_mutex_unlock(&chanMutex); - - return(tmpChannel); - } - -int tuveSendAllInUsersChans(myConnections_t *userConnection,char *output) { - tuveUserChans_t *tmpChans = userConnection->userInfo.chans; - - for (;tmpChans != 0x0;tmpChans = tmpChans->next) { - tuveSendAllInChan(tmpChans->channel,0x0,output); - } - return(0x0); - } - -int tuveSendAllInChan(const char *channel,myConnections_t *userConnection,char const * __restrict fmt, ...) { - tuveChanList_t *tmpChannel = 0x0; - tuveUserList_t *tmpUsers = 0x0; - char data[2048]; - va_list ap; - int len = 0; - - tmpChannel = findChan(channel); - - if (tmpChannel == 0x0) { - writeLog(1,"findChan Failed!\n"); - return(0x1); - } - - - //Dont see why i need a thread lock here - - tmpUsers = tmpChannel->users; - - va_start(ap,fmt); - len = vsnprintf(data,2046,fmt,ap); - va_end(ap); -// data[len++] = '\r'; - data[len++] = '\n'; - - //THIS IS A TEMP SOLUTION I HATE IT! - - for (;tmpUsers != 0x0;tmpUsers = tmpUsers->next) { - if (userConnection == 0x0) - send(tmpUsers->user->fd,data,len,MSG_NOSIGNAL);//sSendData(tmpUsers->user,data); - else if (strcasecmp(tmpUsers->user->userInfo.username,userConnection->userInfo.username)) - send(tmpUsers->user->fd,data,len,MSG_NOSIGNAL);//sSendData(tmpUsers->user,data); - } - - return(0x0); - } - -int tuveSetTopic(myConnections_t *userConnection,char *chan,char *topic) { - char output[1024]; - tuveChanList_t *tmpChannel = 0x0; - - tmpChannel = findChan(chan); - - if (tmpChannel == 0x0) { - writeLog(1,"findChan Failed: SetTopic\n"); - return(0x1); - } - - strncpy(tmpChannel->topic,topic,128); - sprintf(output,"TOPIC:%s:%s",chan,tmpChannel->topic); - tuveSendAllInChan(chan,0x0,output); - sprintf(output,"MSG:TUveD:%s:%s has set the topic to: %s",chan,userConnection->userInfo.username,tmpChannel->topic); - tuveSendAllInChan(chan,0x0,output); - - tmpChannel->topicSet = time(NULL); - sprintf(tmpChannel->topicSetBy,userConnection->userInfo.username); - - return(0x0); - } - -int tuveKick(myConnections_t *byConnection,char *chan,char *nick,char *msg) { - tuveChanList_t *tmpChannel = 0x0; - myConnections_t *userConnection = 0x0; - char output[1024]; - - tmpChannel = findChan(chan); - - if (tmpChannel == 0x0) { - writeLog(1,"findchan Failed: Kick\n"); - return(0x1); - } - - userConnection = findNickOnChan(nick,chan); - - if (userConnection == 0x0) { - sSendData(byConnection,"MSG:TUveD:STATUS:%s Not On %s",nick,chan); - return(0x1); - } - - sSendData(userConnection,"KICK:%s:%s:%s",chan,byConnection->userInfo.username,msg); - - - nick = userConnection->userInfo.username; - - if (tuveRemoveFromChanList(chan,userConnection) == 0x1) - writeLog(0,"ERROR: Can not remove %s from %s\n",userConnection->userInfo.username,chan); - if (tuveDelChan(chan,userConnection) == 0x1) - writeLog(0,"ERROR: Can not remove %s from %s's List\n",chan,userConnection->userInfo.username); - - - sprintf(output,"MSG:TUveD:%s:%s has been kicked by %s, Reason: %s",chan,nick,byConnection->userInfo.username,msg); - tuveSendAllInChan(chan,0x0,output); - - sprintf(output,"PART:%s:%s",chan,nick); - tuveSendAllInChan(chan,0x0,output); - - writeLog(0,"Kicked %s\n",output); - - tuveChanJoin("#doghouse",userConnection); - - return(0x0); - } - -int tuveBan(myConnections_t *byConnection,const char *channel,const char *nick,int length) { - char output[1024]; - tuveChanList_t *tmpChannel = 0x0; - myConnections_t *userConnection = 0x0; - int i = 0x0; - - tmpChannel = findChan(channel); - - if (tmpChannel == 0x0) { - writeLog(1,"findChan Failed: Ban\n"); - return(0x1); - } - - if (tuveFindChanLevel(channel,byConnection,0) < 1) { - sSendData(byConnection,"MSG:TUveD:STATUS:You do not have permission to ban."); - return(0x0); - } - - userConnection = findNick(nick); - - if (userConnection == 0x0) { - writeLog(1,"nick Filed: Ban\n"); - return(0x1); - } - - sSendData(userConnection,"BAN"); - - for (i = 0x0;i < CHAN_MAX_BANS;i++) { - if (tmpChannel->bans[i][0] == 0x0) { - tmpChannel->bans[i][0] = userConnection->userInfo.uid; - tmpChannel->bans[i][1] = length + time(NULL); - break; - } - } - - sprintf(output,"MSG:TUveD:%s:%s has been banned for %i seconds",channel,userConnection->userInfo.username,length); - tuveSendAllInChan(channel,0x0,output); - - return(0x0); - } - -int tuveUnBan(const char *channel,const char *nick) { - char output[1024]; - tuveChanList_t *tmpChannel = 0x0; - myConnections_t *userConnection = 0x0; - int i = 0x0; - - tmpChannel = findChan(channel); - - if (tmpChannel == 0x0) { - writeLog(1,"findchan Failed: Ban\n"); - return(0x1); - } - - userConnection = findNick(nick); - - if (userConnection == 0x0) { - writeLog(1,"nick Filed: Ban\n"); - return(0x1); - } - - for (i = 0x0;i < CHAN_MAX_BANS;i++) { - if (tmpChannel->bans[i][0] == userConnection->userInfo.uid) { - tmpChannel->bans[i][0] = 0x0; - break; - } - } - - sprintf(output,"MSG:TUveD:%s:%s has been unbanned",channel,userConnection->userInfo.username); - tuveSendAllInChan(channel,0x0,output); - - return(0x0); - } - -int tuveVerifyBan(const char *channel,const char *nick) { - tuveChanList_t *tmpChannel = 0x0; - myConnections_t *userConnection = 0x0; - int i = 0x0; - - tmpChannel = findChan(channel); - - if (tmpChannel == 0x0) { - writeLog(1,"findchan Failed: Ban\n"); - return(0x1); - } - - userConnection = findNick(nick); - - if (userConnection == 0x0) { - writeLog(1,"nick Filed: Ban\n"); - return(0x1); - } - - for (i = 0x0;i < CHAN_MAX_BANS;i++) { - if (tmpChannel->bans[i][0] == userConnection->userInfo.uid) { - return(0x1); - } - } - - return(0x0); - } - -myConnections_t *findNickOnChan(const char *nick,const char *channel) { - tuveChanList_t *tmpChannel = 0x0; - tuveUserList_t *tmpUser = 0x0; - - tmpChannel = findChan(channel); - if (tmpChannel == 0x0) - return(0x0); - - for (tmpUser = tmpChannel->users;tmpUser != 0x0;tmpUser = tmpUser->next) { - if (!strcasecmp(tmpUser->user->userInfo.username,nick)) - return(tmpUser->user); - } - return(0x0); - } - -int tuveFindChanLevel(const char *channel,myConnections_t *userConnection,int eo) { - tuveChanList_t *tmpChannel = 0x0; - tuveUserList_t *tmpUser = 0x0; - - if ((userConnection->userInfo.modes[USER_OVERLORD] == 1) && (eo != 1)) - return(0x1); - - tmpChannel = findChan(channel); - if (tmpChannel == 0x0) - return(0x0); - - for (tmpUser = tmpChannel->users;tmpUser != 0x0;tmpUser = tmpUser->next) { - if (tmpUser->user == userConnection) - return(tmpUser->chanLevel); - } - return(-1); - } - -int tuveChanOp(const char *channel,const char *nick,int level) { - tuveChanList_t *tmpChannel = 0x0; - tuveUserList_t *tmpUser = 0x0; - char output[512]; - - tmpChannel = findChan(channel); - if (tmpChannel == 0x0) - return(0x1); - - writeLog(3,"Looking for %s on %s\n",nick,channel); - for (tmpUser = tmpChannel->users;tmpUser != 0x0;tmpUser = tmpUser->next) { - if (!strcasecmp(tmpUser->user->userInfo.username,nick)) { - tmpUser->chanLevel = level; - sprintf(output,"MODE:%s:O:%i:%s",tmpChannel->channel,level,tmpUser->user->userInfo.username); - tuveSendAllInChan(channel,0x0,output); - return(0x0); - } - } - return(0x1); - } diff --git a/config.c b/config.c deleted file mode 100644 index a8c9260..0000000 --- a/config.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include - -int parseConfig() { - config_t cfg; - - config_setting_t *setting; - - config_init(&cfg); - - if (access("./tuved.cfg", F_OK) != -1) { - if (!config_read_file(&cfg, "./tuved.cfg")) { - fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); - config_destroy(&cfg); - return(EXIT_FAILURE); - } - } - else if (access("/usr/local/etc/tuved.cfg", F_OK) != -1) { - if (!config_read_file(&cfg, "/usr/local/etc/tuved.cfg")) { - fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); - config_destroy(&cfg); - return(EXIT_FAILURE); - } - } - else { - config_destroy(&cfg); - return(EXIT_FAILURE); - } - - setting = config_lookup(&cfg, "daemon"); - - if (setting != NULL) { - int i = 9999; - - config_setting_lookup_int(setting, "port", &i); - - //printf("port: %i", i); - } - - return(0); - -} diff --git a/extra/tuved b/extra/tuved index f684072..957dd3b 100755 --- a/extra/tuved +++ b/extra/tuved @@ -10,7 +10,7 @@ # tuved_enable="YES" # tuved_flags="" # -# See rsync(1) for tuved_flags +# See tuved(1) for tuved_flags # . /etc/rc.subr @@ -29,7 +29,7 @@ required_files="${tuved_configfile}" -command_args="-d 4 -config ${tuved_configfile}" +command_args="-d 4 -c ${tuved_configfile}" tuved_precmd() { diff --git a/extra/tuved.cfg b/extra/tuved.cfg new file mode 100644 index 0000000..13823de --- /dev/null +++ b/extra/tuved.cfg @@ -0,0 +1,10 @@ +daemon = { + sport = 2007; +} + +database = { + hostname = "SPBX-DB002.SpherePBX.com"; + database = "tuve"; + username = "tuve"; + password = "5558585"; +} diff --git a/lib.c b/lib.c deleted file mode 100644 index 5b0aff1..0000000 --- a/lib.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include "tuved.h" - - -int formatTime(time_t sTime,char *output) { - int day,hour,min,sec; - time_t curTime; - - curTime = sTime; - - day = curTime / 86400; - curTime -= (86400 * day); - hour = curTime / 3600; - curTime -= (3600 * hour); - min = curTime / 60; - curTime -= (60 * min); - sec = curTime; - - if (day) - sprintf(output, "%i:%.2d:%.2d:%.2d", day, hour, min, sec); - else - if (hour) sprintf(output, "%.2d:%.2d:%.2d", hour, min, sec); - else - if (min) sprintf(output, "%.2d:%.2d", min, sec); - else - sprintf(output, "%.2d", sec); - - return(sTime); - } diff --git a/main.c b/main.c deleted file mode 100644 index 7734328..0000000 --- a/main.c +++ /dev/null @@ -1,167 +0,0 @@ -/***************************************************************************************** - Copyright (c) 2002-2004, 2005, 2007 Ubix Technology Group - All rights reserved. - - $Id: main.c,v 1.21 2008/06/30 18:55:10 reddawg Exp $ - -*****************************************************************************************/ - -#include -#include -#include -#include - -#include "tuved.h" - -FILE *logFile = 0x0; -int logLevel = 1; -pthread_mutex_t chanMutex = PTHREAD_MUTEX_INITIALIZER; -time_t startTime; -int userCount = 0; -int channelCount = 0; -int songCount = 0; -int playCount = 0; -char logFileName[64]; - -void usage(); - -int main(int argc,char **argv) { - fd_set readset; - int ch; - int readSocks = 0x0; - int doFork = 0x1; - int rc = 0x0; - int t = 0x0; - time_t seconds = 0; - struct timeval timeout = {30,0}; - - /* Get our start time */ - startTime = time(NULL); - - while ((ch = getopt(argc,argv,"sl:nd:c:")) != -1) { - switch (ch) { - case 's': - logFile = stdout; - break; - case 'l': - logFile = fopen(optarg,"a"); - break; - case 'n': - doFork = 0; - break; - case 'd': - logLevel = atoi(optarg); - if (logLevel < 1) - logLevel = 1; - break; - case 'c': - break; - default: - usage(); - } - } - argc -= optind; - argv += optind; - - parseConfig(); - - - /* Prepare log file */ - if (logFile == 0x0) { - sprintf(logFileName,"/var/log/tuved.%i.log", time(NULL)); - logFile = fopen(logFileName,"a"); - } - - /* Fork into background unless specified not to do so */ - if (doFork == 1) - if (fork() != 0x0) - exit(0x1); - - writeLog(0,"TUve Daemon Starting: %i\n",startTime); - - int fd; - FILE *somefile; - - somefile = fopen("/var/run/tuved.pid", "w"); - - //text - fprintf(somefile, "%d", getpid()); - - fclose(somefile); - - /* - //binary - pid_t pid = getpid(); - - fwrite(&pid, sizeof(pid), 1, somefile); - - write(fd, &pid, sizeof(pid)); - */ - - if (dbInit() == 0x1) - exit(0x1); - - /* Reset Server Sessions */ - dbQuery("DELETE FROM active",0); - - srandom(time(NULL)); - - pthread_mutex_init(&chanMutex, NULL); - - pthread_t threads[NUM_THREADS]; - rc = pthread_create(&threads[t], NULL, tuveCMD_Thread, (void *)t); - - sStartListener(); - - while (1) { - - /* Get Socket Set For Readable Connections */ - if (sGetConnections(&readset) == 0x0) { - writeLog(0,"Error: sGetConnections Failed\nShutting Down\n"); - exit(0x1); - } - - readSocks = select(highSock+1,&readset,0x0,0x0,&timeout); - - if (readSocks < 0) { - writeLog(0,"Error: select Failed\nShutting Down\n"); - exit(0x1); - } - else if (readSocks > 0) { - sProcessConnections(&readset); - } - - if ((seconds + PING_INTERVAL) < time(NULL)) { - sSendPing(seconds); - seconds = time(NULL); - } - - /* Clean up old connections */ - sCleanConnections(); - - /* Flush the log file */ - fflush(logFile); - } - - return(0); - } - -void usage() { - printf("%s\n","usage: tuved -n -s [-l logfile] [-d debuglevel]"); - exit(1); - } - - -int writeLog(int level,char const * __restrict fmt, ...) { - int ret; - va_list ap; - - if (level > logLevel) - return(0x0); - - va_start(ap, fmt); - ret = vfprintf(logFile, fmt, ap); - va_end(ap); - - return(ret); - } /* End writeLog(); */ diff --git a/mysql.c b/mysql.c deleted file mode 100644 index 71bed1b..0000000 --- a/mysql.c +++ /dev/null @@ -1,61 +0,0 @@ -#include - -#include "tuved.h" - -MYSQL *conn = 0x0; - -pthread_mutex_t mysqlMutex = PTHREAD_MUTEX_INITIALIZER; - - -int dbInit() { - - conn = mysql_init(0x0); - - if (conn == NULL) { - writeLog(0,"mysql_init() failed (probably out of memory)\n."); - return(0x1); - } - - my_bool reconnect = 1; - - if (mysql_options(conn,MYSQL_OPT_RECONNECT, &reconnect) != 0x0) - writeLog(0,"mysql_options() failed: To Set Reconnect\n"); - - if (!mysql_real_connect(conn,MYSQL_HOST_NAME,MYSQL_USERNAME,MYSQL_PASSWORD,MYSQL_DB_NAME,0,NULL,0)) { - writeLog(0,"mysql_real_connect() failed: Error %u (%s)\n.", mysql_errno(conn), mysql_error(conn)); - return(0x1); - } - - - pthread_mutex_init(&mysqlMutex, NULL); - - writeLog(0,"Sucessful connection to the MySQL Database.\n"); - - return(0x0); - } - -MYSQL_RES *dbQuery(const char *query,short store) { - MYSQL_RES *res_set = 0x0; - - pthread_mutex_lock(&mysqlMutex); - - writeLog(0,"Query: %s\n",query); - - if (mysql_query(conn,query) != 0x0) { - writeLog(0,"mysql_query() failed: Error %u (%s)\n.", mysql_errno(conn), mysql_error(conn)); - pthread_mutex_unlock(&mysqlMutex); - return(0x0); - } - - if (store == 1) { - res_set = mysql_store_result(conn); - if (res_set == 0x0) { - writeLog(0,"mysql_store_result() failed: Error %u (%s)\n.", mysql_errno(conn), mysql_error(conn)); - pthread_mutex_unlock(&mysqlMutex); - return(0x0); - } - } - - pthread_mutex_unlock(&mysqlMutex); - return(res_set); - } diff --git a/nick.c b/nick.c deleted file mode 100644 index 08eef30..0000000 --- a/nick.c +++ /dev/null @@ -1,97 +0,0 @@ -#include -#include - -#include "tuved.h" - - -int -tuveVerifyNick(char *nick) { - int i = 0x0; - int len = 0x0; - - assert(nick); - assert(connections); - - len = strlen(nick); - - for (i = 0x0;i < len;i++) { - if ((nick[i] < 48) || (nick[i] > 122) || ((nick[i] > 57) && (nick[i] < 65)) || ((nick[i] > 90) && (nick[i] < 97))) - return(0x1); - } - - - - if (findNick(nick) != 0x0) - return(0x1); - - return(0x0); -} // tuveVerifyNick() - - -myConnections_t *findNick(const char *nick) { - if (nick == 0x0) - return(0x0); - - myConnections_t *tmpConnection = 0x0; - for (tmpConnection = connections;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { - if (!strcasecmp(nick,tmpConnection->userInfo.username)) - return(tmpConnection); - } - return(0x0); - } - -int tuveWhois(myConnections_t *userConnection,char *nick) { - myConnections_t *user = 0x0; - tuveUserChans_t *chans = 0x0; - char output[256]; - char channel[MAX_CHAN_LEN + 1]; - int len = 0; - - if (strlen(nick) > MAX_USER_LEN) - return(0x0); - - user = findNick(nick); - - if (user == 0x0) { - sprintf(output,"MSG:TUveD:STATUS:%s Not Found",nick); - sSendData(userConnection,output); - return(0x0); - } - - sprintf(output,"MSG:TUveD:STATUS:%s is %s",user->userInfo.username,user->host); - sSendData(userConnection,output); - len = sprintf(output,"MSG:TUveD:STATUS:%s Signed On %s",user->userInfo.username,ctime(&user->signedOn)); - output[len -1] = '\0'; - sSendData(userConnection,output); - - sprintf(output,"MSG:TUveD:STATUS:%s Is running %4.2f",user->userInfo.username,user->userInfo.version); - sSendData(userConnection,output); - - if (user->userInfo.modes[USER_OVERLORD] == 1) { - sprintf(output,"MSG:TUveD:STATUS:%s Is an Evil Overlord",user->userInfo.username); - sSendData(userConnection,output); - } - if ((time(NULL) - user->userInfo.idle) > 30) { - sprintf(output,"MSG:TUveD:STATUS:%s Has been idle for %i seconds.",user->userInfo.username,time(NULL) - user->userInfo.idle); - sSendData(userConnection,output); - } - - if (user->userInfo.chans != 0x0) { - memset(output,0x0,256); - for (chans = user->userInfo.chans;chans != 0x0;chans = chans->next) { - - if (tuveFindChanLevel(chans->channel,user,1) == 0) - strcpy(channel,chans->channel); - else - sprintf(channel,"&%s",chans->channel); - - if (strlen(output) == 0) - sprintf(output,"MSG:TUveD:STATUS:%s Is on channel(s) %s",user->userInfo.username,channel); - else - sprintf(output,"%s,%s",output,channel); - } - sSendData(userConnection,output); - } - - return(0x0); - } diff --git a/server.c b/server.c deleted file mode 100644 index 6a49e76..0000000 --- a/server.c +++ /dev/null @@ -1,45 +0,0 @@ -#include - -#include "tuved.h" - - -int tuveStatus(myConnections_t *userConnection) { - char output[512]; - int day,hour,min,sec; - time_t curTime; - - curTime = time(NULL); - - - sprintf(output,"MSG:TUveD:STATUS:Server on-line since: %s",ctime(&startTime)); - sSendData(userConnection,output); - curTime -= startTime; - day = curTime / 86400; - curTime -= (86400 * day); - hour = curTime / 3600; - curTime -= (3600 * hour); - min = curTime / 60; - curTime -= (60 * min); - sec = curTime; - sprintf(output,"MSG:TUveD:STATUS:Server is running TUveD %s",VERSION); - sSendData(userConnection,output); - sprintf(output,"MSG:TUveD:STATUS:Server has been running for %i days %i hours %i min %.2i sec",day,hour,min,sec); - sSendData(userConnection,output); - sprintf(output,"MSG:TUveD:STATUS:There are currently %i users online.",userCount); - sSendData(userConnection,output); - sprintf(output,"MSG:TUveD:STATUS:There are currently %i channels active.",channelCount); - sSendData(userConnection,output); - curTime = playCount; - day = curTime / 86400; - curTime -= (86400 * day); - hour = curTime / 3600; - curTime -= (3600 * hour); - min = curTime / 60; - curTime -= (60 * min); - sec = curTime; - sprintf(output,"MSG:TUveD:STATUS:There have been %i videos played. For a total Playtime of %i days %i hours %i min %.2i secs",songCount,day,hour,min,sec); - sSendData(userConnection,output); - - return(0x0); -} // tuveStatus() - diff --git a/socket.c b/socket.c deleted file mode 100644 index e3c3590..0000000 --- a/socket.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - tuved - Socket Server - (c) 2007 Christopher Olsen - - $Id: socket.c,v 1.30 2008/02/05 01:27:29 reddawg Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tuved.h" - -myConnections_t *connections = 0x0; - -int listenerFD = 0x0; -int highSock = 0x0; - -int sStartListener() { - int optVal = 0x1; - - struct sockaddr_in myAddr; // my address information - - if ((listenerFD = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - perror("socket"); - exit(1); - } - - if (setsockopt(listenerFD, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(int)) == -1) { - perror("setsockopt"); - exit(1); - } - - myAddr.sin_family = AF_INET; // host byte order - myAddr.sin_port = htons(MYPORT); // short, network byte order - myAddr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP - memset(myAddr.sin_zero, '\0', sizeof myAddr.sin_zero); - - if (bind(listenerFD, (struct sockaddr *)&myAddr, sizeof(struct sockaddr)) == -1) { - perror("bind"); - exit(1); - } - - if (listen(listenerFD, BACKLOG) == -1) { - perror("listen"); - exit(1); - } - - fcntl(listenerFD, F_SETFL, fcntl(listenerFD, F_GETFL, 0) | O_NONBLOCK); - - sAddConnection(listenerFD,"127.0.0.1"); - - writeLog(2,"Listener FD: [%i]\n",listenerFD); - - return(0x0); - } - -ssize_t sReadSocket(int socketFD,void *buffer,size_t length) { - ssize_t recLen = 0x0; - - recLen = read(socketFD,buffer,length); - - if (recLen <= 2) - recLen = 0x0; - - return(recLen); - } - -int sGetConnection() { - int newFD = 0x0; // New Socket; - socklen_t sin_size; - struct sockaddr_in remoteAddr; - struct hostent *hp; - sin_size = sizeof(struct sockaddr_in); - - if ((newFD = accept(listenerFD, (struct sockaddr *)&remoteAddr, &sin_size)) == -1) { - perror("accept"); - } - - - /* Add Socket */ - hp = gethostbyaddr((char *)&remoteAddr.sin_addr,sizeof(remoteAddr.sin_addr),AF_INET); - sAddConnection(newFD,(hp ? hp->h_name : inet_ntoa(remoteAddr.sin_addr))); - - /* Return */ - return(0x0); - } - -int sAddConnection(int socketFD,char *host) { - myConnections_t *tmpConnection = 0x0; - - writeLog(2,"Adding Socket: [%i]\n",socketFD); - - userCount++; - - if (connections == 0x0) { - connections = (myConnections_t *)calloc(1,sizeof(myConnections_t)); - connections->prev = 0x0; - connections->next = 0x0; - connections->fd = socketFD; - connections->signedOn = time(NULL); - sprintf(connections->host,host); - } - else { - tmpConnection = (myConnections_t *)calloc(1,sizeof(myConnections_t)); - //memset(tmpConnection,0x0,sizeof(myConnections_t)); - tmpConnection->fd = socketFD; - tmpConnection->prev = connections; - tmpConnection->next = connections->next; - tmpConnection->signedOn = time(NULL); - sprintf(tmpConnection->host,host); - if (connections->next != 0x0) - connections->next->prev = tmpConnection; - - connections->next = tmpConnection; - } - writeLog(2,"Socket Added\n"); - - return(0x0); - } - -myConnections_t *sFindConnection(int fd) { - myConnections_t *tmpConnection = 0x0; - - for (tmpConnection = connections->next;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { - if (tmpConnection->fd == fd) - return(tmpConnection); - } - - return(0x0); - } - -int sCleanConnections() { - myConnections_t *tmpConnection = 0x0; - myConnections_t *delConnection = 0x0; - char output[256]; - - for (tmpConnection = connections->next;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { - if (tmpConnection->userInfo.status == -1) { - // Set temporary pointer to connection so we can free it later - delConnection = tmpConnection; - - // Hard close the socket so it doesn't linger - close(tmpConnection->fd); - - writeLog(2,"Removed User: [%s]\n",tmpConnection->userInfo.username); - - // If connection has a previous pointer which it always should adjust it's next pointer to match current next - if (tmpConnection->prev != 0x0) - tmpConnection->prev->next = tmpConnection->next; - - // If connection has a next pointer which it may not adjust it to point to match our current previous - if (tmpConnection->next != 0x0) - tmpConnection->next->prev = tmpConnection->prev; - - // Adjust tmpConnection to match our previous pointer which should always happen - if (tmpConnection->prev != 0x0) - tmpConnection = tmpConnection->prev; - else - tmpConnection = tmpConnection->next; - - userCount--; - - if (delConnection->userInfo.ident == 2) { - sprintf(output,"DELETE FROM active WHERE userid = %lld",delConnection->userInfo.uid); - dbQuery(output,0); - } - - //Free the bad connection - free(delConnection); - writeLog(2,"Remove Completed\n"); - } - } - return(0x0); - } - -int sRemoveConnection(int socketFD) { - myConnections_t *tmpConnection = 0x0; - char output[256]; - - writeLog(2,"Removing Socket: %i\n",socketFD); - - for (tmpConnection = connections->next;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { - if (tmpConnection->fd == socketFD) { - - tmpConnection->prev->next = tmpConnection->next; - - if (tmpConnection->next != 0x0) - tmpConnection->next->prev = tmpConnection->prev; - writeLog(2,"Removed Socket: [%i]\n",tmpConnection->fd); - - userCount--; - - if (tmpConnection->userInfo.ident == 2) { - sprintf(output,"DELETE FROM active WHERE userid = %lld",tmpConnection->userInfo.uid); - dbQuery(output,0); - } - - free(tmpConnection); - return(0x0); - } - } - - writeLog(2,"Error: No Socket Removed\n"); - return(-1); - } - -int sGetConnections(fd_set *readset) { - int retVal = 0; - myConnections_t *tmpConnection = 0x0; - - FD_ZERO(readset); - -// FD_SET(listenerFD,readset); - - highSock = 0; - - if (connections != 0x0) { - for (tmpConnection = connections;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { - FD_SET(tmpConnection->fd,readset); - if (tmpConnection->fd > highSock) - highSock = tmpConnection->fd; - } - retVal = 1; - } - - return(retVal); - } - -/************************************ - * * - * Send ping broadcast to all users * - * * - ************************************/ -int sSendPing(time_t ping) { - myConnections_t *tmpConnection = 0x0; - char sPing[32]; - - for (tmpConnection = connections->next;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { - if (tmpConnection->userInfo.pfailed < MAX_PING) { - if (tmpConnection->userInfo.pong < ping) { - tmpConnection->userInfo.pfailed++; - tmpConnection->userInfo.pong = ping; - if (tmpConnection->userInfo.ident >= 0x1) { - sprintf(sPing,"PING %i\r\n", time(NULL)); - send(tmpConnection->fd,sPing,strlen(sPing),MSG_NOSIGNAL); - } - } - } - else { - send(tmpConnection->fd,"TIMEOUT\r\n",sizeof("TIMEOUT\r\n"),MSG_NOSIGNAL); - tuveDelUserChans(tmpConnection,"TIMEOUT"); - tmpConnection->userInfo.status = -1; - } - } - - return(0x0); - } /* End sSendPing() */ - -int sSendData(myConnections_t *con,char const * __restrict fmt, ...) { - int len = 0; - char data[2048]; - va_list ap; - - if (con == 0x0) { - writeLog(1,"Error Sending Data"); - return(0x1); - } - else if (con->userInfo.status == -1) { - writeLog(3,"User: %s Socket Not Avail\n",con->userInfo.username); - return(0x1); - } - - va_start(ap,fmt); - len = vsnprintf(data,2046,fmt,ap); - va_end(ap); - - //data[len++] = '\r'; - data[len++] = '\n'; - - - send(con->fd,data,len,MSG_NOSIGNAL); - return(0x0); - } - -int sProcessConnections(fd_set *readset) { - myConnections_t *tmpConnection = 0x0; - - for (tmpConnection = connections;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { - if (FD_ISSET(tmpConnection->fd,readset) != 0x0) { - if (tmpConnection->fd == listenerFD) { - sGetConnection(); - writeLog(2,"Listen Socket Was Ready?\n"); - } - else { - if (tuveGetData(tmpConnection) == -1) { - close(tmpConnection->fd); - tuveDelUserChans(tmpConnection,"SIG PIPE"); - sRemoveConnection(tmpConnection->fd); - } - } - } - } - return(0x0); - } diff --git a/src/botthread.c b/src/botthread.c new file mode 100644 index 0000000..e4568b6 --- /dev/null +++ b/src/botthread.c @@ -0,0 +1,579 @@ +#include +#include +#include + +#include "tuved.h" + +int playCnt = 0; + +int nextSong(); +int chanMaint(); + +int tuveCMD_CMD(myConnections_t *userConnection,char *chan,char *data) { + char output[512]; + char dMS[2] = {'-','+'}; + char *cmd = 0x0; + char *cmdData = 0x0; + char *modeString = 0x0; + char *tmp = 0x0; + char *tmp2 = 0x0; + char *tok_last = 0x0; + tuveChanList_t *tmpChan = 0x0; + tuveUserList_t *tmpUser = 0x0; + MYSQL_RES *res = 0x0; + MYSQL_ROW row; + short dM = 0x0; + unsigned int i = 0x0; + + if (data == 0x0) + return(0x1); + + cmd = strtok_r(data," ",&tok_last); + cmdData = strtok_r(NULL,"\n",&tok_last); + + if (cmd == 0x0) + return(0x1); + + if (strcasecmp(cmd,"login") == 0x0) { + tok_last = 0x0; + tmp = strtok_r(cmdData," ",&tok_last); + tmp2 = strtok_r(NULL,"\n",&tok_last); + if ((tmp != 0x0) & (tmp2 != 0x0)) { + sprintf(output,"SELECT username,gid,uid FROM users WHERE username = '%s' AND password = '%s'",tmp,tmp2); + res = dbQuery(output,1); + if (res == 0x0) { + sSendData(userConnection,"MSG:TUveD:STATUS:Sorry I'm Having MySQL Troubles."); + } + else if (mysql_num_rows(res) == 1) { + sSendData(userConnection,"MSG:TUveD:%s:You have successfully logged in.",chan); + row = mysql_fetch_row(res); + sprintf(output,"INSERT INTO active (gid,uid,userid) VALUES(%s,%s,%lld)",row[1],row[2],userConnection->userInfo.uid); + dbQuery(output,0); + sSendData(findNick("TUveBOT"),"LOGIN:%s:%lld",userConnection->userInfo.username,userConnection->userInfo.uid); + if (atoi(row[1]) == 1) { + sprintf(output,"EMOTE:%s:STATUS:Is now an Evil Overlord!",userConnection->userInfo.username); + tuveSendAllInUsersChans(userConnection,output); + userConnection->userInfo.modes[USER_OVERLORD] = 1; + } + userConnection->userInfo.ident = 2; + } + else { + sSendData(userConnection,"MSG:TUveD:%s:You have failed login.",chan); + } + if (res != 0x0) + mysql_free_result(res); + } + } /* End login */ + else if (tuveFindChanLevel(chan,userConnection,0) == 0) { + sSendData(userConnection,"MSG:TUveD:STATUS:You do not have permission to set channel mode."); + return(0x0); + } /* Commands Stop Here If You Channel Level Isn't >= 1 */ + else if (strcasecmp(cmd,"pause") == 0x0) { + tuveSendAllInChan(chan,0x0,"PAUSE"); + } + else if (strcasecmp(cmd,"resume") == 0x0) { + tuveSendAllInChan(chan,0x0,"RESUME\n"); + } + else if (strcasecmp(cmd,"skip") == 0x0) { + if (cmdData != 0x0) + tmpChan = findChan(cmdData); + else + tmpChan = findChan(chan); + if (tmpChan != 0x0) { + if (tmpChan->vidClass != 7) { + tmpChan->videoEnd = 0x0; + tmpChan->count = MAX_COUNT; + } + } + } + else if (strcasecmp(cmd,"mode") == 0x0) { + tmpChan = findChan(chan); + + if (cmdData != 0x0) { + tok_last = 0x0; + modeString = strtok_r(cmdData," ",&tok_last); + + if (modeString[0] == '-') + dM = 0; + else if (modeString[0] == '+') + dM = 1; + else { + sSendData(userConnection,"MSG:TUveD:STATUS:Invalid Mode String."); + return(0x0); + } + + + for (i = 1;i < strlen(modeString);i++) { + switch(modeString[i]) { + case '-': + dM = 0; + break; + case '+': + dM = 1; + break; + case 'o': + case 'O': + tmp = strtok_r(NULL," ",&tok_last); + if (tmp != 0x0) { + if (tuveChanOp(chan,tmp,dM) == 0x0) { + sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cO %s",chan,userConnection->userInfo.username,dMS[dM],tmp); + tuveSendAllInChan(chan,0x0,output); + } + } + else { + sSendData(userConnection,"MSG:TUveD:STATUS:Missing +O Opperators"); + } + break; + case 'a': + case 'A': + tmp = strtok_r(NULL," ",&tok_last); + if (tmp != 0x0) { + tmpChan->modes[CHAN_RATING] = atoi(tmp); + sprintf(output,"MODE:%s:A:%i",tmpChan->channel,tmpChan->modes[CHAN_RATING]); + tuveSendAllInChan(chan,0x0,output); + } + break; + case 'c': + case 'C': + tmp = strtok_r(NULL," ",&tok_last); + if (tmp != 0x0) { + tmpChan->modes[CHAN_CLASS] = atoi(tmp); + sprintf(output,"MODE:%s:C:%i",tmpChan->channel,tmpChan->modes[CHAN_CLASS]); + tuveSendAllInChan(chan,0x0,output); + } + break; + case 'e': + case 'E': + if (dM == 0) { + tmpChan->modes[CHAN_EXCLUSIVE] = 0; + sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cExclusive",chan,userConnection->userInfo.username,dMS[dM]); + tuveSendAllInChan(chan,0x0,output); + } + else { + sprintf(output,"SELECT oid FROM channels WHERE channel LIKE '%s'",tmpChan->channel); + res = dbQuery(output,1); + if (res == 0x0) { + sprintf(output,"MSG:TUveD:%s:Sorry I'm having SQL troubles today.",tmpChan->channel); + tuveSendAllInChan(tmpChan->channel,0x0,output); + } + else if (mysql_num_rows(res) == 0x0) { + sprintf(output,"MSG:TUveD:%s:Sorry this channel is not registered.",tmpChan->channel); + tuveSendAllInChan(tmpChan->channel,0x0,output); + } + else { + row = mysql_fetch_row(res); + tmpChan->modes[CHAN_EXCLUSIVE] = 1; + tmpChan->oid = atoi(row[0]); + sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cExclusive",chan,userConnection->userInfo.username,dMS[1]); + tuveSendAllInChan(chan,0x0,output); + } + if (res != 0x0) + mysql_free_result(res); + } + sprintf(output,"MODE:%s:E:%i",tmpChan->channel,tmpChan->modes[CHAN_EXCLUSIVE]); + tuveSendAllInChan(chan,0x0,output); + break; + case 'r': + case 'R': + tmpChan->modes[CHAN_RANDOM] = dM; + sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cRandom",chan,userConnection->userInfo.username,dMS[dM]); + tuveSendAllInChan(chan,0x0,output); + sprintf(output,"MODE:%s:R:%i",tmpChan->channel,dM); + tuveSendAllInChan(chan,0x0,output); + break; + case 'q': + case 'Q': + tmpChan->modes[CHAN_QUEUE] = dM; + sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cQueue",chan,userConnection->userInfo.username,dMS[dM]); + tuveSendAllInChan(chan,0x0,output); + sprintf(output,"MODE:%s:Q:%i",tmpChan->channel,dM); + tuveSendAllInChan(chan,0x0,output); + break; + case 'X': + tmpChan->modes[CHAN_NOADS] = dM; + sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cNo Advertisements",chan,userConnection->userInfo.username,dMS[dM]); + tuveSendAllInChan(chan,0x0,output); + sprintf(output,"MODE:%s:X:%i",tmpChan->channel,dM); + tuveSendAllInChan(chan,0x0,output); + break; + case 't': + case 'T': + if (dM == 1) { + tmp = strtok_r(NULL," ",&tok_last); + if (tmp != 0x0) { + tmpChan->modes[CHAN_TIME] = dM; + tmpChan->maxTime = atoi(tmp); + sprintf(output,"MSG:TUveD:%s:%s Sets Mode +Time Limit %s",chan,userConnection->userInfo.username,tmp); + tuveSendAllInChan(chan,0x0,output); + sprintf(output,"MODE:%s:T:%i:%s",tmpChan->channel,dM,tmp); + tuveSendAllInChan(chan,0x0,output); + } + } + else { + tmpChan->modes[CHAN_TIME] = dM; + sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cTime Limit",chan,userConnection->userInfo.username,dMS[dM]); + tuveSendAllInChan(chan,0x0,output); + sprintf(output,"MODE:%s:T:%i",tmpChan->channel,dM); + tuveSendAllInChan(chan,0x0,output); + } + break; + case 'S': + if (dM == 0x1) { + for (tmpUser = tmpChan->users;tmpUser != 0x0;tmpUser = tmpUser->next) { + if (tmpUser->user == userConnection) { + tmpChan->nextUser = tmpUser; + } + } + } + else + tmpChan->nextUser = tmpChan->users; + + tmpChan->modes[CHAN_SCHEDULED] = dM; + sprintf(output,"MSG:TUveD:%s:%s Sets Mode %cScheduled",chan,userConnection->userInfo.username,dMS[dM]); + tuveSendAllInChan(chan,0x0,output); + sprintf(output,"MODE:%s:S:%i",tmpChan->channel,dM); + tuveSendAllInChan(chan,0x0,output); + break; + default: + sSendData(userConnection,"MSG:TUveD:STATUS:Invalid Channel Mode"); + break; + } + } + + + } + } + else if (strcasecmp(cmd,"queue") == 0x0) { + tmpChan = findChan(chan); + if (tmpChan == 0x0) + return(0x0); + sprintf(output,"MSG:TUveD:%s:Queue Order - ",userConnection->userInfo.username); + for (tmpUser = tmpChan->users;tmpUser != 0x0;tmpUser = tmpUser->next) { + if (tmpUser == tmpChan->nextUser) + sprintf(output,"%s(%s),",output,tmpUser->user->userInfo.username); + else if (tmpUser == tmpChan->nextUser->next) + sprintf(output,"%s[%s],",output,tmpUser->user->userInfo.username); + else + sprintf(output,"%s%s,",output,tmpUser->user->userInfo.username); + } + sSendData(userConnection,output); + } + else if (strcasecmp(cmd,"random") == 0x0) { + tmpChan = findChan(chan); + if (tmpChan == 0x0) + return(0x0); + if ((tmpChan->modes[CHAN_LIVE] == 0x1) || (tmpChan->vidClass == 7)) + return(0x0); + + sprintf(output,"SELECT artist,title,file,length,vid,classification,rating FROM videos WHERE status = 0 AND rating <= %i",tmpChan->modes[CHAN_RATING]); + if (tmpChan->modes[CHAN_EXCLUSIVE]) + sprintf(output,"%s AND oid = %i",output,tmpChan->modes[CHAN_EXCLUSIVE]); + if (tmpChan->modes[CHAN_CLASS]) + sprintf(output,"%s AND classification = %i",output,tmpChan->modes[CHAN_CLASS]); + + res = dbQuery(output,1); + if (res == 0x0) { + sprintf(output,"MSG:TUveD:%s:Sorry I'm Have SQL Troubles Today.",chan); + tuveSendAllInChan(chan,0x0,output); + } + else if (mysql_num_rows(res) == 0x0) { + sprintf(output,"MSG:TUveD:%s:Sorry There Are No Videos Available At The Current Channel Settings.",chan); + tuveSendAllInChan(chan,0x0,output); + } + else { + mysql_data_seek(res,(random() % mysql_num_rows(res))); + row = mysql_fetch_row(res); + //sprintf(output,"UPDATE videos SET count = %i WHERE vid = %s",atoi(row[7])+1,row[4]); + //dbQuery(output,0); + tuveBotSetSong(chan,userConnection->userInfo.username,row[0],row[1],atoi(row[3]),row[2],atoi(row[5]),atoi(row[6]),atoi(row[4])); + } + if (res != 0x0) + mysql_free_result(res); + } + else if (strcasecmp(cmd,"rotatelog") == 0x0) { + writeLog(0,"Rotating Log File"); + fclose(logFile); + sprintf(logFileName,"./logs/tuved.%li.log", time(NULL)); + logFile = fopen(logFileName,"a"); + writeLog(0,"Log Rotated"); + } + else if (strcasecmp(cmd,"nextuser") == 0x0) { + sprintf(output,"MSG:TUveD:%s:The Next User is %s",chan,tmpChan->nextUser->user->userInfo.username); + tuveSendAllInChan(chan,0x0,output); + } + return(0x0); + } + +void *tuveCMD_Thread(void *threadid) { + int tid; + MYSQL_RES *res = 0x0; + MYSQL_ROW row; + + tid = (int)threadid; + writeLog(0,"Starting Bot Thread: [%d]\n", tid); + + res = dbQuery("SELECT count FROM videos ORDER BY count ASC LIMIT 1",1); + row = mysql_fetch_row(res); + if (row) + playCnt = atoi(row[0]); + mysql_free_result(res); + + while (1) { + sleep(5); + nextSong(); + chanMaint(); + } + pthread_exit(NULL); + } /* End tuveCMD_Thread() */ + +int chanMaint() { + tuveChanList_t *tmpChans; + time_t curTime = time(NULL); + int i = 0x0; + + pthread_mutex_lock(&chanMutex); + for (tmpChans = channels;tmpChans != 0x0;tmpChans = tmpChans->next) { + for (i = 0;i < CHAN_MAX_BANS;i++) { + if ((tmpChans->bans[i][0] != 0x0) && (tmpChans->bans[i][1] < curTime)) + tmpChans->bans[i][0] = 0x0; + } + } + pthread_mutex_unlock(&chanMutex); + return(0x0); + } + +int tuveBotSetVideo(char *chan,char *nick,int vid) { + MYSQL_RES *res = 0x0; + MYSQL_ROW row; + char output[256]; + + sprintf(output,"SELECT artist,title,file,length,classification,rating,count FROM videos WHERE vid = %i",vid); + + res = dbQuery(output,1); + + if ((res == 0x0) || (mysql_num_rows(res) == 0x0)) { + sprintf(output,"MSG:TUveD:%s:Sorry I'm Have SQL Troubles Today.",chan); + tuveSendAllInChan(chan,0x0,output); + } + else { + row = mysql_fetch_row(res); + sprintf(output,"UPDATE videos SET count = %i WHERE vid = %i",atoi(row[6])+1,vid); + dbQuery(output,0); + tuveBotSetSong(chan,nick,row[0],row[1],atoi(row[3]),row[2],atoi(row[4]),atoi(row[5]),vid); + } + + if (res != 0x0) + mysql_free_result(res); + return(0x0); + } + +int +tuveBotSetSong(char *channel,char *nick,char *artist,char *title,int length,char *file,int class,int rating,int vid) { + tuveChanList_t *tmpChan; + + char output[1024]; + int min, sec; + + songCount++; + playCount += length; + + tmpChan = findChan(channel); + + if (tmpChan->modes[CHAN_SCHEDULED] == 0x1) + goto jmpAhd; + + if (tmpChan->modes[CHAN_TIME] == 0x1) { + if (length > tmpChan->maxTime) { + return(0x0); + } + } + if (tmpChan->modes[CHAN_RATING] < rating) + return(0x0); + + if ((tmpChan->modes[CHAN_CLASS] != class) && (tmpChan->modes[CHAN_CLASS] != 0x0) && (class != 7)) + return(0x0); + + jmpAhd: + + tmpChan->comDelay -= length; + tmpChan->vidClass = class; + + min = length / 60; + sec = length % 60; + + tmpChan->videoTime = length; + tmpChan->videoEnd = length + time(NULL) + VIDE_PAD_TIME; + tmpChan->vid = vid; + sprintf(tmpChan->videoFile,"%s", file); + if (nick[strlen(nick)-1] == 's') + sprintf(tmpChan->videoChanTitle,"%s' Pick -> [%s - %s]",nick,vid,artist,title); + else + sprintf(tmpChan->videoChanTitle,"%s's Pick -> [%s - %s]",nick,vid,artist,title); + sprintf(tmpChan->videoTitle,"%s - %s",artist,title); + + sprintf(output,"CURPOS:%s:0:%s:%s:%i:%i",tmpChan->channel,file,tmpChan->videoTitle,length,vid); + writeLog(0,"[%s][%s]\n",output,channel); + tuveSendAllInChan(channel,0x0,output); + + sprintf(output,"MSG:TUveD:%s:Playing %s (%d:%.2d)",channel,tmpChan->videoChanTitle,min,sec); + tuveSendAllInChan(channel,0x0,output); +/* + + if (tmpChan->count != -1) { + if (tmpChan->nextUser != 0x0) + tmpChan->nextUser = tmpChan->nextUser->next; + if (tmpChan->nextUser == 0x0) + tmpChan->nextUser = tmpChan->users; + } +*/ + + tmpChan->count = MAX_COUNT; + + return(0x0); + } // tuveBotSetSong() + +int nextSong() { + char output[1024]; + tuveChanList_t *tmpChans; + MYSQL_RES *res = 0x0; + MYSQL_ROW row; + time_t curTime; + short lC; + + curTime = time(NULL); + + pthread_mutex_lock(&chanMutex); + + for (tmpChans = channels;tmpChans != 0x0;tmpChans = tmpChans->next) { + if ((tmpChans->modes[CHAN_LIVE] == 0x0) && (tmpChans->videoEnd < curTime)) { + /* Set point to starting user */ + + findUser: + if (tmpChans->modes[CHAN_SCHEDULED] == 0x1) + goto gotUser; + + if ((tmpChans->modes[CHAN_NOADS] == 0) && (tmpChans->comDelay <= 0)) + goto getCommercial; + + + //if (tmpChans->modes[CHAN_QUEUE] == 0x0) /* If Channel Has Queues Disabled Jump Right To Random */ + // goto getRandom; + + if (tmpChans->count == MAX_COUNT) { + lC = 0; + while (lC <= tmpChans->userCount) { + /* Reset Chan Counter */ + tmpChans->count = 0x0; + + if (tmpChans->nextUser == 0x0) + goto getRandom; + + tmpChans->nextUser = tmpChans->nextUser->next; + + /* Make sure we didn't go beyond the list */ + if (tmpChans->nextUser == 0x0) + tmpChans->nextUser = tmpChans->users; + + if (tmpChans->nextUser == 0x0) + goto sE; + + if (((tmpChans->modes[CHAN_QUEUE] == 0x0) && (tmpChans->nextUser->chanLevel >= 1)) || (tmpChans->modes[CHAN_QUEUE] == 0x1)) + if (tmpChans->nextUser->user->userInfo.queue == 0x1) + goto gotUser; + + lC++; + } + } + else if (tmpChans->nextUser != 0x0) + goto gotUser; + + + /* Find A Random Song */ + getRandom: + if (tmpChans->modes[CHAN_RANDOM] == 0x1) { + sprintf(output,"SELECT artist,title,file,length,vid,classification,rating,count,random_count FROM videos WHERE status = 0 AND rating <= %i",tmpChans->modes[CHAN_RATING]); + if (tmpChans->modes[CHAN_EXCLUSIVE]) + sprintf(output,"%s AND oid = %i",output,tmpChans->oid); //tmpChans->modes[CHAN_EXCLUSIVE]); + if (tmpChans->modes[CHAN_CLASS]) + sprintf(output,"%s AND classification = %i",output,tmpChans->modes[CHAN_CLASS]); + + sprintf(output,"%s ORDER BY random_count ASC, RAND() LIMIT 1", output); + + res = dbQuery(output,1); + if (res == 0x0) { + sprintf(output,"MSG:TUveD:%s:Sorry I'm Having SQL Troubles Today.",tmpChans->channel); + tuveSendAllInChan(tmpChans->channel,0x0,output); + } + else if (mysql_num_rows(res) == 0x0) { + sprintf(output,"MSG:TUveD:%s:Sorry Videos Matching The Channels Settings.",tmpChans->channel); + tuveSendAllInChan(tmpChans->channel,0x0,output); + } + else { + //mysql_data_seek(res,(random() % mysql_num_rows(res))); + row = mysql_fetch_row(res); + sprintf(output,"UPDATE videos SET random_count = %i WHERE vid = %s\n",atoi(row[8])+1,row[4]); + dbQuery(output,0); + tmpChans->count = MAX_COUNT; + tuveBotSetSong(tmpChans->channel,"TUveD",row[0],row[1],atoi(row[3]),row[2],atoi(row[5]),atoi(row[6]),atoi(row[4])); + } + if (res != 0x0) + mysql_free_result(res); + } + goto sE; + + getCommercial: + tmpChans->comDelay = COM_DELAY; + + getComAgain: + sprintf(output,"SELECT artist,title,file,length,vid,classification,rating,count FROM videos WHERE rating <= %i AND classification = 7 AND count <= %i",tmpChans->modes[CHAN_RATING],playCnt); + res = dbQuery(output,1); + + if (res == 0x0) { + sprintf(output,"MSG:TUveD:%s:Sorry I'm Having SQL Troubles Today.",tmpChans->channel); + tuveSendAllInChan(tmpChans->channel,0x0,output); + } + else if (mysql_num_rows(res) == 0x0) { + playCnt++; + mysql_free_result(res); + goto getComAgain; + } + else { + mysql_data_seek(res,(random() % mysql_num_rows(res))); + row = mysql_fetch_row(res); + sprintf(output,"UPDATE videos SET count = %i WHERE vid = %s\n",atoi(row[7])+1,row[4]); + dbQuery(output,0); + tmpChans->count = MAX_COUNT; + tuveBotSetSong(tmpChans->channel,"TUveD",row[0],row[1],atoi(row[3]),row[2],atoi(row[5]),atoi(row[6]),atoi(row[4])); + } + if (res != 0x0) + mysql_free_result(res); + goto sE; + + + gotUser: + if (tmpChans->nextUser->user->userInfo.queue == 0x1) { + if (((tmpChans->modes[CHAN_QUEUE] == 0x0) && (tmpChans->nextUser->chanLevel >= 1)) || (tmpChans->modes[CHAN_QUEUE] == 0x1)) { + sSendData(tmpChans->nextUser->user,"GETVIDEO"); + writeLog(0,"Need To Find Next Song For: %s, From User: %s\n",tmpChans->channel,tmpChans->nextUser->user->userInfo.username); + tmpChans->count++; + } + else if (tmpChans->modes[CHAN_SCHEDULED] == 0) { + tmpChans->count = MAX_COUNT; + goto findUser; + } + } + else if (tmpChans->modes[CHAN_SCHEDULED] == 0) { + tmpChans->count = MAX_COUNT; + goto findUser; + } + + sE: + asm("nop"); + } + } + + pthread_mutex_unlock(&chanMutex); + + return(0x0); + } /* End nextSong() */ + diff --git a/src/channel.c b/src/channel.c new file mode 100644 index 0000000..b953b0d --- /dev/null +++ b/src/channel.c @@ -0,0 +1,758 @@ +/* + (c) 2007 Christopher Olsen + $Id: channel.c,v 1.65 2009/02/18 19:37:34 reddawg Exp $ +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "tuved.h" + +tuveChanList_t *channels = 0x0; + +tuveChanList_t *addChan(const char *channel); + +/* + * This function will send the current channel list to the user specified w/ userConnection + * Information provided to that user is channel,user count,current song + * + * We traverse the channel list however there is no need to lock it because the other + * thread just reads this list and does not modify it. + * + */ +int tuveChanList(myConnections_t *userConnection) { + char data[512]; + tuveChanList_t *tmpChan = 0x0; + + /* The first line is header information for the data set */ + sSendData(userConnection,"LIST:Channel:users:Topic"); + + for (tmpChan = channels;tmpChan != 0x0;tmpChan = tmpChan->next) { + sprintf(data,"LIST:%s:%i:%s:%s",tmpChan->channel,tmpChan->userCount,tmpChan->topic,tmpChan->videoTitle); + sSendData(userConnection,data); + } + + return(0x0); + } /* End tuveChanList */ + +int tuveChanPart(const char *channel,myConnections_t *userConnection) { + char output[512]; + short inChan = 0x0; + + if (tuveRemoveFromChanList(channel,userConnection) == 0x1) { + writeLog(0,"ERROR: Can not remove %s from %s\n",userConnection->userInfo.username,channel); + inChan = 1; + } + if (tuveDelChan(channel,userConnection) == 0x1) { + writeLog(0,"ERROR: Can not remove %s from %s's List\n",channel,userConnection->userInfo.username); + inChan = 1; + } + + if (inChan == 0x0) { + sprintf(output,"MSG:TUveD:%s:%s Part (Left Channel)",channel,userConnection->userInfo.username); + tuveSendAllInChan(channel,0x0,output); + sprintf(output,"PART:%s:%s",channel,userConnection->userInfo.username); + tuveSendAllInChan(channel,0x0,output); + return(0x0); + } + + return(0x1); + } /* End tuveChanPart(); */ + +int tuveChanLive(const char *channel,const char *stream,const char *location) { + tuveChanList_t *tmpChan = 0x0; + char output[256]; + + if (stream == 0x0) + return(0x1); + + /* Find The Channel */ + tmpChan = findChan(channel); + if (tmpChan == 0x0) + return(0x1); + + strcpy(tmpChan->liveStream,stream); + + tmpChan->modes[CHAN_LIVE] = 0x1; + + //sprintf(output,"CURPOS:%s:-1:%s:Live Stream:0:0",tmpChan->channel,stream); + sprintf(output,"LIVE:%s:%s",location,stream); + tuveSendAllInChan(channel,0x0,output); + return(0x0); + } /* End int tuveChanLive(channel,stream) */ + +int tuveChanResume(const char *channel) { + char output[256]; + tuveChanList_t *tmpChan = 0x0; + tmpChan = findChan(channel); + + if (tmpChan == 0x0) + return(0x1); + + tmpChan->modes[CHAN_LIVE] = 0x0; + + sprintf(output,"CURPOS:%s:%li:%s:%s:%i:%i",tmpChan->channel,tmpChan->videoTime - (tmpChan->videoEnd - (time(NULL) + VIDE_PAD_TIME)),tmpChan->videoFile,tmpChan->videoTitle,tmpChan->videoTime,tmpChan->vid); + tuveSendAllInChan(channel,0x0,output); + return(0x0); + } + +/* + * Joins A User To A Channel + */ +int +tuveChanJoin(const char *channel,myConnections_t *userConnection) { + char output[256]; + tuveChanList_t *tmpChan = 0x0; + int min, sec; + int i = 0x0; + + tmpChan = findChan(channel); + + if (tmpChan != 0x0) { + for (i = 0x0;i < CHAN_MAX_BANS;i++) { + if (tmpChan->bans[i][0] == userConnection->userInfo.uid) { + sprintf(output,"MSG:TUveD:%s:You are banned from %s",channel,channel); + sSendData(userConnection,output); + return(0x1); + } + } + } + + if (tuveAddChanToUser(channel,userConnection) != 0x0) return(0x1); + + /* Send JOIN to all users in the channel */ + sprintf(output,"JOIN:%s:%s:%lld",channel,userConnection->userInfo.username,userConnection->userInfo.uid); + tuveSendAllInChan(channel,userConnection,output); + + tmpChan = findChan(channel); + assert(tmpChan); + + if (tmpChan->modes[CHAN_LIVE] == 1) { + //sSendData(userConnection,"CURPOS:%s:-1:%s:Live Stream:0:0",tmpChan->channel,tmpChan->liveStream); + sSendData(userConnection,"LIVE:1:%s\n",tmpChan->liveStream); + } + else { + sSendData(userConnection,"CURPOS:%s:%i:%s:%s:%i:%i",tmpChan->channel,tmpChan->videoTime - (tmpChan->videoEnd - (time(NULL) + VIDE_PAD_TIME)),tmpChan->videoFile,tmpChan->videoTitle,tmpChan->videoTime,tmpChan->vid); + + min = tmpChan->videoTime / 60; + sec = tmpChan->videoTime % 60; + + sSendData(userConnection,"MSG:TUveD:%s:Playing %s (%i:%.2i)",channel,tmpChan->videoChanTitle,min,sec); + } + + /* Notify people in the channel that someone has joined */ + sprintf(output,"MSG:TUveD:%s:%s (%s) has joined the channel.",channel,userConnection->userInfo.username,userConnection->host); + tuveSendAllInChan(channel,userConnection,output); + + return(0x0); + } + +int tuveDelUserChans(myConnections_t *userConnection,char *msg) { + tuveUserChans_t *tmpChan = 0x0; + tuveUserChans_t *tmpChan2 = 0x0; + + tmpChan = userConnection->userInfo.chans; + tmpChan2 = tmpChan; + + for (;tmpChan != 0x0;tmpChan = tmpChan->next) { + tuveSendAllInChan(tmpChan->channel,userConnection,"MSG:TUveD:%s:%s Quit (%s)",tmpChan->channel,userConnection->userInfo.username,msg); + tuveSendAllInChan(tmpChan->channel,userConnection,"PART:%s:%s",tmpChan->channel,userConnection->userInfo.username); + tuveRemoveFromChanList(tmpChan->channel,userConnection); + free(tmpChan2); + tmpChan2 = tmpChan->next; + } + + if (tmpChan2 != 0x0) { + free(tmpChan2); + } + + return(0x0); + } + +int tuveAddChanToUser(const char *channel,myConnections_t *userConnection) { + tuveUserChans_t *tmpChan = 0x0; + + if (userConnection->userInfo.chans == 0x0) { + userConnection->userInfo.chans = (tuveUserChans_t *)calloc(1,sizeof(tuveUserChans_t)); + userConnection->userInfo.chans->prev = 0x0; + userConnection->userInfo.chans->next = 0x0; + sprintf(userConnection->userInfo.chans->channel, "%s", channel); + } + else { + tmpChan = (tuveUserChans_t *)calloc(1,sizeof(tuveUserChans_t)); + tmpChan->prev = 0x0; + sprintf(tmpChan->channel, "%s", channel); + tmpChan->next = userConnection->userInfo.chans; + userConnection->userInfo.chans->prev = tmpChan; + userConnection->userInfo.chans = tmpChan; + } + + tuveAddToChanList(channel,userConnection); + + return(0x0); + } + +int tuveDelChan(const char *channel,myConnections_t *userConnection) { + tuveUserChans_t *tmpChan = 0x0; + + if (channel == 0x0) + return(0x1); + + for (tmpChan = userConnection->userInfo.chans;tmpChan != 0x0;tmpChan = tmpChan->next) { + if (!strcasecmp(tmpChan->channel,channel)) { + writeLog(2,"Found %s On %s And Removed\n",tmpChan->channel,userConnection->userInfo.username); + if (tmpChan->prev != 0x0) + tmpChan->prev->next = tmpChan->next; + else + userConnection->userInfo.chans = tmpChan->next; + if (tmpChan->next != 0x0) + tmpChan->next->prev = tmpChan->prev; + free(tmpChan); + return(0x0); + } + } + return(0x1); + } + +int tuveRemoveFromChanList(const char *channel,myConnections_t *userConnection) { + tuveChanList_t *tmpChannel = 0x0; + tuveUserList_t *tmpUsers = 0x0; + + tmpChannel = findChan(channel); + + if (tmpChannel == 0x0) { + writeLog(1,"tuveRemoveFromChanList: findChan failed!\n"); + return(0x1); + } + + tmpUsers = tmpChannel->users; + + writeLog(2,"Freeing User From Chan: %s\n",channel); + + pthread_mutex_lock(&chanMutex); + + for (;tmpUsers != 0x0;tmpUsers = tmpUsers->next) { + if (!strcasecmp(tmpUsers->user->userInfo.username,userConnection->userInfo.username)) { + writeLog(3,"Found and removed user: %s\n",tmpUsers->user->userInfo.username); + + if (tmpUsers->prev != 0x0) + tmpUsers->prev->next = tmpUsers->next; + else + tmpChannel->users = tmpUsers->next; + + if (tmpUsers->next != 0x0) + tmpUsers->next->prev = tmpUsers->prev; + +/* Undo Live + if (tmpChannel->modes[CHAN_LIVE] != 0) && (tmpChannel->d +*/ + + if (tmpChannel->nextUser == tmpUsers) { + if (tmpChannel->modes[CHAN_SCHEDULED] == 1) + tmpChannel->modes[CHAN_SCHEDULED] = 0; + + if (tmpUsers->next != 0x0) + tmpChannel->nextUser = tmpUsers->next; + else if (tmpChannel->users != 0x0) + tmpChannel->nextUser = tmpChannel->users; + else + tmpChannel->nextUser = 0x0; + } + tmpChannel->count = 0x0; + + tmpChannel->userCount--; + + free(tmpUsers); + writeLog(3,"User Freed\n"); + + if (tmpChannel->users == 0x0) { + writeLog(3,"Channel %s Has No More Users Freeing.\n",tmpChannel->channel); + + if (tmpChannel->prev != 0x0) + tmpChannel->prev->next = tmpChannel->next; + else + channels = tmpChannel->next; + + if (tmpChannel->next != 0x0) + tmpChannel->next->prev = tmpChannel->prev; + + channelCount--; + free(tmpChannel); + + writeLog(3,"Channel Freed.\n"); + } + pthread_mutex_unlock(&chanMutex); + return(0x0); + } + } + + pthread_mutex_unlock(&chanMutex); + return(0x1); + } + +int +tuveAddToChanList(const char *channel,myConnections_t *userConnection) { + tuveChanList_t *tmpChannel = 0x0; + tuveUserList_t *tmpUser = 0x0; + + char output[1024]; + char nick[MAX_USER_LEN + 1]; + + int len = 0; + + tmpChannel = findChan(channel); + + // tmpChannel is okay to be null here + + if (tmpChannel == 0x0) { + writeLog(2,"Channel %s does not exist creating now.\n",channel); + tmpChannel = addChan(channel); + } + + for (tmpUser = tmpChannel->users;tmpUser != 0x0;tmpUser = tmpUser->next) { + if (!strcasecmp(tmpUser->user->userInfo.username,userConnection->userInfo.username)) { + writeLog(2,"User: %s already in channel %s\n",userConnection->userInfo.username,channel); + return(0x0); + } + } + + tmpUser = (tuveUserList_t *)calloc(1,sizeof(tuveUserList_t)); + + tmpUser->user = userConnection; + tmpUser->prev = 0x0; + + pthread_mutex_lock(&chanMutex); + + if (tmpChannel->users == 0x0) { + tmpUser->next = 0x0; + tmpUser->chanLevel = 0x1; + tmpChannel->users = tmpUser; + } + else { + tmpUser->next = tmpChannel->users; + tmpUser->chanLevel = 0x0; + tmpChannel->users->prev = tmpUser; + tmpChannel->users = tmpUser; + } + + if (tmpChannel->nextUser == 0x0) { + tmpChannel->nextUser = tmpUser; + tmpChannel->count = 0x0; + } + + tmpChannel->userCount++; + + memset(output,0x0,256); + + /* Send the new user the channel list */ + for (tmpUser = tmpChannel->users;tmpUser != 0x0;tmpUser = tmpUser->next) { + if (tmpUser->chanLevel == 0) + strcpy(nick,tmpUser->user->userInfo.username); + else + sprintf(nick,"&%s",tmpUser->user->userInfo.username); + + if (strlen(output) > 0) + sprintf(output,"%s:%s:%lld",output,nick,tmpUser->user->userInfo.uid); //tmpUser->user->userInfo.username); + else + sprintf(output,"JOIN:%s:%s:%lld",tmpChannel->channel,nick,tmpUser->user->userInfo.uid); //tmpUser->user->userInfo.username); + } + + if (strlen(output) > 0) { + sprintf(output,"%s",output); + sSendData(userConnection,output); + } + + sprintf(output,"TOPIC:%s:%s",tmpChannel->channel,tmpChannel->topic); + sSendData(userConnection,output); + sSendData(userConnection,"MSG:TUveD:%s:Topic for %s: %s",tmpChannel->channel,tmpChannel->channel,tmpChannel->topic); + + len = sprintf(output,"MSG:TUveD:%s:Topic was set by %s on %s",tmpChannel->channel,tmpChannel->topicSetBy, ctime(&tmpChannel->topicSet)); + output[len-1] = '\0'; + sSendData(userConnection,output); + + if (tmpChannel->modes[CHAN_TIME] == 1) { + sSendData(userConnection,"MSG:TUveD:%s:This channel has a time limit of %i seconds for media.",tmpChannel->channel,tmpChannel->maxTime); + sSendData(userConnection,"MODE:%s:T:1:%i",tmpChannel->channel,tmpChannel->maxTime); + } + else { + sprintf(output,"MODE:%s:T:0",tmpChannel->channel); + sSendData(userConnection,output); + } + + if (tmpChannel->modes[CHAN_QUEUE] == 1) + sprintf(output,"MODE:%s:Q:1",tmpChannel->channel); + else + sprintf(output,"MODE:%s:Q:0",tmpChannel->channel); + sSendData(userConnection,output); + + if (tmpChannel->modes[CHAN_RANDOM] == 1) + sprintf(output,"MODE:%s:R:1",tmpChannel->channel); + else + sprintf(output,"MODE:%s:R:0",tmpChannel->channel); + sSendData(userConnection,output); + + sprintf(output,"MODE:%s:A:%i",tmpChannel->channel,tmpChannel->modes[CHAN_RATING]); + sSendData(userConnection,output); + + sprintf(output,"MODE:%s:C:%i",tmpChannel->channel,tmpChannel->modes[CHAN_CLASS]); + sSendData(userConnection,output); + + if (tmpChannel->modes[CHAN_EXCLUSIVE] != 0) + sprintf(output,"MODE:%s:E:%i",tmpChannel->channel,tmpChannel->oid); + else + sprintf(output,"MODE:%s:E:0",tmpChannel->channel); + sSendData(userConnection,output); + + + writeLog(2,"Added user: %s to Channel: %s\n",userConnection->userInfo.username,channel); + pthread_mutex_unlock(&chanMutex); + + return(0x0); + } + +tuveChanList_t *findChan(const char *channel) { + tuveChanList_t *tmpChannel = 0x0; + + assert(channel); + + pthread_mutex_lock(&chanMutex); + + for (tmpChannel = channels;tmpChannel != 0x0;tmpChannel = tmpChannel->next) { + + if (!strcasecmp(tmpChannel->channel,channel)) { + pthread_mutex_unlock(&chanMutex); + return(tmpChannel); + } + } + + pthread_mutex_unlock(&chanMutex); + return(0x0); + } + +/* + * Add A Channel To The Global Channel List + */ +tuveChanList_t *addChan(const char *channel) { + tuveChanList_t *tmpChannel = 0x0; + + pthread_mutex_lock(&chanMutex); + + channelCount++; + + if (channels == 0x0) { + channels = (tuveChanList_t *)calloc(1,sizeof(tuveChanList_t)); + channels->next = 0x0; + channels->prev = 0x0; + channels->users = 0x0; + channels->modes[CHAN_QUEUE] = 0x1; + channels->modes[CHAN_RATING] = 0x2; + channels->modes[CHAN_CLASS] = 0x1; + sprintf(channels->channel, "%s", channel); + sprintf(channels->topic,"No Topic Set"); + sprintf(channels->topicSetBy,"TUveD"); + channels->topicSet = time(NULL); + sprintf(channels->videoChanTitle,"No Video"); + sprintf(channels->videoFile,"NA"); + channels->videoEnd = 0x0; + channels->comDelay = COM_DELAY; + writeLog(2,"ADDED CHAN1\n"); + tmpChannel = channels; + } + else { + tmpChannel = (tuveChanList_t *)calloc(1,sizeof(tuveChanList_t)); + sprintf(tmpChannel->channel, "%s", channel); + sprintf(tmpChannel->topic,"No Topic Set"); + sprintf(tmpChannel->topicSetBy,"TUveD"); + tmpChannel->topicSet = time(NULL); + sprintf(tmpChannel->videoChanTitle,"NoVideo"); + sprintf(tmpChannel->videoFile,"NA"); + tmpChannel->videoEnd = 0x0; + tmpChannel->next = channels; + tmpChannel->prev = 0x0; + tmpChannel->users = 0x0; + tmpChannel->modes[CHAN_QUEUE] = 0x1; + tmpChannel->modes[CHAN_RATING] = 0x2; + tmpChannel->modes[CHAN_CLASS] = 0x1; + tmpChannel->comDelay = COM_DELAY; + channels->prev = tmpChannel; + channels = tmpChannel; + writeLog(2,"ADDED CHAN2\n"); + } + + pthread_mutex_unlock(&chanMutex); + + return(tmpChannel); + } + +int tuveSendAllInUsersChans(myConnections_t *userConnection,char *output) { + tuveUserChans_t *tmpChans = userConnection->userInfo.chans; + + for (;tmpChans != 0x0;tmpChans = tmpChans->next) { + tuveSendAllInChan(tmpChans->channel,0x0,output); + } + return(0x0); + } + +int tuveSendAllInChan(const char *channel,myConnections_t *userConnection,char const * __restrict fmt, ...) { + tuveChanList_t *tmpChannel = 0x0; + tuveUserList_t *tmpUsers = 0x0; + char data[2048]; + va_list ap; + int len = 0; + + tmpChannel = findChan(channel); + + if (tmpChannel == 0x0) { + writeLog(1,"findChan Failed!\n"); + return(0x1); + } + + + //Dont see why i need a thread lock here + + tmpUsers = tmpChannel->users; + + va_start(ap,fmt); + len = vsnprintf(data,2046,fmt,ap); + va_end(ap); +// data[len++] = '\r'; + data[len++] = '\n'; + + //THIS IS A TEMP SOLUTION I HATE IT! + + for (;tmpUsers != 0x0;tmpUsers = tmpUsers->next) { + if (userConnection == 0x0) + send(tmpUsers->user->fd,data,len,MSG_NOSIGNAL);//sSendData(tmpUsers->user,data); + else if (strcasecmp(tmpUsers->user->userInfo.username,userConnection->userInfo.username)) + send(tmpUsers->user->fd,data,len,MSG_NOSIGNAL);//sSendData(tmpUsers->user,data); + } + + return(0x0); + } + +int tuveSetTopic(myConnections_t *userConnection,char *chan,char *topic) { + char output[1024]; + tuveChanList_t *tmpChannel = 0x0; + + tmpChannel = findChan(chan); + + if (tmpChannel == 0x0) { + writeLog(1,"findChan Failed: SetTopic\n"); + return(0x1); + } + + strncpy(tmpChannel->topic,topic,128); + sprintf(output,"TOPIC:%s:%s",chan,tmpChannel->topic); + tuveSendAllInChan(chan,0x0,output); + sprintf(output,"MSG:TUveD:%s:%s has set the topic to: %s",chan,userConnection->userInfo.username,tmpChannel->topic); + tuveSendAllInChan(chan,0x0,output); + + tmpChannel->topicSet = time(NULL); + sprintf(tmpChannel->topicSetBy, "%s", userConnection->userInfo.username); + + return(0x0); + } + +int tuveKick(myConnections_t *byConnection,char *chan,char *nick,char *msg) { + tuveChanList_t *tmpChannel = 0x0; + myConnections_t *userConnection = 0x0; + char output[1024]; + + tmpChannel = findChan(chan); + + if (tmpChannel == 0x0) { + writeLog(1,"findchan Failed: Kick\n"); + return(0x1); + } + + userConnection = findNickOnChan(nick,chan); + + if (userConnection == 0x0) { + sSendData(byConnection,"MSG:TUveD:STATUS:%s Not On %s",nick,chan); + return(0x1); + } + + sSendData(userConnection,"KICK:%s:%s:%s",chan,byConnection->userInfo.username,msg); + + + nick = userConnection->userInfo.username; + + if (tuveRemoveFromChanList(chan,userConnection) == 0x1) + writeLog(0,"ERROR: Can not remove %s from %s\n",userConnection->userInfo.username,chan); + if (tuveDelChan(chan,userConnection) == 0x1) + writeLog(0,"ERROR: Can not remove %s from %s's List\n",chan,userConnection->userInfo.username); + + + sprintf(output,"MSG:TUveD:%s:%s has been kicked by %s, Reason: %s",chan,nick,byConnection->userInfo.username,msg); + tuveSendAllInChan(chan,0x0,output); + + sprintf(output,"PART:%s:%s",chan,nick); + tuveSendAllInChan(chan,0x0,output); + + writeLog(0,"Kicked %s\n",output); + + tuveChanJoin("#doghouse",userConnection); + + return(0x0); + } + +int tuveBan(myConnections_t *byConnection,const char *channel,const char *nick,int length) { + char output[1024]; + tuveChanList_t *tmpChannel = 0x0; + myConnections_t *userConnection = 0x0; + int i = 0x0; + + tmpChannel = findChan(channel); + + if (tmpChannel == 0x0) { + writeLog(1,"findChan Failed: Ban\n"); + return(0x1); + } + + if (tuveFindChanLevel(channel,byConnection,0) < 1) { + sSendData(byConnection,"MSG:TUveD:STATUS:You do not have permission to ban."); + return(0x0); + } + + userConnection = findNick(nick); + + if (userConnection == 0x0) { + writeLog(1,"nick Filed: Ban\n"); + return(0x1); + } + + sSendData(userConnection,"BAN"); + + for (i = 0x0;i < CHAN_MAX_BANS;i++) { + if (tmpChannel->bans[i][0] == 0x0) { + tmpChannel->bans[i][0] = userConnection->userInfo.uid; + tmpChannel->bans[i][1] = length + time(NULL); + break; + } + } + + sprintf(output,"MSG:TUveD:%s:%s has been banned for %i seconds",channel,userConnection->userInfo.username,length); + tuveSendAllInChan(channel,0x0,output); + + return(0x0); + } + +int tuveUnBan(const char *channel,const char *nick) { + char output[1024]; + tuveChanList_t *tmpChannel = 0x0; + myConnections_t *userConnection = 0x0; + int i = 0x0; + + tmpChannel = findChan(channel); + + if (tmpChannel == 0x0) { + writeLog(1,"findchan Failed: Ban\n"); + return(0x1); + } + + userConnection = findNick(nick); + + if (userConnection == 0x0) { + writeLog(1,"nick Filed: Ban\n"); + return(0x1); + } + + for (i = 0x0;i < CHAN_MAX_BANS;i++) { + if (tmpChannel->bans[i][0] == userConnection->userInfo.uid) { + tmpChannel->bans[i][0] = 0x0; + break; + } + } + + sprintf(output,"MSG:TUveD:%s:%s has been unbanned",channel,userConnection->userInfo.username); + tuveSendAllInChan(channel,0x0,output); + + return(0x0); + } + +int tuveVerifyBan(const char *channel,const char *nick) { + tuveChanList_t *tmpChannel = 0x0; + myConnections_t *userConnection = 0x0; + int i = 0x0; + + tmpChannel = findChan(channel); + + if (tmpChannel == 0x0) { + writeLog(1,"findchan Failed: Ban\n"); + return(0x1); + } + + userConnection = findNick(nick); + + if (userConnection == 0x0) { + writeLog(1,"nick Filed: Ban\n"); + return(0x1); + } + + for (i = 0x0;i < CHAN_MAX_BANS;i++) { + if (tmpChannel->bans[i][0] == userConnection->userInfo.uid) { + return(0x1); + } + } + + return(0x0); + } + +myConnections_t *findNickOnChan(const char *nick,const char *channel) { + tuveChanList_t *tmpChannel = 0x0; + tuveUserList_t *tmpUser = 0x0; + + tmpChannel = findChan(channel); + if (tmpChannel == 0x0) + return(0x0); + + for (tmpUser = tmpChannel->users;tmpUser != 0x0;tmpUser = tmpUser->next) { + if (!strcasecmp(tmpUser->user->userInfo.username,nick)) + return(tmpUser->user); + } + return(0x0); + } + +int tuveFindChanLevel(const char *channel,myConnections_t *userConnection,int eo) { + tuveChanList_t *tmpChannel = 0x0; + tuveUserList_t *tmpUser = 0x0; + + if ((userConnection->userInfo.modes[USER_OVERLORD] == 1) && (eo != 1)) + return(0x1); + + tmpChannel = findChan(channel); + if (tmpChannel == 0x0) + return(0x0); + + for (tmpUser = tmpChannel->users;tmpUser != 0x0;tmpUser = tmpUser->next) { + if (tmpUser->user == userConnection) + return(tmpUser->chanLevel); + } + return(-1); + } + +int tuveChanOp(const char *channel,const char *nick,int level) { + tuveChanList_t *tmpChannel = 0x0; + tuveUserList_t *tmpUser = 0x0; + char output[512]; + + tmpChannel = findChan(channel); + if (tmpChannel == 0x0) + return(0x1); + + writeLog(3,"Looking for %s on %s\n",nick,channel); + for (tmpUser = tmpChannel->users;tmpUser != 0x0;tmpUser = tmpUser->next) { + if (!strcasecmp(tmpUser->user->userInfo.username,nick)) { + tmpUser->chanLevel = level; + sprintf(output,"MODE:%s:O:%i:%s",tmpChannel->channel,level,tmpUser->user->userInfo.username); + tuveSendAllInChan(channel,0x0,output); + return(0x0); + } + } + return(0x1); + } diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..a8c9260 --- /dev/null +++ b/src/config.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include + +int parseConfig() { + config_t cfg; + + config_setting_t *setting; + + config_init(&cfg); + + if (access("./tuved.cfg", F_OK) != -1) { + if (!config_read_file(&cfg, "./tuved.cfg")) { + fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); + config_destroy(&cfg); + return(EXIT_FAILURE); + } + } + else if (access("/usr/local/etc/tuved.cfg", F_OK) != -1) { + if (!config_read_file(&cfg, "/usr/local/etc/tuved.cfg")) { + fprintf(stderr, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg)); + config_destroy(&cfg); + return(EXIT_FAILURE); + } + } + else { + config_destroy(&cfg); + return(EXIT_FAILURE); + } + + setting = config_lookup(&cfg, "daemon"); + + if (setting != NULL) { + int i = 9999; + + config_setting_lookup_int(setting, "port", &i); + + //printf("port: %i", i); + } + + return(0); + +} diff --git a/src/lib.c b/src/lib.c new file mode 100644 index 0000000..5b0aff1 --- /dev/null +++ b/src/lib.c @@ -0,0 +1,29 @@ +#include +#include "tuved.h" + + +int formatTime(time_t sTime,char *output) { + int day,hour,min,sec; + time_t curTime; + + curTime = sTime; + + day = curTime / 86400; + curTime -= (86400 * day); + hour = curTime / 3600; + curTime -= (3600 * hour); + min = curTime / 60; + curTime -= (60 * min); + sec = curTime; + + if (day) + sprintf(output, "%i:%.2d:%.2d:%.2d", day, hour, min, sec); + else + if (hour) sprintf(output, "%.2d:%.2d:%.2d", hour, min, sec); + else + if (min) sprintf(output, "%.2d:%.2d", min, sec); + else + sprintf(output, "%.2d", sec); + + return(sTime); + } diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..30319c2 --- /dev/null +++ b/src/main.c @@ -0,0 +1,159 @@ +/***************************************************************************************** + Copyright (c) 2002-2004, 2005, 2007 Ubix Technology Group + All rights reserved. + + $Id: main.c,v 1.21 2008/06/30 18:55:10 reddawg Exp $ + +*****************************************************************************************/ + +#include +#include +#include +#include + +#include "tuved.h" + +FILE *logFile = 0x0; +FILE *pidFile = 0x0; +int logLevel = 1; +pthread_mutex_t chanMutex = PTHREAD_MUTEX_INITIALIZER; +time_t startTime; +int userCount = 0; +int channelCount = 0; +int songCount = 0; +int playCount = 0; +char logFileName[64]; + +void usage(); + +int main(int argc,char **argv) { + fd_set readset; + int ch; + int readSocks = 0x0; + int doFork = 0x1; + int rc = 0x0; + int *param = (int *)malloc(2 * sizeof(int)); + time_t seconds = 0; + struct timeval timeout = {30,0}; + + /* Get our start time */ + startTime = time(NULL); + + while ((ch = getopt(argc,argv,"sl:nd:c:")) != -1) { + switch (ch) { + case 's': + logFile = stdout; + break; + case 'l': + logFile = fopen(optarg,"a"); + break; + case 'n': + doFork = 0; + break; + case 'd': + logLevel = atoi(optarg); + if (logLevel < 1) + logLevel = 1; + break; + case 'c': + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + parseConfig(); + + + /* Prepare log file */ + if (logFile == 0x0) { + // XXX MrOlsen: Do I want to use time any more? - sprintf(logFileName,"/var/log/tuved.%i.log", time(NULL)); + sprintf(logFileName,"/var/log/tuved.log"); + logFile = fopen(logFileName,"a"); + } + + /* Fork into background unless specified not to do so */ + if (doFork == 1) + if (fork() != 0x0) + exit(0x0); + + /* Create PID file */ + pidFile = fopen("/var/run/tuved.pid", "w"); + fprintf(pidFile, "%d", getpid()); + fclose(pidFile); + + writeLog(0,"TUve Daemon Starting: %i\n",startTime); + + if (dbInit() == 0x1) + exit(0x1); + + /* Reset Server Sessions */ + dbQuery("DELETE FROM active",0); + + srandom(time(NULL)); + + pthread_mutex_init(&chanMutex, NULL); + + pthread_t threads[NUM_THREADS]; + rc = pthread_create(&threads[0], NULL, tuveCMD_Thread, param); + + + + + + sStartListener(); + + while (1) { + + /* Get Socket Set For Readable Connections */ + if (sGetConnections(&readset) == 0x0) { + writeLog(0,"Error: sGetConnections Failed\nShutting Down\n"); + exit(0x1); + } + + readSocks = select(highSock+1,&readset,0x0,0x0,&timeout); + + if (readSocks < 0) { + writeLog(0,"Error: select Failed\nShutting Down\n"); + exit(0x1); + } + else if (readSocks > 0) { + sProcessConnections(&readset); + } + + if ((seconds + PING_INTERVAL) < time(NULL)) { + sSendPing(seconds); + seconds = time(NULL); + } + + /* Clean up old connections */ + sCleanConnections(); + + /* Flush the log file */ + fflush(logFile); + } + + return(0); + } + +void usage() { + printf("%s\n","usage: tuved -n -s [-l logfile] [-d debuglevel]"); + exit(1); + } + + +int writeLog(int level,char const * __restrict fmt, ...) { + int ret; + va_list ap; + + if (level > logLevel) + return(0x0); + + va_start(ap, fmt); + ret = vfprintf(logFile, fmt, ap); + va_end(ap); + + return(ret); + } /* End writeLog(); */ diff --git a/src/mysql.c b/src/mysql.c new file mode 100644 index 0000000..71bed1b --- /dev/null +++ b/src/mysql.c @@ -0,0 +1,61 @@ +#include + +#include "tuved.h" + +MYSQL *conn = 0x0; + +pthread_mutex_t mysqlMutex = PTHREAD_MUTEX_INITIALIZER; + + +int dbInit() { + + conn = mysql_init(0x0); + + if (conn == NULL) { + writeLog(0,"mysql_init() failed (probably out of memory)\n."); + return(0x1); + } + + my_bool reconnect = 1; + + if (mysql_options(conn,MYSQL_OPT_RECONNECT, &reconnect) != 0x0) + writeLog(0,"mysql_options() failed: To Set Reconnect\n"); + + if (!mysql_real_connect(conn,MYSQL_HOST_NAME,MYSQL_USERNAME,MYSQL_PASSWORD,MYSQL_DB_NAME,0,NULL,0)) { + writeLog(0,"mysql_real_connect() failed: Error %u (%s)\n.", mysql_errno(conn), mysql_error(conn)); + return(0x1); + } + + + pthread_mutex_init(&mysqlMutex, NULL); + + writeLog(0,"Sucessful connection to the MySQL Database.\n"); + + return(0x0); + } + +MYSQL_RES *dbQuery(const char *query,short store) { + MYSQL_RES *res_set = 0x0; + + pthread_mutex_lock(&mysqlMutex); + + writeLog(0,"Query: %s\n",query); + + if (mysql_query(conn,query) != 0x0) { + writeLog(0,"mysql_query() failed: Error %u (%s)\n.", mysql_errno(conn), mysql_error(conn)); + pthread_mutex_unlock(&mysqlMutex); + return(0x0); + } + + if (store == 1) { + res_set = mysql_store_result(conn); + if (res_set == 0x0) { + writeLog(0,"mysql_store_result() failed: Error %u (%s)\n.", mysql_errno(conn), mysql_error(conn)); + pthread_mutex_unlock(&mysqlMutex); + return(0x0); + } + } + + pthread_mutex_unlock(&mysqlMutex); + return(res_set); + } diff --git a/src/nick.c b/src/nick.c new file mode 100644 index 0000000..98ee048 --- /dev/null +++ b/src/nick.c @@ -0,0 +1,97 @@ +#include +#include + +#include "tuved.h" + + +int +tuveVerifyNick(char *nick) { + int i = 0x0; + int len = 0x0; + + assert(nick); + assert(connections); + + len = strlen(nick); + + for (i = 0x0;i < len;i++) { + if ((nick[i] < 48) || (nick[i] > 122) || ((nick[i] > 57) && (nick[i] < 65)) || ((nick[i] > 90) && (nick[i] < 97))) + return(0x1); + } + + + + if (findNick(nick) != 0x0) + return(0x1); + + return(0x0); +} // tuveVerifyNick() + + +myConnections_t *findNick(const char *nick) { + if (nick == 0x0) + return(0x0); + + myConnections_t *tmpConnection = 0x0; + for (tmpConnection = connections;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { + if (!strcasecmp(nick,tmpConnection->userInfo.username)) + return(tmpConnection); + } + return(0x0); + } + +int tuveWhois(myConnections_t *userConnection,char *nick) { + myConnections_t *user = 0x0; + tuveUserChans_t *chans = 0x0; + char output[256]; + char channel[MAX_CHAN_LEN + 1]; + int len = 0; + + if (strlen(nick) > MAX_USER_LEN) + return(0x0); + + user = findNick(nick); + + if (user == 0x0) { + sprintf(output,"MSG:TUveD:STATUS:%s Not Found",nick); + sSendData(userConnection,output); + return(0x0); + } + + sprintf(output,"MSG:TUveD:STATUS:%s is %s",user->userInfo.username,user->host); + sSendData(userConnection,output); + len = sprintf(output,"MSG:TUveD:STATUS:%s Signed On %s",user->userInfo.username,ctime(&user->signedOn)); + output[len -1] = '\0'; + sSendData(userConnection,output); + + sprintf(output,"MSG:TUveD:STATUS:%s Is running %4.2f",user->userInfo.username,user->userInfo.version); + sSendData(userConnection,output); + + if (user->userInfo.modes[USER_OVERLORD] == 1) { + sprintf(output,"MSG:TUveD:STATUS:%s Is an Evil Overlord",user->userInfo.username); + sSendData(userConnection,output); + } + if ((time(NULL) - user->userInfo.idle) > 30) { + sprintf(output,"MSG:TUveD:STATUS:%s Has been idle for %li seconds.", user->userInfo.username, time(NULL) - user->userInfo.idle); + sSendData(userConnection,output); + } + + if (user->userInfo.chans != 0x0) { + memset(output,0x0,256); + for (chans = user->userInfo.chans;chans != 0x0;chans = chans->next) { + + if (tuveFindChanLevel(chans->channel,user,1) == 0) + strcpy(channel,chans->channel); + else + sprintf(channel,"&%s",chans->channel); + + if (strlen(output) == 0) + sprintf(output,"MSG:TUveD:STATUS:%s Is on channel(s) %s",user->userInfo.username,channel); + else + sprintf(output,"%s,%s",output,channel); + } + sSendData(userConnection,output); + } + + return(0x0); + } diff --git a/src/server.c b/src/server.c new file mode 100644 index 0000000..6a49e76 --- /dev/null +++ b/src/server.c @@ -0,0 +1,45 @@ +#include + +#include "tuved.h" + + +int tuveStatus(myConnections_t *userConnection) { + char output[512]; + int day,hour,min,sec; + time_t curTime; + + curTime = time(NULL); + + + sprintf(output,"MSG:TUveD:STATUS:Server on-line since: %s",ctime(&startTime)); + sSendData(userConnection,output); + curTime -= startTime; + day = curTime / 86400; + curTime -= (86400 * day); + hour = curTime / 3600; + curTime -= (3600 * hour); + min = curTime / 60; + curTime -= (60 * min); + sec = curTime; + sprintf(output,"MSG:TUveD:STATUS:Server is running TUveD %s",VERSION); + sSendData(userConnection,output); + sprintf(output,"MSG:TUveD:STATUS:Server has been running for %i days %i hours %i min %.2i sec",day,hour,min,sec); + sSendData(userConnection,output); + sprintf(output,"MSG:TUveD:STATUS:There are currently %i users online.",userCount); + sSendData(userConnection,output); + sprintf(output,"MSG:TUveD:STATUS:There are currently %i channels active.",channelCount); + sSendData(userConnection,output); + curTime = playCount; + day = curTime / 86400; + curTime -= (86400 * day); + hour = curTime / 3600; + curTime -= (3600 * hour); + min = curTime / 60; + curTime -= (60 * min); + sec = curTime; + sprintf(output,"MSG:TUveD:STATUS:There have been %i videos played. For a total Playtime of %i days %i hours %i min %.2i secs",songCount,day,hour,min,sec); + sSendData(userConnection,output); + + return(0x0); +} // tuveStatus() + diff --git a/src/socket.c b/src/socket.c new file mode 100644 index 0000000..a602338 --- /dev/null +++ b/src/socket.c @@ -0,0 +1,310 @@ +/* + tuved - Socket Server + (c) 2007 Christopher Olsen + + $Id: socket.c,v 1.30 2008/02/05 01:27:29 reddawg Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tuved.h" + +myConnections_t *connections = 0x0; + +int listenerFD = 0x0; +int highSock = 0x0; + +int sStartListener() { + int optVal = 0x1; + + struct sockaddr_in myAddr; // my address information + + if ((listenerFD = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + perror("socket"); + exit(1); + } + + if (setsockopt(listenerFD, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(int)) == -1) { + perror("setsockopt"); + exit(1); + } + + myAddr.sin_family = AF_INET; // host byte order + myAddr.sin_port = htons(MYPORT); // short, network byte order + myAddr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP + memset(myAddr.sin_zero, '\0', sizeof myAddr.sin_zero); + + if (bind(listenerFD, (struct sockaddr *)&myAddr, sizeof(struct sockaddr)) == -1) { + perror("bind"); + exit(1); + } + + if (listen(listenerFD, BACKLOG) == -1) { + perror("listen"); + exit(1); + } + + fcntl(listenerFD, F_SETFL, fcntl(listenerFD, F_GETFL, 0) | O_NONBLOCK); + + sAddConnection(listenerFD,"127.0.0.1"); + + writeLog(2,"Listener FD: [%i]\n",listenerFD); + + return(0x0); + } + +ssize_t sReadSocket(int socketFD,void *buffer,size_t length) { + ssize_t recLen = 0x0; + + recLen = read(socketFD,buffer,length); + + if (recLen <= 2) + recLen = 0x0; + + return(recLen); + } + +int sGetConnection() { + int newFD = 0x0; // New Socket; + socklen_t sin_size; + struct sockaddr_in remoteAddr; + struct hostent *hp; + sin_size = sizeof(struct sockaddr_in); + + if ((newFD = accept(listenerFD, (struct sockaddr *)&remoteAddr, &sin_size)) == -1) { + perror("accept"); + } + + + /* Add Socket */ + hp = gethostbyaddr((char *)&remoteAddr.sin_addr,sizeof(remoteAddr.sin_addr),AF_INET); + sAddConnection(newFD,(hp ? hp->h_name : inet_ntoa(remoteAddr.sin_addr))); + + /* Return */ + return(0x0); + } + +int sAddConnection(int socketFD,char *host) { + myConnections_t *tmpConnection = 0x0; + + writeLog(2,"Adding Socket: [%i]\n",socketFD); + + userCount++; + + if (connections == 0x0) { + connections = (myConnections_t *)calloc(1,sizeof(myConnections_t)); + connections->prev = 0x0; + connections->next = 0x0; + connections->fd = socketFD; + connections->signedOn = time(NULL); + sprintf(connections->host, "%s", host); + } + else { + tmpConnection = (myConnections_t *)calloc(1,sizeof(myConnections_t)); + //memset(tmpConnection,0x0,sizeof(myConnections_t)); + tmpConnection->fd = socketFD; + tmpConnection->prev = connections; + tmpConnection->next = connections->next; + tmpConnection->signedOn = time(NULL); + sprintf(tmpConnection->host, "%s", host); + if (connections->next != 0x0) + connections->next->prev = tmpConnection; + + connections->next = tmpConnection; + } + writeLog(2,"Socket Added\n"); + + return(0x0); + } + +myConnections_t *sFindConnection(int fd) { + myConnections_t *tmpConnection = 0x0; + + for (tmpConnection = connections->next;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { + if (tmpConnection->fd == fd) + return(tmpConnection); + } + + return(0x0); + } + +int sCleanConnections() { + myConnections_t *tmpConnection = 0x0; + myConnections_t *delConnection = 0x0; + char output[256]; + + for (tmpConnection = connections->next;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { + if (tmpConnection->userInfo.status == -1) { + // Set temporary pointer to connection so we can free it later + delConnection = tmpConnection; + + // Hard close the socket so it doesn't linger + close(tmpConnection->fd); + + writeLog(2,"Removed User: [%s]\n",tmpConnection->userInfo.username); + + // If connection has a previous pointer which it always should adjust it's next pointer to match current next + if (tmpConnection->prev != 0x0) + tmpConnection->prev->next = tmpConnection->next; + + // If connection has a next pointer which it may not adjust it to point to match our current previous + if (tmpConnection->next != 0x0) + tmpConnection->next->prev = tmpConnection->prev; + + // Adjust tmpConnection to match our previous pointer which should always happen + if (tmpConnection->prev != 0x0) + tmpConnection = tmpConnection->prev; + else + tmpConnection = tmpConnection->next; + + userCount--; + + if (delConnection->userInfo.ident == 2) { + sprintf(output,"DELETE FROM active WHERE userid = %lld",delConnection->userInfo.uid); + dbQuery(output,0); + } + + //Free the bad connection + free(delConnection); + writeLog(2,"Remove Completed\n"); + } + } + return(0x0); + } + +int sRemoveConnection(int socketFD) { + myConnections_t *tmpConnection = 0x0; + char output[256]; + + writeLog(2,"Removing Socket: %i\n",socketFD); + + for (tmpConnection = connections->next;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { + if (tmpConnection->fd == socketFD) { + + tmpConnection->prev->next = tmpConnection->next; + + if (tmpConnection->next != 0x0) + tmpConnection->next->prev = tmpConnection->prev; + writeLog(2,"Removed Socket: [%i]\n",tmpConnection->fd); + + userCount--; + + if (tmpConnection->userInfo.ident == 2) { + sprintf(output,"DELETE FROM active WHERE userid = %lld",tmpConnection->userInfo.uid); + dbQuery(output,0); + } + + free(tmpConnection); + return(0x0); + } + } + + writeLog(2,"Error: No Socket Removed\n"); + return(-1); + } + +int sGetConnections(fd_set *readset) { + int retVal = 0; + myConnections_t *tmpConnection = 0x0; + + FD_ZERO(readset); + +// FD_SET(listenerFD,readset); + + highSock = 0; + + if (connections != 0x0) { + for (tmpConnection = connections;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { + FD_SET(tmpConnection->fd,readset); + if (tmpConnection->fd > highSock) + highSock = tmpConnection->fd; + } + retVal = 1; + } + + return(retVal); + } + +/************************************ + * * + * Send ping broadcast to all users * + * * + ************************************/ +int sSendPing(time_t ping) { + myConnections_t *tmpConnection = 0x0; + char sPing[32]; + + for (tmpConnection = connections->next;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { + if (tmpConnection->userInfo.pfailed < MAX_PING) { + if (tmpConnection->userInfo.pong < ping) { + tmpConnection->userInfo.pfailed++; + tmpConnection->userInfo.pong = ping; + if (tmpConnection->userInfo.ident >= 0x1) { + sprintf(sPing,"PING %li\r\n", time(NULL)); + send(tmpConnection->fd,sPing,strlen(sPing),MSG_NOSIGNAL); + } + } + } + else { + send(tmpConnection->fd,"TIMEOUT\r\n",sizeof("TIMEOUT\r\n"),MSG_NOSIGNAL); + tuveDelUserChans(tmpConnection,"TIMEOUT"); + tmpConnection->userInfo.status = -1; + } + } + + return(0x0); + } /* End sSendPing() */ + +int sSendData(myConnections_t *con,char const * __restrict fmt, ...) { + int len = 0; + char data[2048]; + va_list ap; + + if (con == 0x0) { + writeLog(1,"Error Sending Data"); + return(0x1); + } + else if (con->userInfo.status == -1) { + writeLog(3,"User: %s Socket Not Avail\n",con->userInfo.username); + return(0x1); + } + + va_start(ap,fmt); + len = vsnprintf(data,2046,fmt,ap); + va_end(ap); + + //data[len++] = '\r'; + data[len++] = '\n'; + + + send(con->fd,data,len,MSG_NOSIGNAL); + return(0x0); + } + +int sProcessConnections(fd_set *readset) { + myConnections_t *tmpConnection = 0x0; + + for (tmpConnection = connections;tmpConnection != 0x0;tmpConnection = tmpConnection->next) { + if (FD_ISSET(tmpConnection->fd,readset) != 0x0) { + if (tmpConnection->fd == listenerFD) { + sGetConnection(); + writeLog(2,"Listen Socket Was Ready?\n"); + } + else { + if (tuveGetData(tmpConnection) == -1) { + close(tmpConnection->fd); + tuveDelUserChans(tmpConnection,"SIG PIPE"); + sRemoveConnection(tmpConnection->fd); + } + } + } + } + return(0x0); + } diff --git a/src/tuve.c b/src/tuve.c new file mode 100644 index 0000000..263643f --- /dev/null +++ b/src/tuve.c @@ -0,0 +1,391 @@ +/* + (c) 2007 Christopher Olsen + $Id: tuve.c,v 1.60 2008/10/07 12:59:56 reddawg Exp $ + +*/ +#include +#include +#include +#include +#include + +#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,"") == 0x0) { + /* Command Checked Tested And Approved */ + sprintf(output,"\n\n\n\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); + } + diff --git a/src/tuved.h b/src/tuved.h new file mode 100644 index 0000000..8cebd95 --- /dev/null +++ b/src/tuved.h @@ -0,0 +1,227 @@ +/* + (c) 2007 Christopher Olsen + + $Id: tuved.h,v 1.60 2009/02/18 19:54:19 reddawg Exp $ +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* TUved Information */ +#define VERSION "v1.93" // Current Version Of Tuved +#define NUM_THREADS 1 // Number Of Threads In The Deamon +#define MYPORT 2007 // the port users will be connecting to +#define BACKLOG 10 // how many pending connections queue will hold +#define LOG_FILE "/var/log/tuved.log" // Default Log File +#define PING_INTERVAL 20 // Interval For Pings +#define MAX_PING 2 // Maximum Number Of Missed Pings +#define MAX_COUNT 2 +#define MAX_TOPIC_LEN 128 // Maximum Length For A Topic +#define MAX_CHAN_LEN 32 // Maximum Length For A Channel Name +#define MAX_USER_LEN 32 // Maximum Length For A Username +#define MAX_USER_AWAYMSG 128 // Maximum Length For Away Message +#define CHAN_MAX_BANS 30 +#define CHAN_LIVE_LENGTH 128 + +/* MySQL Information */ +#define MYSQL_HOST_NAME "SPBX-DB002.SpherePBX.com" // MySQL Server Hostname +#define MYSQL_USERNAME "tuve" // MySQL Server Username +#define MYSQL_PASSWORD "5558585" // MySQL Server Password +#define MYSQL_DB_NAME "tuve" // MySQL Server Database Name + +#define VIDE_PAD_TIME 2 // Video Padding To Ensure All Users Are In Sync +#define MIN_VER 2.7 // Minimum Client Version +#define COM_DELAY 60*20 // Amount Of Playtime Before Commercial; + +/* User Modes */ +#define USER_MODES 2 // Count Of User Modes +#define USER_OVERLORD 0 // User Is An Overlord +#define USER_AWAY 1 // User Is Away + +/* Cannel Modes */ +#define CHAN_MODES 9 // Count Of Channel Modes +#define CHAN_RANDOM 0 // Random Videos +#define CHAN_QUEUE 1 // Users Queues +#define CHAN_TIME 2 // Video Time Limit +#define CHAN_RATING 3 // Video Parental Rating +#define CHAN_CLASS 4 // Video Classs +#define CHAN_LIVE 5 // Channel Is In Live Stream Mode +#define CHAN_EXCLUSIVE 6 // Channel Is In Exclusive Mode +#define CHAN_SCHEDULED 7 // Channel Is In Scheduled Mode +#define CHAN_NOADS 8 // Channel Will Not Play Advertisements + +typedef struct tuveUserList { + struct tuveUserList *prev; + struct tuveUserList *next; + struct myConnections *user; + short chanLevel; + } tuveUserList_t; + +/* Channel Structure */ +typedef struct tuveChanList { + struct tuveChanList *prev; + struct tuveChanList *next; + struct tuveUserList *users; + struct tuveUserList *nextUser; + long long bans[CHAN_MAX_BANS][2]; // Ban List + char liveStream[CHAN_LIVE_LENGTH]; // Live Stream Name + char modes[CHAN_MODES]; // Channel Modes Array + char topicSetBy[MAX_USER_LEN]; // + char topic[MAX_TOPIC_LEN]; + char channel[MAX_CHAN_LEN]; + char videoFile[256]; // File Name Of Video + char videoChanTitle[256]; // Video Title Displayed In The Channel w/ Links + char videoTitle[256]; // Video Title w/o Links + int videoEnd; // Time At Which The Server Considers The Video Has Ended + int videoTime; // Video Length In Seconds + int userCount; // Channels User Count + int vid; // Video ID + int comTime; // Total Ad Time + int comDelay; // Video Play Counter For Next Ad + int oid; // Channels OID + short count; // Counter For Querying A User For A Video + short maxTime; // Maximum Length For A Video + short vidClass; // Video Class - For Skip Protection + time_t topicSet; + } tuveChanList_t; + +typedef struct tuveUserChans { + struct tuveUserChans *prev; + struct tuveUserChans *next; + char channel[32]; + } tuveUserChans_t; + +typedef struct tuveUser { + short ident; + short pfailed; + short status; + short queue; + float version; + long long uid; + time_t pong; + time_t idle; + char modes[USER_MODES]; + char username[MAX_USER_LEN]; + char awayMsg[MAX_USER_AWAYMSG]; + tuveUserChans_t *chans; + } tuveUser_t; + + +typedef struct myConnections { + struct myConnections *prev; + struct myConnections *next; + int fd; + int recLen; + char data[1024]; + char host[128]; + tuveUser_t userInfo; + time_t signedOn; + } myConnections_t; + +/* + Global variables very not safe + */ + +extern int songCount; +extern int playCount; +extern int channelCount; +extern int userCount; +extern int listenerFD; +extern int highSock; +extern myConnections_t *connections; +extern FILE *logFile; +extern tuveChanList_t *channels; +extern pthread_mutex_t chanMutex; +extern time_t startTime; +extern char logFileName[64]; + +/* Socket Functions */ +ssize_t sReadSocket(int socketFD,void *buffer,size_t length); +myConnections_t *sFindConnection(int fd); +int sStartListener(); +int sAddConnection(int,char *host); +int sGetConnections(fd_set *); +int sProcessConnections(fd_set *); +int sSendPing(time_t); // Sends Ping To All Sockets +int sCleanConnections(); // Cleans Up The Dead Connections +int sSendData(myConnections_t *con,char const * __restrict fmt, ...); // Sends Data To A Socket +int sRemoveConnection(int socketFD); +int tuveGetData(myConnections_t *userConnection); +/* + * End Socket functions + */ + +/* Log Functions */ +int writeLog(int level,char const * __restrict, ...); + +/* Channel Functions */ +int tuveChanList(myConnections_t *userConnection); // Sends Channel List To Provided Users +int tuveChanPart(const char *channel,myConnections_t *userConnection); // Parts A User From A Channel +int tuveChanResume(const char *channel); // Resumes Streaming In A Channel +int tuveChanLive(const char *channel,const char *stream,const char *location); // Starts Live Mode In A Channel +int tuveChanJoin(const char *channel,myConnections_t *userConnection); // Joins A Users To A Channel +int tuveAddChanToUser(const char *channel,myConnections_t *userConnection); // Adds Chan To User +int tuveAddToChanList(const char *channel,myConnections_t *userConnection); +int tuveSendAllInChan(const char *channel,myConnections_t *userConnection,char const * __restrict fmt, ...); +int tuveFindChanLevel(const char *channel,myConnections_t *userConnection,int eo); // Returns Users Channel Level +int tuveChanOp(const char *channel,const char *nick,int level); // Sets Channel Opperator Status +int tuveDelUserChans(myConnections_t *userConnection,char *msg); +int tuveRemoveFromChanList(const char *channel,myConnections_t *userConnection); +int tuveSetTopic(myConnections_t *userConnection,char *chan,char *topic); +int tuveSendAllInUsersChans(myConnections_t *userConnection,char *output); +int tuveDelChan(const char *channel,myConnections_t *userConnection); +int tuveKick(myConnections_t *byConnection,char *chan,char *nick,char *msg); +tuveChanList_t *findChan(const char *); +int tuveBan(myConnections_t *byConnection,const char *channel,const char *nick,int length); +int tuveUnBan(const char *channel,const char *nick); +int tuveVerifyBan(const char *channel,const char *nick); +myConnections_t *findNickOnChan(const char *nick,const char *channel); +/* + * End Channel Functions + */ + +/* Bot Functions */ +void *tuveCMD_Thread(void *threadid); +int tuveCMD_CMD(myConnections_t *userConnection,char *chan,char *data); +int tuveBotSetSong(char *channel,char *nick,char *artist,char *title,int length,char *file,int class,int rating,int vid); +int tuveBotSetVideo(char *chan,char *nick,int vid); +/* + * End Bot Functions + */ + +/* Nick Functions */ +int tuveVerifyNick(char *nick); +myConnections_t *findNick(const char *); +int tuveWhois(myConnections_t *userConnection,char *nick); +/* + * End Nick Functions + */ + +/* Server Functions */ +int tuveStatus(myConnections_t *userConnection); +/* + * End Server Functions + */ + +/* Database Functions */ +int dbInit(); +MYSQL_RES *dbQuery(const char *query,short store); +/* + * End Database Functions + */ + +/* Lib Functions */ +int formatTime(time_t sTime,char *output); +/* + * End Lib Functions + */ + + +/* Config Functions */ +int parseConfig(); diff --git a/tuve.c b/tuve.c deleted file mode 100644 index 44cd5be..0000000 --- a/tuve.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - (c) 2007 Christopher Olsen - $Id: tuve.c,v 1.60 2008/10/07 12:59:56 reddawg Exp $ - -*/ -#include -#include -#include -#include -#include - -#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,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,"") == 0x0) { - /* Command Checked Tested And Approved */ - sprintf(output,"\n\n\n\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,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); - } - diff --git a/tuved.cfg b/tuved.cfg deleted file mode 100644 index 13823de..0000000 --- a/tuved.cfg +++ /dev/null @@ -1,10 +0,0 @@ -daemon = { - sport = 2007; -} - -database = { - hostname = "SPBX-DB002.SpherePBX.com"; - database = "tuve"; - username = "tuve"; - password = "5558585"; -} diff --git a/tuved.h b/tuved.h deleted file mode 100644 index 20e28d6..0000000 --- a/tuved.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - (c) 2007 Christopher Olsen - - $Id: tuved.h,v 1.60 2009/02/18 19:54:19 reddawg Exp $ -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* TUved Information */ -#define VERSION "v1.93" // Current Version Of Tuved -#define NUM_THREADS 1 // Number Of Threads In The Deamon -#define MYPORT 2007 // the port users will be connecting to -#define BACKLOG 10 // how many pending connections queue will hold -#define LOG_FILE "/var/log/tuved.log" // Default Log File -#define PING_INTERVAL 20 // Interval For Pings -#define MAX_PING 2 // Maximum Number Of Missed Pings -#define MAX_COUNT 2 -#define MAX_TOPIC_LEN 128 // Maximum Length For A Topic -#define MAX_CHAN_LEN 32 // Maximum Length For A Channel Name -#define MAX_USER_LEN 32 // Maximum Length For A Username -#define MAX_USER_AWAYMSG 128 // Maximum Length For Away Message -#define CHAN_MAX_BANS 30 -#define CHAN_LIVE_LENGTH 128 - -/* MySQL Information */ -#define MYSQL_HOST_NAME "SPBX-DB002.SpherePBX.com" // MySQL Server Hostname -#define MYSQL_USERNAME "tuve" // MySQL Server Username -#define MYSQL_PASSWORD "5558585" // MySQL Server Password -#define MYSQL_DB_NAME "tuve" // MySQL Server Database Name - -#define VIDE_PAD_TIME 2 // Video Padding To Ensure All Users Are In Sync -#define MIN_VER 2.7 // Minimum Client Version -#define COM_DELAY 60*20 // Amount Of Playtime Before Commercial; - -/* User Modes */ -#define USER_MODES 2 // Count Of User Modes -#define USER_OVERLORD 0 // User Is An Overlord -#define USER_AWAY 1 // User Is Away - -/* Cannel Modes */ -#define CHAN_MODES 9 // Count Of Channel Modes -#define CHAN_RANDOM 0 // Random Videos -#define CHAN_QUEUE 1 // Users Queues -#define CHAN_TIME 2 // Video Time Limit -#define CHAN_RATING 3 // Video Parental Rating -#define CHAN_CLASS 4 // Video Classs -#define CHAN_LIVE 5 // Channel Is In Live Stream Mode -#define CHAN_EXCLUSIVE 6 // Channel Is In Exclusive Mode -#define CHAN_SCHEDULED 7 // Channel Is In Scheduled Mode -#define CHAN_NOADS 8 // Channel Will Not Play Advertisements - -typedef struct tuveUserList { - struct tuveUserList *prev; - struct tuveUserList *next; - struct myConnections *user; - short chanLevel; - } tuveUserList_t; - -/* Channel Structure */ -typedef struct tuveChanList { - struct tuveChanList *prev; - struct tuveChanList *next; - struct tuveUserList *users; - struct tuveUserList *nextUser; - long long bans[CHAN_MAX_BANS][2]; // Ban List - char liveStream[CHAN_LIVE_LENGTH]; // Live Stream Name - char modes[CHAN_MODES]; // Channel Modes Array - char topicSetBy[MAX_USER_LEN]; // - char topic[MAX_TOPIC_LEN]; - char channel[MAX_CHAN_LEN]; - char videoFile[256]; // File Name Of Video - char videoChanTitle[256]; // Video Title Displayed In The Channel w/ Links - char videoTitle[256]; // Video Title w/o Links - int videoEnd; // Time At Which The Server Considers The Video Has Ended - int videoTime; // Video Length In Seconds - int userCount; // Channels User Count - int vid; // Video ID - int comTime; // Total Ad Time - int comDelay; // Video Play Counter For Next Ad - int oid; // Channels OID - short count; // Counter For Querying A User For A Video - short maxTime; // Maximum Length For A Video - short vidClass; // Video Class - For Skip Protection - time_t topicSet; - } tuveChanList_t; - -typedef struct tuveUserChans { - struct tuveUserChans *prev; - struct tuveUserChans *next; - char channel[32]; - } tuveUserChans_t; - -typedef struct tuveUser { - short ident; - short pfailed; - short status; - short queue; - float version; - long long uid; - time_t pong; - time_t idle; - char modes[USER_MODES]; - char username[MAX_USER_LEN]; - char awayMsg[MAX_USER_AWAYMSG]; - tuveUserChans_t *chans; - } tuveUser_t; - - -typedef struct myConnections { - struct myConnections *prev; - struct myConnections *next; - int fd; - int recLen; - char data[1024]; - char host[128]; - tuveUser_t userInfo; - time_t signedOn; - } myConnections_t; - -/* - Global variables very not safe - */ - -extern int songCount; -extern int playCount; -extern int channelCount; -extern int userCount; -extern int listenerFD; -extern int highSock; -extern myConnections_t *connections; -extern FILE *logFile; -extern tuveChanList_t *channels; -extern pthread_mutex_t chanMutex; -extern time_t startTime; -extern char logFileName[64]; - -/* Socket Functions */ -ssize_t sReadSocket(int socketFD,void *buffer,size_t length); -myConnections_t *sFindConnection(int fd); -int sStartListener(); -int sAddConnection(int,char *host); -int sGetConnections(fd_set *); -int sProcessConnections(fd_set *); -int sSendPing(time_t); // Sends Ping To All Sockets -int sCleanConnections(); // Cleans Up The Dead Connections -int sSendData(myConnections_t *con,char const * __restrict fmt, ...); // Sends Data To A Socket -int sRemoveConnection(int socketFD); -int tuveGetData(myConnections_t *userConnection); -/* - * End Socket functions - */ - -/* Log Functions */ -int writeLog(int level,char const * __restrict, ...); - -/* Channel Functions */ -int tuveChanList(myConnections_t *userConnection); // Sends Channel List To Provided Users -int tuveChanPart(const char *channel,myConnections_t *userConnection); // Parts A User From A Channel -int tuveChanResume(const char *channel); // Resumes Streaming In A Channel -int tuveChanLive(const char *channel,const char *stream,const char *location); // Starts Live Mode In A Channel -int tuveChanJoin(const char *channel,myConnections_t *userConnection); // Joins A Users To A Channel -int tuveAddChanToUser(const char *channel,myConnections_t *userConnection); // Adds Chan To User -int tuveAddToChanList(const char *channel,myConnections_t *userConnection); -int tuveSendAllInChan(const char *channel,myConnections_t *userConnection,char const * __restrict fmt, ...); -int tuveFindChanLevel(const char *channel,myConnections_t *userConnection,int eo); // Returns Users Channel Level -int tuveChanOp(const char *channel,const char *nick,int level); // Sets Channel Opperator Status -int tuveDelUserChans(myConnections_t *userConnection,char *msg); -int tuveRemoveFromChanList(const char *channel,myConnections_t *userConnection); -int tuveSetTopic(myConnections_t *userConnection,char *chan,char *topic); -int tuveSendAllInUsersChans(myConnections_t *userConnection,char *output); -int tuveDelChan(const char *channel,myConnections_t *userConnection); -int tuveKick(myConnections_t *byConnection,char *chan,char *nick,char *msg); -tuveChanList_t *findChan(const char *); -int tuveBan(myConnections_t *byConnection,const char *channel,const char *nick,int length); -int tuveUnBan(const char *channel,const char *nick); -int tuveVerifyBan(const char *channel,const char *nick); -myConnections_t *findNickOnChan(const char *nick,const char *channel); -/* - * End Channel Functions - */ - -/* Bot Functions */ -void *tuveCMD_Thread(void *threadid); -int tuveCMD_CMD(myConnections_t *userConnection,char *chan,char *data); -int tuveBotSetSong(char *channel,char *nick,char *artist,char *title,int length,char *file,int class,int rating,int vid); -int tuveBotSetVideo(char *chan,char *nick,int vid); -/* - * End Bot Functions - */ - -/* Nick Functions */ -int tuveVerifyNick(char *nick); -myConnections_t *findNick(const char *); -int tuveWhois(myConnections_t *userConnection,char *nick); -/* - * End Nick Functions - */ - -/* Server Functions */ -int tuveStatus(myConnections_t *userConnection); -/* - * End Server Functions - */ - -/* Database Functions */ -int dbInit(); -MYSQL_RES *dbQuery(const char *query,short store); -/* - * End Database Functions - */ - -/* Lib Functions */ -int formatTime(time_t sTime,char *output); -/* - * End Lib Functions - */ -