1 /* ModeNode.c - NeonServ v5.0
2 * Copyright (C) 2011 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, 'v', CHANNEL_MODE_TYPE_A,
29 4, 'k', CHANNEL_MODE_TYPE_B | CHANNEL_MODE_VALUE_STRING | CHANNEL_MODE_KEY,
30 5, 'a', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_INTEGER,
31 6, 'l', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_INTEGER,
32 7, 'f', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_STRING,
33 8, 'F', CHANNEL_MODE_TYPE_C | CHANNEL_MODE_VALUE_STRING,
34 9, 'c', CHANNEL_MODE_TYPE_D,
35 10, 'C', CHANNEL_MODE_TYPE_D,
36 11, 'i', CHANNEL_MODE_TYPE_D,
37 12, 'm', CHANNEL_MODE_TYPE_D,
38 13, 'M', CHANNEL_MODE_TYPE_D,
39 14, 'n', CHANNEL_MODE_TYPE_D,
40 15, 'N', CHANNEL_MODE_TYPE_D,
41 16, 'p', CHANNEL_MODE_TYPE_D,
42 17, 'r', CHANNEL_MODE_TYPE_D,
43 18, 's', CHANNEL_MODE_TYPE_D,
44 19, 't', CHANNEL_MODE_TYPE_D,
45 20, 'u', CHANNEL_MODE_TYPE_D,
46 21, 'D', CHANNEL_MODE_TYPE_D,
47 22, 'd', CHANNEL_MODE_TYPE_D,
48 23, 'R', CHANNEL_MODE_TYPE_D,
49 24, 'z', CHANNEL_MODE_TYPE_D,
54 void init_ModeNode() {
55 unsigned int *mode, flag = 1;
56 modes_with_strarg = 0;
57 modes_with_intarg = 0;
59 for (mode = valid_modes; mode[1]; mode += 3) {
60 if((mode[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING) {
61 mode[2] |= modes_with_strarg << CHANNEL_MODE_VALUE_INDEX_SHIFT;
64 if((mode[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_INTEGER) {
65 mode[2] |= modes_with_intarg << CHANNEL_MODE_VALUE_INDEX_SHIFT;
74 struct ModeNode *createModeNode(struct ChanNode *chan) {
75 struct ModeNode *modes = malloc(sizeof(*modes));
78 perror("malloc() failed");
84 modes->mode_str_args = calloc(modes_with_strarg, sizeof(char*));
85 modes->mode_int_args = calloc(modes_with_intarg, sizeof(int));
89 void freeModeNode(struct ModeNode *modes) {
91 for(i = 0; i < modes_with_strarg; i++) {
92 if(modes->mode_str_args[i])
93 free(modes->mode_str_args[i]);
95 free(modes->mode_str_args);
96 free(modes->mode_int_args);
100 static unsigned int* getModeOptions(char mode) {
102 for (cmode = valid_modes; cmode[1]; cmode += 3) {
109 int isModeSet(struct ModeNode* modes, char modeChar) {
110 unsigned int *modeOpt = getModeOptions(modeChar);
111 return (modes->modes & modeOpt[0]);
114 int isModeAffected(struct ModeNode* modes, char modeChar) {
115 unsigned int *modeOpt = getModeOptions(modeChar);
116 return (modes->allmodes & modeOpt[0]);
119 void* getModeValue(struct ModeNode* modes, char modeChar) {
120 #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
121 unsigned int *modeOpt = getModeOptions(modeChar);
122 if((modeOpt[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_STRING)
123 return modes->mode_str_args[MODE_VALUE_INDEX];
124 if((modeOpt[2] & CHANNEL_MODE_VALUE) == CHANNEL_MODE_VALUE_INTEGER)
125 return &modes->mode_int_args[MODE_VALUE_INDEX];
127 #undef MODE_VALUE_INDEX
130 unsigned int getModeType(struct ModeNode* modes, char modeChar) {
131 #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
132 unsigned int *modeOpt = getModeOptions(modeChar);
133 if(!modeOpt) return 0;
135 #undef MODE_VALUE_INDEX
138 static void parseModesUserPriv(struct ModeNode* modes, unsigned char flag, int add, char *nick) {
139 if(modes->chan == NULL) return;
140 struct UserNode *user = getUserByNick(nick);
141 if(user == NULL) return;
142 struct ChanUser *chanuser = getChanUser(user, modes->chan);
143 if(chanuser == NULL) return;
145 chanuser->flags |= flag;
147 chanuser->flags &= ~flag;
150 static void parseModesBan(struct ModeNode* modes, int add, char *mask) {
151 if(modes->chan == NULL) return;
153 addChannelBan(modes->chan, mask);
155 removeChannelBanMask(modes->chan, mask);
158 void parseModes(struct ModeNode* modes, char *modeStr, char **argv, int argc) {
159 int i, argpos = 0, add = 1;
160 #define MODE_TYPE (modeOpt[2] & CHANNEL_MODE_TYPE)
161 #define MODE_VALUE (modeOpt[2] & CHANNEL_MODE_VALUE)
162 #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
163 unsigned int *modeOpt;
164 for(i = 0; i < strlen(modeStr); i++) {
165 if(modeStr[i] == '+') {
169 if(modeStr[i] == '-') {
173 modeOpt = getModeOptions(modeStr[i]);
174 if(!modeOpt) continue; // unknown mode?
175 if(MODE_TYPE == CHANNEL_MODE_TYPE_A) {
176 if(argpos == argc) continue;
180 parseModesUserPriv(modes, CHANUSERFLAG_OPPED, add, argv[argpos]);
183 parseModesUserPriv(modes, CHANUSERFLAG_VOICED, add, argv[argpos]);
186 parseModesBan(modes, add, argv[argpos]);
189 //we have an unknown TYPE_A mode???
196 if(MODE_TYPE != CHANNEL_MODE_TYPE_D) { //all other types take parameters when set
197 if(argpos == argc) continue;
198 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
199 if(modes->mode_str_args[MODE_VALUE_INDEX])
200 free(modes->mode_str_args[MODE_VALUE_INDEX]);
201 modes->mode_str_args[MODE_VALUE_INDEX] = strdup(argv[argpos++]);
202 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
203 modes->mode_int_args[MODE_VALUE_INDEX] = atoi(argv[argpos++]);
205 argpos++; //we simply don't know what to do with the argument...
207 modes->modes |= modeOpt[0];
208 modes->allmodes |= modeOpt[0];
210 modes->modes &= ~modeOpt[0];
211 modes->allmodes |= modeOpt[0];
212 if(MODE_TYPE == CHANNEL_MODE_TYPE_B) {
213 if(argpos == argc) continue;
214 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
215 free(modes->mode_str_args[MODE_VALUE_INDEX]);
216 modes->mode_str_args[MODE_VALUE_INDEX] = NULL;
217 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
218 modes->mode_int_args[MODE_VALUE_INDEX] = 0;
219 argpos++; //we don't need the argument when unsetting a mode...
225 #undef MODE_VALUE_INDEX
228 void parseModeString(struct ModeNode* modes, char *modeStr) {
230 char *args[modes_count+1];
231 char *a, *b = modeStr;
238 parseModes(modes, args[0], args+1, argc-1);
241 int parseMode(struct ModeNode* modes, int add, char mode, char *param) {
242 #define MODE_TYPE (modeOpt[2] & CHANNEL_MODE_TYPE)
243 #define MODE_VALUE (modeOpt[2] & CHANNEL_MODE_VALUE)
244 #define MODE_VALUE_INDEX (modeOpt[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
245 unsigned int *modeOpt = getModeOptions(mode);
246 if(!modeOpt) return 0;
247 if(MODE_TYPE == CHANNEL_MODE_TYPE_A) {
252 parseModesUserPriv(modes, CHANUSERFLAG_OPPED, add, param);
255 parseModesUserPriv(modes, CHANUSERFLAG_VOICED, add, param);
258 parseModesBan(modes, add, param);
261 return 0; //we have an unknown TYPE_A mode???
265 if(MODE_TYPE != CHANNEL_MODE_TYPE_D) { //all other types take parameters when set
267 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
268 if(modes->mode_str_args[MODE_VALUE_INDEX])
269 free(modes->mode_str_args[MODE_VALUE_INDEX]);
270 modes->mode_str_args[MODE_VALUE_INDEX] = strdup(param);
271 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
272 modes->mode_int_args[MODE_VALUE_INDEX] = atoi(param);
274 modes->modes |= modeOpt[0];
275 modes->allmodes |= modeOpt[0];
277 modes->modes &= ~modeOpt[0];
278 modes->allmodes |= modeOpt[0];
279 if(MODE_TYPE == CHANNEL_MODE_TYPE_B) {
281 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING) {
282 free(modes->mode_str_args[MODE_VALUE_INDEX]);
283 modes->mode_str_args[MODE_VALUE_INDEX] = NULL;
284 } else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
285 modes->mode_int_args[MODE_VALUE_INDEX] = 0;
290 #undef MODE_VALUE_INDEX
294 void getModeString(struct ModeNode* modes, char *modesStr) {
295 #define MODE_TYPE (mode[2] & CHANNEL_MODE_TYPE)
296 #define MODE_VALUE (mode[2] & CHANNEL_MODE_VALUE)
297 #define MODE_VALUE_INDEX (mode[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
298 char paramStr[MAXLEN];
303 for (mode = valid_modes; mode[1]; mode += 3) {
304 if(modes->modes & mode[0]) {
305 modesStr[modePos++] = (char) mode[1];
306 if(MODE_TYPE != CHANNEL_MODE_TYPE_D) {
307 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING)
308 paramPos += sprintf(paramStr + paramPos, " %s", modes->mode_str_args[MODE_VALUE_INDEX]);
309 else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
310 paramPos += sprintf(paramStr + paramPos, " %d", modes->mode_int_args[MODE_VALUE_INDEX]);
314 paramStr[paramPos] = '\0';
315 strcpy(modesStr + modePos, paramStr);
318 #undef MODE_VALUE_INDEX
321 void getFullModeString(struct ModeNode* modes, char *modesStr) {
322 #define MODE_TYPE (mode[2] & CHANNEL_MODE_TYPE)
323 #define MODE_VALUE (mode[2] & CHANNEL_MODE_VALUE)
324 #define MODE_VALUE_INDEX (mode[2] & CHANNEL_MODE_VALUE_INDEX_MASK) >> CHANNEL_MODE_VALUE_INDEX_SHIFT
325 char addMode[modes_count+1];
327 char addParams[MAXLEN];
329 int addParamsPos = 0;
330 char delMode[modes_count+1];
333 for (mode = valid_modes; mode[1]; mode += 3) {
334 if(modes->allmodes & mode[0]) {
335 if(modes->modes & mode[0]) {
336 addMode[addModePos++] = (char) mode[1];
337 if(MODE_TYPE != CHANNEL_MODE_TYPE_D) {
338 if(MODE_VALUE == CHANNEL_MODE_VALUE_STRING)
339 addParamsPos += sprintf(addParams + addParamsPos, " %s", modes->mode_str_args[MODE_VALUE_INDEX]);
340 else if(MODE_VALUE == CHANNEL_MODE_VALUE_INTEGER)
341 addParamsPos += sprintf(addParams + addParamsPos, " %d", modes->mode_int_args[MODE_VALUE_INDEX]);
344 delMode[delModePos++] = (char) mode[1];
348 addMode[addModePos] = '\0';
349 delMode[delModePos] = '\0';
350 addParams[addParamsPos] = '\0';
351 sprintf(modesStr, "%s%s%s%s%s", (addModePos ? "+" : ""), addMode, (delModePos ? "-" : ""), delMode, addParams);
352 if(*modesStr == '\0') {
353 sprintf(modesStr, "+");
357 #undef MODE_VALUE_INDEX