Under some circumstances ngIRCd currently issues a channel MODE message with a trailing space after the last parameter, which isn't permitted by the grammar in RFC 2812 section 2.3.1:
http://tools.ietf.org/html/rfc2812#section-2.3.1
The following patch modifies mode-test.e to expose this, and modifies irc-mode.c to correct it.
Dana
diff -pru ngircd-CVSHEAD/src/ngircd/irc-mode.c ngircd-mode-fix/src/ngircd/irc-mode.c --- ngircd-CVSHEAD/src/ngircd/irc-mode.c 2007-10-14 05:08:57.000000000 -0700 +++ ngircd-mode-fix/src/ngircd/irc-mode.c 2008-02-15 19:30:14.000000000 -0800 @@ -317,7 +317,7 @@ Channel_Mode( CLIENT *Client, REQUEST *R /* Prepare reply string */ if( set ) strcpy( the_modes, "+" ); else strcpy( the_modes, "-" ); - strcpy( the_args, " " ); + the_args[0] = '\0';
x[1] = '\0'; ok = CONNECTED; @@ -528,8 +528,8 @@ Channel_Mode( CLIENT *Client, REQUEST *R /* Channel-User-Mode */ if( Channel_UserModeAdd( Channel, client, x[0] )) { - strlcat( the_args, Client_ID( client ), sizeof( the_args )); strlcat( the_args, " ", sizeof( the_args )); + strlcat( the_args, Client_ID( client ), sizeof( the_args )); strlcat( the_modes, x, sizeof( the_modes )); Log( LOG_DEBUG, "User "%s": Mode change on %s, now "%s"", Client_Mask( client ), Channel_Name( Channel ), Channel_UserModes( Channel, client )); } @@ -552,8 +552,8 @@ Channel_Mode( CLIENT *Client, REQUEST *R /* Channel-User-Mode */ if( Channel_UserModeDel( Channel, client, x[0] )) { - strlcat( the_args, Client_ID( client ), sizeof( the_args )); strlcat( the_args, " ", sizeof( the_args )); + strlcat( the_args, Client_ID( client ), sizeof( the_args )); strlcat( the_modes, x, sizeof( the_modes )); Log( LOG_DEBUG, "User "%s": Mode change on %s, now "%s"", Client_Mask( client ), Channel_Name( Channel ), Channel_UserModes( Channel, client )); } @@ -572,8 +572,7 @@ Channel_Mode( CLIENT *Client, REQUEST *R /* Are there additional arguments to add? */ if( argadd[0] ) { - len = strlen( the_args ) - 1; - if( the_args[len] != ' ' ) strlcat( the_args, " ", sizeof( the_args )); + strlcat( the_args, " ", sizeof( the_args )); strlcat( the_args, argadd, sizeof( the_args )); } } @@ -586,9 +585,6 @@ chan_exit: len = strlen( the_modes ) - 1; if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' )) the_modes[len] = '\0';
- /* Clean up argument string if there are none */ - if( ! the_args[1] ) the_args[0] = '\0'; - if( Client_Type( Client ) == CLIENT_SERVER ) { /* Forward mode changes to channel users and other servers */ diff -pru ngircd-CVSHEAD/src/testsuite/mode-test.e ngircd-mode-fix/src/testsuite/mode-test.e --- ngircd-CVSHEAD/src/testsuite/mode-test.e 2004-03-10 12:40:06.000000000 -0800 +++ ngircd-mode-fix/src/testsuite/mode-test.e 2008-02-15 19:33:48.000000000 -0800 @@ -72,7 +72,7 @@ expect { send "mode #channel +v nick\r" expect { timeout { exit 1 } - "@* MODE #channel +v nick" + "@* MODE #channel +v nick\r" }
send "mode #channel +I nick1\r" @@ -96,7 +96,7 @@ expect { send "mode #channel -vo nick nick\r" expect { timeout { exit 1 } - "@* MODE #channel -vo nick nick" + "@* MODE #channel -vo nick nick\r" }
send "quit\r"