]> jfr.im git - irc/quakenet/newserv.git/blobdiff - chanserv/chanservuser.c
fix indentation
[irc/quakenet/newserv.git] / chanserv / chanservuser.c
index f5e5db70174ee0a038935851f84b8a4c988d52aa..c90c4ac3a0cf9d3ef3671b72be00c54d742e9098 100644 (file)
@@ -243,7 +243,7 @@ void chanservjoinchan(channel *cp) {
   nick *np;
   reguser *rup;
   regchanuser *rcup;
-  flag_t themodes;
+  flag_t themodes = 0;
 
   /* Skip unregistered channels */
   if (!(rcp=cp->index->exts[chanservext]))
@@ -500,6 +500,9 @@ void chanservkillstdmessage(nick *target, int messageid, ... ) {
 }
 
 int checkpassword(reguser *rup, const char *pass) {
+  if (!(*rup->password))
+    return 0;
+
   if (!strncmp(rup->password, pass, PASSLEN))
     return 1;
   return 0;
@@ -508,6 +511,9 @@ int checkpassword(reguser *rup, const char *pass) {
 int checkresponse(reguser *rup, const unsigned char *entropy, const char *response, CRAlgorithm algorithm) {
   char usernamel[NICKLEN+1], *dp, *up;
 
+  if (!(*rup->password))
+    return 0;
+
   for(up=rup->username,dp=usernamel;*up;)
     *dp++ = ToLower(*up++);
   *dp = '\0';
@@ -546,10 +552,21 @@ void cs_checknick(nick *np) {
   if (IsAccount(np) && np->auth) {
     if (np->auth->exts[chanservaext]) {
       rup=getreguserfromnick(np);
+
       /* safe? */
-      if(rup && UHasSuspension(rup)) {
-        chanservkillstdmessage(np, QM_SUSPENDKILL);
-        return;
+      if(rup) {
+        if (UIsDelayedGline(rup)) {
+          /* delayed-gline - schedule the user's squelching */
+          deleteschedule(NULL, &chanservdgline, (void*)rup); /* icky, but necessary unless we stick more stuff in reguser structure */
+          scheduleoneshot(time(NULL)+rand()%900, &chanservdgline, (void*)rup);
+        } else if (UIsGline(rup)) {
+          /* instant-gline - lets be lazy and set a schedule expiring now :) */
+          deleteschedule(NULL, &chanservdgline, (void*)rup); /* icky, but necessary unless we stick more stuff in reguser structure */
+          scheduleoneshot(time(NULL), &chanservdgline, (void*)rup);
+        } else if(UHasSuspension(rup)) {
+          chanservkillstdmessage(np, QM_SUSPENDKILL);
+          return;
+        }
       }
       cs_doallautomodes(np);
     } else {
@@ -635,6 +652,9 @@ void cs_docheckchanmodes(channel *cp, modechanges *changes) {
   }
 }
 
+/* Slightly misnamed function that checks each USER on the channel against channel
+ * settings.  Possible actions are opping/deopping, voicing/devoicing, and banning
+ * for chanflag +k or chanlev flag +b */
 void cs_docheckopvoice(channel *cp, modechanges *changes) {
   regchan *rcp;
   reguser *rup;
@@ -653,7 +673,7 @@ void cs_docheckopvoice(channel *cp, modechanges *changes) {
       continue;
       
     if ((np=getnickbynumeric(cp->users->content[i]))==NULL) {
-      Error("chanserv",ERR_ERROR,"Found non-existent numeric %d on channel %s",cp->users->content[i],
+      Error("chanserv",ERR_ERROR,"Found non-existent numeric %lu on channel %s",cp->users->content[i],
             cp->index->name->content);
       continue;
     }
@@ -663,16 +683,24 @@ void cs_docheckopvoice(channel *cp, modechanges *changes) {
     else
       rcup=NULL;
     
-    if (rcup && CUIsBanned(rcup) && !IsService(np)) {
-      cs_banuser(changes, cp->index, np, NULL);
-      continue;
-    }
-
-    if (!IsService(np) && CIsKnownOnly(rcp) && !(rcup && CUKnown(rcup))) {
-      cs_banuser(changes, cp->index, np, "Authorised users only.");
-      continue;
+    /* Various things that might ban the user - don't apply these to +o, +k or +X users */
+    if (!IsService(np) && !IsXOper(np) && !IsOper(np)) {
+      if (rcup && CUIsBanned(rcup)) {
+        cs_banuser(changes, cp->index, np, NULL);
+        continue;
+      }
+      
+      /* chanflag +k checks; kick them if they "obviously" can't rejoin without a ban */
+      if (CIsKnownOnly(rcp) && !(rcup && CUKnown(rcup))) {
+        if (IsInviteOnly(cp) || (IsRegOnly(cp) && !IsAccount(np))) {
+          localkickuser(chanservnick,cp,np,"Authorised users only.");
+        } else {
+          cs_banuser(NULL, cp->index, np, "Authorised users only.");
+        }
+        continue;
+      }
     }
-    
+                                      
     if ((cp->users->content[i] & CUMODE_OP) && !IsService(np)) {
       if ((CIsBitch(rcp) && (!rcup || !CUHasOpPriv(rcup))) ||
            (rcup && CUIsDeny(rcup)))
@@ -704,11 +732,26 @@ void cs_doallautomodes(nick *np) {
     return;
   
   for (rcup=rup->knownon;rcup;rcup=rcup->nextbyuser) {
+    /* Skip suspended channels */
+    if (CIsSuspended(rcup->chan))
+      continue;
+      
     if (rcup->chan->index->channel) {
       /* Channel exists */
       if ((lp=getnumerichandlefromchanhash(rcup->chan->index->channel->users, np->numeric))) {
         /* User is on channel.. */
 
+        if (CUKnown(rcup) && rcup->chan->index->channel->users->totalusers >= 3) {
+          /* This meets the channel use criteria, update. */
+          rcup->chan->lastactive=time(NULL);
+          
+          /* Don't spam the DB though for channels with lots of joins */
+          if (rcup->chan->lastcountersync < (time(NULL) - COUNTERSYNCINTERVAL)) {
+            csdb_updatechannelcounters(rcup->chan);
+            rcup->chan->lastcountersync=time(NULL);
+          }
+        }
+
         /* Update last use time */
         rcup->usetime=getnettime();
 
@@ -748,7 +791,7 @@ void cs_checknickbans(nick *np) {
   regchan *rcp;
   int i,j;
 
-  if (IsService(np))
+  if (IsService(np) || IsOper(np) || IsXOper(np))
     return;
 
   /* Avoid races: memcpy the channel array */
@@ -758,7 +801,7 @@ void cs_checknickbans(nick *np) {
 
   for (j=0;j<i;j++) {
     if ((rcp=ca[j]->index->exts[chanservext]) && !CIsSuspended(rcp) && 
-       CIsEnforce(rcp) && nickbanned(np, ca[j]))
+       CIsEnforce(rcp) && nickbanned_visible(np, ca[j]))
       localkickuser(chanservnick, ca[j], np, "Banned.");
   }
 
@@ -789,18 +832,18 @@ void cs_checkbans(channel *cp) {
       continue;
     
     if ((np=getnickbynumeric(cp->users->content[i]))==NULL) {
-      Error("chanserv",ERR_ERROR,"Found numeric %d on channel %s who doesn't exist.",
+      Error("chanserv",ERR_ERROR,"Found numeric %lu on channel %s who doesn't exist.",
            cp->users->content[i], cp->index->name->content);
       continue;
     }
     
-    if (IsService(np))
+    if (IsService(np) || IsOper(np) || IsXOper(np))
       continue;
 
     for (rbp=rcp->bans;rbp;rbp=rbp->next) {
       if (((!rbp->expiry) || (rbp->expiry <= now)) &&
-         nickmatchban(np, rbp->cbp)) {
-       if (!nickbanned(np, cp)) {
+         nickmatchban_visible(np, rbp->cbp)) {
+       if (!nickbanned_visible(np, cp)) {
          localdosetmode_ban(&changes, bantostring(rbp->cbp), MCB_ADD);
        }
        localkickuser(chanservnick,cp,np,rbp->reason?rbp->reason->content:"Banned.");
@@ -813,7 +856,7 @@ void cs_checkbans(channel *cp) {
 
     if (CIsEnforce(rcp)) {
       for (cbp=cp->bans;cbp;cbp=cbp->next) {
-       if ((cbp->timeset>=rcp->lastbancheck) && nickmatchban(np, cbp))
+       if ((cbp->timeset>=rcp->lastbancheck) && nickmatchban_visible(np, cbp))
          localkickuser(chanservnick,cp,np,"Banned.");
       }
       rcp->lastbancheck=time(NULL);
@@ -897,9 +940,14 @@ void cs_timerfunc(void *arg) {
   
   if (CIsAutoLimit(rcp)) {
     if (!rcp->limit || rcp->autoupdate <= now) {
-      /* Update limit.. */
-      rcp->limit=cp->users->totalusers+rcp->autolimit;
-      rcp->status |= QCSTAT_MODECHECK;
+      /* Only update the limit if there are <= (autolimit/2) or 
+       * >= (autolimit * 1.5) slots free */
+      
+      if ((cp->users->totalusers >= (rcp->limit - rcp->autolimit/2)) ||
+          (cp->users->totalusers <= (rcp->limit - (3 * rcp->autolimit)/2))) {
+        rcp->limit=cp->users->totalusers+rcp->autolimit;
+        rcp->status |= QCSTAT_MODECHECK;
+      }
       
       /* And set the schedule for the next update */
       rcp->autoupdate = now + AUTOLIMIT_INTERVAL;
@@ -1092,9 +1140,9 @@ int cs_bancheck(nick *np, channel *cp) {
       freesstring(rbp->reason);
       freechanban(rbp->cbp);
       freeregban(rbp);
-    } else if (nickmatchban(np,(*rbh)->cbp)) {
+    } else if (nickmatchban_visible(np,(*rbh)->cbp)) {
       /* This user matches this ban.. */
-      if (!nickbanned(np,cp)) {
+      if (!nickbanned_visible(np,cp)) {
        /* Only bother putting the ban on the channel if they're not banned already */
        /* (might be covered by this ban or a different one.. doesn't really matter */
        localsetmodeinit(&changes, cp, chanservnick);
@@ -1127,8 +1175,8 @@ void cs_setregban(chanindex *cip, regban *rbp) {
   for (i=0;(cip->channel) && i<cip->channel->users->hashsize;i++) {
     if (cip->channel->users->content[i]!=nouser &&
        (np=getnickbynumeric(cip->channel->users->content[i])) &&
-       !IsService(np) &&
-       nickmatchban(np, rbp->cbp))
+       !IsService(np) && !IsOper(np) && !IsXOper(np) &&
+       nickmatchban_visible(np, rbp->cbp))
       localkickuser(chanservnick, cip->channel, np, rbp->reason ? rbp->reason->content : "Banned.");
   }
 
@@ -1142,7 +1190,7 @@ void cs_banuser(modechanges *changes, chanindex *cip, nick *np, const char *reas
   if (!cip->channel)
     return;
 
-  if (nickbanned(np, cip->channel)) {
+  if (nickbanned_visible(np, cip->channel)) {
     localkickuser(chanservnick, cip->channel, np, reason?reason:"Banned.");
     return;
   }