]> jfr.im git - irc/quakenet/newserv.git/blobdiff - chanstats/chanstats.c
fix sstring leak if PROXYSCAN_MAIL is false
[irc/quakenet/newserv.git] / chanstats / chanstats.c
index 7f69d461e3a96162ccfc29b17dd40ed95eeac3ef..f1269170d160ead9713e19515df31f92dad7ca77 100644 (file)
@@ -9,13 +9,16 @@
 #include "../control/control.h"
 #include "../nick/nick.h"
 #include "../lib/irc_string.h"
+#include "../lib/version.h"
 
 #include <stdio.h>
 #include <string.h>
 
+MODULE_VERSION("");
+
 int csext;
 int sampleindex;
-time_t lastsample;
+time_t chanstats_lastsample;
 time_t lastday;
 int uponehour;
 int failedinit;
@@ -29,6 +32,7 @@ void updatechanstats(chanindex *cip, time_t now);
 void rotatechanstats();
 void savechanstats();
 void loadchanstats();
+int dochanstatssave(void *source, int argc, char **argv);
 int dochanstats(void *source, int argc, char **argv);
 int doexpirecheck(void *source, int cargc, char **cargv);
 int douserhistogram(void *source, int cargc, char **cargv);
@@ -59,14 +63,14 @@ void _init() {
   
     /* Work out when to take the next sample */
     now=getnettime();
-    if (now < lastsample) {
-      Error("chanstats",ERR_WARNING,"Last sample time in future (%d > %d)",lastsample,now);
+    if (now < chanstats_lastsample) {
+      Error("chanstats",ERR_WARNING,"Last sample time in future (%d > %d)",chanstats_lastsample,now);
       when=now;
-    } else if (now<(lastsample+SAMPLEINTERVAL)) {
-      lastday=lastsample/(24*3600);
-      when=lastsample+SAMPLEINTERVAL;
+    } else if (now<(chanstats_lastsample+SAMPLEINTERVAL)) {
+      lastday=chanstats_lastsample/(24*3600);
+      when=chanstats_lastsample+SAMPLEINTERVAL;
     } else {
-      if ((lastsample/(24*3600))<lastday) {
+      if ((chanstats_lastsample/(24*3600))<lastday) {
         rotatechanstats();
       }
       when=now;
@@ -77,6 +81,7 @@ void _init() {
     registercontrolcmd("channelhistogram",10,13,&dochanhistogram);
     registercontrolcmd("userhistogram",10,1,&douserhistogram);
     registercontrolcmd("expirecheck",10,1,&doexpirecheck);
+    registercontrolhelpcmd("chanstatssave",NO_DEVELOPER,1, &dochanstatssave, "Usage: chanstatssave\nForce a save of chanstats data");
     schedulerecurring(when,0,SAMPLEINTERVAL,&doupdate,NULL);  
   }
 }
@@ -89,6 +94,7 @@ void _fini() {
     deregistercontrolcmd("channelhistogram",&dochanhistogram);
     deregistercontrolcmd("userhistogram",&douserhistogram);
     deregistercontrolcmd("expirecheck",&doexpirecheck);
+    deregistercontrolcmd("chanstatssave",&dochanstatssave);
     releasechanext(csext);
     cstsfreeall();
   }
@@ -133,7 +139,7 @@ void doupdate(void *arg) {
     }
   }
   
-  lastsample=now;
+  chanstats_lastsample=now;
   if (now-lastsave > SAVEINTERVAL) {
     savechanstats();
     lastsave=now;
@@ -151,7 +157,25 @@ void updatechanstats(chanindex *cip, time_t now) {
   }
 
   if (cip->channel!=NULL) {
-    currentusers=countuniquehosts(cip->channel);
+    channel *cp = cip->channel;
+    int i;
+    nick *np;
+
+    currentusers=countuniquehosts(cp);
+
+    for (i=0;i<cp->users->hashsize;i++) {
+      if (cp->users->content[i]==nouser)
+        continue;
+
+      if ((np=getnickbynumeric(cp->users->content[i]))==NULL) {
+        Error("channel",ERR_ERROR,"Found unknown numeric %u on channel %s",cp->users->content[i],cp->index->name->content);
+        continue;
+      }
+
+      if (IsXOper(np) || IsService(np))
+        currentusers--;
+    }
+
     csp->todaysamples++;
   } else {
     currentusers=0;
@@ -223,19 +247,19 @@ void savechanstats() {
   chanindex *cip;
   chanstats *chp;
   
-  if ((fp=fopen("chanstats","w"))==NULL) {
+  if ((fp=fopen("data/chanstats","w"))==NULL) {
     return;
   }
   
   /* header: samples for today + last HISTORYDAYS days */
   
-  fprintf(fp,"%lu %u",lastsample,todaysamples);
+  fprintf(fp,"%lu %u",chanstats_lastsample,todaysamples);
   for(i=0;i<HISTORYDAYS;i++) {
     fprintf(fp," %u",lastdaysamples[i]);
   }  
   fprintf(fp,"\n");
   
-  /* body: channel, lastsample, samplestoday, sizetoday, <last sizes, last samples> */
+  /* body: channel, chanstats_lastsample, samplestoday, sizetoday, <last sizes, last samples> */
   for (i=0;i<CHANNELHASHSIZE;i++) {
     for (cip=chantable[i];cip;cip=cip->next) {
       if ((chp=cip->exts[csext])==NULL) { 
@@ -262,7 +286,7 @@ void loadchanstats() {
   chanstats *chp;
   chanindex *cip;
   
-  if ((fp=fopen("chanstats","r"))==NULL) {
+  if ((fp=fopen("data/chanstats","r"))==NULL) {
     Error("chanstats",ERR_ERROR,"Unable to load channel stats file");
     return;
   }
@@ -280,7 +304,7 @@ void loadchanstats() {
     return;
   }
   
-  lastsample=strtol(args[0],NULL,10);
+  chanstats_lastsample=strtol(args[0],NULL,10);
   todaysamples=strtol(args[1],NULL,10);
   for(i=0;i<HISTORYDAYS;i++) {
     lastdaysamples[i]=strtol(args[i+2],NULL,10);
@@ -690,3 +714,12 @@ void dohist_namelen(int *data, float *bounds, int cats) {
     }
   }
 }
+
+int dochanstatssave(void *source, int cargc, char **cargv) {
+  nick *sender=(nick *)source;
+
+  controlreply(sender,"Saving Chanstats..");
+  savechanstats();   
+  controlreply(sender,"Chanstats saved"); 
+  return CMD_OK;
+}