commit - 3022d7cff35118b6651c1165227aa79d759d9bfd
commit + 6bd35bf090694a77b4a6c13c8fe5bb52e5905ec1
blob - 1ad48a4e0a8f531ef6153b7ecf02c92f6b784bcb
blob + c18df41da05c86885ee254d6a24cd27b91784241
--- ChangeLog
+++ ChangeLog
ngIRCd HEAD
+ - implement RFC 2812 handling of "0" argument to 'JOIN':
+ must be treated as if the user had sent PART commands
+ for all channels the user is a member of. (Dana Dahlstrom)
- allow NOTICEs to be sent to a channel. (Fabian Schlager)
ngIRCd 0.11.0 (2008-01-15)
--
-$Id: ChangeLog,v 1.335 2008/01/15 22:28:15 fw Exp $
+$Id: ChangeLog,v 1.336 2008/02/05 13:31:50 fw Exp $
blob - fcc6e4aadde4e067d183864f30e5a8eb133ff54a
blob + 3481e19e66e617cb34039e00f35489cb8cd75dba
--- src/ngircd/irc-channel.c
+++ src/ngircd/irc-channel.c
#include "portab.h"
-static char UNUSED id[] = "$Id: irc-channel.c,v 1.41 2008/01/07 11:42:00 fw Exp $";
+static char UNUSED id[] = "$Id: irc-channel.c,v 1.42 2008/02/05 13:31:50 fw Exp $";
#include "imp.h"
#include <assert.h>
#include "exp.h"
#include "irc-channel.h"
+
+
+/*
+ * RFC 2812, (3.2.1 Join message Command):
+ * Note that this message
+ * accepts a special argument ("0"), which is a special request to leave all
+ * channels the user is currently a member of. The server will process this
+ * message as if the user had sent a PART command (See Section 3.2.2) for
+ * each channel he is a member of.
+ */
+static bool
+part_from_all_channels(CLIENT* client, CLIENT *target)
+{
+ CL2CHAN *cl2chan = Channel_FirstChannelOf(target);
+ CHANNEL *chan;
+
+ while (cl2chan) {
+ chan = Channel_GetChannel(cl2chan);
+ assert( chan != NULL );
+ Channel_Part(target, client, Channel_Name(chan), Client_ID(target));
+
+ /* next */
+ cl2chan = Channel_FirstChannelOf(target);
+ }
+ return CONNECTED;
+}
GLOBAL bool
bool is_new_chan, is_invited, is_banned;
CLIENT *target;
CHANNEL *chan;
-
+
assert( Client != NULL );
assert( Req != NULL );
else target = Client;
if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
+ /* Is argument "0"? */
+ if (Req->argc == 1 && !strncmp("0", Req->argv[0], 2))
+ return part_from_all_channels(Client, target);
+
/* Are channel keys given? */
if (Req->argc > 1) {
key = Req->argv[1];
blob - 240abf64bd657b4c2faddaa9f02866727054e08e
blob + 16c67ad4a007eeeada1a6f08fedcc9571b2d069a
--- src/testsuite/channel-test.e
+++ src/testsuite/channel-test.e
-# $Id: channel-test.e,v 1.3 2003/12/27 13:01:12 alex Exp $
+# $Id: channel-test.e,v 1.4 2008/02/05 13:31:51 fw Exp $
spawn telnet localhost 6789
expect {
"@* PART #channel :nick"
}
+send "join #channel\r"
+expect {
+ timeout { exit 1 }
+ "@* JOIN :#channel"
+}
+expect {
+ timeout { exit 1 }
+ "366"
+}
+
+send "join #channel2\r"
+expect {
+ timeout { exit 1 }
+ "@* JOIN :#channel2"
+}
+expect {
+ timeout { exit 1 }
+ "366"
+}
+
+send "join 0\r"
+expect {
+ timeout { exit 1 }
+ "@* PART #channel2 :nick"
+}
+expect {
+ timeout { exit 1 }
+ "@* PART #channel :nick"
+}
+
send "quit\r"
expect {
timeout { exit 1 }