X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fexpire%2Fserv_expire.c;h=00466cf77c0274eccbbaa35f71e27c0585ec04fe;hb=8c47559cb5ae97ec0fa35660ee16fd61a9451c72;hp=6bdbbb3a48eb4b1ccd979289c3f6c5026b984817;hpb=cbc2a603ed4c3995836e45fd400e44e12868f5f8;p=citadel.git diff --git a/citadel/modules/expire/serv_expire.c b/citadel/modules/expire/serv_expire.c index 6bdbbb3a4..00466cf77 100644 --- a/citadel/modules/expire/serv_expire.c +++ b/citadel/modules/expire/serv_expire.c @@ -3,10 +3,25 @@ * * This module handles the expiry of old messages and the purging of old users. * - */ - - -/* + * You might also see this module affectionately referred to as the DAP (the Dreaded Auto-Purger). + * + * Copyright (c) 1988-2009 by citadel.org (Art Cancro, Wilifried Goesgens, and others) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * * A brief technical discussion: * * Several of the purge operations found in this module operate in two @@ -66,7 +81,7 @@ #include "msgbase.h" #include "user_ops.h" #include "control.h" -#include "serv_network.h" /* Needed for defenition of UseTable */ +#include "serv_network.h" /* Needed for definition of UseTable */ #include "threads.h" #include "ctdl_module.h" @@ -121,10 +136,9 @@ int messages_purged; int users_not_purged; char *users_corrupt_msg = NULL; char *users_zero_msg = NULL; - struct ctdlroomref *rr = NULL; - extern struct CitContext *ContextList; +int force_purge_now = 0; /* set to nonzero to force a run right now */ /* @@ -152,6 +166,10 @@ void GatherPurgeMessages(struct ctdlroom *qrbuf, void *data) { if (epbuf.expire_mode == EXPIRE_NEXTLEVEL) return; if (epbuf.expire_mode == EXPIRE_MANUAL) return; + /* Don't purge messages containing system configuration, dumbass. */ + if (!strcasecmp(qrbuf->QRname, SYSCONFIGROOM)) return; + + /* Ok, we got this far ... now let's see what's in the room */ cdbfr = cdb_fetch(CDB_MSGLISTS, &qrbuf->QRnumber, sizeof(long)); if (cdbfr != NULL) { @@ -167,6 +185,7 @@ void GatherPurgeMessages(struct ctdlroom *qrbuf, void *data) { return; } + /* If the room is set to expire by count, do that */ if (epbuf.expire_mode == EXPIRE_NUMMSGS) { if (num_msgs > epbuf.expire_value) { @@ -290,6 +309,7 @@ void DoPurgeRooms(struct ctdlroom *qrbuf, void *data) { if (qrbuf->QRflags & QR_PERMANENT) return; if (qrbuf->QRflags & QR_DIRECTORY) return; if (qrbuf->QRflags & QR_NETWORK) return; + if (qrbuf->QRflags2 & QR2_SYSTEM) return; if (!strcasecmp(qrbuf->QRname, SYSCONFIGROOM)) return; if (is_noneditable(qrbuf)) return; @@ -410,6 +430,10 @@ void do_user_purge(struct ctdluser *us, void *data) { /* The default rule is to not purge. */ purge = 0; + + /* don't attempt to purge system users. */ + if (!strncmp(us->fullname, "SYS_", 4)) + goto skip_all_this; /* If the user hasn't called in two months and expiring of accounts is turned on, his/her account * has expired, so purge the record. @@ -489,7 +513,8 @@ void do_user_purge(struct ctdluser *us, void *data) { } } - +skip_all_this: + if (purge == 1) { pptr = (struct PurgeList *) malloc(sizeof(struct PurgeList)); pptr->next = UserPurgeList; @@ -520,7 +545,8 @@ int PurgeUsers(void) { ForEachUser(do_uid_user_purge, NULL); break; default: - CtdlLogPrintf(CTDL_DEBUG, "Unknown authentication mode!\n"); + CtdlLogPrintf(CTDL_DEBUG, "User purge for auth mode %d is not implemented.\n", + config.c_auth_mode); break; } @@ -792,8 +818,9 @@ int PurgeStaleOpenIDassociations(void) { char *deleteme = NULL; long len; void *Value; - char *Key; + const char *Key; int num_deleted = 0; + long usernum = 0L; keys = NewHash(1, NULL); if (!keys) return(0); @@ -802,8 +829,7 @@ int PurgeStaleOpenIDassociations(void) { cdb_rewind(CDB_OPENID); while (cdboi = cdb_next_item(CDB_OPENID), cdboi != NULL) { if (cdboi->len > sizeof(long)) { - long usernum; - usernum = ((long)*(cdboi->ptr)); + memcpy(&usernum, cdboi->ptr, sizeof(long)); if (getuserbynumber(&usbuf, usernum) != 0) { deleteme = strdup(cdboi->ptr + sizeof(long)), Put(keys, deleteme, strlen(deleteme), deleteme, generic_free_handler); @@ -814,7 +840,7 @@ int PurgeStaleOpenIDassociations(void) { /* Go through the hash list, deleting keys we stored in it */ - HashPos = GetNewHashPos(); + HashPos = GetNewHashPos(keys, 0); while (GetNextHashPos(keys, HashPos, &len, &Key, &Value)!=0) { CtdlLogPrintf(CTDL_DEBUG, "Deleting associated OpenID <%s>\n", Value); @@ -851,7 +877,10 @@ void *purge_databases(void *args) */ now = time(NULL); localtime_r(&now, &tm); - if ((tm.tm_hour != config.c_purge_hour) || ((now - last_purge) < 43200)) { + if ( + ((tm.tm_hour != config.c_purge_hour) || ((now - last_purge) < 43200)) + && (force_purge_now == 0) + ) { CtdlThreadSleep(60); continue; } @@ -911,6 +940,7 @@ void *purge_databases(void *args) { CtdlLogPrintf(CTDL_INFO, "Auto-purger: finished.\n"); last_purge = now; /* So we don't do it again soon */ + force_purge_now = 0; } else CtdlLogPrintf(CTDL_INFO, "Auto-purger: STOPPED.\n"); @@ -921,6 +951,10 @@ void *purge_databases(void *args) /*****************************************************************************/ +/* The FSCK command has been removed because people were misusing it */ + +#if 0 + void do_fsck_msg(long msgnum, void *userdata) { struct ctdlroomref *ptr; @@ -999,7 +1033,16 @@ void cmd_fsck(char *argbuf) { } +#endif /* end of commented-out fsck cmd */ +/* + * Manually initiate a run of The Dreaded Auto-Purger (tm) + */ +void cmd_tdap(char *argbuf) { + if (CtdlAccessCheck(ac_aide)) return; + force_purge_now = 1; + cprintf("%d Manually initiating a purger run now.\n", CIT_OK); +} /*****************************************************************************/ @@ -1008,7 +1051,8 @@ CTDL_MODULE_INIT(expire) { if (!threading) { - CtdlRegisterProtoHook(cmd_fsck, "FSCK", "Check message ref counts"); + /* CtdlRegisterProtoHook(cmd_fsck, "FSCK", "Check message ref counts"); */ + CtdlRegisterProtoHook(cmd_tdap, "TDAP", "Manually initiate auto-purger"); } else CtdlThreadCreate("Auto Purger", CTDLTHREAD_BIGSTACK, purge_databases, NULL);