repo: ngircd action: commit revision: path_from: revision_from: 3d8eda9c860cbcbf195fe2242c67dd57fe966b3e: path_to: revision_to:
commit 3d8eda9c860cbcbf195fe2242c67dd57fe966b3e Author: Bryan CaldwellDate: Mon May 5 16:04:48 2008 +0200 Allow KICK to handle comma-delimited lists (of channels, nicks). includes test cases. [fw@strlen.de: - move code around to avoid duplication - use const where possible - integrate test case] diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,8 @@
ngIRCd-dev
+ - Fixed Bug 75: KICK now handles comma-delimited lists.
+ (Brandon Beresini, Bryan Caldwell)
- Fixed Bug 83: ngIRCd chokes on 1-character messages.
- Add support for modeless channels ("+channels").
(Bryan Caldwell, Ali Shemiran)
diff --git a/src/ngircd/irc-op.c b/src/ngircd/irc-op.c
--- a/src/ngircd/irc-op.c +++ b/src/ngircd/irc-op.c @@ -14,8 +14,6 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-op.c,v 1.17 2006/12/07 17:57:20 fw Exp $"; - #include "imp.h" #include#include @@ -35,28 +33,96 @@ static char UNUSED id[] = "$Id: irc-op.c,v 1.17 2006/12/07 17:57:20 fw Exp $"; #include "irc-op.h" +static bool +try_kick(CLIENT* from, const char *nick, const char *channel, const char *reason) +{ + CLIENT *target = Client_Search(nick); + + if (!target) + return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG, Client_ID(from), nick); + + Channel_Kick(target, from, channel, reason); + return true; +} + + GLOBAL bool -IRC_KICK( CLIENT *Client, REQUEST *Req ) +IRC_KICK(CLIENT *Client, REQUEST *Req) { - CLIENT *target, *from; - + CLIENT *from; + char *itemList = Req->argv[0]; + const char* currentNick, *currentChannel, *reason; + unsigned int channelCount = 1; + unsigned int nickCount = 1; + assert( Client != NULL ); assert( Req != NULL ); - /* Falsche Anzahl Parameter? */ - if(( Req->argc < 2) || ( Req->argc > 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + if ((Req->argc < 2) || (Req->argc > 3)) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); + + while (*itemList) { + if (*itemList == ',') { + *itemList = '\0'; + channelCount++; + } + itemList++; + } - if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix ); - else from = Client; - if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix ); - - /* Ziel-User suchen */ - target = Client_Search( Req->argv[1] ); - if( ! target ) return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( from ), Req->argv[1] ); + itemList = Req->argv[1]; + while (*itemList) { + if (*itemList == ',') { + *itemList = '\0'; + nickCount++; + } + itemList++; + } - Channel_Kick( target, from, Req->argv[0], Req->argc == 3 ? Req->argv[2] : Client_ID( from )); - return CONNECTED; -} /* IRC_KICK */ + if (Client_Type(Client) == CLIENT_SERVER) + from = Client_Search(Req->prefix); + else + from = Client; + + if (!from) + return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + Client_ID(Client), Req->prefix); + + reason = Req->argc == 3 ? Req->argv[2] : Client_ID(from); + currentNick = Req->argv[1]; + currentChannel = Req->argv[0]; + if (channelCount == 1) { + while (nickCount > 0) { + if (!try_kick(from, currentNick, currentChannel, reason)) + return false; + + while (*currentNick) + currentNick++; + + currentNick++; + nickCount--; + } + } else if (channelCount == nickCount) { + while (nickCount > 0) { + if (!try_kick(from, currentNick, currentChannel, reason)) + return false; + + while (*currentNick) + currentNick++; + + while (*currentChannel) + currentChannel++; + + currentNick++; + currentChannel++; + nickCount--; + } + } else { + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); + } + return true; +} /* IRC_KICK */ GLOBAL bool diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am
--- a/src/testsuite/Makefile.am
+++ b/src/testsuite/Makefile.am
@@ -21,6 +21,7 @@ EXTRA_DIST = \
start-server.sh stop-server.sh tests.sh stress-server.sh \
test-loop.sh wait-tests.sh \
channel-test.e connect-test.e check-idle.e misc-test.e mode-test.e \
+ kick-test.e \
opless-channel-test.e \
who-test.e stress-A.e stress-B.e \
ngircd-test.conf
@@ -48,6 +49,10 @@ channel-test: tests.sh
rm -f channel-test
ln -s $(srcdir)/tests.sh channel-test
+kick-test: tests.sh
+ rm -f kick-test
+ ln -s $(srcdir)/tests.sh kick-test
+
opless-channel-test: tests.sh
rm -f opless-channel-test
ln -s $(srcdir)/tests.sh opless-channel-test
@@ -67,6 +72,7 @@ mode-test: tests.sh
TESTS = start-server.sh \
connect-test \
channel-test \
+ kick-test \
misc-test \
mode-test \
who-test \
diff --git a/src/testsuite/kick-test.e b/src/testsuite/kick-test.e
new file mode 100644
index 0000000000000000000000000000000000000000..9412d321b990be4c852f5834ff06259ad4b962c0
--- /dev/null
+++ b/src/testsuite/kick-test.e
@@ -0,0 +1,112 @@
+spawn telnet localhost 6789
+expect {
+ timeout { exit 1 }
+ "Connected"
+}
+
+send "nick nick\r"
+send "user user . . :User\r"
+expect {
+ timeout { exit 1 }
+ "376"
+}
+
+send "kick #Channel nick\r"
+expect {
+ timeout { exit 1 }
+ "403"
+}
+
+send "join #Channel\r"
+
+send "kick #Channel nick\r"
+expect {
+ timeout { exit 1 }
+ "@* KICK #Channel nick :nick"
+}
+
+send "join #Channel\r"
+
+send "kick #Channel nick :reason\r"
+expect {
+ timeout { exit 1 }
+ "@* KICK #Channel nick :reason"
+}
+
+send "join #Channel,#Channel2\r"
+
+send "kick #Channel,#Channel2 nick\r"
+expect {
+ timeout { exit 1 }
+ "461"
+}
+
+send "kick #Channel,#Channel2,#NoExists,#NoExists nick1,nick,nick3,nick :reason\r"
+expect {
+ timeout { exit 1 }
+ "401"
+}
+expect {
+ timeout { exit 1 }
+ "@* KICK #Channel2 nick :reason"
+}
+expect {
+ timeout { exit 1 }
+ "401"
+}
+expect {
+ timeout { exit 1 }
+ "403"
+}
+
+send "kick #Channel nick2,nick,nick3\r"
+expect {
+ timeout { exit 1 }
+ "401"
+}
+expect {
+ timeout { exit 1 }
+ "@* KICK #Channel nick :nick"
+}
+expect {
+ timeout { exit 1 }
+ "401"
+}
+
+send "kick #Channel ,,\r"
+expect {
+ timeout { exit 1 }
+ "401"
+}
+expect {
+ timeout { exit 1 }
+ "401"
+}
+
+send "kick ,, ,,,\r"
+expect {
+ timeout { exit 1 }
+ "461"
+}
+
+send "kick ,, ,,\r"
+expect {
+ timeout { exit 1 }
+ "401"
+}
+expect {
+ timeout { exit 1 }
+ "401"
+}
+expect {
+ timeout { exit 1 }
+ "401"
+}
+
+send "quit\r"
+expect {
+ timeout { exit 1 }
+ "Connection closed"
+}
+
+# -eof-
-----END OF PAGE-----