changed Makefile; build all commands as an own file
[NeonServV5.git] / ChanNode.c
index 5bca72ea2bf361cf9ca57ae8ecae8b248e63d5e2..73adbf6b3881ee6d17c505cb6eb48101a49c3519 100644 (file)
@@ -1,52 +1,11 @@
 #include "ChanNode.h"
 #include "ChanUser.h"
 #include "UserNode.h"
+#include "BanNode.h"
+#include "modcmd.h"
+#include "ModeNode.h"
 
 static struct ChanNode **chanList;
-static int modes_with_strarg, modes_with_intarg;
-
-//Types: http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt
-#define CHANNEL_MODE_TYPE_A        0x01 /* ... special (addresses or users) ... */
-#define CHANNEL_MODE_TYPE_B        0x02 /* These modes always take a parameter. */
-#define CHANNEL_MODE_TYPE_C        0x03 /* These modes take a parameter only when set. */
-#define CHANNEL_MODE_TYPE_D        0x04 /* These modes never take a parameter. */
-#define CHANNEL_MODE_TYPE          0x07 /* bit mask to get the type */
-
-#define CHANNEL_MODE_VALUE_STRING  0x10
-#define CHANNEL_MODE_VALUE_INTEGER 0x20
-#define CHANNEL_MODE_VALUE         0x30 /* bit mask to get the value */
-
-#define CHANNEL_MODE_VALUE_INDEX_SHIFT 8
-#define CHANNEL_MODE_VALUE_INDEX_MASK  (0xff << CHANNEL_MODE_VALUE_INDEX_SHIFT) /* this "bitrange" is reserved for storing the array indexes of the mode values */
-
-static unsigned int valid_modes[] = { /* Thats our mode list :P */
-    1,  'b', CHANNEL_MODE_TYPE_A,
-    2,  'o', CHANNEL_MODE_TYPE_A,
-    3,  'v', CHANNEL_MODE_TYPE_A,
-    4,  'k', CHANNEL_MODE_TYPE_B | CHANNEL_MODE_VALUE_STRING,
-    5,  'a', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_INTEGER,
-    6,  'l', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_INTEGER,
-    7,  'f', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_STRING,
-    8,  'F', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_STRING,
-    9,  'c', CHANNEL_MODE_TYPE_D,
-    10, 'C', CHANNEL_MODE_TYPE_D,
-    11, 'i', CHANNEL_MODE_TYPE_D,
-    12, 'm', CHANNEL_MODE_TYPE_D,
-    13, 'M', CHANNEL_MODE_TYPE_D,
-    14, 'n', CHANNEL_MODE_TYPE_D,
-    15, 'N', CHANNEL_MODE_TYPE_D,
-    16, 'p', CHANNEL_MODE_TYPE_D,
-    17, 'r', CHANNEL_MODE_TYPE_D,
-    18, 's', CHANNEL_MODE_TYPE_D,
-    19, 't', CHANNEL_MODE_TYPE_D,
-    20, 'u', CHANNEL_MODE_TYPE_D,
-    21, 'D', CHANNEL_MODE_TYPE_D,
-    22, 'd', CHANNEL_MODE_TYPE_D,
-    23, 'R', CHANNEL_MODE_TYPE_D,
-    24, 'z', CHANNEL_MODE_TYPE_D,
-//  ^ maximum is 32!!!
-    0x00, 0x00, 0x00
-};
 
 void init_ChanNode() {
     /*
@@ -58,22 +17,26 @@ void init_ChanNode() {
      ---------------------------
      = 47
     */
-    chanList = calloc(47, sizeof(*chanList));
-    unsigned int *mode, flag = 1;
-    modes_with_strarg = 0;
-    modes_with_intarg = 0;
-    for (mode = valid_modes; mode[1]; mode += 3) {
-        if((mode[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING) {
-            mode[2] |= modes_with_strarg << CHANNEL_MODE_VALUE_INDEX_SHIFT;
-            modes_with_strarg++;
-        }
-        if((mode[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_INTEGER) {
-            mode[2] |= modes_with_intarg << CHANNEL_MODE_VALUE_INDEX_SHIFT;
-            modes_with_intarg++;
+    #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);
         }
-        mode[0] = flag;
-        flag = flag << 1;
     }
+    free(chanList);
 }
 
 int is_valid_chan(const char *name) {
@@ -137,19 +100,55 @@ struct ChanNode* addChannel(const char *name) {
     }
     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 = 0;
-    chan->mode_str_args = calloc(modes_with_strarg, sizeof(char*));
-    chan->mode_int_args = calloc(modes_with_intarg, sizeof(int));
+    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) {
     int chanListIndex = get_chanlist_entry(chan->name[1]);
     if(chanListIndex == -1) return;
@@ -179,13 +178,17 @@ void delChannel(struct ChanNode* chan, int freeChan) {
 }
 
 void freeChanNode(struct ChanNode* chan) {
-    int i;
-    for(i = 0; i < modes_with_strarg; i++) {
-        if(chan->mode_str_args[i])
-            free(chan->mode_str_args[i]);
+    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);
+        }
     }
-    free(chan->mode_str_args);
-    free(chan->mode_int_args);
+    freeModeNode(chan->modes);
+    if(chan->bans)
+        removeChannelBans(chan);
     free(chan);
 }
 
@@ -211,113 +214,3 @@ void checkChannelVisibility(struct ChanNode* chan) {
     chan->user = NULL;
     delChannel(chan, 1);
 }
-
-static unsigned int* getModeOptions(char mode) {
-    unsigned int *cmode;
-    for (cmode = valid_modes; cmode[1]; cmode += 3) {
-        if(cmode[1] == mode)
-            return cmode;
-    }
-    return NULL;
-}
-
-int isModeSet(struct ChanNode* chan, char modeChar) {
-    unsigned int *modeOpt = getModeOptions(modeChar);
-    return (chan->modes & modeOpt[0]);
-}
-
-void* getModeValue(struct ChanNode* chan, char modeChar) {
-    #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
-    unsigned int *modeOpt = getModeOptions(modeChar);
-    if((modeOpt[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING)
-        return chan->mode_str_args[MODE_VALUE_INDEX];
-    if((modeOpt[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_INTEGER)
-        return &chan->mode_int_args[MODE_VALUE_INDEX];
-    return NULL;
-    #undef MODE_VALUE_INDEX
-}
-
-static void parseModesUserPriv(struct ChanNode* chan, unsigned char flag, int add, char *nick) {
-    struct UserNode *user = getUserByNick(nick);
-    if(user == NULL) return;
-    struct ChanUser *chanuser = getChanUser(user, chan);
-    if(chanuser == NULL) return;
-    if(add)
-        chanuser->flags |= flag;
-    else
-        chanuser->flags &= ~flag;
-}
-
-static void parseModesBan(struct ChanNode* chan, int add, char *mask) {
-    //to be continued...
-}
-
-void parseModes(struct ChanNode* chan, char *modeStr, char **argv, int argc) {
-    int i, argpos = 0, add = 1;
-    #define MODE_TYPE (modeOpt[2] & CHANNEL_MODE_TYPE)
-    #define MODE_VALUE (modeOpt[2] & CHANNEL_MODE_VALUE)
-    #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
-    unsigned int *modeOpt;
-    for(i = 0; i < strlen(modeStr); i++) {
-        if(modeStr[i] == '+') {
-            add = 1;
-            continue;
-        }
-        if(modeStr[i] == '-') {
-            add = 0;
-            continue;
-        }
-        modeOpt = getModeOptions(modeStr[i]);
-        if(!modeOpt) continue; // unknown mode?
-        if(MODE_TYPE == CHANNEL_MODE_TYPE_A) {
-            if(argpos == argc) continue;
-            //special mode ;)
-            switch(modeStr[i]) {
-                case 'o':
-                    parseModesUserPriv(chan, CHANUSERFLAG_OPPED, add, argv[argc]);
-                    break;
-                case 'v':
-                    parseModesUserPriv(chan, CHANUSERFLAG_VOICED, add, argv[argc]);
-                    break;
-                case 'b':
-                    parseModesBan(chan, add, argv[argc]);
-                    break;
-                default:
-                    //we have an unknown TYPE_A mode???
-                    break;
-            }
-            argc++;
-            continue;
-        }
-        if(add) {
-            if(MODE_TYPE != CHANNEL_MODE_TYPE_D) { //all other types take parameters when set
-                if(argpos == argc) continue;
-                if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
-                    if(chan->mode_str_args[MODE_VALUE_INDEX])
-                        free(chan->mode_str_args[MODE_VALUE_INDEX]);
-                    chan->mode_str_args[MODE_VALUE_INDEX] = strdup(argv[argc++]);
-                } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
-                    chan->mode_int_args[MODE_VALUE_INDEX] = atoi(argv[argc++]);
-                else
-                    argc++; //we simply don't know what to do with the argument...
-            }
-            chan->modes |= modeOpt[0];
-        } else {
-            chan->modes &= ~modeOpt[0];
-            if(MODE_TYPE == CHANNEL_MODE_TYPE_B) {
-                if(argpos == argc) continue;
-                if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
-                    free(chan->mode_str_args[MODE_VALUE_INDEX]);
-                    chan->mode_str_args[MODE_VALUE_INDEX] = NULL;
-                } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
-                    chan->mode_int_args[MODE_VALUE_INDEX] = 0;
-                argc++; //we don't need the argument when unsetting a mode...
-            }
-        }
-    }
-    #undef MODE_TYPE
-    #undef MODE_VALUE
-    #undef MODE_VALUE_INDEX
-}
-
-