static const char hide_desc[] = "Hides channel memberships not shared";
-static void h_huc_doing_whois_channel_visibility(hook_data_client *);
+static void h_huc_doing_whois_channel_visibility(void *);
mapi_hfn_list_av1 huc_hfnlist[] = {
{ "doing_whois_channel_visibility", (hookfn) h_huc_doing_whois_channel_visibility },
DECLARE_MODULE_AV2(hide_uncommon_channels, NULL, NULL, NULL, NULL, huc_hfnlist, NULL, NULL, hide_desc);
static void
-h_huc_doing_whois_channel_visibility(hook_data_client *hdata)
+h_huc_doing_whois_channel_visibility(void *data_)
{
- hdata->approved = ((PubChannel(hdata->chptr) && !IsInvisible(hdata->target)) || IsMember((hdata->client), (hdata->chptr)));
+ hook_data_channel_visibility *data = data_;
+ data->approved = data->approved && (!IsInvisible(data->targms->client_p) || data->clientms != NULL);
}
struct Channel *
find_allowing_channel(struct Client *source_p, struct Client *target_p)
{
- rb_dlink_node *ptr;
- struct membership *msptr;
+ rb_dlink_node *ps = source_p->user->channel.head;
+ rb_dlink_node *pt = target_p->user->channel.head;
- RB_DLINK_FOREACH(ptr, source_p->user->channel.head)
+ while (ps && pt)
{
- msptr = ptr->data;
- if (is_chanop_voiced(msptr) && IsMember(target_p, msptr->chptr))
- return msptr->chptr;
+ struct membership *ms = ps->data;
+ struct membership *mt = pt->data;
+ int d;
+ if (ms->chptr == mt->chptr)
+ {
+ if (is_chanop_voiced(ms))
+ return ms->chptr;
+ ps = ps->next;
+ pt = pt->next;
+ continue;
+ }
+ d = irccmp(ms->chptr->chname, mt->chptr->chname);
+ if (d < 0)
+ ps = ps->next;
+ else if (d > 0)
+ pt = pt->next;
+ else
+ assert("different channels can't have equal names" && false);
}
return NULL;
}
{
char buf[BUFSIZE];
rb_dlink_node *ptr;
- struct membership *msptr;
- struct Channel *chptr;
int cur_len = 0;
int mlen;
char *t;
if (!IsService(target_p))
{
- RB_DLINK_FOREACH(ptr, target_p->user->channel.head)
- {
- msptr = ptr->data;
- chptr = msptr->chptr;
+ hook_data_channel_visibility hdata_vis;
+ rb_dlink_node *ps = source_p->user->channel.head;
+ rb_dlink_node *pt = target_p->user->channel.head;
+
+ hdata_vis.client = source_p;
- hdata.chptr = chptr;
+ while (pt)
+ {
+ struct membership *mt = pt->data;
+ int dir = 0;
+ if (ps != NULL)
+ {
+ struct membership *ms = ps->data;
+ if (ms->chptr == mt->chptr)
+ {
+ ps = ps->next;
+ pt = pt->next;
+ hdata_vis.chptr = mt->chptr;
+ hdata_vis.clientms = ms;
+ hdata_vis.targms = mt;
+ hdata_vis.approved = 1;
+ dir = 0;
+ }
+ else
+ {
+ dir = irccmp(ms->chptr->chname, mt->chptr->chname);
+ }
+ }
+ else
+ {
+ dir = 1;
+ }
+ if (dir < 0)
+ {
+ ps = ps->next;
+ continue;
+ }
+ else if (dir > 0)
+ {
+ pt = pt->next;
+ hdata_vis.chptr = mt->chptr;
+ hdata_vis.clientms = NULL;
+ hdata_vis.targms = mt;
+ hdata_vis.approved = PubChannel(mt->chptr);
+ }
- hdata.approved = ShowChannel(source_p, chptr);
- call_hook(doing_whois_channel_visibility_hook, &hdata);
+ call_hook(doing_whois_channel_visibility_hook, &hdata_vis);
- if(hdata.approved || operspy)
+ if(hdata_vis.approved || operspy)
{
- if((cur_len + strlen(chptr->chname) + 3) > (BUFSIZE - 5))
+ if((cur_len + strlen(mt->chptr->chname) + 3) > (BUFSIZE - 5))
{
sendto_one(source_p, "%s", buf);
cur_len = mlen + extra_space;
}
tlen = sprintf(t, "%s%s%s ",
- hdata.approved ? "" : "!",
- find_channel_status(msptr, 1),
- chptr->chname);
+ hdata_vis.approved ? "" : "!",
+ find_channel_status(mt, 1),
+ mt->chptr->chname);
t += tlen;
cur_len += tlen;
}