about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAli Shemiran <ashemira@ucsd.edu>2008-05-01 15:19:31 +0200
committerAlexander Barton <alex@barton.de>2008-05-01 15:55:12 +0200
commit530112b114ffa7d5352c0733790ddf90253f41f9 (patch)
tree6c97813360181e0c0b24b803cb103d584d77489b /src
parent6cfc56064e25b5bb54fb1f9503820a7e38846303 (diff)
downloadngircd-530112b114ffa7d5352c0733790ddf90253f41f9.tar.gz
ngircd-530112b114ffa7d5352c0733790ddf90253f41f9.zip
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 ]
Diffstat (limited to 'src')
-rw-r--r--src/ngircd/channel.c13
-rw-r--r--src/ngircd/irc-channel.c24
-rw-r--r--src/ngircd/irc-mode.c6
-rw-r--r--src/ngircd/messages.h1
-rw-r--r--src/testsuite/Makefile.am6
-rw-r--r--src/testsuite/opless-channel-test.e32
6 files changed, 74 insertions, 8 deletions
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-