//
// You might also see this module affectionately referred to as TDAP (The Dreaded Auto-Purger).
//
-// Copyright (c) 1988-2022 by citadel.org (Art Cancro, Wilifried Goesgens, and others)
+// Copyright (c) 1988-2023 by citadel.org (Art Cancro, Wilifried Goesgens, and others)
//
-// This program is open source 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.
+// This program is open source software. Use, duplication, or disclosure
+// is subject to the terms of the GNU General Public License, version 3.
#include "../../sysdep.h"
#include <string.h>
#include <limits.h>
#include <libcitadel.h>
-#include "../../citadel.h"
+#include "../../citadel_defs.h"
#include "../../server.h"
#include "../../citserver.h"
#include "../../support.h"
long msgnum;
};
-struct UPurgeList {
- struct UPurgeList *next;
- char up_key[256];
-};
-
struct EPurgeList {
struct EPurgeList *next;
int ep_keylen;
//
int PurgeVisits(void) {
struct cdbdata *cdbvisit;
- visit vbuf;
+ struct visit vbuf;
struct VPurgeList *VisitPurgeList = NULL;
struct VPurgeList *vptr;
int purged = 0;
// Now traverse through the visits, purging irrelevant records...
cdb_rewind(CDB_VISIT);
while(cdbvisit = cdb_next_item(CDB_VISIT), cdbvisit != NULL) {
- memset(&vbuf, 0, sizeof(visit));
+ memset(&vbuf, 0, sizeof(struct visit));
memcpy(&vbuf, cdbvisit->ptr,
- ( (cdbvisit->len > sizeof(visit)) ?
- sizeof(visit) : cdbvisit->len) );
+ ( (cdbvisit->len > sizeof(struct visit)) ?
+ sizeof(struct visit) : cdbvisit->len) );
cdb_free(cdbvisit);
RoomIsValid = 0;
// Purge the use table of old entries.
+// Holy crap, this is WAY better. We need to replace most linked lists with arrays.
int PurgeUseTable(StrBuf *ErrMsg) {
int purged = 0;
+ int total = 0;
struct cdbdata *cdbut;
struct UseTable ut;
- struct UPurgeList *ul = NULL;
- struct UPurgeList *uptr;
+ Array *purge_list = array_new(sizeof(int));
// Phase 1: traverse through the table, discovering old records...
syslog(LOG_DEBUG, "Purge use table: phase 1");
cdb_rewind(CDB_USETABLE);
while(cdbut = cdb_next_item(CDB_USETABLE), cdbut != NULL) {
+ ++total;
if (cdbut->len > sizeof(struct UseTable))
memcpy(&ut, cdbut->ptr, sizeof(struct UseTable));
else {
}
cdb_free(cdbut);
- if ( (time(NULL) - ut.ut_timestamp) > USETABLE_RETAIN ) {
- uptr = (struct UPurgeList *) malloc(sizeof(struct UPurgeList));
- if (uptr != NULL) {
- uptr->next = ul;
- safestrncpy(uptr->up_key, ut.ut_msgid, sizeof uptr->up_key);
- ul = uptr;
- }
+ if ( (time(NULL) - ut.timestamp) > USETABLE_RETAIN ) {
+ array_append(purge_list, &ut.hash);
++purged;
}
-
}
// Phase 2: delete the records
syslog(LOG_DEBUG, "Purge use table: phase 2");
- while (ul != NULL) {
- cdb_delete(CDB_USETABLE, ul->up_key, strlen(ul->up_key));
- uptr = ul->next;
- free(ul);
- ul = uptr;
+ int i;
+ for (i=0; i<purged; ++i) {
+ struct UseTable *u = (struct UseTable *)array_get_element_at(purge_list, i);
+ cdb_delete(CDB_USETABLE, &u->hash, sizeof(int));
}
+ array_free(purge_list);
- syslog(LOG_DEBUG, "Purge use table: finished (purged %d records)", purged);
+ syslog(LOG_DEBUG, "Purge use table: finished (purged %d of %d records)", purged, total);
return(purged);
}
}
-// Purge external auth assocations for missing users (theoretically this will never delete anything)
-int PurgeStaleExtAuthAssociations(void) {
- struct cdbdata *cdboi;
- struct ctdluser usbuf;
- HashList *keys = NULL;
- HashPos *HashPos;
- char *deleteme = NULL;
- long len;
- void *Value;
- const char *Key;
- int num_deleted = 0;
- long usernum = 0L;
-
- keys = NewHash(1, NULL);
- if (!keys) return(0);
-
- cdb_rewind(CDB_EXTAUTH);
- while (cdboi = cdb_next_item(CDB_EXTAUTH), cdboi != NULL) {
- if (cdboi->len > sizeof(long)) {
- memcpy(&usernum, cdboi->ptr, sizeof(long));
- if (CtdlGetUserByNumber(&usbuf, usernum) != 0) {
- deleteme = strdup(cdboi->ptr + sizeof(long)),
- Put(keys, deleteme, strlen(deleteme), deleteme, NULL);
- }
- }
- cdb_free(cdboi);
- }
-
- // Go through the hash list, deleting keys we stored in it
-
- HashPos = GetNewHashPos(keys, 0);
- while (GetNextHashPos(keys, HashPos, &len, &Key, &Value)!=0) {
- syslog(LOG_DEBUG, "Deleting associated external authenticator <%s>", (char*)Value);
- cdb_delete(CDB_EXTAUTH, Value, strlen(Value));
- // note: don't free(Value) -- deleting the hash list will handle this for us
- ++num_deleted;
- }
- DeleteHashPos(&HashPos);
- DeleteHash(&keys);
- return num_deleted;
-}
-
-
void purge_databases(void) {
int retval;
static time_t last_purge = 0;
syslog(LOG_NOTICE, "Purged %d entries from the EUID index.", retval);
}
- if (!server_shutting_down) {
- retval = PurgeStaleExtAuthAssociations();
- syslog(LOG_NOTICE, "Purged %d stale external auth associations.", retval);
- }
-
//if (!server_shutting_down) {
// FIXME this is where we could do a non-interactive delete of zero-refcount messages
//}