X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/2e918bf5155df91166746755113ecc76b5364687..01ed04abaf7c31f0cdd4683e0dc2e4f9bed607b1:/src/chmode.c diff --git a/src/chmode.c b/src/chmode.c index 9d67ed25..b6c761dd 100644 --- a/src/chmode.c +++ b/src/chmode.c @@ -72,12 +72,11 @@ int chmode_flags[256]; /* OPTIMIZE ME! -- dwr */ void -construct_noparam_modes(void) +construct_cflags_strings(void) { int i; char *ptr = cflagsbuf; char *ptr2 = cflagsmyinfo; - static int prev_chmode_flags[256]; *ptr = '\0'; *ptr2 = '\0'; @@ -99,22 +98,6 @@ construct_noparam_modes(void) chmode_flags[i] = 0; } - if (prev_chmode_flags[i] != 0 && prev_chmode_flags[i] != chmode_flags[i]) - { - if (chmode_flags[i] == 0) - { - chmode_table[i].set_func = chm_orphaned; - sendto_realops_snomask(SNO_DEBUG, L_ALL, "Cmode +%c is now orphaned", i); - } - else - { - 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]; - switch (chmode_flags[i]) { case MODE_EXLIMIT: @@ -158,7 +141,7 @@ construct_noparam_modes(void) * 0 if no cflags are available * side effects - NONE */ -unsigned int +static unsigned int find_cflag_slot(void) { unsigned int all_cflags = 0, my_cflag = 0, i; @@ -172,6 +155,34 @@ find_cflag_slot(void) return my_cflag; } +unsigned int +cflag_add(char c_, ChannelModeFunc function) +{ + int c = (unsigned char)c_; + + if (chmode_table[c].set_func != chm_nosuch && + chmode_table[c].set_func != chm_orphaned) + return 0; + + if (chmode_table[c].set_func == chm_nosuch) + chmode_table[c].mode_type = find_cflag_slot(); + if (chmode_table[c].mode_type == 0) + return 0; + chmode_table[c].set_func = function; + construct_cflags_strings(); + return chmode_table[c].mode_type; +} + +void +cflag_orphan(char c_) +{ + int c = (unsigned char)c_; + + s_assert(chmode_flags[c] != 0); + chmode_table[c].set_func = chm_orphaned; + construct_cflags_strings(); +} + static int get_channel_access(struct Client *source_p, struct membership *msptr) { @@ -687,8 +698,8 @@ chm_ban(struct Client *source_p, struct Channel *chptr, case CHFL_QUIET: list = &chptr->quietlist; errorval = SM_ERR_RPL_Q; - rpl_list = RPL_BANLIST; - rpl_endlist = RPL_ENDOFBANLIST; + rpl_list = RPL_QUIETLIST; + rpl_endlist = RPL_ENDOFQUIETLIST; mems = ALL_MEMBERS; caps = 0; break; @@ -723,10 +734,7 @@ chm_ban(struct Client *source_p, struct Channel *chptr, me.name, source_p->name, chptr->chname, banptr->banstr, banptr->who, banptr->when); } - if (mode_type == CHFL_QUIET) - sendto_one(source_p, ":%s %d %s %s :End of Channel Quiet List", me.name, rpl_endlist, source_p->name, chptr->chname); - else - sendto_one(source_p, form_str(rpl_endlist), me.name, source_p->name, chptr->chname); + sendto_one(source_p, form_str(rpl_endlist), me.name, source_p->name, chptr->chname); return; } @@ -1654,6 +1662,12 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, dir = MODE_QUERY; break; default: + /* If this mode char is locked, don't allow local users to change it. */ + if (MyClient(source_p) && chptr->mode_lock && strchr(chptr->mode_lock, c)) + { + sendto_one_numeric(source_p, ERR_MLOCKRESTRICTED, form_str(ERR_MLOCKRESTRICTED), chptr->name, c, chptr->mode_lock); + continue; + } chmode_table[(unsigned char) c].set_func(fakesource_p, chptr, alevel, parc, &parn, parv, &errors, dir, c, @@ -1751,3 +1765,21 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, if(MyClient(source_p) || rb_dlink_list_length(&serv_list) > 1) send_cap_mode_changes(client_p, source_p, chptr, mode_changes, mode_count); } + +/* set_channel_mlock() + * + * inputs - client, source, channel, params + * output - + * side effects - channel mlock is changed / MLOCK is propagated + */ +void +set_channel_mlock(struct Client *client_p, struct Client *source_p, + struct Channel *chptr, const char *newmlock) +{ + rb_free(chptr->mode_lock); + chptr->mode_lock = newmlock ? rb_strdup(newmlock) : NULL; + + sendto_server(client_p, NULL, CAP_TS6 | CAP_MLOCK, NOCAPS, ":%s MLOCK %ld %s :%s", + source_p->id, (long) chptr->channelts, chptr->chname, + chptr->mode_lock ? chptr->mode_lock : ""); +}