#include <stdio.h>
#include <string.h>
+#include <stdint.h>
-MODULE_VERSION("$Id: chanstats.c 663 2006-05-16 17:27:36Z newserv $")
+MODULE_VERSION("");
int csext;
int sampleindex;
-time_t lastsample;
+time_t chanstats_lastsample;
time_t lastday;
int uponehour;
int failedinit;
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);
void dohist_days(int *data, float *bounds, int cats, int days);
void dohist_namelen(int *data, float *bounds, int cats);
+#define EXPIREMIN 4
+
void _init() {
time_t now,when;
/* 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 (%jd > %jd)",(intmax_t)chanstats_lastsample,(intmax_t)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;
}
lastsave=now;
- registercontrolcmd("chanstats",10,1,&dochanstats);
- registercontrolcmd("channelhistogram",10,13,&dochanhistogram);
- registercontrolcmd("userhistogram",10,1,&douserhistogram);
- registercontrolcmd("expirecheck",10,1,&doexpirecheck);
+ registercontrolhelpcmd("chanstats",NO_OPER,1,&dochanstats, "Show usage statistics for a channel");
+ registercontrolhelpcmd("channelhistogram",NO_OPER,13,&dochanhistogram, "Display a histogram of network channel sizes");
+ registercontrolhelpcmd("userhistogram",NO_OPER,1,&douserhistogram, "Display a user histogram of channel size");
+ registercontrolhelpcmd("expirecheck",NO_DEVELOPER,1,&doexpirecheck, "Check if channel has too few users for services");
+ registercontrolhelpcmd("chanstatssave",NO_DEVELOPER,1, &dochanstatssave, "Usage: chanstatssave\nForce a save of chanstats data");
schedulerecurring(when,0,SAMPLEINTERVAL,&doupdate,NULL);
}
}
deregistercontrolcmd("channelhistogram",&dochanhistogram);
deregistercontrolcmd("userhistogram",&douserhistogram);
deregistercontrolcmd("expirecheck",&doexpirecheck);
+ deregistercontrolcmd("chanstatssave",&dochanstatssave);
releasechanext(csext);
cstsfreeall();
}
}
}
- lastsample=now;
+ chanstats_lastsample=now;
if (now-lastsave > SAVEINTERVAL) {
savechanstats();
lastsave=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 %lu on channel %s",cp->users->content[i],cp->index->name->content);
+ continue;
+ }
+
+ if (IsXOper(np) || IsService(np))
+ currentusers--;
+ }
+
csp->todaysamples++;
} else {
currentusers=0;
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) {
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;
}
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);
return CMD_OK;
}
-#define EXPIREMIN 4
-
int doexpirecheck(void *source, int cargc, char **cargv) {
nick *sender=(nick *)source;
chanindex *cip;
/* Did they hit the minimum today? */
if (csp->todaymax >= EXPIREMIN) {
+ controlreply(sender,"OK %s",cargv[0]);
return CMD_OK;
}
/* Or recently? */
for (i=0;i<HISTORYDAYS;i++) {
if (csp->lastmax[i] >= EXPIREMIN) {
+ controlreply(sender,"OK %s",cargv[0]);
return CMD_OK;
}
}
}
}
}
+
+int dochanstatssave(void *source, int cargc, char **cargv) {
+ nick *sender=(nick *)source;
+
+ controlreply(sender,"Saving Chanstats..");
+ savechanstats();
+ controlreply(sender,"Chanstats saved");
+ return CMD_OK;
+}