allow MODE_PARSE_FOCE flag overriding target channel check on MODE_FORWARD (srvx...
[ircu2.10.12-pk.git] / ircd / channel.c
index 9de97d3755d5f65c516c8e6bfc2eeab9e2a74d64..30b9f1de6d3864cf78b71756416c9190184b3d81 100644 (file)
@@ -2537,15 +2537,17 @@ mode_parse_altchan(struct ParseState *state, ulong64 *flag_p)
     if (!IsChannelName(t_str) || !strIsIrcCh(t_str) || strlen(t_str) > IRCD_MIN(CHANNELLEN, feature_int(FEAT_CHANNELLEN)) || t_str[0] == '&') /* only parse it if it's a valid channel name! */
       return;
     
-    struct Channel *chptr;
-    struct Membership *member;
-    if (!(chptr = FindChannel(t_str)))
+    if(!(state->flags & MODE_PARSE_FORCE)) {
+      struct Channel *chptr;
+      struct Membership *member;
+      if (!(chptr = FindChannel(t_str)))
         return;
-    if(!(member = find_member_link(chptr, state->sptr)))
+      if(!(member = find_member_link(chptr, state->sptr)))
         return;
-    if(!IsChanOp(member)) {
+      if(!IsChanOp(member)) {
         send_notoper(state);
         return;
+      }
     }
     
     if (!(state->flags & MODE_PARSE_WIPEOUT) &&
@@ -2589,10 +2591,13 @@ mode_parse_altchan(struct ParseState *state, ulong64 *flag_p)
     modebuf_mode_string(state->mbuf, state->dir | flag_p[0], t_str, 0);
 
   if (state->flags & MODE_PARSE_SET) {
-    if (state->dir == MODE_DEL) /* remove the old altchan */
+    if (state->dir == MODE_DEL) /* remove the old altchan */
       *state->chptr->mode.altchan = '\0';
-    else
+      state->chptr->mode.mode &= ~flag_p[0];
+    } else {
       ircd_strncpy(state->chptr->mode.altchan, t_str, CHANNELLEN);
+      state->chptr->mode.mode |= flag_p[0];
+    }
   }
 }
 
@@ -2684,10 +2689,13 @@ mode_parse_noflood(struct ParseState *state, ulong64 *flag_p)
     modebuf_mode_string(state->mbuf, state->dir | flag_p[0], t_str, 0);
 
   if (state->flags & MODE_PARSE_SET) {
-    if (state->dir == MODE_DEL) /* remove the old noflood */
+    if (state->dir == MODE_DEL) /* remove the old noflood */
       *state->chptr->mode.noflood = '\0';
-    else
+      state->chptr->mode.mode &= ~flag_p[0];
+    } else {
       ircd_strncpy(state->chptr->mode.noflood, t_str, CHANNELLEN);
+      state->chptr->mode.mode |= flag_p[0];
+    }
   }
   
   if (state->dir == MODE_ADD) {
@@ -2699,6 +2707,7 @@ mode_parse_noflood(struct ParseState *state, ulong64 *flag_p)
     state->chptr->mode.noflood_value = noflood_value;
   } else {
     //removed the mode so free all flood objects
+    state->chptr->mode.noflood_value = 0;
     struct Membership *member;
     for(member = state->chptr->members; member; member = member->next_member) {
         struct MemberFlood *floodnode;
@@ -4364,7 +4373,7 @@ int ext_amsg_block(struct Client *cptr, struct Channel *chptr, const char *msg)
  * --pk910 2011/7/1
  */
 int ext_noflood_block(struct Client *cptr, struct Channel *chptr) {
-  if(chptr->mode.noflood == NULL || !chptr->mode.noflood) return 0;
+  if(!*chptr->mode.noflood) return 0;
   struct Membership *member = find_member_link(chptr, cptr);
   if(!member) return 0; //TODO: we've no check for -n channels implemented, yet
   //check if this user is really affected by +f