repo: ngircd
action: commit
revision: 
path_from: 
revision_from: 2f71fbb2a1319d1b0aca4c9564c2e51a88b4a578:
path_to: 
revision_to: 
git.thebackupbox.net
ngircd
git clone git://git.thebackupbox.net/ngircd
commit 2f71fbb2a1319d1b0aca4c9564c2e51a88b4a578
Author: Dana Dahlstrom 
Date:   Sun Feb 17 00:00:12 2008 +0000

    Include flags in RPL_WHOREPLY messages.

    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.

    Modify who-test.e to expose missing flags,
    modify ngircd-test.conf to accommodate who-test.e, and fix
    irc-info.c to correct these problems.

diff --git a/ChangeLog b/ChangeLog
index e73d4c9ad6d2538c29f7e96e90c7afa25e80f0a9..
index ..303661f0fe24c950a9c88e4826d6a70cbbe3aa90 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,9 @@


 ngIRCd HEAD
+  - RPL_WHOREPLY messages generated by IRC_WHO didn't
+    include flags (*,@,+) (Dana Dahlstrom)
+  - also add test cases for this (again, Dana)
   - Under some circumstances ngIRCd issued
   channel MODE messages with a trailing space. (Dana Dahlstrom)
   - IRC_WHO now supports search patterns and will test this
@@ -746,4 +749,4 @@ ngIRCd 0.0.1, 31.12.2001


 -- 
-$Id: ChangeLog,v 1.338 2008/02/16 11:27:48 fw Exp $
+$Id: ChangeLog,v 1.339 2008/02/17 00:00:12 fw Exp $
diff --git a/src/ngircd/irc-info.c b/src/ngircd/irc-info.c
index 1a9f7b4bf5acde5fbf0137d76720de312b5873dc..
index ..7878c5d4ab2a3459b580505df2b53b81e0f1b2e2 100644
--- a/src/ngircd/irc-info.c
+++ b/src/ngircd/irc-info.c
@@ -14,7 +14,7 @@

 #include "portab.h"

-static char UNUSED id[] = "$Id: irc-info.c,v 1.42 2008/02/11 11:06:31 fw Exp $";
+static char UNUSED id[] = "$Id: irc-info.c,v 1.43 2008/02/17 00:00:12 fw Exp $";

 #include "imp.h"
 #include 
@@ -603,6 +603,26 @@ write_whoreply(CLIENT *Client, CLIENT *c, const char *channelname, const char *f
 }


+static const char *
+who_flags_status(const char *client_modes)
+{
+	if (strchr(client_modes, 'a'))
+		return "G"; /* away */
+	return "H";
+}
+
+
+static const char *
+who_flags_qualifier(const char *chan_user_modes)
+{
+	if (strchr(chan_user_modes, 'o'))
+		return "@";
+	else if (strchr(chan_user_modes, 'v'))
+		return "+";
+	return "";
+}
+
+
 static bool
 IRC_Send_WHO(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
 {
@@ -633,18 +653,12 @@ IRC_Send_WHO(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)

 		is_visible = strchr(client_modes, 'i') == NULL;
 		if (is_member || is_visible) {
-			if (strchr(client_modes, 'a'))
-				strcpy(flags, "G"); /* away */
-			else
-				strcpy(flags, "H");
+			strcpy(flags, who_flags_status(client_modes));
 			if (is_ircop)
 				strlcat(flags, "*", sizeof(flags));

 			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));
+			strlcat(flags, who_flags_qualifier(chan_user_modes), sizeof(flags));

 			if (!write_whoreply(Client, c, Channel_Name(Chan), flags))
 				return DISCONNECTED;
@@ -654,6 +668,7 @@ IRC_Send_WHO(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
 } /* IRC_Send_WHO */


+
 static bool
 MatchCaseInsensitive(const char *pattern, const char *searchme)
 {
@@ -671,7 +686,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;
@@ -743,12 +758,9 @@ IRC_WHO( CLIENT *Client, REQUEST *Req )
 				continue;
 		}

-		if (strchr(client_modes, 'a'))
-			strcpy(flags, "G"); /* user is away */
-		else
-			strcpy(flags, "H");
+		strcpy(flags, who_flags_status(client_modes));

-		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 +775,11 @@ 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);
+			strlcat(flags, who_flags_qualifier(chan_user_modes), sizeof(flags));
+		} else
 			channelname = "*";

 		if (!write_whoreply(Client, c, channelname, flags))
diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am
index 58a617ee61b858705b4cf2bea7b6413639b8cf89..
index ..6ea9597c2596f53925ec94dcf108b913a59e18e6 100644
--- a/src/testsuite/Makefile.am
+++ b/src/testsuite/Makefile.am
@@ -9,7 +9,7 @@
 # Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
 # der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
 #
-# $Id: Makefile.am,v 1.16 2008/02/11 11:06:32 fw Exp $
+# $Id: Makefile.am,v 1.17 2008/02/17 00:00:13 fw Exp $
 #

 AUTOMAKE_OPTIONS = ../portab/ansi2knr
@@ -21,7 +21,7 @@ EXTRA_DIST = \
 	start-server.sh stop-server.sh tests.sh stress-server.sh \
 	test-loop.sh wait-tests.sh \
 	connect-test.e channel-test.e mode-test.e \
-	who-away-test.e
+	who-test.e
 	stress-A.e stress-B.e check-idle.e \
 	ngircd-test.conf

@@ -48,9 +48,9 @@ channel-test: tests.sh
 	rm -f channel-test
 	ln -s $(srcdir)/tests.sh channel-test

-who-away-test: tests.sh
-	rm -f who-away-test
-	ln -s $(srcdir)/tests.sh who-away-test
+who-test: tests.sh
+	rm -f who-test
+	ln -s $(srcdir)/tests.sh who-test

 mode-test: tests.sh
 	rm -f mode-test
@@ -59,7 +59,7 @@ mode-test: tests.sh
 TESTS = start-server.sh \
 	connect-test \
 	channel-test \
-	who-away-test \
+	who-test \
 	mode-test \
 	stress-server.sh \
 	stop-server.sh
diff --git a/src/testsuite/ngircd-test.conf b/src/testsuite/ngircd-test.conf
index 3f0ffe95d29e312ed1fe673a6c38a2c4f79438da..
index ..5b1fbe3353c6c4c5949b511a426125a9e888fd8e 100644
--- a/src/testsuite/ngircd-test.conf
+++ b/src/testsuite/ngircd-test.conf
@@ -1,4 +1,4 @@
-# $Id: ngircd-test.conf,v 1.5 2007/11/18 15:07:16 alex Exp $
+# $Id: ngircd-test.conf,v 1.6 2008/02/17 00:00:13 fw Exp $

 [Global]
 	Name = ngircd.test.server
@@ -9,6 +9,7 @@
 	MaxConnectionsIP = 0
 	ServerUID = 1
 	ServerGID = 1
+	OperCanUseMode = yes

 [Operator]
 	Name = TestOp
diff --git a/src/testsuite/who-away-test.e b/src/testsuite/who-away-test.e
deleted file mode 100644
index e5e442a079f3dba31188d12983f792669023bee5..0000000000000000000000000000000000000000
--- a/src/testsuite/who-away-test.e
+++ /dev/null
@@ -1,100 +0,0 @@
-# $Id: who-away-test.e,v 1.1 2008/02/11 11:06:32 fw Exp $
-
-spawn telnet localhost 6789
-expect {
-	timeout { exit 1 }
-	"Connected"
-}
-
-send "nick nick\r"
-send "user user . . :Real Name\r"
-expect {
-	timeout { exit 1 }
-	"376"
-}
-
-send "who\r"
-expect {
-	timeout { exit 1 }
-	":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name"
-}
-
-send "who 0\r"
-expect {
-	timeout { exit 1 }
-	":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name"
-}
-
-send "who *\r"
-expect {
-	timeout { exit 1 }
-	":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name"
-}
-
-send "away :testing\r"
-expect {
-	timeout { exit 1 }
-	"306 nick"
-}
-
-send "who localhost\r"
-expect {
-	timeout { exit 1 }
-	":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick G :0 Real Name"
-}
-
-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"
-}
-
-send "who Real?Name\r"
-expect {
-	timeout { exit 1 }
-	":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick G :0 Real Name"
-}
-
-send "who nick\r"
-expect {
-	timeout { exit 1 }
-	":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick G :0 Real Name"
-}
-
-send "away\r"
-expect {
-	timeout { exit 1 }
-	"305 nick"
-}
-
-send "who *cal*ho??\r"
-expect {
-	timeout { exit 1 }
-	":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name"
-}
-
-send "who *.server\r"
-expect {
-	timeout { exit 1 }
-	":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name"
-}
-
-send "who Real*me\r"
-expect {
-	timeout { exit 1 }
-	":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name"
-}
-
-send "who n?c?\r"
-expect {
-	timeout { exit 1 }
-	":ngircd.test.server 352 nick * ~user localhost ngircd.test.server nick H :0 Real Name"
-}
-
-send "quit\r"
-expect {
-	timeout { exit 1 }
-	"Connection closed"
-}
-
-# -eof-
diff --git a/src/testsuite/who-test.e b/src/testsuite/who-test.e
new file mode 100644
index 0000000000000000000000000000000000000000..c54a190f843c4f7752ebaa8aff1ab937c7c8aa96
--- /dev/null
+++ b/src/testsuite/who-test.e
@@ -0,0 +1,162 @@
+spawn telnet localhost 6789
+expect {
+	timeout { exit 1 }
+	"Connected"
+}
+
+send "nick nick\r"
+send "user user . . :Real Name\r"
+expect {
+	timeout { exit 1 }
+	"376"
+}
+
+send "who\r"
+expect {
+	timeout { exit 1 }
+	":ngircd.test.server 352 nick \* ~user localhost ngircd.test.server nick H :0 Real Name"
+}
+
+send "join #channel\r"
+expect {
+	timeout { exit 1 }
+	"@* JOIN :#channel"
+}
+
+send "who 0\r"
+expect {
+	timeout { exit 1 }
+	":ngircd.test.server 352 nick #channel ~user localhost ngircd.test.server nick H@ :0 Real Name"
+}
+
+send "away :testing\r"
+expect {
+	timeout { exit 1 }
+	"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 #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 #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"
+}
+
+send "oper TestOp 123\r"
+expect {
+	timeout { exit 1 }
+	"MODE nick :+o"
+}
+expect {
+	timeout { exit 1 }
+	"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"
+expect {
+	timeout { exit 1 }
+	"305 nick"
+}
+
+send "who *cal*ho??\r"
+expect {
+	timeout { exit 1 }
+	":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 #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 #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"
+}
+
+send "quit\r"
+expect {
+	timeout { exit 1 }
+	"Connection closed"
+}
+
+# -eof-

-----END OF PAGE-----