Author: Isomer <isomer@coders.net>
[ircu2.10.12-pk.git] / ircd / m_names.c
index e1bfb3f258a7968729248929f260282ec07fc543..1c69828aaf06c214021e84822d09f5f0d0c5e72e 100644 (file)
 #include <assert.h>
 #include <string.h>
 
-#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).
+ *  NAMES_EON - When OR'd with the other two, adds an 'End of Names' numeric
+ *              used by m_join
  *
  */
 
@@ -124,6 +123,10 @@ void do_names(struct Client* sptr, struct Channel* chptr, int filter)
   char buf[BUFSIZE];
   struct Client *c2ptr;
   struct Membership* member;
+  
+  assert(chptr);
+  assert(sptr);
+  assert((filter&NAMES_ALL) != (filter&NAMES_VIS));
 
   /* Tag Pub/Secret channels accordingly. */
 
@@ -152,7 +155,10 @@ void do_names(struct Client* sptr, struct Channel* chptr, int filter)
   {
     c2ptr = member->user;
 
-    if ((filter == NAMES_VIS) && IsInvisible(c2ptr))
+    if (((filter&NAMES_VIS)!=0) && IsInvisible(c2ptr))
+      continue;
+
+    if (IsZombie(member) && member->user != sptr)
       continue;
 
     if (needs_space) {
@@ -162,13 +168,8 @@ void do_names(struct Client* sptr, struct Channel* chptr, int filter)
     needs_space=1;
     if (IsZombie(member))
     {
-      if (member->user != sptr)
-        continue;
-      else
-      {
-        strcat(buf, "!");
-        idx++;
-      }
+      strcat(buf, "!");
+      idx++;
     }
     else if (IsChanOp(member))
     {
@@ -185,8 +186,8 @@ void do_names(struct Client* sptr, struct Channel* chptr, int filter)
     flag = 1;
     if (mlen + idx + NICKLEN + 5 > BUFSIZE)
       /* space, modifier, nick, \r \n \0 */
-    {
-      send_reply(sptr, RPL_NAMREPLY, buf);
+    { 
+      sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, sptr->name, buf);
       strcpy(buf, "* ");
       ircd_strncpy(buf + 2, chptr->chname, len + 1);
       buf[len + 2] = 0;
@@ -202,6 +203,8 @@ void do_names(struct Client* sptr, struct Channel* chptr, int filter)
   }
   if (flag)
     send_reply(sptr, RPL_NAMREPLY, buf); 
+  if (filter&NAMES_EON)
+    send_reply(sptr, RPL_ENDOFNAMES, chptr->chname);
 }
 
 /*
@@ -220,16 +223,17 @@ int m_names(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   char* s;
   char* para = parc > 1 ? parv[1] : 0; 
 
-  if (parc > 2 && hunt_server_cmd(sptr, CMD_NAMES, cptr, 1, "%s %C", 2, parc,
-                                 parv))
+  if (parc > 2 && hunt_server_cmd(sptr, CMD_NAMES, cptr, 1, "%s %C", 2, parc, parv))
     return 0; 
 
-  if (EmptyString(para))
+  if (EmptyString(para)) {
+    send_reply(sptr, RPL_ENDOFNAMES, "*");
     return 0;
+  }
   else if (*para == '0')
     *para = '\0';
   
-  s = strchr(para, ','); /* Recursively call m_names for each comma-seperated channel. */
+  s = strchr(para, ','); /* Recursively call m_names for each comma-seperated channel. Eww. */
   if (s) {
     parv[1] = ++s;
     m_names(cptr, sptr, parc, parv);
@@ -318,31 +322,28 @@ int m_names(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
 
   clean_channelname(para);
   chptr = FindChannel(para); 
-  member = find_member_link(chptr, sptr); 
-  if (member)
-  { 
-    if (chptr) do_names(sptr, chptr, NAMES_ALL);
-    if (!EmptyString(para))
-    {
-      send_reply(sptr, RPL_ENDOFNAMES, chptr ? chptr->chname : para);
-      return 1;
-    }
 
-  }
-    else
-  {
-    /*
-     *  Special Case 3: User isn't on this channel, show all visible users, in 
-     *  non secret channels.
-     */
-     
-    if (chptr) do_names(sptr, chptr, NAMES_VIS);
-    if (!EmptyString(para))
-    {
-      send_reply(sptr, RPL_ENDOFNAMES, para);
-      return 1;
+  if (chptr) {
+    member = find_member_link(chptr, sptr);
+    if (member)
+    { 
+      do_names(sptr, chptr, NAMES_ALL);
+      if (!EmptyString(para))
+      {
+        send_reply(sptr, RPL_ENDOFNAMES, chptr ? chptr->chname : para);
+        return 1;
+      }
     }
+      else 
+    {
+      /*
+       *  Special Case 3: User isn't on this channel, show all visible users, in 
+       *  non secret channels.
+       */ 
+      do_names(sptr, chptr, NAMES_VIS);
+    } 
+  } else { /* Channel doesn't exist. */ 
+      send_reply(sptr, RPL_ENDOFNAMES, para); 
   }
   return 1;
 }
@@ -363,12 +364,13 @@ int ms_names(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   char* s;
   char* para = parc > 1 ? parv[1] : 0; 
 
-  if (parc > 2 && hunt_server_cmd(sptr, CMD_NAMES, cptr, 1, "%s %C", 2, parc,
-                                 parv))
+  if (parc > 2 && hunt_server_cmd(sptr, CMD_NAMES, cptr, 1, "%s %C", 2, parc, parv))
     return 0; 
 
-  if (EmptyString(para))
+  if (EmptyString(para)) {
+    send_reply(sptr, RPL_ENDOFNAMES, "*");
     return 0;
+  }
   else if (*para == '0')
     *para = '\0';
   
@@ -461,32 +463,29 @@ int ms_names(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
 
   clean_channelname(para);
   chptr = FindChannel(para); 
-  member = find_member_link(chptr, sptr); 
-  if (member)
-  { 
-    if (chptr) do_names(sptr, chptr, NAMES_ALL);
-    if (!EmptyString(para))
-    {
-      send_reply(sptr, RPL_ENDOFNAMES, chptr ? chptr->chname : para);
-      return 1;
-    }
 
-  }
-    else
-  {
-    /*
-     *  Special Case 3: User isn't on this channel, show all visible users, in 
-     *  non secret channels.
-     */
-     
-    if (chptr) do_names(sptr, chptr, NAMES_VIS);
-    if (!EmptyString(para))
-    {
-      send_reply(sptr, RPL_ENDOFNAMES, para);
-      return 1;
+  if (chptr) {
+    member = find_member_link(chptr, sptr);
+    if (member)
+    { 
+      do_names(sptr, chptr, NAMES_ALL);
+      if (!EmptyString(para))
+      {
+        send_reply(sptr, RPL_ENDOFNAMES, chptr ? chptr->chname : para);
+        return 1;
+      }
     }
-  } 
+      else 
+    {
+      /*
+       *  Special Case 3: User isn't on this channel, show all visible users, in 
+       *  non secret channels.
+       */ 
+      do_names(sptr, chptr, NAMES_VIS);
+    } 
+  } else { /* Channel doesn't exist. */ 
+      send_reply(sptr, RPL_ENDOFNAMES, para); 
+  }
   return 1;
 }