Newer
Older
tuved / channel.c
@reddawg reddawg on 28 Oct 2007 11 KB Sync
/*
  (c) 2007 Christopher Olsen
  $Id$
*/

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <assert.h>

#include "tuved.h"

tuveChanList_t *channels = 0x0;

tuveChanList_t *findChan(char *channel);
tuveChanList_t *addChan(char *channel);

int tuveChanPart(char *channel,myConnections_t *userConnection) {
  char output[512];
  
  if (tuveRemoveFromChanList(channel,userConnection) == 0x1)
    writeLog(0,"ERROR: Can not remove %s from %s\n",userConnection->userInfo.username,channel);
  if (tuveDelChan(channel,userConnection) == 0x1)
    writeLog(0,"ERROR: Can not remove %s From %s's List\n",channel,userConnection->userInfo);
    
  sprintf(output,"CHANMSG:TUveD:%s:%s Part (Left Channel)\n",channel,userConnection->userInfo.username);
  tuveSendAllInChan(channel,0x0,output);
  sprintf(output,"PART:%s:%s\n",channel,userConnection->userInfo.username);
  tuveSendAllInChan(channel,0x0,output);
  return(0x0);
  } /* End tuveChanPart(); */
  
/*
 * Joins A User To A Channel
 */
int 
tuveChanJoin(char *channel,myConnections_t *userConnection) {
  char output[256];
  tuveChanList_t *tmpChan = 0x0;
  int min, sec;

  assert(channel);
  assert(userConnection);

  if (tuveAddChan(channel,userConnection) != 0x0) return(0x1);

  /* Send JOIN to all users in the channel */
  sprintf(output,"JOIN:%s:%s\n",channel,userConnection->userInfo.username);
  tuveSendAllInChan(channel,userConnection,output);

  tmpChan = findChan(channel);
  assert(tmpChan);

  sprintf(output,"CURPOS:%i:%s:%s\n",tmpChan->songTime - (tmpChan->songEnd - (time(NULL) + 2)),tmpChan->curSong,tmpChan->songTitle);
  sSendData(userConnection,output);

  min = tmpChan->songTime / 60;
  sec = tmpChan->songTime % 60;

  sprintf(output,"CHANMSG:@TUveBOT:%s:Playing %s (%i:%.2i)\n",channel,tmpChan->songTitle,min,sec);
  sSendData(userConnection,output);

    
  /* Notify people in the channel that someone has joined */
  sprintf(output,"CHANMSG:TUveD:%s:%s (%s) has joined the channel.\n",channel,userConnection->userInfo.username,userConnection->host);
  tuveSendAllInChan(channel,userConnection,output);

  return(0x0);
  }

int tuveDelUserChans(myConnections_t *userConnection,char *msg) {
  char output[256];
  tuveUserChans_t *tmpChan  = 0x0;
  tuveUserChans_t *tmpChan2 = 0x0;

  tmpChan = userConnection->userInfo.chans;
  tmpChan2 = tmpChan;

  for (;tmpChan != 0x0;tmpChan = tmpChan->next) {
    sprintf(output,"CHANMSG:TUveD:%s:%s Quit (%s)\n",tmpChan->channel,userConnection->userInfo.username,msg);
    tuveSendAllInChan(tmpChan->channel,userConnection,output);
    sprintf(output,"PART:%s:%s\n",tmpChan->channel,userConnection->userInfo.username);
    tuveSendAllInChan(tmpChan->channel,userConnection,output);
    tuveRemoveFromChanList(tmpChan->channel,userConnection);
    free(tmpChan2);
    tmpChan2 = tmpChan->next;
    }

  if (tmpChan2 != 0x0) {
    free(tmpChan2);
    }

  return(0x0);
  }

int tuveAddChan(char *channel,myConnections_t *userConnection) {
  tuveUserChans_t *tmpChan = 0x0;

  if (userConnection->userInfo.chans == 0x0) {
    userConnection->userInfo.chans = (tuveUserChans_t *)malloc(sizeof(tuveUserChans_t));
    userConnection->userInfo.chans->prev = 0x0;
    userConnection->userInfo.chans->next = 0x0;
    sprintf(userConnection->userInfo.chans->channel,channel);
    }
  else {
    tmpChan = (tuveUserChans_t *)malloc(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(char *channel,myConnections_t *userConnection) {
  tuveUserChans_t *tmpChan = 0x0;

  if (channel == 0x0)
    writeLog(0,"WHERE IS THE CHANNEL? tuveDelChan\n");

  writeLog(0,"TESTING DEL\n");
  
  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);
 
          writeLog(0,"TEST: [0x%X]\n",userConnection->userInfo.chans);

          return(0x0);
  	  }
    }
  return(0x1);
  }

int tuveRemoveFromChanList(char *channel,myConnections_t *userConnection) {
  tuveChanList_t *tmpChannel = 0x0;
  tuveUserList_t *tmpUsers   = 0x0;

  tmpChannel = findChan(channel);
  if (tmpChannel == 0x0) {
    writeLog(1,"findChan failed!\n");
    return(0x1);
    }
   
  tmpUsers = tmpChannel->users;

  writeLog(2,"Freeing User From Chan: %s\n",channel);

  for (;tmpUsers != 0x0;tmpUsers = tmpUsers->next) {
    if (!strcasecmp(tmpUsers->user->userInfo.username,userConnection->userInfo.username)) {
      printf("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;

      if (tmpChannel->nextUser == tmpUsers) {
        if (tmpUsers->next != 0x0)
          tmpChannel->nextUser = tmpUsers->next;
        else if (tmpChannel->users != 0x0)
          tmpChannel->nextUser = tmpChannel->users;
        else 
          tmpChannel->nextUser = 0x0;
        }
      tmpChannel->count = 0x0;

      free(tmpUsers);
      printf("User Freed\n");
      return(0x0);
      }
    }
  return(0x1);
  }

int 
tuveAddToChanList(char *channel,myConnections_t *userConnection) {
  tuveChanList_t *tmpChannel = 0x0;
  tuveUserList_t *tmpUsers   = 0x0;

  char output[1024];
  
  tmpChannel = findChan(channel);

  // tmpChannel is okay to be null here  

  if (tmpChannel == 0x0) {
    writeLog(2,"Channel %s Does Not Exist Adding To List\n",channel);
    tmpChannel = addChan(channel);
    } 

  for (tmpUsers = tmpChannel->users;tmpUsers != 0x0;tmpUsers = tmpUsers->next) {
    if (!strcasecmp(tmpUsers->user->userInfo.username,userConnection->userInfo.username)) {
      writeLog(2,"User: %s already in channel %s\n",userConnection->userInfo.username,channel);
      return(0x0);
      }
    }

  tmpUsers = (tuveUserList_t *)malloc(sizeof(tuveUserList_t));

  tmpUsers->user = userConnection;
  tmpUsers->prev = 0x0;

  if (tmpChannel->users == 0x0) {
    tmpUsers->next = 0x0;
    tmpChannel->users = tmpUsers;
    }
  else {
    tmpUsers->next = tmpChannel->users;
    tmpChannel->users->prev = tmpUsers;
    tmpChannel->users = tmpUsers;
    }

  if (tmpChannel->nextUser == 0x0) {
    tmpChannel->nextUser = tmpUsers;
    tmpChannel->count = 0x0;
    }

  memset(output,0x0,256);
  sprintf(output,"JOIN:%s:@TUveBOT",tmpChannel->channel);

  /* Send the new user the channel list */
  for (tmpUsers = tmpChannel->users->next;tmpUsers != 0x0;tmpUsers = tmpUsers->next) {
    if (strlen(output) > 0)
      sprintf(output,"%s:%s",output,tmpUsers->user->userInfo.username);
    else
      sprintf(output,"JOIN:%s:%s",tmpChannel->channel,tmpUsers->user->userInfo.username);
    }

  if (strlen(output) > 0) {
    sprintf(output,"%s\n",output);
    sSendData(userConnection,output);
    }

  sprintf(output,"TOPIC:%s:%s\n",tmpChannel->channel,tmpChannel->topic);
  sSendData(userConnection,output);
  
  writeLog(2,"Added user: %s to Channel: %s\n",userConnection->userInfo.username,channel);

  return(0x0);
  }

tuveChanList_t *findChan(char *channel) {
  tuveChanList_t *tmpChannel = 0x0;

  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(char *channel) {
  tuveChanList_t *tmpChannel = 0x0;

  pthread_mutex_lock(&chanMutex);

  if (channels == 0x0) {
    channels = (tuveChanList_t *)malloc(sizeof(tuveChanList_t));
    channels->next = 0x0;
    channels->prev = 0x0;
    channels->users = 0x0;
    sprintf(channels->channel,channel);
    sprintf(channels->topic,"No Topic Set");
    writeLog(2,"ADDED CHAN1\n");
    tmpChannel = channels;
    }
  else {
    tmpChannel = (tuveChanList_t *)malloc(sizeof(tuveChanList_t));
    sprintf(tmpChannel->channel,channel);
    sprintf(tmpChannel->topic,"General Information About The TUve Network\n");
    tmpChannel->next = channels;
    tmpChannel->prev = 0x0;
    tmpChannel->users = 0x0;
    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(char *channel,myConnections_t *userConnection,char *output) {
  tuveChanList_t *tmpChannel = 0x0;
  tuveUserList_t *tmpUsers   = 0x0;

  tmpChannel = findChan(channel);

  if (tmpChannel == 0x0) {
    writeLog(1,"findChan Failed!\n");
    return(0x1);
    }

  tmpUsers = tmpChannel->users;

  for (;tmpUsers != 0x0;tmpUsers = tmpUsers->next) {
    if (userConnection == 0x0)
      sSendData(tmpUsers->user,output);
    else if (strcasecmp(tmpUsers->user->userInfo.username,userConnection->userInfo.username))
      sSendData(tmpUsers->user,output);
    }
  
  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);
    }

  sprintf(tmpChannel->topic,topic);
  sprintf(output,"TOPIC:%s:%s\n",chan,tmpChannel->topic);
  tuveSendAllInChan(chan,0x0,output);
  sprintf(output,"CHANMSG:TUveD:%s:%s Has Set The Topic\n",chan,userConnection->userInfo.username);
  tuveSendAllInChan(chan,userConnection,output);

  return(0x0);
  }

int tuveKick(char *by,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 = findNick(nick);

  if (userConnection == 0x0) {
    writeLog(1,"findNick Failed: Kick\n");
    return(0x1);
    }

  sprintf(output,"KICK:%s:%s:%s\n",chan,by,msg);
  sSendData(userConnection,output);

  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);


  sprintf(output,"CHANMSG:TUveD:%s:%s Has Been Kick By %s, Reason: %s\n",chan,nick,by,msg);
  tuveSendAllInChan(chan,0x0,output);

  sprintf(output,"PART:%s:%s\n",chan,nick);
  tuveSendAllInChan(chan,0x0,output);

  writeLog(0,"Kicked %s\n",output);

  return(0x0);
  }