*mbuf++ = 'D';
else if (MyUser(cptr) && (chptr->mode.mode & MODE_WASDELJOINS))
*mbuf++ = 'd';
+ if (chptr->mode.mode & MODE_REGISTERED)
+ *mbuf++ = 'R';
if (chptr->mode.limit) {
*mbuf++ = 'l';
ircd_snprintf(0, pbuf, buflen, "%u", chptr->mode.limit);
MODE_NOPRIVMSGS, 'n',
MODE_REGONLY, 'r',
MODE_DELJOINS, 'D',
+ MODE_REGISTERED, 'R',
/* MODE_KEY, 'k', */
/* MODE_BAN, 'b', */
MODE_LIMIT, 'l',
mode &= (MODE_ADD | MODE_DEL | MODE_PRIVATE | MODE_SECRET | MODE_MODERATED |
MODE_TOPICLIMIT | MODE_INVITEONLY | MODE_NOPRIVMSGS | MODE_REGONLY |
- MODE_DELJOINS | MODE_WASDELJOINS);
+ MODE_DELJOINS | MODE_WASDELJOINS | MODE_REGISTERED);
if (!(mode & ~(MODE_ADD | MODE_DEL))) /* don't add empty modes... */
return;
MODE_KEY, 'k',
MODE_APASS, 'A',
MODE_UPASS, 'U',
+ MODE_REGISTERED, 'R',
/* MODE_BAN, 'b', */
MODE_LIMIT, 'l',
MODE_REGONLY, 'r',
return;
}
-/** Simple function to invalidate bans
+/** Simple function to invalidate a channel's ban cache.
*
- * This function sets all bans as being valid.
+ * This function marks all members of the channel as being neither
+ * banned nor banned.
*
* @param chan The channel to operate on.
*/
assert(newban->flags & (BAN_ADD|BAN_DEL));
if (newban->flags & BAN_ADD) {
size_t totlen = 0;
- /* If a less specific entry is found, fail. */
+ /* If a less specific *active* entry is found, fail. */
for (ban = *banlist; ban; ban = ban->next) {
- if (!bmatch(ban, newban)) {
+ if (!bmatch(ban, newban) && !(ban->flags & BAN_DEL)) {
if (do_free)
free_ban(newban);
return 1;
if (!state->mbuf)
return;
+ /* Local users are not permitted to change registration status */
+ if (flag_p[0] == MODE_REGISTERED && !(state->flags & MODE_PARSE_FORCE) &&
+ MyUser(state->sptr))
+ return;
+
if (state->dir == MODE_ADD) {
state->add |= flag_p[0];
state->del &= ~flag_p[0];
MODE_KEY, 'k',
MODE_APASS, 'A',
MODE_UPASS, 'U',
+ MODE_REGISTERED, 'R',
MODE_BAN, 'b',
MODE_LIMIT, 'l',
MODE_REGONLY, 'r',