7 static int modes_with_strarg, modes_with_intarg, modes_count;
9 unsigned int valid_modes[] = { /* Thats our mode list :P */
10 1, 'b', CHANNEL_MODE_TYPE_A,
11 2, 'o', CHANNEL_MODE_TYPE_A,
12 3, 'v', CHANNEL_MODE_TYPE_A,
13 4, 'k', CHANNEL_MODE_TYPE_B | CHANNEL_MODE_VALUE_STRING | CHANNEL_MODE_KEY,
14 5, 'a', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_INTEGER,
15 6, 'l', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_INTEGER,
16 7, 'f', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_STRING,
17 8, 'F', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_STRING,
18 9, 'c', CHANNEL_MODE_TYPE_D,
19 10, 'C', CHANNEL_MODE_TYPE_D,
20 11, 'i', CHANNEL_MODE_TYPE_D,
21 12, 'm', CHANNEL_MODE_TYPE_D,
22 13, 'M', CHANNEL_MODE_TYPE_D,
23 14, 'n', CHANNEL_MODE_TYPE_D,
24 15, 'N', CHANNEL_MODE_TYPE_D,
25 16, 'p', CHANNEL_MODE_TYPE_D,
26 17, 'r', CHANNEL_MODE_TYPE_D,
27 18, 's', CHANNEL_MODE_TYPE_D,
28 19, 't', CHANNEL_MODE_TYPE_D,
29 20, 'u', CHANNEL_MODE_TYPE_D,
30 21, 'D', CHANNEL_MODE_TYPE_D,
31 22, 'd', CHANNEL_MODE_TYPE_D,
32 23, 'R', CHANNEL_MODE_TYPE_D,
33 24, 'z', CHANNEL_MODE_TYPE_D,
38 void init_ModeNode() {
39 unsigned int *mode, flag = 1;
40 modes_with_strarg = 0;
41 modes_with_intarg = 0;
43 for (mode = valid_modes; mode[1]; mode += 3) {
44 if((mode[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING) {
45 mode[2] |= modes_with_strarg << CHANNEL_MODE_VALUE_INDEX_SHIFT;
48 if((mode[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_INTEGER) {
49 mode[2] |= modes_with_intarg << CHANNEL_MODE_VALUE_INDEX_SHIFT;
58 struct ModeNode *createModeNode(struct ChanNode *chan) {
59 struct ModeNode *modes = malloc(sizeof(*modes));
62 perror("malloc() failed");
68 modes->mode_str_args = calloc(modes_with_strarg, sizeof(char*));
69 modes->mode_int_args = calloc(modes_with_intarg, sizeof(int));
73 void freeModeNode(struct ModeNode *modes) {
75 for(i = 0; i < modes_with_strarg; i++) {
76 if(modes->mode_str_args[i])
77 free(modes->mode_str_args[i]);
79 free(modes->mode_str_args);
80 free(modes->mode_int_args);
84 static unsigned int* getModeOptions(char mode) {
86 for (cmode = valid_modes; cmode[1]; cmode += 3) {
93 int isModeSet(struct ModeNode* modes, char modeChar) {
94 unsigned int *modeOpt = getModeOptions(modeChar);
95 return (modes->modes & modeOpt[0]);
98 int isModeAffected(struct ModeNode* modes, char modeChar) {
99 unsigned int *modeOpt = getModeOptions(modeChar);
100 return (modes->allmodes & modeOpt[0]);
103 void* getModeValue(struct ModeNode* modes, char modeChar) {
104 #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
105 unsigned int *modeOpt = getModeOptions(modeChar);
106 if((modeOpt[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING)
107 return modes->mode_str_args[MODE_VALUE_INDEX];
108 if((modeOpt[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_INTEGER)
109 return &modes->mode_int_args[MODE_VALUE_INDEX];
111 #undef MODE_VALUE_INDEX
114 unsigned int getModeType(struct ModeNode* modes, char modeChar) {
115 #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
116 unsigned int *modeOpt = getModeOptions(modeChar);
117 if(!modeOpt) return 0;
119 #undef MODE_VALUE_INDEX
122 static void parseModesUserPriv(struct ModeNode* modes, unsigned char flag, int add, char *nick) {
123 if(modes->chan == NULL) return;
124 struct UserNode *user = getUserByNick(nick);
125 if(user == NULL) return;
126 struct ChanUser *chanuser = getChanUser(user, modes->chan);
127 if(chanuser == NULL) return;
129 chanuser->flags |= flag;
131 chanuser->flags &= ~flag;
134 static void parseModesBan(struct ModeNode* modes, int add, char *mask) {
135 if(modes->chan == NULL) return;
137 addChannelBan(modes->chan, mask);
139 removeChannelBanMask(modes->chan, mask);
142 void parseModes(struct ModeNode* modes, char *modeStr, char **argv, int argc) {
143 int i, argpos = 0, add = 1;
144 #define MODE_TYPE (modeOpt[2] & CHANNEL_MODE_TYPE)
145 #define MODE_VALUE (modeOpt[2] & CHANNEL_MODE_VALUE)
146 #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
147 unsigned int *modeOpt;
148 for(i = 0; i < strlen(modeStr); i++) {
149 if(modeStr[i] == '+') {
153 if(modeStr[i] == '-') {
157 modeOpt = getModeOptions(modeStr[i]);
158 if(!modeOpt) continue; // unknown mode?
159 if(MODE_TYPE == CHANNEL_MODE_TYPE_A) {
160 if(argpos == argc) continue;
164 parseModesUserPriv(modes, CHANUSERFLAG_OPPED, add, argv[argpos]);
167 parseModesUserPriv(modes, CHANUSERFLAG_VOICED, add, argv[argpos]);
170 parseModesBan(modes, add, argv[argpos]);
173 //we have an unknown TYPE_A mode???
180 if(MODE_TYPE != CHANNEL_MODE_TYPE_D) { //all other types take parameters when set
181 if(argpos == argc) continue;
182 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
183 if(modes->mode_str_args[MODE_VALUE_INDEX])
184 free(modes->mode_str_args[MODE_VALUE_INDEX]);
185 modes->mode_str_args[MODE_VALUE_INDEX] = strdup(argv[argpos++]);
186 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
187 modes->mode_int_args[MODE_VALUE_INDEX] = atoi(argv[argpos++]);
189 argpos++; //we simply don't know what to do with the argument...
191 modes->modes |= modeOpt[0];
192 modes->allmodes |= modeOpt[0];
194 modes->modes &= ~modeOpt[0];
195 modes->allmodes |= modeOpt[0];
196 if(MODE_TYPE == CHANNEL_MODE_TYPE_B) {
197 if(argpos == argc) continue;
198 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
199 free(modes->mode_str_args[MODE_VALUE_INDEX]);
200 modes->mode_str_args[MODE_VALUE_INDEX] = NULL;
201 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
202 modes->mode_int_args[MODE_VALUE_INDEX] = 0;
203 argpos++; //we don't need the argument when unsetting a mode...
209 #undef MODE_VALUE_INDEX
212 void parseModeString(struct ModeNode* modes, char *modeStr) {
214 char *args[modes_count+1];
215 char *a, *b = modeStr;
222 parseModes(modes, args[0], args+1, argc-1);
225 int parseMode(struct ModeNode* modes, int add, char mode, char *param) {
226 #define MODE_TYPE (modeOpt[2] & CHANNEL_MODE_TYPE)
227 #define MODE_VALUE (modeOpt[2] & CHANNEL_MODE_VALUE)
228 #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
229 unsigned int *modeOpt = getModeOptions(mode);
230 if(!modeOpt) return 0;
231 if(MODE_TYPE == CHANNEL_MODE_TYPE_A) {
236 parseModesUserPriv(modes, CHANUSERFLAG_OPPED, add, param);
239 parseModesUserPriv(modes, CHANUSERFLAG_VOICED, add, param);
242 parseModesBan(modes, add, param);
245 return 0; //we have an unknown TYPE_A mode???
249 if(MODE_TYPE != CHANNEL_MODE_TYPE_D) { //all other types take parameters when set
251 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
252 if(modes->mode_str_args[MODE_VALUE_INDEX])
253 free(modes->mode_str_args[MODE_VALUE_INDEX]);
254 modes->mode_str_args[MODE_VALUE_INDEX] = strdup(param);
255 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
256 modes->mode_int_args[MODE_VALUE_INDEX] = atoi(param);
258 modes->modes |= modeOpt[0];
259 modes->allmodes |= modeOpt[0];
261 modes->modes &= ~modeOpt[0];
262 modes->allmodes |= modeOpt[0];
263 if(MODE_TYPE == CHANNEL_MODE_TYPE_B) {
265 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
266 free(modes->mode_str_args[MODE_VALUE_INDEX]);
267 modes->mode_str_args[MODE_VALUE_INDEX] = NULL;
268 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
269 modes->mode_int_args[MODE_VALUE_INDEX] = 0;
274 #undef MODE_VALUE_INDEX
278 void getModeString(struct ModeNode* modes, char *modesStr) {
279 #define MODE_TYPE (mode[2] & CHANNEL_MODE_TYPE)
280 #define MODE_VALUE (mode[2] & CHANNEL_MODE_VALUE)
281 #define MODE_VALUE_INDEX (mode[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
282 char paramStr[MAXLEN];
287 for (mode = valid_modes; mode[1]; mode += 3) {
288 if(modes->modes & mode[0]) {
289 modesStr[modePos++] = (char) mode[1];
290 if(MODE_TYPE != CHANNEL_MODE_TYPE_D) {
291 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING)
292 paramPos += sprintf(paramStr + paramPos, " %s", modes->mode_str_args[MODE_VALUE_INDEX]);
293 else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
294 paramPos += sprintf(paramStr + paramPos, " %d", modes->mode_int_args[MODE_VALUE_INDEX]);
298 paramStr[paramPos] = '\0';
299 strcpy(modesStr + modePos, paramStr);
302 #undef MODE_VALUE_INDEX
305 void getFullModeString(struct ModeNode* modes, char *modesStr) {
306 #define MODE_TYPE (mode[2] & CHANNEL_MODE_TYPE)
307 #define MODE_VALUE (mode[2] & CHANNEL_MODE_VALUE)
308 #define MODE_VALUE_INDEX (mode[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
309 char addMode[modes_count+1];
311 char addParams[MAXLEN];
313 int addParamsPos = 0;
314 char delMode[modes_count+1];
317 for (mode = valid_modes; mode[1]; mode += 3) {
318 if(modes->allmodes & mode[0]) {
319 if(modes->modes & mode[0]) {
320 addMode[addModePos++] = (char) mode[1];
321 if(MODE_TYPE != CHANNEL_MODE_TYPE_D) {
322 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING)
323 addParamsPos += sprintf(addParams + addParamsPos, " %s", modes->mode_str_args[MODE_VALUE_INDEX]);
324 else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
325 addParamsPos += sprintf(addParams + addParamsPos, " %d", modes->mode_int_args[MODE_VALUE_INDEX]);
328 delMode[delModePos++] = (char) mode[1];
332 addMode[addModePos] = '\0';
333 delMode[delModePos] = '\0';
334 addParams[addParamsPos] = '\0';
335 sprintf(modesStr, "%s%s%s%s%s", (addModePos ? "+" : ""), addMode, (delModePos ? "-" : ""), delMode, addParams);
336 if(*modesStr == '\0') {
337 sprintf(modesStr, "+");
341 #undef MODE_VALUE_INDEX