#include "../parser/parser.h"
#include "../irc/irc.h"
#include "../lib/base64.h"
+#include "../lib/version.h"
+#include "../core/nsmalloc.h"
#include <stdio.h>
#include <string.h>
+MODULE_VERSION("");
+
#define channelhash(x) (crc32i(x)%CHANNELHASHSIZE)
unsigned long nouser;
-chanindex *chantable[CHANNELHASHSIZE];
const flag cmodeflags[] = {
{ 'n', CHANMODE_NOEXTMSG },
{ 'D', CHANMODE_DELJOINS },
{ 'u', CHANMODE_NOQUITMSG },
{ 'N', CHANMODE_NONOTICE },
+ { 'M', CHANMODE_MODNOAUTH },
+ { 'T', CHANMODE_SINGLETARG },
{ '\0', 0 } };
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();
+ }
+
/* Set up our hooks */
registerhook(HOOK_NICK_NEWNICK,&addordelnick);
registerhook(HOOK_NICK_LOSTNICK,&addordelnick);
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);
deregisterhook(HOOK_NICK_NEWNICK,&addordelnick);
deregisterhook(HOOK_NICK_LOSTNICK,&addordelnick);
+ 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) {
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;
}
}
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;
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;
}
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;
+ }
+ }
+}