Author: Bleep <helveytw@home.com>
[ircu2.10.12-pk.git] / ircd / numnicks.c
index 09b904cebc287f85f2b23e83559886d9a478a4c1..93053f46738af1ba20777c6c19e7a360311915c9 100644 (file)
  * 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$
  */
 
 #include "numnicks.h"
-
-#include "sys.h"
-#include "h.h"
-#include "s_serv.h"
-#include "struct.h"
-#include "common.h"
+#include "client.h"
 #include "ircd.h"
-#include "s_misc.h"
+#include "ircd_alloc.h"
+#include "ircd_string.h"
 #include "match.h"
 #include "s_bsd.h"
 #include "s_debug.h"
+#include "s_misc.h"
+#include "struct.h"
 
 #include <assert.h>
+#include <stdio.h>
+#include <string.h>
 
-RCSTAG_CC("$Id$");
 
 /*
  * Numeric nicks are new as of version ircu2.10.00beta1.
@@ -55,23 +56,28 @@ RCSTAG_CC("$Id$");
  */
 
 /*
- * when n2k comes, define this for more capacity
+ * Lets have *LOTS* of connections...
  */
-#undef  EXTENDED_NUMERICS
+#define  EXTENDED_NUMERICS
 
 /* These must be the same on ALL servers ! Do not change ! */
 
 #define NUMNICKLOG 6
-#define NUMNICKMAXCHAR 'z'     /* See convert2n[] */
-#define NUMNICKBASE 64         /* (2 << NUMNICKLOG) */
-#define NUMNICKMASK 63         /* (NUMNICKBASE-1) */
-#define NN_MAX_SERVER 4096     /* (NUMNICKBASE * NUMNICKBASE) */
+#define NUMNICKMAXCHAR 'z'      /* See convert2n[] */
+#define NUMNICKBASE 64          /* (2 << NUMNICKLOG) */
+#define NUMNICKMASK 63          /* (NUMNICKBASE-1) */
+#define NN_MAX_SERVER 4096      /* (NUMNICKBASE * NUMNICKBASE) */
+#if defined(EXTENDED_NUMERICS)
+#define NN_MAX_CLIENT 262144    /* NUMNICKBASE ^ 3 */
+#else
+#define NN_MAX_CLIENT 4096      /* (NUMNICKBASE * NUMNICKBASE) */
+#endif
 
 /*
  * The internal counter for the 'XX' of local clients
  */
 static unsigned int lastNNServer = 0;
-static struct Client *server_list[NN_MAX_SERVER];
+static struct Clientserver_list[NN_MAX_SERVER];
 
 /* *INDENT-OFF* */
 
@@ -81,13 +87,13 @@ static struct Client *server_list[NN_MAX_SERVER];
  *
  * '\0' : Because we use '\0' as end of line.
  *
- * ' ' : Because parse_*() uses this as parameter seperator.
- * ':' : Because parse_server() uses this to detect if a prefix is a
- *       numeric or a name.
- * '+' : Because m_nick() uses this to determine if parv[6] is a
- *       umode or not.
+ * ' '  : Because parse_*() uses this as parameter seperator.
+ * ':'  : Because parse_server() uses this to detect if a prefix is a
+ *        numeric or a name.
+ * '+'  : Because m_nick() uses this to determine if parv[6] is a
+ *        umode or not.
  * '&', '#', '+', '$', '@' and '%' :
- *       Because m_message() matches these characters to detect special cases.
+ *        Because m_message() matches these characters to detect special cases.
  */
 static const char convert2y[] = {
   'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
@@ -119,29 +125,27 @@ static const unsigned int convert2n[] = {
 /* *INDENT-ON* */
 
 
-unsigned int base64toint(const char *s)
+unsigned int base64toint(const chars)
 {
-  unsigned int i = convert2n[(unsigned char)*s++];
-  while (*s)
-  {
+  unsigned int i = convert2n[(unsigned char) *s++];
+  while (*s) {
     i <<= NUMNICKLOG;
-    i += convert2n[(unsigned char)*s++];
+    i += convert2n[(unsigned char) *s++];
   }
   return i;
 }
 
-const char *inttobase64(char *buf, unsigned int v, size_t count)
+const char* inttobase64(char* buf, unsigned int v, unsigned int count)
 {
-  buf[count] = '\0';
-  while (count > 0)
-  {
+  buf[count] = '\0';  
+  while (count > 0) {
     buf[--count] = convert2y[(v & NUMNICKMASK)];
     v >>= NUMNICKLOG;
   }
   return buf;
 }
 
-static struct Client *FindXNServer(const char *numeric)
+static struct Client* FindXNServer(const char* numeric)
 {
   char buf[3];
   buf[0] = *numeric++;
@@ -151,99 +155,65 @@ static struct Client *FindXNServer(const char *numeric)
   return server_list[base64toint(buf)];
 }
 
-struct Client *FindNServer(const char *numeric)
+struct Client* FindNServer(const char* numeric)
 {
-  size_t len = strlen(numeric);
-  if (len < 3)
-  {
+  unsigned int len = strlen(numeric);
+
+  if (len < 3) {
     Debug((DEBUG_DEBUG, "FindNServer: %s(%d)", numeric, base64toint(numeric)));
     return server_list[base64toint(numeric)];
   }
-  else if (len == 3)
-  {
-    Debug((DEBUG_DEBUG, "FindNServer: %c(%d)", *numeric,
-       convert2n[(unsigned char)*numeric]));
-    return server_list[convert2n[(unsigned char)*numeric]];
+  else if (len == 3) {
+    Debug((DEBUG_DEBUG, "FindNServer: %c(%d)", *numeric, 
+           convert2n[(unsigned char) *numeric]));
+    return server_list[convert2n[(unsigned char) *numeric]];
   }
   return FindXNServer(numeric);
 }
 
-void RemoveYXXClient(struct Client *server, const char *yxx)
+struct Client* findNUser(const char* yxx)
+{
+  struct Client* server = 0;
+  if (5 == strlen(yxx)) {
+    if (0 != (server = FindXNServer(yxx))) {
+      Debug((DEBUG_DEBUG, "findNUser: %s(%d)", yxx, 
+             base64toint(yxx + 2) & server->serv->nn_mask));
+      return server->serv->client_list[base64toint(yxx + 2) & server->serv->nn_mask];
+    }
+  }
+  else if (0 != (server = FindNServer(yxx))) {
+    Debug((DEBUG_DEBUG, "findNUser: %s(%d)",
+           yxx, base64toint(yxx + 1) & server->serv->nn_mask));
+    return server->serv->client_list[base64toint(yxx + 1) & server->serv->nn_mask];
+  }
+  return 0;
+}
+
+void RemoveYXXClient(struct Client* server, const char* yxx)
 {
   assert(0 != server);
   assert(0 != yxx);
-  if (*yxx)
-  {
-    unsigned int index = 0;
-
-    if (strlen(yxx) < 3)
-      index = base64toint(yxx) & server->serv->nn_mask;
-    else
-      index = base64toint(yxx);
-
-    Debug((DEBUG_DEBUG, "RemoveYXXClient: %s(%d)", yxx, index));
-
-    if (index < (server->serv->nn_mask + 1))
-      server->serv->client_list[index] = NULL;
+  if (*yxx) {
+    Debug((DEBUG_DEBUG, "RemoveYXXClient: %s(%d)", yxx,
+           base64toint(yxx) & server->serv->nn_mask));
+    server->serv->client_list[base64toint(yxx) & server->serv->nn_mask] = 0;
   }
 }
 
-void SetServerYXX(struct Client *cptr, struct Client *server, const char *yxx)
+void SetServerYXX(struct Client* cptr, struct Client* server, const char* yxx)
 {
   unsigned int index;
-#ifndef NO_PROTOCOL9
-  /* Use cptr, because we do protocol 9 -> 10 translation for numeric nicks ! */
-  if (Protocol(cptr) > 9)
-  {
-#endif
-    if (5 == strlen(yxx))
-    {
-      strncpy(server->yxx, yxx, 2);
-      strncpy(server->serv->nn_capacity, yxx + 2, 3);
-    }
-    else
-    {
-      server->yxx[0] = yxx[0];
-      server->serv->nn_capacity[0] = yxx[1];
-      server->serv->nn_capacity[1] = yxx[2];
-    }
-    server->serv->nn_mask = base64toint(server->serv->nn_capacity);
-
-#ifndef NO_PROTOCOL9
+  if (5 == strlen(yxx)) {
+    ircd_strncpy(server->yxx, yxx, 2);
+    ircd_strncpy(server->serv->nn_capacity, yxx + 2, 3);
   }
-  else
-  {
-    static const struct ServerNameNumeric {
-      const char *name;
-      unsigned int numeric;
-    } server_table[] = {
-      {
-      "Uworld.undernet.org", 22},
-      {
-      "Uworld2.undernet.org", 23},
-      {
-      "channels.undernet.org", 30},
-      {
-      "channels2.undernet.org", 31},
-      {
-      0, 0}
-    };
-    int i;
-    for (i = 0; i < 4; ++i)
-    {
-      if (!strCasediff(server_table[i].name, server->name))
-      {
-       /*
-        * XXX - just use the old format for services for now
-        */
-       *server->yxx = convert2y[server_table[i].numeric];
-       inttobase64(server->serv->nn_capacity, 63, 2);
-       server->serv->nn_mask = 63;
-       break;
-      }
-    }
+  else {
+    server->yxx[0]               = yxx[0];
+    server->serv->nn_capacity[0] = yxx[1];
+    server->serv->nn_capacity[1] = yxx[2];
   }
-#endif
+  server->serv->nn_mask = base64toint(server->serv->nn_capacity);
+
   index = base64toint(server->yxx);
   if (index >= lastNNServer)
     lastNNServer = index + 1;
@@ -253,43 +223,39 @@ void SetServerYXX(struct Client *cptr, struct Client *server, const char *yxx)
    * determine that SetServerYXX has been called - and then calls
    * ClearServerYXX. However, freeing the allocation happens in free_client() */
   server->serv->client_list =
-      (struct Client **)RunCalloc(server->serv->nn_mask + 1,
-      sizeof(struct Client *));
+      (struct Client**) MyCalloc(server->serv->nn_mask + 1, sizeof(struct Client*));
 }
 
-void SetYXXCapacity(struct Client *c, size_t capacity)
+void SetYXXCapacity(struct Client* c, unsigned int capacity)
 {
-  unsigned int max_clients;
-#if defined(EXTENDED_NUMERICS)
-  max_clients = capacity - 1;
-  inttobase64(c->serv->nn_capacity, max_clients, 3);
-#else
-  max_clients = 16;
+  unsigned int max_clients = 16;
   /* 
    * Calculate mask to be used for the maximum number of clients
    */
-  while (capacity >= max_clients)
-    max_clients = max_clients << 1;
+  while (max_clients < capacity)
+    max_clients <<= 1;
   /*
    * Sanity checks
    */
-  if (max_clients > NN_MAX_SERVER)
-  {
+  if (max_clients > NN_MAX_CLIENT) {
     fprintf(stderr, "MAXCLIENTS (or MAXCONNECTIONS) is (at least) %d "
-       "too large ! Please decrease this value.\n",
-       max_clients - NN_MAX_SERVER);
+            "too large ! Please decrease this value.\n",
+             max_clients - NN_MAX_CLIENT);
     exit(-1);
   }
   --max_clients;
-  inttobase64(c->serv->nn_capacity, max_clients, 2);
+#if defined(EXTENDED_NUMERICS)
+  inttobase64(c->serv->nn_capacity, max_clients, 3); 
+#else
+  inttobase64(c->serv->nn_capacity, max_clients, 2); 
 #endif
-  c->serv->nn_mask = max_clients;      /* Our Numeric Nick mask */
-  c->serv->client_list = (struct Client **)RunCalloc(max_clients + 1,
-      sizeof(struct Client *));
+  c->serv->nn_mask = max_clients;       /* Our Numeric Nick mask */
+  c->serv->client_list = (struct Client**) MyCalloc(max_clients + 1, 
+                                                     sizeof(struct Client*));
   server_list[base64toint(c->yxx)] = c;
 }
 
-void SetYXXServerName(struct Client *c, unsigned int numeric)
+void SetYXXServerName(struct Clientc, unsigned int numeric)
 {
   assert(0 != c);
   assert(numeric < NN_MAX_SERVER);
@@ -308,8 +274,8 @@ void SetYXXServerName(struct Client *c, unsigned int numeric)
 void ClearServerYXX(const struct Client *server)
 {
   unsigned int index = base64toint(server->yxx);
-  if (server_list[index] == server)    /* Sanity check */
-    server_list[index] = NULL;
+  if (server_list[index] == server)     /* Sanity check */
+    server_list[index] = 0;
 }
 
 /*
@@ -318,34 +284,24 @@ void ClearServerYXX(const struct Client *server)
  * Register numeric of new, remote, client.
  * Add it to the appropriate client_list.
  */
-int SetRemoteNumNick(struct Client *acptr, const char *yxx)
+void SetRemoteNumNick(struct Client* acptr, const char *yxx)
 {
-  struct Client **acptrp;
-  struct Client *server = acptr->user->server;
-  unsigned int index = 0;
-
-  if (5 == strlen(yxx))
-  {
+  struct Client** acptrp;
+  struct Client*  server = acptr->user->server;
+  if (5 == strlen(yxx)) {
     strcpy(acptr->yxx, yxx + 2);
-    index = base64toint(acptr->yxx);
   }
-  else
-  {
+  else {
     acptr->yxx[0] = *++yxx;
     acptr->yxx[1] = *++yxx;
     acptr->yxx[2] = 0;
-    index = base64toint(acptr->yxx) & server->serv->nn_mask;
   }
+  Debug((DEBUG_DEBUG, "SetRemoteNumNick: %s(%d)", acptr->yxx, 
+         base64toint(acptr->yxx) & server->serv->nn_mask));
 
-  Debug((DEBUG_DEBUG, "SetRemoteNumNick: %s(%d)", acptr->yxx, index));
-  if (index > server->serv->nn_mask)
-    return 0;
-
-  assert(index <= server->serv->nn_mask);
-
-  acptrp = &server->serv->client_list[index];
-  if (*acptrp)
-  {
+  acptrp = &server->serv->client_list[base64toint(acptr->yxx) & server->serv->nn_mask];
+  if (*acptrp) {
     /*
      * this exits the old client in the array, not the client
      * that is being set
@@ -353,7 +309,6 @@ int SetRemoteNumNick(struct Client *acptr, const char *yxx)
     exit_client(acptr->from, *acptrp, server, "Numeric nick collision (Ghost)");
   }
   *acptrp = acptr;
-  return 1;
 }
 
 
@@ -361,56 +316,35 @@ int SetRemoteNumNick(struct Client *acptr, const char *yxx)
  * SetLocalNumNick()
  *
  * Register numeric of new, local, client. Add it to our client_list.
+ * Muxtex needed if threaded
  */
-void SetLocalNumNick(struct Client *cptr)
+int SetLocalNumNick(struct Client *cptr)
 {
-  static unsigned int last_nn = 0;
-  struct Client **client_list = me.serv->client_list;
-  unsigned int capacity = me.serv->nn_mask + 1;
-  unsigned int count = 0;
+  static unsigned int last_nn     = 0;
+  struct Client**     client_list = me.serv->client_list;
+  unsigned int        mask        = me.serv->nn_mask;
+  unsigned int        count       = 0;
 
   assert(cptr->user->server == &me);
 
-  while (client_list[last_nn])
-  {
-    if (++count == capacity)
-    {
-      assert(count < capacity);
-      return;
+  while (client_list[last_nn & mask]) {
+    if (++count == NN_MAX_CLIENT) {
+      assert(count < NN_MAX_CLIENT);
+      return 0;
     }
-    if (++last_nn == capacity)
+    if (++last_nn == NN_MAX_CLIENT)
       last_nn = 0;
   }
-  client_list[last_nn] = cptr; /* Reserve the numeric ! */
+  client_list[last_nn & mask] = cptr;  /* Reserve the numeric ! */
 
 #if defined(EXTENDED_NUMERICS)
   inttobase64(cptr->yxx, last_nn, 3);
 #else
   inttobase64(cptr->yxx, last_nn, 2);
 #endif
-}
-
-struct Client *findNUser(const char *yxx)
-{
-  struct Client *server = 0;
-  unsigned int index = 0;
-  if (5 == strlen(yxx))
-  {
-    if (0 != (server = FindXNServer(yxx)))
-    {
-      Debug((DEBUG_DEBUG, "findNUser: %s(%d) (%p)", yxx,
-         base64toint(yxx + 2), server));
-      if ((index = base64toint(yxx + 2)) <= server->serv->nn_mask)
-       return server->serv->client_list[index];
-    }
-  }
-  else if (0 != (server = FindNServer(yxx)))
-  {
-    index = base64toint(yxx + 1) & server->serv->nn_mask;
-    Debug((DEBUG_DEBUG, "findNUser: %s(%d) (%p)", yxx, index, server));
-    return server->serv->client_list[index];
-  }
-  return 0;
+  if (++last_nn == NN_MAX_CLIENT)
+    last_nn = 0;
+  return 1;
 }
 
 /* 
@@ -424,78 +358,32 @@ int markMatchexServer(const char *cmask, int minlen)
   int i;
   struct Client *acptr;
 
-  for (i = 0; i < lastNNServer; i++)
-  {
-    if ((acptr = server_list[i]))
-    {
+  for (i = 0; i < lastNNServer; i++) {
+    if ((acptr = server_list[i])) {
       if (matchexec(acptr->name, cmask, minlen))
-       acptr->flags &= ~FLAGS_MAP;
-      else
-      {
-       acptr->flags |= FLAGS_MAP;
-       cnt++;
+        acptr->flags &= ~FLAGS_MAP;
+      else {
+        acptr->flags |= FLAGS_MAP;
+        cnt++;
       }
     }
   }
   return cnt;
 }
 
-struct Client *find_match_server(char *mask)
+struct Clientfind_match_server(char *mask)
 {
   struct Client *acptr;
   int i;
 
-  if (!(BadPtr(mask)))
-  {
+  if (!(BadPtr(mask))) {
     collapse(mask);
-    for (i = 0; i < lastNNServer; i++)
-    {
+    for (i = 0; i < lastNNServer; i++) {
       if ((acptr = server_list[i]) && (!match(mask, acptr->name)))
-       return acptr;
+        return acptr;
     }
   }
-  return NULL;
+  return 0;
 }
 
 
-#ifndef NO_PROTOCOL9
-
-/******************************************************************************
- *
- * The following functions can be removed as soon as all servers have upgraded
- * to ircu2.10.
- */
-
-/*
- * CreateNNforProtocol9server
- *
- * We do not receive numeric nicks from servers behind a protocol 9 link
- * so we generate it ourselfs.
- */
-const char *CreateNNforProtocol9server(const struct Client *server)
-{
-  static char YXX[4];
-  struct Server *serv = server->serv;
-  unsigned int count = 0;
-
-  assert(IsServer(server));
-  assert(9 == Protocol(server));
-
-  YXX[0] = *server->yxx;
-  YXX[3] = 0;
-
-  while (serv->client_list[serv->nn_last])
-  {
-    if (++count == NUMNICKBASE)
-    {
-      assert(count < NUMNICKBASE);
-      return NULL;
-    }
-    if (++serv->nn_last == NUMNICKBASE)
-      serv->nn_last = 0;
-  }
-  inttobase64(YXX + 1, serv->nn_last, 2);
-  return YXX;
-}
-
-#endif /* !NO_PROTOCOL9 */