keep in sync with OGN upstream (SVN-322 && SVN-323) && fixed ISUPPORT (005) raw ...
authorpk910 <philipp@zoelle1.de>
Thu, 24 May 2012 19:16:14 +0000 (21:16 +0200)
committerpk910 <philipp@zoelle1.de>
Thu, 24 May 2012 19:16:14 +0000 (21:16 +0200)
include/channel.h
include/numeric.h
include/supported.h
ircd/channel.c
ircd/m_clearmode.c
ircd/s_err.c

index 63cb19c8709daddeaafa14cf3de4827a9d0f8ef2..b3deec89220ee10be89162deb3e3f0f84e1bf62c 100644 (file)
@@ -139,14 +139,15 @@ typedef signed long long long64;
 #define MODE_AUDITORIUM 0x200000000LLU /**< +u Auditorium */
 #define MODE_NOFLOOD    0x400000000LLU /**< +f NoFlood */
 #define MODE_SSLCHAN    0x800000000LLU /**< +S SSL Channel */
+#define MODE_BANEXCEPTION 0x1000000000LLU /**< +e Ban exception */
 /** mode flags which take another parameter (With PARAmeterS)
  */
-#define MODE_WPARAS     (MODE_CHANOP|MODE_HALFOP|MODE_VOICE|MODE_BAN|MODE_KEY|MODE_LIMIT|MODE_APASS|MODE_UPASS|MODE_ALTCHAN|MODE_ACCESS|MODE_NOFLOOD)
+#define MODE_WPARAS     (MODE_CHANOP|MODE_HALFOP|MODE_VOICE|MODE_BAN|MODE_KEY|MODE_LIMIT|MODE_APASS|MODE_UPASS|MODE_ALTCHAN|MODE_ACCESS|MODE_NOFLOOD|MODE_BANEXCEPTION)
 
 /** Available Channel modes */
-#define infochanmodes feature_bool(FEAT_OPLEVELS) ? "AcCbhiklmMnNopsStuUvrDRzQu" : "cCbhiklmMnNopsStuvrDRzQu"
+#define infochanmodes feature_bool(FEAT_OPLEVELS) ? "AcCbehiklmMnNopsStuUvrDRzQu" : "cCbehiklmMnNopsStuvrDRzQu"
 /** Available Channel modes that take parameters */
-#define infochanmodeswithparams feature_bool(FEAT_OPLEVELS) ? "AbfhkloUvFa" : "bfhklovFa"
+#define infochanmodeswithparams feature_bool(FEAT_OPLEVELS) ? "AbefhkloUvFa" : "befhklovFa"
 
 #define HoldChannel(x)          (!(x))
 /** name invisible */
index 30e54d936cdbad663bac4d1887e561bb273cf9cb..4b144e752735da5980b1a84f16e0c25bf9643e8c 100644 (file)
@@ -268,8 +268,8 @@ extern const struct Numeric* get_error_numeric(int err);
 #define RPL_ISSUEDINVITE     345        /* Undernet extension */
 #define RPL_INVITELIST       346        /* IRCnet, Undernet extension */
 #define RPL_ENDOFINVITELIST  347        /* IRCnet, Undernet extension */
-/*      RPL_EXCEPTLIST       348           IRCnet extension */
-/*      RPL_ENDOFEXCEPTLIST  349           IRCnet extension */
+#define RPL_EXCEPTLIST       348        /* IRCnet extension */
+#define RPL_ENDOFEXCEPTLIST  349        /* IRCnet extension */
 
 #define RPL_VERSION          351
 #define RPL_WHOREPLY         352        /* See also RPL_ENDOFWHO */
index 5bbd5be1f3d30c491e9ee2ee49fa6978da345a79..87807a17a435bd5a2815238febea1fedf9ba3cee 100644 (file)
@@ -65,7 +65,7 @@
 #define FEATURESVALUES2 NICKLEN, TOPICLEN, AWAYLEN, TOPICLEN, \
                         feature_int(FEAT_CHANNELLEN), CHANNELLEN, \
                         (feature_bool(FEAT_LOCAL_CHANNELS) ? "#&" : "#"), "(ohv)@%+", "@%+", \
-                        (feature_bool(FEAT_OPLEVELS) ? "b,AkU,alfF,cCimMnNprstuDdRz" : "b,k,alfF,cCimMnNprstuDdRz"), \
+                        (feature_bool(FEAT_OPLEVELS) ? "be,AkU,alfF,cCimMnNprstuDdRz" : "be,k,alfF,cCimMnNprstuDdRz"), \
                         "rfc1459", feature_str(FEAT_NETWORK)
 
 #endif /* INCLUDED_supported_h */
index b82d8e0780b25c4e3d0f8a92cb7ff71fd72a6d63..02cdd96c52ad48fde34a1197cae6fad234022881 100644 (file)
@@ -1318,11 +1318,31 @@ static void send_ban_list(struct Client* cptr, struct Channel* chptr)
   assert(0 != chptr);
 
   for (lp = chptr->banlist; lp; lp = lp->next)
-    send_reply(cptr, RPL_BANLIST, chptr->chname, lp->banstr, lp->who, lp->when);
+    if ((lp->flags & BAN_EXCEPTION) != BAN_EXCEPTION)
+      send_reply(cptr, RPL_BANLIST, chptr->chname, lp->banstr, lp->who, lp->when);
 
   send_reply(cptr, RPL_ENDOFBANLIST, chptr->chname);
 }
 
+/** send an exception list to a client for a channel
+ *
+ * @param cptr Client to send the banlist to.
+ * @param chptr Channel whose exception list to send.
+ */
+static void send_exception_list(struct Client* cptr, struct Channel* chptr)
+{
+  struct Ban* lp;
+
+  assert(0 != cptr);
+  assert(0 != chptr);
+
+  for (lp = chptr->banlist; lp; lp = lp->next)
+    if ((lp->flags & BAN_EXCEPTION) == BAN_EXCEPTION)
+      send_reply(cptr, RPL_EXCEPTLIST, chptr->chname, lp->banstr, lp->who, lp->when);
+
+  send_reply(cptr, RPL_ENDOFEXCEPTLIST, chptr->chname);
+}
+
 /** Get a channel block, creating if necessary.
  *  Get Channel block for chname (and allocate a new channel
  *  block, if it didn't exists before).
@@ -1632,6 +1652,7 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all)
        MODE_QUARANTINE,  'Q',
        MODE_AUDITORIUM,  'u',
     MODE_SSLCHAN,     'S',
+/*     MODE_BANEXCEPTION 'e', */
     0x0, 0x0
   };
   static ulong64 local_flags[] = {
@@ -1728,14 +1749,14 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all)
           bufptr[(*bufptr_i)++] = 'v';
        totalbuflen -= IRCD_MAX(9, tmp) + 1;
       }
-    } else if (MB_TYPE(mbuf, i) & (MODE_BAN | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD)) {
+    } else if (MB_TYPE(mbuf, i) & (MODE_BAN | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD | MODE_BANEXCEPTION)) {
       tmp = strlen(MB_STRING(mbuf, i));
 
       if ((totalbuflen - tmp) <= 0) /* don't overflow buffer */
        MB_TYPE(mbuf, i) |= MODE_SAVE; /* save for later */
       else {
        char mode_char;
-       switch(MB_TYPE(mbuf, i) & (MODE_BAN | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD))
+       switch(MB_TYPE(mbuf, i) & (MODE_BAN | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD | MODE_BANEXCEPTION))
        {
          case MODE_APASS:
            mode_char = 'A';
@@ -1749,8 +1770,11 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all)
          case MODE_NOFLOOD:
                mode_char = 'f';
                break;
+      case MODE_BAN:
+        mode_char = 'b';
+           break;
          default:
-           mode_char = 'b';
+           mode_char = 'e';
            break;
        }
        bufptr[(*bufptr_i)++] = mode_char;
@@ -1826,7 +1850,7 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all)
        build_string(strptr, strptr_i, cli_name(MB_CLIENT(mbuf, i)), 0, ' ');
 
       /* deal with bans... */
-      else if (MB_TYPE(mbuf, i) & (MODE_BAN))
+      else if (MB_TYPE(mbuf, i) & (MODE_BAN | MODE_BANEXCEPTION))
        build_string(strptr, strptr_i, MB_STRING(mbuf, i), 0, ' ');
 
       /* deal with keys... */
@@ -1942,7 +1966,7 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all)
        build_string(strptr, strptr_i, NumNick(MB_CLIENT(mbuf, i)), ' ');
 
       /* deal with modes that take strings */
-      else if (MB_TYPE(mbuf, i) & (MODE_KEY | MODE_BAN | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD))
+      else if (MB_TYPE(mbuf, i) & (MODE_KEY | MODE_BAN | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD | MODE_BANEXCEPTION))
        build_string(strptr, strptr_i, MB_STRING(mbuf, i), 0, ' ');
 
       /*
@@ -2258,6 +2282,7 @@ modebuf_extract(struct ModeBuf *mbuf, char *buf)
        MODE_AUDITORIUM, 'u',
     MODE_SSLCHAN,    'S',
        MODE_NOFLOOD,   'f',
+/*  MODE_BANEXCEPTION, 'e', */
     0x0, 0x0
   };
   ulong64 add;
@@ -2369,6 +2394,7 @@ mode_invite_clear(struct Channel *chan)
 #define DONE_ALTCHAN   0x800   /**< We've set the altchan */
 #define DONE_ACCESS    0x1000  /**< We've set the access */
 #define DONE_NOFLOOD   0x2000  /**< We've set the noflood options */
+#define DONE_EXCEPTLIST 0x4000  /**< We've sent the exception list */
 
 struct ParseState {
   struct ModeBuf *mbuf;
@@ -3322,9 +3348,14 @@ mode_parse_ban(struct ParseState *state, ulong64 *flag_p)
   struct Ban *ban, *newban;
 
   if (state->parc <= 0) { /* Not enough args, send ban list */
-    if (MyUser(state->sptr) && !(state->done & DONE_BANLIST)) {
-      send_ban_list(state->sptr, state->chptr);
-      state->done |= DONE_BANLIST;
+    if (MyUser(state->sptr)) {
+      if (*flag_p == MODE_BANEXCEPTION && !(state->done & DONE_EXCEPTLIST)) {
+        send_exception_list(state->sptr, state->chptr);
+        state->done |= DONE_EXCEPTLIST;
+      } else if (*flag_p == MODE_BAN && !(state->done & DONE_BANLIST)) {
+        send_ban_list(state->sptr, state->chptr);
+        state->done |= DONE_BANLIST;
+      }
     }
     return;
   }
@@ -3390,9 +3421,9 @@ mode_process_bans(struct ParseState *state)
 
     if ((ban->flags & (BAN_DEL | BAN_ADD)) == (BAN_DEL | BAN_ADD)) {
       if (prevban)
-       prevban->next = 0; /* Break the list; ban isn't a real ban */
+        prevban->next = 0; /* Break the list; ban isn't a real ban */
       else
-       state->chptr->banlist = 0;
+        state->chptr->banlist = 0;
 
       count--;
       len -= banlen;
@@ -3401,59 +3432,57 @@ mode_process_bans(struct ParseState *state)
     } else if (ban->flags & BAN_DEL) { /* Deleted a ban? */
       char *bandup;
       DupString(bandup, ban->banstr);
-      modebuf_mode_string(state->mbuf, MODE_DEL | MODE_BAN, bandup, 1);
+      modebuf_mode_string(state->mbuf, MODE_DEL | ((ban->flags & BAN_EXCEPTION) ? MODE_BANEXCEPTION : MODE_BAN), bandup, 1);
 
       if (state->flags & MODE_PARSE_SET) { /* Ok, make it take effect */
-       if (prevban) /* clip it out of the list... */
-         prevban->next = ban->next;
-       else
-         state->chptr->banlist = ban->next;
+        if (prevban) /* clip it out of the list... */
+          prevban->next = ban->next;
+        else
+          state->chptr->banlist = ban->next;
 
-       count--;
-       len -= banlen;
+        count--;
+        len -= banlen;
         free_ban(ban);
 
-       changed++;
-       continue; /* next ban; keep prevban like it is */
+        changed++;
+        continue; /* next ban; keep prevban like it is */
       } else
-       ban->flags &= BAN_IPMASK; /* unset other flags */
+        ban->flags &= (BAN_IPMASK | BAN_EXCEPTION); /* unset other flags */
     } else if (ban->flags & BAN_ADD) { /* adding a ban? */
       if (prevban)
-       prevban->next = 0; /* Break the list; ban isn't a real ban */
+        prevban->next = 0; /* Break the list; ban isn't a real ban */
       else
-       state->chptr->banlist = 0;
+        state->chptr->banlist = 0;
 
       /* If we're supposed to ignore it, do so. */
-      if (ban->flags & BAN_OVERLAPPED &&
-         !(state->flags & MODE_PARSE_BOUNCE)) {
-       count--;
-       len -= banlen;
+      if (ban->flags & BAN_OVERLAPPED && !(state->flags & MODE_PARSE_BOUNCE)) {
+        count--;
+        len -= banlen;
       } else {
-       if (state->flags & MODE_PARSE_SET && MyUser(state->sptr) &&
-           (len > (feature_int(FEAT_AVBANLEN) * feature_int(FEAT_MAXBANS)) ||
-            count > feature_int(FEAT_MAXBANS))) {
-         send_reply(state->sptr, ERR_BANLISTFULL, state->chptr->chname,
-                    ban->banstr);
-         count--;
-         len -= banlen;
-       } else {
+        if (state->flags & MODE_PARSE_SET && MyUser(state->sptr) &&
+            (len > (feature_int(FEAT_AVBANLEN) * feature_int(FEAT_MAXBANS)) ||
+            count > feature_int(FEAT_MAXBANS))) {
+          send_reply(state->sptr, ERR_BANLISTFULL, state->chptr->chname, ban->banstr);
+          count--;
+          len -= banlen;
+        } else {
           char *bandup;
-         /* add the ban to the buffer */
+          /* add the ban to the buffer */
           DupString(bandup, ban->banstr);
-          modebuf_mode_string(state->mbuf, MODE_ADD | MODE_BAN, bandup, 1);
+          modebuf_mode_string(state->mbuf, MODE_ADD | ((ban->flags & BAN_EXCEPTION) ? MODE_BANEXCEPTION : MODE_BAN), bandup, 1);
 
-         if (state->flags & MODE_PARSE_SET) { /* create a new ban */
-           newban = make_ban(ban->banstr);
+          if (state->flags & MODE_PARSE_SET) { /* create a new ban */
+            newban = make_ban(ban->banstr);
             strcpy(newban->who, ban->who);
-           newban->when = ban->when;
-           newban->flags = ban->flags & BAN_IPMASK;
+            newban->when = ban->when;
+            newban->flags = ban->flags & (BAN_IPMASK | BAN_EXCEPTION);
 
-           newban->next = state->chptr->banlist; /* and link it in */
-           state->chptr->banlist = newban;
+            newban->next = state->chptr->banlist; /* and link it in */
+            state->chptr->banlist = newban;
 
-           changed++;
-         }
-       }
+            changed++;
+          }
+        }
       }
     }
 
@@ -3802,6 +3831,7 @@ mode_parse(struct ModeBuf *mbuf, struct Client *cptr, struct Client *sptr,
        MODE_AUDITORIUM,    'u',
     MODE_SSLCHAN,       'S',
        MODE_NOFLOOD,       'f',
+    MODE_BANEXCEPTION,  'e',
     MODE_ADD,          '+',
     MODE_DEL,          '-',
     0x0, 0x0
@@ -3892,6 +3922,7 @@ mode_parse(struct ModeBuf *mbuf, struct Client *cptr, struct Client *sptr,
        mode_parse_upass(&state, flag_p);
        break;
       case 'b': /* deal with bans */
+      case 'e': /* and exceptions */
        mode_parse_ban(&state, flag_p);
         break;
 
index 26955743a3b84318bcf8e7456452172cd8a813c3..2e02bb0253ca9acf7baf31c3d313a7eb7e3991f1 100644 (file)
@@ -128,6 +128,7 @@ do_clearmode(struct Client *cptr, struct Client *sptr, struct Channel *chptr,
     MODE_NOCOLOUR,      'c',
     MODE_NOCTCP,        'C',
     MODE_NOAMSGS,       'M',
+    MODE_BANEXCEPTION,  'e',
     0x0, 0x0
   };
   int *flag_p;
@@ -194,12 +195,12 @@ do_clearmode(struct Client *cptr, struct Client *sptr, struct Channel *chptr,
   }
 
   /* Deal with users on the channel */
-  if (del_mode & (MODE_BAN | MODE_CHANOP | MODE_HALFOP | MODE_VOICE))
+  if (del_mode & (MODE_BAN | MODE_BANEXCEPTION | MODE_CHANOP | MODE_HALFOP | MODE_VOICE))
     for (member = chptr->members; member; member = member->next_member) {
       if (IsZombie(member)) /* we ignore zombies */
        continue;
 
-      if (del_mode & MODE_BAN) /* If we cleared bans, clear the valid flags */
+      if (del_mode & (MODE_BAN | MODE_BANEXCEPTION)) /* If we cleared bans, clear the valid flags */
        ClearBanValid(member);
 
       /* Drop channel operator status */
@@ -285,7 +286,7 @@ int
 mo_clearmode(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
 {
   struct Channel *chptr;
-  char *control = "ovpsmikbl"; /* default control string */
+  char *control = "ovpsmikble"; /* default control string */
   const char *chname, *qreason;
   int force = 0;
 
index cc9ccf88f933c8970d6cd932819339d175532a11..e5531d7cd85a0817a1088f02f5b5ba3974cbb736 100644 (file)
@@ -728,9 +728,9 @@ static Numeric replyTable[] = {
 /* 347 */
   { RPL_ENDOFINVITELIST, ":End of Invite List", "347" },
 /* 348 */
-  { 0 },
+  { RPL_EXCEPTLIST, "%s %s %s %Tu", "348" },
 /* 349 */
-  { 0 },
+  { RPL_ENDOFEXCEPTLIST, "%s :End of Channel Exception List", "349" },
 /* 350 */
   { 0 },
 /* 351 */