mirror of
https://github.com/matrix-construct/construct
synced 2025-01-14 00:34:18 +01:00
Upgrade channel membership lists.
This commit is contained in:
parent
276cad4275
commit
5752be41b8
33 changed files with 447 additions and 394 deletions
|
@ -52,7 +52,7 @@ m_findforwards(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *
|
||||||
/* Allow ircops to search for forwards to nonexistent channels */
|
/* Allow ircops to search for forwards to nonexistent channels */
|
||||||
if(!IsOper(source_p))
|
if(!IsOper(source_p))
|
||||||
{
|
{
|
||||||
if((chptr = find_channel(parv[1])) == NULL || (msptr = find_channel_membership(chptr, source_p)) == NULL)
|
if((chptr = find_channel(parv[1])) == NULL || (msptr = get(chptr->members, *source_p, std::nothrow)) == NULL)
|
||||||
{
|
{
|
||||||
sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
|
sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
|
||||||
form_str(ERR_NOTONCHANNEL), parv[1]);
|
form_str(ERR_NOTONCHANNEL), parv[1]);
|
||||||
|
|
|
@ -84,7 +84,7 @@ mo_ojoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
|
|
||||||
if(*parv[1] == '@')
|
if(*parv[1] == '@')
|
||||||
{
|
{
|
||||||
add_user_to_channel(chptr, source_p, chan::CHANOP);
|
add(*chptr, *source_p, chan::CHANOP);
|
||||||
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
||||||
":%s SJOIN %ld %s + :@%s",
|
":%s SJOIN %ld %s + :@%s",
|
||||||
me.id, (long) chptr->channelts, chptr->name.c_str(), source_p->id);
|
me.id, (long) chptr->channelts, chptr->name.c_str(), source_p->id);
|
||||||
|
@ -95,7 +95,7 @@ mo_ojoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
}
|
}
|
||||||
else if(*parv[1] == '+')
|
else if(*parv[1] == '+')
|
||||||
{
|
{
|
||||||
add_user_to_channel(chptr, source_p, chan::VOICE);
|
add(*chptr, *source_p, chan::VOICE);
|
||||||
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
||||||
":%s SJOIN %ld %s + :+%s",
|
":%s SJOIN %ld %s + :+%s",
|
||||||
me.id, (long) chptr->channelts, chptr->name.c_str(), source_p->id);
|
me.id, (long) chptr->channelts, chptr->name.c_str(), source_p->id);
|
||||||
|
@ -105,7 +105,7 @@ mo_ojoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
add_user_to_channel(chptr, source_p, chan::PEON);
|
add(*chptr, *source_p, chan::PEON);
|
||||||
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
||||||
":%s JOIN %ld %s +",
|
":%s JOIN %ld %s +",
|
||||||
source_p->id, (long) chptr->channelts, chptr->name.c_str());
|
source_p->id, (long) chptr->channelts, chptr->name.c_str());
|
||||||
|
|
|
@ -97,7 +97,7 @@ mo_okick(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((msptr = find_channel_membership(chptr, target_p)) == NULL)
|
if((msptr = get(chptr->members, *target_p, std::nothrow)) == NULL)
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL), parv[1], parv[2]);
|
sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL), parv[1], parv[2]);
|
||||||
return;
|
return;
|
||||||
|
@ -120,5 +120,6 @@ mo_okick(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
me.name, chptr->name.c_str(), who->name, comment);
|
me.name, chptr->name.c_str(), who->name, comment);
|
||||||
sendto_server(&me, chptr, CAP_TS6, NOCAPS,
|
sendto_server(&me, chptr, CAP_TS6, NOCAPS,
|
||||||
":%s KICK %s %s :%s", me.id, chptr->name.c_str(), who->id, comment);
|
":%s KICK %s %s :%s", me.id, chptr->name.c_str(), who->id, comment);
|
||||||
remove_user_from_channel(msptr);
|
|
||||||
|
del(*chptr, *target_p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ mo_omode(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now know the channel exists */
|
/* Now know the channel exists */
|
||||||
msptr = find_channel_membership(chptr, source_p);
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
wasonchannel = msptr != NULL;
|
wasonchannel = msptr != NULL;
|
||||||
|
|
||||||
if (is_chanop(msptr))
|
if (is_chanop(msptr))
|
||||||
|
@ -133,8 +133,8 @@ mo_omode(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
msptr->flags |= chan::CHANOP;
|
msptr->flags |= chan::CHANOP;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
add_user_to_channel(chptr, source_p, chan::CHANOP);
|
add(*chptr, *source_p, chan::CHANOP);
|
||||||
msptr = find_channel_membership(chptr, source_p);
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
}
|
}
|
||||||
set_channel_mode(client_p, source_p, chptr, msptr,
|
set_channel_mode(client_p, source_p, chptr, msptr,
|
||||||
parc - 2, parv + 2);
|
parc - 2, parv + 2);
|
||||||
|
@ -144,7 +144,7 @@ mo_omode(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
if (wasonchannel)
|
if (wasonchannel)
|
||||||
msptr->flags &= ~chan::CHANOP;
|
msptr->flags &= ~chan::CHANOP;
|
||||||
else
|
else
|
||||||
remove_user_from_channel(msptr);
|
del(*chptr, get_client(*msptr));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,9 +57,9 @@ mo_opme(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, chptr->members.head)
|
for(auto &pit : chptr->members.global)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
msptr = &pit.second;
|
||||||
|
|
||||||
if(is_chanop(msptr))
|
if(is_chanop(msptr))
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@ mo_opme(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msptr = find_channel_membership(chptr, source_p);
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
|
|
||||||
if(msptr == NULL)
|
if(msptr == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -80,7 +80,7 @@ m_remove(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
|
|
||||||
if(!IsServer(source_p))
|
if(!IsServer(source_p))
|
||||||
{
|
{
|
||||||
msptr = find_channel_membership(chptr, source_p);
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
|
|
||||||
if((msptr == NULL) && MyConnect(source_p))
|
if((msptr == NULL) && MyConnect(source_p))
|
||||||
{
|
{
|
||||||
|
@ -139,7 +139,7 @@ m_remove(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
msptr = find_channel_membership(chptr, who);
|
msptr = get(chptr->members, *who, std::nothrow);
|
||||||
|
|
||||||
if(msptr != NULL)
|
if(msptr != NULL)
|
||||||
{
|
{
|
||||||
|
@ -190,7 +190,7 @@ m_remove(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
":%s KICK %s %s :%s",
|
":%s KICK %s %s :%s",
|
||||||
use_id(source_p), chptr->name.c_str(), use_id(who), comment);
|
use_id(source_p), chptr->name.c_str(), use_id(who), comment);
|
||||||
|
|
||||||
remove_user_from_channel(msptr);
|
del(*chptr, get_client(*msptr));
|
||||||
}
|
}
|
||||||
else if (MyClient(source_p))
|
else if (MyClient(source_p))
|
||||||
sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
|
sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
|
||||||
|
|
|
@ -140,7 +140,7 @@ m_displaymsg(struct MsgBuf *msgbuf_p, struct Client *source_p, const char *chann
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(msptr = find_channel_membership(chptr, source_p)))
|
if(!(msptr = get(chptr->members, *source_p, std::nothrow)))
|
||||||
{
|
{
|
||||||
sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
|
sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
|
||||||
form_str(ERR_NOTONCHANNEL), chptr->name.c_str());
|
form_str(ERR_NOTONCHANNEL), chptr->name.c_str());
|
||||||
|
|
|
@ -43,7 +43,7 @@ h_scc_channel_join(void *vdata)
|
||||||
struct Client *source_p = data->client;
|
struct Client *source_p = data->client;
|
||||||
|
|
||||||
/* If they just joined a channel, and it only has one member, then they just created it. */
|
/* If they just joined a channel, and it only has one member, then they just created it. */
|
||||||
if(rb_dlink_list_length(&chptr->members) == 1 && is_chanop(find_channel_membership(chptr, source_p)))
|
if(size(chptr->members) == 1 && is_chanop(get(chptr->members, *source_p, std::nothrow)))
|
||||||
{
|
{
|
||||||
sendto_realops_snomask(snomask_modes['l'], L_NETWIDE, "%s is creating new channel %s",
|
sendto_realops_snomask(snomask_modes['l'], L_NETWIDE, "%s is creating new channel %s",
|
||||||
source_p->name, chptr->name.c_str());
|
source_p->name, chptr->name.c_str());
|
||||||
|
|
|
@ -165,11 +165,10 @@ int chans_add(struct chan *const chan)
|
||||||
if(!rb_radixtree_add(chans, chan->name.c_str(), chan))
|
if(!rb_radixtree_add(chans, chan->name.c_str(), chan))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rb_dlink_node *ptr;
|
for(const auto &pit : chan->members.global)
|
||||||
RB_DLINK_FOREACH(ptr, chan->members.head)
|
|
||||||
{
|
{
|
||||||
const auto msptr(reinterpret_cast<membership *>(ptr->data));
|
const auto &client(pit.first);
|
||||||
bloom_add_str(msptr->client->name);
|
bloom_add_str(client->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace chan {
|
||||||
IRCD_EXCEPTION(ircd::error, error)
|
IRCD_EXCEPTION(ircd::error, error)
|
||||||
IRCD_EXCEPTION(error, not_found)
|
IRCD_EXCEPTION(error, not_found)
|
||||||
IRCD_EXCEPTION(error, invalid_list)
|
IRCD_EXCEPTION(error, invalid_list)
|
||||||
|
IRCD_EXCEPTION(error, invalid_argument)
|
||||||
|
|
||||||
enum status
|
enum status
|
||||||
{
|
{
|
||||||
|
@ -96,17 +97,15 @@ uint operator~(const modes &);
|
||||||
|
|
||||||
struct membership
|
struct membership
|
||||||
{
|
{
|
||||||
rb_dlink_node channode;
|
using global = std::map<client *, membership>;
|
||||||
rb_dlink_node locchannode;
|
using local = std::list<membership *>;
|
||||||
rb_dlink_node usernode;
|
|
||||||
|
|
||||||
struct chan *chan;
|
|
||||||
Client *client;
|
|
||||||
unsigned int flags;
|
|
||||||
|
|
||||||
|
uint flags;
|
||||||
time_t bants;
|
time_t bants;
|
||||||
|
global::iterator git;
|
||||||
|
local::iterator lit;
|
||||||
|
|
||||||
membership();
|
membership(const uint &flags = 0);
|
||||||
~membership() noexcept;
|
~membership() noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -119,6 +118,27 @@ bool is_chanop_voiced(const membership *const &);
|
||||||
bool can_send_banned(const membership &);
|
bool can_send_banned(const membership &);
|
||||||
bool can_send_banned(const membership *const &);
|
bool can_send_banned(const membership *const &);
|
||||||
const char *find_status(const membership *const &msptr, const int &combine);
|
const char *find_status(const membership *const &msptr, const int &combine);
|
||||||
|
const client &get_client(const membership &);
|
||||||
|
client &get_client(membership &);
|
||||||
|
|
||||||
|
struct members
|
||||||
|
{
|
||||||
|
membership::global global;
|
||||||
|
membership::local local;
|
||||||
|
|
||||||
|
members();
|
||||||
|
~members() noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool empty(const members &);
|
||||||
|
size_t size(const members &);
|
||||||
|
bool local_empty(const members &);
|
||||||
|
size_t local_size(const members &);
|
||||||
|
bool exists(const members &, const client &);
|
||||||
|
const membership *get(const members &, const client &, std::nothrow_t);
|
||||||
|
const membership &get(const members &, const client &);
|
||||||
|
membership *get(members &, const client &, std::nothrow_t);
|
||||||
|
membership &get(members &, const client &);
|
||||||
|
|
||||||
bool has_prefix(const char *const &name);
|
bool has_prefix(const char *const &name);
|
||||||
bool has_prefix(const std::string &name);
|
bool has_prefix(const std::string &name);
|
||||||
|
@ -131,11 +151,8 @@ struct chan
|
||||||
struct modes mode;
|
struct modes mode;
|
||||||
std::string mode_lock;
|
std::string mode_lock;
|
||||||
struct topic topic;
|
struct topic topic;
|
||||||
|
struct members members;
|
||||||
rb_dlink_list members;
|
|
||||||
rb_dlink_list locmembers;
|
|
||||||
std::set<client *> invites;
|
std::set<client *> invites;
|
||||||
|
|
||||||
list bans;
|
list bans;
|
||||||
list excepts;
|
list excepts;
|
||||||
list invexs;
|
list invexs;
|
||||||
|
@ -160,6 +177,7 @@ struct chan
|
||||||
~chan() noexcept;
|
~chan() noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const auto &name(const chan &);
|
||||||
bool is_secret(const chan &);
|
bool is_secret(const chan &);
|
||||||
bool is_secret(const chan *const &);
|
bool is_secret(const chan *const &);
|
||||||
bool is_hidden(const chan &);
|
bool is_hidden(const chan &);
|
||||||
|
@ -206,9 +224,6 @@ void del_invite(chan &, client &);
|
||||||
void clear_invites(chan &);
|
void clear_invites(chan &);
|
||||||
|
|
||||||
bool flood_attack_channel(int p_or_n, client *source, chan *);
|
bool flood_attack_channel(int p_or_n, client *source, chan *);
|
||||||
void add_user_to_channel(chan *, client *, int flags);
|
|
||||||
void remove_user_from_channel(membership *);
|
|
||||||
void remove_user_from_channels(client *);
|
|
||||||
void invalidate_bancache_user(client *);
|
void invalidate_bancache_user(client *);
|
||||||
void channel_member_names(chan *, client *, int show_eon);
|
void channel_member_names(chan *, client *, int show_eon);
|
||||||
const char *channel_modes(chan *, client *who);
|
const char *channel_modes(chan *, client *who);
|
||||||
|
@ -227,13 +242,17 @@ int match_extban(const char *banstr, client *, chan *, long mode_type);
|
||||||
int valid_extban(const char *banstr, client *, chan *, long mode_type);
|
int valid_extban(const char *banstr, client *, chan *, long mode_type);
|
||||||
const char * get_extban_string(void);
|
const char * get_extban_string(void);
|
||||||
int get_channel_access(client *source, chan *, membership *, int dir, const char *modestr);
|
int get_channel_access(client *source, chan *, membership *, int dir, const char *modestr);
|
||||||
membership *find_channel_membership(chan *chptr, client *client_p);
|
|
||||||
void send_join(chan &, client &);
|
void send_join(chan &, client &);
|
||||||
|
|
||||||
//extern std::map<std::string, std::unique_ptr<chan>> chans;
|
//extern std::map<std::string, std::unique_ptr<chan>> chans;
|
||||||
extern rb_dlink_list global_channel_list;
|
extern rb_dlink_list global_channel_list;
|
||||||
|
|
||||||
|
// Add and remove clients from channels
|
||||||
|
void add(chan &, client &, const int &flags = PEON);
|
||||||
|
void del(chan &, client &);
|
||||||
|
void del(client &); // remove from all channels
|
||||||
|
|
||||||
|
// Initialize subsystem
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
|
||||||
|
@ -276,8 +295,7 @@ is_public(const chan *const &c)
|
||||||
inline bool
|
inline bool
|
||||||
is_member(const chan &c, const client &client)
|
is_member(const chan &c, const client &client)
|
||||||
{
|
{
|
||||||
//return client.user && get(c, client, std::nothrow) != nullptr;
|
return exists(c.members, client);
|
||||||
return find_channel_membership(const_cast<struct chan *>(&c), const_cast<Client *>(&client)) != nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
|
@ -322,6 +340,42 @@ valid_name(const std::string &name)
|
||||||
return !name.empty() && std::all_of(begin(name), end(name), rfc1459::is_chan);
|
return !name.empty() && std::all_of(begin(name), end(name), rfc1459::is_chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const auto &
|
||||||
|
name(const chan &chan)
|
||||||
|
{
|
||||||
|
return chan.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t
|
||||||
|
local_size(const members &m)
|
||||||
|
{
|
||||||
|
return std::distance(begin(m.local), end(m.local));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
local_empty(const members &m)
|
||||||
|
{
|
||||||
|
return m.local.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t
|
||||||
|
size(const members &m)
|
||||||
|
{
|
||||||
|
return m.global.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
empty(const members &m)
|
||||||
|
{
|
||||||
|
return m.global.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
exists(const members &m, const client &c)
|
||||||
|
{
|
||||||
|
return m.global.count(const_cast<client *>(&c));
|
||||||
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
is_chanop(const membership &m)
|
is_chanop(const membership &m)
|
||||||
{
|
{
|
||||||
|
@ -358,6 +412,18 @@ is_chanop_voiced(const membership *const &m)
|
||||||
return m && is_chanop_voiced(*m);
|
return m && is_chanop_voiced(*m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline client &
|
||||||
|
get_client(membership &m)
|
||||||
|
{
|
||||||
|
return *m.git->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const client &
|
||||||
|
get_client(const membership &m)
|
||||||
|
{
|
||||||
|
return *m.git->first;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
can_send_banned(const membership &m)
|
can_send_banned(const membership &m)
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,7 +68,7 @@ typedef int SSL_OPEN_CB(struct Client *, int status);
|
||||||
*/
|
*/
|
||||||
struct User
|
struct User
|
||||||
{
|
{
|
||||||
rb_dlink_list channel; /* chain of channel pointer blocks */
|
std::map<chan::chan *, chan::membership *> channel;
|
||||||
std::set<chan::chan *> invited;
|
std::set<chan::chan *> invited;
|
||||||
char *away; /* pointer to away message */
|
char *away; /* pointer to away message */
|
||||||
int refcnt; /* Number of times this block is referenced */
|
int refcnt; /* Number of times this block is referenced */
|
||||||
|
|
346
ircd/channel.cc
346
ircd/channel.cc
|
@ -49,8 +49,7 @@ chan::chan::chan(const std::string &name)
|
||||||
,mode{}
|
,mode{}
|
||||||
,mode_lock{}
|
,mode_lock{}
|
||||||
,topic{}
|
,topic{}
|
||||||
,members{0}
|
,members{}
|
||||||
,locmembers{0}
|
|
||||||
,join_count{0}
|
,join_count{0}
|
||||||
,join_delta{0}
|
,join_delta{0}
|
||||||
,flood_noticed{0}
|
,flood_noticed{0}
|
||||||
|
@ -74,13 +73,108 @@ noexcept
|
||||||
del_from_channel_hash(name.c_str(), this);
|
del_from_channel_hash(name.c_str(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
chan::membership::membership()
|
/* remove_user_from_channels()
|
||||||
:channode{0}
|
*
|
||||||
,locchannode{0}
|
* input - user to remove from all channels
|
||||||
,usernode{0}
|
* output -
|
||||||
,chan{nullptr}
|
* side effects - user is removed from all channels
|
||||||
,client{nullptr}
|
*/
|
||||||
,flags{0}
|
void
|
||||||
|
chan::del(client &client)
|
||||||
|
{
|
||||||
|
auto &client_chans(client.user->channel);
|
||||||
|
for(const auto &pit : client_chans)
|
||||||
|
{
|
||||||
|
auto &chan(*pit.first);
|
||||||
|
auto &member(*pit.second);
|
||||||
|
|
||||||
|
if (my(client))
|
||||||
|
chan.members.local.erase(member.lit);
|
||||||
|
|
||||||
|
chan.members.global.erase(member.git);
|
||||||
|
chan.invites.erase(&client);
|
||||||
|
|
||||||
|
if (empty(chan.members) && ~chan.mode & mode::PERMANENT)
|
||||||
|
delete &chan;
|
||||||
|
}
|
||||||
|
|
||||||
|
client_chans.clear();
|
||||||
|
client.user->invited.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
chan::del(chan &chan,
|
||||||
|
client &client)
|
||||||
|
{
|
||||||
|
// These are the relevant containers.
|
||||||
|
auto &global(chan.members.global);
|
||||||
|
auto &local(chan.members.local);
|
||||||
|
auto &client_chans(client.user->channel);
|
||||||
|
|
||||||
|
const auto it(client_chans.find(&chan));
|
||||||
|
if (it == end(client_chans))
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto &member(*it->second);
|
||||||
|
|
||||||
|
if (my(client))
|
||||||
|
chan.members.local.erase(member.lit);
|
||||||
|
|
||||||
|
chan.members.global.erase(member.git); // The member is destroyed at this point.
|
||||||
|
client_chans.erase(it);
|
||||||
|
|
||||||
|
if (empty(chan.members) && ~chan.mode & mode::PERMANENT)
|
||||||
|
delete &chan;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
chan::add(chan &chan,
|
||||||
|
client &client,
|
||||||
|
const int &flags)
|
||||||
|
{
|
||||||
|
if (!client.user)
|
||||||
|
{
|
||||||
|
s_assert(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are the relevant containers.
|
||||||
|
auto &global(chan.members.global);
|
||||||
|
auto &local(chan.members.local);
|
||||||
|
auto &client_chans(client.user->channel);
|
||||||
|
|
||||||
|
// Add client to channel's global map
|
||||||
|
const auto iit(global.emplace(&client, flags));
|
||||||
|
if (!iit.second)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// The global map hosts the membership structure.
|
||||||
|
auto &member(iit.first->second);
|
||||||
|
|
||||||
|
// Add iterator (pointer to the element) for constant time lookup/removal
|
||||||
|
member.git = iit.first;
|
||||||
|
|
||||||
|
// Add channel to client's channel map, pointing to the membership;
|
||||||
|
client_chans.emplace(&chan, &member);
|
||||||
|
|
||||||
|
// Add membership to a local list which can be iterated for local IO;
|
||||||
|
// iterator to this element is saved more crucially here to prevent linear removal
|
||||||
|
if (my(client))
|
||||||
|
member.lit = local.emplace(end(local), &member);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
chan::members::members()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
chan::members::~members()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
chan::membership::membership(const uint &flags)
|
||||||
|
:flags{flags}
|
||||||
,bants{0}
|
,bants{0}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -144,46 +238,66 @@ chan::send_join(chan &chan,
|
||||||
client.user->away);
|
client.user->away);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find_channel_membership()
|
chan::membership &
|
||||||
*
|
chan::get(members &members,
|
||||||
* input - channel to find them in, client to find
|
const client &client)
|
||||||
* output - membership of client in channel, else NULL
|
|
||||||
* side effects -
|
|
||||||
*/
|
|
||||||
chan::membership *
|
|
||||||
chan::find_channel_membership(chan *chptr, client *client_p)
|
|
||||||
{
|
{
|
||||||
struct membership *msptr;
|
if (!is_client(client))
|
||||||
rb_dlink_node *ptr;
|
throw invalid_argument();
|
||||||
|
|
||||||
if(!IsClient(client_p))
|
const auto key(const_cast<ircd::chan::client *>(&client)); //TODO: temp elaborated
|
||||||
return NULL;
|
const auto it(members.global.find(key));
|
||||||
|
if (it == end(members.global))
|
||||||
|
throw not_found();
|
||||||
|
|
||||||
/* Pick the most efficient list to use to be nice to things like
|
return it->second;
|
||||||
* CHANSERV which could be in a large number of channels
|
}
|
||||||
*/
|
|
||||||
if(rb_dlink_list_length(&chptr->members) < rb_dlink_list_length(&client_p->user->channel))
|
|
||||||
{
|
|
||||||
RB_DLINK_FOREACH(ptr, chptr->members.head)
|
|
||||||
{
|
|
||||||
msptr = (membership *)ptr->data;
|
|
||||||
|
|
||||||
if(msptr->client == client_p)
|
const chan::membership &
|
||||||
return msptr;
|
chan::get(const members &members,
|
||||||
}
|
const client &client)
|
||||||
}
|
{
|
||||||
else
|
if (!is_client(client))
|
||||||
{
|
throw invalid_argument();
|
||||||
RB_DLINK_FOREACH(ptr, client_p->user->channel.head)
|
|
||||||
{
|
|
||||||
msptr = (membership *)ptr->data;
|
|
||||||
|
|
||||||
if(msptr->chan == chptr)
|
const auto key(const_cast<ircd::chan::client *>(&client)); //TODO: temp elaborated
|
||||||
return msptr;
|
const auto it(members.global.find(key));
|
||||||
}
|
if (it == end(members.global))
|
||||||
}
|
throw not_found();
|
||||||
|
|
||||||
return NULL;
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
chan::membership *
|
||||||
|
chan::get(members &members,
|
||||||
|
const client &client,
|
||||||
|
std::nothrow_t)
|
||||||
|
{
|
||||||
|
if (!is_client(client))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const auto key(const_cast<ircd::chan::client *>(&client)); //TODO: temp elaborated
|
||||||
|
const auto it(members.global.find(key));
|
||||||
|
if (it == end(members.global))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const chan::membership *
|
||||||
|
chan::get(const members &members,
|
||||||
|
const client &client,
|
||||||
|
std::nothrow_t)
|
||||||
|
{
|
||||||
|
if (!is_client(client))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const auto key(const_cast<ircd::chan::client *>(&client)); //TODO: temp elaborated
|
||||||
|
const auto it(members.global.find(key));
|
||||||
|
if (it == end(members.global))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find_channel_status()
|
/* find_channel_status()
|
||||||
|
@ -215,102 +329,6 @@ chan::find_status(const membership *const &msptr,
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add_user_to_channel()
|
|
||||||
*
|
|
||||||
* input - channel to add client to, client to add, channel flags
|
|
||||||
* output -
|
|
||||||
* side effects - user is added to channel
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
chan::add_user_to_channel(chan *chptr, client *client_p, int flags)
|
|
||||||
{
|
|
||||||
membership *msptr;
|
|
||||||
|
|
||||||
s_assert(client_p->user != NULL);
|
|
||||||
if(client_p->user == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
msptr = new membership;
|
|
||||||
|
|
||||||
msptr->chan = chptr;
|
|
||||||
msptr->client = client_p;
|
|
||||||
msptr->flags = flags;
|
|
||||||
|
|
||||||
rb_dlinkAdd(msptr, &msptr->usernode, &client_p->user->channel);
|
|
||||||
rb_dlinkAdd(msptr, &msptr->channode, &chptr->members);
|
|
||||||
|
|
||||||
if(MyClient(client_p))
|
|
||||||
rb_dlinkAdd(msptr, &msptr->locchannode, &chptr->locmembers);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove_user_from_channel()
|
|
||||||
*
|
|
||||||
* input - membership pointer to remove from channel
|
|
||||||
* output -
|
|
||||||
* side effects - membership (thus user) is removed from channel
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
chan::remove_user_from_channel(membership *msptr)
|
|
||||||
{
|
|
||||||
client *client_p;
|
|
||||||
chan *chptr;
|
|
||||||
s_assert(msptr != NULL);
|
|
||||||
if(msptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
client_p = msptr->client;
|
|
||||||
chptr = msptr->chan;
|
|
||||||
|
|
||||||
rb_dlinkDelete(&msptr->usernode, &client_p->user->channel);
|
|
||||||
rb_dlinkDelete(&msptr->channode, &chptr->members);
|
|
||||||
|
|
||||||
if(client_p->servptr == &me)
|
|
||||||
rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers);
|
|
||||||
|
|
||||||
if(!(chptr->mode.mode & mode::PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0)
|
|
||||||
delete chptr;
|
|
||||||
|
|
||||||
delete msptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove_user_from_channels()
|
|
||||||
*
|
|
||||||
* input - user to remove from all channels
|
|
||||||
* output -
|
|
||||||
* side effects - user is removed from all channels
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
chan::remove_user_from_channels(client *client_p)
|
|
||||||
{
|
|
||||||
chan *chptr;
|
|
||||||
membership *msptr;
|
|
||||||
rb_dlink_node *ptr;
|
|
||||||
rb_dlink_node *next_ptr;
|
|
||||||
|
|
||||||
if(client_p == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->user->channel.head)
|
|
||||||
{
|
|
||||||
msptr = (membership *)ptr->data;
|
|
||||||
chptr = msptr->chan;
|
|
||||||
|
|
||||||
rb_dlinkDelete(&msptr->channode, &chptr->members);
|
|
||||||
|
|
||||||
if(client_p->servptr == &me)
|
|
||||||
rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers);
|
|
||||||
|
|
||||||
if(!(chptr->mode.mode & mode::PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0)
|
|
||||||
delete chptr;
|
|
||||||
|
|
||||||
delete msptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
client_p->user->channel.head = client_p->user->channel.tail = NULL;
|
|
||||||
client_p->user->channel.length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* invalidate_bancache_user()
|
/* invalidate_bancache_user()
|
||||||
*
|
*
|
||||||
* input - user to invalidate ban cache for
|
* input - user to invalidate ban cache for
|
||||||
|
@ -319,19 +337,17 @@ chan::remove_user_from_channels(client *client_p)
|
||||||
* to be used after a nick change
|
* to be used after a nick change
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
chan::invalidate_bancache_user(client *client_p)
|
chan::invalidate_bancache_user(client *client)
|
||||||
{
|
{
|
||||||
membership *msptr;
|
if(!client)
|
||||||
rb_dlink_node *ptr;
|
|
||||||
|
|
||||||
if(client_p == NULL)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, client_p->user->channel.head)
|
for(const auto &pair : client->user->channel)
|
||||||
{
|
{
|
||||||
msptr = (membership *)ptr->data;
|
auto &chan(*pair.first);
|
||||||
msptr->bants = 0;
|
auto &member(*pair.second);
|
||||||
msptr->flags &= ~BANNED;
|
member.bants = 0;
|
||||||
|
member.flags &= ~BANNED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,7 +374,6 @@ channel_pub_or_secret(chan::chan *const &chptr)
|
||||||
void
|
void
|
||||||
chan::channel_member_names(chan *chptr, client *client_p, int show_eon)
|
chan::channel_member_names(chan *chptr, client *client_p, int show_eon)
|
||||||
{
|
{
|
||||||
membership *msptr;
|
|
||||||
client *target_p;
|
client *target_p;
|
||||||
rb_dlink_node *ptr;
|
rb_dlink_node *ptr;
|
||||||
char lbuf[BUFSIZE];
|
char lbuf[BUFSIZE];
|
||||||
|
@ -376,10 +391,10 @@ chan::channel_member_names(chan *chptr, client *client_p, int show_eon)
|
||||||
|
|
||||||
t = lbuf + cur_len;
|
t = lbuf + cur_len;
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, chptr->members.head)
|
for(const auto &pair : chptr->members.global)
|
||||||
{
|
{
|
||||||
msptr = (membership *)ptr->data;
|
auto *const target_p(pair.first);
|
||||||
target_p = msptr->client;
|
const auto &member(pair.second);
|
||||||
|
|
||||||
if(IsInvisible(target_p) && !is_member(chptr, client_p))
|
if(IsInvisible(target_p) && !is_member(chptr, client_p))
|
||||||
continue;
|
continue;
|
||||||
|
@ -395,7 +410,7 @@ chan::channel_member_names(chan *chptr, client *client_p, int show_eon)
|
||||||
t = lbuf + mlen;
|
t = lbuf + mlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
tlen = sprintf(t, "%s%s!%s@%s ", find_status(msptr, stack),
|
tlen = sprintf(t, "%s%s!%s@%s ", find_status(&member, stack),
|
||||||
target_p->name, target_p->username, target_p->host);
|
target_p->name, target_p->username, target_p->host);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -409,7 +424,7 @@ chan::channel_member_names(chan *chptr, client *client_p, int show_eon)
|
||||||
t = lbuf + mlen;
|
t = lbuf + mlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
tlen = sprintf(t, "%s%s ", find_status(msptr, stack),
|
tlen = sprintf(t, "%s%s ", find_status(&member, stack),
|
||||||
target_p->name);
|
target_p->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -733,8 +748,7 @@ chan::can_join(client *source_p, chan *chptr, const char *key, const char **forw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(chptr->mode.limit &&
|
if(chptr->mode.limit && size(chptr->members) >= ulong(chptr->mode.limit))
|
||||||
rb_dlink_list_length(&chptr->members) >= (unsigned long) chptr->mode.limit)
|
|
||||||
i = ERR_CHANNELISFULL;
|
i = ERR_CHANNELISFULL;
|
||||||
if(chptr->mode.mode & mode::REGONLY && EmptyString(source_p->user->suser))
|
if(chptr->mode.mode & mode::REGONLY && EmptyString(source_p->user->suser))
|
||||||
i = ERR_NEEDREGGEDNICK;
|
i = ERR_NEEDREGGEDNICK;
|
||||||
|
@ -783,7 +797,7 @@ chan::can_send(chan *chptr, client *source_p, membership *msptr)
|
||||||
|
|
||||||
if(msptr == NULL)
|
if(msptr == NULL)
|
||||||
{
|
{
|
||||||
msptr = find_channel_membership(chptr, source_p);
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
|
|
||||||
if(msptr == NULL)
|
if(msptr == NULL)
|
||||||
{
|
{
|
||||||
|
@ -828,7 +842,7 @@ chan::can_send(chan *chptr, client *source_p, membership *msptr)
|
||||||
moduledata.approved = CAN_SEND_OPV;
|
moduledata.approved = CAN_SEND_OPV;
|
||||||
|
|
||||||
moduledata.client = source_p;
|
moduledata.client = source_p;
|
||||||
moduledata.chptr = msptr->chan;
|
moduledata.chptr = chptr;
|
||||||
moduledata.msptr = msptr;
|
moduledata.msptr = msptr;
|
||||||
moduledata.target = NULL;
|
moduledata.target = NULL;
|
||||||
moduledata.dir = moduledata.approved == CAN_SEND_NO? MODE_ADD : MODE_QUERY;
|
moduledata.dir = moduledata.approved == CAN_SEND_NO? MODE_ADD : MODE_QUERY;
|
||||||
|
@ -913,10 +927,11 @@ chan::find_bannickchange_channel(client *client_p)
|
||||||
sprintf(src_host, "%s!%s@%s", client_p->name, client_p->username, client_p->host);
|
sprintf(src_host, "%s!%s@%s", client_p->name, client_p->username, client_p->host);
|
||||||
sprintf(src_iphost, "%s!%s@%s", client_p->name, client_p->username, client_p->sockhost);
|
sprintf(src_iphost, "%s!%s@%s", client_p->name, client_p->username, client_p->sockhost);
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, client_p->user->channel.head)
|
for(const auto &pit : client_p->user->channel)
|
||||||
{
|
{
|
||||||
msptr = (membership *)ptr->data;
|
auto &chptr(pit.first);
|
||||||
chptr = msptr->chan;
|
auto &msptr(pit.second);
|
||||||
|
|
||||||
if (is_chanop_voiced(msptr))
|
if (is_chanop_voiced(msptr))
|
||||||
continue;
|
continue;
|
||||||
/* cached can_send */
|
/* cached can_send */
|
||||||
|
@ -1270,10 +1285,11 @@ chan::resv_chan_forcepart(const char *name, const char *reason, int temp_time)
|
||||||
chptr = find_channel(name);
|
chptr = find_channel(name);
|
||||||
if(chptr != NULL)
|
if(chptr != NULL)
|
||||||
{
|
{
|
||||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
|
// Iterate a copy of the local list while all of this is going on
|
||||||
|
auto local(chptr->members.local);
|
||||||
|
for(auto &msptr : local)
|
||||||
{
|
{
|
||||||
msptr = (membership *)ptr->data;
|
const auto target_p(msptr->git->first);
|
||||||
target_p = msptr->client;
|
|
||||||
|
|
||||||
if(IsExemptResv(target_p))
|
if(IsExemptResv(target_p))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1285,7 +1301,7 @@ chan::resv_chan_forcepart(const char *name, const char *reason, int temp_time)
|
||||||
target_p->name, target_p->username,
|
target_p->name, target_p->username,
|
||||||
target_p->host, chptr->name.c_str(), target_p->name);
|
target_p->host, chptr->name.c_str(), target_p->name);
|
||||||
|
|
||||||
remove_user_from_channel(msptr);
|
del(*chptr, *target_p);
|
||||||
|
|
||||||
/* notify opers & user they were removed from the channel */
|
/* notify opers & user they were removed from the channel */
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||||
|
|
|
@ -409,8 +409,7 @@ pretty_mask(const char *idmask)
|
||||||
* side effects - numeric sent if not allowed
|
* side effects - numeric sent if not allowed
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
check_forward(struct Client *source_p, chan::chan *chptr,
|
check_forward(Client *source_p, chan::chan *chptr, const char *forward)
|
||||||
const char *forward)
|
|
||||||
{
|
{
|
||||||
chan::chan *targptr = NULL;
|
chan::chan *targptr = NULL;
|
||||||
chan::membership *msptr;
|
chan::membership *msptr;
|
||||||
|
@ -436,11 +435,13 @@ check_forward(struct Client *source_p, chan::chan *chptr,
|
||||||
}
|
}
|
||||||
if(MyClient(source_p) && !(targptr->mode.mode & mode::FREETARGET))
|
if(MyClient(source_p) && !(targptr->mode.mode & mode::FREETARGET))
|
||||||
{
|
{
|
||||||
if((msptr = find_channel_membership(targptr, source_p)) == NULL ||
|
auto *const msptr(get(targptr->members, *source_p, std::nothrow));
|
||||||
chan::get_channel_access(source_p, targptr, msptr, MODE_QUERY, NULL) < chan::CHANOP)
|
if(!msptr || get_channel_access(source_p, targptr, msptr, MODE_QUERY, NULL) < chan::CHANOP)
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
|
||||||
me.name, source_p->name, targptr->name.c_str());
|
me.name,
|
||||||
|
source_p->name,
|
||||||
|
targptr->name.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -954,7 +955,7 @@ mode::functor::op(client *source_p, chan *chptr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mstptr = find_channel_membership(chptr, targ_p);
|
mstptr = get(chptr->members, *targ_p, std::nothrow);
|
||||||
|
|
||||||
if(mstptr == NULL)
|
if(mstptr == NULL)
|
||||||
{
|
{
|
||||||
|
@ -1030,7 +1031,7 @@ mode::functor::voice(client *source_p, chan *chptr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mstptr = find_channel_membership(chptr, targ_p);
|
mstptr = get(chptr->members, *targ_p, std::nothrow);
|
||||||
|
|
||||||
if(mstptr == NULL)
|
if(mstptr == NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1265,10 +1265,10 @@ exit_generic_client(struct Client *client_p, struct Client *source_p, struct Cli
|
||||||
source_p->name,
|
source_p->name,
|
||||||
source_p->username, source_p->host, comment);
|
source_p->username, source_p->host, comment);
|
||||||
|
|
||||||
chan::remove_user_from_channels(source_p);
|
chan::del(*source_p);
|
||||||
|
|
||||||
/* Should not be in any channels now */
|
/* Should not be in any channels now */
|
||||||
s_assert(source_p->user->channel.head == NULL);
|
s_assert(source_p->user->channel.empty());
|
||||||
|
|
||||||
// Clean up invitefield
|
// Clean up invitefield
|
||||||
for (auto &chan : source_p->user->invited)
|
for (auto &chan : source_p->user->invited)
|
||||||
|
@ -1839,10 +1839,10 @@ free_user(struct User *user, struct Client *client_p)
|
||||||
/*
|
/*
|
||||||
* sanity check
|
* sanity check
|
||||||
*/
|
*/
|
||||||
if(user->refcnt < 0 || !user->invited.empty() || user->channel.head)
|
if(user->refcnt < 0 || !user->invited.empty() || !user->channel.empty())
|
||||||
{
|
{
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||||
"* %p user (%s!%s@%s) %p %lu %p %lu %d *",
|
"* %p user (%s!%s@%s) %p %lu %lu %d *",
|
||||||
client_p,
|
client_p,
|
||||||
client_p ? client_p->
|
client_p ? client_p->
|
||||||
name : "<noname>",
|
name : "<noname>",
|
||||||
|
@ -1850,12 +1850,11 @@ free_user(struct User *user, struct Client *client_p)
|
||||||
client_p->host,
|
client_p->host,
|
||||||
user,
|
user,
|
||||||
user->invited.size(),
|
user->invited.size(),
|
||||||
user->channel.head,
|
user->channel.size(),
|
||||||
rb_dlink_list_length(&user->channel),
|
|
||||||
user->refcnt);
|
user->refcnt);
|
||||||
s_assert(!user->refcnt);
|
s_assert(!user->refcnt);
|
||||||
s_assert(user->invited.empty());
|
s_assert(user->invited.empty());
|
||||||
s_assert(!user->channel.head);
|
s_assert(user->channel.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_bh_free(user_heap, user);
|
rb_bh_free(user_heap, user);
|
||||||
|
|
|
@ -646,11 +646,12 @@ burst_TS6(struct Client *client_p)
|
||||||
|
|
||||||
t = buf + mlen;
|
t = buf + mlen;
|
||||||
|
|
||||||
RB_DLINK_FOREACH(uptr, chptr->members.head)
|
for (auto &pair : chptr->members.global)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)uptr->data;
|
msptr = &pair.second;
|
||||||
|
auto *const client(pair.first);
|
||||||
|
|
||||||
tlen = strlen(use_id(msptr->client)) + 1;
|
tlen = strlen(use_id(client)) + 1;
|
||||||
if(is_chanop(msptr))
|
if(is_chanop(msptr))
|
||||||
tlen++;
|
tlen++;
|
||||||
if(is_voiced(msptr))
|
if(is_voiced(msptr))
|
||||||
|
@ -664,13 +665,13 @@ burst_TS6(struct Client *client_p)
|
||||||
t = buf + mlen;
|
t = buf + mlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(t, "%s%s ", chan::find_status(msptr, 1), use_id(msptr->client));
|
sprintf(t, "%s%s ", chan::find_status(msptr, 1), use_id(client));
|
||||||
|
|
||||||
cur_len += tlen;
|
cur_len += tlen;
|
||||||
t += tlen;
|
t += tlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rb_dlink_list_length(&chptr->members) > 0)
|
if (!empty(chptr->members))
|
||||||
{
|
{
|
||||||
/* remove trailing space */
|
/* remove trailing space */
|
||||||
*(t-1) = '\0';
|
*(t-1) = '\0';
|
||||||
|
|
|
@ -1473,11 +1473,10 @@ change_nick_user_host(struct Client *target_p, const char *nick, const char *use
|
||||||
{
|
{
|
||||||
rb_dlink_node *ptr;
|
rb_dlink_node *ptr;
|
||||||
chan::chan *chptr;
|
chan::chan *chptr;
|
||||||
chan::membership *mscptr;
|
|
||||||
int changed = irccmp(target_p->name, nick);
|
int changed = irccmp(target_p->name, nick);
|
||||||
int changed_case = strcmp(target_p->name, nick);
|
int changed_case = strcmp(target_p->name, nick);
|
||||||
int do_qjm = irccmp(target_p->username, user) || irccmp(target_p->host, host);
|
int do_qjm = irccmp(target_p->username, user) || irccmp(target_p->host, host);
|
||||||
char mode[10], modeval[NICKLEN * 2 + 2], reason[256], *mptr;
|
char mode[10], modeval[NICKLEN * 2 + 2], reason[256];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
modeval[0] = '\0';
|
modeval[0] = '\0';
|
||||||
|
@ -1499,20 +1498,20 @@ change_nick_user_host(struct Client *target_p, const char *nick, const char *use
|
||||||
target_p->name, target_p->username, target_p->host,
|
target_p->name, target_p->username, target_p->host,
|
||||||
reason);
|
reason);
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, target_p->user->channel.head)
|
for(const auto &pit : target_p->user->channel)
|
||||||
{
|
{
|
||||||
mscptr = (chan::membership *)ptr->data;
|
auto &chan(*pit.first);
|
||||||
chptr = mscptr->chan;
|
auto &member(*pit.second);
|
||||||
mptr = mode;
|
char *mptr(mode);
|
||||||
|
|
||||||
if(is_chanop(mscptr))
|
if(is_chanop(member))
|
||||||
{
|
{
|
||||||
*mptr++ = 'o';
|
*mptr++ = 'o';
|
||||||
strcat(modeval, nick);
|
strcat(modeval, nick);
|
||||||
strcat(modeval, " ");
|
strcat(modeval, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_voiced(mscptr))
|
if(is_voiced(member))
|
||||||
{
|
{
|
||||||
*mptr++ = 'v';
|
*mptr++ = 'v';
|
||||||
strcat(modeval, nick);
|
strcat(modeval, nick);
|
||||||
|
@ -1520,16 +1519,16 @@ change_nick_user_host(struct Client *target_p, const char *nick, const char *use
|
||||||
|
|
||||||
*mptr = '\0';
|
*mptr = '\0';
|
||||||
|
|
||||||
sendto_channel_local_with_capability_butone(target_p, chan::ALL_MEMBERS, NOCAPS, CLICAP_EXTENDED_JOIN | CLICAP_CHGHOST, chptr,
|
sendto_channel_local_with_capability_butone(target_p, chan::ALL_MEMBERS, NOCAPS, CLICAP_EXTENDED_JOIN | CLICAP_CHGHOST, &chan,
|
||||||
":%s!%s@%s JOIN %s", nick, user, host, chptr->name.c_str());
|
":%s!%s@%s JOIN %s", nick, user, host, chan.name.c_str());
|
||||||
sendto_channel_local_with_capability_butone(target_p, chan::ALL_MEMBERS, CLICAP_EXTENDED_JOIN, CLICAP_CHGHOST, chptr,
|
sendto_channel_local_with_capability_butone(target_p, chan::ALL_MEMBERS, CLICAP_EXTENDED_JOIN, CLICAP_CHGHOST, &chan,
|
||||||
":%s!%s@%s JOIN %s %s :%s", nick, user, host, chptr->name.c_str(),
|
":%s!%s@%s JOIN %s %s :%s", nick, user, host, chan.name.c_str(),
|
||||||
EmptyString(target_p->user->suser) ? "*" : target_p->user->suser,
|
EmptyString(target_p->user->suser) ? "*" : target_p->user->suser,
|
||||||
target_p->info);
|
target_p->info);
|
||||||
|
|
||||||
if(*mode)
|
if(*mode)
|
||||||
sendto_channel_local_with_capability_butone(target_p, chan::ALL_MEMBERS, NOCAPS, CLICAP_CHGHOST, chptr,
|
sendto_channel_local_with_capability_butone(target_p, chan::ALL_MEMBERS, NOCAPS, CLICAP_CHGHOST, &chan,
|
||||||
":%s MODE %s +%s %s", target_p->servptr->name, chptr->name.c_str(), mode, modeval);
|
":%s MODE %s +%s %s", target_p->servptr->name, chan.name.c_str(), mode, modeval);
|
||||||
|
|
||||||
*modeval = '\0';
|
*modeval = '\0';
|
||||||
}
|
}
|
||||||
|
|
74
ircd/send.cc
74
ircd/send.cc
|
@ -485,8 +485,6 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
|
||||||
va_list args;
|
va_list args;
|
||||||
buf_head_t rb_linebuf_local;
|
buf_head_t rb_linebuf_local;
|
||||||
buf_head_t rb_linebuf_id;
|
buf_head_t rb_linebuf_id;
|
||||||
struct Client *target_p;
|
|
||||||
chan::membership *msptr;
|
|
||||||
rb_dlink_node *ptr;
|
rb_dlink_node *ptr;
|
||||||
rb_dlink_node *next_ptr;
|
rb_dlink_node *next_ptr;
|
||||||
int current_capmask = 0;
|
int current_capmask = 0;
|
||||||
|
@ -506,10 +504,10 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
|
||||||
linebuf_put_msgbuf(&msgbuf, &rb_linebuf_local, NOCAPS, "%s", buf);
|
linebuf_put_msgbuf(&msgbuf, &rb_linebuf_local, NOCAPS, "%s", buf);
|
||||||
rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf);
|
rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf);
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
|
for(const auto &pair : chptr->members.global)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
auto *const target_p(pair.first);
|
||||||
target_p = msptr->client;
|
const auto &member(pair.second);
|
||||||
|
|
||||||
if(!MyClient(source_p) && (IsIOError(target_p->from) || target_p->from == one))
|
if(!MyClient(source_p) && (IsIOError(target_p->from) || target_p->from == one))
|
||||||
continue;
|
continue;
|
||||||
|
@ -517,7 +515,7 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
|
||||||
if(MyClient(source_p) && !IsCapable(source_p, CLICAP_ECHO_MESSAGE) && target_p == one)
|
if(MyClient(source_p) && !IsCapable(source_p, CLICAP_ECHO_MESSAGE) && target_p == one)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(type && ((msptr->flags & type) == 0))
|
if(type && ((member.flags & type) == 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(IsDeaf(target_p))
|
if(IsDeaf(target_p))
|
||||||
|
@ -572,8 +570,6 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p,
|
||||||
buf_head_t rb_linebuf_local;
|
buf_head_t rb_linebuf_local;
|
||||||
buf_head_t rb_linebuf_old;
|
buf_head_t rb_linebuf_old;
|
||||||
buf_head_t rb_linebuf_new;
|
buf_head_t rb_linebuf_new;
|
||||||
struct Client *target_p;
|
|
||||||
chan::membership *msptr;
|
|
||||||
rb_dlink_node *ptr;
|
rb_dlink_node *ptr;
|
||||||
rb_dlink_node *next_ptr;
|
rb_dlink_node *next_ptr;
|
||||||
|
|
||||||
|
@ -606,10 +602,10 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p,
|
||||||
":%s %s =%s :%s",
|
":%s %s =%s :%s",
|
||||||
use_id(source_p), command, chptr->name.c_str(), text);
|
use_id(source_p), command, chptr->name.c_str(), text);
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
|
for(const auto &pair : chptr->members.global)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
auto *const target_p(pair.first);
|
||||||
target_p = msptr->client;
|
const auto &member(pair.second);
|
||||||
|
|
||||||
if(!MyClient(source_p) && (IsIOError(target_p->from) || target_p->from == one))
|
if(!MyClient(source_p) && (IsIOError(target_p->from) || target_p->from == one))
|
||||||
continue;
|
continue;
|
||||||
|
@ -617,7 +613,7 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p,
|
||||||
if(MyClient(source_p) && !IsCapable(source_p, CLICAP_ECHO_MESSAGE) && target_p == one)
|
if(MyClient(source_p) && !IsCapable(source_p, CLICAP_ECHO_MESSAGE) && target_p == one)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if((msptr->flags & chan::CHANOP) == 0)
|
if((member.flags & chan::CHANOP) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(IsDeaf(target_p))
|
if(IsDeaf(target_p))
|
||||||
|
@ -660,10 +656,6 @@ sendto_channel_local(int type, chan::chan *chptr, const char *pattern, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
buf_head_t linebuf;
|
buf_head_t linebuf;
|
||||||
chan::membership *msptr;
|
|
||||||
struct Client *target_p;
|
|
||||||
rb_dlink_node *ptr;
|
|
||||||
rb_dlink_node *next_ptr;
|
|
||||||
|
|
||||||
rb_linebuf_newbuf(&linebuf);
|
rb_linebuf_newbuf(&linebuf);
|
||||||
|
|
||||||
|
@ -671,10 +663,10 @@ sendto_channel_local(int type, chan::chan *chptr, const char *pattern, ...)
|
||||||
rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
|
rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
|
for (const auto &pair : chptr->members.global)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
auto *const target_p(pair.first);
|
||||||
target_p = msptr->client;
|
const auto &member(pair.second);
|
||||||
|
|
||||||
if(IsIOError(target_p))
|
if(IsIOError(target_p))
|
||||||
continue;
|
continue;
|
||||||
|
@ -684,7 +676,7 @@ sendto_channel_local(int type, chan::chan *chptr, const char *pattern, ...)
|
||||||
if (!IsOper(target_p))
|
if (!IsOper(target_p))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if(type && ((msptr->flags & type) == 0))
|
else if(type && ((member.flags & type) == 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
_send_linebuf(target_p, &linebuf);
|
_send_linebuf(target_p, &linebuf);
|
||||||
|
@ -703,18 +695,13 @@ _sendto_channel_local_with_capability_butone(struct Client *one, int type, int c
|
||||||
const char *pattern, va_list * args)
|
const char *pattern, va_list * args)
|
||||||
{
|
{
|
||||||
buf_head_t linebuf;
|
buf_head_t linebuf;
|
||||||
chan::membership *msptr;
|
|
||||||
struct Client *target_p;
|
|
||||||
rb_dlink_node *ptr;
|
|
||||||
rb_dlink_node *next_ptr;
|
|
||||||
|
|
||||||
rb_linebuf_newbuf(&linebuf);
|
rb_linebuf_newbuf(&linebuf);
|
||||||
rb_linebuf_putmsg(&linebuf, pattern, args, NULL);
|
rb_linebuf_putmsg(&linebuf, pattern, args, NULL);
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
|
for(const auto &member : chptr->members.local)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
const auto target_p(member->git->first);
|
||||||
target_p = msptr->client;
|
|
||||||
|
|
||||||
if (target_p == one)
|
if (target_p == one)
|
||||||
continue;
|
continue;
|
||||||
|
@ -724,7 +711,7 @@ _sendto_channel_local_with_capability_butone(struct Client *one, int type, int c
|
||||||
!NotCapable(target_p, negcaps))
|
!NotCapable(target_p, negcaps))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(type && ((msptr->flags & type) == 0))
|
if(type && ((member->flags & type) == 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
_send_linebuf(target_p, &linebuf);
|
_send_linebuf(target_p, &linebuf);
|
||||||
|
@ -780,8 +767,6 @@ sendto_channel_local_butone(struct Client *one, int type, chan::chan *chptr, con
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
buf_head_t linebuf;
|
buf_head_t linebuf;
|
||||||
chan::membership *msptr;
|
|
||||||
struct Client *target_p;
|
|
||||||
struct MsgBuf msgbuf;
|
struct MsgBuf msgbuf;
|
||||||
rb_dlink_node *ptr;
|
rb_dlink_node *ptr;
|
||||||
rb_dlink_node *next_ptr;
|
rb_dlink_node *next_ptr;
|
||||||
|
@ -794,10 +779,9 @@ sendto_channel_local_butone(struct Client *one, int type, chan::chan *chptr, con
|
||||||
rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
|
rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
|
for(const auto &member : chptr->members.local)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
const auto target_p(member->git->first);
|
||||||
target_p = msptr->client;
|
|
||||||
|
|
||||||
if(target_p == one)
|
if(target_p == one)
|
||||||
continue;
|
continue;
|
||||||
|
@ -805,7 +789,7 @@ sendto_channel_local_butone(struct Client *one, int type, chan::chan *chptr, con
|
||||||
if(IsIOError(target_p))
|
if(IsIOError(target_p))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(type && ((msptr->flags & type) == 0))
|
if(type && ((member->flags & type) == 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* attach the present linebuf to the target */
|
/* attach the present linebuf to the target */
|
||||||
|
@ -848,15 +832,14 @@ sendto_common_channels_local(struct Client *user, int cap, int negcap, const cha
|
||||||
|
|
||||||
++current_serial;
|
++current_serial;
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
|
for(const auto &pit : user->user->channel)
|
||||||
{
|
{
|
||||||
mscptr = (chan::membership *)ptr->data;
|
auto &chptr(pit.first);
|
||||||
chptr = mscptr->chan;
|
auto &mscptr(pit.second);
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
|
for(const auto &msptr : chptr->members.local)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)uptr->data;
|
const auto target_p(msptr->git->first);
|
||||||
target_p = msptr->client;
|
|
||||||
|
|
||||||
if(IsIOError(target_p) ||
|
if(IsIOError(target_p) ||
|
||||||
target_p->serial == current_serial ||
|
target_p->serial == current_serial ||
|
||||||
|
@ -915,15 +898,14 @@ sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, co
|
||||||
/* Skip them -- jilles */
|
/* Skip them -- jilles */
|
||||||
user->serial = current_serial;
|
user->serial = current_serial;
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
|
for(const auto &pit : user->user->channel)
|
||||||
{
|
{
|
||||||
mscptr = (membership *)ptr->data;
|
auto &chptr(pit.first);
|
||||||
chptr = mscptr->chan;
|
auto &mscptr(pit.second);
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
|
for(const auto &msptr : chptr->members.local)
|
||||||
{
|
{
|
||||||
msptr = (membership *)uptr->data;
|
const auto target_p(msptr->git->first);
|
||||||
target_p = msptr->client;
|
|
||||||
|
|
||||||
if(IsIOError(target_p) ||
|
if(IsIOError(target_p) ||
|
||||||
target_p->serial == current_serial ||
|
target_p->serial == current_serial ||
|
||||||
|
|
|
@ -27,18 +27,18 @@ namespace ircd {
|
||||||
static int add_hashed_target(struct Client *source_p, uint32_t hashv);
|
static int add_hashed_target(struct Client *source_p, uint32_t hashv);
|
||||||
|
|
||||||
chan::chan *
|
chan::chan *
|
||||||
find_allowing_channel(struct Client *source_p, struct Client *target_p)
|
find_allowing_channel(struct Client *source, struct Client *target)
|
||||||
{
|
{
|
||||||
rb_dlink_node *ptr;
|
for(const auto &pit : source->user->channel)
|
||||||
chan::membership *msptr;
|
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, source_p->user->channel.head)
|
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
auto &chan(*pit.first);
|
||||||
if (is_chanop_voiced(msptr) && is_member(msptr->chan, target_p))
|
auto &member(*pit.second);
|
||||||
return msptr->chan;
|
|
||||||
|
if (is_chanop_voiced(member) && is_member(chan, *target))
|
||||||
|
return &chan;
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -48,7 +48,7 @@ chm_noctcp_process(hook_data_privmsg_channel *data)
|
||||||
data->approved = ERR_CANNOTSENDTOCHAN;
|
data->approved = ERR_CANNOTSENDTOCHAN;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (rb_dlink_list_length(&data->chptr->locmembers) > (unsigned)(GlobalSetOptions.floodcount / 2))
|
else if (local_size(data->chptr->members) > (unsigned)(GlobalSetOptions.floodcount / 2))
|
||||||
data->source_p->large_ctcp_sent = rb_current_time();
|
data->source_p->large_ctcp_sent = rb_current_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -221,7 +221,7 @@ m_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
||||||
/* JOIN 0 simply parts all channels the user is in */
|
/* JOIN 0 simply parts all channels the user is in */
|
||||||
if(*name == '0' && !atoi(name))
|
if(*name == '0' && !atoi(name))
|
||||||
{
|
{
|
||||||
if(source_p->user->channel.head == NULL)
|
if(source_p->user->channel.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
do_join_0(&me, source_p);
|
do_join_0(&me, source_p);
|
||||||
|
@ -265,10 +265,10 @@ m_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
||||||
flags = chan::CHANOP;
|
flags = chan::CHANOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((rb_dlink_list_length(&source_p->user->channel) >=
|
if(((source_p->user->channel.size()) >=
|
||||||
(unsigned long) ConfigChannel.max_chans_per_user) &&
|
(unsigned long) ConfigChannel.max_chans_per_user) &&
|
||||||
(!IsExtendChans(source_p) ||
|
(!IsExtendChans(source_p) ||
|
||||||
(rb_dlink_list_length(&source_p->user->channel) >=
|
(source_p->user->channel.size() >=
|
||||||
(unsigned long) ConfigChannel.max_chans_per_user_large)))
|
(unsigned long) ConfigChannel.max_chans_per_user_large)))
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS),
|
sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS),
|
||||||
|
@ -309,7 +309,7 @@ m_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
||||||
chan::check_spambot_warning(source_p, name);
|
chan::check_spambot_warning(source_p, name);
|
||||||
|
|
||||||
/* add the user to the channel */
|
/* add the user to the channel */
|
||||||
add_user_to_channel(chptr, source_p, flags);
|
add(*chptr, *source_p, flags);
|
||||||
if (chptr->mode.join_num &&
|
if (chptr->mode.join_num &&
|
||||||
rb_current_time() - chptr->join_delta >= chptr->mode.join_time)
|
rb_current_time() - chptr->join_delta >= chptr->mode.join_time)
|
||||||
{
|
{
|
||||||
|
@ -482,7 +482,7 @@ ms_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
|
||||||
|
|
||||||
if(!is_member(chptr, source_p))
|
if(!is_member(chptr, source_p))
|
||||||
{
|
{
|
||||||
add_user_to_channel(chptr, source_p, chan::PEON);
|
add(*chptr, *source_p, chan::PEON);
|
||||||
if (chptr->mode.join_num &&
|
if (chptr->mode.join_num &&
|
||||||
rb_current_time() - chptr->join_delta >= chptr->mode.join_time)
|
rb_current_time() - chptr->join_delta >= chptr->mode.join_time)
|
||||||
{
|
{
|
||||||
|
@ -637,12 +637,11 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
{
|
{
|
||||||
chan::membership *msptr;
|
chan::membership *msptr;
|
||||||
struct Client *who;
|
struct Client *who;
|
||||||
int l = rb_dlink_list_length(&chptr->members);
|
int l = size(chptr->members);
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
|
for(const auto &msptr : chptr->members.local)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
who = &get_client(*msptr);
|
||||||
who = msptr->client;
|
|
||||||
sendto_one(who, ":%s KICK %s %s :Net Rider",
|
sendto_one(who, ":%s KICK %s %s :Net Rider",
|
||||||
me.name, chptr->name.c_str(), who->name);
|
me.name, chptr->name.c_str(), who->name);
|
||||||
|
|
||||||
|
@ -650,7 +649,7 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
":%s KICK %s %s :Net Rider",
|
":%s KICK %s %s :Net Rider",
|
||||||
me.id, chptr->name.c_str(),
|
me.id, chptr->name.c_str(),
|
||||||
who->id);
|
who->id);
|
||||||
remove_user_from_channel(msptr);
|
del(*chptr, *who);
|
||||||
if (--l == 0)
|
if (--l == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -822,7 +821,7 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
|
|
||||||
if(!is_member(chptr, target_p))
|
if(!is_member(chptr, target_p))
|
||||||
{
|
{
|
||||||
add_user_to_channel(chptr, target_p, fl);
|
add(*chptr, *target_p, fl);
|
||||||
send_join(*chptr, *target_p);
|
send_join(*chptr, *target_p);
|
||||||
joins++;
|
joins++;
|
||||||
}
|
}
|
||||||
|
@ -953,18 +952,19 @@ do_join_0(struct Client *client_p, struct Client *source_p)
|
||||||
|
|
||||||
sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s JOIN 0", use_id(source_p));
|
sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s JOIN 0", use_id(source_p));
|
||||||
|
|
||||||
while((ptr = source_p->user->channel.head))
|
for(const auto &pit : source_p->user->channel)
|
||||||
{
|
{
|
||||||
if(MyConnect(source_p) &&
|
if(MyConnect(source_p) &&
|
||||||
!IsOper(source_p) && !IsExemptSpambot(source_p))
|
!IsOper(source_p) && !IsExemptSpambot(source_p))
|
||||||
chan::check_spambot_warning(source_p, NULL);
|
chan::check_spambot_warning(source_p, NULL);
|
||||||
|
|
||||||
msptr = (chan::membership *)ptr->data;
|
auto &msptr(pit.second);
|
||||||
chptr = msptr->chan;
|
auto &chptr(pit.first);
|
||||||
sendto_channel_local(chan::ALL_MEMBERS, chptr, ":%s!%s@%s PART %s",
|
sendto_channel_local(chan::ALL_MEMBERS, chptr, ":%s!%s@%s PART %s",
|
||||||
source_p->name,
|
source_p->name,
|
||||||
source_p->username, source_p->host, chptr->name.c_str());
|
source_p->username, source_p->host, chptr->name.c_str());
|
||||||
remove_user_from_channel(msptr);
|
|
||||||
|
del(*chptr, get_client(*msptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1162,7 +1162,6 @@ set_final_mode(chan::modes *mode, chan::modes *oldmode)
|
||||||
static void
|
static void
|
||||||
remove_our_modes(chan::chan *chptr, struct Client *source_p)
|
remove_our_modes(chan::chan *chptr, struct Client *source_p)
|
||||||
{
|
{
|
||||||
chan::membership *msptr;
|
|
||||||
rb_dlink_node *ptr;
|
rb_dlink_node *ptr;
|
||||||
char lmodebuf[chan::mode::BUFLEN];
|
char lmodebuf[chan::mode::BUFLEN];
|
||||||
char *lpara[chan::mode::MAXPARAMS];
|
char *lpara[chan::mode::MAXPARAMS];
|
||||||
|
@ -1175,14 +1174,15 @@ remove_our_modes(chan::chan *chptr, struct Client *source_p)
|
||||||
for(i = 0; i < chan::mode::MAXPARAMS; i++)
|
for(i = 0; i < chan::mode::MAXPARAMS; i++)
|
||||||
lpara[i] = NULL;
|
lpara[i] = NULL;
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, chptr->members.head)
|
for(auto &pit : chptr->members.global)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
auto &client(pit.first);
|
||||||
|
auto &msptr(pit.second);
|
||||||
|
|
||||||
if(is_chanop(msptr))
|
if(is_chanop(msptr))
|
||||||
{
|
{
|
||||||
msptr->flags &= ~chan::CHANOP;
|
msptr.flags &= ~chan::CHANOP;
|
||||||
lpara[count++] = msptr->client->name;
|
lpara[count++] = client->name;
|
||||||
*mbuf++ = 'o';
|
*mbuf++ = 'o';
|
||||||
|
|
||||||
/* +ov, might not fit so check. */
|
/* +ov, might not fit so check. */
|
||||||
|
@ -1206,15 +1206,15 @@ remove_our_modes(chan::chan *chptr, struct Client *source_p)
|
||||||
lpara[i] = NULL;
|
lpara[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
msptr->flags &= ~chan::VOICE;
|
msptr.flags &= ~chan::VOICE;
|
||||||
lpara[count++] = msptr->client->name;
|
lpara[count++] = client->name;
|
||||||
*mbuf++ = 'v';
|
*mbuf++ = 'v';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(is_voiced(msptr))
|
else if(is_voiced(msptr))
|
||||||
{
|
{
|
||||||
msptr->flags &= ~chan::VOICE;
|
msptr.flags &= ~chan::VOICE;
|
||||||
lpara[count++] = msptr->client->name;
|
lpara[count++] = client->name;
|
||||||
*mbuf++ = 'v';
|
*mbuf++ = 'v';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -75,7 +75,7 @@ m_kick(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
||||||
|
|
||||||
if(!IsServer(source_p))
|
if(!IsServer(source_p))
|
||||||
{
|
{
|
||||||
msptr = find_channel_membership(chptr, source_p);
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
|
|
||||||
if((msptr == NULL) && MyConnect(source_p))
|
if((msptr == NULL) && MyConnect(source_p))
|
||||||
{
|
{
|
||||||
|
@ -114,7 +114,7 @@ m_kick(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
msptr = find_channel_membership(chptr, who);
|
msptr = get(chptr->members, *who, std::nothrow);
|
||||||
|
|
||||||
if(msptr != NULL)
|
if(msptr != NULL)
|
||||||
{
|
{
|
||||||
|
@ -168,7 +168,8 @@ m_kick(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
||||||
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
||||||
":%s KICK %s %s :%s",
|
":%s KICK %s %s :%s",
|
||||||
use_id(source_p), chptr->name.c_str(), use_id(who), comment);
|
use_id(source_p), chptr->name.c_str(), use_id(who), comment);
|
||||||
remove_user_from_channel(msptr);
|
|
||||||
|
del(*chptr, *who);
|
||||||
}
|
}
|
||||||
else if (MyClient(source_p))
|
else if (MyClient(source_p))
|
||||||
sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
|
sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,
|
||||||
|
|
|
@ -336,7 +336,7 @@ build_target_list(enum message_type msgtype, struct Client *client_p,
|
||||||
{
|
{
|
||||||
chan::membership *msptr;
|
chan::membership *msptr;
|
||||||
|
|
||||||
msptr = find_channel_membership(chptr, source_p);
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
|
|
||||||
if(!IsServer(source_p) && !IsService(source_p) && !is_chanop_voiced(msptr))
|
if(!IsServer(source_p) && !IsService(source_p) && !is_chanop_voiced(msptr))
|
||||||
{
|
{
|
||||||
|
|
|
@ -120,7 +120,7 @@ m_mode(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
msptr = find_channel_membership(chptr, source_p);
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
|
|
||||||
/* Finish the flood grace period... */
|
/* Finish the flood grace period... */
|
||||||
if(MyClient(source_p) && !IsFloodDone(source_p))
|
if(MyClient(source_p) && !IsFloodDone(source_p))
|
||||||
|
@ -182,7 +182,7 @@ ms_tmode(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
msptr = find_channel_membership(chptr, source_p);
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
|
|
||||||
set_channel_mode(client_p, source_p, chptr, msptr, parc - 3, parv + 3);
|
set_channel_mode(client_p, source_p, chptr, msptr, parc - 3, parv + 3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ part_one_client(struct Client *client_p, struct Client *source_p, char *name, co
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
msptr = find_channel_membership(chptr, source_p);
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
if(msptr == NULL)
|
if(msptr == NULL)
|
||||||
{
|
{
|
||||||
sendto_one_numeric(source_p, ERR_NOTONCHANNEL, form_str(ERR_NOTONCHANNEL), name);
|
sendto_one_numeric(source_p, ERR_NOTONCHANNEL, form_str(ERR_NOTONCHANNEL), name);
|
||||||
|
@ -145,7 +145,7 @@ part_one_client(struct Client *client_p, struct Client *source_p, char *name, co
|
||||||
chptr->name.c_str());
|
chptr->name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_user_from_channel(msptr);
|
del(*chptr, *source_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -212,7 +212,6 @@ m_chantrace(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou
|
||||||
{
|
{
|
||||||
struct Client *target_p;
|
struct Client *target_p;
|
||||||
chan::chan *chptr;
|
chan::chan *chptr;
|
||||||
chan::membership *msptr;
|
|
||||||
const char *sockhost;
|
const char *sockhost;
|
||||||
const char *name;
|
const char *name;
|
||||||
rb_dlink_node *ptr;
|
rb_dlink_node *ptr;
|
||||||
|
@ -251,10 +250,10 @@ m_chantrace(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, chptr->members.head)
|
for(const auto &pit : chptr->members.global)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
auto &target_p(pit.first);
|
||||||
target_p = msptr->client;
|
auto &member(pit.second);
|
||||||
|
|
||||||
if(EmptyString(target_p->sockhost))
|
if(EmptyString(target_p->sockhost))
|
||||||
sockhost = empty_sockhost;
|
sockhost = empty_sockhost;
|
||||||
|
|
|
@ -112,7 +112,7 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
msptr = find_channel_membership(chptr, source_p);
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
if(MyClient(source_p) && (msptr == NULL))
|
if(MyClient(source_p) && (msptr == NULL))
|
||||||
{
|
{
|
||||||
sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
|
sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
|
||||||
|
|
|
@ -98,7 +98,7 @@ m_knock(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
|
||||||
|
|
||||||
if(!((chptr->mode.mode & chan::mode::INVITEONLY) || (*chptr->mode.key) ||
|
if(!((chptr->mode.mode & chan::mode::INVITEONLY) || (*chptr->mode.key) ||
|
||||||
(chptr->mode.limit &&
|
(chptr->mode.limit &&
|
||||||
rb_dlink_list_length(&chptr->members) >= (unsigned long)chptr->mode.limit)))
|
size(chptr->members) >= (unsigned long)chptr->mode.limit)))
|
||||||
{
|
{
|
||||||
sendto_one_numeric(source_p, ERR_CHANOPEN,
|
sendto_one_numeric(source_p, ERR_CHANOPEN,
|
||||||
form_str(ERR_CHANOPEN), name);
|
form_str(ERR_CHANOPEN), name);
|
||||||
|
|
|
@ -291,7 +291,7 @@ static void list_one_channel(struct Client *source_p, chan::chan *chptr,
|
||||||
strip_colour(topic);
|
strip_colour(topic);
|
||||||
sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name,
|
sendto_one(source_p, form_str(RPL_LIST), me.name, source_p->name,
|
||||||
visible ? "" : "!",
|
visible ? "" : "!",
|
||||||
chptr->name.c_str(), rb_dlink_list_length(&chptr->members),
|
chptr->name.c_str(), size(chptr->members),
|
||||||
topic);
|
topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,8 +422,7 @@ static void safelist_one_channel(struct Client *source_p, chan::chan *chptr, str
|
||||||
if (!visible && !params->operspy)
|
if (!visible && !params->operspy)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((unsigned int)chptr->members.length < params->users_min
|
if (size(chptr->members) < params->users_min || size(chptr->members) > params->users_max)
|
||||||
|| (unsigned int)chptr->members.length > params->users_max)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (params->topic_min && chptr->topic.time < params->topic_min)
|
if (params->topic_min && chptr->topic.time < params->topic_min)
|
||||||
|
|
|
@ -113,7 +113,6 @@ names_global(struct Client *source_p)
|
||||||
rb_dlink_node *lp, *ptr;
|
rb_dlink_node *lp, *ptr;
|
||||||
struct Client *target_p;
|
struct Client *target_p;
|
||||||
chan::chan *chptr = NULL;
|
chan::chan *chptr = NULL;
|
||||||
chan::membership *msptr;
|
|
||||||
char buf[BUFSIZE];
|
char buf[BUFSIZE];
|
||||||
char *t;
|
char *t;
|
||||||
|
|
||||||
|
@ -143,10 +142,9 @@ names_global(struct Client *source_p)
|
||||||
* both were missed out above. if the target is on a
|
* both were missed out above. if the target is on a
|
||||||
* common channel with source, its already been shown.
|
* common channel with source, its already been shown.
|
||||||
*/
|
*/
|
||||||
RB_DLINK_FOREACH(lp, target_p->user->channel.head)
|
for(const auto &pit : target_p->user->channel)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)lp->data;
|
auto &chptr(pit.first);
|
||||||
chptr = msptr->chan;
|
|
||||||
|
|
||||||
if(is_public(chptr) || is_member(chptr, source_p) || is_secret(chptr))
|
if(is_public(chptr) || is_member(chptr, source_p) || is_secret(chptr))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1336,7 +1336,7 @@ stats_memory (struct Client *source_p)
|
||||||
{
|
{
|
||||||
users_counted++;
|
users_counted++;
|
||||||
users_invited_count += target_p->user->invited.size();
|
users_invited_count += target_p->user->invited.size();
|
||||||
user_channels += rb_dlink_list_length(&target_p->user->channel);
|
user_channels += target_p->user->channel.size();
|
||||||
if(target_p->user->away)
|
if(target_p->user->away)
|
||||||
{
|
{
|
||||||
aways_counted++;
|
aways_counted++;
|
||||||
|
@ -1352,7 +1352,7 @@ stats_memory (struct Client *source_p)
|
||||||
channel_count++;
|
channel_count++;
|
||||||
channel_memory += (strlen(chptr->name.c_str()) + sizeof(chan::chan));
|
channel_memory += (strlen(chptr->name.c_str()) + sizeof(chan::chan));
|
||||||
|
|
||||||
channel_users += rb_dlink_list_length(&chptr->members);
|
channel_users += size(chptr->members);
|
||||||
channel_invites += chptr->invites.size();
|
channel_invites += chptr->invites.size();
|
||||||
|
|
||||||
channel_bans += size(*chptr, chan::mode::BAN);
|
channel_bans += size(*chptr, chan::mode::BAN);
|
||||||
|
|
|
@ -85,7 +85,7 @@ m_topic(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
|
||||||
/* setting topic */
|
/* setting topic */
|
||||||
if(parc > 2)
|
if(parc > 2)
|
||||||
{
|
{
|
||||||
msptr = find_channel_membership(chptr, source_p);
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
|
|
||||||
if(msptr == NULL)
|
if(msptr == NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,7 +54,7 @@ static void do_who_on_channel(struct Client *source_p, chan::chan *chptr,
|
||||||
struct who_format *fmt);
|
struct who_format *fmt);
|
||||||
static void who_global(struct Client *source_p, const char *mask, int server_oper, int operspy, struct who_format *fmt);
|
static void who_global(struct Client *source_p, const char *mask, int server_oper, int operspy, struct who_format *fmt);
|
||||||
static void do_who(struct Client *source_p,
|
static void do_who(struct Client *source_p,
|
||||||
struct Client *target_p, chan::membership *msptr,
|
struct Client *target_p, chan::chan *, chan::membership *msptr,
|
||||||
struct who_format *fmt);
|
struct who_format *fmt);
|
||||||
|
|
||||||
struct Message who_msgtab = {
|
struct Message who_msgtab = {
|
||||||
|
@ -144,10 +144,10 @@ m_who(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p,
|
||||||
if(source_p->user == NULL)
|
if(source_p->user == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if((lp = source_p->user->channel.head) != NULL)
|
if (!source_p->user->channel.empty())
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)lp->data;
|
auto *const chan(begin(source_p->user->channel)->first);
|
||||||
do_who_on_channel(source_p, msptr->chan, server_oper, true, &fmt);
|
do_who_on_channel(source_p, chan, server_oper, true, &fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendto_one(source_p, form_str(RPL_ENDOFWHO),
|
sendto_one(source_p, form_str(RPL_ENDOFWHO),
|
||||||
|
@ -176,7 +176,7 @@ m_who(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p,
|
||||||
|
|
||||||
if(chptr != NULL)
|
if(chptr != NULL)
|
||||||
{
|
{
|
||||||
if (!IsOper(source_p) && !ratelimit_client_who(source_p, rb_dlink_list_length(&chptr->members)/50))
|
if (!IsOper(source_p) && !ratelimit_client_who(source_p, size(chptr->members)/50))
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(RPL_LOAD2HI),
|
sendto_one(source_p, form_str(RPL_LOAD2HI),
|
||||||
me.name, source_p->name, "WHO");
|
me.name, source_p->name, "WHO");
|
||||||
|
@ -207,27 +207,27 @@ m_who(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p,
|
||||||
int isinvis = 0;
|
int isinvis = 0;
|
||||||
|
|
||||||
isinvis = IsInvisible(target_p);
|
isinvis = IsInvisible(target_p);
|
||||||
RB_DLINK_FOREACH(lp, target_p->user->channel.head)
|
for(const auto &pit : target_p->user->channel)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)lp->data;
|
chptr = pit.first;
|
||||||
chptr = msptr->chan;
|
msptr = get(chptr->members, *source_p, std::nothrow);
|
||||||
|
|
||||||
member = is_member(chptr, source_p);
|
|
||||||
|
|
||||||
if(isinvis && !member)
|
if(isinvis && !member)
|
||||||
|
{
|
||||||
|
msptr = nullptr;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if(member || (!isinvis && is_public(chptr)))
|
if(member || (!isinvis && is_public(chptr)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
msptr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we stopped midlist, lp->data is the membership for
|
/* if we stopped midlist, msptr is the membership for
|
||||||
* target_p of chptr
|
* target_p of chptr
|
||||||
*/
|
*/
|
||||||
if(lp != NULL)
|
do_who(source_p, target_p, chptr, msptr, &fmt);
|
||||||
do_who(source_p, target_p, (chan::membership *)lp->data, &fmt);
|
|
||||||
else
|
|
||||||
do_who(source_p, target_p, NULL, &fmt);
|
|
||||||
|
|
||||||
sendto_one(source_p, form_str(RPL_ENDOFWHO),
|
sendto_one(source_p, form_str(RPL_ENDOFWHO),
|
||||||
me.name, source_p->name, mask);
|
me.name, source_p->name, mask);
|
||||||
|
@ -286,32 +286,28 @@ who_common_channel(struct Client *source_p, chan::chan *chptr,
|
||||||
const char *mask, int server_oper, int *maxmatches,
|
const char *mask, int server_oper, int *maxmatches,
|
||||||
struct who_format *fmt)
|
struct who_format *fmt)
|
||||||
{
|
{
|
||||||
chan::membership *msptr;
|
for(const auto &pit : chptr->members.global)
|
||||||
struct Client *target_p;
|
|
||||||
rb_dlink_node *ptr;
|
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, chptr->members.head)
|
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
const auto &target(pit.first);
|
||||||
target_p = msptr->client;
|
const auto &member(pit.second);
|
||||||
|
|
||||||
if(!IsInvisible(target_p) || IsMarked(target_p))
|
if(!IsInvisible(target) || IsMarked(target))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(server_oper && !IsOper(target_p))
|
if(server_oper && !IsOper(target))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SetMark(target_p);
|
SetMark(target);
|
||||||
|
|
||||||
if(*maxmatches > 0)
|
if(*maxmatches > 0)
|
||||||
{
|
{
|
||||||
if((mask == NULL) ||
|
if((mask == NULL) ||
|
||||||
match(mask, target_p->name) || match(mask, target_p->username) ||
|
match(mask, target->name) || match(mask, target->username) ||
|
||||||
match(mask, target_p->host) || match(mask, target_p->servptr->name) ||
|
match(mask, target->host) || match(mask, target->servptr->name) ||
|
||||||
(IsOper(source_p) && match(mask, target_p->orighost)) ||
|
(IsOper(source_p) && match(mask, target->orighost)) ||
|
||||||
match(mask, target_p->info))
|
match(mask, target->info))
|
||||||
{
|
{
|
||||||
do_who(source_p, target_p, NULL, fmt);
|
do_who(source_p, target, chptr, nullptr, fmt);
|
||||||
--(*maxmatches);
|
--(*maxmatches);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,10 +341,10 @@ who_global(struct Client *source_p, const char *mask, int server_oper, int opers
|
||||||
*/
|
*/
|
||||||
if(!operspy)
|
if(!operspy)
|
||||||
{
|
{
|
||||||
RB_DLINK_FOREACH(lp, source_p->user->channel.head)
|
for(const auto &pit : source_p->user->channel)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)lp->data;
|
auto &chan(pit.first);
|
||||||
who_common_channel(source_p, msptr->chan, mask, server_oper, &maxmatches, fmt);
|
who_common_channel(source_p, chan, mask, server_oper, &maxmatches, fmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!ConfigFileEntry.operspy_dont_care_user_info)
|
else if (!ConfigFileEntry.operspy_dont_care_user_info)
|
||||||
|
@ -382,7 +378,7 @@ who_global(struct Client *source_p, const char *mask, int server_oper, int opers
|
||||||
(IsOper(source_p) && match(mask, target_p->orighost)) ||
|
(IsOper(source_p) && match(mask, target_p->orighost)) ||
|
||||||
match(mask, target_p->info))
|
match(mask, target_p->info))
|
||||||
{
|
{
|
||||||
do_who(source_p, target_p, NULL, fmt);
|
do_who(source_p, target_p, nullptr, nullptr, fmt);
|
||||||
--maxmatches;
|
--maxmatches;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -408,22 +404,18 @@ who_global(struct Client *source_p, const char *mask, int server_oper, int opers
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
do_who_on_channel(struct Client *source_p, chan::chan *chptr,
|
do_who_on_channel(struct Client *source_p, chan::chan *chptr,
|
||||||
int server_oper, int member, struct who_format *fmt)
|
int server_oper, int source_member, struct who_format *fmt)
|
||||||
{
|
{
|
||||||
struct Client *target_p;
|
for(auto &pit : chptr->members.global)
|
||||||
chan::membership *msptr;
|
|
||||||
rb_dlink_node *ptr;
|
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, chptr->members.head)
|
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
const auto &target(pit.first);
|
||||||
target_p = msptr->client;
|
auto &member(pit.second);
|
||||||
|
|
||||||
if(server_oper && !IsOper(target_p))
|
if(server_oper && !IsOper(target))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(member || !IsInvisible(target_p))
|
if(source_member || !IsInvisible(target))
|
||||||
do_who(source_p, target_p, msptr, fmt);
|
do_who(source_p, target, chptr, &member, fmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,7 +456,7 @@ append_format(char *buf, size_t bufsize, size_t *pos, const char *fmt, ...)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_who(struct Client *source_p, struct Client *target_p, chan::membership *msptr, struct who_format *fmt)
|
do_who(struct Client *source_p, struct Client *target_p, chan::chan *chan, chan::membership *msptr, struct who_format *fmt)
|
||||||
{
|
{
|
||||||
char status[16];
|
char status[16];
|
||||||
char str[510 + 1]; /* linebuf.c will add \r\n */
|
char str[510 + 1]; /* linebuf.c will add \r\n */
|
||||||
|
@ -476,7 +468,7 @@ do_who(struct Client *source_p, struct Client *target_p, chan::membership *msptr
|
||||||
|
|
||||||
if (fmt->fields == 0)
|
if (fmt->fields == 0)
|
||||||
sendto_one(source_p, form_str(RPL_WHOREPLY), me.name,
|
sendto_one(source_p, form_str(RPL_WHOREPLY), me.name,
|
||||||
source_p->name, msptr ? msptr->chan->name.c_str() : "*",
|
source_p->name, msptr ? chan->name.c_str() : "*",
|
||||||
target_p->username, target_p->host,
|
target_p->username, target_p->host,
|
||||||
target_p->servptr->name, target_p->name, status,
|
target_p->servptr->name, target_p->name, status,
|
||||||
ConfigServerHide.flatten_links && !IsOper(source_p) && !IsExemptShide(source_p) ? 0 : target_p->hopcount,
|
ConfigServerHide.flatten_links && !IsOper(source_p) && !IsExemptShide(source_p) ? 0 : target_p->hopcount,
|
||||||
|
@ -490,7 +482,7 @@ do_who(struct Client *source_p, struct Client *target_p, chan::membership *msptr
|
||||||
if (fmt->fields & FIELD_QUERYTYPE)
|
if (fmt->fields & FIELD_QUERYTYPE)
|
||||||
append_format(str, sizeof str, &pos, " %s", fmt->querytype);
|
append_format(str, sizeof str, &pos, " %s", fmt->querytype);
|
||||||
if (fmt->fields & FIELD_CHANNEL)
|
if (fmt->fields & FIELD_CHANNEL)
|
||||||
append_format(str, sizeof str, &pos, " %s", msptr? msptr->chan->name.c_str() : "*");
|
append_format(str, sizeof str, &pos, " %s", msptr? name(*chan).c_str() : "*");
|
||||||
if (fmt->fields & FIELD_USER)
|
if (fmt->fields & FIELD_USER)
|
||||||
append_format(str, sizeof str, &pos, " %s", target_p->username);
|
append_format(str, sizeof str, &pos, " %s", target_p->username);
|
||||||
if (fmt->fields & FIELD_IP)
|
if (fmt->fields & FIELD_IP)
|
||||||
|
|
|
@ -252,10 +252,10 @@ single_whois(struct Client *source_p, struct Client *target_p, int operspy)
|
||||||
|
|
||||||
if (!IsService(target_p))
|
if (!IsService(target_p))
|
||||||
{
|
{
|
||||||
RB_DLINK_FOREACH(ptr, target_p->user->channel.head)
|
for(const auto &pit : target_p->user->channel)
|
||||||
{
|
{
|
||||||
msptr = (chan::membership *)ptr->data;
|
auto &chptr(pit.first);
|
||||||
chptr = msptr->chan;
|
auto &msptr(pit.second);
|
||||||
|
|
||||||
hdata.chptr = chptr;
|
hdata.chptr = chptr;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue