]> jfr.im git - irc/quakenet/newserv.git/blobdiff - request/sqrequest.c
TRUSTS: require sqlite
[irc/quakenet/newserv.git] / request / sqrequest.c
index a765c85e30c40068b4edb90b114824e4d4799341..f2e069889fcac4c0f2f9b630e3c481955bc5b916 100644 (file)
@@ -14,6 +14,9 @@
 #include "../lib/irc_string.h"
 #include "../core/schedule.h"
 #include "../core/config.h"
+/*
+#include "../spamscan2/spamscan2.h"
+*/
 
 #include <stdarg.h>
 #include <stdio.h>
@@ -47,7 +50,7 @@ requestrec *nextreql, *lastreql;
 requestrec *nextreqq, *lastreqq;
 
 
-requestrec *nextqreq, *lastqreq;
+static requestrec *nextqreq, *lastqreq;
 
 extern nick *rqnick;
 int rlstate;
@@ -60,6 +63,12 @@ int qr_toosmall = 0;
 int qr_nochanlev = 0;
 int qr_notowner = 0;
 
+int qr_a = 0;
+int qr_b = 0;
+int qr_c = 0;
+int qr_d = 0;
+int qr_e = 0;
+
 /* Check whether the user is blocked */
 int qr_blockcheck(requestrec *req) {
   nick *np;
@@ -97,12 +106,13 @@ unsigned int rq_countchanusers(channel *cp) {
  * as part of the process.
  */
 
-void qr_result(requestrec *req, int outcome, char *message, ...) {
+static void qr_result(requestrec *req, int outcome, char failcode, char *message, ...) __attribute__ ((format (printf, 4, 5)));
+static void qr_result(requestrec *req, int outcome, char failcode, char *message, ...) {
   sstring *user, *password;
   requestrec **rh;
   char msgbuf[512];
   va_list va;
-  nick *lnp, *qnp, *np, *tnp, *snp;
+  nick *np, *tnp, *snp;
   char now[50];
   time_t now_ts;
   unsigned int unique, total;
@@ -160,47 +170,30 @@ void qr_result(requestrec *req, int outcome, char *message, ...) {
 
     strftime(now, sizeof(now), "%c", localtime(&now_ts));
     fprintf(rq_logfd, "%s: request (%s) for %s (%d unique users, "
-            "%d total users) from %s: Request was %s.\n", now,
-            (req->what == QR_CSERVE) ? RQ_QNICK : RQ_SNICK,
-            req->cip->name->content, unique, total, tnp->nick,
-            (outcome == QR_OK) ? "accepted" : "denied");
+            "%d total users) from %s!%s@%s%s%s: Request was %s (%c).\n", now,
+            (req->what == QR_CSERVE) ? rq_qnick->content : rq_snick->content,
+            req->cip->name->content, unique, total,
+            tnp->nick, tnp->ident, tnp->host->name->content, IsAccount(tnp)?"/":"", IsAccount(tnp)?tnp->authname:"",
+            (outcome == QR_OK) ? "accepted" : "denied", failcode);
     fflush(rq_logfd);
   }
   
   if (outcome==QR_OK) {
-    if (req->what == QR_CSERVE) {
-      /* Delete L, add Q.  Check that they both exist first, though. */
-
-      if (!(lnp=getnickbynick(RQ_LNICK)) || !(qnp=getnickbynick(RQ_QNICK))) {
-        sendnoticetouser(rqnick, tnp,
-                         "Error: Cannot find %s and %s on the network. "
-                         "Please request again later.", RQ_LNICK, RQ_QNICK);
-        free(req);
-        return;
-      }
-  
-      /* /msg Q ADDCHAN <channel> <flags> <owners nick> <channeltype> */
-      sendmessagetouser(rqnick, qnp, "ADDCHAN %s +ap #%s upgrade",
-                        req->cip->name->content,
-                        np->authname);
-  
-      sendnoticetouser(rqnick, tnp, "Adding %s to channel, please wait...",
-                        RQ_QNICK);
-    } else if (req->what == QR_SPAMSCAN) {
+    if (req->what == QR_SPAMSCAN) {
       /* Add S */
 
-      if (!(snp=getnickbynick(RQ_SNICK))) {
+      if (!(snp=getnickbynick(rq_snick->content))) {
         sendnoticetouser(rqnick, tnp,
-                         "Error: Cannot find %s on the network. "
-                         "Please request again later.", RQ_SNICK);
+                         "Cannot find %s on the network. "
+                         "Please try your request again later.", rq_snick->content);
 
         free(req);
         return;
       }
 
-      sendnoticetouser(rqnick, tnp, "Requirements met, %s should be added. "
-                        "Contact #help should further assistance be required.",
-                        RQ_SNICK);
+      sendnoticetouser(rqnick, tnp, "Success! %s has been added to '%s' "
+                        "(contact #help if you require further assistance).",
+                        rq_snick->content, req->cip->name->content);
 
       /* auth */
       user = (sstring *)getcopyconfigitem("request", "user", "R", 30);
@@ -210,7 +203,47 @@ void qr_result(requestrec *req, int outcome, char *message, ...) {
       freesstring(password);
 
       /* /msg S addchan <channel> default */
-      sendmessagetouser(rqnick, snp, "ADDCHAN %s default +op", req->cip->name->content);
+      sendmessagetouser(rqnick, snp, "ADDCHAN %s default +o", req->cip->name->content);
+
+/*
+{
+    spamscan_channelprofile *cp;
+    spamscan_channelsettings *cs;
+    spamscan_channelext *ce;
+    chanindex *sc_index;
+    
+    cs = spamscan_getchannelsettings(req->cip->name->content, 0);
+    
+    if ( !cs ) {
+        cp = spamscan_getchannelprofile("Default", 0);
+        
+        if ( cp ) {
+            cs = spamscan_getchannelsettings(req->cip->name->content, 1);
+            
+            if ( cs ) {
+                cs->cp = cp;
+                cs->addedby = spamscan_getaccountsettings("R", 0);
+                cs->flags = SPAMSCAN_CF_IGNOREOPS;
+                
+                sc_index = findorcreatechanindex(req->cip->name->content);
+                
+                if ( sc_index ) {
+                    ce = spamscan_getchanext(sc_index, 1);
+                    ce->cs = cs;
+                    
+                    if ( s_nickname && !CFIsSuspended(cs) && sc_index->channel ) {
+                        ce->joinedchan = 1;
+                        localjoinchannel(s_nickname, sc_index->channel);
+                        localgetops(s_nickname, sc_index->channel);
+                    }
+                }
+                
+                spamscan_insertchanneldb(cs);
+            }
+        }
+    }
+}
+*/
 
       /* we do not put the request into another queue, so free it here */
       free(req);
@@ -248,7 +281,7 @@ void qr_result(requestrec *req, int outcome, char *message, ...) {
  *  Checks that a channel is beeeeg enough for teh Q
  */
 
-int qr_checksize(chanindex *cip, int what) {
+static int qr_checksize(chanindex *cip, int what, char *failcode) {
   chanstats *csp;
   channel *cp;
   nick *np, *qbot;
@@ -265,13 +298,16 @@ int qr_checksize(chanindex *cip, int what) {
 
   /* make sure we can actually add Q */
   if (what == QR_CSERVE) {
-    qbot = getnickbynick(RQ_QNICK);
+    qbot = getnickbynick(rq_qnick->content);
 
     if (!qbot)
       return 0;
 
-    if (QR_MAXQCHANS != 0 && qbot->channels->cursi > QR_MAXQCHANS)
+    if (QR_MAXQCHANS != 0 && qbot->channels->cursi > QR_MAXQCHANS) {
+      qr_a++;
+      *failcode = 'A';
       return 0; /* no Q for you :p */
+    }
   }
 
   /* make sure that there are enough authed users */
@@ -286,8 +322,32 @@ int qr_checksize(chanindex *cip, int what) {
     }
   }
 
-  if (authedcount * 100 / count < ((what == QR_CSERVE) ? QR_AUTHEDPCT_CSERVE : QR_AUTHEDPCT_SPAMSCAN)) 
+  int authedpct;
+  
+  if (what == QR_CSERVE) {
+    if ( count <= QR_AUTHEDPCT_SCALE ) {
+      authedpct = QR_AUTHEDPCT_CSERVE;
+    } else if ( count >= QR_AUTHEDPCT_SCALEMAX ) {
+      authedpct = QR_AUTHEDPCT_CSERVEMIN;
+    } else {
+      authedpct = (QR_AUTHEDPCT_CSERVEMIN + (((QR_AUTHEDPCT_CSERVE - QR_AUTHEDPCT_CSERVEMIN) * (100 - (((count - QR_AUTHEDPCT_SCALE) * 100) / (QR_AUTHEDPCT_SCALEMAX - QR_AUTHEDPCT_SCALE)))) / 100));
+    }
+  }
+  else {
+    if ( count <= QR_AUTHEDPCT_SCALE ) {
+      authedpct = QR_AUTHEDPCT_SPAMSCAN;
+    } else if ( count >= QR_AUTHEDPCT_SCALEMAX ) {
+      authedpct = QR_AUTHEDPCT_SPAMSCANMIN;
+    } else {
+      authedpct = (QR_AUTHEDPCT_SPAMSCANMIN + (((QR_AUTHEDPCT_SPAMSCAN - QR_AUTHEDPCT_SPAMSCANMIN) * (100 - (((count - QR_AUTHEDPCT_SCALE) * 100) / (QR_AUTHEDPCT_SCALEMAX - QR_AUTHEDPCT_SCALE)))) / 100));
+    }
+  }
+  
+  if (authedcount * 100 / count < authedpct) {
+    qr_b++;
+    *failcode = 'B';
     return 0; /* too few authed users */
+  }
 
   if (!(csp=cip->exts[csext]))
     return 0;
@@ -301,16 +361,28 @@ int qr_checksize(chanindex *cip, int what) {
 
   /* chan needs at least QR_MINUSERPCT% of the avg usercount, and can't have
    * more than QR_MAXUSERPCT% */
-  if ((avgcount * QR_MINUSERSPCT / 100 > uniquecount) || 
-         (avgcount * QR_MAXUSERSPCT / 100 < uniquecount))
-    return 0;
-  
+  if ( what == QR_CSERVE ) {
+    if ((avgcount * QR_MINUSERSPCT / 100 > uniquecount)) {
+      qr_c++;
+      *failcode = 'C';
+      return 0;
+    }
+    if ((avgcount * QR_MAXUSERSPCT / 100 < uniquecount)) {
+      qr_e++; 
+      *failcode = 'E';
+      return 0;
+    }
+  }
+
   avg = (what == QR_CSERVE) ? QR_REQUIREDSIZE_CSERVE : QR_REQUIREDSIZE_SPAMSCAN;
 
   if (tot > (avg * 140))
     return 1;
-  else
+  else {
+    qr_d++;
+    *failcode = 'D';
     return 0;
+  }
 }
 
 /* This function deals with notices from L: basically we track the
@@ -325,7 +397,7 @@ int qr_checksize(chanindex *cip, int what) {
  * 11:12 -L(TheLBot@lightweight.quakenet.org)- End of chanlev for #twilightzone.
  */
 
-void qr_handlenotice(nick *sender, char *message) {
+void qr_handle_notice(nick *sender, char *message) {
   char *ch, *chop;
   chanindex *cip;
   requestrec *rrp1, *rrp2;
@@ -333,41 +405,17 @@ void qr_handlenotice(nick *sender, char *message) {
   int delrequest = 0, state, who;
   requestrec *nextreq;
 
-/*  logcp = findchannel("#qnet.request");
-  
-  if (logcp)
-    sendmessagetochannel(rqnick, logcp, "%s: %s - %d %d %x %x", sender->nick, message, rlstate, rqstate, nextreql, nextreqq);
-*/
-  if (!ircd_strcmp(sender->nick, RQ_QNICK) && nextqreq) {
+  if (!ircd_strcmp(sender->nick, rq_qnick->content) && nextqreq) {
     /* Message from Q */
     if (!ircd_strcmp(message,"Done.")) {
       /* Q added the channel: delete from L and tell the user. */
       /* If L has conspired to vanish between the request and the outcome,
        * we have a chan with Q and L... too bad. */
-
-      if ((np=getnickbynick(RQ_LNICK))) {
-        sendmessagetouser(rqnick, np, "SENDCHANLEV %s %s",
-                          nextqreq->cip->name->content, RQ_QNICK);
-
-        sendmessagetouser(rqnick, np, "DELCHAN %s",
-                          nextqreq->cip->name->content);
-      }
-
-      if ((np=getnickbynumeric(nextqreq->reqnumeric))) {
-        sendnoticetouser(rqnick, np, "Request completed. %s added.", RQ_QNICK);
-      }
       
       delrequest = 1;
     } else if (!ircd_strcmp(message,"That channel already exists.")) {
-      if ((np=getnickbynumeric(nextqreq->reqnumeric))) {
-        sendnoticetouser(rqnick, np,
-                         "Your channel appears to have %s already "
-                         "(it may be suspended).", RQ_QNICK);
-
-        qr_suspended++;
         
         delrequest = 1;
-      }
     }
 
     /* For either of the two messages above we want to delete the request
@@ -383,8 +431,8 @@ void qr_handlenotice(nick *sender, char *message) {
     }
   }
 
-  if (!ircd_strcmp(sender->nick, RQ_LNICK) || !ircd_strcmp(sender->nick, RQ_QNICK)) {
-    who = !ircd_strcmp(sender->nick, RQ_LNICK) ? QR_L : QR_Q;
+  if (!ircd_strcmp(sender->nick, rq_qnick->content)) {
+    who = QR_Q;
     state = (who == QR_Q) ? rqstate : rlstate;
     nextreq = (who == QR_Q) ? nextreqq : nextreql;
 
@@ -400,7 +448,6 @@ void qr_handlenotice(nick *sender, char *message) {
           (!ircd_strncmp(message,"Known users on",14) && who == QR_Q)
         ) {
           /* Looks like the right message.  Let's find a channel name */
-
           for (ch=message;*ch;ch++)
             if (*ch=='#')
               break;
@@ -414,12 +461,11 @@ void qr_handlenotice(nick *sender, char *message) {
           /* chop off any remaining words */
           chop = ch;
           while (*(chop++)) {
-            if (*chop == ' ') {
+            if (*chop == ' ' || *chop == ':') {
               *chop = '\0';
               break;
             }
           }
-
           if (!(cip=findchanindex(ch))) {
             Error("qrequest",ERR_WARNING,
                   "Unable to find channel from L/Q message: %s",ch);
@@ -433,7 +479,6 @@ void qr_handlenotice(nick *sender, char *message) {
               rlstate = QRLstate_AWAITINGUSER;
             else
               rqstate = QRLstate_AWAITINGUSER;
-
             return;
           } else {
             /* Uh-oh, not the channel we wanted.  Something is fucked
@@ -462,7 +507,7 @@ void qr_handlenotice(nick *sender, char *message) {
                       "Lost response for channel %s; skipping.",
                       rrp2->cip->name->content);
 
-                qr_result(rrp2, QR_FAILED,
+                qr_result(rrp2, QR_FAILED, 'X',
                           "Sorry, an error occurred while processing your request.");
 
                 rrp2 = nextreq = (who == QR_Q) ? nextreqq : nextreql;
@@ -497,8 +542,7 @@ void qr_handlenotice(nick *sender, char *message) {
           /* Oh dear, we got to the end of the chanlev in this state.
            * This means that we didn't find the user.
            */
-
-          qr_result(nextreq, QR_FAILED,
+          qr_result(nextreq, QR_FAILED, 'X', 
                     "Error: You are not known on %s.",
                     nextreq->cip->name->content);
 
@@ -542,33 +586,42 @@ void qr_handlenotice(nick *sender, char *message) {
             /* This is not the user you are looking for */
             return;
           }
-
           /* Check for owner flag.  Both branches of this if will
            * take the request off the list, one way or the other. */
-          if (strchr(ch, 'n')) {
+
+         /* chop off any remaining words */
+         chop = ch;
+         while (*(chop++)) {
+           if (*chop != ' ' ) {
+             break;
+           }
+        }
+         /* chop off any remaining words */
+         ch = chop;
+         while (*(chop++)) {
+           if (*chop == ' ' || *chop == ':') {
+             *chop = '\0';
+             break;
+           }
+         }
+
+         if (strchr(ch, 'n')) {
+            char failcode;
             /* They iz teh +n! */
-            
             /* Note: We're checking for blocks kind of late, so the request
                system gets a chance to send other error messages first (like
               'no chanstats', 'not known on channel', etc.). This is required
               so that the user doesn't notice that he's being blocked. */
-            if (qr_checksize(nextreq->cip, nextreq->what) && !qr_blockcheck(nextreq)) {
-              qr_result(nextreq, QR_OK, "OK");
+            if (qr_checksize(nextreq->cip, nextreq->what, &failcode) && !qr_blockcheck(nextreq)) {
+              qr_result(nextreq, QR_OK, '-', "OK");
             } else {
-              if (nextreq->what == QR_CSERVE) {
-                qr_result(nextreq, QR_FAILED,
-                          "Error: You do not meet the requirements "
-                          "for %s. Please continue to use %s.", RQ_QNICK, RQ_LNICK);                          
-              } else {
-                qr_result(nextreq, QR_FAILED,
-                          "Error: Your channel does not require %s. "
-                          "Try again later.", RQ_SNICK);
-              }
-
+                qr_result(nextreq, QR_FAILED, failcode,
+                          "Error: Sorry, Your channel '%s' does not require %s. Please try again in a few days.", nextreq->cip->name->content, rq_snick->content);
+       
               qr_toosmall++;
             }
           } else {
-            qr_result(nextreq, QR_FAILED,
+            qr_result(nextreq, QR_FAILED, 'X', 
                       "Error: You don't hold the +n flag on %s.",
                       nextreq->cip->name->content);
 
@@ -616,57 +669,6 @@ void qr_handlenotice(nick *sender, char *message) {
  */
 
 int qr_requestq(nick *rqnick, nick *sender, channel *cp, nick *lnick, nick *qnick) {
-  chanindex *cip = cp->index;
-
-  /* Check:
-   *  - we have some form of channel stats for the channel
-   *
-   * Note that the actual channel stats will not be checked
-   * until we're sure the user has +n on the channel.
-   */
-
-  if (rq_isspam(sender)) {
-      sendnoticetouser(rqnick, sender, "Error: Do not flood the request system."
-            " Try again in %s.", rq_longtoduration(rq_blocktime(sender)));
-    
-      return RQ_ERROR;
-  }
-
-  if (!cip->exts[csext]) {
-    sendnoticetouser(rqnick, sender,
-                     "Error: No historical record exists for %s.",
-                     cip->name->content);
-
-    qr_nohist++;
-
-    return RQ_ERROR;
-  }
-
-  /* Request stats from L */
-  sendmessagetouser(rqnick, lnick, "CHANLEV %s", cip->name->content);
-
-  /* Sort out a request record */
-  if (lastreql) {
-    lastreql->next = (requestrec *)malloc(sizeof(requestrec));
-    lastreql=lastreql->next;
-  } else {
-    lastreql=nextreql=(requestrec *)malloc(sizeof(requestrec));
-  }
-
-  lastreql->next = NULL;
-  lastreql->cip = cip;
-  lastreql->what = QR_CSERVE;
-  lastreql->who = QR_L;
-  lastreql->reqnumeric = sender->numeric;
-
-  if (rlstate == QRLstate_IDLE)
-    rlstate = QRLstate_AWAITINGCHAN;
-
-  sendnoticetouser(rqnick, sender,
-                   "Checking your %s access. "
-                   "This may take a while, please be patient...", RQ_LNICK);
-                   
-  /* we don't know yet whether the request was successful */
   return RQ_UNKNOWN;
 }
 
@@ -675,9 +677,10 @@ int qr_instantrequestq(nick *sender, channel *cp) {
   chanfix *cf;
   regop *ro;
   int rocount, i;
+  char failcode;
   regop *rolist[QR_TOPX];
 
-  if (!qr_checksize(cp->index, QR_CSERVE))
+  if (!qr_checksize(cp->index, QR_CSERVE, &failcode))
     return RQ_ERROR;
 
   cf = cf_findchanfix(cp->index);
@@ -720,37 +723,17 @@ int qr_instantrequestq(nick *sender, channel *cp) {
     nextreql = fakerequest;
   }
   
-  qr_result(fakerequest, QR_OK, "OK");
+  qr_result(fakerequest, QR_OK, '-', "OK");
   
   return RQ_OK;
 }
 
-int qr_requests(nick *rqnick, nick *sender, channel *cp, nick *lnick, nick *qnick) {
+int qr_requests(nick *rqnick, nick *sender, channel *cp, nick *qnick) {
   chanindex *cip = cp->index;
-  int who = 0;
   requestrec *nextreq, *lastreq;
 
-  if (rq_isspam(sender)) {
-      sendnoticetouser(rqnick, sender, "Error: Do not flood the request system."
-          " Try again in %s.", rq_longtoduration(rq_blocktime(sender)));
-    
-      return RQ_ERROR;
-  }
-
   /* check which service is on the channel */
-  if (getnumerichandlefromchanhash(cp->users, lnick->numeric) != NULL) {
-    /* we've found L */
-    who = QR_L;
-
-    /* Request stats from L */
-    sendmessagetouser(rqnick, lnick, "CHANLEV %s", cip->name->content);
-
-    if (rlstate == QRLstate_IDLE)
-      rlstate = QRLstate_AWAITINGCHAN;
-  } else if (getnumerichandlefromchanhash(cp->users, qnick->numeric) != NULL) {
-    /* we've found Q */
-    who = QR_Q;
-
+  if (getnumerichandlefromchanhash(cp->users, qnick->numeric) != NULL) {
     /* Request stats from Q */
     sendmessagetouser(rqnick, qnick, "CHANLEV %s", cip->name->content);
 
@@ -758,8 +741,8 @@ int qr_requests(nick *rqnick, nick *sender, channel *cp, nick *lnick, nick *qnic
       rqstate = QRLstate_AWAITINGCHAN;
   } /* 'else' cannot happen as R has already checked whether the user has L or Q */
 
-  lastreq = (who == QR_Q) ? lastreqq : lastreql;
-  nextreq = (who == QR_Q) ? nextreqq : nextreql;
+  lastreq = lastreqq;
+  nextreq = nextreqq;
 
   /* Sort out a request record */
   if (lastreq) {
@@ -774,18 +757,13 @@ int qr_requests(nick *rqnick, nick *sender, channel *cp, nick *lnick, nick *qnic
   lastreq->what = QR_SPAMSCAN;
   lastreq->reqnumeric = sender->numeric;
 
-  if (who == QR_Q) {
-    nextreqq = nextreq;
-    lastreqq = lastreq;
-  } else {
-    nextreql = nextreq;
-    lastreql = lastreq;
-  }
+  nextreqq = nextreq;
+  lastreqq = lastreq;
 
-   sendnoticetouser(rqnick, sender,
-                   "Checking your %s access. "
+  sendnoticetouser(rqnick, sender,
+                   "Checking your %s access in '%s'. "
                    "This may take a while, please be patient...",
-                   who == QR_Q ? RQ_QNICK : RQ_LNICK);
+                   rq_qnick->content, cip->name->content);
 
   return RQ_UNKNOWN;
 }
@@ -819,9 +797,15 @@ void qr_finirequest(void) {
 }
 
 void qr_requeststats(nick *rqnick, nick *np) {
-  sendnoticetouser(rqnick, np, "- Suspended (Q):                  %d", qr_suspended);
-  sendnoticetouser(rqnick, np, "- No chanstats (Q/S):             %d", qr_nohist);
-  sendnoticetouser(rqnick, np, "- Too small (Q/S):                %d", qr_toosmall);
-  sendnoticetouser(rqnick, np, "- User was not on chanlev (Q/S):  %d", qr_nochanlev);
-  sendnoticetouser(rqnick, np, "- User was not the owner (Q/S):   %d", qr_notowner);
+  sendnoticetouser(rqnick, np, "- Suspended (S):                  %d", qr_suspended);
+  sendnoticetouser(rqnick, np, "- No chanstats (S):               %d", qr_nohist);
+  sendnoticetouser(rqnick, np, "- Too small (S):                  %d", qr_toosmall);
+  sendnoticetouser(rqnick, np, "- User was not on chanlev (S):    %d", qr_nochanlev);
+  sendnoticetouser(rqnick, np, "- User was not the owner (S):     %d", qr_notowner);
+  sendnoticetouser(rqnick, np, "- A:                              %d", qr_a);
+  sendnoticetouser(rqnick, np, "- B:                              %d", qr_b);
+  sendnoticetouser(rqnick, np, "- C:                              %d", qr_c);
+  sendnoticetouser(rqnick, np, "- D:                              %d", qr_d);
+  sendnoticetouser(rqnick, np, "- E:                              %d", qr_e);
+
 }