diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | doc/modes.txt | 1 | ||||
-rw-r--r-- | include/channel.h | 2 | ||||
-rw-r--r-- | include/channel_mode.h | 1 | ||||
-rw-r--r-- | include/numeric.h | 1 | ||||
-rw-r--r-- | modules/core/m_message.c | 17 | ||||
-rw-r--r-- | modules/core/m_part.c | 4 | ||||
-rw-r--r-- | modules/core/m_sjoin.c | 3 | ||||
-rw-r--r-- | src/channel.c | 41 | ||||
-rw-r--r-- | src/channel_mode.c | 3 | ||||
-rw-r--r-- | src/numeric.c | 4 |
11 files changed, 63 insertions, 17 deletions
@@ -2,6 +2,9 @@ o) PCRE support has been dropped o) "STATS o" now shows how many times an oper{} block has been used. Similar to STATS x|q" +o) Implemented channel mode +c. Known from other ircds, this mode basically + prevents users from sending messages including control codes to a channel + that has this mode set -- ircd-hybrid-8.1.0beta2 Release Notes diff --git a/doc/modes.txt b/doc/modes.txt index 6902948..59c56b0 100644 --- a/doc/modes.txt +++ b/doc/modes.txt @@ -40,6 +40,7 @@ User Modes: Channel Modes: +b - ban - Channel ban on nick!user@host ++c - noctrls - Prevent users from sending messages containing control codes to the channel +e - exempt - Exemption from bans +I - invex - Invite exceptions, nick!user@host does not need to be explicitly INVITE'd into the channel before being able diff --git a/include/channel.h b/include/channel.h index 564533e..8780dbe 100644 --- a/include/channel.h +++ b/include/channel.h @@ -115,7 +115,7 @@ struct Ban extern dlink_list global_channel_list; extern int check_channel_name(const char *, const int); -extern int can_send(struct Channel *, struct Client *, struct Membership *); +extern int can_send(struct Channel *, struct Client *, struct Membership *, const char *); extern int is_banned(const struct Channel *, const struct Client *); extern int can_join(struct Client *, struct Channel *, const char *); extern int has_member_flags(const struct Membership *, const unsigned int); diff --git a/include/channel_mode.h b/include/channel_mode.h index 2bd8ce6..ec705a5 100644 --- a/include/channel_mode.h +++ b/include/channel_mode.h @@ -59,6 +59,7 @@ #define MODE_OPERONLY 0x0080 #define MODE_REGISTERED 0x0100 /* Channel has been registered with ChanServ */ #define MODE_REGONLY 0x0200 +#define MODE_NOCTRL 0x0400 /* cache flags for silence on ban */ #define CHFL_BAN_CHECKED 0x0080 diff --git a/include/numeric.h b/include/numeric.h index fb5da3a..923c91c 100644 --- a/include/numeric.h +++ b/include/numeric.h @@ -180,6 +180,7 @@ extern const char *form_str(unsigned int); #define ERR_TOOMANYCHANNELS 405 #define ERR_WASNOSUCHNICK 406 #define ERR_TOOMANYTARGETS 407 +#define ERR_NOCTRLSONCHAN 408 #define ERR_NOORIGIN 409 #define ERR_INVALIDCAPCMD 410 diff --git a/modules/core/m_message.c b/modules/core/m_message.c index 7fadaba..5aaf74b 100644 --- a/modules/core/m_message.c +++ b/modules/core/m_message.c @@ -409,7 +409,7 @@ static void msg_channel(int p_or_n, const char *command, struct Client *client_p, struct Client *source_p, struct Channel *chptr, char *text) { - int result; + int result = 0; if (MyClient(source_p)) { @@ -419,7 +419,7 @@ msg_channel(int p_or_n, const char *command, struct Client *client_p, } /* chanops and voiced can flood their own channel with impunity */ - if ((result = can_send(chptr, source_p, NULL)) < 0) + if ((result = can_send(chptr, source_p, NULL, text)) < 0) { if (result == CAN_SEND_OPV || !flood_attack_channel(p_or_n, source_p, chptr)) @@ -429,9 +429,16 @@ msg_channel(int p_or_n, const char *command, struct Client *client_p, else { if (p_or_n != NOTICE) - sendto_one(source_p, form_str(ERR_CANNOTSENDTOCHAN), - ID_or_name(&me, client_p), - ID_or_name(source_p, client_p), chptr->chname); + { + if (result == ERR_NOCTRLSONCHAN) + sendto_one(source_p, form_str(ERR_NOCTRLSONCHAN), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), chptr->chname, text); + else + sendto_one(source_p, form_str(ERR_CANNOTSENDTOCHAN), + ID_or_name(&me, client_p), + ID_or_name(source_p, client_p), chptr->chname); + } } } diff --git a/modules/core/m_part.c b/modules/core/m_part.c index 3d1e83a..e999c6a 100644 --- a/modules/core/m_part.c +++ b/modules/core/m_part.c @@ -76,7 +76,7 @@ part_one_client(struct Client *client_p, struct Client *source_p, * only allow /part reasons in -m chans */ if (reason[0] && (!MyConnect(source_p) || - ((can_send(chptr, source_p, ms) && + ((can_send(chptr, source_p, ms, reason) && (source_p->localClient->firsttime + ConfigFileEntry.anti_spam_exit_message_time) < CurrentTime)))) { @@ -127,7 +127,7 @@ m_part(struct Client *client_p, struct Client *source_p, return; } - if (parc > 2) + if (parc > 2 && !EmptyString(parv[2])) strlcpy(reason, parv[2], sizeof(reason)); /* Finish the flood grace period... */ diff --git a/modules/core/m_sjoin.c b/modules/core/m_sjoin.c index 65a5caa..8e10097 100644 --- a/modules/core/m_sjoin.c +++ b/modules/core/m_sjoin.c @@ -122,6 +122,9 @@ ms_sjoin(struct Client *client_p, struct Client *source_p, { switch (*s) { + case 'c': + mode.mode |= MODE_NOCTRL; + break; case 't': mode.mode |= MODE_TOPICLIMIT; break; diff --git a/src/channel.c b/src/channel.c index efc64d1..c3967d5 100644 --- a/src/channel.c +++ b/src/channel.c @@ -547,11 +547,7 @@ const char * get_member_status(const struct Membership *ms, int combine) { static char buffer[4]; - char *p = NULL; - - if (ms == NULL) - return ""; - p = buffer; + char *p = buffer; if (ms->flags & CHFL_CHANOP) { @@ -697,6 +693,35 @@ find_channel_link(struct Client *client_p, struct Channel *chptr) return NULL; } +/* + * Basically the same functionality as in bahamut + */ +static int +msg_has_ctrls(const char *message) +{ + const unsigned char *p = (const unsigned char *)message; + + for (; *p; ++p) + { + if (*p > 31 || *p == 1) + continue; + + if (*p == 27) + { + if (*(p + 1) == '$' || + *(p + 1) == '(') + { + ++p; + continue; + } + } + + return 1; + } + + return 0; +} + /*! * \param chptr pointer to Channel struct * \param source_p pointer to Client struct @@ -706,7 +731,8 @@ find_channel_link(struct Client *client_p, struct Channel *chptr) * ERR_CANNOTSENDTOCHAN or ERR_NEEDREGGEDNICK if they cannot send to channel\n */ int -can_send(struct Channel *chptr, struct Client *source_p, struct Membership *ms) +can_send(struct Channel *chptr, struct Client *source_p, + struct Membership *ms, const char *message) { struct MaskItem *conf = NULL; @@ -750,6 +776,9 @@ can_send(struct Channel *chptr, struct Client *source_p, struct Membership *ms) if ((chptr->mode.mode & MODE_REGONLY) && !HasUMode(source_p, UMODE_REGISTERED)) return ERR_NEEDREGGEDNICK; + if ((chptr->mode.mode & MODE_NOCTRL) && msg_has_ctrls(message)) + return ERR_NOCTRLSONCHAN; + return CAN_SEND_NONOP; } diff --git a/src/channel_mode.c b/src/channel_mode.c index 2a21b76..d1e83c5 100644 --- a/src/channel_mode.c +++ b/src/channel_mode.c @@ -321,6 +321,7 @@ del_id(struct Channel *chptr, char *banid, int type) } const struct mode_letter chan_modes[] = { + { MODE_NOCTRL, 'c' }, { MODE_INVITEONLY, 'i' }, { MODE_MODERATED, 'm' }, { MODE_NOPRIVMSGS, 'n' }, @@ -1429,7 +1430,7 @@ static struct ChannelMode ModeTable[255] = {chm_nosuch, NULL}, {chm_nosuch, NULL}, /* a */ {chm_ban, NULL}, /* b */ - {chm_nosuch, NULL}, /* c */ + {chm_simple, (void *) MODE_NOCTRL}, /* c */ {chm_nosuch, NULL}, /* d */ {chm_except, NULL}, /* e */ {chm_nosuch, NULL}, /* f */ diff --git a/src/numeric.c b/src/numeric.c index b7fee5b..b1ee134 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -31,7 +31,7 @@ static const char *replies[] = { /* 001 RPL_WELCOME */ ":%s 001 %s :Welcome to the %s Internet Relay Chat Network %s!%s@%s", /* 002 RPL_YOURHOST */ ":%s 002 %s :Your host is %s, running version %s", /* 003 RPL_CREATED */ ":%s 003 %s :This server was created %s", -/* 004 RPL_MYINFO */ ":%s 004 %s %s %s %s biklmnoprstveIORS bkloveI", +/* 004 RPL_MYINFO */ ":%s 004 %s %s %s %s bciklmnoprstveIORS bkloveI", /* 005 RPL_ISUPPORT */ ":%s 005 %s %s :are supported by this server", /* 006 */ NULL, /* 007 */ NULL, @@ -435,7 +435,7 @@ static const char *replies[] = { /* 405 ERR_TOOMANYCHANNELS */ ":%s 405 %s %s :You have joined too many channels", /* 406 ERR_WASNOSUCHNICK */ ":%s 406 %s %s :There was no such nickname", /* 407 ERR_TOOMANYTARGETS */ ":%s 407 %s %s :Too many recipients. Only %d processed", -/* 408 */ NULL, +/* 408 ERR_NOCTRLSONCHAN*/ ":%s 408 %s %s :You cannot use control codes on this channel. Not sent: %s", /* 409 ERR_NOORIGIN */ ":%s 409 %s :No origin specified", /* 410 ERR_INVALIDCAPCMD */ ":%s 410 %s %s :Invalid CAP subcommand", /* 411 ERR_NORECIPIENT */ ":%s 411 %s :No recipient given (%s)", |