#include "../server/server.h"
#include "../parser/parser.h"
#include "../lib/version.h"
+#include "../lib/ccassert.h"
#include "../core/nsmalloc.h"
#include <stdlib.h>
MODULE_VERSION("");
+CCASSERT(sizeof(host) == sizeof(realname));
+
const flag umodeflags[] = {
{ 'i', UMODE_INV },
{ 'w', UMODE_WALLOPS },
{ 'R', UMODE_REGPRIV },
{ 'I', UMODE_HIDEIDLE },
{ 'P', UMODE_PARANOID },
+ { 'C', UMODE_CLOAKED },
+ { '\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() {
- initnickalloc();
+ 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;
+
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("D",&handlekillmsg,2);
registerserverhandler("Q",&handlequitmsg,1);
registerserverhandler("M",&handleusermodemsg,3);
- registerserverhandler("W",&handlewhoismsg,2);
registerserverhandler("AC",&handleaccountmsg,4);
- registerserverhandler("R",&handlestatsmsg,2);
+ registerserverhandler("P",&handleprivmsg,2);
+ registerserverhandler("A",&handleawaymsg,1);
+ registerserverhandler("CA",&handleaddcloak,1);
+ registerserverhandler("CU",&handleclearcloak,0);
/* Fake the addition of our own server */
handleserverchange(HOOK_SERVER_NEWSERVER,(void *)numerictolong(mynumeric->content,2));
-
- iptree = patricia_new_tree(PATRICIA_MAXBITS);
}
void _fini() {
+ nick *np;
+ int i;
+
+ 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);
deregisterserverhandler("D",&handlekillmsg);
deregisterserverhandler("Q",&handlequitmsg);
deregisterserverhandler("M",&handleusermodemsg);
- deregisterserverhandler("W",&handlewhoismsg);
- deregisterserverhandler("AC",&handleaccountmsg);
- deregisterserverhandler("R",&handlestatsmsg);
+ deregisterserverhandler("AC",&handleaccountmsg);
+ deregisterserverhandler("P",&handleprivmsg);
+ deregisterserverhandler("A",&handleawaymsg);
+ deregisterserverhandler("CA",&handleaddcloak);
+ deregisterserverhandler("CU",&handleclearcloak);
}
/*
releaserealname(np->realname);
releasehost(np->host);
- if(IsAccount(np) && np->auth)
- {
- np->auth->usercount--;
+ 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;
+ for (nh=&(np->auth->nicks);*nh;nh=&((*nh)->nextbyauthname)) {
+ if (*nh==np) {
+ *nh=np->nextbyauthname;
+ break;
+ }
}
- }
- releaseauthname(np->auth);
+ releaseauthname(np->auth);
+ }
}
freesstring(np->shident); /* freesstring(NULL) is OK */
freesstring(np->sethost);
+ freesstring(np->opername);
- np->ipnode->usercount--;
+ node_decrement_usercount(np->ipnode);
derefnode(iptree, np->ipnode);
/* TODO: figure out how to cleanly remove nodes without affecting other modules */
+ /* Remove cloak entries for the user */
+ removecloaktarget(np);
+ clearcloaktargets(np);
+
/* Delete the nick from the servernick table */
*(gethandlebynumericunsafe(np->numeric))=NULL;
*/
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;
}
return getnickbynumeric(numerictolong(numericstr,5));
}
-#endif
-int registernodeext(const char *name) {
- int i;
+#endif
- if (findnodeext(name)!=-1) {
- Error("nick",ERR_WARNING,"Tried to register duplicate node extension %s",name);
- return -1;
- }
+int canseeuser(nick *np, nick *cloaked)
+{
+ return (np == cloaked ||
+ !IsCloaked(cloaked) ||
+ np->cloak_extra == cloaked);
+}
- for (i=0;i<PATRICIA_MAXSLOTS;i++) {
- if (nodeextnames[i]==NULL) {
- nodeextnames[i]=getsstring(name,100);
- return i;
- }
- }
+void addcloaktarget(nick *cloaked, nick *target)
+{
+ removecloaktarget(target);
- Error("nick",ERR_WARNING,"Tried to register too many extensions: %s",name);
- return -1;
+ target->cloak_extra = cloaked;
+ cloaked->cloak_count++;
}
-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;
- }
+void removecloaktarget(nick *target)
+{
+ if (target->cloak_extra) {
+ target->cloak_extra->cloak_count--;
+ target->cloak_extra = NULL;
}
-
- return -1;
}
-void releasenodeext(int index) {
- patricia_node_t *head, *node;
-
- freesstring(nodeextnames[index]);
- nodeextnames[index]=NULL;
+void clearcloaktargets(nick *cloaked)
+{
+ nick *tnp;
+ int j;
- head = iptree->head;
+ for(j=0;j<NICKHASHSIZE;j++)
+ for(tnp=nicktable[j];tnp;tnp=tnp->next)
+ if (tnp->cloak_extra == cloaked)
+ tnp->cloak_extra = NULL;
- PATRICIA_WALK_ALL(head, node)
- {
- node->slots[index]=NULL;
- } PATRICIA_WALK_END;
+ cloaked->cloak_count = 0;
}
+