X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/2df6316a01ba6bd647fcea32a790e33e0011e6e6..8c684fca9c7dbb4a2601628c744be9236ee68641:/chanserv/chanservnetevents.c?ds=sidebyside diff --git a/chanserv/chanservnetevents.c b/chanserv/chanservnetevents.c index 0521174f..0320b00b 100644 --- a/chanserv/chanservnetevents.c +++ b/chanserv/chanservnetevents.c @@ -32,20 +32,12 @@ void cs_handlesethost(int hooknum, void *arg) { void cs_handlelostnick(int hooknum, void *arg) { nick *np=(nick *)arg; - nicklist **nlh; - nicklist *nlp; reguser *rup; if ((rup=getreguserfromnick(np))) { - for (nlh=&(rup->nicks);*nlh;nlh=&((*nlh)->next)) { - if ((*nlh)->np==np) { - nlp=*nlh; - *nlh=nlp->next; - freenicklist(nlp); - break; - } - } - if ((rup->status & QUSTAT_DEAD) && !rup->nicks) { + /* Clean up if this is the last user. auth->usercount is decremented + * AFTER the hook is sent... */ + if ((rup->status & QUSTAT_DEAD) && (np->auth->usercount==1)) { freereguser(rup); } } @@ -131,8 +123,9 @@ void cs_handlejoin(int hooknum, void *arg) { reguser *rup; regchanuser *rcup=NULL; chanindex *cip; - int iscreate; + int iscreate, isopped; int dowelcome=0; + unsigned long *lp; short modes=0; @@ -156,51 +149,70 @@ void cs_handlejoin(int hooknum, void *arg) { if (rup && (rcup=findreguseronchannel(rcp,rup)) && CUKnown(rcup) && cp->users->totalusers >= 3) rcp->lastactive=time(NULL); + + /* Update last use time */ + if (rcup) + rcup->usetime=getnettime(); if (rcp->lastcountersync < (time(NULL) - COUNTERSYNCINTERVAL)) { csdb_updatechannelcounters(rcp); rcp->lastcountersync=time(NULL); } + /* OK, this may be a CREATE but it's possible we have already bursted onto + * the channel and deopped them. So let's just check that out now. + * + * There's a distinction between "is it a create?" and "are they opped + * already?", since we need to send the generic "This is a Q9 channel" + * message on create even if we already deopped them. */ if (hooknum==HOOK_CHANNEL_CREATE) { iscreate=1; + if ((lp=getnumerichandlefromchanhash(cp->users, np->numeric)) && (*lp & CUMODE_OP)) + isopped=1; + else + isopped=0; } else { - iscreate=0; + isopped=iscreate=0; } - /* Check for "Q ban" */ - if (!IsService(np) && cs_bancheck(np,cp)) { - /* They got kicked.. */ - return; - } + /* Various things that can ban the user on join. Don't apply these to anyone + * with one of +k, +X, +o */ + if (!IsService(np) && !IsOper(np) && !IsXOper(np)) { + /* Check for "Q ban" */ + if (cs_bancheck(np,cp)) { + /* They got kicked.. */ + return; + } - /* Check for other ban lurking on channel which we are enforcing */ - if (!IsService(np) && CIsEnforce(rcp) && nickbanned(np,cp)) { - localkickuser(chanservnick,cp,np,"Banned."); - return; - } + /* Check for other ban lurking on channel which we are enforcing */ + if (CIsEnforce(rcp) && nickbanned_visible(np,cp)) { + localkickuser(chanservnick,cp,np,"Banned."); + return; + } - /* Check for +b chanlev flag */ - if (!IsService(np) && rcup && CUIsBanned(rcup)) { - cs_banuser(NULL, cip, np, NULL); - cs_timerfunc(cip); - return; - } - - /* Check for +k chan flag */ - if (!IsService(np) && CIsKnownOnly(rcp) && !(rcup && CUKnown(rcup))) { - if (IsInviteOnly(cp) || (IsRegOnly(cp) && !IsAccount(np))) { - localkickuser(chanservnick,cp,np,"Authorised users only."); - } else { - cs_banuser(NULL, cip, np, "Authorised users only."); + /* Check for +b chanlev flag */ + if (rcup && CUIsBanned(rcup)) { + cs_banuser(NULL, cip, np, NULL); cs_timerfunc(cip); + return; + } + + /* Check for +k chan flag */ + if (CIsKnownOnly(rcp) && !(rcup && CUKnown(rcup))) { + /* Don't ban if they are already "visibly" banned for some reason. */ + if (IsInviteOnly(cp) || (IsRegOnly(cp) && !IsAccount(np))) { + localkickuser(chanservnick,cp,np,"Authorised users only."); + } else { + cs_banuser(NULL, cip, np, "Authorised users only."); + cs_timerfunc(cip); + } + return; } - return; } - + if (!rup || !rcup) { /* They're not a registered user, so deop if it is a create */ - if (iscreate && !IsService(np)) { + if (isopped && !IsService(np)) { modes |= MC_DEOP; } if (CIsVoiceAll(rcp)) { @@ -213,8 +225,6 @@ void cs_handlejoin(int hooknum, void *arg) { dowelcome=2; /* Send a generic warning */ } } else { - /* Update last use time */ - rcup->usetime=getnettime(); /* DB update removed for efficiency.. * csdb_updatelastjoin(rcup); */ @@ -223,12 +233,13 @@ void cs_handlejoin(int hooknum, void *arg) { if (CUIsOp(rcup) && (CIsAutoOp(rcp) || CUIsAutoOp(rcup) || CUIsProtect(rcup) || CIsProtect(rcp)) && !CUIsDeny(rcup)) { /* Auto op */ - if (!iscreate) { + if (!isopped) { modes |= MC_OP; + cs_logchanop(rcp, np->nick, rup); } } else { - /* Not auto op */ - if (iscreate && !CUIsOp(rcup) && !IsService(np)) { + /* Not auto op; deop them if they are opped and are not allowed them */ + if (isopped && !CUHasOpPriv(rcup) && !IsService(np)) { modes |= MC_DEOP; } @@ -263,11 +274,15 @@ void cs_handlejoin(int hooknum, void *arg) { break; } - if (rup && rcup && CIsInfo(rcp) && UIsInfo(rcup->user) && !CUIsHideInfo(rcup) && chanservnick) { - if (rcup->info) { + /* Display infoline if... (deep breath) user is registered, known on channel, + * user,channel,chanlev all +i and user,channel,chanlev all -s AND Q online */ + if (rup && rcup && + CIsInfo(rcp) && UIsInfo(rcup->user) && CUIsInfo(rcup) && + !CIsNoInfo(rcp) && !UIsNoInfo(rcup->user) && !CUIsNoInfo(rcup) && chanservnick) { + if (rcup->info && *(rcup->info->content)) { /* Chan-specific info */ sendmessagetochannel(chanservnick, cp, "[%s] %s",np->nick, rcup->info->content); - } else if (rup->info) { + } else if (rup->info && *(rup->info->content)) { /* Default info */ sendmessagetochannel(chanservnick, cp, "[%s] %s",np->nick, rup->info->content); } @@ -394,7 +409,7 @@ void cs_handlenewban(int hooknum, void *arg) { Error("chanserv",ERR_WARNING,"Found user on channel %s who doesn't exist!",cp->index->name->content); continue; } - if (!IsService(np) && nickmatchban(np,cbp)) { + if (!IsService(np) && nickmatchban_visible(np,cbp)) { localkickuser(chanservnick,cp,np,"Banned."); } }