From 530112b114ffa7d5352c0733790ddf90253f41f9 Mon Sep 17 00:00:00 2001 From: Ali Shemiran Date: Thu, 1 May 2008 15:19:31 +0200 Subject: [PATCH] Add support for modeless channels Add support for modeless channels (+channels). [fw@strlen.de: - integrate test cases - don't support +channels when compiled with --strict-rfc - do not set +o mode for channel creator - force +nt mode when channel is created ] --- ChangeLog | 5 +++++ src/ngircd/channel.c | 13 ++++++++++-- src/ngircd/irc-channel.c | 24 ++++++++++++++++------ src/ngircd/irc-mode.c | 6 ++++++ src/ngircd/messages.h | 1 + src/testsuite/Makefile.am | 6 ++++++ src/testsuite/opless-channel-test.e | 32 +++++++++++++++++++++++++++++ 7 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 src/testsuite/opless-channel-test.e diff --git a/ChangeLog b/ChangeLog index 665d2993..8fa83a7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,11 @@ -- ChangeLog -- +ngIRCd-dev + + - Add support for modeless channels ("+channels"). + (Bryan Caldwell, Ali Shemiran) + ngIRCd 0.12.0-pre2 (2008-04-29) - IPv6: Add config options to disabe ipv4/ipv6 support. diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c index 32f911a2..7859238b 100644 --- a/src/ngircd/channel.c +++ b/src/ngircd/channel.c @@ -480,7 +480,16 @@ Channel_IsValidName( const char *Name ) { assert( Name != NULL ); - if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN )) return false; + switch (Name[0]) { + case '#': break; +#ifndef STRICT_RFC + case '+': /* modeless channel */ + break; +#endif + default: return false; + } + if (strlen(Name) >= CHANNEL_NAME_LEN) + return false; return Name[strcspn(Name, " ,:\007")] == 0; } /* Channel_IsValidName */ @@ -892,7 +901,7 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch IRC_WriteStrClientPrefix(Client, Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason); } - LogDebug("User \"%s\" has been kicked of \"%s\" by \"%s\": %s.", + LogDebug("User \"%s\" has been kicked off \"%s\" by \"%s\": %s.", Client_Mask( Client ), c->name, Client_ID(Origin), Reason); break; default: /* PART */ diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c index c678ceeb..3f76452e 100644 --- a/src/ngircd/irc-channel.c +++ b/src/ngircd/irc-channel.c @@ -239,9 +239,15 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req ) if ((Conf_MaxJoins > 0) && (Channel_CountForUser(Client) >= Conf_MaxJoins)) return IRC_WriteStrClient(Client, ERR_TOOMANYCHANNELS_MSG, Client_ID(Client), channame); - if (!chan) /* New Channel: first user will be channel operator */ - flags = "o"; - else + if (!chan) { + /* + * New Channel: first user will be channel operator + * unless this is a modeless channel... */ +#ifndef STRICT_RFC + if (*channame != '+') +#endif + flags = "o"; + } else if (!join_allowed(Client, target, chan, channame, key)) break; } else { @@ -257,8 +263,14 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req ) if (!Channel_Join(target, channame)) break; - if (!chan) /* channel is new; it has been created above */ + if (!chan) { /* channel is new; it has been created above */ chan = Channel_Search(channame); + assert(chan != NULL); + if (*channame == '+') { /* modeless channel... */ + Channel_ModeAdd(chan, 't'); /* /TOPIC not allowed */ + Channel_ModeAdd(chan, 'n'); /* no external msgs */ + } + } assert(chan != NULL); join_set_channelmodes(chan, target, flags); @@ -333,8 +345,8 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - /* Falsche Anzahl Parameter? */ - if(( Req->argc < 1 ) || ( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + if ((Req->argc < 1) || (Req->argc > 2)) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix ); else from = Client; diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c index 3786e399..3bf809bc 100644 --- a/src/ngircd/irc-mode.c +++ b/src/ngircd/irc-mode.c @@ -286,6 +286,12 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ) long l; size_t len; +#ifndef STRICT_RFC + /* Are modes allowed on channel? */ + if (Channel_Name(Channel)[0] == '+') + return IRC_WriteStrClient(Client, ERR_NOCHANMODES_MSG, + Client_ID(Client), Channel_Name(Channel)); +#endif /* Mode request: let's answer it :-) */ if (Req->argc <= 1) return Channel_Mode_Answer_Request(Origin, Channel); diff --git a/src/ngircd/messages.h b/src/ngircd/messages.h index 4f01ac5e..b42e38be 100644 --- a/src/ngircd/messages.h +++ b/src/ngircd/messages.h @@ -114,6 +114,7 @@ #define ERR_INVITEONLYCHAN_MSG "473 %s %s :Cannot join channel (+i)" #define ERR_BANNEDFROMCHAN_MSG "474 %s %s :Cannot join channel (+b)" #define ERR_BADCHANNELKEY_MSG "475 %s %s :Cannot join channel (+k)" +#define ERR_NOCHANMODES_MSG "477 %s %s :Channel doesn't support modes" #define ERR_NOPRIVILEGES_MSG "481 %s :Permission denied" #define ERR_CHANOPRIVSNEEDED_MSG "482 %s %s :You are not channel operator" #define ERR_CANTKILLSERVER_MSG "483 %s :You can't kill a server!" diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am index 6512aaae..bc8df844 100644 --- 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 \ + opless-channel-test.e \ who-test.e stress-A.e stress-B.e \ ngircd-test.conf @@ -47,6 +48,10 @@ channel-test: tests.sh rm -f channel-test ln -s $(srcdir)/tests.sh channel-test +opless-channel-test: tests.sh + rm -f opless-channel-test + ln -s $(srcdir)/tests.sh opless-channel-test + who-test: tests.sh rm -f who-test ln -s $(srcdir)/tests.sh who-test @@ -65,6 +70,7 @@ TESTS = start-server.sh \ misc-test \ mode-test \ who-test \ + opless-channel-test \ stress-server.sh \ stop-server.sh diff --git a/src/testsuite/opless-channel-test.e b/src/testsuite/opless-channel-test.e new file mode 100644 index 00000000..35d109e9 --- /dev/null +++ b/src/testsuite/opless-channel-test.e @@ -0,0 +1,32 @@ +spawn telnet localhost 6789 +expect { + timeout { exit 1 } + "Connected" +} + +send "nick nick\r" +send "user user . . :User\r" +expect { + timeout { exit 1 } + "376" +} + +send "JOIN +Channel\r" +expect { + timeout { exit 1 } + "@* JOIN :+Channel" +} + +send "mode +Channel +t\r" +expect { + timeout { exit 1 } + "477" +} + +send "quit\r" +expect { + timeout { exit 1 } + "Connection closed" +} + +# -eof-