+#define NAMES_ALL 1 /* List all users in channel */
+#define NAMES_VIS 2 /* List only visible users in non-secret channels */
+
+/*
+ * Sends a suitably formatted 'names' reply to 'sptr' consisting of nicks within
+ * 'chptr', depending on 'filter'.
+ *
+ * NAMES_ALL - Lists all users on channel.
+ * NAMES_VIS - Only list visible (-i) users. --Gte (04/06/2000).
+ *
+ */
+
+void do_names(struct Client* sptr, struct Channel* chptr, int filter)
+{
+ int mlen;
+ int idx;
+ int flag;
+ int needs_space;
+ int len;
+ char buf[BUFSIZE];
+ struct Client *c2ptr;
+ struct Membership* member;
+
+ /* Tag Pub/Secret channels accordingly. */
+
+ strcpy(buf, "* ");
+ if (PubChannel(chptr))
+ *buf = '=';
+ else if (SecretChannel(chptr))
+ *buf = '@';
+
+ len = strlen(chptr->chname);
+ strcpy(buf + 2, chptr->chname);
+ strcpy(buf + 2 + len, " :");
+
+ idx = len + 4;
+ flag = 1;
+ needs_space = 0;
+
+ if (!ShowChannel(sptr, chptr)) /* Don't list private channels unless we are on them. */
+ return;
+
+ /* Iterate over all channel members, and build up the list. */
+
+ mlen = strlen(me.name) + 10 + strlen(sptr->name);
+
+ for (member = chptr->members; member; member = member->next_member)
+ {
+ c2ptr = member->user;
+
+ if ((filter == NAMES_VIS) && IsInvisible(c2ptr))
+ continue;
+
+ if (needs_space) {
+ strcat(buf, " ");
+ idx++;
+ }
+ needs_space=1;
+ if (IsZombie(member))
+ {
+ if (member->user != sptr)
+ continue;
+ else
+ {
+ strcat(buf, "!");
+ idx++;
+ }
+ }
+ else if (IsChanOp(member))
+ {
+ strcat(buf, "@");
+ idx++;
+ }
+ else if (HasVoice(member))
+ {
+ strcat(buf, "+");
+ idx++;
+ }
+ strcat(buf, c2ptr->name);
+ idx += strlen(c2ptr->name) + 1;
+ flag = 1;
+ if (mlen + idx + NICKLEN + 5 > BUFSIZE)
+ /* space, modifier, nick, \r \n \0 */
+ {
+ send_reply(sptr, RPL_NAMREPLY, buf);
+ strcpy(buf, "* ");
+ ircd_strncpy(buf + 2, chptr->chname, len + 1);
+ buf[len + 2] = 0;
+ strcat(buf, " :");
+ if (PubChannel(chptr))
+ *buf = '=';
+ else if (SecretChannel(chptr))
+ *buf = '@';
+ idx = len + 4;
+ flag = 0;
+ needs_space=0;
+ }
+ }
+ if (flag)
+ send_reply(sptr, RPL_NAMREPLY, buf);
+}
+