]> arthur.barton.de Git - ngircd.git/commitdiff
Add support for modeless channels
authorAli Shemiran <ashemira@ucsd.edu>
Thu, 1 May 2008 13:19:31 +0000 (15:19 +0200)
committerAlexander Barton <alex@barton.de>
Thu, 1 May 2008 13:55:12 +0000 (15:55 +0200)
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
src/ngircd/channel.c
src/ngircd/irc-channel.c
src/ngircd/irc-mode.c
src/ngircd/messages.h
src/testsuite/Makefile.am
src/testsuite/opless-channel-test.e [new file with mode: 0644]

index 665d2993d12444352ea055a2d31a70b39807c3c5..8fa83a7b71a3dcc3512eb4c64537751e105e68ce 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
                                -- 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.
index 32f911a200f6269eed0f51420a8523ea980c0b78..7859238b447e2844b2c6cbcf8b38057362b20753 100644 (file)
@@ -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 */
index c678ceeb3f4160a933c6e845ed427e45c7aff70c..3f76452e48f93fafdf5a68b67686476d649e78fa 100644 (file)
@@ -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;
index 3786e3994593c53aa41c4e3d067190a136a61ee1..3bf809bc0968adc90fa18edc4a4c053d85674395 100644 (file)
@@ -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);
index 4f01ac5e4ccdad96e7d922fd8869fdbafc020bfb..b42e38beb2c08ca0fd1adbfc9208530b854c60ae 100644 (file)
 #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!"
index 6512aaae337713ac9f7a79f3bacd0b83e73673a4..bc8df8442deb534d61a6f4f25ad3c21397249904 100644 (file)
@@ -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 (file)
index 0000000..35d109e
--- /dev/null
@@ -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-