6.3.1+map Patch.

This is a standalone MAP command patch for Hybrid 6.3.1 release.  It may
apply and run on older or newer versions, but they are untested.

1.  Untar a pristine copy of Hybrid 6.3.1
2.  cd into the source tree and run the following command:

$ patch -p1 </path/to/6.3.1+map.diff

3.  Run configure and set up the server as you would normally.

This MAP implementation was originally written by jv, with optimizations
by Androsyn and Hwy.

This patch is maintained by Hwy.

W. Campbell <wcampbel@botbay.net>

diff -uNrd ircd-hybrid-6.3.1.dist/include/client.h ircd-hybrid-6.3.1/include/client.h
--- ircd-hybrid-6.3.1.dist/include/client.h	Sun Feb 17 00:58:09 2002
+++ ircd-hybrid-6.3.1/include/client.h	Tue Dec 24 21:59:18 2002
@@ -103,6 +103,7 @@
   struct Client*   servers;     /* Servers on this server */
   struct Client*   users;       /* Users on this server */
   int		   tsversion;   /* ts version sent in SVINFO */
+  unsigned int usercnt;
 };
 
 struct Client
diff -uNrd ircd-hybrid-6.3.1.dist/include/m_commands.h ircd-hybrid-6.3.1/include/m_commands.h
--- ircd-hybrid-6.3.1.dist/include/m_commands.h	Thu Nov 29 01:28:23 2001
+++ ircd-hybrid-6.3.1/include/m_commands.h	Tue Dec 24 22:00:44 2002
@@ -99,4 +99,7 @@
 extern int m_dns(struct Client *,struct Client *,int,char **);
 extern int m_htm(struct Client *,struct Client *,int,char **);
 extern int m_set(struct Client *,struct Client *,int,char **);
+
+extern int m_map(struct Client *,struct Client *,int,char **);
+
 #endif /* INCLUDED_m_commands_h */
diff -uNrd ircd-hybrid-6.3.1.dist/include/msg.h ircd-hybrid-6.3.1/include/msg.h
--- ircd-hybrid-6.3.1.dist/include/msg.h	Fri Dec  7 21:38:15 2001
+++ ircd-hybrid-6.3.1/include/msg.h	Tue Dec 24 22:02:10 2002
@@ -127,6 +127,7 @@
 #define MSG_LWALLOPS "LWALLOPS" /* Same as LOCOPS */
 #endif /* LWALLOPS */
 
+#define MSG_MAP            "MAP"    /* MAP */
 #define MSG_KNOCK          "KNOCK"  /* KNOCK */
 
 #define MAXPARA    15 
@@ -252,6 +253,7 @@
   { MSG_DIE, m_die,          0, MAXPARA, 1, 0, 0, 0L },
   { MSG_HTM,    m_htm,       0, MAXPARA, 1, 0, 0, 0L },
   { MSG_SET,    m_set,       0, MAXPARA, 1, 0, 0, 0L },
+  { MSG_MAP,    m_map,       0, MAXPARA, 1, 0, 0, 0L },
   { MSG_TESTLINE,       m_testline,          0, MAXPARA, 1, 0, 0, 0L },
   { (char *) 0, (int (*)()) 0 , 0, 0,    0, 0, 0, 0L }
 };
diff -uNrd ircd-hybrid-6.3.1.dist/include/numeric.h ircd-hybrid-6.3.1/include/numeric.h
--- ircd-hybrid-6.3.1.dist/include/numeric.h	Thu Dec 13 18:16:34 2001
+++ ircd-hybrid-6.3.1/include/numeric.h	Tue Dec 24 22:02:40 2002
@@ -141,6 +141,9 @@
 #define RPL_CREATED          003
 #define RPL_MYINFO           004
 #define RPL_ISUPPORT         005
+#define RPL_MAP              15
+#define RPL_MAPMORE          16 /* Not currently used */
+#define RPL_MAPEND           17
 
 /*
  * Numeric replies from server commands.
diff -uNrd ircd-hybrid-6.3.1.dist/include/patchlevel.h ircd-hybrid-6.3.1/include/patchlevel.h
--- ircd-hybrid-6.3.1.dist/include/patchlevel.h	Wed Apr 17 22:54:49 2002
+++ ircd-hybrid-6.3.1/include/patchlevel.h	Tue Dec 24 22:00:55 2002
@@ -19,5 +19,5 @@
  */
 
 #ifndef PATCHLEVEL
-#define PATCHLEVEL    "2.8/hybrid-6.3.1"
+#define PATCHLEVEL    "2.8/hybrid-6.3.1+map"
 #endif
diff -uNrd ircd-hybrid-6.3.1.dist/src/.depend ircd-hybrid-6.3.1/src/.depend
--- ircd-hybrid-6.3.1.dist/src/.depend	Thu Dec  6 23:13:29 2001
+++ ircd-hybrid-6.3.1/src/.depend	Tue Dec 24 22:18:47 2002
@@ -196,6 +196,10 @@
  ../include/setup.h ../include/client.h ../include/ircd_defs.h \
  ../include/dbuf.h ../include/ircd.h ../include/numeric.h \
  ../include/s_serv.h ../include/s_user.h ../include/send.h
+m_map.o: m_map.c ../include/ircd.h ../include/config.h \
+ ../include/setup.h ../include/client.h ../include/ircd_defs.h \
+ ../include/dbuf.h ../include/numeric.h ../include/send.h \
+ ../include/s_conf.h ../include/fileio.h ../include/motd.h
 m_message.o: m_message.c ../include/m_commands.h ../include/config.h \
  ../include/setup.h ../include/client.h ../include/ircd_defs.h \
  ../include/dbuf.h ../include/flud.h ../include/ircd.h \
@@ -399,13 +403,13 @@
 s_log.o: s_log.c ../include/s_log.h ../include/irc_string.h \
  ../include/ircd_defs.h ../include/config.h ../include/setup.h \
  ../include/ircd.h ../include/s_misc.h
-s_misc.o: s_misc.c ../include/s_misc.h ../include/client.h \
+s_misc.o: s_misc.c ../include/s_misc.h ../include/channel.h \
  ../include/config.h ../include/setup.h ../include/ircd_defs.h \
- ../include/dbuf.h ../include/common.h ../include/irc_string.h \
- ../include/ircd.h ../include/numeric.h ../include/res.h \
- ../include/fileio.h ../include/../adns/adns.h ../include/s_bsd.h \
- ../include/s_conf.h ../include/motd.h ../include/s_serv.h \
- ../include/send.h ../include/struct.h
+ ../include/client.h ../include/dbuf.h ../include/common.h \
+ ../include/irc_string.h ../include/ircd.h ../include/numeric.h \
+ ../include/res.h ../include/fileio.h ../include/../adns/adns.h \
+ ../include/s_bsd.h ../include/s_conf.h ../include/motd.h \
+ ../include/s_serv.h ../include/send.h ../include/struct.h
 s_serv.o: s_serv.c ../include/s_serv.h ../include/config.h \
  ../include/setup.h ../include/channel.h ../include/ircd_defs.h \
  ../include/class.h ../include/client.h ../include/dbuf.h \
diff -uNrd ircd-hybrid-6.3.1.dist/src/Makefile.in ircd-hybrid-6.3.1/src/Makefile.in
--- ircd-hybrid-6.3.1.dist/src/Makefile.in	Thu Dec  6 23:13:29 2001
+++ ircd-hybrid-6.3.1/src/Makefile.in	Tue Dec 24 22:03:36 2002
@@ -51,6 +51,7 @@
 	m_locops.c \
 	m_ltrace.c \
 	m_lusers.c \
+	m_map.c \
 	m_message.c \
 	m_mode.c \
 	m_operwall.c \
diff -uNrd ircd-hybrid-6.3.1.dist/src/client.c ircd-hybrid-6.3.1/src/client.c
--- ircd-hybrid-6.3.1.dist/src/client.c	Sun Feb 17 00:58:13 2002
+++ ircd-hybrid-6.3.1/src/client.c	Tue Dec 24 22:07:38 2002
@@ -1173,7 +1173,10 @@
         ts_warn("server %s without servptr!", sptr->name);
     }
   else if (sptr->servptr && sptr->servptr->serv)
+    {
       del_client_from_llist(&(sptr->servptr->serv->users), sptr);
+      sptr->servptr->serv->usercnt--;
+    }
   /* there are clients w/o a servptr: unregistered ones */
 
   /*
diff -uNrd ircd-hybrid-6.3.1.dist/src/m_map.c ircd-hybrid-6.3.1/src/m_map.c
--- ircd-hybrid-6.3.1.dist/src/m_map.c	Wed Dec 31 19:00:00 1969
+++ ircd-hybrid-6.3.1/src/m_map.c	Tue Dec 24 22:10:36 2002
@@ -0,0 +1,122 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, contrib/m_map.c
+ *   Copyright (C) 1990 Jarkko Oikarinen and
+ *                      University of Oulu, Computing Center
+ *
+ *   See file AUTHORS in IRC package for additional names of
+ *   the programmers.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *   $Id: m_map.c,v 1.13 2002/04/13 14:26:43 reddawg Exp $
+ */
+
+#include <assert.h>
+#include "ircd.h"
+#include "config.h"
+#include "client.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_conf.h"
+
+#define USER_COL       50 /* display | Users: %d at col 50 */
+
+static char buf[BUFSIZE];
+
+static void dump_map(struct Client *cptr,struct Client *root_p, char *pbuf);
+
+/* m_map
+**     parv[0] = sender prefix
+*/
+
+int m_map(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
+{
+#ifdef SERVERHIDE
+  if (!IsAnOper(cptr))
+  {
+    sendto_one(cptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
+    return;
+  }
+#endif
+  dump_map(cptr,&me,buf);
+  sendto_one(cptr, form_str(RPL_MAPEND), me.name, cptr->name);
+  sendto_realops_flags(FLAGS_SPY, "MAP requested by %s (%s@%s)",
+                       sptr->name, sptr->username, sptr->host);
+  return;
+}
+
+/*
+** dump_map
+**   dumps server map, called recursively.
+*/
+static void dump_map(struct Client *cptr,struct Client *root_p, char *pbuf)
+{
+  int cnt = 0, i = 0, len;
+  int users = 0;
+  struct Client *server_p,*user_p;
+
+  *pbuf= '\0';
+
+  strncat(pbuf,root_p->name,BUFSIZE - ((size_t) pbuf - (size_t) buf));
+  len = strlen(buf);
+  buf[len] = ' ';
+
+  if (len < USER_COL)
+  {
+     for (i = len+1; i < USER_COL; i++)
+     {
+       buf[i] = ' ';
+     }
+  }
+
+  snprintf(buf + USER_COL, BUFSIZE - USER_COL,
+           " Users: %5d (%4.1f%%)", root_p->serv->usercnt,
+           100 * (float) root_p->serv->usercnt / (float) Count.total);
+
+  sendto_one(cptr, form_str(RPL_MAP),me.name,cptr->name,buf);
+
+  if ((server_p = root_p->serv->servers))
+  {
+    for (; server_p; server_p = server_p->lnext)
+    {
+      cnt++;
+    }
+
+    if (cnt)
+    {
+      if (pbuf > buf + 3)
+      {
+        pbuf[-2] = ' ';
+        if (pbuf[-3] == '`')
+          pbuf[-3] = ' ';
+      }
+    }
+  }
+  for (i = 1,server_p = root_p->serv->servers; server_p; server_p=server_p->lnext)
+  {
+    *pbuf = ' ';
+    if (i < cnt)
+      *(pbuf + 1) = '|';
+    else
+      *(pbuf + 1) = '`';
+
+    *(pbuf + 2) = '-';
+    *(pbuf + 3) = ' ';
+    dump_map(cptr,server_p,pbuf+4);
+
+    i++;
+   }
+}
+
diff -uNrd ircd-hybrid-6.3.1.dist/src/messages.tab ircd-hybrid-6.3.1/src/messages.tab
--- ircd-hybrid-6.3.1.dist/src/messages.tab	Sat Dec 29 22:25:48 2001
+++ ircd-hybrid-6.3.1/src/messages.tab	Tue Dec 24 22:12:39 2002
@@ -38,9 +38,9 @@
 /* 012 */       NULL,
 /* 013 */       NULL,
 /* 014 */       NULL,
-/* 015 */       NULL,
+/* 015 RPL_MAP, */ ":%s 015 %s :%s",
 /* 016 */       NULL,
-/* 017 */       NULL,
+/* 017 RPL_MAPEND, */ ":%s 017 %s :End of /MAP",
 /* 018 */       NULL,
 /* 019 */       NULL,
 /* 020 */       NULL,
diff -uNrd ircd-hybrid-6.3.1.dist/src/messages_cust.tab ircd-hybrid-6.3.1/src/messages_cust.tab
--- ircd-hybrid-6.3.1.dist/src/messages_cust.tab	Sat Dec 29 22:25:48 2001
+++ ircd-hybrid-6.3.1/src/messages_cust.tab	Tue Dec 24 22:13:04 2002
@@ -39,9 +39,9 @@
 /* 012 */       NULL,
 /* 013 */       NULL,
 /* 014 */       NULL,
-/* 015 */       NULL,
+/* 015 RPL_MAP, */ ":%s 015 %s :%s",
 /* 016 */       NULL,
-/* 017 */       NULL,
+/* 017 RPL_MAPEND, */ ":%s 017 %s :End of /MAP",
 /* 018 */       NULL,
 /* 019 */       NULL,
 /* 020 */       NULL,
diff -uNrd ircd-hybrid-6.3.1.dist/src/s_misc.c ircd-hybrid-6.3.1/src/s_misc.c
--- ircd-hybrid-6.3.1.dist/src/s_misc.c	Sun Feb 17 13:16:03 2002
+++ ircd-hybrid-6.3.1/src/s_misc.c	Tue Dec 24 22:15:51 2002
@@ -206,11 +206,11 @@
 /* Make ISUPPORT string */
 char *make_isupport()
 {
-  static char tisupport[200];
+  static char tisupport[250];
 
   ircsprintf(tisupport, "WALLCHOPS PREFIX=(ov)@+ CHANTYPES=#& MAXCHANNELS=%d "
                         "MAXBANS=%d NICKLEN=%d TOPICLEN=%d KICKLEN=%d "
-                        "NETWORK=%s "
+                        "NETWORK=%s MAP"
 #ifdef CHANMODE_E
                         "CHANMODES=be,k,l,imnpst EXCEPTS"
 #else
diff -uNrd ircd-hybrid-6.3.1.dist/src/s_user.c ircd-hybrid-6.3.1/src/s_user.c
--- ircd-hybrid-6.3.1.dist/src/s_user.c	Wed Jan 23 13:39:08 2002
+++ ircd-hybrid-6.3.1/src/s_user.c	Tue Dec 24 22:18:12 2002
@@ -773,6 +773,7 @@
       return exit_client(NULL, sptr, &me, "Ghost");
     }
   add_client_to_llist(&(sptr->servptr->serv->users), sptr);
+  sptr->servptr->serv->usercnt++;
 
 /* Increment our total user count here */
   if (++Count.total > Count.max_tot)
