added basic ssl support to ircu
[ircu2.10.12-pk.git] / ircd / channel.c
index ee5a887640a00fa4b52eccba786f8e6c6e45b4a2..9c0f192d2a3cd79502fda636e5d7ada15bfaec89 100644 (file)
@@ -1489,6 +1489,20 @@ build_string(char *strptr, int *strptr_i, const char *str1,
   strptr[(*strptr_i)] = '\0';
 }
 
+/** Check a channel for join-delayed members.
+ * @param[in] chan Channel to search.
+ * @return Non-zero if any members are join-delayed; false if none are.
+ */
+static int
+find_delayed_joins(const struct Channel *chan)
+{
+  const struct Membership *memb;
+  for (memb = chan->members; memb; memb = memb->next_member)
+    if (IsDelayedJoin(memb))
+      return 1;
+  return 0;
+}
+
 /** Flush out the modes
  * This is the workhorse of our ModeBuf suite; this actually generates the
  * output MODE commands, HACK notices, or whatever.  It's pretty complicated.
@@ -1568,6 +1582,23 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all)
   else
     app_source = mbuf->mb_source;
 
+  /* Must be set if going -D and some clients are hidden */
+  if ((mbuf->mb_rem & MODE_DELJOINS)
+      && !(mbuf->mb_channel->mode.mode & (MODE_DELJOINS | MODE_WASDELJOINS))
+      && find_delayed_joins(mbuf->mb_channel)) {
+    mbuf->mb_channel->mode.mode |= MODE_WASDELJOINS;
+    mbuf->mb_add |= MODE_WASDELJOINS;
+    mbuf->mb_rem &= ~MODE_WASDELJOINS;
+  }
+
+  /* +d must be cleared if +D is set */
+  if ((mbuf->mb_add & MODE_DELJOINS)
+      && (mbuf->mb_channel->mode.mode & MODE_WASDELJOINS)) {
+    mbuf->mb_channel->mode.mode &= ~MODE_WASDELJOINS;
+    mbuf->mb_add &= ~MODE_WASDELJOINS;
+    mbuf->mb_rem |= MODE_WASDELJOINS;
+  }
+
   /*
    * Account for user we're bouncing; we have to get it in on the first
    * bounced MODE, or we could have problems
@@ -2024,47 +2055,15 @@ modebuf_mode_client(struct ModeBuf *mbuf, unsigned int mode,
     modebuf_flush_int(mbuf, 0);
 }
 
-/** Check a channel for join-delayed members.
- * @param[in] chan Channel to search.
- * @return Non-zero if any members are join-delayed; false if none are.
- */
-static int
-find_delayed_joins(const struct Channel *chan)
-{
-  const struct Membership *memb;
-  for (memb = chan->members; memb; memb = memb->next_member)
-    if (IsDelayedJoin(memb))
-      return 1;
-  return 0;
-}
-
 /** The exported binding for modebuf_flush()
  *
  * @param mbuf The mode buffer to flush.
- * 
+ *
  * @see modebuf_flush_int()
  */
 int
 modebuf_flush(struct ModeBuf *mbuf)
 {
-  /* Check if MODE_WASDELJOINS should be set: */
-  /* Must be set if going -D and some clients are hidden */
-  if ((mbuf->mb_rem & MODE_DELJOINS)
-      && !(mbuf->mb_channel->mode.mode & (MODE_DELJOINS | MODE_WASDELJOINS))
-      && find_delayed_joins(mbuf->mb_channel)) {
-    mbuf->mb_channel->mode.mode |= MODE_WASDELJOINS;
-    mbuf->mb_add |= MODE_WASDELJOINS;
-    mbuf->mb_rem &= ~MODE_WASDELJOINS;
-  }
-  /* Must be cleared if +D is set */
-  if ((mbuf->mb_add & MODE_DELJOINS)
-      && ((mbuf->mb_channel->mode.mode & (MODE_WASDELJOINS | MODE_WASDELJOINS))
-          == (MODE_WASDELJOINS | MODE_WASDELJOINS))) {
-    mbuf->mb_channel->mode.mode &= ~MODE_WASDELJOINS;
-    mbuf->mb_add &= ~MODE_WASDELJOINS;
-    mbuf->mb_rem |= MODE_WASDELJOINS;
-  }
-
   return modebuf_flush_int(mbuf, 1);
 }
 
@@ -2919,6 +2918,7 @@ mode_process_bans(struct ParseState *state)
        len -= banlen;
       } else {
        if (state->flags & MODE_PARSE_SET && MyUser(state->sptr) &&
+            !(state->mbuf->mb_dest & MODEBUF_DEST_OPMODE) &&
            (len > (feature_int(FEAT_AVBANLEN) * feature_int(FEAT_MAXBANS)) ||
             count > feature_int(FEAT_MAXBANS))) {
          send_reply(state->sptr, ERR_BANLISTFULL, state->chptr->chname,
@@ -2989,17 +2989,19 @@ mode_parse_client(struct ParseState *state, int *flag_p)
     if (colon != NULL) {
       *colon++ = '\0';
       req_oplevel = atoi(colon);
-      if (!(state->flags & MODE_PARSE_FORCE)
+      if (*flag_p == CHFL_VOICE || state->dir == MODE_DEL) {
+        /* Ignore the colon and its argument. */
+      } else if (!(state->flags & MODE_PARSE_FORCE)
           && state->member
           && (req_oplevel < OpLevel(state->member)
               || (req_oplevel == OpLevel(state->member)
                   && OpLevel(state->member) < MAXOPLEVEL)
-              || req_oplevel > MAXOPLEVEL))
+              || req_oplevel > MAXOPLEVEL)) {
         send_reply(state->sptr, ERR_NOTLOWEROPLEVEL,
                    t_str, state->chptr->chname,
                    OpLevel(state->member), req_oplevel, "op",
                    OpLevel(state->member) == req_oplevel ? "the same" : "a higher");
-      else if (req_oplevel <= MAXOPLEVEL)
+      else if (req_oplevel <= MAXOPLEVEL)
         oplevel = req_oplevel;
     }
     /* find client we're manipulating */