#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() {
/*
---------------------------
= 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) {
}
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;
}
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);
}
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
-}
-
-