added .gitignore
[NeonServV5.git] / ChanNode.c
index 93f4266c4e754e68ad6f60ceb9aed0a8002d7ecb..47e06635179c723ebd9a4f137f1e7924b0061f67 100644 (file)
@@ -1,6 +1,7 @@
 #include "ChanNode.h"
 #include "ChanUser.h"
 #include "UserNode.h"
+#include "modcmd.h"
 
 static struct ChanNode **chanList;
 static int modes_with_strarg, modes_with_intarg;
@@ -76,6 +77,24 @@ void init_ChanNode() {
     }
 }
 
+void free_ChanNode() {
+    //kamikaze free all channels and chanusers
+    int i;
+    struct ChanNode *chan, *next;
+    struct ChanUser *chanuser, *next_chanuser;
+    for(i = 0; i < 47; 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) {
     unsigned int ii;
     if (*name !='#')
@@ -142,6 +161,7 @@ struct ChanNode* addChannel(const char *name) {
     chan->flags = 0;
     /* mode lists */
     chan->modes = 0;
+    chan->trigger = NULL;
     chan->mode_str_args = calloc(modes_with_strarg, sizeof(char*));
     chan->mode_int_args = calloc(modes_with_intarg, sizeof(int));
     
@@ -184,6 +204,14 @@ void freeChanNode(struct ChanNode* chan) {
         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;
+            free(trigger->trigger);
+            free(trigger);
+        }
+    }
     free(chan->mode_str_args);
     free(chan->mode_int_args);
     free(chan);
@@ -237,6 +265,21 @@ void* getModeValue(struct ChanNode* chan, char modeChar) {
     #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)
@@ -255,7 +298,23 @@ void parseModes(struct ChanNode* chan, char *modeStr, char **argv, int argc) {
         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[argpos]);
+                    break;
+                case 'v':
+                    parseModesUserPriv(chan, CHANUSERFLAG_VOICED, add, argv[argpos]);
+                    break;
+                case 'b':
+                    parseModesBan(chan, add, argv[argpos]);
+                    break;
+                default:
+                    //we have an unknown TYPE_A mode???
+                    break;
+            }
+            argpos++;
             continue;
         }
         if(add) {
@@ -264,11 +323,11 @@ void parseModes(struct ChanNode* chan, char *modeStr, char **argv, int argc) {
                 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++]);
+                    chan->mode_str_args[MODE_VALUE_INDEX] = strdup(argv[argpos++]);
                 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
-                    chan->mode_int_args[MODE_VALUE_INDEX] = atoi(argv[argc++]);
+                    chan->mode_int_args[MODE_VALUE_INDEX] = atoi(argv[argpos++]);
                 else
-                    argc++; //we simply don't know what to do with the argument...
+                    argpos++; //we simply don't know what to do with the argument...
             }
             chan->modes |= modeOpt[0];
         } else {
@@ -280,7 +339,7 @@ void parseModes(struct ChanNode* chan, char *modeStr, char **argv, int argc) {
                     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...
+                argpos++; //we don't need the argument when unsetting a mode...
             }
         }
     }
@@ -289,4 +348,30 @@ void parseModes(struct ChanNode* chan, char *modeStr, char **argv, int argc) {
     #undef MODE_VALUE_INDEX
 }
 
+void getModeString(struct ChanNode* chan, char *modesStr) {
+    #define MODE_TYPE (mode[2] & CHANNEL_MODE_TYPE)
+    #define MODE_VALUE (mode[2] & CHANNEL_MODE_VALUE)
+    #define MODE_VALUE_INDEX (mode[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
+    char paramStr[MAXLEN];
+    modesStr[0] = '+';
+    unsigned int *mode;
+    int modePos = 1;
+    int paramPos = 0;
+    for (mode = valid_modes; mode[1]; mode += 3) {
+        if(chan->modes & mode[0]) {
+            modesStr[modePos++] = (char) mode[1];
+            if(MODE_TYPE != CHANNEL_MODE_TYPE_D) {
+                if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING)
+                    paramPos += sprintf(paramStr + paramPos, " %s", chan->mode_str_args[MODE_VALUE_INDEX]);
+                else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
+                    paramPos += sprintf(paramStr + paramPos, " %d", chan->mode_int_args[MODE_VALUE_INDEX]);
+            }
+        }
+    }
+    paramStr[paramPos] = '\0';
+    strcpy(modesStr + modePos, paramStr);
+    #undef MODE_TYPE
+    #undef MODE_VALUE
+    #undef MODE_VALUE_INDEX
+}