diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6ada1d0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +src/*.o +bin diff --git a/Makefile b/Makefile index f7dd57f..0e28cf6 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ # Application Makefile (C) 2002-2004 The UbixOS Project #Compiler -CC = gcc -CXX = g++ +CC = cc +CXX = c++ #Linker LD = ld @@ -15,7 +15,7 @@ REMOVE = rm -f #Objects -OBJS = thread.o bot.o mysql.o main.o socket.o +OBJS = src/thread.o src/bot.o src/mysql.o src/main.o src/socket.o LIBRARIES = -lthr -L/usr/local/lib/mysql -lmysqlclient CFLAGS = -Wall -W -ggdb @@ -23,6 +23,9 @@ # Link The Binary $(BINARY) : $(OBJS) +.if !exists(bin) + mkdir bin +.endif $(CC) $(CFLAGS) -o $@ $(LIBRARIES) $(OBJS) # Compile the source files @@ -43,4 +46,12 @@ # Clean Up The junk clean: - $(REMOVE) $(OBJS) $(BINARY) *.core + $(REMOVE) $(OBJS) bin/$(BINARY) *.core + + +install: +.if !exists(/usr/local/etc/tuve) + mkdir /usr/local/etc/tuve +.endif + cp extra/tuvebot.cfg /usr/local/etc/tuve + cp bin/tuvebot /usr/local/bin diff --git a/bot.c b/bot.c deleted file mode 100644 index 60d8ffc..0000000 --- a/bot.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - bot.c (C) 2007 Christopher Olsen - - $Id: bot.c,v 1.40 2008/05/28 12:03:41 reddawg Exp $ -*/ - -#include -#include "tuvebot.h" - -botChanList_t *chans = 0x0; - -pthread_mutex_t chanMutex = PTHREAD_MUTEX_INITIALIZER; - -botChanList_t *botFindChan(char *channel) { - botChanList_t *tmpChan = 0x0; - - pthread_mutex_lock(&chanMutex); - - for (tmpChan = chans;tmpChan != 0x0;tmpChan = tmpChan->next) { - if (!strcasecmp(tmpChan->channel,channel)) { - pthread_mutex_unlock(&chanMutex); - return(tmpChan); - } - } - - pthread_mutex_unlock(&chanMutex); - return(0x0); - } - -botChanList_t *botAddChan(char *channel) { - botChanList_t *tmpChan = 0x0; - - tmpChan = botFindChan(channel); - - if (tmpChan != 0x0) - return(tmpChan); - - writeLog(2,"ADDING CHANNEL: %s\n",channel); - - tmpChan = (botChanList_t *)malloc(sizeof(botChanList_t)); - - strcpy(tmpChan->channel,channel); - tmpChan->next = 0x0; - tmpChan->prev = 0x0; - tmpChan->updated = 0x0; - bzero(tmpChan->modes,CHAN_MODES); - - pthread_mutex_lock(&chanMutex); - - if (chans == 0x0) - chans = tmpChan; - else { - tmpChan->next = chans; - chans->prev = tmpChan; - chans = tmpChan; - } - - pthread_mutex_unlock(&chanMutex); - - return(tmpChan); - } - -int botJoinChans() { - MYSQL_RES *res = 0x0; - MYSQL_RES *res2 = 0x0; - MYSQL_ROW row; - unsigned int i = 0x0; - unsigned int x = 0x0; - int tmpVal = 0; - botChanList_t *tmpChan = 0x0; - char qryStr[256]; - - res = dbQuery("SELECT channel,rating,classification,random,queue,exclusive,time,noads,topic,cid FROM channels",1); - - joinChan = 2; - - if (mysql_num_rows(res) > 0) { - for (i = 0;i < mysql_num_rows(res);i++) { - - row = mysql_fetch_row(res); - tmpChan = botAddChan(row[0]); - - if (tmpChan == 0x0) - return(-1); - - sWriteSocket("JOIN %s",row[0]); - sleep(2); - - pthread_mutex_lock(&chanMutex); - - /* Op Myself */ - sWriteSocket("MSG %s:.tv MODE +O TUveBOT",row[0]); - - /* Set Access Level */ - tmpVal = atoi(row[1]); - if (tmpVal > 0) - sWriteSocket("MSG %s:.tv mode +A %i",row[0],tmpVal); - else - sWriteSocket("MSG %s:.tv mode -A",row[0]); - tmpChan->modes[CHAN_RATING] = tmpVal; - - /* Set Classification */ - tmpVal = atoi(row[2]); - if (tmpVal > 0) - sWriteSocket("MSG %s:.tv mode +C %i",row[0],tmpVal); - else - sWriteSocket("MSG %s:.tv mode -C",row[0]); - tmpChan->modes[CHAN_CLASS] = tmpVal; - - /* Set Random */ - tmpVal = atoi(row[3]); - if (tmpVal == 1) - sWriteSocket("MSG %s:.tv mode +R",row[0]); - else - sWriteSocket("MSG %s:.tv mode -R",row[0]); - tmpChan->modes[CHAN_RANDOM] = tmpVal; - - /* Set Queue */ - tmpVal = atoi(row[4]); - if (tmpVal == 1) - sWriteSocket("MSG %s:.tv mode +Q",row[0]); - else - sWriteSocket("MSG %s:.tv mode -Q",row[0]); - tmpChan->modes[CHAN_QUEUE] = tmpVal; - - /* Set Exclusive */ - tmpVal = atoi(row[5]); - if (tmpVal == 1) - sWriteSocket("MSG %s:.tv mode +E",row[0]); - else - sWriteSocket("MSG %s:.tv mode -E",row[0]); - tmpChan->modes[CHAN_EXCLUSIVE] = tmpVal; - - /* Set Time */ - tmpVal = atoi(row[6]); - if (tmpVal > 0) - sWriteSocket("MSG %s:.tv mode +T %i",row[0],tmpVal); - else - sWriteSocket("MSG %s:.tv mode -T",row[0]); - tmpChan->modes[CHAN_TIME] = tmpVal; - - /* Set NoAds */ - tmpVal = atoi(row[7]); - if (tmpVal == 1) - sWriteSocket("MSG %s:.tv mode +X",row[0]); - else - sWriteSocket("MSG %s:.tv mode -X",row[0]); - tmpChan->modes[CHAN_NOADS] = tmpVal; - - if (row[8] != 0x0) { - sWriteSocket("TOPIC %s:%s",row[0],row[8]); - strcpy(tmpChan->topic,row[8]); - } - tmpChan->cid = atoi(row[9]); -sprintf(qryStr,"SELECT s.vid,time,length FROM schedule s INNER JOIN videos v ON s.vid = v.vid WHERE cid = %i AND time > %i ORDER BY time LIMIT 0,9",tmpChan->cid,time(NULL)); - res2 = dbQuery(qryStr,1); - tmpChan->sCount = mysql_num_rows(res2); - tmpChan->sCur = 0; - for (x = 0;x < tmpChan->sCount;x++) { - row = mysql_fetch_row(res2); - tmpChan->schedule[x][0] = atoi(row[1]); - tmpChan->schedule[x][1] = atoi(row[0]); - tmpChan->schedule[x][2] = atoi(row[2]); - } - if (res2) - mysql_free_result(res2); - - - tmpChan->updated = 1; - pthread_mutex_unlock(&chanMutex); - } - mysql_free_result(res); - } - joinChan = 0; - return(0x0); - } - -int botSetMode(char *data) { - botChanList_t *tmpChan = 0x0; - char *chan = 0x0; - char *mode = 0x0; - char *md_tok = 0x0; - int tmpVal = 0x0; - char qryStr[512]; - - chan = strtok_r(data,":",&md_tok); - - tmpChan = botFindChan(chan); - - if (tmpChan == 0x0) - return(-1); - - if (tmpChan->updated == 0x0) - return(0x0); - - mode = strtok_r(NULL,":",&md_tok); - - switch (mode[0]) { - case 'A': - tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); - if (tmpChan->modes[CHAN_RATING] != tmpVal) { - tmpChan->modes[CHAN_RATING] = tmpVal; - sprintf(qryStr,"UPDATE channels SET rating = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); - dbQuery(qryStr,0); - } - break; - case 'C': - tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); - if (tmpChan->modes[CHAN_CLASS] != tmpVal) { - tmpChan->modes[CHAN_CLASS] = tmpVal; - sprintf(qryStr,"UPDATE channels SET classification = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); - dbQuery(qryStr,0); - } - break; - case 'R': - tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); - if (tmpChan->modes[CHAN_RANDOM] != tmpVal) { - tmpChan->modes[CHAN_RANDOM] = tmpVal; - sprintf(qryStr,"UPDATE channels SET random = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); - dbQuery(qryStr,0); - } - break; - case 'Q': - tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); - if (tmpChan->modes[CHAN_QUEUE] != tmpVal) { - tmpChan->modes[CHAN_QUEUE] = tmpVal; - sprintf(qryStr,"UPDATE channels SET queue = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); - dbQuery(qryStr,0); - } - break; - case 'X': - tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); - if (tmpChan->modes[CHAN_NOADS] != tmpVal) { - tmpChan->modes[CHAN_NOADS] = tmpVal; - sprintf(qryStr,"UPDATE channels SET noads = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); - dbQuery(qryStr,0); - } - break; - case 'E': - tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); - if (tmpVal != 0x0) - tmpVal = 1; - if (tmpChan->modes[CHAN_EXCLUSIVE] != tmpVal) { - tmpChan->modes[CHAN_EXCLUSIVE] = tmpVal; - sprintf(qryStr,"UPDATE channels SET exclusive = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); - dbQuery(qryStr,0); - } - break; - case 'T': - tmpVal = atoi(strtok_r(NULL,":",&md_tok)); - if (tmpVal != 0x0) - tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); - if (tmpChan->modes[CHAN_TIME] != tmpVal) { - tmpChan->modes[CHAN_TIME] = tmpVal; - sprintf(qryStr,"UPDATE channels SET time = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); - dbQuery(qryStr,0); - } - break; - default: - writeLog(0,"Invalid Mode: %c\n",mode[0]); - } - return(0x0); - } - -int botSetCurSong(char *data) { - char output[128]; - char *chan = 0x0; - char *song = 0x0; - - if (data == 0x0) - return(-1); - - chan = strtok(data,":"); - strtok(NULL,":"); - strtok(NULL,":"); - strtok(NULL,":"); - strtok(NULL,":"); - song = strtok(NULL,":"); - - if (song == 0x0) - return(-1); - - sprintf(output,"UPDATE channels SET nowplaying = %s WHERE channel = '%s'",song,chan); - dbQuery(output,0); - - writeLog(0,"Test: %s %s\n",chan,song); - return(0x0); - } - -int botStoreTopic(char *data) { - char *chan = 0x0; - char *topic = 0x0; - char qStr[512]; - - if (data == 0x0) - return(0x1); - - chan = strtok(data,":"); - topic = strtok(NULL,"\n"); - - if (chan == 0x0) - return(0x1); - - sprintf(qStr,"UPDATE channels SET topic = \"%s\" WHERE channel = '%s'",topic,chan); - dbQuery(qStr,0); - - return(0x0); - } - -int botDoLogin(char *cmdData) { - char *nick = 0x0; - char *ident = 0x0; - char *str_tok = 0x0; - char qryStr[256]; - MYSQL_RES *res = 0x0; - MYSQL_ROW row; - unsigned int i = 0x0; - - nick = strtok_r(cmdData,":",&str_tok); - ident = strtok_r(NULL,"\n",&str_tok); - - sprintf(qryStr,"SELECT channel FROM active a INNER JOIN channels c ON a.uid = c.oid WHERE a.userid = %s",ident); - res = dbQuery(qryStr,1); - - for (i = 0x0;i < mysql_num_rows(res);i++) { - row = mysql_fetch_row(res); - sWriteSocket("MSG %s:.tv mode +O %s",row[0],nick); - } - - if (res != 0x0) - mysql_free_result(res); - - return(0x0); - } - -int botDoJoin(char *cmdData) { - char *chan = 0x0; - char *nick = 0x0; - char *ident = 0x0; - char *str_tok = 0x0; - char qryStr[256]; - MYSQL_RES *res = 0x0; - - if (cmdData == 0x0) - return(-1); - - chan = strtok_r(cmdData,":",&str_tok); - nick = strtok_r(NULL,":",&str_tok); - ident = strtok_r(NULL,":",&str_tok); - - while (ident != 0x0) { - sprintf(qryStr,"SELECT cid FROM active a INNER JOIN channels c ON a.uid = c.oid WHERE userid = %s AND channel like '%s'",ident,chan); - res = dbQuery(qryStr,1); - if (res != 0x0) { - if (mysql_num_rows(res) > 0) - sWriteSocket("MSG %s:.tv mode +O %s",chan,nick); - mysql_free_result(res); - } - nick = strtok_r(NULL,":",&str_tok); - ident = strtok_r(NULL,":",&str_tok); - } - return(0x0); - } - -int botDoEmote(char cmdData) { -/* - char *nick = 0x0; - char *where = 0x0; - char *msg = 0x0; - - if (cmdData != 0x0) { - nick = strtok(cmdData,":"); - where = strtok(NULL,":"); - msg = strtok(NULL,"\n"); - } -*/ - return(0x0); - } diff --git a/extra/tuvebot b/extra/tuvebot new file mode 100755 index 0000000..25e21ca --- /dev/null +++ b/extra/tuvebot @@ -0,0 +1,43 @@ +#!/bin/sh + +# PROVIDE: tuvebot +# REQUIRE: LOGIN +# BEFORE: securelevel +# KEYWORD: shutdown + +# Add the following lines to /etc/rc.conf to enable `tuvebot': +# +# tuvebot_enable="YES" +# tuvebot_flags="" +# +# See tuvebot(1) for tuvebot_flags +# + +. /etc/rc.subr + +name="tuvebot" +rcvar=tuvebot_enable + +command="/usr/local/bin/tuvebot" +start_precmd="tuvebot_precmd" +pidfile="/var/run/$name.pid" + +# read configuration and set defaults +load_rc_config "$name" +: ${tuvebot_enable="NO"} +: ${tuvebot_configfile:=/usr/local/etc/tuve/$name.cfg} + +required_files="${tuvebot_configfile}" + +command_args="-d 4 -c ${tuvebot_configfile}" + +tuvebot_precmd() +{ + if [ -f "/usr/local/etc/$name.cfg" ] && [ ! -L "/usr/local/etc/$name.cfg" ]; then + echo "Found /usr/local/etc/$name.cfg in old location. Migrating to /usr/local/etc/tuve/$name.cfg." + mv /usr/local/etc/$name.cfg /usr/local/etc/tuve/$name.cfg + ln -s /usr/local/etc/tuvebot/$name.cfg /usr/local/etc/$name.cfg + fi +} + +run_rc_command "$1" diff --git a/extra/tuvebot.cfg b/extra/tuvebot.cfg new file mode 100644 index 0000000..13823de --- /dev/null +++ b/extra/tuvebot.cfg @@ -0,0 +1,10 @@ +daemon = { + sport = 2007; +} + +database = { + hostname = "SPBX-DB002.SpherePBX.com"; + database = "tuve"; + username = "tuve"; + password = "5558585"; +} diff --git a/main.c b/main.c deleted file mode 100644 index b93b087..0000000 --- a/main.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - Tuved Server - (C) 2007 Christopher Olsen - - $Id: main.c,v 1.22 2008/05/28 12:03:41 reddawg Exp $ -*/ - -#include -#include -#include -#include - -#include "tuvebot.h" - -FILE *logFile = 0x0; -int logLevel = 1; -int highSock = 0x0; -int joinChan = 0x0; -time_t startTime; - -void usage(); -int botProcessData(char *data); - -int main(int argc,char **argv) { - int ch; - int doFork = 0x1; - int readSocks = 0x0; - int t = 0x0; - fd_set readSet; - char data[1024]; - struct timeval timeout = {30,0}; - - /* Get our start time */ - startTime = time(NULL); - - while ((ch = getopt(argc,argv,"sl:nd:")) != -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; - default: - usage(); - } - } - argc -= optind; - argv += optind; - - - /* Prepare log file */ - if (logFile == 0x0) - logFile = fopen(LOG_FILE,"a"); - - /* Fork into background unless specified not to do so */ - if (doFork == 1) - if (fork() != 0x0) - exit(1); - - writeLog(0,"TUveBOT Starting: %i\n",startTime); - - dbInit(); - - srandom(time(NULL)); - - pthread_t threads[NUM_THREADS]; - - pthread_create(&threads[t], NULL, botCMD_Thread, (void *)t); - t = 1; - pthread_create(&threads[t], NULL, botSCHD_Thread, (void *)t); - - pthread_mutex_init(&chanMutex, NULL); - - sConnect(SERVER_HOST,SERVER_PORT); - - - while (1) { - - /* Build our readSet */ - sGetConnections(&readSet); - - readSocks = select(highSock+1,&readSet,0x0,0x0,&timeout); - - if (readSocks < 0) { - perror("select failed"); - exit(0x1); - } - - if (FD_ISSET(mySocket,&readSet) != 0x0) { - memset(&data,0x0,1024); - if (sReadSocket(&data,1024) == -1) { - writeLog(0,"Socket Died!\n"); - sConnect(SERVER_HOST,SERVER_PORT); - //exit(1); - } - else { - botProcessData(data); - } - } - - /* 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); - } - -int botProcessMsg(char *data) { - char *nick; - char *chan; - char *cmdData; - char *str_tok = 0x0; - botChanList_t *tmpChan; - int i; - - nick = strtok_r(data,":",&str_tok); - chan = strtok_r(NULL,":",&str_tok); - cmdData = strtok_r(NULL,"\n",&str_tok); - - if ((!strcasecmp(nick,"MrOlsen")) && (!strcasecmp(chan,"PRIVMSG"))) { - printf("cmdData: [%s]\n",cmdData); - sWriteSocket("%s\n",cmdData); - } - else if (!strcasecmp(nick,"MrOlsen") && !strcasecmp(cmdData,".ss")) { - tmpChan = botFindChan(chan); - for (i = tmpChan->sCur;i < tmpChan->sCount;i++) { - sWriteSocket("MSG %s:Time: %i,VID: %i\n",chan,tmpChan->schedule[i][0],tmpChan->schedule[i][1]); - } - } - return(0x0); - } - -int botProcessData(char *dataFresh) { - char *cmd = 0x0; - char *cmdData = 0x0; - char *str_tok = 0x0; - char *data = 0x0; - char *data2 = 0x0; - char *data_tok = 0x0; - - data = strtok_r(dataFresh,"\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 (strstr(cmd,":")) { - cmd = strtok_r(data,":",&str_tok); - cmdData = strtok_r(NULL,"\n",&str_tok); - str_tok = 0x0; - writeLog(3,"DATA: (%s)CMD: [%s], Data: [%s]\n",data,cmd,cmdData); - } - else - writeLog(3,"DATA: (%s)CMD: [%s]\n",data,cmd); - - if (cmd == 0x0) - return(0x0); - - if (strstr(cmd,"PING")) { - sWriteSocket("PONG!\n"); - } - else if (!strcmp(cmd,"IDENT")) { - sWriteSocket("MSG TUveD:.tv login tuvebot 5558585\n"); - joinChan = 1; - } - else if (!strcmp(cmd,"MSG")) - botProcessMsg(cmdData); - else if (!strcmp(cmd,"TOPIC")) - botStoreTopic(cmdData); - else if (!strcmp(cmd,"CURPOS")) - botSetCurSong(cmdData); - else if (!strcmp(cmd,"MODE")) - botSetMode(cmdData); - else if (!strcmp(cmd,"JOIN")) - botDoJoin(cmdData); - else if (!strcmp(cmd,"EMOTE")) - botDoEmote(cmdData); - else if (!strcmp(cmd,"LOGIN")) - botDoLogin(cmdData); - else { - writeLog(0,"Unknown Command: [%s]\n",cmd); - } - - if (data2 != 0x0) { - data = 0x0; - goto Head; - } - - return(0x0); - } diff --git a/mysql.c b/mysql.c deleted file mode 100644 index d46fb20..0000000 --- a/mysql.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - (C) 2007 Christopher Olsen - - $Id: mysql.c,v 1.3 2008/04/22 11:52:28 reddawg Exp $ -*/ - -#include - -#include "tuvebot.h" - -MYSQL *conn = 0x0; - -pthread_mutex_t mysqlMutex = PTHREAD_MUTEX_INITIALIZER; - - -int dbInit() { - - conn = mysql_init(NULL); - if (conn == NULL) { - writeLog(0,"mysql_init() failed (probably out of memory)\n."); - return(0x1); - } - - 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); - } - - if (mysql_options(conn,MYSQL_OPT_RECONNECT,"true") != 0x0) { - writeLog(0,"mysql_options() failed: To Set Reconnect\n"); - } - - 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/socket.c b/socket.c deleted file mode 100644 index a632394..0000000 --- a/socket.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - tuvebot - Socket Code - (C) 2007 Christopher Olsen - - $Id: socket.c,v 1.14 2008/04/22 11:52:28 reddawg Exp $ - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tuvebot.h" - -int mySocket = 0x0; -int connected = 0x0; - -int sConnect(const char *host,int port) { - struct sockaddr_in rmAddr; // remote address information - struct hostent *hp; - int att; - - connected = 0; - - for (att = 1;att < 10;att++) { - if (mySocket != 0x0) - close(mySocket); - - if ((mySocket = socket(PF_INET, SOCK_STREAM, 0)) == -1) { - perror("socket"); - exit(1); - } - - writeLog(0,"Connecting to: %s, port %i, socket %i, attempt: %i\n",host,port,mySocket,att); - - hp = gethostbyname(host); - - bzero(&rmAddr,sizeof(struct sockaddr_in)); - - //memcpy(&(rmAddr.sin_addr.s_addr),*(hp->h_addr_list),sizeof(struct in_addr)); - bcopy((char *)hp->h_addr,(char *)&rmAddr.sin_addr.s_addr,hp->h_length); - - rmAddr.sin_family = AF_INET; // host byte order - rmAddr.sin_port = htons(port); // short, network byte order - memset(rmAddr.sin_zero, '\0', sizeof rmAddr.sin_zero); - - if (connect(mySocket,&rmAddr,sizeof(rmAddr)) == 0x0) - break; - - writeLog(1,"Error Connecting: %i.\n",errno); - sleep(5); - } - - writeLog(2,"my Socket: [%i]\n",mySocket); - - sWriteSocket("IDENT TUveBOT:1234567\n"); - - return(0x0); - } - -ssize_t sReadSocket(void *buffer,size_t length) { - ssize_t recLen = 0x0; - - recLen = read(mySocket,buffer,length); - if (recLen == 0x0) - return(-1); - - return(recLen); - } - -int sWriteSocket(char const * __restrict fmt, ...) { - char data[1024]; - int len = 0x0; - va_list ap; - - va_start(ap,fmt); - len = vsnprintf(data,1023,fmt,ap); - va_end(ap); - - data[len++] = '\n'; - - send(mySocket,data,len,MSG_NOSIGNAL); - return(0x0); - } - -int sGetConnections(fd_set *readset) { - - FD_ZERO(readset); - - FD_SET(mySocket,readset); - - highSock = mySocket + 1; - - return(0x0); - } - diff --git a/src/bot.c b/src/bot.c new file mode 100644 index 0000000..60d8ffc --- /dev/null +++ b/src/bot.c @@ -0,0 +1,378 @@ +/* + bot.c (C) 2007 Christopher Olsen + + $Id: bot.c,v 1.40 2008/05/28 12:03:41 reddawg Exp $ +*/ + +#include +#include "tuvebot.h" + +botChanList_t *chans = 0x0; + +pthread_mutex_t chanMutex = PTHREAD_MUTEX_INITIALIZER; + +botChanList_t *botFindChan(char *channel) { + botChanList_t *tmpChan = 0x0; + + pthread_mutex_lock(&chanMutex); + + for (tmpChan = chans;tmpChan != 0x0;tmpChan = tmpChan->next) { + if (!strcasecmp(tmpChan->channel,channel)) { + pthread_mutex_unlock(&chanMutex); + return(tmpChan); + } + } + + pthread_mutex_unlock(&chanMutex); + return(0x0); + } + +botChanList_t *botAddChan(char *channel) { + botChanList_t *tmpChan = 0x0; + + tmpChan = botFindChan(channel); + + if (tmpChan != 0x0) + return(tmpChan); + + writeLog(2,"ADDING CHANNEL: %s\n",channel); + + tmpChan = (botChanList_t *)malloc(sizeof(botChanList_t)); + + strcpy(tmpChan->channel,channel); + tmpChan->next = 0x0; + tmpChan->prev = 0x0; + tmpChan->updated = 0x0; + bzero(tmpChan->modes,CHAN_MODES); + + pthread_mutex_lock(&chanMutex); + + if (chans == 0x0) + chans = tmpChan; + else { + tmpChan->next = chans; + chans->prev = tmpChan; + chans = tmpChan; + } + + pthread_mutex_unlock(&chanMutex); + + return(tmpChan); + } + +int botJoinChans() { + MYSQL_RES *res = 0x0; + MYSQL_RES *res2 = 0x0; + MYSQL_ROW row; + unsigned int i = 0x0; + unsigned int x = 0x0; + int tmpVal = 0; + botChanList_t *tmpChan = 0x0; + char qryStr[256]; + + res = dbQuery("SELECT channel,rating,classification,random,queue,exclusive,time,noads,topic,cid FROM channels",1); + + joinChan = 2; + + if (mysql_num_rows(res) > 0) { + for (i = 0;i < mysql_num_rows(res);i++) { + + row = mysql_fetch_row(res); + tmpChan = botAddChan(row[0]); + + if (tmpChan == 0x0) + return(-1); + + sWriteSocket("JOIN %s",row[0]); + sleep(2); + + pthread_mutex_lock(&chanMutex); + + /* Op Myself */ + sWriteSocket("MSG %s:.tv MODE +O TUveBOT",row[0]); + + /* Set Access Level */ + tmpVal = atoi(row[1]); + if (tmpVal > 0) + sWriteSocket("MSG %s:.tv mode +A %i",row[0],tmpVal); + else + sWriteSocket("MSG %s:.tv mode -A",row[0]); + tmpChan->modes[CHAN_RATING] = tmpVal; + + /* Set Classification */ + tmpVal = atoi(row[2]); + if (tmpVal > 0) + sWriteSocket("MSG %s:.tv mode +C %i",row[0],tmpVal); + else + sWriteSocket("MSG %s:.tv mode -C",row[0]); + tmpChan->modes[CHAN_CLASS] = tmpVal; + + /* Set Random */ + tmpVal = atoi(row[3]); + if (tmpVal == 1) + sWriteSocket("MSG %s:.tv mode +R",row[0]); + else + sWriteSocket("MSG %s:.tv mode -R",row[0]); + tmpChan->modes[CHAN_RANDOM] = tmpVal; + + /* Set Queue */ + tmpVal = atoi(row[4]); + if (tmpVal == 1) + sWriteSocket("MSG %s:.tv mode +Q",row[0]); + else + sWriteSocket("MSG %s:.tv mode -Q",row[0]); + tmpChan->modes[CHAN_QUEUE] = tmpVal; + + /* Set Exclusive */ + tmpVal = atoi(row[5]); + if (tmpVal == 1) + sWriteSocket("MSG %s:.tv mode +E",row[0]); + else + sWriteSocket("MSG %s:.tv mode -E",row[0]); + tmpChan->modes[CHAN_EXCLUSIVE] = tmpVal; + + /* Set Time */ + tmpVal = atoi(row[6]); + if (tmpVal > 0) + sWriteSocket("MSG %s:.tv mode +T %i",row[0],tmpVal); + else + sWriteSocket("MSG %s:.tv mode -T",row[0]); + tmpChan->modes[CHAN_TIME] = tmpVal; + + /* Set NoAds */ + tmpVal = atoi(row[7]); + if (tmpVal == 1) + sWriteSocket("MSG %s:.tv mode +X",row[0]); + else + sWriteSocket("MSG %s:.tv mode -X",row[0]); + tmpChan->modes[CHAN_NOADS] = tmpVal; + + if (row[8] != 0x0) { + sWriteSocket("TOPIC %s:%s",row[0],row[8]); + strcpy(tmpChan->topic,row[8]); + } + tmpChan->cid = atoi(row[9]); +sprintf(qryStr,"SELECT s.vid,time,length FROM schedule s INNER JOIN videos v ON s.vid = v.vid WHERE cid = %i AND time > %i ORDER BY time LIMIT 0,9",tmpChan->cid,time(NULL)); + res2 = dbQuery(qryStr,1); + tmpChan->sCount = mysql_num_rows(res2); + tmpChan->sCur = 0; + for (x = 0;x < tmpChan->sCount;x++) { + row = mysql_fetch_row(res2); + tmpChan->schedule[x][0] = atoi(row[1]); + tmpChan->schedule[x][1] = atoi(row[0]); + tmpChan->schedule[x][2] = atoi(row[2]); + } + if (res2) + mysql_free_result(res2); + + + tmpChan->updated = 1; + pthread_mutex_unlock(&chanMutex); + } + mysql_free_result(res); + } + joinChan = 0; + return(0x0); + } + +int botSetMode(char *data) { + botChanList_t *tmpChan = 0x0; + char *chan = 0x0; + char *mode = 0x0; + char *md_tok = 0x0; + int tmpVal = 0x0; + char qryStr[512]; + + chan = strtok_r(data,":",&md_tok); + + tmpChan = botFindChan(chan); + + if (tmpChan == 0x0) + return(-1); + + if (tmpChan->updated == 0x0) + return(0x0); + + mode = strtok_r(NULL,":",&md_tok); + + switch (mode[0]) { + case 'A': + tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); + if (tmpChan->modes[CHAN_RATING] != tmpVal) { + tmpChan->modes[CHAN_RATING] = tmpVal; + sprintf(qryStr,"UPDATE channels SET rating = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); + dbQuery(qryStr,0); + } + break; + case 'C': + tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); + if (tmpChan->modes[CHAN_CLASS] != tmpVal) { + tmpChan->modes[CHAN_CLASS] = tmpVal; + sprintf(qryStr,"UPDATE channels SET classification = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); + dbQuery(qryStr,0); + } + break; + case 'R': + tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); + if (tmpChan->modes[CHAN_RANDOM] != tmpVal) { + tmpChan->modes[CHAN_RANDOM] = tmpVal; + sprintf(qryStr,"UPDATE channels SET random = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); + dbQuery(qryStr,0); + } + break; + case 'Q': + tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); + if (tmpChan->modes[CHAN_QUEUE] != tmpVal) { + tmpChan->modes[CHAN_QUEUE] = tmpVal; + sprintf(qryStr,"UPDATE channels SET queue = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); + dbQuery(qryStr,0); + } + break; + case 'X': + tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); + if (tmpChan->modes[CHAN_NOADS] != tmpVal) { + tmpChan->modes[CHAN_NOADS] = tmpVal; + sprintf(qryStr,"UPDATE channels SET noads = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); + dbQuery(qryStr,0); + } + break; + case 'E': + tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); + if (tmpVal != 0x0) + tmpVal = 1; + if (tmpChan->modes[CHAN_EXCLUSIVE] != tmpVal) { + tmpChan->modes[CHAN_EXCLUSIVE] = tmpVal; + sprintf(qryStr,"UPDATE channels SET exclusive = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); + dbQuery(qryStr,0); + } + break; + case 'T': + tmpVal = atoi(strtok_r(NULL,":",&md_tok)); + if (tmpVal != 0x0) + tmpVal = atoi(strtok_r(NULL,"\n",&md_tok)); + if (tmpChan->modes[CHAN_TIME] != tmpVal) { + tmpChan->modes[CHAN_TIME] = tmpVal; + sprintf(qryStr,"UPDATE channels SET time = %i WHERE channel = '%s'",tmpVal,tmpChan->channel); + dbQuery(qryStr,0); + } + break; + default: + writeLog(0,"Invalid Mode: %c\n",mode[0]); + } + return(0x0); + } + +int botSetCurSong(char *data) { + char output[128]; + char *chan = 0x0; + char *song = 0x0; + + if (data == 0x0) + return(-1); + + chan = strtok(data,":"); + strtok(NULL,":"); + strtok(NULL,":"); + strtok(NULL,":"); + strtok(NULL,":"); + song = strtok(NULL,":"); + + if (song == 0x0) + return(-1); + + sprintf(output,"UPDATE channels SET nowplaying = %s WHERE channel = '%s'",song,chan); + dbQuery(output,0); + + writeLog(0,"Test: %s %s\n",chan,song); + return(0x0); + } + +int botStoreTopic(char *data) { + char *chan = 0x0; + char *topic = 0x0; + char qStr[512]; + + if (data == 0x0) + return(0x1); + + chan = strtok(data,":"); + topic = strtok(NULL,"\n"); + + if (chan == 0x0) + return(0x1); + + sprintf(qStr,"UPDATE channels SET topic = \"%s\" WHERE channel = '%s'",topic,chan); + dbQuery(qStr,0); + + return(0x0); + } + +int botDoLogin(char *cmdData) { + char *nick = 0x0; + char *ident = 0x0; + char *str_tok = 0x0; + char qryStr[256]; + MYSQL_RES *res = 0x0; + MYSQL_ROW row; + unsigned int i = 0x0; + + nick = strtok_r(cmdData,":",&str_tok); + ident = strtok_r(NULL,"\n",&str_tok); + + sprintf(qryStr,"SELECT channel FROM active a INNER JOIN channels c ON a.uid = c.oid WHERE a.userid = %s",ident); + res = dbQuery(qryStr,1); + + for (i = 0x0;i < mysql_num_rows(res);i++) { + row = mysql_fetch_row(res); + sWriteSocket("MSG %s:.tv mode +O %s",row[0],nick); + } + + if (res != 0x0) + mysql_free_result(res); + + return(0x0); + } + +int botDoJoin(char *cmdData) { + char *chan = 0x0; + char *nick = 0x0; + char *ident = 0x0; + char *str_tok = 0x0; + char qryStr[256]; + MYSQL_RES *res = 0x0; + + if (cmdData == 0x0) + return(-1); + + chan = strtok_r(cmdData,":",&str_tok); + nick = strtok_r(NULL,":",&str_tok); + ident = strtok_r(NULL,":",&str_tok); + + while (ident != 0x0) { + sprintf(qryStr,"SELECT cid FROM active a INNER JOIN channels c ON a.uid = c.oid WHERE userid = %s AND channel like '%s'",ident,chan); + res = dbQuery(qryStr,1); + if (res != 0x0) { + if (mysql_num_rows(res) > 0) + sWriteSocket("MSG %s:.tv mode +O %s",chan,nick); + mysql_free_result(res); + } + nick = strtok_r(NULL,":",&str_tok); + ident = strtok_r(NULL,":",&str_tok); + } + return(0x0); + } + +int botDoEmote(char cmdData) { +/* + char *nick = 0x0; + char *where = 0x0; + char *msg = 0x0; + + if (cmdData != 0x0) { + nick = strtok(cmdData,":"); + where = strtok(NULL,":"); + msg = strtok(NULL,"\n"); + } +*/ + return(0x0); + } diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..b93b087 --- /dev/null +++ b/src/main.c @@ -0,0 +1,225 @@ +/* + Tuved Server + (C) 2007 Christopher Olsen + + $Id: main.c,v 1.22 2008/05/28 12:03:41 reddawg Exp $ +*/ + +#include +#include +#include +#include + +#include "tuvebot.h" + +FILE *logFile = 0x0; +int logLevel = 1; +int highSock = 0x0; +int joinChan = 0x0; +time_t startTime; + +void usage(); +int botProcessData(char *data); + +int main(int argc,char **argv) { + int ch; + int doFork = 0x1; + int readSocks = 0x0; + int t = 0x0; + fd_set readSet; + char data[1024]; + struct timeval timeout = {30,0}; + + /* Get our start time */ + startTime = time(NULL); + + while ((ch = getopt(argc,argv,"sl:nd:")) != -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; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + + /* Prepare log file */ + if (logFile == 0x0) + logFile = fopen(LOG_FILE,"a"); + + /* Fork into background unless specified not to do so */ + if (doFork == 1) + if (fork() != 0x0) + exit(1); + + writeLog(0,"TUveBOT Starting: %i\n",startTime); + + dbInit(); + + srandom(time(NULL)); + + pthread_t threads[NUM_THREADS]; + + pthread_create(&threads[t], NULL, botCMD_Thread, (void *)t); + t = 1; + pthread_create(&threads[t], NULL, botSCHD_Thread, (void *)t); + + pthread_mutex_init(&chanMutex, NULL); + + sConnect(SERVER_HOST,SERVER_PORT); + + + while (1) { + + /* Build our readSet */ + sGetConnections(&readSet); + + readSocks = select(highSock+1,&readSet,0x0,0x0,&timeout); + + if (readSocks < 0) { + perror("select failed"); + exit(0x1); + } + + if (FD_ISSET(mySocket,&readSet) != 0x0) { + memset(&data,0x0,1024); + if (sReadSocket(&data,1024) == -1) { + writeLog(0,"Socket Died!\n"); + sConnect(SERVER_HOST,SERVER_PORT); + //exit(1); + } + else { + botProcessData(data); + } + } + + /* 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); + } + +int botProcessMsg(char *data) { + char *nick; + char *chan; + char *cmdData; + char *str_tok = 0x0; + botChanList_t *tmpChan; + int i; + + nick = strtok_r(data,":",&str_tok); + chan = strtok_r(NULL,":",&str_tok); + cmdData = strtok_r(NULL,"\n",&str_tok); + + if ((!strcasecmp(nick,"MrOlsen")) && (!strcasecmp(chan,"PRIVMSG"))) { + printf("cmdData: [%s]\n",cmdData); + sWriteSocket("%s\n",cmdData); + } + else if (!strcasecmp(nick,"MrOlsen") && !strcasecmp(cmdData,".ss")) { + tmpChan = botFindChan(chan); + for (i = tmpChan->sCur;i < tmpChan->sCount;i++) { + sWriteSocket("MSG %s:Time: %i,VID: %i\n",chan,tmpChan->schedule[i][0],tmpChan->schedule[i][1]); + } + } + return(0x0); + } + +int botProcessData(char *dataFresh) { + char *cmd = 0x0; + char *cmdData = 0x0; + char *str_tok = 0x0; + char *data = 0x0; + char *data2 = 0x0; + char *data_tok = 0x0; + + data = strtok_r(dataFresh,"\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 (strstr(cmd,":")) { + cmd = strtok_r(data,":",&str_tok); + cmdData = strtok_r(NULL,"\n",&str_tok); + str_tok = 0x0; + writeLog(3,"DATA: (%s)CMD: [%s], Data: [%s]\n",data,cmd,cmdData); + } + else + writeLog(3,"DATA: (%s)CMD: [%s]\n",data,cmd); + + if (cmd == 0x0) + return(0x0); + + if (strstr(cmd,"PING")) { + sWriteSocket("PONG!\n"); + } + else if (!strcmp(cmd,"IDENT")) { + sWriteSocket("MSG TUveD:.tv login tuvebot 5558585\n"); + joinChan = 1; + } + else if (!strcmp(cmd,"MSG")) + botProcessMsg(cmdData); + else if (!strcmp(cmd,"TOPIC")) + botStoreTopic(cmdData); + else if (!strcmp(cmd,"CURPOS")) + botSetCurSong(cmdData); + else if (!strcmp(cmd,"MODE")) + botSetMode(cmdData); + else if (!strcmp(cmd,"JOIN")) + botDoJoin(cmdData); + else if (!strcmp(cmd,"EMOTE")) + botDoEmote(cmdData); + else if (!strcmp(cmd,"LOGIN")) + botDoLogin(cmdData); + else { + writeLog(0,"Unknown Command: [%s]\n",cmd); + } + + if (data2 != 0x0) { + data = 0x0; + goto Head; + } + + return(0x0); + } diff --git a/src/mysql.c b/src/mysql.c new file mode 100644 index 0000000..d46fb20 --- /dev/null +++ b/src/mysql.c @@ -0,0 +1,64 @@ +/* + (C) 2007 Christopher Olsen + + $Id: mysql.c,v 1.3 2008/04/22 11:52:28 reddawg Exp $ +*/ + +#include + +#include "tuvebot.h" + +MYSQL *conn = 0x0; + +pthread_mutex_t mysqlMutex = PTHREAD_MUTEX_INITIALIZER; + + +int dbInit() { + + conn = mysql_init(NULL); + if (conn == NULL) { + writeLog(0,"mysql_init() failed (probably out of memory)\n."); + return(0x1); + } + + 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); + } + + if (mysql_options(conn,MYSQL_OPT_RECONNECT,"true") != 0x0) { + writeLog(0,"mysql_options() failed: To Set Reconnect\n"); + } + + 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/socket.c b/src/socket.c new file mode 100644 index 0000000..a632394 --- /dev/null +++ b/src/socket.c @@ -0,0 +1,100 @@ +/* + tuvebot - Socket Code + (C) 2007 Christopher Olsen + + $Id: socket.c,v 1.14 2008/04/22 11:52:28 reddawg Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tuvebot.h" + +int mySocket = 0x0; +int connected = 0x0; + +int sConnect(const char *host,int port) { + struct sockaddr_in rmAddr; // remote address information + struct hostent *hp; + int att; + + connected = 0; + + for (att = 1;att < 10;att++) { + if (mySocket != 0x0) + close(mySocket); + + if ((mySocket = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + perror("socket"); + exit(1); + } + + writeLog(0,"Connecting to: %s, port %i, socket %i, attempt: %i\n",host,port,mySocket,att); + + hp = gethostbyname(host); + + bzero(&rmAddr,sizeof(struct sockaddr_in)); + + //memcpy(&(rmAddr.sin_addr.s_addr),*(hp->h_addr_list),sizeof(struct in_addr)); + bcopy((char *)hp->h_addr,(char *)&rmAddr.sin_addr.s_addr,hp->h_length); + + rmAddr.sin_family = AF_INET; // host byte order + rmAddr.sin_port = htons(port); // short, network byte order + memset(rmAddr.sin_zero, '\0', sizeof rmAddr.sin_zero); + + if (connect(mySocket,&rmAddr,sizeof(rmAddr)) == 0x0) + break; + + writeLog(1,"Error Connecting: %i.\n",errno); + sleep(5); + } + + writeLog(2,"my Socket: [%i]\n",mySocket); + + sWriteSocket("IDENT TUveBOT:1234567\n"); + + return(0x0); + } + +ssize_t sReadSocket(void *buffer,size_t length) { + ssize_t recLen = 0x0; + + recLen = read(mySocket,buffer,length); + if (recLen == 0x0) + return(-1); + + return(recLen); + } + +int sWriteSocket(char const * __restrict fmt, ...) { + char data[1024]; + int len = 0x0; + va_list ap; + + va_start(ap,fmt); + len = vsnprintf(data,1023,fmt,ap); + va_end(ap); + + data[len++] = '\n'; + + send(mySocket,data,len,MSG_NOSIGNAL); + return(0x0); + } + +int sGetConnections(fd_set *readset) { + + FD_ZERO(readset); + + FD_SET(mySocket,readset); + + highSock = mySocket + 1; + + return(0x0); + } + diff --git a/src/thread.c b/src/thread.c new file mode 100644 index 0000000..171210f --- /dev/null +++ b/src/thread.c @@ -0,0 +1,207 @@ +/* + (C) 2007,2008 Christopher Olsen + + $Id: thread.c,v 1.22 2008/05/28 12:03:41 reddawg Exp $ +*/ + +#include +#include +#include "tuvebot.h" + +void *botSCHD_Thread(void *threadid) { + botChanList_t *tmpChan = 0x0; + int i = 0x0; + int sTime = 0x0; + unsigned int cTime = 0x0; + unsigned int tM = 0x0; + char qryStr[256]; + MYSQL_RES *res = 0x0; + MYSQL_ROW row; + + while (1) { + writeLog(0,"schedule!\n"); + pthread_mutex_lock(&chanMutex); + writeLog(0,"Doing Chans: 0x%X\n",tmpChan); + cTime = time(NULL); + sTime = 30; + for (tmpChan = chans;tmpChan != 0x0;tmpChan = tmpChan->next) { + writeLog(0,"Time: %i:%i [%s]\n",tmpChan->schedule[tmpChan->sCur][0],cTime,tmpChan->channel); + if ((tmpChan->sCount > 0) && (tmpChan->schedule[tmpChan->sCur][0] <= cTime)) { + sTime = 5; + if (tmpChan->sM == 0) { + sWriteSocket("MSG %s:.tv mode +S\n",tmpChan->channel); + tmpChan->sM = 1; + } + sWriteSocket("VIDEO %s:%i\n",tmpChan->channel,tmpChan->schedule[tmpChan->sCur][1]); + tM = tmpChan->schedule[tmpChan->sCur + 1][0] - (tmpChan->schedule[tmpChan->sCur][0] + tmpChan->schedule[tmpChan->sCur][2]); + if (tM < 0 || tM > 30) { + sWriteSocket("MSG %s:.tv mode -S\n",tmpChan->channel); + tmpChan->sM = 0; + } + tmpChan->sCur++; + if (tmpChan->sCur >= tmpChan->sCount - 1) { + sprintf(qryStr,"SELECT s.vid,time,length FROM schedule s INNER JOIN videos v ON s.vid = v.vid WHERE cid = %i AND time > %i ORDER BY time LIMIT 0,9",tmpChan->cid,cTime); + res = dbQuery(qryStr,1); + tmpChan->sCount = mysql_num_rows(res); + tmpChan->sCur = 0; + for (i = 0;i < tmpChan->sCount;i++) { + row = mysql_fetch_row(res); + tmpChan->schedule[i][0] = atoi(row[1]); + tmpChan->schedule[i][1] = atoi(row[0]); + tmpChan->schedule[i][2] = atoi(row[2]); + } + if (res) + mysql_free_result(res); + } + } + } + pthread_mutex_unlock(&chanMutex); + + sleep(sTime); + } + } + +void *botCMD_Thread(void *threadid) { + int tid = 0x0; + unsigned int i = 0; + unsigned int x = 0; + int tmpVal = 0; + short lC = 0x0; + char qryStr[256]; + botChanList_t *tmpChan = 0x0; + MYSQL_RES *res = 0x0; + MYSQL_ROW row; + MYSQL_RES *res2 = 0x0; + + tid = (int)threadid; + writeLog(0,"Starting Bot's CMD Thread: [%d]\n", tid); + + while (1) { + if (connected == 0) { + sleep(5); + if (joinChan != 0) { + connected = 1; + if (joinChan != 2) + botJoinChans(); + } + } + else { + sleep(30); + res = dbQuery("SELECT channel,rating,classification,random,queue,exclusive,time,topic,noads,cid FROM channels WHERE updated = 1",1); + if (mysql_num_rows(res) > 0) { + for (i = 0;i < mysql_num_rows(res);i++) { + row = mysql_fetch_row(res); + + tmpChan = botFindChan(row[0]); + if (tmpChan == 0x0) { + writeLog(3,"Adding Chan: %s\n",row[0]); + tmpChan = botAddChan(row[0]); + } + pthread_mutex_lock(&chanMutex); + /* Set Access Level */ + tmpVal = atoi(row[1]); + if (tmpChan->modes[CHAN_RATING] != tmpVal) { + if (tmpVal > 0) + sWriteSocket("MSG %s:.tv mode +A %i",row[0],tmpVal); + else + sWriteSocket("MSG %s:.tv mode -A",row[0]); + tmpChan->modes[CHAN_RATING] = tmpVal; + } + + /* Set Classification */ + tmpVal = atoi(row[2]); + if (tmpChan->modes[CHAN_CLASS] != tmpVal) { + if (tmpVal > 0) + sWriteSocket("MSG %s:.tv mode +C %i",row[0],tmpVal); + else + sWriteSocket("MSG %s:.tv mode -C",row[0]); + tmpChan->modes[CHAN_CLASS] = tmpVal; + } + + /* Set Random */ + tmpVal = atoi(row[3]); + if (tmpChan->modes[CHAN_RANDOM] != tmpVal) { + if (tmpVal == 1) + sWriteSocket("MSG %s:.tv mode +R",row[0]); + else + sWriteSocket("MSG %s:.tv mode -R",row[0]); + tmpChan->modes[CHAN_RANDOM] = tmpVal; + } + + /* Set Queue */ + tmpVal = atoi(row[4]); + if (tmpChan->modes[CHAN_QUEUE] != tmpVal) { + if (tmpVal == 1) + sWriteSocket("MSG %s:.tv mode +Q",row[0]); + else + sWriteSocket("MSG %s:.tv mode -Q",row[0]); + tmpChan->modes[CHAN_QUEUE] = tmpVal; + } + + /* Set Exclusive */ + tmpVal = atoi(row[5]); + if (tmpChan->modes[CHAN_EXCLUSIVE] != tmpVal) { + if (tmpVal == 1) + sWriteSocket("MSG %s:.tv mode +E",row[0]); + else + sWriteSocket("MSG %s:.tv mode -E",row[0]); + tmpChan->modes[CHAN_EXCLUSIVE] = tmpVal; + } + + /* Set Time */ + tmpVal = atoi(row[6]); + if (tmpChan->modes[CHAN_TIME] != tmpVal) { + if (tmpVal > 0) + sWriteSocket("MSG %s:.tv mode +T %i",row[0],tmpVal); + else + sWriteSocket("MSG %s:.tv mode -T",row[0]); + tmpChan->modes[CHAN_TIME] = tmpVal; + } + + tmpVal = atoi(row[8]); + if (tmpChan->modes[CHAN_NOADS] != tmpVal) { + if (tmpVal == 1) + sWriteSocket("MSG %s:.tv mode +X",row[0]); + else + sWriteSocket("MSG %s:.tv mode -X",row[0]); + tmpChan->modes[CHAN_NOADS] = tmpVal; + } + + if (strcmp(tmpChan->topic,row[7])) { + sWriteSocket("TOPIC %s:%s",row[0],row[7]); + strcpy(tmpChan->topic,row[7]); + } + + sprintf(qryStr,"UPDATE channels SET updated = 0 WHERE channel = '%s'",row[0]); + dbQuery(qryStr,0); + + tmpChan->cid = atoi(row[9]); + sprintf(qryStr,"SELECT s.vid,time,length FROM schedule s INNER JOIN videos v ON s.vid = v.vid WHERE cid = %i AND time > %i ORDER BY time LIMIT 0,9",tmpChan->cid,time(NULL)); + writeLog(0,qryStr); + res2 = dbQuery(qryStr,1); + tmpChan->sCount = mysql_num_rows(res2); + tmpChan->sCur = 0; + for (x = 0;x < tmpChan->sCount;x++) { + row = mysql_fetch_row(res2); + tmpChan->schedule[x][0] = atoi(row[1]); + tmpChan->schedule[x][1] = atoi(row[0]); + tmpChan->schedule[x][2] = atoi(row[2]); + } + if (res2) + mysql_free_result(res2); + pthread_mutex_unlock(&chanMutex); + } + } + + if (res != 0x0) + mysql_free_result(res); + + if (lC == 6) { + lC = 0; + sWriteSocket("STATUS"); + } + lC++; + } + } + pthread_exit(NULL); + } /* End tuveCMD_Thread() */ diff --git a/src/tuvebot.h b/src/tuvebot.h new file mode 100644 index 0000000..0b6ed2c --- /dev/null +++ b/src/tuvebot.h @@ -0,0 +1,127 @@ +/* + (c) 2007 Christopher Olsen + + $Id: tuvebot.h,v 1.18 2009/02/18 19:53:46 reddawg Exp $ +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define SERVER_HOST "127.0.0.1" //"Ivorytower.UbixOnline.com" +#define SERVER_PORT 2007 + +#define NUM_THREADS 2 +#define MYPORT 2007 // the port users will be connecting to +#define BACKLOG 10 // how many pending connections queue will hold +#define LOG_FILE "./logs/tuvebot.log" +#define PING_INTERVAL 20 +#define MAX_PING 2 +#define MAX_COUNT 2 +#define MAX_TOPIC_LEN 128 +#define MAX_CHAN_LEN 32 +#define VERSION "v0.40" +#define MYSQL_HOST_NAME "SPBX-DB002.SpherePBX.com" +#define MYSQL_USERNAME "tuve" +#define MYSQL_PASSWORD "5558585" +#define MYSQL_DB_NAME "tuve" + +/* Cannel Modes */ +#define CHAN_MODES 8 // 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_NOADS 7 // Channel Has No Advertisements + +typedef struct botChanList { + struct botChanList *prev; + struct botChanList *next; + int modes[CHAN_MODES]; + char topic[MAX_TOPIC_LEN]; + char channel[MAX_CHAN_LEN]; + short updated; + short sM; + unsigned int schedule[10][3]; + int sCount; + int sCur; + int cid; + } botChanList_t; + +typedef struct myConnections { + struct myConnections *prev; + struct myConnections *next; + int fd; + int recLen; + char data[1024]; + char host[128]; + time_t signedOn; + } myConnections_t; + +/* + Global variables very not safe + */ + +extern int mySocket; +extern int connected; +extern pthread_mutex_t chanMutex; +extern botChanList_t *chans; + +extern int highSock; +extern FILE *logFile; +extern time_t startTime; +extern int joinChan; + +/* Socket Functions */ +int sConnect(const char *host,int port); +ssize_t sReadSocket(void *buffer,size_t length); +int sGetConnections(fd_set *readset); +int sWriteSocket(char const * __restrict fmt, ...); + +/* Log Functions */ +int writeLog(int level,char const * __restrict, ...); + +/* Channel Functions */ +int tuveChanList(myConnections_t *userConnection); +int tuveChanPart(const char *channel,myConnections_t *userConnection); +int tuveChanJoin(const char *channel,myConnections_t *userConnection); +int tuveAddChan(const char *channel,myConnections_t *userConnection); +int tuveAddToChanList(const char *channel,myConnections_t *userConnection); +int tuveSendAllInChan(const char *channel,myConnections_t *userConnection,char *output); +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(char *by,char *chan,char *nick,char *msg); +int tuveBan(const char *channel,const char *nick); +int tuveUnBan(const char *channel,const char *nick); +int tuveVerifyBan(const char *channel,const char *nick); + +/* Bot Functions */ +void *tuveBotThread(void *threadid); +int tuveBotCMD(myConnections_t *userConnection,char *chan,char *data); +int tuveBotSetSong(char *chan,char *playTime,char *file,char *title); +int tuveBotNoSong(char *chan); + +/* Database Functions */ +int dbInit(); +MYSQL_RES *dbQuery(const char *query,short type); + +/* Bot Functions */ +int botJoinChans(); +int botStoreTopic(char *data); +void *botCMD_Thread(void *threadid); +void *botSCHD_Thread(void *threadid); +botChanList_t *botFindChan(char *channel); +botChanList_t *botAddChan(char *channel); +int botDoLogin(char *cmdData); diff --git a/thread.c b/thread.c deleted file mode 100644 index 171210f..0000000 --- a/thread.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - (C) 2007,2008 Christopher Olsen - - $Id: thread.c,v 1.22 2008/05/28 12:03:41 reddawg Exp $ -*/ - -#include -#include -#include "tuvebot.h" - -void *botSCHD_Thread(void *threadid) { - botChanList_t *tmpChan = 0x0; - int i = 0x0; - int sTime = 0x0; - unsigned int cTime = 0x0; - unsigned int tM = 0x0; - char qryStr[256]; - MYSQL_RES *res = 0x0; - MYSQL_ROW row; - - while (1) { - writeLog(0,"schedule!\n"); - pthread_mutex_lock(&chanMutex); - writeLog(0,"Doing Chans: 0x%X\n",tmpChan); - cTime = time(NULL); - sTime = 30; - for (tmpChan = chans;tmpChan != 0x0;tmpChan = tmpChan->next) { - writeLog(0,"Time: %i:%i [%s]\n",tmpChan->schedule[tmpChan->sCur][0],cTime,tmpChan->channel); - if ((tmpChan->sCount > 0) && (tmpChan->schedule[tmpChan->sCur][0] <= cTime)) { - sTime = 5; - if (tmpChan->sM == 0) { - sWriteSocket("MSG %s:.tv mode +S\n",tmpChan->channel); - tmpChan->sM = 1; - } - sWriteSocket("VIDEO %s:%i\n",tmpChan->channel,tmpChan->schedule[tmpChan->sCur][1]); - tM = tmpChan->schedule[tmpChan->sCur + 1][0] - (tmpChan->schedule[tmpChan->sCur][0] + tmpChan->schedule[tmpChan->sCur][2]); - if (tM < 0 || tM > 30) { - sWriteSocket("MSG %s:.tv mode -S\n",tmpChan->channel); - tmpChan->sM = 0; - } - tmpChan->sCur++; - if (tmpChan->sCur >= tmpChan->sCount - 1) { - sprintf(qryStr,"SELECT s.vid,time,length FROM schedule s INNER JOIN videos v ON s.vid = v.vid WHERE cid = %i AND time > %i ORDER BY time LIMIT 0,9",tmpChan->cid,cTime); - res = dbQuery(qryStr,1); - tmpChan->sCount = mysql_num_rows(res); - tmpChan->sCur = 0; - for (i = 0;i < tmpChan->sCount;i++) { - row = mysql_fetch_row(res); - tmpChan->schedule[i][0] = atoi(row[1]); - tmpChan->schedule[i][1] = atoi(row[0]); - tmpChan->schedule[i][2] = atoi(row[2]); - } - if (res) - mysql_free_result(res); - } - } - } - pthread_mutex_unlock(&chanMutex); - - sleep(sTime); - } - } - -void *botCMD_Thread(void *threadid) { - int tid = 0x0; - unsigned int i = 0; - unsigned int x = 0; - int tmpVal = 0; - short lC = 0x0; - char qryStr[256]; - botChanList_t *tmpChan = 0x0; - MYSQL_RES *res = 0x0; - MYSQL_ROW row; - MYSQL_RES *res2 = 0x0; - - tid = (int)threadid; - writeLog(0,"Starting Bot's CMD Thread: [%d]\n", tid); - - while (1) { - if (connected == 0) { - sleep(5); - if (joinChan != 0) { - connected = 1; - if (joinChan != 2) - botJoinChans(); - } - } - else { - sleep(30); - res = dbQuery("SELECT channel,rating,classification,random,queue,exclusive,time,topic,noads,cid FROM channels WHERE updated = 1",1); - if (mysql_num_rows(res) > 0) { - for (i = 0;i < mysql_num_rows(res);i++) { - row = mysql_fetch_row(res); - - tmpChan = botFindChan(row[0]); - if (tmpChan == 0x0) { - writeLog(3,"Adding Chan: %s\n",row[0]); - tmpChan = botAddChan(row[0]); - } - pthread_mutex_lock(&chanMutex); - /* Set Access Level */ - tmpVal = atoi(row[1]); - if (tmpChan->modes[CHAN_RATING] != tmpVal) { - if (tmpVal > 0) - sWriteSocket("MSG %s:.tv mode +A %i",row[0],tmpVal); - else - sWriteSocket("MSG %s:.tv mode -A",row[0]); - tmpChan->modes[CHAN_RATING] = tmpVal; - } - - /* Set Classification */ - tmpVal = atoi(row[2]); - if (tmpChan->modes[CHAN_CLASS] != tmpVal) { - if (tmpVal > 0) - sWriteSocket("MSG %s:.tv mode +C %i",row[0],tmpVal); - else - sWriteSocket("MSG %s:.tv mode -C",row[0]); - tmpChan->modes[CHAN_CLASS] = tmpVal; - } - - /* Set Random */ - tmpVal = atoi(row[3]); - if (tmpChan->modes[CHAN_RANDOM] != tmpVal) { - if (tmpVal == 1) - sWriteSocket("MSG %s:.tv mode +R",row[0]); - else - sWriteSocket("MSG %s:.tv mode -R",row[0]); - tmpChan->modes[CHAN_RANDOM] = tmpVal; - } - - /* Set Queue */ - tmpVal = atoi(row[4]); - if (tmpChan->modes[CHAN_QUEUE] != tmpVal) { - if (tmpVal == 1) - sWriteSocket("MSG %s:.tv mode +Q",row[0]); - else - sWriteSocket("MSG %s:.tv mode -Q",row[0]); - tmpChan->modes[CHAN_QUEUE] = tmpVal; - } - - /* Set Exclusive */ - tmpVal = atoi(row[5]); - if (tmpChan->modes[CHAN_EXCLUSIVE] != tmpVal) { - if (tmpVal == 1) - sWriteSocket("MSG %s:.tv mode +E",row[0]); - else - sWriteSocket("MSG %s:.tv mode -E",row[0]); - tmpChan->modes[CHAN_EXCLUSIVE] = tmpVal; - } - - /* Set Time */ - tmpVal = atoi(row[6]); - if (tmpChan->modes[CHAN_TIME] != tmpVal) { - if (tmpVal > 0) - sWriteSocket("MSG %s:.tv mode +T %i",row[0],tmpVal); - else - sWriteSocket("MSG %s:.tv mode -T",row[0]); - tmpChan->modes[CHAN_TIME] = tmpVal; - } - - tmpVal = atoi(row[8]); - if (tmpChan->modes[CHAN_NOADS] != tmpVal) { - if (tmpVal == 1) - sWriteSocket("MSG %s:.tv mode +X",row[0]); - else - sWriteSocket("MSG %s:.tv mode -X",row[0]); - tmpChan->modes[CHAN_NOADS] = tmpVal; - } - - if (strcmp(tmpChan->topic,row[7])) { - sWriteSocket("TOPIC %s:%s",row[0],row[7]); - strcpy(tmpChan->topic,row[7]); - } - - sprintf(qryStr,"UPDATE channels SET updated = 0 WHERE channel = '%s'",row[0]); - dbQuery(qryStr,0); - - tmpChan->cid = atoi(row[9]); - sprintf(qryStr,"SELECT s.vid,time,length FROM schedule s INNER JOIN videos v ON s.vid = v.vid WHERE cid = %i AND time > %i ORDER BY time LIMIT 0,9",tmpChan->cid,time(NULL)); - writeLog(0,qryStr); - res2 = dbQuery(qryStr,1); - tmpChan->sCount = mysql_num_rows(res2); - tmpChan->sCur = 0; - for (x = 0;x < tmpChan->sCount;x++) { - row = mysql_fetch_row(res2); - tmpChan->schedule[x][0] = atoi(row[1]); - tmpChan->schedule[x][1] = atoi(row[0]); - tmpChan->schedule[x][2] = atoi(row[2]); - } - if (res2) - mysql_free_result(res2); - pthread_mutex_unlock(&chanMutex); - } - } - - if (res != 0x0) - mysql_free_result(res); - - if (lC == 6) { - lC = 0; - sWriteSocket("STATUS"); - } - lC++; - } - } - pthread_exit(NULL); - } /* End tuveCMD_Thread() */ diff --git a/tuvebot.h b/tuvebot.h deleted file mode 100644 index a68b615..0000000 --- a/tuvebot.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - (c) 2007 Christopher Olsen - - $Id: tuvebot.h,v 1.18 2009/02/18 19:53:46 reddawg Exp $ -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - - -#define SERVER_HOST "127.0.0.1" //"Ivorytower.UbixOnline.com" -#define SERVER_PORT 9999 - -#define NUM_THREADS 2 -#define MYPORT 9999 // the port users will be connecting to -#define BACKLOG 10 // how many pending connections queue will hold -#define LOG_FILE "./logs/tuvebot.log" -#define PING_INTERVAL 20 -#define MAX_PING 2 -#define MAX_COUNT 2 -#define MAX_TOPIC_LEN 128 -#define MAX_CHAN_LEN 32 -#define VERSION "v0.40" -#define MYSQL_HOST_NAME "SPBX-DB002.SpherePBX.com" -#define MYSQL_USERNAME "tuve" -#define MYSQL_PASSWORD "5558585" -#define MYSQL_DB_NAME "tuve" - -/* Cannel Modes */ -#define CHAN_MODES 8 // 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_NOADS 7 // Channel Has No Advertisements - -typedef struct botChanList { - struct botChanList *prev; - struct botChanList *next; - int modes[CHAN_MODES]; - char topic[MAX_TOPIC_LEN]; - char channel[MAX_CHAN_LEN]; - short updated; - short sM; - unsigned int schedule[10][3]; - int sCount; - int sCur; - int cid; - } botChanList_t; - -typedef struct myConnections { - struct myConnections *prev; - struct myConnections *next; - int fd; - int recLen; - char data[1024]; - char host[128]; - time_t signedOn; - } myConnections_t; - -/* - Global variables very not safe - */ - -extern int mySocket; -extern int connected; -extern pthread_mutex_t chanMutex; -extern botChanList_t *chans; - -extern int highSock; -extern FILE *logFile; -extern time_t startTime; -extern int joinChan; - -/* Socket Functions */ -int sConnect(const char *host,int port); -ssize_t sReadSocket(void *buffer,size_t length); -int sGetConnections(fd_set *readset); -int sWriteSocket(char const * __restrict fmt, ...); - -/* Log Functions */ -int writeLog(int level,char const * __restrict, ...); - -/* Channel Functions */ -int tuveChanList(myConnections_t *userConnection); -int tuveChanPart(const char *channel,myConnections_t *userConnection); -int tuveChanJoin(const char *channel,myConnections_t *userConnection); -int tuveAddChan(const char *channel,myConnections_t *userConnection); -int tuveAddToChanList(const char *channel,myConnections_t *userConnection); -int tuveSendAllInChan(const char *channel,myConnections_t *userConnection,char *output); -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(char *by,char *chan,char *nick,char *msg); -int tuveBan(const char *channel,const char *nick); -int tuveUnBan(const char *channel,const char *nick); -int tuveVerifyBan(const char *channel,const char *nick); - -/* Bot Functions */ -void *tuveBotThread(void *threadid); -int tuveBotCMD(myConnections_t *userConnection,char *chan,char *data); -int tuveBotSetSong(char *chan,char *playTime,char *file,char *title); -int tuveBotNoSong(char *chan); - -/* Database Functions */ -int dbInit(); -MYSQL_RES *dbQuery(const char *query,short type); - -/* Bot Functions */ -int botJoinChans(); -int botStoreTopic(char *data); -void *botCMD_Thread(void *threadid); -void *botSCHD_Thread(void *threadid); -botChanList_t *botFindChan(char *channel); -botChanList_t *botAddChan(char *channel); -int botDoLogin(char *cmdData);