From 1cdd8fdfd7307c739623ec0a029ed61448742455 Mon Sep 17 00:00:00 2001 From: JD Horelick Date: Wed, 3 Mar 2010 14:35:54 -0500 Subject: [PATCH] Framework for hidden (only opers can see/set them) chmodes. The first one of these is +M and the actual extension which handles +M will be added next commit. --- include/channel.h | 2 ++ include/chmode.h | 3 +++ src/channel.c | 4 ++++ src/chmode.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-- src/send.c | 7 +++++- 5 files changed, 71 insertions(+), 3 deletions(-) diff --git a/include/channel.h b/include/channel.h index 1744acd..1cbcb1d 100644 --- a/include/channel.h +++ b/include/channel.h @@ -150,6 +150,7 @@ typedef int (*ExtbanFunc)(const char *data, struct Client *client_p, #define ONLY_SERVERS 0x0020 #define CHFL_HALFOP 0x0040 #define CHFL_OWNER 0x0080 +#define ONLY_OPERS 0x0100 #define ALL_MEMBERS CHFL_PEON #define ONLY_CHANOPS CHFL_CHANOP #define ONLY_CHANOPSVOICED (CHFL_CHANOP|CHFL_VOICE) @@ -183,6 +184,7 @@ typedef int (*ExtbanFunc)(const char *data, struct Client *client_p, #define MODE_NOCAPS 0x100000 /* Block messages in all capital letters */ #define MODE_NOREJOIN 0x200000 /* Block rejoin immediately after kick */ #define MODE_NOREPEAT 0x400000 /* Block repeat messages */ +#define MODE_NOOPERKICK 0x800000 /* disallow kicking opers */ #define CHFL_BAN 0x10000000 /* ban channel flag */ #define CHFL_EXCEPTION 0x20000000 /* exception to ban channel flag */ diff --git a/include/chmode.h b/include/chmode.h index 9538194..897c64f 100644 --- a/include/chmode.h +++ b/include/chmode.h @@ -48,6 +48,9 @@ extern void chm_simple(struct Client *source_p, struct Channel *chptr, extern void chm_ban(struct Client *source_p, struct Channel *chptr, int alevel, int parc, int *parn, const char **parv, int *errors, int dir, char c, long mode_type); +extern void chm_hidden(struct Client *source_p, struct Channel *chptr, + int alevel, int parc, int *parn, + const char **parv, int *errors, int dir, char c, long mode_type); extern void chm_staff(struct Client *source_p, struct Channel *chptr, int alevel, int parc, int *parn, const char **parv, int *errors, int dir, char c, long mode_type); diff --git a/src/channel.c b/src/channel.c index 89c271b..fb0fd35 100644 --- a/src/channel.c +++ b/src/channel.c @@ -1252,8 +1252,12 @@ channel_modes(struct Channel *chptr, struct Client *client_p) *pbuf = '\0'; for (i = 0; i < 256; i++) + { + if(chmode_table[i].set_func == chm_hidden && !IsOper(client_p)) + continue; if(chptr->mode.mode & chmode_flags[i]) *mbuf++ = i; + } if(chptr->mode.limit) { diff --git a/src/chmode.c b/src/chmode.c index f6c3934..cb2e224 100644 --- a/src/chmode.c +++ b/src/chmode.c @@ -587,6 +587,59 @@ chm_orphaned(struct Client *source_p, struct Channel *chptr, } } +void +chm_hidden(struct Client *source_p, struct Channel *chptr, + int alevel, int parc, int *parn, + const char **parv, int *errors, int dir, char c, long mode_type) +{ + if(!IsOper(source_p) && !IsServer(source_p)) + { + if(!(*errors & SM_ERR_NOPRIVS)) + sendto_one_numeric(source_p, ERR_NOPRIVILEGES, form_str(ERR_NOPRIVILEGES)); + *errors |= SM_ERR_NOPRIVS; + return; + } + if(MyClient(source_p) && !IsOperAdmin(source_p)) + { + if(!(*errors & SM_ERR_NOPRIVS)) + sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, + source_p->name, "cmodes"); + *errors |= SM_ERR_NOPRIVS; + return; + } + + if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE)) + return; + + /* setting + */ + if((dir == MODE_ADD) && !(chptr->mode.mode & mode_type)) + { + chptr->mode.mode |= mode_type; + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_ADD; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count].mems = ONLY_OPERS; + mode_changes[mode_count].override = 0; + mode_changes[mode_count++].arg = NULL; + } + else if((dir == MODE_DEL) && (chptr->mode.mode & mode_type)) + { + chptr->mode.mode &= ~mode_type; + + mode_changes[mode_count].letter = c; + mode_changes[mode_count].dir = MODE_DEL; + mode_changes[mode_count].caps = 0; + mode_changes[mode_count].nocaps = 0; + mode_changes[mode_count].mems = ONLY_OPERS; + mode_changes[mode_count].id = NULL; + mode_changes[mode_count].override = 0; + mode_changes[mode_count++].arg = NULL; + } +} + void chm_staff(struct Client *source_p, struct Channel *chptr, int alevel, int parc, int *parn, @@ -1731,7 +1784,7 @@ struct ChannelMode chmode_table[256] = {chm_simple, MODE_NOREJOIN }, /* J */ {chm_simple, MODE_NOREPEAT }, /* K */ {chm_staff, MODE_EXLIMIT }, /* L */ - {chm_nosuch, 0 }, /* M */ + {chm_hidden, MODE_NOOPERKICK }, /* M */ {chm_simple, MODE_NONICK }, /* N */ {chm_nosuch, 0 }, /* O */ {chm_staff, MODE_PERMANENT }, /* P */ @@ -1949,6 +2002,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, const char *ml = parv[0]; char c; struct Client *fakesource_p; + int flags_list[3] = { ALL_MEMBERS, ONLY_CHANOPS, ONLY_OPERS }; mask_pos = 0; mode_count = 0; @@ -2013,7 +2067,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, add_user_to_channel(chptr, source_p, CHFL_CHANOP); } - for(j = 0, flags = ALL_MEMBERS; j < 2; j++, flags = ONLY_CHANOPS) + for(j = 0, flags = flags_list[0]; j < 3; j++, flags = flags_list[j]) { cur_len = mlen; mbuf = modebuf + mlen; diff --git a/src/send.c b/src/send.c index e5d71f2..db98c57 100644 --- a/src/send.c +++ b/src/send.c @@ -646,7 +646,12 @@ sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...) if(IsIOError(target_p)) continue; - if(type && ((msptr->flags & type) == 0)) + if(type == ONLY_OPERS) + { + if(!IsOper(target_p)) + continue; + } + else if(type && ((msptr->flags & type) == 0)) continue; _send_linebuf(target_p, &linebuf);