mirror of
https://github.com/osmarks/ngircd.git
synced 2026-10-04 23:01:44 +00:00
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.
This commit is contained in:
committed by
Florian Westphal
parent
1784180bf3
commit
2f71fbb2a1
@@ -11,6 +11,9 @@
|
|||||||
|
|
||||||
|
|
||||||
ngIRCd HEAD
|
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
|
- Under some circumstances ngIRCd issued
|
||||||
channel MODE messages with a trailing space. (Dana Dahlstrom)
|
channel MODE messages with a trailing space. (Dana Dahlstrom)
|
||||||
- IRC_WHO now supports search patterns and will test this
|
- 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 $
|
||||||
|
|||||||
+32
-16
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
#include "portab.h"
|
#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 "imp.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@@ -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
|
static bool
|
||||||
IRC_Send_WHO(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
|
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;
|
is_visible = strchr(client_modes, 'i') == NULL;
|
||||||
if (is_member || is_visible) {
|
if (is_member || is_visible) {
|
||||||
if (strchr(client_modes, 'a'))
|
strcpy(flags, who_flags_status(client_modes));
|
||||||
strcpy(flags, "G"); /* away */
|
|
||||||
else
|
|
||||||
strcpy(flags, "H");
|
|
||||||
if (is_ircop)
|
if (is_ircop)
|
||||||
strlcat(flags, "*", sizeof(flags));
|
strlcat(flags, "*", sizeof(flags));
|
||||||
|
|
||||||
chan_user_modes = Channel_UserModes(Chan, c);
|
chan_user_modes = Channel_UserModes(Chan, c);
|
||||||
if (strchr(chan_user_modes, 'o'))
|
strlcat(flags, who_flags_qualifier(chan_user_modes), sizeof(flags));
|
||||||
strlcat(flags, "@", sizeof(flags));
|
|
||||||
else if (strchr(chan_user_modes, 'v'))
|
|
||||||
strlcat(flags, "+", sizeof(flags));
|
|
||||||
|
|
||||||
if (!write_whoreply(Client, c, Channel_Name(Chan), flags))
|
if (!write_whoreply(Client, c, Channel_Name(Chan), flags))
|
||||||
return DISCONNECTED;
|
return DISCONNECTED;
|
||||||
@@ -654,6 +668,7 @@ IRC_Send_WHO(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
|
|||||||
} /* IRC_Send_WHO */
|
} /* IRC_Send_WHO */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
MatchCaseInsensitive(const char *pattern, const char *searchme)
|
MatchCaseInsensitive(const char *pattern, const char *searchme)
|
||||||
{
|
{
|
||||||
@@ -671,7 +686,7 @@ GLOBAL bool
|
|||||||
IRC_WHO( CLIENT *Client, REQUEST *Req )
|
IRC_WHO( CLIENT *Client, REQUEST *Req )
|
||||||
{
|
{
|
||||||
bool only_ops, have_arg, client_match;
|
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 pattern[COMMAND_LEN];
|
||||||
char flags[4];
|
char flags[4];
|
||||||
CL2CHAN *cl2chan;
|
CL2CHAN *cl2chan;
|
||||||
@@ -743,12 +758,9 @@ IRC_WHO( CLIENT *Client, REQUEST *Req )
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strchr(client_modes, 'a'))
|
strcpy(flags, who_flags_status(client_modes));
|
||||||
strcpy(flags, "G"); /* user is away */
|
|
||||||
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));
|
strlcat(flags, "*", sizeof(flags));
|
||||||
|
|
||||||
/* Search suitable channel */
|
/* Search suitable channel */
|
||||||
@@ -763,7 +775,11 @@ IRC_WHO( CLIENT *Client, REQUEST *Req )
|
|||||||
}
|
}
|
||||||
cl2chan = Channel_NextChannelOf(c, cl2chan);
|
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 = "*";
|
channelname = "*";
|
||||||
|
|
||||||
if (!write_whoreply(Client, c, channelname, flags))
|
if (!write_whoreply(Client, c, channelname, flags))
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||||
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
# 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
|
AUTOMAKE_OPTIONS = ../portab/ansi2knr
|
||||||
@@ -21,7 +21,7 @@ EXTRA_DIST = \
|
|||||||
start-server.sh stop-server.sh tests.sh stress-server.sh \
|
start-server.sh stop-server.sh tests.sh stress-server.sh \
|
||||||
test-loop.sh wait-tests.sh \
|
test-loop.sh wait-tests.sh \
|
||||||
connect-test.e channel-test.e mode-test.e \
|
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 \
|
stress-A.e stress-B.e check-idle.e \
|
||||||
ngircd-test.conf
|
ngircd-test.conf
|
||||||
|
|
||||||
@@ -48,9 +48,9 @@ channel-test: tests.sh
|
|||||||
rm -f channel-test
|
rm -f channel-test
|
||||||
ln -s $(srcdir)/tests.sh channel-test
|
ln -s $(srcdir)/tests.sh channel-test
|
||||||
|
|
||||||
who-away-test: tests.sh
|
who-test: tests.sh
|
||||||
rm -f who-away-test
|
rm -f who-test
|
||||||
ln -s $(srcdir)/tests.sh who-away-test
|
ln -s $(srcdir)/tests.sh who-test
|
||||||
|
|
||||||
mode-test: tests.sh
|
mode-test: tests.sh
|
||||||
rm -f mode-test
|
rm -f mode-test
|
||||||
@@ -59,7 +59,7 @@ mode-test: tests.sh
|
|||||||
TESTS = start-server.sh \
|
TESTS = start-server.sh \
|
||||||
connect-test \
|
connect-test \
|
||||||
channel-test \
|
channel-test \
|
||||||
who-away-test \
|
who-test \
|
||||||
mode-test \
|
mode-test \
|
||||||
stress-server.sh \
|
stress-server.sh \
|
||||||
stop-server.sh
|
stop-server.sh
|
||||||
|
|||||||
@@ -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]
|
[Global]
|
||||||
Name = ngircd.test.server
|
Name = ngircd.test.server
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
MaxConnectionsIP = 0
|
MaxConnectionsIP = 0
|
||||||
ServerUID = 1
|
ServerUID = 1
|
||||||
ServerGID = 1
|
ServerGID = 1
|
||||||
|
OperCanUseMode = yes
|
||||||
|
|
||||||
[Operator]
|
[Operator]
|
||||||
Name = TestOp
|
Name = TestOp
|
||||||
|
|||||||
@@ -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-
|
|
||||||
@@ -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-
|
||||||
Reference in New Issue
Block a user