+++ /dev/null
-#include "ModeNode.h"
-#include "ChanNode.h"
-#include "ChanUser.h"
-#include "UserNode.h"
-#include "BanNode.h"
-
-static int modes_with_strarg, modes_with_intarg, modes_count;
-
-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 | CHANNEL_MODE_KEY,
- 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_ModeNode() {
- unsigned int *mode, flag = 1;
- modes_with_strarg = 0;
- modes_with_intarg = 0;
- modes_count = 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++;
- }
- modes_count++;
- mode[0] = flag;
- flag = flag << 1;
- }
-}
-
-struct ModeNode *createModeNode(struct ChanNode *chan) {
- struct ModeNode *modes = malloc(sizeof(*modes));
- if (!modes)
- {
- perror("malloc() failed");
- return NULL;
- }
- modes->chan = chan;
- modes->modes = 0;
- modes->allmodes = 0;
- modes->mode_str_args = calloc(modes_with_strarg, sizeof(char*));
- modes->mode_int_args = calloc(modes_with_intarg, sizeof(int));
- return modes;
-}
-
-void freeModeNode(struct ModeNode *modes) {
- int i;
- for(i = 0; i < modes_with_strarg; i++) {
- if(modes->mode_str_args[i])
- free(modes->mode_str_args[i]);
- }
- free(modes->mode_str_args);
- free(modes->mode_int_args);
- free(modes);
-}
-
-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 ModeNode* modes, char modeChar) {
- unsigned int *modeOpt = getModeOptions(modeChar);
- return (modes->modes & modeOpt[0]);
-}
-
-int isModeAffected(struct ModeNode* modes, char modeChar) {
- unsigned int *modeOpt = getModeOptions(modeChar);
- return (modes->allmodes & modeOpt[0]);
-}
-
-void* getModeValue(struct ModeNode* modes, 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 modes->mode_str_args[MODE_VALUE_INDEX];
- if((modeOpt[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_INTEGER)
- return &modes->mode_int_args[MODE_VALUE_INDEX];
- return NULL;
- #undef MODE_VALUE_INDEX
-}
-
-unsigned int getModeType(struct ModeNode* modes, 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) return 0;
- return modeOpt[2];
- #undef MODE_VALUE_INDEX
-}
-
-static void parseModesUserPriv(struct ModeNode* modes, unsigned char flag, int add, char *nick) {
- if(modes->chan == NULL) return;
- struct UserNode *user = getUserByNick(nick);
- if(user == NULL) return;
- struct ChanUser *chanuser = getChanUser(user, modes->chan);
- if(chanuser == NULL) return;
- if(add)
- chanuser->flags |= flag;
- else
- chanuser->flags &= ~flag;
-}
-
-static void parseModesBan(struct ModeNode* modes, int add, char *mask) {
- if(modes->chan == NULL) return;
- if(add)
- addChannelBan(modes->chan, mask);
- else
- removeChannelBanMask(modes->chan, mask);
-}
-
-void parseModes(struct ModeNode* modes, 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(modes, CHANUSERFLAG_OPPED, add, argv[argpos]);
- break;
- case 'v':
- parseModesUserPriv(modes, CHANUSERFLAG_VOICED, add, argv[argpos]);
- break;
- case 'b':
- parseModesBan(modes, 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(modes->mode_str_args[MODE_VALUE_INDEX])
- free(modes->mode_str_args[MODE_VALUE_INDEX]);
- modes->mode_str_args[MODE_VALUE_INDEX] = strdup(argv[argpos++]);
- } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
- modes->mode_int_args[MODE_VALUE_INDEX] = atoi(argv[argpos++]);
- else
- argpos++; //we simply don't know what to do with the argument...
- }
- modes->modes |= modeOpt[0];
- modes->allmodes |= modeOpt[0];
- } else {
- modes->modes &= ~modeOpt[0];
- modes->allmodes |= modeOpt[0];
- if(MODE_TYPE == CHANNEL_MODE_TYPE_B) {
- if(argpos == argc) continue;
- if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
- free(modes->mode_str_args[MODE_VALUE_INDEX]);
- modes->mode_str_args[MODE_VALUE_INDEX] = NULL;
- } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
- modes->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 parseModeString(struct ModeNode* modes, char *modeStr) {
- int argc = 0;
- char *args[modes_count+1];
- char *a, *b = modeStr;
- do {
- a = strstr(b, " ");
- if(a) *a = '\0';
- args[argc++] = b;
- if(a) b = a+1;
- } while(a);
- parseModes(modes, args[0], args+1, argc-1);
-}
-
-int parseMode(struct ModeNode* modes, int add, char mode, char *param) {
- #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 = getModeOptions(mode);
- if(!modeOpt) return 0;
- if(MODE_TYPE == CHANNEL_MODE_TYPE_A) {
- if(!param) return 0;
- //special mode ;)
- switch(mode) {
- case 'o':
- parseModesUserPriv(modes, CHANUSERFLAG_OPPED, add, param);
- break;
- case 'v':
- parseModesUserPriv(modes, CHANUSERFLAG_VOICED, add, param);
- break;
- case 'b':
- parseModesBan(modes, add, param);
- break;
- default:
- return 0; //we have an unknown TYPE_A mode???
- }
- }
- if(add) {
- if(MODE_TYPE != CHANNEL_MODE_TYPE_D) { //all other types take parameters when set
- if(!param) return 0;
- if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
- if(modes->mode_str_args[MODE_VALUE_INDEX])
- free(modes->mode_str_args[MODE_VALUE_INDEX]);
- modes->mode_str_args[MODE_VALUE_INDEX] = strdup(param);
- } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
- modes->mode_int_args[MODE_VALUE_INDEX] = atoi(param);
- }
- modes->modes |= modeOpt[0];
- modes->allmodes |= modeOpt[0];
- } else {
- modes->modes &= ~modeOpt[0];
- modes->allmodes |= modeOpt[0];
- if(MODE_TYPE == CHANNEL_MODE_TYPE_B) {
- if(!param) return 0;
- if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
- free(modes->mode_str_args[MODE_VALUE_INDEX]);
- modes->mode_str_args[MODE_VALUE_INDEX] = NULL;
- } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
- modes->mode_int_args[MODE_VALUE_INDEX] = 0;
- }
- }
- #undef MODE_TYPE
- #undef MODE_VALUE
- #undef MODE_VALUE_INDEX
- return 1;
-}
-
-void getModeString(struct ModeNode* modes, 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(modes->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", modes->mode_str_args[MODE_VALUE_INDEX]);
- else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
- paramPos += sprintf(paramStr + paramPos, " %d", modes->mode_int_args[MODE_VALUE_INDEX]);
- }
- }
- }
- paramStr[paramPos] = '\0';
- strcpy(modesStr + modePos, paramStr);
- #undef MODE_TYPE
- #undef MODE_VALUE
- #undef MODE_VALUE_INDEX
-}
-
-void getFullModeString(struct ModeNode* modes, 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 addMode[modes_count+1];
- int addModePos = 0;
- char addParams[MAXLEN];
- addParams[0] = '\0';
- int addParamsPos = 0;
- char delMode[modes_count+1];
- int delModePos = 0;
- unsigned int *mode;
- for (mode = valid_modes; mode[1]; mode += 3) {
- if(modes->allmodes & mode[0]) {
- if(modes->modes & mode[0]) {
- addMode[addModePos++] = (char) mode[1];
- if(MODE_TYPE != CHANNEL_MODE_TYPE_D) {
- if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING)
- addParamsPos += sprintf(addParams + addParamsPos, " %s", modes->mode_str_args[MODE_VALUE_INDEX]);
- else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
- addParamsPos += sprintf(addParams + addParamsPos, " %d", modes->mode_int_args[MODE_VALUE_INDEX]);
- }
- } else {
- delMode[delModePos++] = (char) mode[1];
- }
- }
- }
- addMode[addModePos] = '\0';
- delMode[delModePos] = '\0';
- addParams[addParamsPos] = '\0';
- sprintf(modesStr, "%s%s%s%s%s", (addModePos ? "+" : ""), addMode, (delModePos ? "-" : ""), delMode, addParams);
- if(*modesStr == '\0') {
- sprintf(modesStr, "+");
- }
- #undef MODE_TYPE
- #undef MODE_VALUE
- #undef MODE_VALUE_INDEX
-}