#include "../nick/nick.h"
#include "../lib/irc_string.h"
#include "../control/control.h"
+#include "../lib/version.h"
+
+MODULE_VERSION("")
/* control's nick */
extern nick *mynick;
int cfext;
int cfnext;
-int cffailedinit;
+
+static int cffailedinit;
/* user accessible commands */
int cfcmd_debug(void *source, int cargc, char **cargv);
if (cfext < 0 || cfnext < 0) {
Error("chanfix", ERR_ERROR, "Couldn't register channel and/or nick extension");
cffailedinit = 1;
- } else {
- schedulerecurring(time(NULL), 0, CFSAMPLEINTERVAL, &cfsched_dosample, NULL);
- schedulerecurring(time(NULL), 0, CFEXPIREINTERVAL, &cfsched_doexpire, NULL);
- schedulerecurring(time(NULL), 0, CFAUTOSAVEINTERVAL, &cfsched_dosave, NULL);
+ return;
+ }
- registercontrolhelpcmd("cfdebug", NO_DEVELOPER, 1, &cfcmd_debug, "Display Debug Information on chanfix data for channel");
- registercontrolhelpcmd("cfhistogram", NO_DEVELOPER, 1, &cfcmd_debughistogram, "Display Debug Histogram of chanfix data for channel");
+ schedulerecurring(time(NULL), 0, CFSAMPLEINTERVAL, &cfsched_dosample, NULL);
+ schedulerecurring(time(NULL), 0, CFEXPIREINTERVAL, &cfsched_doexpire, NULL);
+ schedulerecurring(time(NULL), 0, CFAUTOSAVEINTERVAL, &cfsched_dosave, NULL);
+
+ registercontrolhelpcmd("cfdebug", NO_DEVELOPER, 1, &cfcmd_debug, "Display Debug Information on chanfix data for channel");
+ registercontrolhelpcmd("cfhistogram", NO_DEVELOPER, 1, &cfcmd_debughistogram, "Display Debug Histogram of chanfix data for channel");
#if CFDEBUG
- registercontrolhelpcmd("cfsample", NO_DEVELOPER, 1, &cfcmd_debugsample, "DEBUG Command - must not be loaded on live instances");
- registercontrolhelpcmd("cfexpire", NO_DEVELOPER, 1, &cfcmd_debugexpire, "DEBUG Command - must not be loaded on live instances");
+ registercontrolhelpcmd("cfsample", NO_DEVELOPER, 1, &cfcmd_debugsample, "DEBUG Command - must not be loaded on live instances");
+ registercontrolhelpcmd("cfexpire", NO_DEVELOPER, 1, &cfcmd_debugexpire, "DEBUG Command - must not be loaded on live instances");
#endif
- registercontrolhelpcmd("chanopstat", NO_OPER, 1, &cfcmd_chanopstat, "Shows chanop statistics for a given channel");
- registercontrolhelpcmd("chanoplist", NO_OPER, 1, &cfcmd_chanoplist, "Shows lists of known chanops, including scores");
+ registercontrolhelpcmd("chanopstat", NO_OPER, 1, &cfcmd_chanopstat, "Shows chanop statistics for a given channel");
+ registercontrolhelpcmd("chanoplist", NO_OPER, 1, &cfcmd_chanoplist, "Shows lists of known chanops, including scores");
- registercontrolhelpcmd("chanfix", NO_OPER, 1, &cfcmd_chanfix, "Perform a chanfix on a channel to op known users only");
- registercontrolhelpcmd("showregs", NO_OPER, 1, &cfcmd_showregs, "Show regular ops known on a channel (including services)");
+ registercontrolhelpcmd("chanfix", NO_OPER, 1, &cfcmd_chanfix, "Perform a chanfix on a channel to op known users only");
+ registercontrolhelpcmd("showregs", NO_OPER, 1, &cfcmd_showregs, "Show regular ops known on a channel (including services)");
#if CFDEBUG
- /* should we disable this in the 'final' build? */
- /* registercontrolcmd("requestop", 0, 2, &cfcmd_requestop); */
+ /* should we disable this in the 'final' build? */
+ /* registercontrolcmd("requestop", 0, 2, &cfcmd_requestop); */
#endif
- registercontrolhelpcmd("cfsave", NO_DEVELOPER, 0, &cfcmd_save, "Force save of chanfix data");
- registercontrolhelpcmd("cfload", NO_DEVELOPER, 0, &cfcmd_load, "Force load of chanfix data");
+ registercontrolhelpcmd("cfsave", NO_DEVELOPER, 0, &cfcmd_save, "Force save of chanfix data");
+ registercontrolhelpcmd("cfload", NO_DEVELOPER, 0, &cfcmd_load, "Force load of chanfix data");
#if CFAUTOFIX
- registerhook(HOOK_CHANNEL_DEOPPED, &cfhook_autofix);
- registerhook(HOOK_CHANNEL_PART, &cfhook_autofix);
- registerhook(HOOK_CHANNEL_KICK, &cfhook_autofix);
- registerhook(HOOK_CHANNEL_JOIN, &cfhook_autofix);
+ registerhook(HOOK_CHANNEL_DEOPPED, &cfhook_autofix);
+ registerhook(HOOK_CHANNEL_PART, &cfhook_autofix);
+ registerhook(HOOK_CHANNEL_KICK, &cfhook_autofix);
+ registerhook(HOOK_CHANNEL_JOIN, &cfhook_autofix);
#endif
- registerhook(HOOK_CORE_STATSREQUEST, &cfhook_statsreport);
- registerhook(HOOK_NICK_ACCOUNT, &cfhook_auth);
+ registerhook(HOOK_CORE_STATSREQUEST, &cfhook_statsreport);
+ registerhook(HOOK_NICK_ACCOUNT, &cfhook_auth);
- cf_loadchanfix();
+ cf_loadchanfix();
- cffailedinit = 0;
- }
+ cffailedinit = 0;
}
void _fini() {
- if (cfext >= 0) {
- releasechanext(cfext);
- }
-
- if (cfnext >= 0) {
- releasenickext(cfnext);
- }
+ if (cffailedinit == 0)
+ return;
- if (cffailedinit == 0) {
- deleteschedule(NULL, &cfsched_dosample, NULL);
- deleteschedule(NULL, &cfsched_doexpire, NULL);
- deleteschedule(NULL, &cfsched_dosave, NULL);
+ deleteschedule(NULL, &cfsched_dosample, NULL);
+ deleteschedule(NULL, &cfsched_doexpire, NULL);
+ deleteschedule(NULL, &cfsched_dosave, NULL);
- cf_storechanfix();
+ cf_storechanfix();
- cf_free();
+ cf_free();
- deregistercontrolcmd("cfdebug", &cfcmd_debug);
- deregistercontrolcmd("cfhistogram", &cfcmd_debughistogram);
+ deregistercontrolcmd("cfdebug", &cfcmd_debug);
+ deregistercontrolcmd("cfhistogram", &cfcmd_debughistogram);
#if CFDEBUG
- deregistercontrolcmd("cfsample", &cfcmd_debugsample);
- deregistercontrolcmd("cfexpire", &cfcmd_debugexpire);
+ deregistercontrolcmd("cfsample", &cfcmd_debugsample);
+ deregistercontrolcmd("cfexpire", &cfcmd_debugexpire);
#endif
- deregistercontrolcmd("chanopstat", &cfcmd_chanopstat);
- deregistercontrolcmd("chanoplist", &cfcmd_chanoplist);
- deregistercontrolcmd("chanfix", &cfcmd_chanfix);
- deregistercontrolcmd("showregs", &cfcmd_showregs);
+ deregistercontrolcmd("chanopstat", &cfcmd_chanopstat);
+ deregistercontrolcmd("chanoplist", &cfcmd_chanoplist);
+ deregistercontrolcmd("chanfix", &cfcmd_chanfix);
+ deregistercontrolcmd("showregs", &cfcmd_showregs);
#if CFDEBUG
-// deregistercontrolcmd("requestop", &cfcmd_requestop);
+// deregistercontrolcmd("requestop", &cfcmd_requestop);
#endif
- deregistercontrolcmd("cfsave", &cfcmd_save);
- deregistercontrolcmd("cfload", &cfcmd_load);
+ deregistercontrolcmd("cfsave", &cfcmd_save);
+ deregistercontrolcmd("cfload", &cfcmd_load);
#if CFAUTOFIX
- deregisterhook(HOOK_CHANNEL_DEOPPED, &cfhook_autofix);
- deregisterhook(HOOK_CHANNEL_PART, &cfhook_autofix);
- deregisterhook(HOOK_CHANNEL_KICK, &cfhook_autofix);
- deregisterhook(HOOK_CHANNEL_JOIN, &cfhook_autofix);
+ deregisterhook(HOOK_CHANNEL_DEOPPED, &cfhook_autofix);
+ deregisterhook(HOOK_CHANNEL_PART, &cfhook_autofix);
+ deregisterhook(HOOK_CHANNEL_KICK, &cfhook_autofix);
+ deregisterhook(HOOK_CHANNEL_JOIN, &cfhook_autofix);
#endif
- deregisterhook(HOOK_CORE_STATSREQUEST, &cfhook_statsreport);
- deregisterhook(HOOK_NICK_ACCOUNT, &cfhook_auth);
- }
+ deregisterhook(HOOK_CORE_STATSREQUEST, &cfhook_statsreport);
+ deregisterhook(HOOK_NICK_ACCOUNT, &cfhook_auth);
+
+ if (cfext >= 0)
+ releasechanext(cfext);
+
+ if (cfnext >= 0)
+ releasenickext(cfnext);
}
int cfcmd_debug(void *source, int cargc, char **cargv) {
regop *ro;
int i;
- if (cargc < 1) {
- controlreply(np, "Syntax: cfdebug <#channel>");
-
- return CMD_ERROR;
- }
+ if (cargc < 1)
+ return CMD_USAGE;
cip = findchanindex(cargv[0]);
controlreply(np, "No such channel.");
return CMD_ERROR;
- } else
- controlreply(np, "Found channel %s. Retrieving chanfix information...", cargv[0]);
+ }
+
+ controlreply(np, "Found channel %s. Retrieving chanfix information...", cargv[0]);
cf = cip->exts[cfext];
controlreply(np, "No chanfix information for %s", cargv[0]);
return CMD_ERROR;
- } else
- controlreply(np, "Found chanfix information. Dumping...");
+ }
+
+ controlreply(np, "Found chanfix information. Dumping...");
for (i=0;i<cf->regops.cursi;i++) {
ro = ((regop**)cf->regops.content)[i];
qsort(cf->regops.content, cf->regops.cursi, sizeof(regop*), cmpregop);
- for (i = 0; i < min(max, cf->regops.cursi); i++) {
+ for (i = 0; i < min(max, cf->regops.cursi); i++)
list[i] = ((regop**)cf->regops.content)[i];
- }
return i;
}
int i, a, count;
int *scores;
- if (cargc < 1) {
- controlreply(np, "Syntax: chanopstat <#channel>");
-
- return CMD_ERROR;
- }
+ if (cargc < 1)
+ return CMD_USAGE;
cp = findchannel(cargv[0]);
count = cf_getsortedregops(cf, 10, rolist);
controlreply(np, "Scores of \"best ops\" on %s are:", cargv[0]);
- for (i=0;i<count;i++) {
+ for (i=0;i<count;i++)
controlreply(np, " %d", rolist[i]->score);
- }
/* current ops */
scores = (int*)malloc(sizeof(int) * cp->users->hashsize);
char date[50];
unsigned long *hand;
- if (cargc < 1) {
- controlreply(np, "Syntax: chanoplist <#channel>");
-
- return CMD_ERROR;
- }
+ if (cargc < 1)
+ return CMD_USAGE;
cip = findchanindex(cargv[0]);
channel *cp;
int ret;
- if (cargc < 1) {
- controlreply(np, "Syntax: chanfix <#channel>");
-
- return CMD_ERROR;
- }
+ if (cargc < 1)
+ return CMD_USAGE;
cp = findchannel(cargv[0]);
return CMD_ERROR;
}
- if (sp_countsplitservers() > 0) {
+ if (sp_countsplitservers(SERVERTYPEFLAG_USER_STATE) > 0) {
controlreply(np, "Chanfix cannot be used during a netsplit.");
return CMD_ERROR;
int i, count, ops;
regop *rolist[50];
- if (cargc < 1) {
- controlreply(np, "Syntax: showregs <#channel>");
-
- return CMD_ERROR;
- }
+ if (cargc < 1)
+ return CMD_USAGE;
cp = findchannel(cargv[0]);
unsigned long *hand;
modechanges changes;
- if (cargc < 1) {
- controlreply(np, "Syntax: requestop <#channel> [nick]");
-
- return CMD_ERROR;
- }
+ if (cargc < 1)
+ return CMD_USAGE;
cp = findchannel(cargv[0]);
}
}
- if (sp_countsplitservers() > 0) {
+ if (sp_countsplitservers(SERVERTYPEFLAG_USER_STATE) > 0) {
controlreply(np, "One or more servers are currently split. Wait until the"
" netsplit is over and try again.");
}
void cfsched_dosample(void *arg) {
- int i,a,now,cfscore,cfnewro,cfuhost,diff;
+ int i,a,now,cfscore,cfnewro,diff;
channel *cp;
chanindex *cip;
nick *np;
- chanfix *cf;
regop *ro, *roh;
struct timeval start;
struct timeval end;
- char buf[USERLEN+1+HOSTLEN+1];
now = getnettime();
- cfuhost = cfscore = cfnewro = 0;
+ cfscore = cfnewro = 0;
- if (sp_countsplitservers() > CFMAXSPLITSERVERS)
+ if (sp_countsplitservers(SERVERTYPEFLAG_USER_STATE) > CFMAXSPLITSERVERS)
return;
gettimeofday(&start, NULL);
for (i=0; i<CHANNELHASHSIZE; i++) {
for (cip=chantable[i]; cip; cip=cip->next) {
- cf = (chanfix*)cip->exts[cfext];
cp = cip->channel;
if (!cp || cp->users->totalusers < CFMINUSERS)
if ((cp->users->content[a] != nouser) && (cp->users->content[a] & CUMODE_OP)) {
np = getnickbynumeric(cp->users->content[a]);
+ if (!np)
+ continue;
+
#if !CFDEBUG
if (IsService(np))
continue;
/* lastopped == now if the user has clones, we obviously
* don't want to give them points in this case */
- if (ro && ro->lastopped != now) {
- if (ro->type != CFHOST || !cf_hasauthedcloneonchan(np, cp)) {
- ro->score++;
- cfscore++;
- }
-
- /* merge any matching CFHOST records */
- if (roh && roh->type == CFHOST && ro->type == CFACCOUNT) {
- /* hmm */
- ro->score += roh->score;
-
- cf_deleteregop(cip, roh);
- }
-
- /* store the user's account/host if we have to */
- if (ro->uh == NULL && ro->score >= CFMINSCOREUH) {
- if (ro->type == CFACCOUNT)
- ro->uh = getsstring(np->authname, ACCOUNTLEN);
- else {
- snprintf(buf, sizeof(buf), "%s@%s", np->ident, np->host->name->content);
- roh->uh = getsstring(buf, USERLEN+1+HOSTLEN);
- }
-
- cfuhost++;
- }
-
- ro->lastopped = now;
+ if (!ro || ro->lastopped == now)
+ continue;
+
+ if (ro->type != CFHOST || !cf_hasauthedcloneonchan(np, cp)) {
+ ro->score++;
+ cfscore++;
+ }
+
+ /* merge any matching CFHOST records */
+ if (roh && roh->type == CFHOST && ro->type == CFACCOUNT) {
+ /* hmm */
+ ro->score += roh->score;
+
+ cf_deleteregop(cip, roh);
}
+
+ ro->lastopped = now;
}
}
}
(start.tv_sec * 1000 + start.tv_usec / 1000);
sendmessagetochannel(mynick, cp, "sampled chanfix scores, assigned %d new"
- " points, %d new regops, %d user@hosts added, deltaT: %dms", cfscore,
- cfnewro, cfuhost, diff);
+ " points, %d new regops, deltaT: %dms", cfscore,
+ cfnewro, diff);
}
}
chanindex *cip;
chanindex *ncip;
chanfix *cf;
- int i,a,cfscore,cfregop,cffreeuh,diff;
+ int i,a,cfscore,cfregop,diff;
regop **rolist;
regop *ro;
struct timeval start;
struct timeval end;
time_t currenttime;
- cffreeuh = cfscore = cfregop = 0;
+ cfscore = cfregop = 0;
gettimeofday(&start, NULL);
currenttime=getnettime();
cfscore++;
}
- if ((ro->score < CFMINSCOREUH) && ro->uh) {
- freesstring(ro->uh);
- ro->uh = NULL;
-
- cffreeuh++;
- }
-
if (ro->score == 0 || ro->lastopped < (currenttime - CFREMEMBEROPS)) {
cf_deleteregop(cip, ro);
cfregop++;
(start.tv_sec * 1000 + start.tv_usec / 1000);
sendmessagetochannel(mynick, cp, "expired chanfix scores, purged %d points,"
- " scrapped %6d regops, %d user@hosts freed, deltaT: %dms", cfscore,
- cfregop, cffreeuh, diff);
+ " scrapped %6d regops, deltaT: %dms", cfscore,
+ cfregop, diff);
}
}
hook == HOOK_CHANNEL_KICK || hook == HOOK_CHANNEL_JOIN) {
cp = args[0];
- if (sp_countsplitservers() > 0)
+ if (sp_countsplitservers(SERVERTYPEFLAG_USER_STATE) > 0)
return;
for(a=0;a<cp->users->hashsize;a++) {
chanfix *cf = cip->exts[cfext];
int slot, type;
regop **rolist;
+ char buf[USERLEN+1+HOSTLEN+1];
if (cf == NULL) {
cf = (chanfix*)malloc(sizeof(chanfix));
rolist[slot] = (regop*)malloc(sizeof(regop));
- if (IsAccount(np))
+ if (IsAccount(np)) {
type = CFACCOUNT;
- else
+ rolist[slot]->uh = getsstring(np->authname, ACCOUNTLEN);
+ } else {
type = CFHOST;
+ snprintf(buf, sizeof(buf), "%s@%s", np->ident, np->host->name->content);
+ rolist[slot]->uh = getsstring(buf, USERLEN+1+HOSTLEN);
+ }
+
rolist[slot]->type = type;
rolist[slot]->hash = cf_gethash(np, type);
- rolist[slot]->uh = NULL;
rolist[slot]->lastopped = 0;
rolist[slot]->score = 0;
rolist[slot]->hash = hash;
rolist[slot]->lastopped = lastopped;
rolist[slot]->score = score;
-
- if (count >= 6)
- rolist[slot]->uh = getsstring(host, USERLEN+1+HOSTLEN);
- else
- rolist[slot]->uh = NULL;
+ rolist[slot]->uh = getsstring(host, USERLEN+1+HOSTLEN);
return 1;
}