X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/b2666b7f78447ef7c24c896660e9827db27951a9..28aa186de14dc4fa7488866e70beb6ae933dde79:/chanfix/chanfix.c diff --git a/chanfix/chanfix.c b/chanfix/chanfix.c index ed293459..698511b4 100644 --- a/chanfix/chanfix.c +++ b/chanfix/chanfix.c @@ -47,7 +47,6 @@ void cfsched_dosave(void *arg); void cfhook_autofix(int hook, void *arg); void cfhook_statsreport(int hook, void *arg); void cfhook_auth(int hook, void *arg); -void cfhook_lostnick(int hook, void *arg); /* helper functions */ regop *cf_createregop(nick *np, chanindex *cip); @@ -75,7 +74,7 @@ void _init() { 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, &cfcmd_debugsample, "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"); @@ -99,7 +98,6 @@ void _init() { registerhook(HOOK_CORE_STATSREQUEST, &cfhook_statsreport); registerhook(HOOK_NICK_ACCOUNT, &cfhook_auth); - registerhook(HOOK_NICK_LOSTNICK, &cfhook_lostnick); cf_loadchanfix(); @@ -108,9 +106,6 @@ void _init() { } void _fini() { - int i; - nick *nip; - if (cffailedinit == 0) { deleteschedule(NULL, &cfsched_dosample, NULL); deleteschedule(NULL, &cfsched_doexpire, NULL); @@ -120,13 +115,6 @@ void _fini() { cf_free(); - for (i=0; inext) - free(nip->exts[cfnext]); - - releasechanext(cfext); - releasenickext(cfnext); - deregistercontrolcmd("cfdebug", &cfcmd_debug); deregistercontrolcmd("cfhistogram", &cfcmd_debughistogram); #if CFDEBUG @@ -152,7 +140,14 @@ void _fini() { deregisterhook(HOOK_CORE_STATSREQUEST, &cfhook_statsreport); deregisterhook(HOOK_NICK_ACCOUNT, &cfhook_auth); - deregisterhook(HOOK_NICK_LOSTNICK, &cfhook_lostnick); + } + + if (cfext >= 0) { + releasechanext(cfext); + } + + if (cfnext >= 0) { + releasenickext(cfnext); } } @@ -190,7 +185,7 @@ int cfcmd_debug(void *source, int cargc, char **cargv) { for (i=0;iregops.cursi;i++) { ro = ((regop**)cf->regops.content)[i]; - controlreply(np, "%d. type: %s hash: 0x%x lastopped: %d uh: %s score: %d", + controlreply(np, "%d. type: %s hash: 0x%lx lastopped: %lu uh: %s score: %d", i + 1, ro->type == CFACCOUNT ? "CFACCOUNT" : "CFHOST", ro->hash, ro->lastopped, ro->uh ? ro->uh->content : "(unknown)", ro->score); } @@ -205,7 +200,6 @@ int cfcmd_debughistogram(void *source, int cargc, char **cargv) { int i,a,score; chanindex* cip; chanfix *cf; - char buf[400]; int histogram[10001]; /* 625 (lines) * 16 (columns/line) + 1 (for histogram[0]) */ for (i = 0; i < 10001; i++) @@ -227,16 +221,11 @@ int cfcmd_debughistogram(void *source, int cargc, char **cargv) { controlreply(np, "--- Histogram of chanfix scores"); for (i = 1; i < 10001; i += 16) { - buf[0] = '\0'; - - for (a = 0; a < 16; a++) { - if (a != 0) - strcat(buf, " "); - - sprintf(buf+strlen(buf),"%d", histogram[i+a]); - } - - controlreply(np, "%6d: %s", i, buf); + controlreply(np, "%6d: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", + i, histogram[i], histogram[i+1], histogram[i+2], histogram[i+3], histogram[i+4], + histogram[i+5], histogram[i+6], histogram[i+7], histogram[i+8], histogram[i+9], + histogram[i+10], histogram[i+11], histogram[i+12], histogram[i+13], histogram[i+14], + histogram[i+15]); } controlreply(np, "--- End of histogram"); @@ -310,7 +299,6 @@ int cfcmd_chanopstat(void *source, int cargc, char **cargv) { regop *rolist[10]; int i, a, count; int *scores; - char buf[400]; if (cargc < 1) { controlreply(np, "Syntax: chanopstat <#channel>"); @@ -336,18 +324,12 @@ int cfcmd_chanopstat(void *source, int cargc, char **cargv) { /* known ops */ count = cf_getsortedregops(cf, 10, rolist); - - buf[0] = '\0'; + controlreply(np, "Scores of \"best ops\" on %s are:", cargv[0]); for (i=0;iscore); + controlreply(np, " %d", rolist[i]->score); } - controlreply(np, "Scores of \"best ops\" on %s are: %s", cargv[0], buf); - /* current ops */ scores = (int*)malloc(sizeof(int) * cp->users->hashsize); @@ -365,23 +347,16 @@ int cfcmd_chanopstat(void *source, int cargc, char **cargv) { } qsort(scores, i, sizeof(int), &cmpint); - - buf[0] = '\0'; + controlreply(np, "Scores of current ops on %s are:", cargv[0]); for (a=0;ahost->name->content, np2->realname->name->content); } else { ct = rolist[i]->lastopped; - - cdate = ctime(&ct); - - date = (char*)malloc(strlen(cdate) + 1); - strcpy(date, cdate); - - for (a=0;ascore, - (rolist[i]->type == CFACCOUNT) ? "account" : "host", - "", "!NONE!", + (rolist[i]->type == CFACCOUNT) ? "account" : "host", "", "!NONE!", rolist[i]->uh ? rolist[i]->uh->content : "!UNKNOWN!", date); - - free(date); } } @@ -485,7 +446,7 @@ int cfcmd_chanfix(void *source, int cargc, char **cargv) { 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; @@ -516,7 +477,7 @@ int cfcmd_showregs(void *source, int cargc, char **cargv) { nick *np2; chanfix *cf; channel *cp; - int a, i, count, ops; + int i, count, ops; regop *rolist[50]; if (cargc < 1) { @@ -543,9 +504,9 @@ int cfcmd_showregs(void *source, int cargc, char **cargv) { count = 0; - for(a=0;ausers->hashsize;a++) { - if(cp->users->content[a] != nouser) { - np2 = getnickbynumeric(cp->users->content[a]); + for(i=0;iusers->hashsize;i++) { + if(cp->users->content[i] != nouser) { + np2 = getnickbynumeric(cp->users->content[i]); if (IsService(np2)) { controlreply(np, "%s (service)", np2->nick); @@ -625,7 +586,7 @@ int cfcmd_requestop(void *source, int cargc, char **cargv) { } } - 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."); @@ -718,7 +679,6 @@ void cfsched_dosample(void *arg) { channel *cp; chanindex *cip; nick *np; - chanfix *cf; regop *ro, *roh; struct timeval start; struct timeval end; @@ -728,14 +688,13 @@ void cfsched_dosample(void *arg) { cfuhost = cfscore = cfnewro = 0; - if (sp_countsplitservers() > CFMAXSPLITSERVERS) + if (sp_countsplitservers(SERVERTYPEFLAG_USER_STATE) > CFMAXSPLITSERVERS) return; gettimeofday(&start, NULL); for (i=0; inext) { - cf = (chanfix*)cip->exts[cfext]; cp = cip->channel; if (!cp || cp->users->totalusers < CFMINUSERS) @@ -745,6 +704,9 @@ void cfsched_dosample(void *arg) { 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; @@ -779,10 +741,7 @@ void cfsched_dosample(void *arg) { if (ro->type == CFACCOUNT) ro->uh = getsstring(np->authname, ACCOUNTLEN); else { - strcpy(buf, np->ident); - strcat(buf, "@"); - strcat(buf, np->host->name->content); - + snprintf(buf, sizeof(buf), "%s@%s", np->ident, np->host->name->content); roh->uh = getsstring(buf, USERLEN+1+HOSTLEN); } @@ -837,19 +796,19 @@ void cfsched_doexpire(void *arg) { for (a=0;aregops.cursi;a++) { ro = rolist[a]; - if ((currenttime - ro->lastopped > 2 * CFSAMPLEINTERVAL) && ro->score) { + if (((currenttime - ro->lastopped) > (2 * CFSAMPLEINTERVAL)) && ro->score) { ro->score--; cfscore++; } - if (ro->score < CFMINSCOREUH && ro->uh) { + if ((ro->score < CFMINSCOREUH) && ro->uh) { freesstring(ro->uh); ro->uh = NULL; cffreeuh++; } - if (ro->score == 0 || ro->lastopped < currenttime - CFREMEMBEROPS) { + if (ro->score == 0 || ro->lastopped < (currenttime - CFREMEMBEROPS)) { cf_deleteregop(cip, ro); cfregop++; } @@ -899,7 +858,7 @@ void cfhook_autofix(int hook, void *arg) { 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;ausers->hashsize;a++) { @@ -925,7 +884,6 @@ void cfhook_statsreport(int hook, void *arg) { char buf[300]; int i,a,rc,mc,memory; chanindex *cip; - nick *nip; chanfix *cf; if ((long)arg > 2) { @@ -950,15 +908,8 @@ void cfhook_statsreport(int hook, void *arg) { } } - for (i=0; inext) { - if (nip->exts[cfnext]) - memory += sizeof(int); - } - } - - sprintf(buf, "Chanfix : %6d registered ops, %9d monitored channels. %9d" - " kbytes of memory used", rc, mc, memory / 1024); + snprintf(buf, sizeof(buf), "Chanfix : %6d registered ops, %9d monitored channels. %9d" + " kbytes of memory used", rc, mc, (memory / 1024)); triggerhook(HOOK_CORE_STATSREPLY, buf); } } @@ -967,20 +918,12 @@ void cfhook_auth(int hook, void *arg) { nick *np = (nick*)arg; /* Invalidate the user's hash */ - free(np->exts[cfnext]); - np->exts[cfnext] = NULL; /* Calculate the new hash */ cf_gethash(np, CFACCOUNT); } -void cfhook_lostnick(int hook, void *arg) { - nick *np = (nick*)arg; - - free(np->exts[cfnext]); -} - /* Returns the hash of a specific user (np), type can be either CFACCOUNT, CFHOST or both (binary or'd values). cf_gethash will also cache the user's hash in a nick extension */ @@ -988,30 +931,25 @@ unsigned long cf_gethash(nick *np, int type) { char buf[USERLEN+1+HOSTLEN+1]; unsigned long hash; - if (IsAccount(np) && type & CFACCOUNT) { + if (IsAccount(np) && (type & CFACCOUNT)) { if (np->exts[cfnext] == NULL) { - np->exts[cfnext] = (int*)malloc(sizeof(int)); - *(int*)np->exts[cfnext] = crc32(np->authname); + np->exts[cfnext] = (void *)crc32(np->authname); } - return *(int*)np->exts[cfnext]; + return (unsigned long)np->exts[cfnext]; } else if (type == CFACCOUNT) return 0; /* this should not happen */ if (type & CFHOST) { if (!IsAccount(np) && np->exts[cfnext]) - return *(int*)np->exts[cfnext]; + return (unsigned long)np->exts[cfnext]; else { - strcpy(buf, np->ident); - strcat(buf, "@"); - strcat(buf, np->host->name->content); + snprintf(buf, sizeof(buf), "%s@%s", np->ident, np->host->name->content); hash = crc32(buf); /* if the user is not authed, update the hash */ if (!IsAccount(np)) { - np->exts[cfnext] = (int*)malloc(sizeof(int)); - - *(int*)np->exts[cfnext] = hash; + np->exts[cfnext] = (void *)hash; } return hash; @@ -1102,7 +1040,7 @@ regop *cf_findregop(nick *np, chanindex *cip, int type) { if (cf == NULL) return NULL; - if (IsAccount(np) && type & CFACCOUNT) + if (IsAccount(np) && (type & CFACCOUNT)) ty = CFACCOUNT; else ty = CFHOST; @@ -1115,7 +1053,7 @@ regop *cf_findregop(nick *np, chanindex *cip, int type) { } /* try using the uhost if we didn't find a user with the right account */ - if (ty == CFACCOUNT && type & CFHOST) + if (ty == CFACCOUNT && (type & CFHOST)) return cf_findregop(np, cip, CFHOST); else return NULL; @@ -1225,7 +1163,7 @@ int cf_fixchannel(channel *cp) { /* and op some of them */ for (i=0;i= CFMAXOPS || rolist[i]->score < rolist[0]->score / 2) + if (count >= CFMAXOPS || rolist[i]->score < (rolist[0]->score / 2)) break; if (rolist[i]->score < CFMINSCORE && i != 0 ) @@ -1260,16 +1198,16 @@ int cf_storechanfix(void) { char dstfile[300]; int a, i, count = 0; - snprintf(dstfile, 300, "%s.%d", CFSTORAGE, CFSAVEFILES); + snprintf(dstfile, sizeof(dstfile), "%s.%d", CFSTORAGE, CFSAVEFILES); unlink(dstfile); for (i = CFSAVEFILES; i > 0; i--) { - snprintf(srcfile, 300, "%s.%i", CFSTORAGE, i - 1); - snprintf(dstfile, 300, "%s.%i", CFSTORAGE, i); + snprintf(srcfile, sizeof(srcfile), "%s.%i", CFSTORAGE, i - 1); + snprintf(dstfile, sizeof(dstfile), "%s.%i", CFSTORAGE, i); rename(srcfile, dstfile); } - snprintf(srcfile, 300, "%s.0", CFSTORAGE); + snprintf(srcfile, sizeof(srcfile), "%s.0", CFSTORAGE); cfdata = fopen(srcfile, "w"); if (cfdata == NULL) @@ -1282,14 +1220,11 @@ int cf_storechanfix(void) { ro = ((regop**)cf->regops.content)[a]; if (ro->uh) - fprintf(cfdata, "%s %lu %lu %lu %lu %s\n", cip->name->content, - (unsigned long)ro->type, (unsigned long)ro->hash, - (unsigned long)ro->lastopped, (unsigned long)ro->score, - ro->uh->content); + fprintf(cfdata, "%s %d %lu %lu %d %s\n", cip->name->content, + ro->type, ro->hash, ro->lastopped, ro->score, ro->uh->content); else - fprintf(cfdata, "%s %lu %lu %lu %lu\n", cip->name->content, - (unsigned long)ro->type, (unsigned long)ro->hash, - (unsigned long)ro->lastopped, (unsigned long)ro->score); + fprintf(cfdata, "%s %d %lu %lu %d\n", cip->name->content, + ro->type, ro->hash, ro->lastopped, ro->score); count++; } } @@ -1308,11 +1243,13 @@ int cf_parseline(char *line) { int count; int slot; char chan[CHANNELLEN+1]; + int type, score; + unsigned long hash; + time_t lastopped; char host[USERLEN+1+HOSTLEN+1]; - unsigned long type,hash,lastopped,score; regop **rolist; - count = sscanf(line, "%s %lu %lu %lu %lu %s", chan, &type, &hash, &lastopped, &score, host); + count = sscanf(line, "%s %d %lu %lu %d %s", chan, &type, &hash, &lastopped, &score, host); if (count < 5) return 0; /* invalid chanfix record */ @@ -1341,7 +1278,7 @@ int cf_parseline(char *line) { rolist[slot]->lastopped = lastopped; rolist[slot]->score = score; - if (count >= 6 && strchr(host, '@') != NULL) + if (count >= 6) rolist[slot]->uh = getsstring(host, USERLEN+1+HOSTLEN); else rolist[slot]->uh = NULL; @@ -1357,7 +1294,7 @@ int cf_loadchanfix(void) { cf_free(); - snprintf(srcfile, 300, "%s.0", CFSTORAGE); + snprintf(srcfile, sizeof(srcfile), "%s.0", CFSTORAGE); cfdata = fopen(srcfile, "r"); if (cfdata == NULL)