+
+ if (IsFakeHost(who) && IsHiddenHost(who))
+ irc_numeric(from, RPL_WHOISUSER, "%s %s %s * :%s", who->nick, who->ident, who->fakehost, who->info);
+ else if (IsHiddenHost(who) && who->handle_info && hidden_host_suffix)
+ irc_numeric(from, RPL_WHOISUSER, "%s %s %s.%s * :%s", who->nick, who->ident, who->handle_info->handle, hidden_host_suffix, who->info);
+ else
+ irc_numeric(from, RPL_WHOISUSER, "%s %s %s * :%s", who->nick, who->ident, who->hostname, who->info);
+
+ if (!IsService(who) || (from == who)) {
+ struct modeNode *mn;
+ mlen = strlen(self->name) + strlen(from->nick) + 12 + strlen(who->nick);
+ len = 0;
+ *buf = '\0';
+ for (i = who->channels.used; i > 0; )
+ {
+ mn = who->channels.list[--i];
+
+ if (!IsOper(from) && (mn->channel->modes & (MODE_PRIVATE | MODE_SECRET)) && !GetUserMode(mn->channel, from))
+ continue;
+
+ if (len + strlen(mn->channel->name) + mlen > MAXLEN - 5)
+ {
+ irc_numeric(from, RPL_WHOISCHANNELS, "%s :%s", who->nick, buf);
+ *buf = '\0';
+ len = 0;
+ }
+
+ if (IsDeaf(who))
+ *(buf + len++) = '-';
+ if ((mn->channel->modes & (MODE_PRIVATE | MODE_SECRET)) && !GetUserMode(mn->channel, from))
+ *(buf + len++) = '*';
+ if (mn->modes & MODE_CHANOP)
+ *(buf + len++) = '@';
+ else if (mn->modes & MODE_HALFOP)
+ *(buf + len++) = '%';
+ else if (mn->modes & MODE_VOICE)
+ *(buf + len++) = '+';
+
+ if (len)
+ *(buf + len) = '\0';
+ strcpy(buf + len, mn->channel->name);
+ len += strlen(mn->channel->name);
+ strcat(buf + len, " ");
+ len++;
+ }
+ if (buf[0] != '\0')
+ irc_numeric(from, RPL_WHOISCHANNELS, "%s :%s", who->nick, buf);