From c74115f25c8ea3f67c75120c0a1398975bac03ad Mon Sep 17 00:00:00 2001 From: "Federico G. Schwindt" Date: Sun, 4 Aug 2013 18:28:04 +0100 Subject: [PATCH] Simplify mode checking on channels and users within a channel Add Channel_HasMode() and Channel_UserHasMode() and use it where possible. --- src/ngircd/channel.c | 100 ++++++++++++++++++++------------------- src/ngircd/channel.h | 4 +- src/ngircd/irc-channel.c | 34 +++++++------ src/ngircd/irc-info.c | 16 +++---- src/ngircd/irc-mode.c | 22 ++++----- src/ngircd/irc-op.c | 14 +++--- src/ngircd/irc.c | 6 +-- src/ngircd/numeric.c | 14 +++--- 8 files changed, 104 insertions(+), 106 deletions(-) diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c index 45bf615c..c5f65fe8 100644 --- a/src/ngircd/channel.c +++ b/src/ngircd/channel.c @@ -299,7 +299,6 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name, const char *Reason ) { CHANNEL *chan; - char *ptr, *target_modes; bool can_kick = false; assert(Peer != NULL); @@ -336,7 +335,7 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name, if(Client_Type(Peer) == CLIENT_USER) { /* Channel mode 'Q' and user mode 'q' on target: nobody but * IRC Operators and servers can kick the target user */ - if ((strchr(Channel_Modes(chan), 'Q') + if ((Channel_HasMode(chan, 'Q') || Client_HasMode(Target, 'q') || Client_Type(Target) == CLIENT_SERVICE) && !Client_HasMode(Origin, 'o')) { @@ -347,40 +346,28 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name, } /* Check if client has the rights to kick target */ - ptr = Channel_UserModes(chan, Peer); - target_modes = Channel_UserModes(chan, Target); - while(*ptr) { - /* Owner can kick everyone */ - if ( *ptr == 'q') { - can_kick = true; - break; - } - /* Admin can't kick owner */ - if ( *ptr == 'a' ) { - if (!strchr(target_modes, 'q')) { - can_kick = true; - break; - } - } - /* Op can't kick owner | admin */ - if ( *ptr == 'o' ) { - if (!strchr(target_modes, 'q') && - !strchr(target_modes, 'a')) { - can_kick = true; - break; - } - } - /* Half Op can't kick owner | admin | op */ - if ( *ptr == 'h' ) { - if (!strchr(target_modes, 'q') && - !strchr(target_modes, 'a') && - !strchr(target_modes, 'o')) { - can_kick = true; - break; - } - } - ptr++; - } + + /* Owner can kick everyone */ + if (Channel_UserHasMode(chan, Peer, 'q')) + can_kick = true; + + /* Admin can't kick owner */ + else if (Channel_UserHasMode(chan, Peer, 'a') && + !Channel_UserHasMode(chan, Target, 'q')) + can_kick = true; + + /* Op can't kick owner | admin */ + else if (Channel_UserHasMode(chan, Peer, 'o') && + !Channel_UserHasMode(chan, Target, 'q') && + !Channel_UserHasMode(chan, Target, 'a')) + can_kick = true; + + /* Half Op can't kick owner | admin | op */ + else if (Channel_UserHasMode(chan, Peer, 'h') && + !Channel_UserHasMode(chan, Target, 'q') && + !Channel_UserHasMode(chan, Target, 'a') && + !Channel_UserHasMode(chan, Target, 'o')) + can_kick = true; if(!can_kick) { IRC_WriteStrClient(Origin, ERR_CHANOPPRIVTOOLOW_MSG, @@ -433,7 +420,7 @@ Channel_CountVisible (CLIENT *Client) c = My_Channels; while(c) { if (Client) { - if (!strchr(Channel_Modes(c), 's') + if (!Channel_HasMode(c, 's') || Channel_IsMemberOf(c, Client)) count++; } else @@ -499,6 +486,14 @@ Channel_Modes( CHANNEL *Chan ) } /* Channel_Modes */ +GLOBAL bool +Channel_HasMode( CHANNEL *Chan, char Mode ) +{ + assert( Chan != NULL ); + return strchr( Chan->modes, Mode ) != NULL; +} /* Channel_HasMode */ + + GLOBAL char * Channel_Key( CHANNEL *Chan ) { @@ -636,7 +631,7 @@ Channel_ModeAdd( CHANNEL *Chan, char Mode ) assert( Chan != NULL ); x[0] = Mode; x[1] = '\0'; - if( ! strchr( Chan->modes, x[0] )) + if( ! Channel_HasMode( Chan, x[0] )) { /* Channel does not have this mode yet, set it */ strlcat( Chan->modes, x, sizeof( Chan->modes )); @@ -745,6 +740,13 @@ Channel_UserModes( CHANNEL *Chan, CLIENT *Client ) } /* Channel_UserModes */ +GLOBAL bool +Channel_UserHasMode( CHANNEL *Chan, CLIENT *Client, char Mode ) +{ + return strchr(Channel_UserModes(Chan, Client), Mode) != NULL; +} /* Channel_UserHasMode */ + + GLOBAL bool Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client ) { @@ -873,15 +875,15 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From) if (Channel_IsMemberOf(Chan, From)) { is_member = true; - if (strchr(Channel_UserModes(Chan, From), 'v')) + if (Channel_UserHasMode(Chan, From, 'v')) has_voice = true; - if (strchr(Channel_UserModes(Chan, From), 'h')) + if (Channel_UserHasMode(Chan, From, 'h')) is_halfop = true; - if (strchr(Channel_UserModes(Chan, From), 'o')) + if (Channel_UserHasMode(Chan, From, 'o')) is_op = true; - if (strchr(Channel_UserModes(Chan, From), 'a')) + if (Channel_UserHasMode(Chan, From, 'a')) is_chanadmin = true; - if (strchr(Channel_UserModes(Chan, From), 'q')) + if (Channel_UserHasMode(Chan, From, 'q')) is_owner = true; } @@ -891,17 +893,17 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From) * If channel mode n set: non-members cannot send to channel. * If channel mode m set: need voice. */ - if (strchr(Channel_Modes(Chan), 'n') && !is_member) + if (Channel_HasMode(Chan, 'n') && !is_member) return false; - if (strchr(Channel_Modes(Chan), 'M') && !Client_HasMode(From, 'R') + if (Channel_HasMode(Chan, 'M') && !Client_HasMode(From, 'R') && !Client_HasMode(From, 'o')) return false; if (has_voice || is_halfop || is_op || is_chanadmin || is_owner) return true; - if (strchr(Channel_Modes(Chan), 'm')) + if (Channel_HasMode(Chan, 'm')) return false; if (Lists_Check(&Chan->list_excepts, From)) @@ -918,7 +920,7 @@ Channel_Write(CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Command, if (!Can_Send_To_Channel(Chan, From)) { if (! SendErrors) return CONNECTED; /* no error, see RFC 2812 */ - if (strchr(Channel_Modes(Chan), 'M')) + if (Channel_HasMode(Chan, 'M')) return IRC_WriteStrClient(From, ERR_NEEDREGGEDNICK_MSG, Client_ID(From), Channel_Name(Chan)); else @@ -1089,7 +1091,7 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch } /* When channel is empty and is not pre-defined, delete */ - if( ! strchr( Channel_Modes( Chan ), 'P' )) + if( ! Channel_HasMode( Chan, 'P' )) { if( ! Get_First_Cl2Chan( NULL, Chan )) Delete_Channel( Chan ); } @@ -1217,7 +1219,7 @@ Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key) assert(Client != NULL); assert(Key != NULL); - if (!strchr(Chan->modes, 'k')) + if (!Channel_HasMode(Chan, 'k')) return true; if (*Key == '\0') return false; diff --git a/src/ngircd/channel.h b/src/ngircd/channel.h index d8607a9c..1bc77760 100644 --- a/src/ngircd/channel.h +++ b/src/ngircd/channel.h @@ -79,7 +79,6 @@ GLOBAL unsigned long Channel_MemberCount PARAMS(( CHANNEL *Chan )); GLOBAL int Channel_CountForUser PARAMS(( CLIENT *Client )); GLOBAL const char *Channel_Name PARAMS(( const CHANNEL *Chan )); -GLOBAL char *Channel_Modes PARAMS(( CHANNEL *Chan )); GLOBAL char *Channel_Topic PARAMS(( CHANNEL *Chan )); GLOBAL char *Channel_Key PARAMS(( CHANNEL *Chan )); GLOBAL unsigned long Channel_MaxUsers PARAMS(( CHANNEL *Chan )); @@ -106,9 +105,12 @@ GLOBAL bool Channel_IsValidName PARAMS(( const char *Name )); GLOBAL bool Channel_ModeAdd PARAMS(( CHANNEL *Chan, char Mode )); GLOBAL bool Channel_ModeDel PARAMS(( CHANNEL *Chan, char Mode )); +GLOBAL bool Channel_HasMode PARAMS(( CHANNEL *Chan, char Mode )); +GLOBAL char *Channel_Modes PARAMS(( CHANNEL *Chan )); GLOBAL bool Channel_UserModeAdd PARAMS(( CHANNEL *Chan, CLIENT *Client, char Mode )); GLOBAL bool Channel_UserModeDel PARAMS(( CHANNEL *Chan, CLIENT *Client, char Mode )); +GLOBAL bool Channel_UserHasMode PARAMS(( CHANNEL *Chan, CLIENT *Client, char Mode )); GLOBAL char *Channel_UserModes PARAMS(( CHANNEL *Chan, CLIENT *Client )); GLOBAL bool Channel_IsMemberOf PARAMS(( CHANNEL *Chan, CLIENT *Client )); diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c index 07a6e5a5..d06caa31 100644 --- a/src/ngircd/irc-channel.c +++ b/src/ngircd/irc-channel.c @@ -82,10 +82,9 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame, const char *key) { bool is_invited, is_banned, is_exception; - const char *channel_modes; /* Allow IRC operators to overwrite channel limits */ - if (strchr(Client_Modes(Client), 'o')) + if (Client_HasMode(Client, 'o')) return true; is_banned = Lists_Check(Channel_GetListBans(chan), Client); @@ -99,8 +98,7 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame, return false; } - channel_modes = Channel_Modes(chan); - if (strchr(channel_modes, 'i') && !is_invited) { + if (Channel_HasMode(chan, 'i') && !is_invited) { /* Channel is "invite-only" and client is not on invite list */ IRC_WriteStrClient(Client, ERR_INVITEONLYCHAN_MSG, Client_ID(Client), channame); @@ -115,7 +113,7 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame, return false; } - if (strchr(channel_modes, 'l') && + if (Channel_HasMode(chan, 'l') && (Channel_MaxUsers(chan) <= Channel_MemberCount(chan))) { /* There are more clints joined to this channel than allowed */ IRC_WriteStrClient(Client, ERR_CHANNELISFULL_MSG, @@ -123,7 +121,7 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame, return false; } - if (strchr(channel_modes, 'z') && !Conn_UsesSSL(Client_Conn(Client))) { + if (Channel_HasMode(chan, 'z') && !Conn_UsesSSL(Client_Conn(Client))) { /* Only "secure" clients are allowed, but clients doesn't * use SSL encryption */ IRC_WriteStrClient(Client, ERR_SECURECHANNEL_MSG, @@ -131,14 +129,14 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame, return false; } - if (strchr(channel_modes, 'O') && !Client_OperByMe(Client)) { + if (Channel_HasMode(chan, 'O') && !Client_OperByMe(Client)) { /* Only IRC operators are allowed! */ IRC_WriteStrClient(Client, ERR_OPONLYCHANNEL_MSG, Client_ID(Client), channame); return false; } - if (strchr(channel_modes, 'R') && !strchr(Client_Modes(Client), 'R')) { + if (Channel_HasMode(chan, 'R') && !Client_HasMode(Client, 'R')) { /* Only registered users are allowed! */ IRC_WriteStrClient(Client, ERR_REGONLYCHANNEL_MSG, Client_ID(Client), channame); @@ -167,8 +165,8 @@ join_set_channelmodes(CHANNEL *chan, CLIENT *target, const char *flags) /* If the channel is persistent (+P) and client is an IRC op: * make client chanop, if not disabled in configuration. */ - if (strchr(Channel_Modes(chan), 'P') && Conf_OperChanPAutoOp - && strchr(Client_Modes(target), 'o')) + if (Channel_HasMode(chan, 'P') && Conf_OperChanPAutoOp + && Client_HasMode(target, 'o')) Channel_UserModeAdd(chan, target, 'o'); } /* join_set_channelmodes */ @@ -530,13 +528,13 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req ) Channel_Name(chan)); } - if (strchr(Channel_Modes(chan), 't')) { + if (Channel_HasMode(chan, 't')) { /* Topic Lock. Is the user a channel op or IRC operator? */ if(!topic_power && - !strchr(Channel_UserModes(chan, from), 'h') && - !strchr(Channel_UserModes(chan, from), 'o') && - !strchr(Channel_UserModes(chan, from), 'a') && - !strchr(Channel_UserModes(chan, from), 'q')) + !Channel_UserHasMode(chan, from, 'h') && + !Channel_UserHasMode(chan, from, 'o') && + !Channel_UserHasMode(chan, from, 'a') && + !Channel_UserHasMode(chan, from, 'q')) return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(from), Channel_Name(chan)); @@ -619,7 +617,7 @@ IRC_LIST( CLIENT *Client, REQUEST *Req ) /* Check search pattern */ if (MatchCaseInsensitive(pattern, Channel_Name(chan))) { /* Gotcha! */ - if (!strchr(Channel_Modes(chan), 's') + if (!Channel_HasMode(chan, 's') || Channel_IsMemberOf(chan, from) || (!Conf_MorePrivacy && Client_OperByMe(Client))) { if ((Conf_MaxListSize > 0) @@ -697,9 +695,9 @@ IRC_CHANINFO( CLIENT *Client, REQUEST *Req ) Channel_SetModes(chan, &Req->argv[1][1]); if(Req->argc == 5) { - if(strchr(Channel_Modes(chan), 'k')) + if(Channel_HasMode(chan, 'k')) Channel_SetKey(chan, Req->argv[2]); - if(strchr(Channel_Modes(chan), 'l')) + if(Channel_HasMode(chan, 'l')) Channel_SetMaxUsers(chan, atol(Req->argv[3])); } else { /* Delete modes which we never want to inherit */ diff --git a/src/ngircd/irc-info.c b/src/ngircd/irc-info.c index 6fb2e31c..5d2ae36d 100644 --- a/src/ngircd/irc-info.c +++ b/src/ngircd/irc-info.c @@ -165,7 +165,7 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps) is_member = Channel_IsMemberOf(Chan, Client); /* Secret channel? */ - if (!is_member && strchr(Channel_Modes(Chan), 's')) + if (!is_member && Channel_HasMode(Chan, 's')) return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client), Channel_Name(Chan)); @@ -174,11 +174,11 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps) c = Channel_GetClient(cl2chan); client_modes = Client_Modes(c); - is_ircop = strchr(client_modes, 'o') != NULL; + is_ircop = Client_HasMode(c, 'o'); if (OnlyOps && !is_ircop) continue; - is_visible = strchr(client_modes, 'i') == NULL; + is_visible = Client_HasMode(c, 'i'); if (is_member || is_visible) { strlcpy(flags, who_flags_status(client_modes), sizeof(flags)); @@ -275,7 +275,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps) break; strlcpy(flags, who_flags_status(Client_Modes(c)), sizeof(flags)); - if (strchr(Client_Modes(c), 'o')) + if (Client_HasMode(c, 'o')) strlcat(flags, "*", sizeof(flags)); if (!write_whoreply(Client, c, "*", flags)) @@ -330,7 +330,7 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c) cl2chan = Channel_NextChannelOf(c, cl2chan); /* Secret channel? */ - if (strchr(Channel_Modes(chan), 's') + if (Channel_HasMode(chan, 's') && !Channel_IsMemberOf(chan, Client)) continue; @@ -833,7 +833,7 @@ IRC_NAMES( CLIENT *Client, REQUEST *Req ) while (c) { if (Client_Type(c) == CLIENT_USER && Channel_FirstChannelOf(c) == NULL - && !strchr(Client_Modes(c), 'i')) + && !Client_HasMode(c, 'i')) { /* its a user, concatenate ... */ if (rpl[strlen(rpl) - 1] != ':') @@ -1530,7 +1530,7 @@ IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan) return CONNECTED; /* Secret channel? */ - if (!is_member && strchr(Channel_Modes(Chan), 's')) + if (!is_member && Channel_HasMode(Chan, 's')) return CONNECTED; snprintf(str, sizeof(str), RPL_NAMREPLY_MSG, Client_ID(Client), "=", @@ -1539,7 +1539,7 @@ IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan) while (cl2chan) { cl = Channel_GetClient(cl2chan); - if (strchr(Client_Modes(cl), 'i')) + if (Client_HasMode(cl, 'i')) is_visible = false; else is_visible = true; diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c index cebddd22..0df848f3 100644 --- a/src/ngircd/irc-mode.c +++ b/src/ngircd/irc-mode.c @@ -436,7 +436,7 @@ static bool Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel) { char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], - argadd[CLIENT_PASS_LEN], *mode_ptr, *o_mode_ptr; + argadd[CLIENT_PASS_LEN], *mode_ptr; bool connected, set, skiponce, retval, use_servermode, is_halfop, is_op, is_admin, is_owner, is_machine, is_oper; int mode_arg, arg_arg, mode_arg_count = 0; @@ -547,18 +547,14 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel) arg_arg = -1; if(!is_machine && !is_oper) { - o_mode_ptr = Channel_UserModes(Channel, Client); - while( *o_mode_ptr ) { - if ( *o_mode_ptr == 'q') - is_owner = true; - if ( *o_mode_ptr == 'a') - is_admin = true; - if ( *o_mode_ptr == 'o') - is_op = true; - if ( *o_mode_ptr == 'h') - is_halfop = true; - o_mode_ptr++; - } + if (Channel_UserHasMode(Channel, Client, 'q')) + is_owner = true; + if (Channel_UserHasMode(Channel, Client, 'a')) + is_admin = true; + if (Channel_UserHasMode(Channel, Client, 'o')) + is_op = true; + if (Channel_UserHasMode(Channel, Client, 'h')) + is_halfop = true; } /* Validate modes */ diff --git a/src/ngircd/irc-op.c b/src/ngircd/irc-op.c index 23fcc71c..0d471512 100644 --- a/src/ngircd/irc-op.c +++ b/src/ngircd/irc-op.c @@ -162,17 +162,17 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req) return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG, Client_ID(Client), Req->argv[1]); /* Is the channel "invite-disallow"? */ - if (strchr(Channel_Modes(chan), 'V')) + if (Channel_HasMode(chan, 'V')) return IRC_WriteStrClient(from, ERR_NOINVITE_MSG, Client_ID(from), Channel_Name(chan)); /* Is the channel "invite-only"? */ - if (strchr(Channel_Modes(chan), 'i')) { + if (Channel_HasMode(chan, 'i')) { /* Yes. The user must be channel owner/admin/operator/halfop! */ - if (!strchr(Channel_UserModes(chan, from), 'q') && - !strchr(Channel_UserModes(chan, from), 'a') && - !strchr(Channel_UserModes(chan, from), 'o') && - !strchr(Channel_UserModes(chan, from), 'h')) + if (!Channel_UserHasMode(chan, from, 'q') && + !Channel_UserHasMode(chan, from, 'a') && + !Channel_UserHasMode(chan, from, 'o') && + !Channel_UserHasMode(chan, from, 'h')) return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(from), Channel_Name(chan)); remember = true; @@ -215,7 +215,7 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req) Client_ID(from), Req->argv[0], colon_if_necessary, Req->argv[1])) return DISCONNECTED; - if (strchr(Client_Modes(target), 'a') && + if (Client_HasMode(target, 'a') && !IRC_WriteStrClient(from, RPL_AWAY_MSG, Client_ID(from), Client_ID(target), Client_Away(target))) return DISCONNECTED; diff --git a/src/ngircd/irc.c b/src/ngircd/irc.c index ddef7d02..e4f48307 100644 --- a/src/ngircd/irc.c +++ b/src/ngircd/irc.c @@ -329,7 +329,7 @@ IRC_TRACE(CLIENT *Client, REQUEST *Req) return DISCONNECTED; } if (Client_Type(c) == CLIENT_USER - && strchr(Client_Modes(c), 'o')) { + && Client_HasMode(c, 'o')) { /* IRC Operator */ if (!IRC_WriteStrClient(from, RPL_TRACEOPERATOR_MSG, @@ -652,7 +652,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) } if (SendErrors && (Client_Type(Client) != CLIENT_SERVER) - && strchr(Client_Modes(cl), 'a')) { + && Client_HasMode(cl, 'a')) { /* Target is away */ if (!IRC_WriteStrClient(from, RPL_AWAY_MSG, Client_ID(from), @@ -708,7 +708,7 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask, cl = NULL; - if (strchr(Client_Modes(from), 'o') == NULL) { + if (!Client_HasMode(from, 'o')) { if (!SendErrors) return true; return IRC_WriteStrClient(from, ERR_NOPRIVILEGES_MSG, diff --git a/src/ngircd/numeric.c b/src/ngircd/numeric.c index f2c61e8a..a43739f1 100644 --- a/src/ngircd/numeric.c +++ b/src/ngircd/numeric.c @@ -68,15 +68,15 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan) strlcat(str, ",", sizeof(str)); /* Prepare user prefix (ChanOp, voiced, ...) */ - if (xop && strchr(Channel_UserModes(Chan, cl), 'q')) + if (xop && Channel_UserHasMode(Chan, cl, 'q')) strlcat(str, "~", sizeof(str)); - if (xop && strchr(Channel_UserModes(Chan, cl), 'a')) + if (xop && Channel_UserHasMode(Chan, cl, 'a')) strlcat(str, "&", sizeof(str)); - if (strchr(Channel_UserModes(Chan, cl), 'o')) + if (Channel_UserHasMode(Chan, cl, 'o')) strlcat(str, "@", sizeof(str)); - if (xop && strchr(Channel_UserModes(Chan, cl), 'h')) + if (xop && Channel_UserHasMode(Chan, cl, 'h')) strlcat(str, "%", sizeof(str)); - if (strchr(Channel_UserModes(Chan, cl), 'v')) + if (Channel_UserHasMode(Chan, cl, 'v')) strlcat(str, "+", sizeof(str)); strlcat(str, Client_ID(cl), sizeof(str)); @@ -232,8 +232,8 @@ Send_CHANINFO(CLIENT * Client, CHANNEL * Chan) if (!*modes && !*topic) return CONNECTED; - has_k = strchr(modes, 'k') != NULL; - has_l = strchr(modes, 'l') != NULL; + has_k = Channel_HasMode(Chan, 'k'); + has_l = Channel_HasMode(Chan, 'l'); /* send CHANINFO */ if (!has_k && !has_l) { -- 2.39.2