CBitcoinSecret::CBitcoinSecret(const CSecret& vchSecret, bool fCompressed) { SetSecret(vchSecret, fCompressed); }
int handlemodemsg(void *source, int cargc, char **cargv) { channel *cp; int dir=1; int arg=2; char *modestr; unsigned long *lp; void *harg[4]; nick *np, *target; int hooknum; int changes=0; if (cargc<2) { return CMD_OK; } if (cargv[0][0]!='#' && cargv[0][0]!='+') { /* Not a channel, ignore */ return CMD_OK; } if ((cp=findchannel(cargv[0]))==NULL) { /* No channel, abort */ Error("channel",ERR_WARNING,"Mode change on non-existent channel %s",cargv[0]); return CMD_OK; } if (((char *)source)[2]=='\0') { /* Server mode change, treat as divine intervention */ np=NULL; } else if ((np=getnickbynumericstr((char *)source))==NULL) { /* No sender, continue but moan */ Error("channel",ERR_WARNING,"Mode change by non-existent user %s on channel %s",(char *)source,cp->index->name->content); } /* Set up the hook data */ harg[0]=cp; harg[1]=np; harg[3]=(void *)(long)(cp->flags); /* Process the mode string one character at a time */ /* Maybe I'll write this more intelligently one day if I can comprehend the ircu code that does this */ for (modestr=cargv[1];*modestr;modestr++) { switch(*modestr) { /* Set whether we are adding or removing modes */ case '+': dir=1; break; case '-': dir=0; break; /* Simple modes: just set or clear based on value of dir */ case 'n': if (dir) { SetNoExtMsg(cp); } else { ClearNoExtMsg(cp); } changes |= MODECHANGE_MODES; break; case 't': if (dir) { SetTopicLimit(cp); } else { ClearTopicLimit(cp); } changes |= MODECHANGE_MODES; break; case 's': if (dir) { SetSecret(cp); ClearPrivate(cp); } else { ClearSecret(cp); } changes |= MODECHANGE_MODES; break; case 'p': if (dir) { SetPrivate(cp); ClearSecret(cp); } else { ClearPrivate(cp); } changes |= MODECHANGE_MODES; break; case 'i': if (dir) { SetInviteOnly(cp); } else { ClearInviteOnly(cp); } changes |= MODECHANGE_MODES; break; case 'm': if (dir) { SetModerated(cp); } else { ClearModerated(cp); } changes |= MODECHANGE_MODES; break; case 'c': if (dir) { SetNoColour(cp); } else { ClearNoColour(cp); } changes |= MODECHANGE_MODES; break; case 'C': if (dir) { SetNoCTCP(cp); } else { ClearNoCTCP(cp); } changes |= MODECHANGE_MODES; break; case 'r': if (dir) { SetRegOnly(cp); } else { ClearRegOnly(cp); } changes |= MODECHANGE_MODES; break; case 'D': if (dir) { SetDelJoins(cp); } else { ClearDelJoins(cp); } changes |= MODECHANGE_MODES; break; case 'u': if (dir) { SetNoQuitMsg(cp); } else { ClearNoQuitMsg(cp); } changes |= MODECHANGE_MODES; break; case 'N': if (dir) { SetNoNotice(cp); } else { ClearNoNotice(cp); } changes |= MODECHANGE_MODES; break; case 'M': if (dir) { SetModNoAuth(cp); } else { ClearModNoAuth(cp); } changes |= MODECHANGE_MODES; break; case 'T': if (dir) { SetSingleTarg(cp); } else { ClearSingleTarg(cp); } changes |= MODECHANGE_MODES; break; /* Parameter modes: advance parameter and possibly read it in */ case 'l': if (dir) { /* +l uses a parameter, but -l does not. * If there is no parameter, don't set the mode. * I guess we should moan too in that case, but * they might be even nastier to us if we do ;) */ if (arg<cargc) { cp->limit=strtol(cargv[arg++],NULL,10); SetLimit(cp); } } else { ClearLimit(cp); cp->limit=0; } changes |= MODECHANGE_MODES; break; case 'k': if (dir) { /* +k uses a parameter in both directions */ if (arg<cargc) { freesstring(cp->key); /* It's probably NULL, but be safe */ cp->key=getsstring(cargv[arg++],KEYLEN); SetKey(cp); } } else { freesstring(cp->key); cp->key=NULL; ClearKey(cp); arg++; /* Eat the arg without looking at it, even if it's not there */ } changes |= MODECHANGE_MODES; break; /* Op/Voice */ case 'o': case 'v': if (arg<cargc) { if((lp=getnumerichandlefromchanhash(cp->users,numerictolong(cargv[arg++],5)))==NULL) { /* They're not on the channel; MODE crossed with part/kill/kick/blah */ Error("channel",ERR_DEBUG,"Mode change for user %s not on channel %s",cargv[arg-1],cp->index->name->content); } else { if ((target=getnickbynumeric(*lp))==NULL) { /* This really is a fuckup, we found them on the channel but there isn't a user with that numeric */ /* This means there's a serious bug in the nick/channel tracking code */ Error("channel",ERR_ERROR,"Mode change for user %s on channel %s who doesn't exist",cargv[arg-1],cp->index->name->content); } else { /* Do the mode change whilst admiring the beautiful code layout */ harg[2]=target; if (*modestr=='o') { if (dir) { *lp |= CUMODE_OP; hooknum=HOOK_CHANNEL_OPPED; } else { *lp &= ~CUMODE_OP; hooknum=HOOK_CHANNEL_DEOPPED; } } else { if (dir) { *lp |= CUMODE_VOICE; hooknum=HOOK_CHANNEL_VOICED; } else { *lp &= ~CUMODE_VOICE; hooknum=HOOK_CHANNEL_DEVOICED; } } triggerhook(hooknum,harg); } } } changes |= MODECHANGE_USERS; break; case 'b': if (arg<cargc) { if (dir) { setban(cp,cargv[arg++]); triggerhook(HOOK_CHANNEL_BANSET,harg); } else { clearban(cp,cargv[arg++],0); triggerhook(HOOK_CHANNEL_BANCLEAR,harg); } } changes |= MODECHANGE_BANS; break; default: Error("channel",ERR_DEBUG,"Unknown mode char '%c' %s on %s",*modestr,dir?"set":"cleared",cp->index->name->content); break; } } harg[2]=(void *)((long)changes); triggerhook(HOOK_CHANNEL_MODECHANGE,(void *)harg); return CMD_OK; }