X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ChanNode.c;h=73adbf6b3881ee6d17c505cb6eb48101a49c3519;hb=795115bf680185ae01043bd1222b78bfed8c1d87;hp=898169b32494866d913b04942519cc456d9ad1aa;hpb=1b20a2f385dd76d592fabb3eb0e1331b521ecaa5;p=NeonServV5.git diff --git a/ChanNode.c b/ChanNode.c index 898169b..73adbf6 100644 --- a/ChanNode.c +++ b/ChanNode.c @@ -3,52 +3,9 @@ #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() { /* @@ -62,21 +19,6 @@ void init_ChanNode() { */ #define CHANNEL_LIST_SIZE 47 chanList = calloc(CHANNEL_LIST_SIZE, 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++; - } - mode[0] = flag; - flag = flag << 1; - } } void free_ChanNode() { @@ -164,10 +106,8 @@ struct ChanNode* addChannel(const char *name) { chan->topic[0] = 0; chan->flags = 0; /* mode lists */ - chan->modes = 0; + chan->modes = createModeNode(chan); chan->trigger = NULL; - chan->mode_str_args = calloc(modes_with_strarg, sizeof(char*)); - chan->mode_int_args = calloc(modes_with_intarg, sizeof(int)); chan->next = chanList[chanListIndex]; chanList[chanListIndex] = chan; @@ -238,21 +178,15 @@ 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_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); @@ -280,141 +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) { - if(add) - addChannelBan(chan, mask); - else - removeChannelBanMask(chan, mask); -} - -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[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) { - 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[argpos++]); - } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER) - chan->mode_int_args[MODE_VALUE_INDEX] = atoi(argv[argpos++]); - else - argpos++; //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; - argpos++; //we don't need the argument when unsetting a mode... - } - } - } - #undef MODE_TYPE - #undef MODE_VALUE - #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 -}