1 /* ModeNode.c - NeonServ v5.3
2 * Copyright (C) 2011-2012 Philipp Kreil (pk910)
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 static int modes_with_strarg, modes_with_intarg, modes_count;
25 unsigned int valid_modes[] = { /* Thats our mode list :P */
26 1, 'b', CHANNEL_MODE_TYPE_A,
27 2, 'o', CHANNEL_MODE_TYPE_A,
28 3, 'h', CHANNEL_MODE_TYPE_A,
29 4, 'v', CHANNEL_MODE_TYPE_A,
30 5, 'k', CHANNEL_MODE_TYPE_B | CHANNEL_MODE_VALUE_STRING | CHANNEL_MODE_KEY,
31 6, 'a', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_INTEGER,
32 7, 'l', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_INTEGER,
33 8, 'f', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_STRING,
34 9, 'F', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_STRING,
35 10, 'c', CHANNEL_MODE_TYPE_D,
36 11, 'C', CHANNEL_MODE_TYPE_D,
37 12, 'i', CHANNEL_MODE_TYPE_D,
38 13, 'm', CHANNEL_MODE_TYPE_D,
39 14, 'M', CHANNEL_MODE_TYPE_D,
40 15, 'n', CHANNEL_MODE_TYPE_D,
41 16, 'N', CHANNEL_MODE_TYPE_D,
42 17, 'p', CHANNEL_MODE_TYPE_D,
43 18, 'r', CHANNEL_MODE_TYPE_D,
44 19, 's', CHANNEL_MODE_TYPE_D,
45 20, 'S', CHANNEL_MODE_TYPE_D,
46 21, 't', CHANNEL_MODE_TYPE_D,
47 22, 'u', CHANNEL_MODE_TYPE_D,
48 23, 'D', CHANNEL_MODE_TYPE_D,
49 24, 'd', CHANNEL_MODE_TYPE_D,
50 25, 'R', CHANNEL_MODE_TYPE_D,
51 26, 'z', CHANNEL_MODE_TYPE_D,
56 void init_ModeNode() {
57 unsigned int *mode, flag = 1;
58 modes_with_strarg = 0;
59 modes_with_intarg = 0;
61 for (mode = valid_modes; mode[1]; mode += 3) {
62 if((mode[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING) {
63 mode[2] |= modes_with_strarg << CHANNEL_MODE_VALUE_INDEX_SHIFT;
66 if((mode[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_INTEGER) {
67 mode[2] |= modes_with_intarg << CHANNEL_MODE_VALUE_INDEX_SHIFT;
76 struct ModeNode *createModeNode(struct ChanNode *chan) {
77 struct ModeNode *modes = malloc(sizeof(*modes));
80 perror("malloc() failed");
86 modes->mode_str_args = calloc(modes_with_strarg, sizeof(char*));
87 modes->mode_int_args = calloc(modes_with_intarg, sizeof(int));
91 void freeModeNode(struct ModeNode *modes) {
93 for(i = 0; i < modes_with_strarg; i++) {
94 if(modes->mode_str_args[i])
95 free(modes->mode_str_args[i]);
97 free(modes->mode_str_args);
98 free(modes->mode_int_args);
102 static unsigned int* getModeOptions(char mode) {
104 for (cmode = valid_modes; cmode[1]; cmode += 3) {
111 int isModeSet(struct ModeNode* modes, char modeChar) {
112 unsigned int *modeOpt = getModeOptions(modeChar);
113 return (modes->modes & modeOpt[0]);
116 int isModeAffected(struct ModeNode* modes, char modeChar) {
117 unsigned int *modeOpt = getModeOptions(modeChar);
118 return (modes->allmodes & modeOpt[0]);
121 void* getModeValue(struct ModeNode* modes, char modeChar) {
122 #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
123 unsigned int *modeOpt = getModeOptions(modeChar);
124 if((modeOpt[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING)
125 return modes->mode_str_args[MODE_VALUE_INDEX];
126 if((modeOpt[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_INTEGER)
127 return &modes->mode_int_args[MODE_VALUE_INDEX];
129 #undef MODE_VALUE_INDEX
132 unsigned int getModeType(struct ModeNode* modes, char modeChar) {
133 #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
134 unsigned int *modeOpt = getModeOptions(modeChar);
135 if(!modeOpt) return 0;
137 #undef MODE_VALUE_INDEX
140 static void parseModesUserPriv(struct ModeNode* modes, unsigned char flag, int add, char *nick) {
141 if(modes->chan == NULL) return;
142 struct UserNode *user = getUserByNick(nick);
143 if(user == NULL) return;
144 struct ChanUser *chanuser = getChanUser(user, modes->chan);
145 if(chanuser == NULL) return;
147 chanuser->flags |= flag;
149 chanuser->flags &= ~flag;
150 if((chanuser->flags & CHANUSERFLAG_OPPED_OR_VOICED) && (chanuser->flags & CHANUSERFLAG_INVISIBLE))
151 chanuser->flags &= ~CHANUSERFLAG_INVISIBLE;
154 static void parseModesBan(struct ModeNode* modes, int add, char *mask) {
155 if(modes->chan == NULL) return;
157 addChannelBan(modes->chan, mask);
159 removeChannelBanMask(modes->chan, mask);
162 void parseModes(struct ModeNode* modes, char *modeStr, char **argv, int argc) {
163 int i, argpos = 0, add = 1;
164 #define MODE_TYPE (modeOpt[2] & CHANNEL_MODE_TYPE)
165 #define MODE_VALUE (modeOpt[2] & CHANNEL_MODE_VALUE)
166 #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
167 unsigned int *modeOpt;
168 for(i = 0; i < strlen(modeStr); i++) {
169 if(modeStr[i] == '+') {
173 if(modeStr[i] == '-') {
177 modeOpt = getModeOptions(modeStr[i]);
178 if(!modeOpt) continue; // unknown mode?
179 if(MODE_TYPE == CHANNEL_MODE_TYPE_A) {
180 if(argpos == argc) continue;
184 parseModesUserPriv(modes, CHANUSERFLAG_OPPED, add, argv[argpos]);
187 parseModesUserPriv(modes, CHANUSERFLAG_HALFOPPED, add, argv[argpos]);
190 parseModesUserPriv(modes, CHANUSERFLAG_VOICED, add, argv[argpos]);
193 parseModesBan(modes, add, argv[argpos]);
196 //we have an unknown TYPE_A mode???
203 if(MODE_TYPE != CHANNEL_MODE_TYPE_D) { //all other types take parameters when set
204 if(argpos == argc) continue;
205 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
206 if(modes->mode_str_args[MODE_VALUE_INDEX])
207 free(modes->mode_str_args[MODE_VALUE_INDEX]);
208 modes->mode_str_args[MODE_VALUE_INDEX] = strdup(argv[argpos++]);
209 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
210 modes->mode_int_args[MODE_VALUE_INDEX] = atoi(argv[argpos++]);
212 argpos++; //we simply don't know what to do with the argument...
214 modes->modes |= modeOpt[0];
215 modes->allmodes |= modeOpt[0];
217 modes->modes &= ~modeOpt[0];
218 modes->allmodes |= modeOpt[0];
219 if(MODE_TYPE == CHANNEL_MODE_TYPE_B) {
220 if(argpos == argc) continue;
221 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
222 free(modes->mode_str_args[MODE_VALUE_INDEX]);
223 modes->mode_str_args[MODE_VALUE_INDEX] = NULL;
224 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
225 modes->mode_int_args[MODE_VALUE_INDEX] = 0;
226 argpos++; //we don't need the argument when unsetting a mode...
232 #undef MODE_VALUE_INDEX
235 void parseModeString(struct ModeNode* modes, char *modeStr) {
237 char *args[modes_count+1];
238 char *a, *b = modeStr;
245 parseModes(modes, args[0], args+1, argc-1);
248 int parseMode(struct ModeNode* modes, int add, char mode, char *param) {
249 #define MODE_TYPE (modeOpt[2] & CHANNEL_MODE_TYPE)
250 #define MODE_VALUE (modeOpt[2] & CHANNEL_MODE_VALUE)
251 #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
252 unsigned int *modeOpt = getModeOptions(mode);
253 if(!modeOpt) return 0;
254 if(MODE_TYPE == CHANNEL_MODE_TYPE_A) {
259 parseModesUserPriv(modes, CHANUSERFLAG_OPPED, add, param);
262 parseModesUserPriv(modes, CHANUSERFLAG_VOICED, add, param);
265 parseModesBan(modes, add, param);
268 return 0; //we have an unknown TYPE_A mode???
272 if(MODE_TYPE != CHANNEL_MODE_TYPE_D) { //all other types take parameters when set
274 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
275 if(modes->mode_str_args[MODE_VALUE_INDEX])
276 free(modes->mode_str_args[MODE_VALUE_INDEX]);
277 modes->mode_str_args[MODE_VALUE_INDEX] = strdup(param);
278 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
279 modes->mode_int_args[MODE_VALUE_INDEX] = atoi(param);
281 modes->modes |= modeOpt[0];
282 modes->allmodes |= modeOpt[0];
284 modes->modes &= ~modeOpt[0];
285 modes->allmodes |= modeOpt[0];
286 if(MODE_TYPE == CHANNEL_MODE_TYPE_B) {
287 if(!param && !(modeOpt[2] & CHANNEL_MODE_KEY)) return 0;
288 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
289 free(modes->mode_str_args[MODE_VALUE_INDEX]);
290 modes->mode_str_args[MODE_VALUE_INDEX] = NULL;
291 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
292 modes->mode_int_args[MODE_VALUE_INDEX] = 0;
297 #undef MODE_VALUE_INDEX
301 void getModeString(struct ModeNode* modes, char *modesStr) {
302 #define MODE_TYPE (mode[2] & CHANNEL_MODE_TYPE)
303 #define MODE_VALUE (mode[2] & CHANNEL_MODE_VALUE)
304 #define MODE_VALUE_INDEX (mode[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
305 char paramStr[MAXLEN];
310 for (mode = valid_modes; mode[1]; mode += 3) {
311 if(modes->modes & mode[0]) {
312 modesStr[modePos++] = (char) mode[1];
313 if(MODE_TYPE != CHANNEL_MODE_TYPE_D) {
314 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING)
315 paramPos += sprintf(paramStr + paramPos, " %s", modes->mode_str_args[MODE_VALUE_INDEX]);
316 else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
317 paramPos += sprintf(paramStr + paramPos, " %d", modes->mode_int_args[MODE_VALUE_INDEX]);
321 paramStr[paramPos] = '\0';
322 strcpy(modesStr + modePos, paramStr);
325 #undef MODE_VALUE_INDEX
328 void getFullModeString(struct ModeNode* modes, char *modesStr) {
329 #define MODE_TYPE (mode[2] & CHANNEL_MODE_TYPE)
330 #define MODE_VALUE (mode[2] & CHANNEL_MODE_VALUE)
331 #define MODE_VALUE_INDEX (mode[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
332 char addMode[modes_count+1];
334 char addParams[MAXLEN];
336 int addParamsPos = 0;
337 char delMode[modes_count+1];
340 for (mode = valid_modes; mode[1]; mode += 3) {
341 if(modes->allmodes & mode[0]) {
342 if(modes->modes & mode[0]) {
343 addMode[addModePos++] = (char) mode[1];
344 if(MODE_TYPE != CHANNEL_MODE_TYPE_D) {
345 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING)
346 addParamsPos += sprintf(addParams + addParamsPos, " %s", modes->mode_str_args[MODE_VALUE_INDEX]);
347 else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
348 addParamsPos += sprintf(addParams + addParamsPos, " %d", modes->mode_int_args[MODE_VALUE_INDEX]);
351 delMode[delModePos++] = (char) mode[1];
355 addMode[addModePos] = '\0';
356 delMode[delModePos] = '\0';
357 addParams[addParamsPos] = '\0';
358 sprintf(modesStr, "%s%s%s%s%s", (addModePos ? "+" : ""), addMode, (delModePos ? "-" : ""), delMode, addParams);
359 if(*modesStr == '\0') {
360 sprintf(modesStr, "+");
364 #undef MODE_VALUE_INDEX