Fix various mode-related bugs (including SF#2964782 and SF#2966959).
authorMichael Poole <mdpoole@troilus.org>
Mon, 15 Mar 2010 01:40:24 +0000 (21:40 -0400)
committerMichael Poole <mdpoole@troilus.org>
Mon, 15 Mar 2010 01:40:24 +0000 (21:40 -0400)
src/chanserv.c (cmd_mode): Use MCP_NO_APASS, and unparse the mode
    change for display.
  (chan_opt_usergreeting): Use MCP_NO_APASS here too.
  (chanserv_conf_read): Likewise.
  (chanserv_channel_read): Likewise.

src/opserv.c (cmd_kick): Do not let users try to kick services.

src/proto.h (MCP_NO_APASS): New flag.

src/proto-p10.c (irc_user_mode_chars): Allow displaying +x.
  (mod_usermode): Treat +h as setting +x also.
  (mod_chanmode_parse): Reject +A and +U when passed MCP_NO_APASS.

src/chanserv.c
src/opserv.c
src/proto-p10.c
src/proto.h

index a9f8ad11e2f0dcf2500ffca0e20f852ce2dd94a9..421da74d69eb26342f52d01af523fbb238c9183d 100644 (file)
@@ -4211,6 +4211,7 @@ static CHANSERV_FUNC(cmd_mode)
     struct userData *uData;
     struct mod_chanmode *change;
     short base_oplevel;
+    char fmt[MAXLEN];
 
     if(argc < 2)
     {
@@ -4230,7 +4231,7 @@ static CHANSERV_FUNC(cmd_mode)
         base_oplevel = 1;
     else
         base_oplevel = 1 + UL_OWNER - uData->access;
-    change = mod_chanmode_parse(channel, argv+1, argc-1, MCP_KEY_FREE|MCP_REGISTERED, base_oplevel);
+    change = mod_chanmode_parse(channel, argv+1, argc-1, MCP_KEY_FREE|MCP_REGISTERED|MCP_NO_APASS, base_oplevel);
     if(!change)
     {
         reply("MSG_INVALID_MODES", unsplit_string(argv+1, argc-1, NULL));
@@ -4247,8 +4248,9 @@ static CHANSERV_FUNC(cmd_mode)
     }
 
     modcmd_chanmode_announce(change);
+    mod_chanmode_format(change, fmt);
     mod_chanmode_free(change);
-    reply("CSMSG_MODES_SET", unsplit_string(argv+1, argc-1, NULL));
+    reply("CSMSG_MODES_SET", fmt);
     return 1;
 }
 
@@ -5407,7 +5409,7 @@ static MODCMD_FUNC(chan_opt_usergreeting)
 static MODCMD_FUNC(chan_opt_modes)
 {
     struct mod_chanmode *new_modes;
-    char modes[MODELEN];
+    char modes[MAXLEN];
 
     if(argc > 1)
     {
@@ -5420,7 +5422,7 @@ static MODCMD_FUNC(chan_opt_modes)
         {
             memset(&channel->channel_info->modes, 0, sizeof(channel->channel_info->modes));
         }
-        else if(!(new_modes = mod_chanmode_parse(channel, argv+1, argc-1, MCP_KEY_FREE|MCP_REGISTERED, 0)))
+        else if(!(new_modes = mod_chanmode_parse(channel, argv+1, argc-1, MCP_KEY_FREE|MCP_REGISTERED|MCP_NO_APASS, 0)))
         {
             reply("CSMSG_INVALID_MODE_LOCK", unsplit_string(argv+1, argc-1, NULL));
             return 0;
@@ -7057,7 +7059,7 @@ chanserv_conf_read(void)
         str = "+nt";
     safestrncpy(mode_line, str, sizeof(mode_line));
     ii = split_line(mode_line, 0, ArrayLength(modes), modes);
-    if((change = mod_chanmode_parse(NULL, modes, ii, MCP_KEY_FREE, 0))
+    if((change = mod_chanmode_parse(NULL, modes, ii, MCP_KEY_FREE|MCP_NO_APASS, 0))
        && (change->argc < 2))
     {
         chanserv_conf.default_modes = *change;
@@ -7424,7 +7426,7 @@ chanserv_channel_read(const char *key, struct record_data *hir)
     if(!IsSuspended(cData)
        && (str = database_get_data(channel, KEY_MODES, RECDB_QSTRING))
        && (argc = split_line(str, 0, ArrayLength(argv), argv))
-       && (modes = mod_chanmode_parse(cNode, argv, argc, MCP_KEY_FREE, 0))) {
+       && (modes = mod_chanmode_parse(cNode, argv, argc, MCP_KEY_FREE|MCP_NO_APASS, 0))) {
         cData->modes = *modes;
         if(off_channel > 0)
           cData->modes.modes_set |= MODE_REGISTERED;
index f9af6bb80ad8e61098e66f4fe1ddd0460217314d..d7bddd5213044ce0036a73a2691216daae7a0021 100644 (file)
@@ -1022,6 +1022,10 @@ static MODCMD_FUNC(cmd_kick)
         reply("OSMSG_NOT_ON_CHANNEL", target->nick, channel->name);
         return 0;
     }
+    if (IsService(target)) {
+        reply("MSG_SERVICE_IMMUNE", target->nick);
+        return 0;
+    }
     KickChannelUser(target, channel, cmd->parent->bot, reason);
     return 1;
 }
index 6509fabb6cf61151cf8e541de3aa513e1bece9e3..3d291a5bbd50594ab728e9eb9e89c9ff2fc367ab 100644 (file)
@@ -294,7 +294,7 @@ static const char *his_servercomment;
 static struct channelList dead_channels;
 
 /* These correspond to 1 << X:      012345678901234567 */
-const char irc_user_mode_chars[] = "o iw dkgn        I";
+const char irc_user_mode_chars[] = "o iw dkgn    x   I";
 
 static struct userNode *AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *numeric, const char *userinfo, unsigned long timestamp, const char *realip);
 
@@ -2322,6 +2322,7 @@ void mod_usermode(struct userNode *user, const char *mode_change) {
                 char mask[MAXLEN];
                 char *host, *ident;
                 unsigned int ii;
+
                 for (ii=0; (*word != ' ') && (*word != '\0'); )
                     mask[ii++] = *word++;
                 mask[ii] = 0;
@@ -2335,6 +2336,7 @@ void mod_usermode(struct userNode *user, const char *mode_change) {
                     ident = NULL;
                     host = mask;
                 }
+                user->modes |= FLAGS_HIDDEN_HOST;
                 assign_fakehost(user, host, ident, 0, 0);
             }
             break;
@@ -2431,6 +2433,8 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
             }
             break;
         case 'U':
+            if (flags & MCP_NO_APASS)
+                goto error;
             if (add)
             {
                 if ((in_arg >= argc)
@@ -2447,6 +2451,8 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
             }
             break;
         case 'A':
+            if (flags & MCP_NO_APASS)
+                goto error;
             if (add) {
                 if ((in_arg >= argc)
                     || keyncpy(change->new_apass, modes[in_arg++], sizeof(change->new_apass)))
index 3d8e2e74083b30d637b3ad0c2609d10a36250600..99ca1099703fddf03aa3fd6b69d0e93de99dea48 100644 (file)
@@ -210,6 +210,7 @@ struct mod_chanmode {
 #define MCP_REGISTERED    0x0008 /* chan is already registered; do not allow changes to MODE_REGISTERED */
 #define MCP_UPASS_FREE    0x0010 /* -U without a key argument */
 #define MCP_APASS_FREE    0x0020 /* -A without a key argument */
+#define MCP_NO_APASS      0x0040 /* Do not allow +/-A or +/-U */
 #define MC_ANNOUNCE       0x0100 /* send a mod_chanmode() change out */
 #define MC_NOTIFY         0x0200 /* make local callbacks to announce */
 #ifdef NDEBUG