X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/73de5d22eddfad566e7c3b543e78bb787ba4398b..1229514e6d1cee2b6ef5a50b3b15ff7745026b53:/src/chmode.c diff --git a/src/chmode.c b/src/chmode.c index 40e56c4..5cbcde3 100644 --- a/src/chmode.c +++ b/src/chmode.c @@ -57,61 +57,97 @@ #define SM_ERR_RPL_Q 0x00000800 #define SM_ERR_RPL_F 0x00001000 +#define MAXMODES_SIMPLE 46 /* a-zA-Z except bqeIov */ + static struct ChModeChange mode_changes[BUFSIZE]; static int mode_count; static int mode_limit; +static int mode_limit_simple; static int mask_pos; -static int orphaned_cflags = 0; +char cflagsbuf[256]; +char cflagsmyinfo[256]; int chmode_flags[256]; + +/* OPTIMIZE ME! -- dwr */ void -find_orphaned_cflags(void) +construct_noparam_modes(void) { int i; - static int prev_chmode_flags[256]; + char *ptr = cflagsbuf; + char *ptr2 = cflagsmyinfo; + static int prev_chmode_flags[256]; + + *ptr = '\0'; + *ptr2 = '\0'; - for (i = 0; i < 256; i++) + for(i = 0; i < 256; i++) { + if( !(chmode_table[i].set_func == chm_ban) && + !(chmode_table[i].set_func == chm_forward) && + !(chmode_table[i].set_func == chm_throttle) && + !(chmode_table[i].set_func == chm_key) && + !(chmode_table[i].set_func == chm_limit) && + !(chmode_table[i].set_func == chm_op) && + !(chmode_table[i].set_func == chm_voice)) + { + chmode_flags[i] = chmode_table[i].mode_type; + } + else + { + chmode_flags[i] = 0; + } + if (prev_chmode_flags[i] != 0 && prev_chmode_flags[i] != chmode_flags[i]) { if (chmode_flags[i] == 0) { - orphaned_cflags |= prev_chmode_flags[i]; + chmode_table[i].set_func = chm_orphaned; sendto_realops_snomask(SNO_DEBUG, L_ALL, "Cmode +%c is now orphaned", i); } else { - orphaned_cflags &= ~prev_chmode_flags[i]; sendto_realops_snomask(SNO_DEBUG, L_ALL, "Orphaned cmode +%c is picked up by module", i); } chmode_flags[i] = prev_chmode_flags[i]; } else prev_chmode_flags[i] = chmode_flags[i]; - } -} - -void -construct_noparam_modes(void) -{ - int i; - - for(i = 0; i < 256; i++) - { - if( (chmode_table[i].set_func == chm_simple) || - (chmode_table[i].set_func == chm_staff) || - (chmode_table[i].set_func == chm_regonly)) + + switch (chmode_flags[i]) { - chmode_flags[i] = chmode_table[i].mode_type; + case MODE_EXLIMIT: + case MODE_DISFORWARD: + if(ConfigChannel.use_forward) + { + *ptr++ = (char) i; + } + + break; + case MODE_REGONLY: + if(rb_dlink_list_length(&service_list)) + { + *ptr++ = (char) i; + } + + break; + default: + if(chmode_flags[i] != 0) + { + *ptr++ = (char) i; + } } - else + + /* Should we leave orphaned check here? -- dwr */ + if(!(chmode_table[i].set_func == chm_nosuch) && !(chmode_table[i].set_func == chm_orphaned)) { - chmode_flags[i] = 0; + *ptr2++ = (char) i; } } - find_orphaned_cflags(); + *ptr++ = '\0'; + *ptr2++ = '\0'; } /* @@ -345,7 +381,7 @@ pretty_mask(const char *idmask) if(*t != '\0') user = t; } - else if(strchr(mask, '.') != NULL || strchr(mask, ':') != NULL) + else if(strchr(mask, '.') != NULL || strchr(mask, ':') != NULL || strchr(mask, '/') != NULL) { if(*mask != '\0') host = mask; @@ -465,8 +501,7 @@ chm_simple(struct Client *source_p, struct Channel *chptr, return; } - /* +ntspmaikl == 9 + MAXMODEPARAMS (4 * +o) */ - if(MyClient(source_p) && (++mode_limit > (9 + MAXMODEPARAMS))) + if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE)) return; /* setting + */ @@ -501,6 +536,40 @@ chm_simple(struct Client *source_p, struct Channel *chptr, } } +void +chm_orphaned(struct Client *source_p, struct Channel *chptr, + int alevel, int parc, int *parn, + const char **parv, int *errors, int dir, char c, long mode_type) +{ + if(MyClient(source_p)) + return; + + if((dir == MODE_ADD) && !(chptr->mode.mode & mode_type)) + { + chptr->mode.mode |= mode_type; + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_ADD; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count++].arg = NULL; + } + else if((dir == MODE_DEL) && (chptr->mode.mode & mode_type)) + { + chptr->mode.mode &= ~mode_type; + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_DEL; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ALL_MEMBERS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count++].arg = NULL; + } +} + void chm_staff(struct Client *source_p, struct Channel *chptr, int alevel, int parc, int *parn, @@ -522,6 +591,9 @@ chm_staff(struct Client *source_p, struct Channel *chptr, return; } + if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE)) + return; + /* setting + */ if((dir == MODE_ADD) && !(chptr->mode.mode & mode_type)) { @@ -924,6 +996,9 @@ chm_limit(struct Client *source_p, struct Channel *chptr, if(dir == MODE_QUERY) return; + if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE)) + return; + if((dir == MODE_ADD) && parc > *parn) { lstr = parv[(*parn)]; @@ -980,6 +1055,9 @@ chm_throttle(struct Client *source_p, struct Channel *chptr, if(dir == MODE_QUERY) return; + if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE)) + return; + if((dir == MODE_ADD) && parc > *parn) { sscanf(parv[(*parn)], "%d:%d", &joins, ×lice); @@ -1066,6 +1144,9 @@ chm_forward(struct Client *source_p, struct Channel *chptr, } #endif + if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE)) + return; + if(dir == MODE_ADD && parc > *parn) { forward = parv[(*parn)]; @@ -1149,6 +1230,9 @@ chm_key(struct Client *source_p, struct Channel *chptr, if(dir == MODE_QUERY) return; + if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE)) + return; + if((dir == MODE_ADD) && parc > *parn) { key = LOCAL_COPY(parv[(*parn)]); @@ -1223,14 +1307,17 @@ chm_regonly(struct Client *source_p, struct Channel *chptr, if(dir == MODE_QUERY) return; - if(((dir == MODE_ADD) && (chptr->mode.mode & MODE_REGONLY)) || - ((dir == MODE_DEL) && !(chptr->mode.mode & MODE_REGONLY))) + if(((dir == MODE_ADD) && (chptr->mode.mode & mode_type)) || + ((dir == MODE_DEL) && !(chptr->mode.mode & mode_type))) + return; + + if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE)) return; if(dir == MODE_ADD) - chptr->mode.mode |= MODE_REGONLY; + chptr->mode.mode |= mode_type; else - chptr->mode.mode &= ~MODE_REGONLY; + chptr->mode.mode &= ~mode_type; mode_changes[mode_count].letter = c; mode_changes[mode_count].dir = dir; @@ -1359,7 +1446,7 @@ struct ChannelMode chmode_table[256] = {chm_op, 0 }, /* o */ {chm_simple, MODE_PRIVATE }, /* p */ {chm_ban, CHFL_QUIET }, /* q */ - {chm_regonly, 0 }, /* r */ + {chm_regonly, MODE_REGONLY }, /* r */ {chm_simple, MODE_SECRET }, /* s */ {chm_simple, MODE_TOPICLIMIT }, /* t */ {chm_nosuch, 0 }, /* u */ @@ -1543,6 +1630,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, mask_pos = 0; mode_count = 0; mode_limit = 0; + mode_limit_simple = 0; alevel = get_channel_access(source_p, msptr);