From a57748e1a14dc6fa51291d31dae92c9a5abdd7c0 Mon Sep 17 00:00:00 2001 From: Alexander Barton Date: Mon, 10 Jan 2011 12:15:05 +0100 Subject: [PATCH] Implement channel mode 'O': "IRC operators only" This channel mode is used on DALnet (bahamut), for example. --- src/ngircd/defines.h | 2 +- src/ngircd/irc-channel.c | 7 +++++++ src/ngircd/irc-mode.c | 17 +++++++++++++++++ src/ngircd/messages.h | 1 + 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/ngircd/defines.h b/src/ngircd/defines.h index ff456a34..3f1122ca 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 81a9eb2e..ed71dc70 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 1e6772a6..30f4dee3 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 900d2ff1..ec4bd869 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)" -- 2.39.2