]> jfr.im git - irc/quakenet/newserv.git/blobdiff - channel/channel.c
CHANSERV: tell user when they can't attempts to auth any more, and drop max attempts...
[irc/quakenet/newserv.git] / channel / channel.c
index c1662ac5ee33bad317d73cd372a3ae669d0a9a1b..378fbcd2fb53d28c26bba1b6428ca8f35e0391e1 100644 (file)
@@ -9,6 +9,7 @@
 #include "../irc/irc.h"
 #include "../lib/base64.h"
 #include "../lib/version.h"
+#include "../core/nsmalloc.h"
 
 #include <stdio.h>
 #include <string.h>
@@ -18,7 +19,6 @@ MODULE_VERSION("");
 #define channelhash(x)  (crc32i(x)%CHANNELHASHSIZE)
 
 unsigned long nouser;
-chanindex *chantable[CHANNELHASHSIZE];
 
 const flag cmodeflags[] = {
    { 'n', CHANMODE_NOEXTMSG    },
@@ -43,14 +43,16 @@ void channelstats(int hooknum, void *arg);
 void sendchanburst(int hooknum, void *arg);
 
 void _init() {
-  /* Initialise internal structures */
-  initchannelalloc();
-  initchannelindex();
-  memset(chantable,0,sizeof(chantable));
-
   /* Set up the nouser marker according to our own numeric */
   nouser=(mylongnum<<18)|CU_NOUSERMASK;
   
+  /* If we're connected to IRC, force a disconnect.  This needs to be done
+   * before we register all our hooks which would otherwise get called
+   * during the disconnect. */
+  if (connected) { 
+    irc_send("%s SQ %s 0 :Resync [adding channel support]",mynumeric->content,myserver->content); irc_disconnected(0);
+  }
+
   /* Set up our hooks */
   registerhook(HOOK_NICK_NEWNICK,&addordelnick);
   registerhook(HOOK_NICK_LOSTNICK,&addordelnick);
@@ -67,15 +69,14 @@ void _init() {
   registerserverhandler("M",&handlemodemsg,8);
   registerserverhandler("OM",&handlemodemsg,8); /* Treat OPMODE just like MODE */
   registerserverhandler("CM",&handleclearmodemsg,2);
-  
-  /* If we're connected to IRC, force a disconnect */
-  if (connected) {
-    irc_send("%s SQ %s 0 :Resync [adding channel support]",mynumeric->content,myserver->content);
-    irc_disconnected();  
-  }
 }
 
 void _fini() {
+  unsigned int i;
+  struct channel *cp;
+  struct chanindex *cip, *ncip;
+  nick *np;
+
   deregisterserverhandler("B",&handleburstmsg);
   deregisterserverhandler("J",&handlejoinmsg);
   deregisterserverhandler("C",&handlecreatemsg);
@@ -91,6 +92,25 @@ void _fini() {
   deregisterhook(HOOK_CORE_STATSREQUEST,&channelstats);
   deregisterhook(HOOK_IRC_SENDBURSTBURSTS,&sendchanburst);
   deregisterhook(HOOK_NICK_WHOISCHANNELS,&handlewhoischannels);
+  /* Free all the channels */
+  for(i=0;i<CHANNELHASHSIZE;i++) {
+    for (cip=chantable[i];cip;cip=ncip) {
+      ncip=cip->next;
+      if ((cp=cip->channel))
+        delchannel(cp);
+    }
+  }
+  
+  /* We also need to remove the channels array from each user */
+  for (i=0;i<NICKHASHSIZE;i++) {
+    for (np=nicktable[i];np;np=np->next) {
+      array_free(np->channels);
+      free(np->channels);
+    }
+  }
+  
+  nsfreeall(POOL_CHANNEL);
 }
 
 int addnicktochannel(channel *cp, long numeric) {
@@ -138,7 +158,7 @@ void delnickfromchannel(channel *cp, long numeric, int updateuser) {
   void *args[2];
   
   if ((np=getnickbynumeric(numeric&CU_NUMERICMASK))==NULL) {
-    Error("channel",ERR_ERROR,"Trying to remove non-existent nick %d from channel %s",numeric,cp->index->name);
+    Error("channel",ERR_ERROR,"Trying to remove non-existent nick %lu from channel %s",numeric,cp->index->name->content);
     return;
   }
   
@@ -238,7 +258,7 @@ channel *findchannel(char *name) {
 }
 
 void channelstats(int hooknum, void *arg) {
-  int level=(int)arg;
+  long level=(long)arg;
   int i,curchain,maxchain=0,total=0,buckets=0,realchans=0;
   int users=0,slots=0;
   chanindex *cip;
@@ -395,7 +415,7 @@ unsigned int countuniquehosts(channel *cp) {
       continue;
       
     if ((np=getnickbynumeric(cp->users->content[i]))==NULL) {
-      Error("channel",ERR_ERROR,"Found unknown numeric %u on channel %s",cp->users->content[i],cp->index->name->content);
+      Error("channel",ERR_ERROR,"Found unknown numeric %lu on channel %s",cp->users->content[i],cp->index->name->content);
       continue;
     }
     
@@ -408,3 +428,19 @@ unsigned int countuniquehosts(channel *cp) {
   
   return count;
 }
+
+/*
+ * clean_key: returns a "cleaned" version of the key like ircu does.
+ *
+ * Note that s is a signed char, so we are basically allowing everything from 33-127 except : or ,
+ *
+ * Unlike ircu we don't check against KEYLEN here, this is done elsewhere.
+ */
+void clean_key(char *key) {
+  for (;*key;key++) {
+    if (*key<=32 || *key==':' || *key==',') {
+      *key=0;
+      return;
+    }
+  }
+}