From 2e946447e4956286ace9a133cd65a306816daca5 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Thu, 6 Oct 2005 04:09:19 +0000 Subject: [PATCH] * THE DREADED AUTO-PURGER now purges euid index records which point to messages that no longer exist. --- citadel/ChangeLog | 5 +++- citadel/euidindex.c | 14 +++++++-- citadel/msgbase.c | 17 ++++------- citadel/serv_expire.c | 68 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 88 insertions(+), 16 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 4df65e6ba..acc29f1c7 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,8 @@ $Log$ +Revision 655.22 2005/10/06 04:09:19 ajc +* THE DREADED AUTO-PURGER now purges euid index records which point to + messages that no longer exist. + Revision 655.21 2005/10/06 03:36:05 ajc * Changed the format of the euidindex record to contain the record's key. This will allow us to auto-purge stale records later. @@ -7201,4 +7205,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import - diff --git a/citadel/euidindex.c b/citadel/euidindex.c index 9a8d59843..ef2cb2780 100644 --- a/citadel/euidindex.c +++ b/citadel/euidindex.c @@ -46,19 +46,24 @@ #include "euidindex.h" /* - * The structure of an EUID *index* is: + * The structure of an euidindex record *key* is: * * |----room_number----|----------EUID-------------| * (sizeof long) (actual length of euid) * * - * The structure of an EUID *record* is: + * The structure of an euidindex record *value* is: * * |-----msg_number----|----room_number----|----------EUID-------------| * (sizeof long) (sizeof long) (actual length of euid) * */ + +/* + * Locate a message in a given room with a given euid, and return + * its message number. + */ long locate_message_by_euid(char *euid, struct ctdlroom *qrbuf) { char *key; int key_len; @@ -89,6 +94,11 @@ long locate_message_by_euid(char *euid, struct ctdlroom *qrbuf) { return(msgnum); } + +/* + * Store the euid index for a message, which has presumably just been + * stored in this room by the caller. + */ void index_message_by_euid(char *euid, struct ctdlroom *qrbuf, long msgnum) { char *key; int key_len; diff --git a/citadel/msgbase.c b/citadel/msgbase.c index ffddf5c73..e1608b4cb 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1776,8 +1776,8 @@ int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, int do_repl_check, long highest_msg = 0L; struct CtdlMessage *msg = NULL; - lprintf(CTDL_DEBUG, "CtdlSaveMsgPointerInRoom(roomname=%s, msgid=%ld, do_repl_check=%d)\n", - roomname, msgid, do_repl_check); + /*lprintf(CTDL_DEBUG, "CtdlSaveMsgPointerInRoom(roomname=%s, msgid=%ld, do_repl_check=%d)\n", + roomname, msgid, do_repl_check);*/ strcpy(hold_rm, CC->room.QRname); @@ -2019,8 +2019,8 @@ void ReplicationChecks(struct CtdlMessage *msg) { if (msg == NULL) return; if (msg->cm_fields['E'] == NULL) return; if (strlen(msg->cm_fields['E']) == 0) return; - lprintf(CTDL_DEBUG, "Exclusive ID: <%s> for room <%s>\n", - msg->cm_fields['E'], CC->room.QRname); + /*lprintf(CTDL_DEBUG, "Exclusive ID: <%s> for room <%s>\n", + msg->cm_fields['E'], CC->room.QRname);*/ old_msgnum = locate_message_by_euid(msg->cm_fields['E'], &CC->room); if (old_msgnum > 0L) { @@ -2066,7 +2066,6 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ * giving it one, right now. */ if (msg->cm_fields['T'] == NULL) { - lprintf(CTDL_DEBUG, "Generating timestamp\n"); snprintf(generated_timestamp, sizeof generated_timestamp, "%ld", (long)time(NULL)); msg->cm_fields['T'] = strdup(generated_timestamp); } @@ -2074,7 +2073,6 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ /* If this message has no path, we generate one. */ if (msg->cm_fields['P'] == NULL) { - lprintf(CTDL_DEBUG, "Generating path\n"); if (msg->cm_fields['A'] != NULL) { msg->cm_fields['P'] = strdup(msg->cm_fields['A']); for (a=0; acm_fields['P']); ++a) { @@ -2096,7 +2094,6 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } /* Learn about what's inside, because it's what's inside that counts */ - lprintf(CTDL_DEBUG, "Learning what's inside\n"); if (msg->cm_fields['M'] == NULL) { lprintf(CTDL_ERR, "ERROR: attempt to save message with NULL body\n"); return(-2); @@ -2127,8 +2124,7 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } /* Goto the correct room */ - lprintf(CTDL_DEBUG, "Selected room %s\n", - (recps) ? CC->room.QRname : SENTITEMS); + lprintf(CTDL_DEBUG, "Selected room %s\n", (recps) ? CC->room.QRname : SENTITEMS); strcpy(hold_rm, CC->room.QRname); strcpy(actual_rm, CC->room.QRname); if (recps != NULL) { @@ -2136,12 +2132,11 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } /* If the user is a twit, move to the twit room for posting */ - lprintf(CTDL_DEBUG, "Handling twit stuff: %s\n", - (CC->user.axlevel == 2) ? config.c_twitroom : "OK"); if (TWITDETECT) { if (CC->user.axlevel == 2) { strcpy(hold_rm, actual_rm); strcpy(actual_rm, config.c_twitroom); + lprintf(CTDL_DEBUG, "Diverting to twit room\n"); } } diff --git a/citadel/serv_expire.c b/citadel/serv_expire.c index 0da8e381c..ba354fa2d 100644 --- a/citadel/serv_expire.c +++ b/citadel/serv_expire.c @@ -97,7 +97,13 @@ struct ctdlroomref { struct UPurgeList { struct UPurgeList *next; - char up_key[SIZ]; + char up_key[256]; +}; + +struct EPurgeList { + struct EPurgeList *next; + int ep_keylen; + char *ep_key; }; @@ -604,7 +610,7 @@ int PurgeUseTable(void) { uptr = (struct UPurgeList *) malloc(sizeof(struct UPurgeList)); if (uptr != NULL) { uptr->next = ul; - safestrncpy(uptr->up_key, ut.ut_msgid, SIZ); + safestrncpy(uptr->up_key, ut.ut_msgid, sizeof uptr->up_key); ul = uptr; } ++purged; @@ -626,6 +632,61 @@ int PurgeUseTable(void) { } + +/* + * Purge the EUID Index of old records. + * + */ +int PurgeEuidIndexTable(void) { + int purged = 0; + struct cdbdata *cdbei; + struct EPurgeList *el = NULL; + struct EPurgeList *eptr; + long msgnum; + struct CtdlMessage *msg; + + /* Phase 1: traverse through the table, discovering old records... */ + lprintf(CTDL_DEBUG, "Purge EUID index: phase 1\n"); + cdb_rewind(CDB_EUIDINDEX); + while(cdbei = cdb_next_item(CDB_EUIDINDEX), cdbei != NULL) { + + memcpy(&msgnum, cdbei->ptr, sizeof(long)); + + msg = CtdlFetchMessage(msgnum, 0); + if (msg != NULL) { + CtdlFreeMessage(msg); /* it still exists, so do nothing */ + } + else { + eptr = (struct EPurgeList *) malloc(sizeof(struct EPurgeList)); + if (eptr != NULL) { + eptr->next = el; + eptr->ep_keylen = cdbei->len - sizeof(long); + eptr->ep_key = malloc(cdbei->len); + memcpy(eptr->ep_key, &cdbei->ptr[sizeof(long)], eptr->ep_keylen); + el = eptr; + } + ++purged; + } + + cdb_free(cdbei); + + } + + /* Phase 2: delete the records */ + lprintf(CTDL_DEBUG, "Purge euid index: phase 2\n"); + while (el != NULL) { + cdb_delete(CDB_EUIDINDEX, el->ep_key, el->ep_keylen); + free(el->ep_key); + eptr = el->next; + free(el); + el = eptr; + } + + lprintf(CTDL_DEBUG, "Purge euid index: finished (purged %d records)\n", purged); + return(purged); +} + + void purge_databases(void) { int retval; static time_t last_purge = 0; @@ -658,6 +719,9 @@ void purge_databases(void) { retval = PurgeUseTable(); lprintf(CTDL_NOTICE, "Purged %d entries from the use table.\n", retval); + retval = PurgeEuidIndexTable(); + lprintf(CTDL_NOTICE, "Purged %d entries from the EUID index.\n", retval); + lprintf(CTDL_INFO, "Auto-purger: finished.\n"); last_purge = now; /* So we don't do it again soon */ -- 2.30.2