From 3ebde4ab503d0d571d58752061425c151522fce7 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sat, 27 Aug 2016 21:52:31 -0700 Subject: [PATCH] Convert umodes to mode_lease mechanism. --- configure.ac | 1 + extensions/extb_usermode.cc | 4 +- extensions/helpops.cc | 20 +---- extensions/ip_cloaking.cc | 23 ++--- extensions/override.cc | 31 +++---- extensions/umode_noctcp.cc | 16 +--- include/ircd/client.h | 14 +-- include/ircd/client_mode.h | 73 ++++++++-------- include/ircd/mode_lease.h | 13 ++- include/ircd/mode_table.h | 35 ++++++-- include/ircd/s_user.h | 4 - include/rb/requires.h | 1 + ircd/Makefile.am | 1 + ircd/client.cc | 2 +- ircd/client_mode.cc | 62 ++++++++++++++ ircd/ircd.cc | 2 - ircd/newconf.cc | 4 +- ircd/s_user.cc | 164 ++++-------------------------------- ircd/send.cc | 2 +- ircd/supported.cc | 4 +- modules/core/m_nick.cc | 4 +- modules/m_scan.cc | 4 +- 22 files changed, 207 insertions(+), 277 deletions(-) create mode 100644 ircd/client_mode.cc diff --git a/configure.ac b/configure.ac index 5860a46ce..8135346ac 100644 --- a/configure.ac +++ b/configure.ac @@ -320,6 +320,7 @@ RB_CHK_SYSHEADER([type_traits], [TYPE_TRAITS]) RB_CHK_SYSHEADER([utility], [UTILITY]) RB_CHK_SYSHEADER([functional], [FUNCTIONAL]) RB_CHK_SYSHEADER([algorithm], [ALGORITHM]) +RB_CHK_SYSHEADER([numeric], [NUMERIC]) RB_CHK_SYSHEADER([memory], [MEMORY]) RB_CHK_SYSHEADER([exception], [EXCEPTION]) RB_CHK_SYSHEADER([cerrno], [CERRNO]) diff --git a/extensions/extb_usermode.cc b/extensions/extb_usermode.cc index 677c45b8f..fa4fc5732 100644 --- a/extensions/extb_usermode.cc +++ b/extensions/extb_usermode.cc @@ -58,11 +58,11 @@ static int eb_usermode(const char *data, client::client *client_p, switch (dir) { case MODE_DEL: - modes_nak |= user_modes[(unsigned char) *p]; + modes_nak |= umode::table[(unsigned char) *p]; break; case MODE_ADD: default: - modes_ack |= user_modes[(unsigned char) *p]; + modes_ack |= umode::table[(unsigned char) *p]; break; } break; diff --git a/extensions/helpops.cc b/extensions/helpops.cc index ea1b64c36..8529b926c 100644 --- a/extensions/helpops.cc +++ b/extensions/helpops.cc @@ -27,8 +27,6 @@ mapi_hfn_list_av1 helpops_hfnlist[] = { { NULL, NULL } }; -static int UMODE_HELPOPS = 0; - struct Message dehelper_msgtab = { "DEHELPER", 0, 0, 0, 0, {mg_unreg, mg_not_oper, mg_not_oper, mg_ignore, {me_dehelper, 2}, {mo_dehelper, 2}} @@ -36,6 +34,8 @@ struct Message dehelper_msgtab = { mapi_clist_av1 helpops_clist[] = { &dehelper_msgtab, NULL }; +umode::mode UMODE_HELPOPS { 'H' }; + static void mo_dehelper(struct MsgBuf *msgbuf_p, client::client &client, client::client &source, int parc, const char **parv) { @@ -96,21 +96,9 @@ do_dehelper(client::client &source, client::client &target) static int _modinit(void) { - /* add the usermode to the available slot */ - user_modes['H'] = UMODE_HELPOPS = find_umode_slot(); - construct_umodebuf(); - return 0; } -static void -_moddeinit(void) -{ - /* disable the umode and remove it from the available list */ - user_modes['H'] = UMODE_HELPOPS = 0; - construct_umodebuf(); -} - static void h_hdl_stats_request(hook_data_int *hdata) { @@ -169,7 +157,7 @@ h_hdl_umode_changed(hook_data_umode_changed *hdata) { if (my(source) && !HasPrivilege(&source, "usermode:helpops")) { - source.mode &= umode(~UMODE_HELPOPS); + source.mode &= ~UMODE_HELPOPS; sendto_one(&source, form_str(ERR_NOPRIVS), me.name, source.name, "usermode:helpops"); return; } @@ -192,4 +180,4 @@ h_hdl_whois(hook_data_client *hdata) } } -DECLARE_MODULE_AV2(helpops, _modinit, _moddeinit, helpops_clist, NULL, helpops_hfnlist, NULL, NULL, helpops_desc); +DECLARE_MODULE_AV2(helpops, _modinit, nullptr, helpops_clist, NULL, helpops_hfnlist, NULL, NULL, helpops_desc); diff --git a/extensions/ip_cloaking.cc b/extensions/ip_cloaking.cc index 75aea823c..4176b0fdd 100644 --- a/extensions/ip_cloaking.cc +++ b/extensions/ip_cloaking.cc @@ -9,22 +9,17 @@ using namespace ircd; static const char ip_cloaking_desc[] = "New IP cloaking module that uses user mode +x instead of +h"; +umode::mode UMODE_IP_CLOAKING { 'x' }; + static int _modinit(void) { - /* add the usermode to the available slot */ - user_modes['x'] = find_umode_slot(); - construct_umodebuf(); - return 0; } static void _moddeinit(void) { - /* disable the umode and remove it from the available list */ - user_modes['x'] = 0; - construct_umodebuf(); } static void check_umode_change(void *data); @@ -162,14 +157,14 @@ check_umode_change(void *vdata) return; /* didn't change +h umode, we don't need to do anything */ - if (!((data->oldumodes ^ source_p->mode) & user_modes['x'])) + if (!((data->oldumodes ^ source_p->mode) & UMODE_IP_CLOAKING)) return; - if (source_p->mode & user_modes['x']) + if (source_p->mode & UMODE_IP_CLOAKING) { if (is_ip_spoof(*source_p) || source_p->localClient->mangledhost == NULL || (is_dyn_spoof(*source_p) && strcmp(source_p->host, source_p->localClient->mangledhost))) { - source_p->mode &= umode(~user_modes['x']); + source_p->mode &= ~UMODE_IP_CLOAKING; return; } if (strcmp(source_p->host, source_p->localClient->mangledhost)) @@ -180,7 +175,7 @@ check_umode_change(void *vdata) sendto_one_numeric(source_p, RPL_HOSTHIDDEN, "%s :is now your hidden host", source_p->host); } - else if (!(source_p->mode & user_modes['x'])) + else if (!(source_p->mode & UMODE_IP_CLOAKING)) { if (source_p->localClient->mangledhost != NULL && !strcmp(source_p->host, source_p->localClient->mangledhost)) @@ -197,7 +192,7 @@ check_new_user(void *vdata) if (is_ip_spoof(*source_p)) { - source_p->mode &= umode(~user_modes['x']); + source_p->mode &= ~UMODE_IP_CLOAKING; return; } source_p->localClient->mangledhost = (char *)rb_malloc(HOSTLEN + 1); @@ -206,8 +201,8 @@ check_new_user(void *vdata) else do_host_cloak_host(source_p->orighost, source_p->localClient->mangledhost); if (is_dyn_spoof(*source_p)) - source_p->mode &= umode(~user_modes['x']); - if (source_p->mode & user_modes['x']) + source_p->mode &= ~UMODE_IP_CLOAKING; + if (source_p->mode & UMODE_IP_CLOAKING) { rb_strlcpy(source_p->host, source_p->localClient->mangledhost, sizeof(source_p->host)); if (irccmp(source_p->host, source_p->orighost)) diff --git a/extensions/override.cc b/extensions/override.cc index db7993936..4e49b8557 100644 --- a/extensions/override.cc +++ b/extensions/override.cc @@ -30,6 +30,8 @@ mapi_hfn_list_av1 override_hfnlist[] = { { NULL, NULL } }; +umode::mode UMODE_OVERRIDE { 'p' }; + #define CHFL_OVERRIDE 0x0004 #define IsOperOverride(x) (HasPrivilege((x), "oper:override")) @@ -102,18 +104,18 @@ check_umode_change(void *vdata) return; if (data->oldumodes & umode::OPER && !is(*source_p, umode::OPER)) - source_p->mode &= umode(~user_modes['p']); + source_p->mode &= ~UMODE_OVERRIDE; /* didn't change +p umode, we don't need to do anything */ - if (!((data->oldumodes ^ source_p->mode) & user_modes['p'])) + if (!((data->oldumodes ^ source_p->mode) & UMODE_OVERRIDE)) return; - if (source_p->mode & user_modes['p']) + if (source_p->mode & UMODE_OVERRIDE) { if (!IsOperOverride(source_p)) { sendto_one_notice(source_p, ":*** You need oper:override privilege for +p"); - source_p->mode &= umode(~user_modes['p']); + source_p->mode &= ~UMODE_OVERRIDE; return; } @@ -122,7 +124,7 @@ check_umode_change(void *vdata) sendto_realops_snomask(sno::GENERAL, L_NETWIDE, "%s has enabled oper-override (+p)", get_oper_name(source_p)); } - else if (!(source_p->mode & user_modes['p'])) + else if (!(source_p->mode & UMODE_OVERRIDE)) { rb_dlink_node *n, *tn; @@ -153,7 +155,7 @@ hack_channel_access(void *vdata) if (data->approved == chan::CHANOP) return; - if (data->client->mode & user_modes['p']) + if (data->client->mode & UMODE_OVERRIDE) { update_session_deadline(data->client, NULL); data->approved = CHFL_OVERRIDE; @@ -173,7 +175,7 @@ hack_can_join(void *vdata) if (data->approved == 0) return; - if (data->client->mode & user_modes['p']) + if (data->client->mode & UMODE_OVERRIDE) { update_session_deadline(data->client, NULL); data->approved = 0; @@ -193,7 +195,7 @@ hack_can_kick(void *vdata) if (alevel != CHFL_OVERRIDE) return; - if (data->client->mode & user_modes['p']) + if (data->client->mode & UMODE_OVERRIDE) { update_session_deadline(data->client, NULL); sendto_realops_snomask(sno::GENERAL, L_NETWIDE, "%s is using oper-override on %s (KICK %s)", @@ -212,7 +214,7 @@ hack_can_send(void *vdata) if (data->approved == chan::CAN_SEND_NONOP || data->approved == chan::CAN_SEND_OPV) return; - if (data->client->mode & user_modes['p']) + if (data->client->mode & UMODE_OVERRIDE) { data->approved = chan::CAN_SEND_NONOP; @@ -249,22 +251,13 @@ struct ev_entry *expire_override_deadlines_ev = NULL; static int _modinit(void) { - /* add the usermode to the available slot */ - user_modes['p'] = find_umode_slot(); - construct_umodebuf(); - - expire_override_deadlines_ev = rb_event_add("expire_override_deadlines", expire_override_deadlines, NULL, 60); - + expire_override_deadlines_ev = rb_event_add("expire_override_deadlines", expire_override_deadlines, NULL, 60); return 0; } static void _moddeinit(void) { - /* disable the umode and remove it from the available list */ - user_modes['p'] = 0; - construct_umodebuf(); - rb_event_delete(expire_override_deadlines_ev); } diff --git a/extensions/umode_noctcp.cc b/extensions/umode_noctcp.cc index cdd41e9bd..21d740bbd 100644 --- a/extensions/umode_noctcp.cc +++ b/extensions/umode_noctcp.cc @@ -32,13 +32,15 @@ mapi_hfn_list_av1 umode_noctcp_hfnlist[] = { { NULL, NULL } }; +umode::mode UMODE_NOCTCP { 'C' }; + static void umode_noctcp_process(hook_data_privmsg_user *data) { if (data->approved || data->msgtype == MESSAGE_TYPE_NOTICE) { return; } - if (data->target_p->mode & user_modes['C'] && *data->text == '\001' && rb_strncasecmp(data->text + 1, "ACTION", 6)) { + if (data->target_p->mode & UMODE_NOCTCP && *data->text == '\001' && rb_strncasecmp(data->text + 1, "ACTION", 6)) { sendto_one_numeric(data->source_p, ERR_CANNOTSENDTOUSER, form_str(ERR_CANNOTSENDTOUSER), data->target_p->name, "+C set"); data->approved = ERR_CANNOTSENDTOUSER; return; @@ -48,17 +50,7 @@ umode_noctcp_process(hook_data_privmsg_user *data) { static int _modinit(void) { - user_modes['C'] = find_umode_slot(); - construct_umodebuf(); - return 0; } -static void -_moddeinit(void) -{ - user_modes['C'] = 0; - construct_umodebuf(); -} - -DECLARE_MODULE_AV2(umode_noctcp, _modinit, _moddeinit, NULL, NULL, umode_noctcp_hfnlist, NULL, NULL, umode_noctcp_desc); +DECLARE_MODULE_AV2(umode_noctcp, _modinit, nullptr, NULL, NULL, umode_noctcp_hfnlist, NULL, NULL, umode_noctcp_desc); diff --git a/include/ircd/client.h b/include/ircd/client.h index cf424f6d9..a08972689 100644 --- a/include/ircd/client.h +++ b/include/ircd/client.h @@ -97,7 +97,7 @@ struct client // unique whowas id associating any history to *this (TODO: replace with connid) whowas::id_t wwid; time_t tsinfo; /* TS on the nick, SVINFO on server */ - mode::mode mode; + mode::mask mode; uint64_t flags; /* client flags */ unsigned int snomask; /* server notice mask */ @@ -327,21 +327,21 @@ struct ListClient inline bool -is(const client &client, const mode::mode &mode) +is(const client &client, const mode::mask &mask) { - return is(client.mode, mode); + return mode::is(client.mode, mask); } inline void -set(client &client, const mode::mode &mode) +set(client &client, const mode::mask &mask) { - return set(client.mode, mode); + return mode::set(client.mode, mask); } inline void -clear(client &client, const mode::mode &mode) +clear(client &client, const mode::mask &mask) { - return clear(client.mode, mode); + return mode::clear(client.mode, mask); } inline void diff --git a/include/ircd/client_mode.h b/include/ircd/client_mode.h index 93a538b66..1cf884a05 100644 --- a/include/ircd/client_mode.h +++ b/include/ircd/client_mode.h @@ -27,63 +27,68 @@ namespace ircd { namespace client { namespace mode { -enum mode : uint +using mask = uint64_t; +extern mode_table table; +extern char available[64]; + +class mode +:public mode_lease { - SERVNOTICE = 0x0001, // server notices - WALLOP = 0x0002, // send wallops to them - OPERWALL = 0x0004, // operwalls - INVISIBLE = 0x0008, // makes user invisible - CALLERID = 0x0010, // block unless caller id's - LOCOPS = 0x0020, // show locops - SERVICE = 0x0040, - DEAF = 0x0080, - NOFORWARD = 0x0100, // don't forward - REGONLYMSG = 0x0200, // only allow logged in users to msg - OPER = 0x1000, // operator - ADMIN = 0x2000, // admin on server - SSLCLIENT = 0x4000, // using SSL + void release() noexcept override; + + public: + explicit mode(const char &c); }; -const mode DEFAULT_OPER_UMODES -{ - SERVNOTICE | - OPERWALL | - WALLOP | - LOCOPS -}; +extern mode SERVNOTICE; // server notices +extern mode WALLOP; // send wallops to them +extern mode OPERWALL; // operwalls +extern mode INVISIBLE; // makes user invisible +extern mode CALLERID; // block unless caller id's +extern mode LOCOPS; // show locops +extern mode SERVICE; +extern mode DEAF; +extern mode NOFORWARD; // don't forward +extern mode REGONLYMSG; // only allow logged in users to msg +extern mode OPER; // operator +extern mode ADMIN; // admin on server +extern mode SSLCLIENT; // using SSL + +extern const mask DEFAULT_OPER_UMODES; + +bool is(const mask &, const mask &); +void clear(mask &, const mask &); +void set(mask &, const mask &); -bool is(const mode &mask, const mode &bits); -void clear(mode &mask, const mode &bits); -void set(mode &mask, const mode &bits); } // namespace mode } // namespace client // Import `umode` type into ircd:: namespace -using umode = client::mode::mode; +namespace umode = client::mode; } // namespace ircd inline void -ircd::client::mode::set(mode &mask, - const mode &bits) +ircd::client::mode::set(mask &cur, + const mask &bit) { - mask |= bits; + cur |= bit; } inline void -ircd::client::mode::clear(mode &mask, - const mode &bits) +ircd::client::mode::clear(mask &cur, + const mask &bit) { - mask &= ~bits; + cur &= ~bit; } inline bool -ircd::client::mode::is(const mode &mask, - const mode &bits) +ircd::client::mode::is(const mask &cur, + const mask &bit) { - return (mask & bits) == bits; + return (cur & bit) == bit; } #endif // __cplusplus diff --git a/include/ircd/mode_lease.h b/include/ircd/mode_lease.h index 98599213b..e28f288f2 100644 --- a/include/ircd/mode_lease.h +++ b/include/ircd/mode_lease.h @@ -33,7 +33,7 @@ class mode_lease char c = '\0'; - virtual void release() { table[c] = { 0 }; } + virtual void release() noexcept { table[c] = { 0 }; } public: explicit operator const char &() const { return c; } @@ -44,7 +44,7 @@ class mode_lease mode_lease() = default; mode_lease(mode_lease &&) noexcept; mode_lease(const mode_lease &) = delete; - ~mode_lease() noexcept; + virtual ~mode_lease() noexcept; }; template::mode_lease(const char &c, args&&... a) :c(c) { + if(!c) + return; + if(!!table[c]) throw mode_filled("Character [%c] is already leased", c); @@ -74,8 +77,10 @@ template::~mode_lease() noexcept { - if(c) - release(); + if(!c) + return; + + release(); } } // namespace ircd diff --git a/include/ircd/mode_table.h b/include/ircd/mode_table.h index e78384ee3..d896a163b 100644 --- a/include/ircd/mode_table.h +++ b/include/ircd/mode_table.h @@ -194,6 +194,33 @@ find(const mode_table &table, return int8_t(std::distance(begin(table), it)); } +template +auto +mask_table(const mode_table &table) +{ + using mask_t = typename mode_table::mask_t; + + return std::accumulate(begin(table), end(table), mask_t(0), [] + (auto mask, const T &elem) + { + return mask |= static_cast(elem); + }); +} + +template +char * +mask_table(const mode_table &table, + char *const &buf) +{ + char *p(buf); + for(size_t i(0); i < table.size(); ++i) + if(!!table[i]) + *p++ = i; + + *p = '\0'; + return buf; +} + template auto find_slot(const mode_table &table, @@ -201,13 +228,7 @@ find_slot(const mode_table &table, { using mask_t = typename mode_table::mask_t; - mask_t mask(0); - std::for_each(begin(table), end(table), [&mask] - (const T &elem) - { - mask |= elem; - }); - + const auto mask(mask_table(table)); for(mask_t i(1); i; i <<= 1) if(~mask & i) return i; diff --git a/include/ircd/s_user.h b/include/ircd/s_user.h index 052aa097f..344378316 100644 --- a/include/ircd/s_user.h +++ b/include/ircd/s_user.h @@ -45,10 +45,6 @@ void introduce_client(client::client *client_p, client::client *source_p, const extern void change_nick_user_host(client::client *target_p, const char *nick, const char *user, const char *host, int newts, const char *format, ...); -extern int user_modes[256]; -extern unsigned int find_umode_slot(void); -extern void construct_umodebuf(void); - extern void oper_up(client::client *, struct oper_conf *); } // namespace ircd diff --git a/include/rb/requires.h b/include/rb/requires.h index afe18fe9a..9b1ac3d04 100644 --- a/include/rb/requires.h +++ b/include/rb/requires.h @@ -62,6 +62,7 @@ extern "C" { #include + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice is present in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +using namespace ircd; +using client::mode::mode; + +mode_table client::mode::table; +decltype(client::mode::available) client::mode::available; + +mode client::mode::SERVNOTICE { 's' }; +mode client::mode::WALLOP { 'w' }; +mode client::mode::OPERWALL { 'z' }; +mode client::mode::INVISIBLE { 'i' }; +mode client::mode::CALLERID { 'g' }; +mode client::mode::LOCOPS { 'l' }; +mode client::mode::SERVICE { 'S' }; +mode client::mode::DEAF { 'D' }; +mode client::mode::NOFORWARD { 'Q' }; +mode client::mode::REGONLYMSG { 'R' }; +mode client::mode::OPER { 'o' }; +mode client::mode::ADMIN { 'a' }; +mode client::mode::SSLCLIENT { 'Z' }; + +const client::mode::mask client::mode::DEFAULT_OPER_UMODES +{ + SERVNOTICE | + OPERWALL | + WALLOP | + LOCOPS +}; + +mode::mode(const char &c) +:mode_lease{c} +{ + mask_table(table, available); +} + +void +mode::release() +noexcept +{ + table[char(*this)] = 0; + mask_table(table, available); +} diff --git a/ircd/ircd.cc b/ircd/ircd.cc index a4a763ee9..e01034264 100644 --- a/ircd/ircd.cc +++ b/ircd/ircd.cc @@ -623,8 +623,6 @@ charybdis_main(int argc, char * const argv[]) rb_dlinkAddAlloc(&me, &global_serv_list); - construct_umodebuf(); - check_class(); write_pidfile(pidFileName); cache::help::load(); diff --git a/ircd/newconf.cc b/ircd/newconf.cc index c00be1a44..4b22f9072 100644 --- a/ircd/newconf.cc +++ b/ircd/newconf.cc @@ -295,7 +295,7 @@ conf_set_modules_path(void *data) struct mode_table_ { const char *name; - int mode; + umode::mask mode; }; /* *INDENT-OFF* */ @@ -1677,7 +1677,7 @@ conf_set_general_default_umodes(void *data) break; default: - if ((flag = user_modes[(unsigned char) *pm])) + if ((flag = umode::table[(unsigned char) *pm])) { /* Proper value has probably not yet been set * so don't check oper_only_umodes -- jilles */ diff --git a/ircd/s_user.cc b/ircd/s_user.cc index 98bf5df26..455ee7dad 100644 --- a/ircd/s_user.cc +++ b/ircd/s_user.cc @@ -27,81 +27,6 @@ namespace ircd { static void report_and_set_user_flags(client::client *, struct ConfItem *); void user_welcome(client::client *source_p); -char umodebuf[128]; - -static int orphaned_umodes = 0; - -int user_modes[256] = { - /* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0F */ - /* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1F */ - /* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x2F */ - /* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x3F */ - 0, /* @ */ - 0, /* A */ - 0, /* B */ - 0, /* C */ - umode::DEAF, /* D */ - 0, /* E */ - 0, /* F */ - 0, /* G */ - 0, /* H */ - 0, /* I */ - 0, /* J */ - 0, /* K */ - 0, /* L */ - 0, /* M */ - 0, /* N */ - 0, /* O */ - 0, /* P */ - umode::NOFORWARD, /* Q */ - umode::REGONLYMSG, /* R */ - umode::SERVICE, /* S */ - 0, /* T */ - 0, /* U */ - 0, /* V */ - 0, /* W */ - 0, /* X */ - 0, /* Y */ - umode::SSLCLIENT, /* Z */ - /* 0x5B */ 0, 0, 0, 0, 0, 0, /* 0x60 */ - umode::ADMIN, /* a */ - 0, /* b */ - 0, /* c */ - 0, /* d */ - 0, /* e */ - 0, /* f */ - umode::CALLERID, /* g */ - 0, /* h */ - umode::INVISIBLE, /* i */ - 0, /* j */ - 0, /* k */ - umode::LOCOPS, /* l */ - 0, /* m */ - 0, /* n */ - umode::OPER, /* o */ - 0, /* p */ - 0, /* q */ - 0, /* r */ - umode::SERVNOTICE, /* s */ - 0, /* t */ - 0, /* u */ - 0, /* v */ - umode::WALLOP, /* w */ - 0, /* x */ - 0, /* y */ - umode::OPERWALL, /* z */ - /* 0x7B */ 0, 0, 0, 0, 0, /* 0x7F */ - /* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9F */ - /* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9F */ - /* 0xA0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xAF */ - /* 0xB0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xBF */ - /* 0xC0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCF */ - /* 0xD0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xDF */ - /* 0xE0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xEF */ - /* 0xF0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xFF */ -}; -/* *INDENT-ON* */ - /* * show_lusers - * @@ -557,7 +482,7 @@ register_local_user(client::client *client_p, client::client *source_p) set_dyn_spoof(*source_p); } - source_p->mode |= umode(ConfigFileEntry.default_umodes & ~ConfigFileEntry.oper_only_umodes & ~orphaned_umodes); + source_p->mode |= (ConfigFileEntry.default_umodes & ~ConfigFileEntry.oper_only_umodes); call_hook(h_new_local_user, source_p); @@ -946,7 +871,7 @@ show_other_user_mode(client::client *source_p, client::client *target_p) *m++ = '+'; for (i = 0; i < 128; i++) /* >= 127 is extended ascii */ - if (target_p->mode & user_modes[i]) + if (target_p->mode & umode::table[i]) *m++ = (char) i; *m = '\0'; @@ -1026,7 +951,7 @@ user_mode(client::client *client_p, client::client *source_p, int parc, const ch *m++ = '+'; for (i = 0; i < 128; i++) /* >= 127 is extended ascii */ - if (source_p->mode & user_modes[i]) + if (source_p->mode & umode::table[i]) *m++ = (char) i; *m = '\0'; @@ -1084,7 +1009,7 @@ user_mode(client::client *client_p, client::client *source_p, int parc, const ch if(my_connect(*source_p)) { - clear(*source_p, umode(ConfigFileEntry.oper_only_umodes)); + clear(*source_p, ConfigFileEntry.oper_only_umodes); if (!is(*source_p, umode::SERVNOTICE) && source_p->snomask != 0) { source_p->snomask = 0; @@ -1151,12 +1076,11 @@ user_mode(client::client *client_p, client::client *source_p, int parc, const ch break; } - if((flag = user_modes[(unsigned char) *pm])) + if((flag = umode::table[(unsigned char) *pm])) { if(my_connect(*source_p) && ((!is_oper(*source_p) - && (ConfigFileEntry.oper_only_umodes & flag)) - || (orphaned_umodes & flag))) + && (ConfigFileEntry.oper_only_umodes & flag)))) { if (what == MODE_ADD || source_p->mode & flag) badflag = true; @@ -1164,9 +1088,9 @@ user_mode(client::client *client_p, client::client *source_p, int parc, const ch else { if(what == MODE_ADD) - set(*source_p, umode(flag)); + set(*source_p, flag); else - clear(*source_p, umode(flag)); + clear(*source_p, flag); } } else @@ -1245,7 +1169,7 @@ send_umode(client::client *client_p, client::client *source_p, int old, char *um for (i = 0; i < 128; i++) { - flag = user_modes[i]; + flag = umode::table[i]; if((flag & old) && !(source_p->mode & flag)) { @@ -1322,7 +1246,13 @@ user_welcome(client::client *source_p) sendto_one_numeric(source_p, RPL_YOURHOST, form_str(RPL_YOURHOST), get_listener_name(source_p->localClient->listener), info::version.c_str()); sendto_one_numeric(source_p, RPL_CREATED, form_str(RPL_CREATED), info::compiled.c_str()); - sendto_one_numeric(source_p, RPL_MYINFO, form_str(RPL_MYINFO), me.name, info::version.c_str(), umodebuf, chan::mode::arity[0], chan::mode::arity[1]); + + sendto_one_numeric(source_p, RPL_MYINFO, form_str(RPL_MYINFO), + me.name, + info::version.c_str(), + client::mode::available, + chan::mode::arity[0], + chan::mode::arity[1]); supported::show(*source_p); @@ -1355,17 +1285,15 @@ user_welcome(client::client *source_p) void oper_up(client::client *source_p, struct oper_conf *oper_p) { - using umode = client::mode::mode; - unsigned int old = source_p->mode, oldsnomask = source_p->snomask; hook_data_umode_changed hdata; set_oper(*source_p); if(oper_p->umodes) - source_p->mode |= umode(oper_p->umodes); + source_p->mode |= oper_p->umodes; else if(ConfigFileEntry.oper_umodes) - source_p->mode |= umode(ConfigFileEntry.oper_umodes); + source_p->mode |= ConfigFileEntry.oper_umodes; else source_p->mode |= client::mode::DEFAULT_OPER_UMODES; @@ -1425,62 +1353,6 @@ oper_up(client::client *source_p, struct oper_conf *oper_p) cache::motd::send_oper(*source_p); } -/* - * find_umode_slot - * - * inputs - NONE - * outputs - an available umode bitmask or - * 0 if no umodes are available - * side effects - NONE - */ -unsigned int -find_umode_slot(void) -{ - unsigned int all_umodes = 0, my_umode = 0, i; - - for (i = 0; i < 128; i++) - all_umodes |= user_modes[i]; - - for (my_umode = 1; my_umode && (all_umodes & my_umode); - my_umode <<= 1); - - return my_umode; -} - -void -construct_umodebuf(void) -{ - int i; - char *ptr = umodebuf; - static int prev_user_modes[128]; - - *ptr = '\0'; - - for (i = 0; i < 128; i++) - { - if (prev_user_modes[i] != 0 && prev_user_modes[i] != user_modes[i]) - { - if (user_modes[i] == 0) - { - orphaned_umodes |= prev_user_modes[i]; - sendto_realops_snomask(sno::DEBUG, L_ALL, "Umode +%c is now orphaned", i); - } - else - { - orphaned_umodes &= ~prev_user_modes[i]; - sendto_realops_snomask(sno::DEBUG, L_ALL, "Orphaned umode +%c is picked up by module", i); - } - user_modes[i] = prev_user_modes[i]; - } - else - prev_user_modes[i] = user_modes[i]; - if (user_modes[i]) - *ptr++ = (char) i; - } - - *ptr++ = '\0'; -} - void change_nick_user_host(client::client *target_p, const char *nick, const char *username, const char *host, int newts, const char *format, ...) diff --git a/ircd/send.cc b/ircd/send.cc index 0aaaed76d..4c463a866 100644 --- a/ircd/send.cc +++ b/ircd/send.cc @@ -1315,7 +1315,7 @@ sendto_wallops_flags(int flags, client::client *source_p, const char *pattern, . { client_p = (client::client *)ptr->data; - if (is(*client_p, umode(flags))) + if (is(*client_p, flags)) _send_linebuf(client_p, &linebuf); } diff --git a/ircd/supported.cc b/ircd/supported.cc index ff8a676b0..0cd78c578 100644 --- a/ircd/supported.cc +++ b/ircd/supported.cc @@ -140,7 +140,7 @@ supported::init() add("STATUSMSG", "@+"); add("CALLERID", [](ostream &s) { - if(ConfigFileEntry.oper_only_umodes & user_modes['g']) + if(ConfigFileEntry.oper_only_umodes & umode::table['g']) return; s << 'g'; @@ -162,7 +162,7 @@ supported::init() add("DEAF", [](ostream &s) { - if(ConfigFileEntry.oper_only_umodes & user_modes['D']) + if(ConfigFileEntry.oper_only_umodes & umode::table['D']) return; s << 'D'; diff --git a/modules/core/m_nick.cc b/modules/core/m_nick.cc index c53224e52..eda2cf9b1 100644 --- a/modules/core/m_nick.cc +++ b/modules/core/m_nick.cc @@ -1044,7 +1044,7 @@ register_client(client::client &client, client::client *server, m = &parv[4][1]; while(*m) { - flag = user_modes[(unsigned char) *m]; + flag = umode::table[(unsigned char) *m]; if(flag & umode::SERVICE) { @@ -1075,7 +1075,7 @@ register_client(client::client &client, client::client *server, if(!(source->mode & umode::OPER) && (flag & umode::OPER)) Count.oper++; - source->mode |= umode(flag); + source->mode |= flag; m++; } diff --git a/modules/m_scan.cc b/modules/m_scan.cc index d039c06f1..7e0c63d84 100644 --- a/modules/m_scan.cc +++ b/modules/m_scan.cc @@ -132,7 +132,7 @@ scan_umodes(struct MsgBuf *msgbuf_p, client::client &client, client::client &sou what = MODE_DEL; break; default: - if ((mode = user_modes[(unsigned char) *c]) != 0) + if ((mode = umode::table[(unsigned char) *c]) != 0) { if (what == MODE_ADD) allowed_umodes |= mode; @@ -236,7 +236,7 @@ scan_umodes(struct MsgBuf *msgbuf_p, client::client &client, client::client &sou for (i = 0; i < 128; i++) { - if (is(*target_p, umode(user_modes[i]))) + if (is(*target_p, umode::table[i])) *m++ = (char) i; }