repo: ngircd
action: commit
revision: 
path_from: 
revision_from: a57748e1a14dc6fa51291d31dae92c9a5abdd7c0:
path_to: 
revision_to: 
git.thebackupbox.net
ngircd
git clone git://git.thebackupbox.net/ngircd
commit a57748e1a14dc6fa51291d31dae92c9a5abdd7c0
Author: Alexander Barton 
Date:   Mon Jan 10 12:15:05 2011 +0100

    Implement channel mode 'O': "IRC operators only"

    This channel mode is used on DALnet (bahamut), for example.

diff --git a/src/ngircd/defines.h b/src/ngircd/defines.h
index ff456a34fc542648efe5531229501d56eac29f20..
index ..3f1122ca2fcaba6c93f502667a8ea0f5ffc73699 100644
--- a/src/ngircd/defines.h
+++ b/src/ngircd/defines.h
@@ -81,7 +81,7 @@
 					   in seconds. */

 #define USERMODES "aciorswx"		/* Supported user modes. */
-#define CHANMODES "biIklmnoPstvz"	/* Supported channel modes. */
+#define CHANMODES "biIklmnoOPstvz"	/* Supported channel modes. */

 #define CONNECTED true			/* Internal status codes. */
 #define DISCONNECTED false
diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c
index 81a9eb2e89f5f017f7dc9a9007441655df66059d..
index ..ed71dc70bc683d3e3b0e7622e2f62798d881723e 100644
--- a/src/ngircd/irc-channel.c
+++ b/src/ngircd/irc-channel.c
@@ -122,6 +122,13 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
 		return false;
 	}

+	if (strchr(channel_modes, 'O') && !Client_OperByMe(Client)) {
+		/* Only IRC operators are allowed! */
+		IRC_WriteStrClient(Client, ERR_OPONLYCHANNEL_MSG,
+				   Client_ID(Client), channame);
+		return false;
+	}
+
 	return true;
 }

diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c
index 1e6772a69e636a6288ecf1393cf8db96eff7df47..
index ..30f4dee3ef26b9249c1d9f1aba76802c01df0c1d 100644
--- a/src/ngircd/irc-mode.c
+++ b/src/ngircd/irc-mode.c
@@ -499,6 +499,23 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 				goto chan_exit;
 			}
 			break;
+		case 'O': /* IRC operators only */
+			if (modeok) {
+				/* Only IRC operators are allowed to
+				 * set the 'O' channel mode! */
+				if (set && !(Client_OperByMe(Client)
+				    || Client_Type(Client) == CLIENT_SERVER))
+					connected = IRC_WriteStrClient(Origin,
+						ERR_NOPRIVILEGES_MSG,
+						Client_ID(Origin));
+				else
+					x[0] = 'O';
+			} else
+				connected = IRC_WriteStrClient(Origin,
+						ERR_CHANOPRIVSNEEDED_MSG,
+						Client_ID(Origin),
+						Channel_Name(Channel));
+				break;
 		case 'P': /* Persistent channel */
 			if (modeok) {
 				/* Only IRC operators are allowed to
diff --git a/src/ngircd/messages.h b/src/ngircd/messages.h
index 900d2ff1101a9f80d77cc6efc75194ca48fa07a4..
index ..ec4bd869df928aeec2e22a2fb554e9ba45d068aa 100644
--- a/src/ngircd/messages.h
+++ b/src/ngircd/messages.h
@@ -117,6 +117,7 @@
 #define ERR_PASSWDMISMATCH_MSG		"464 %s :Invalid password"
 #define ERR_CHANNELISFULL_MSG		"471 %s %s :Cannot join channel (+l)"
 #define ERR_SECURECHANNEL_MSG		"471 %s %s :Cannot join channel (+z)"
+#define ERR_OPONLYCHANNEL_MSG		"471 %s %s :Cannot join channel (+O)"
 #define ERR_UNKNOWNMODE_MSG		"472 %s: %c :is unknown mode char for %s"
 #define ERR_INVITEONLYCHAN_MSG		"473 %s %s :Cannot join channel (+i)"
 #define ERR_BANNEDFROMCHAN_MSG		"474 %s %s :Cannot join channel (+b)"

-----END OF PAGE-----