Bump patchlevel; add more epoll support; assertion check in
[ircu2.10.12-pk.git] / ircd / channel.c
index 81be0d993346796f09e823b4b51ce458a5b1c4bc..1912d16275899a6a9470964f39fa45e40ccb6ab8 100644 (file)
@@ -346,12 +346,15 @@ struct Ban *find_ban(struct Client *cptr, struct Ban *banlist)
 {
   char        nu[NICKLEN + USERLEN + 2];
   char        tmphost[HOSTLEN + 1];
+  char        iphost[SOCKIPLEN + 1];
+  char       *hostmask;
   char       *sr;
   struct Ban *found;
 
   /* Build nick!user and alternate host names. */
   ircd_snprintf(0, nu, sizeof(nu), "%s!%s",
                 cli_name(cptr), cli_user(cptr)->username);
+  ircd_ntoa_r(iphost, &cli_ip(cptr));
   if (!IsAccount(cptr))
     sr = NULL;
   else if (HasHiddenHost(cptr))
@@ -376,10 +379,12 @@ struct Ban *find_ban(struct Client *cptr, struct Ban *banlist)
     if (res)
       continue;
     /* Compare host portion of ban. */
-    if (!((banlist->flags & BAN_IPMASK)
-         && ipmask_check(&cli_ip(cptr), &banlist->address, banlist->addrbits))
-        && match(banlist->banstr + banlist->nu_len + 1, cli_user(cptr)->host)
-        && !(sr && match(banlist->banstr + banlist->nu_len + 1, sr) == 0))
+    hostmask = banlist->banstr + banlist->nu_len + 1;
+    if (((banlist->flags & BAN_IPMASK)
+         ? !ipmask_check(&cli_ip(cptr), &banlist->address, banlist->addrbits)
+         : match(hostmask, iphost))
+        && match(hostmask, cli_user(cptr)->host)
+        && !(sr && match(hostmask, sr) == 0))
       continue;
     /* If an exception matches, no ban can match. */
     if (banlist->flags & BAN_EXCEPTION)
@@ -1104,9 +1109,10 @@ char *pretty_mask(char *mask)
       user = mask;
       host = ++ptr;
     }
-    else if (*ptr == '.')
+    else if (*ptr == '.' || *ptr == ':')
     {
-      /* Case 2: Found last '.' (without finding a '!' or '@' yet) */
+      /* Case 2: Found character specific to IP or hostname (without
+       * finding a '!' or '@' yet) */
       last_dot = ptr;
       continue;
     }
@@ -1630,8 +1636,8 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all)
 
   /* Ok, if we were given the OPMODE flag, or its a server, hide the source.
    */
-  if (mbuf->mb_dest & MODEBUF_DEST_OPMODE || IsServer(mbuf->mb_source))
-    app_source = &me;
+  if (mbuf->mb_dest & MODEBUF_DEST_OPMODE || IsServer(mbuf->mb_source) || IsMe(mbuf->mb_source))
+    app_source = &his;
   else
     app_source = mbuf->mb_source;
 
@@ -2537,6 +2543,7 @@ mode_parse_upass(struct ParseState *state, int *flag_p)
 static void
 mode_parse_apass(struct ParseState *state, int *flag_p)
 {
+  struct Membership *memb;
   char *t_str, *s;
   int t_len;
 
@@ -2645,10 +2652,18 @@ mode_parse_apass(struct ParseState *state, int *flag_p)
        send_reply(state->sptr, RPL_APASSWARN_SECRET, state->chptr->chname,
                    state->chptr->mode.apass);
       }
+      /* Give the channel manager level 0 ops. */
+      if (!(state->flags & MODE_PARSE_FORCE) && IsChannelManager(state->member))
+        SetOpLevel(state->member, 0);
     } else { /* remove the old apass */
       *state->chptr->mode.apass = '\0';
       if (MyUser(state->sptr))
         send_reply(state->sptr, RPL_APASSWARN_CLEAR);
+      /* Revert everyone to MAXOPLEVEL. */
+      for (memb = state->chptr->members; memb; memb = memb->next_member) {
+        if (memb->status & MODE_CHANOP)
+          memb->oplevel = MAXOPLEVEL;
+      }
     }
   }
 }
@@ -2804,7 +2819,7 @@ mode_parse_ban(struct ParseState *state, int *flag_p)
   newban->flags = ((state->dir == MODE_ADD) ? BAN_ADD : BAN_DEL)
       | (*flag_p == MODE_BAN ? 0 : BAN_EXCEPTION);
   set_ban_mask(newban, collapse(pretty_mask(t_str)));
-  ircd_strncpy(newban->who, cli_name(state->sptr), HOSTLEN);
+  ircd_strncpy(newban->who, IsUser(state->sptr) ? cli_name(state->sptr) : "*", NICKLEN);
   newban->when = TStime();
   apply_ban(&state->chptr->banlist, newban, 0);
 }
@@ -3395,10 +3410,11 @@ joinbuf_join(struct JoinBuf *jbuf, struct Channel *chan, unsigned int flags)
     /* send notification to all servers */
     if (jbuf->jb_type != JOINBUF_TYPE_CREATE && !is_local)
     {
-      if (flags & CHFL_CHANOP)
+      if (flags & CHFL_CHANOP) {
+        assert(oplevel == 0 || oplevel == 1);
         sendcmdto_serv_butone(jbuf->jb_source, CMD_JOIN, jbuf->jb_connect,
                               "%u:%H %Tu", oplevel, chan, chan->creationtime);
-      else
+      else
         sendcmdto_serv_butone(jbuf->jb_source, CMD_JOIN, jbuf->jb_connect,
                               "%H %Tu", chan, chan->creationtime);
     }
@@ -3409,7 +3425,7 @@ joinbuf_join(struct JoinBuf *jbuf, struct Channel *chan, unsigned int flags)
 
       /* send an op, too, if needed */
       if (flags & CHFL_CHANOP && (oplevel < MAXOPLEVEL || !MyUser(jbuf->jb_source)))
-       sendcmdto_channel_butserv_butone((chan->mode.apass[0] ? &me : jbuf->jb_source),
+       sendcmdto_channel_butserv_butone((chan->mode.apass[0] ? &his : jbuf->jb_source),
                                          CMD_MODE, chan, NULL, 0, "%H +o %C",
                                         chan, jbuf->jb_source);
     } else if (MyUser(jbuf->jb_source))
@@ -3516,7 +3532,7 @@ void CheckDelayedJoins(struct Channel *chan)
     if (!memb2) {
       /* clear +d */
       chan->mode.mode &= ~MODE_WASDELJOINS;
-      sendcmdto_channel_butserv_butone(&me, CMD_MODE, chan, NULL, 0,
+      sendcmdto_channel_butserv_butone(&his, CMD_MODE, chan, NULL, 0,
                                        "%H -d", chan);
     }
   }