#include "../parser/parser.h"
#include <stdlib.h>
#include <string.h>
+#include <stdint.h>
/*
* handlenickmsg:
nick **nh;
char *fakehost;
char *accountts;
+ char *accountflags;
+ struct irc_in_addr ipaddress;
+ char *accountid;
+ unsigned long userid;
if (cargc==2) { /* rename */
/* Nyklon 1017697578 */
* different case, e.g. Flash -> flash. In this case the timestamp for the change should
* match the existing timestamp, and we can bypass all the collision checking and hash fettling. */
if (np->timestamp!=timestamp) {
- Error("nick",ERR_WARNING,"Rename to same nickname with different timestamp (%s(%d) -> %s(%d))",
- np->nick,np->timestamp,cargv[0],timestamp);
+ Error("nick",ERR_WARNING,"Rename to same nickname with different timestamp (%s(%jd) -> %s(%jd))",
+ np->nick,(intmax_t)np->timestamp,cargv[0], (intmax_t)timestamp);
np->timestamp=timestamp;
}
strncpy(np->nick,cargv[0],NICKLEN);
Error("nick",ERR_WARNING,"Received NICK with invalid numeric %s from %s.",cargv[cargc-2],sender);
return CMD_ERROR;
}
-
+
+ base64toip(cargv[cargc-3], &ipaddress);
+ if (!irc_in_addr_valid(&ipaddress)) {
+ Error("nick",ERR_ERROR,"Received NICK with invalid ipaddress for %s from %s.",cargv[0],sender);
+ return CMD_ERROR;
+ }
+
/* At this stage the nick is cleared to proceed */
np=newnick();
strncpy(np->nick,cargv[0],NICKLEN);
np->nextbyrealname=np->realname->nicks;
np->realname->nicks=np;
np->timestamp=timestamp;
- np->ipaddress=numerictolong(cargv[cargc-3],6);
+
+ base64toip(cargv[cargc-3], &ipaddress);
+ np->ipnode = refnode(iptree, &ipaddress, PATRICIA_MAXBITS);
+ node_increment_usercount(np->ipnode);
+
np->shident=NULL;
np->sethost=NULL;
+ np->opername=NULL;
np->umodes=0;
np->marker=0;
memset(np->exts, 0, MAXNICKEXTS * sizeof(void *));
- np->authname[0]='\0';
+ np->authname=NULLAUTHNAME;
+ np->auth=NULL;
+ np->accountts=0;
if(cargc>=9) {
+ int sethostarg = 6, opernamearg = 6, accountarg = 6;
+
setflags(&(np->umodes),UMODE_ALL,cargv[5],umodeflags,REJECT_NONE);
+
+ if(IsOper(np) && (serverlist[myhub].flags & SMODE_OPERNAME)) {
+ accountarg++;
+ sethostarg++;
+
+ np->opername=getsstring(cargv[opernamearg],ACCOUNTLEN);
+ }
+
if (IsAccount(np)) {
- if ((accountts=strchr(cargv[6],':'))) {
+ sethostarg++;
+
+ if ((accountts=strchr(cargv[accountarg],':'))) {
+ userid=0;
*accountts++='\0';
- np->accountts=strtoul(accountts,NULL,10);
- } else {
- np->accountts=0;
+ np->accountts=strtoul(accountts,&accountid,10);
+ if(accountid) {
+ userid=strtoul(accountid + 1,&accountflags,10);
+ if(userid) {
+ np->auth=findorcreateauthname(userid, cargv[accountarg]);
+ np->authname=np->auth->name;
+ np->auth->usercount++;
+ np->nextbyauthname=np->auth->nicks;
+ np->auth->nicks=np;
+ if(accountflags)
+ np->auth->flags=strtoull(accountflags + 1,NULL,10);
+ }
+ }
+ if(!userid) {
+ np->authname=malloc(strlen(cargv[accountarg]) + 1);
+ strcpy(np->authname,cargv[accountarg]);
+ }
}
- strncpy(np->authname,cargv[6],ACCOUNTLEN);
- np->authname[ACCOUNTLEN]='\0';
}
- if (IsSetHost(np) && (fakehost=strchr(cargv[cargc-4],'@'))) {
+ if (IsSetHost(np) && (fakehost=strchr(cargv[sethostarg],'@'))) {
/* valid sethost */
*fakehost++='\0';
- np->shident=getsstring(cargv[cargc-4],USERLEN);
+ np->shident=getsstring(cargv[sethostarg],USERLEN);
np->sethost=getsstring(fakehost,HOSTLEN);
}
}
nick *np;
void *harg[2];
- if (cargc>1) {
- harg[1]=(void *)cargv[1];
+ if (cargc>0) {
+ harg[1]=(void *)cargv[0];
} else {
harg[1]="";
}
int handlekillmsg(void *source, int cargc, char **cargv) {
nick *np;
-
+ void *harg[2];
+#warning Fix me to use source
+
if (cargc<1) {
Error("nick",ERR_WARNING,"Kill message with too few parameters");
return CMD_ERROR;
}
+
+ if (cargc>1) {
+ harg[1]=(void *)cargv[1];
+ } else {
+ harg[1]="";
+ }
+
np=getnickbynumericstr(cargv[0]);
if (np) {
+ harg[0]=(void *)np;
+ triggerhook(HOOK_NICK_KILL, harg);
deletenick(np);
} else {
Error("nick",ERR_WARNING,"Kill for non-existant numeric %s",cargv[0]);
return CMD_OK;
}
oldflags=np->umodes;
- if (strchr(cargv[1],'o')) {
- void *harg[2];
- harg[0]=np;
- harg[1]=cargv[1];
- triggerhook(HOOK_NICK_MODEOPER,harg);
- }
setflags(&(np->umodes),UMODE_ALL,cargv[1],umodeflags,REJECT_NONE);
+
+ if (strchr(cargv[1],'o')) { /* o always comes on its own when being set */
+ if(serverlist[myhub].flags & SMODE_OPERNAME) {
+ if((np->umodes & UMODE_OPER)) {
+ np->opername = getsstring(cargv[2], ACCOUNTLEN);
+ } else {
+ freesstring(np->opername);
+ np->opername = NULL;
+ }
+ }
+ if((np->umodes ^ oldflags) & UMODE_OPER)
+ triggerhook(HOOK_NICK_MODEOPER,np);
+ }
if (strchr(cargv[1],'h')) { /* Have to allow +h twice.. */
/* +-h: just the freesstring() calls for the -h case */
freesstring(np->shident); /* freesstring(NULL) is OK */
}
if (homeserver(target->numeric)==mylongnum && !IsService(target) && !IsHideIdle(target)) {
irc_send(":%s 317 %s %s %ld %ld :seconds idle, signon time",myserver->content,sender->nick,target->nick,
- target->timestamp % 3600,target->timestamp);
+ (getnettime() - target->timestamp) % (((target->numeric + target->timestamp) % 983) + 7),target->timestamp);
}
}
int handleaccountmsg(void *source, int cargc, char **cargv) {
nick *target;
-
- if (cargc<2) {
+ unsigned long userid;
+ time_t accountts;
+ u_int64_t accountflags=0, oldflags;
+
+ if (cargc<4) {
return CMD_OK;
}
return CMD_OK;
}
+ accountts=strtoul(cargv[2],NULL,10);
+ userid=strtoul(cargv[3],NULL,10);
+ if(cargc>=5)
+ accountflags=strtoull(cargv[4],NULL,10);
+
+ /* allow user flags to change if all fields match */
if (IsAccount(target)) {
+ void *arg[2];
+
+ if (!target->auth || strcmp(target->auth->name,cargv[1]) || (target->auth->userid != userid) || (target->accountts != accountts)) {
+ return CMD_OK;
+ }
+
+ oldflags = target->auth->flags;
+ arg[0] = target->auth;
+ arg[1] = &oldflags;
+
+ if (cargc>=5)
+ target->auth->flags=accountflags;
+
+ triggerhook(HOOK_AUTH_FLAGSUPDATED, (void *)arg);
+
return CMD_OK;
}
SetAccount(target);
- strncpy(target->authname,cargv[1],ACCOUNTLEN);
- target->authname[ACCOUNTLEN]='\0';
+ target->accountts=accountts;
+
+ if(!userid) {
+ target->auth=NULL;
+ target->authname=malloc(strlen(cargv[1]) + 1);
+ strcpy(target->authname,cargv[1]);
+ } else {
+ target->auth=findorcreateauthname(userid, cargv[1]);
+ target->auth->usercount++;
+ target->authname=target->auth->name;
+ target->nextbyauthname = target->auth->nicks;
+ target->auth->nicks = target;
+ if (cargc>=5)
+ target->auth->flags=accountflags;
+ }
triggerhook(HOOK_NICK_ACCOUNT, (void *)target);
-
+
return CMD_OK;
}
case 'P':
irc_send(":%s 217 %s P none 0 :0x2000",fromstring,replytarget);
break;
-
+
+ case 'm':
+ stats_m(fromstring, replytarget);
+ break;
}
irc_send(":%s 219 %s %c :End of /STATS report",fromstring,replytarget,cargv[0][0]);
return CMD_OK;
}
+
+int handleprivmsg(void *source, int cargc, char **cargv) {
+ nick *sender;
+ char *message;
+ void *args[3];
+
+ if (cargc<2)
+ return CMD_OK;
+
+ if (cargv[0][0]!='$')
+ return CMD_OK;
+
+ sender=getnickbynumericstr((char *)source);
+
+ if (!match2strings(cargv[0] + 1,myserver->content))
+ return CMD_OK;
+
+ message=cargv[0];
+
+ args[0]=sender;
+ args[1]=cargv[0];
+ args[2]=cargv[1];
+
+ triggerhook(HOOK_NICK_MASKPRIVMSG, (void *)args);
+
+ return CMD_OK;
+}
+