+ CLIENT *c;
+ CL2CHAN *cl2chan;
+ CHANNEL *chan;
+ bool client_match, is_visible;
+ char flags[4];
+ int count = 0;
+
+ assert (Client != NULL);
+
+ if (Mask)
+ ngt_LowerStr(Mask);
+
+ for (c = Client_First(); c != NULL; c = Client_Next(c)) {
+ if (Client_Type(c) != CLIENT_USER)
+ continue;
+
+ if (OnlyOps && !Client_HasMode(c, 'o'))
+ continue;
+
+ if (Mask) {
+ /* Match pattern against user host/server/name/nick */
+ client_match = MatchCaseInsensitive(Mask,
+ Client_Hostname(c));
+ if (!client_match)
+ client_match = MatchCaseInsensitive(Mask,
+ Client_ID(Client_Introducer(c)));
+ if (!client_match)
+ client_match = MatchCaseInsensitive(Mask,
+ Client_Info(c));
+ if (!client_match)
+ client_match = MatchCaseInsensitive(Mask,
+ Client_ID(c));
+ if (!client_match)
+ continue; /* no match: skip this client */
+ }
+
+ is_visible = !Client_HasMode(c, 'i');
+
+ /* Target client is invisible, but mask matches exactly? */
+ if (!is_visible && Mask && strcasecmp(Client_ID(c), Mask) == 0)
+ is_visible = true;
+
+ /* Target still invisible, but are both on the same channel? */
+ if (!is_visible) {
+ cl2chan = Channel_FirstChannelOf(Client);
+ while (cl2chan && !is_visible) {
+ chan = Channel_GetChannel(cl2chan);
+ if (Channel_IsMemberOf(chan, c))
+ is_visible = true;
+ cl2chan = Channel_NextChannelOf(Client, cl2chan);
+ }
+ }
+
+ if (!is_visible) /* target user is not visible */
+ continue;
+
+ if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
+ break;