RPL_WHOREPLY messages generated by IRC_WHO don't include flags (*,@,+) that should appear according to this description:
http://www.mishscript.de/reference/rawhelp3.htm#raw352
Other IRC servers do include the flags.
The following patch modifies who-away-test.e to expose missing flags, modifies ngircd-test.conf to accommodate who-away-test.e, and modifies irc-info.c to correct these problems.
Two additional notes:
(1) The modifications to irc-info.c on lines 767-772 create even more code duplicated in both IRC_WHO and IRC_Send_WHO. These functions could probably benefit from some refactoring.
(2) The file who-away-test.e, especially as modified here, would probably be more accurately called simply who-test.e.
Dana
--- ngircd-CVSHEAD/src/testsuite/who-away-test.e 2008-02-11 03:06:32.000000000 -0800 +++ ngircd-WHO-fixes/src/testsuite/who-away-test.e 2008-02-16 11:55:58.000000000 -0800 @@ -16,19 +16,19 @@ expect { send "who\r" expect { timeout { exit 1 } - ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name" + ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name" }
-send "who 0\r" +send "join #channel\r" expect { timeout { exit 1 } - ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name" + "@* JOIN :#channel" }
-send "who *\r" +send "who 0\r" expect { timeout { exit 1 } - ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name" + ":ngircd.test.server 352 nick #channel ~user localhost ngircd.test.server nick H@ :0 Real Name" }
send "away :testing\r" @@ -37,28 +37,62 @@ expect { "306 nick" }
+send "who *\r" +expect { + timeout { exit 1 } + ":ngircd.test.server 352 nick #channel ~user localhost ngircd.test.server nick G@ :0 Real Name" +} + +send "mode #channel +v nick\r" +expect { + timeout { exit 1 } + "@* MODE #channel +v nick\r" +} + send "who localhost\r" expect { timeout { exit 1 } - ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick G :0 Real Name" + ":ngircd.test.server 352 nick #channel ~user localhost ngircd.test.server nick G@ :0 Real Name" +} + +send "mode #channel -o nick\r" +expect { + timeout { exit 1 } + "@* MODE #channel -o nick\r" }
send "who ngircd.test.server\r" expect { timeout { exit 1 } - ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick G :0 Real Name" + ":ngircd.test.server 352 nick #channel ~user localhost ngircd.test.server nick G+ :0 Real Name" +} + +send "part #channel\r" +expect { + timeout { exit 1 } + "@* PART #channel :nick" }
send "who Real?Name\r" expect { timeout { exit 1 } - ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick G :0 Real Name" + ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick G :0 Real Name" }
-send "who nick\r" +send "oper TestOp 123\r" +expect { + timeout { exit 1 } + "MODE nick :+o" +} expect { timeout { exit 1 } - ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick G :0 Real Name" + "381 nick" +} + +send "who 0 o\r" +expect { + timeout { exit 1 } + ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick G* :0 Real Name" }
send "away\r" @@ -70,25 +104,55 @@ expect { send "who *cal*ho??\r" expect { timeout { exit 1 } - ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name" + ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H* :0 Real Name" +} + +send "join #opers\r" +expect { + timeout { exit 1 } + "@* JOIN :#opers" +} + +send "who #opers\r" +expect { + timeout { exit 1 } + ":ngircd.test.server 352 nick #opers ~user localhost ngircd.test.server nick H*@ :0 Real Name" +} + +send "mode #opers -o nick\r" +expect { + timeout { exit 1 } + "@* MODE #opers -o nick\r" }
send "who *.server\r" expect { timeout { exit 1 } - ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name" + ":ngircd.test.server 352 nick #opers ~user localhost ngircd.test.server nick H* :0 Real Name" +} + +send "mode #opers +v nick\r" +expect { + timeout { exit 1 } + "@* MODE #opers +v nick\r" }
send "who Real*me\r" expect { timeout { exit 1 } - ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name" + ":ngircd.test.server 352 nick #opers ~user localhost ngircd.test.server nick H*+ :0 Real Name" +} + +send "mode #opers +s\r" +expect { + timeout { exit 1 } + "@* MODE #opers +s\r" }
send "who n?c?\r" expect { timeout { exit 1 } - ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name" + ":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H* :0 Real Name" }
send "quit\r" --- ngircd-CVSHEAD/src/testsuite/ngircd-test.conf 2007-11-18 07:07:16.000000000 -0800 +++ ngircd-WHO-fixes/src/testsuite/ngircd-test.conf 2008-02-16 11:53:36.000000000 -0800 @@ -9,6 +9,7 @@ MaxConnectionsIP = 0 ServerUID = 1 ServerGID = 1 + OperCanUseMode = yes
[Operator] Name = TestOp --- ngircd-CVSHEAD/src/ngircd/irc-info.c 2008-02-11 15:15:21.000000000 -0800 +++ ngircd-WHO-fixes/src/ngircd/irc-info.c 2008-02-16 11:05:16.000000000 -0800 @@ -671,7 +671,7 @@ GLOBAL bool IRC_WHO( CLIENT *Client, REQUEST *Req ) { bool only_ops, have_arg, client_match; - const char *channelname, *client_modes; + const char *channelname, *client_modes, *chan_user_modes; char pattern[COMMAND_LEN]; char flags[4]; CL2CHAN *cl2chan; @@ -748,7 +748,7 @@ IRC_WHO( CLIENT *Client, REQUEST *Req ) else strcpy(flags, "H");
- if (only_ops) /* this client is an operator */ + if (strchr(client_modes, 'o')) /* this client is an operator */ strlcat(flags, "*", sizeof(flags));
/* Search suitable channel */ @@ -763,7 +763,14 @@ IRC_WHO( CLIENT *Client, REQUEST *Req ) } cl2chan = Channel_NextChannelOf(c, cl2chan); } - if (!cl2chan) + if (cl2chan) { + chan = Channel_GetChannel(cl2chan); + chan_user_modes = Channel_UserModes(chan, c); + if (strchr(chan_user_modes, 'o')) + strlcat(flags, "@", sizeof(flags)); + else if (strchr(chan_user_modes, 'v')) + strlcat(flags, "+", sizeof(flags)); + } else channelname = "*";
if (!write_whoreply(Client, c, channelname, flags))
Dana Dahlstrom dana+70@cs.ucsd.edu wrote:
RPL_WHOREPLY messages generated by IRC_WHO don't include flags (*,@,+) that should appear according to this description:
You're right; also applied.
Alex, this is getting silly as CVS cannot properly track individual patch authors; this would IMO work much better if we'd switch over to git.
(1) The modifications to irc-info.c on lines 767-772 create even more code duplicated in both IRC_WHO and IRC_Send_WHO. These functions could probably benefit from some refactoring.
Yes. I'll look at this again tomorrow.
(2) The file who-away-test.e, especially as modified here, would probably be more accurately called simply who-test.e.
Indeed, i renamed it (another thing which git does much better...).