#include "../server/server.h"
#include "../parser/parser.h"
#include "../lib/version.h"
+#include "../core/nsmalloc.h"
+
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
{ 'h', UMODE_SETHOST },
{ 'R', UMODE_REGPRIV },
{ 'I', UMODE_HIDEIDLE },
+ { 'P', UMODE_PARANOID },
+ { '\0', 0 } };
+
+const flag accountflags[] = {
+ { 'q', AFLAG_STAFF },
+ { 'h', AFLAG_SUPPORT },
+ { 'o', AFLAG_OPER },
+ { 'a', AFLAG_ADMIN },
+ { 'd', AFLAG_DEVELOPER },
{ '\0', 0 } };
#define nickhash(x) ((crc32i(x))%NICKHASHSIZE)
nick **servernicks[MAXSERVERS];
sstring *nickextnames[MAXNICKEXTS];
-sstring *nodeextnames[PATRICIA_MAXSLOTS];
-patricia_tree_t *iptree;
void nickstats(int hooknum, void *arg);
+char *NULLAUTHNAME = "";
+
void _init() {
+ unsigned int i;
+ authname *anp;
+
+ /* Clear up the nicks in authext */
+ for (i=0;i<AUTHNAMEHASHSIZE;i++)
+ for (anp=authnametable[i];anp;anp=anp->next)
+ anp->nicks=NULL;
+
initnickalloc();
initnickhelpers();
memset(nicktable,0,sizeof(nicktable));
memset(servernicks,0,sizeof(servernicks));
+
+ /* 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 nick support]",mynumeric->content,myserver->content); irc_disconnected();
+ }
/* Register our hooks */
registerhook(HOOK_SERVER_NEWSERVER,&handleserverchange);
registerserverhandler("Q",&handlequitmsg,1);
registerserverhandler("M",&handleusermodemsg,3);
registerserverhandler("W",&handlewhoismsg,2);
- registerserverhandler("AC",&handleaccountmsg,2);
+ registerserverhandler("AC",&handleaccountmsg,4);
registerserverhandler("R",&handlestatsmsg,2);
+ registerserverhandler("P",&handleprivmsg,2);
/* Fake the addition of our own server */
handleserverchange(HOOK_SERVER_NEWSERVER,(void *)numerictolong(mynumeric->content,2));
+}
+
+void _fini() {
+ nick *np;
+ int i;
- iptree = patricia_new_tree(PATRICIA_MAXBITS);
+ fininickhelpers();
+
+ for (i=0;i<NICKHASHSIZE;i++) {
+ for (np=nicktable[i];np;np=np->next) {
+ freesstring(np->shident);
+ freesstring(np->sethost);
+ freesstring(np->opername);
+ if(!np->auth && np->authname && (np->authname != NULLAUTHNAME))
+ free(np->authname);
+ }
+ }
+
+ nsfreeall(POOL_NICK);
+
+ /* Free the hooks */
+ deregisterhook(HOOK_SERVER_NEWSERVER,&handleserverchange);
+ deregisterhook(HOOK_SERVER_LOSTSERVER,&handleserverchange);
+ deregisterhook(HOOK_CORE_STATSREQUEST,&nickstats);
+
+ /* And our server handlers */
+ deregisterserverhandler("N",&handlenickmsg);
+ deregisterserverhandler("D",&handlekillmsg);
+ deregisterserverhandler("Q",&handlequitmsg);
+ deregisterserverhandler("M",&handleusermodemsg);
+ deregisterserverhandler("W",&handlewhoismsg);
+ deregisterserverhandler("AC",&handleaccountmsg);
+ deregisterserverhandler("R",&handlestatsmsg);
+ deregisterserverhandler("P",&handleprivmsg);
}
/*
*/
void handleserverchange(int hooknum, void *arg) {
- int servernum;
+ long servernum;
int i;
- servernum=(int)arg;
+ servernum=(long)arg;
switch(hooknum) {
case HOOK_SERVER_NEWSERVER:
- servernicks[servernum]=(nick **)malloc((serverlist[servernum].maxusernum+1)*sizeof(nick **));
+ servernicks[servernum]=(nick **)nsmalloc(POOL_NICK,(serverlist[servernum].maxusernum+1)*sizeof(nick **));
memset(servernicks[servernum],0,(serverlist[servernum].maxusernum+1)*sizeof(nick **));
break;
deletenick(servernicks[servernum][i]);
}
}
- free(servernicks[servernum]);
+ nsfree(POOL_NICK,servernicks[servernum]);
break;
}
}
releaserealname(np->realname);
releasehost(np->host);
+ if(IsAccount(np)) {
+ if(!np->auth) {
+ if(np->authname && (np->authname != NULLAUTHNAME))
+ free(np->authname);
+ } else {
+ np->auth->usercount--;
+
+ for (nh=&(np->auth->nicks);*nh;nh=&((*nh)->nextbyauthname)) {
+ if (*nh==np) {
+ *nh=np->nextbyauthname;
+ break;
+ }
+ }
+
+ releaseauthname(np->auth);
+ }
+ }
+
freesstring(np->shident); /* freesstring(NULL) is OK */
freesstring(np->sethost);
+ freesstring(np->opername);
+ node_decrement_usercount(np->ipnode);
derefnode(iptree, np->ipnode);
/* TODO: figure out how to cleanly remove nodes without affecting other modules */
}
}
- if ((int)arg>5) {
+ if ((long)arg>5) {
/* Full stats */
sprintf(buf,"Nick : %6d nicks (HASH: %6d/%6d, chain %3d)",total,buckets,NICKHASHSIZE,maxchain);
- } else if ((int)arg>2) {
+ } else if ((long)arg>2) {
sprintf(buf,"Nick : %6d users on network.",total);
}
- if ((int)arg>2) {
+ if ((long)arg>2) {
triggerhook(HOOK_CORE_STATSREPLY,buf);
}
}
}
}
- Error("channel",ERR_WARNING,"Tried to register too many extensions: %s",name);
+ Error("nick",ERR_WARNING,"Tried to register too many nick extensions: %s",name);
return -1;
}
*/
char *visiblehostmask(nick *np, char *buf) {
+ char uhbuf[USERLEN+HOSTLEN+2];
+
+ visibleuserhost(np, uhbuf);
+ sprintf(buf,"%s!%s",np->nick,uhbuf);
+
+ return buf;
+}
+
+/* visibleuserhost
+ * As above without nick
+ */
+
+char *visibleuserhost(nick *np, char *buf) {
char hostbuf[HOSTLEN+1];
char *ident, *host;
host=hostbuf;
}
- sprintf(buf,"%s!%s@%s",np->nick,ident,host);
+ sprintf(buf,"%s@%s",ident,host);
return buf;
}
#endif
-int registernodeext(const char *name) {
- int i;
-
- if (findnodeext(name)!=-1) {
- Error("nick",ERR_WARNING,"Tried to register duplicate node extension %s",name);
- return -1;
- }
-
- for (i=0;i<PATRICIA_MAXSLOTS;i++) {
- if (nodeextnames[i]==NULL) {
- nodeextnames[i]=getsstring(name,100);
- return i;
- }
- }
-
- Error("nick",ERR_WARNING,"Tried to register too many extensions: %s",name);
- return -1;
-}
-
-int findnodeext(const char *name) {
- int i;
-
- for (i=0;i<PATRICIA_MAXSLOTS;i++) {
- if (nodeextnames[i]!=NULL && !ircd_strcmp(name,nodeextnames[i]->content)) {
- return i;
- }
- }
-
- return -1;
-}
-
-void releasenodeext(int index) {
- patricia_node_t *head, *node;
-
- freesstring(nodeextnames[index]);
- nodeextnames[index]=NULL;
-
- head = iptree->head;
-
- PATRICIA_WALK_ALL(head, node)
- {
- node->slots[index]=NULL;
- } PATRICIA_WALK_END;
-}