#include "chanserv.h"
#include "../lib/irc_string.h"
+#include "../lib/version.h"
#include <stdio.h>
#include <string.h>
+MODULE_VERSION(QVERSION);
+
static void cleanupdb(void *arg);
static void schedulecleanup(int hooknum, void *arg);
}
static void schedulecleanup(int hooknum, void *arg) {
- /* run at midnight but only if we're more than 1h away from it, otherwise run tomorrow */
+ /* run at 1am but only if we're more than 15m away from it, otherwise run tomorrow */
time_t t = time(NULL);
- time_t next_midnight = (t / 86400) * 86400 + 86400;
- if(next_midnight - t < 3600)
- next_midnight+=86400;
-
-// schedulerecurring(next_midnight,0,86400,cleanupdb,NULL);
-// scheduleoneshot(time(NULL)+5,cleanupdb,NULL);
+ time_t next_run = ((t / 86400) * 86400 + 86400) + 3600;
+ if(next_run - t < 900)
+ next_run+=86400;
+
+ schedulerecurring(next_run,0,86400,cleanupdb,NULL);
}
__attribute__ ((format (printf, 1, 2)))
authname *anp;
int i,j;
time_t t, to_age, unused_age, maxchan_age, authhistory_age;
- int expired = 0, unauthed = 0, chansvaped = 0;
+ int expired = 0, unauthed = 0, chansvaped = 0, chansempty = 0;
chanindex *cip, *ncip;
regchan *rcp;
DBResult *pgres;
if (anp->marker == themarker)
continue;
+ /* HACK: don't ever delete the last user -- prevents userids being reused */
+ if (vrup->ID == lastuserID)
+ continue;
+
if(!anp->nicks && !UHasStaffPriv(vrup) && !UIsCleanupExempt(vrup)) {
if(vrup->lastauth && (vrup->lastauth < to_age)) {
expired++;
if (!(rcp=cip->exts[chanservext]))
continue;
+ /* HACK: don't ever delete the last channel -- prevents channelids being reused */
+ if (rcp->ID == lastchannelID)
+ continue;
+
/* there's a bug here... if no joins or modes are done within the threshold
* and someone leaves just before the cleanup then the channel will be nuked.
*/
/* this is one possible soln but relies on cleanupdb being run more frequently than
* the threshold:
*/
+ /* slug: no longer required as we scan the entire network every 1h (cs_hourlyfunc) */
+/*
if(cip->channel && cs_ischannelactive(cip->channel, rcp)) {
rcp->lastactive = t;
if (rcp->lastcountersync < (t - COUNTERSYNCINTERVAL)) {
rcp->lastcountersync=t;
}
}
+*/
if(rcp->lastactive < maxchan_age) {
/* don't remove channels with the original founder as an oper */
cs_log(NULL, "CLEANUPDB inactive channel %s", cip->name?cip->name->content:"??");
cs_removechannel(rcp, "Channel deleted due to lack of activity.");
chansvaped++;
+ continue;
}
/* Get rid of any dead chanlev entries */
cs_log(NULL, "Removing user %s from channel %s (no flags)",rcup->user->username,rcp->index->name->content);
csdb_deletechanuser(rcup);
delreguserfromchannel(rcp, rcup->user);
+ freeregchanuser(rcup);
}
}
}
+
+ if (cs_removechannelifempty(NULL, rcp)) {
+ /* logged+parted by cs_removechannelifempty */
+ chansempty++;
+ continue;
+ }
}
}
csdb_cleanuphistories(authhistory_age);
- cleanuplog("Stats: %d accounts inactive for %d days, %d accounts weren't used within %d days, %d channels were inactive for %d days.", expired, CLEANUP_ACCOUNT_INACTIVE, unauthed, CLEANUP_ACCOUNT_UNUSED, chansvaped, CLEANUP_CHANNEL_INACTIVE);
+ cleanuplog("Stats: %d accounts inactive for %d days, %d accounts weren't used within %d days, %d channels were inactive for %d days, %d channels empty.", expired, CLEANUP_ACCOUNT_INACTIVE, unauthed, CLEANUP_ACCOUNT_UNUSED, chansvaped, CLEANUP_CHANNEL_INACTIVE, chansempty);
out:
cleanupdb_active=0;
/* This query returns a single column containing the userids of all users
* who have active sessions now, or sessions which ended in the last
* CLEANUP_ACCOUNT_INACTIVE days. */
+
+ dbquery("BEGIN TRANSACTION;");
+
+ /* increase memory for aggregate (GROUP BY) -- query can take hours if this spills to disk */
+ dbquery("SET LOCAL work_mem = '512MB';");
q9cleanup_asyncquery(cleanupdb_real, NULL,
- "SELECT userID from chanserv.authhistory WHERE disconnecttime=0 OR disconnecttime > %d GROUP BY userID", to_age);
-
+ "SELECT userID from chanserv.authhistory WHERE disconnecttime=0 OR disconnecttime > %d GROUP BY userID;", to_age);
+ dbquery("COMMIT;");
+
cleanupdb_active=1;
}