changed Makefile; build all commands as an own file
[NeonServV5.git] / ChanNode.c
index f7161aacee15632374be936bbfda69ffe211e32f..73adbf6b3881ee6d17c505cb6eb48101a49c3519 100644 (file)
@@ -1,4 +1,9 @@
 #include "ChanNode.h"
+#include "ChanUser.h"
+#include "UserNode.h"
+#include "BanNode.h"
+#include "modcmd.h"
+#include "ModeNode.h"
 
 static struct ChanNode **chanList;
 
@@ -12,7 +17,26 @@ void init_ChanNode() {
      ---------------------------
      = 47
     */
-    userList = calloc(47, sizeof(*userList));
+    #define CHANNEL_LIST_SIZE 47
+    chanList = calloc(CHANNEL_LIST_SIZE, sizeof(*chanList));
+}
+
+void free_ChanNode() {
+    //kamikaze free all channels and chanusers
+    int i;
+    struct ChanNode *chan, *next;
+    struct ChanUser *chanuser, *next_chanuser;
+    for(i = 0; i < CHANNEL_LIST_SIZE; i++) {
+        for(chan = chanList[i]; chan; chan = next) {
+            next = chan->next;
+            for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = next_chanuser) {
+                next_chanuser = getChannelUsers(chan, chanuser);
+                free(chanuser);
+            }
+            freeChanNode(chan);
+        }
+    }
+    free(chanList);
 }
 
 int is_valid_chan(const char *name) {
@@ -53,7 +77,7 @@ static int get_chanlist_entry(int name) {
 }
 
 struct ChanNode* getChanByName(const char *name) { //case insensitive
-    int chanListIndex = get_chanlist_entry(*name);
+    int chanListIndex = get_chanlist_entry(name[1]);
     if(chanListIndex == -1 || chanList[chanListIndex] == NULL)
         return NULL;
     struct ChanNode *chan;
@@ -64,10 +88,129 @@ struct ChanNode* getChanByName(const char *name) { //case insensitive
     return NULL;
 }
 
-struct ChanNode* addChannel(const char *chan) {
-    return NULL; //to be continued
+struct ChanNode* addChannel(const char *name) {
+    int chanListIndex = get_chanlist_entry(name[1]);
+    if(chanListIndex == -1 || !is_valid_chan(name))
+        return NULL;
+    struct ChanNode *chan = malloc(sizeof(*chan));
+    if (!chan)
+    {
+        perror("malloc() failed");
+        return NULL;
+    }
+    strcpy(chan->name, name);
+    chan->user = NULL;
+    chan->bans = NULL;
+    chan->usercount = 0;
+    chan->chanbot = NULL;
+    chan->topic[0] = 0;
+    chan->flags = 0;
+    /* mode lists */
+    chan->modes = createModeNode(chan);
+    chan->trigger = NULL;
+    
+    chan->next = chanList[chanListIndex];
+    chanList[chanListIndex] = chan;
+    return chan;
+}
+
+int getChannelCount() {
+    int i, count = 0;
+    struct ChanNode *chan;
+    for(i = 0; i < CHANNEL_LIST_SIZE; i++) {
+        for(chan = chanList[i]; chan; chan = chan->next) {
+            count++;
+        }
+    }
+    return count;
+}
+
+int getChanUserCount() {
+    int i, count = 0;
+    struct ChanNode *chan;
+    for(i = 0; i < CHANNEL_LIST_SIZE; i++) {
+        for(chan = chanList[i]; chan; chan = chan->next) {
+            count += chan->usercount;
+        }
+    }
+    return count;
+}
+
+int getChanBanCount() {
+    int i, count = 0;
+    struct ChanNode *chan;
+    struct BanNode *ban;
+    for(i = 0; i < CHANNEL_LIST_SIZE; i++) {
+        for(chan = chanList[i]; chan; chan = chan->next) {
+            for(ban = chan->bans; ban; ban = ban->next)
+                count ++;
+        }
+    }
+    return count;
 }
 
 void delChannel(struct ChanNode* chan, int freeChan) {
-    //to be continued
+    int chanListIndex = get_chanlist_entry(chan->name[1]);
+    if(chanListIndex == -1) return;
+    struct ChanNode *cchan, *last_chan = NULL;
+    for(cchan = chanList[chanListIndex]; cchan; cchan = cchan->next) {
+        if(cchan == chan) {
+            if(last_chan)
+                last_chan->next = chan->next;
+            else
+                chanList[chanListIndex] = chan->next;
+            break;
+        } else
+            last_chan = cchan;
+    }
+    if(chan->user) {
+        //free all chanusers
+        struct ChanUser *chanuser, *next;
+        for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = next) {
+            next = getChannelUsers(chan, chanuser);
+            removeChanUserFromLists(chanuser, 0, 1, 1);
+        }
+    }
+    if(freeChan)
+        freeChanNode(chan);
+    else
+        chan->next = NULL;
+}
+
+void freeChanNode(struct ChanNode* chan) {
+    if(chan->trigger) {
+        struct trigger_cache *trigger, *next_trigger;
+        for(trigger = chan->trigger; trigger; trigger = next_trigger) {
+            next_trigger = trigger->next;
+            free(trigger->trigger);
+            free(trigger);
+        }
+    }
+    freeModeNode(chan->modes);
+    if(chan->bans)
+        removeChannelBans(chan);
+    free(chan);
+}
+
+void checkChannelVisibility(struct ChanNode* chan) {
+    struct ChanUser *chanuser, *next;
+    for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = getChannelUsers(chan, chanuser)) {
+        if(chanuser->user->flags & USERFLAG_ISBOT) {
+            chan->chanbot = chanuser->user;
+            return;
+        }
+    }
+    //free the channel...
+    for(chanuser = getChannelUsers(chan, NULL); chanuser; chanuser = next) {
+        next = getChannelUsers(chan, chanuser);
+        //remove the channel from the user's channel-list
+        removeChanUserFromLists(chanuser, 0, 1, 0);
+        if(!chanuser->user->channel) {
+            //free the user (no more channels)
+            delUser(chanuser->user, 1);
+        }
+        free(chanuser);
+    }
+    chan->user = NULL;
+    delChannel(chan, 1);
 }