X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Feuidindex.c;h=95c7c77a792fe05b885f685a5048cf19696fb525;hb=0fadbcbe2c27134ad71634b9c81d277d118eff17;hp=04c14b91a8982cfe542870e5b13490defcd0f690;hpb=b4057d567a5a15e17b5ffc89ea31b372b0c2f5e1;p=citadel.git diff --git a/citadel/euidindex.c b/citadel/euidindex.c index 04c14b91a..95c7c77a7 100644 --- a/citadel/euidindex.c +++ b/citadel/euidindex.c @@ -1,67 +1,122 @@ /* - * $Id$ - * * Index messages by EUID per room. - * */ #include "sysdep.h" -#include -#include #include -#include - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - - -#include -#include -#include -#include -#include -#include -#include "citadel.h" -#include "server.h" -#include "serv_extensions.h" -#include "database.h" -#include "msgbase.h" -#include "support.h" -#include "sysdep_decls.h" +#include + #include "citserver.h" #include "room_ops.h" -#include "user_ops.h" -#include "file_ops.h" -#include "config.h" -#include "control.h" -#include "tools.h" -#include "euidindex.h" +/* + * The structure of an euidindex record *key* is: + * + * |----room_number----|----------EUID-------------| + * (sizeof long) (actual length of euid) + * + * + * The structure of an euidindex record *value* is: + * + * |-----msg_number----|----room_number----|----------EUID-------------| + * (sizeof long) (sizeof long) (actual length of euid) + * + */ -long locate_message_by_euid(char *euid, struct ctdlroom *qrbuf) { + + +/* + * Return nonzero if the supplied room is one which should have + * an EUID index. + */ +int DoesThisRoomNeedEuidIndexing(struct ctdlroom *qrbuf) { + + switch(qrbuf->QRdefaultview) { + case VIEW_BBS: return(0); + case VIEW_MAILBOX: return(0); + case VIEW_ADDRESSBOOK: return(1); + case VIEW_DRAFTS: return(0); + case VIEW_CALENDAR: return(1); + case VIEW_TASKS: return(1); + case VIEW_NOTES: return(1); + case VIEW_WIKI: return(1); + case VIEW_WIKIMD: return(1); + case VIEW_BLOG: return(1); + } + return(0); } + + + + + +/* + * 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) { + return CtdlLocateMessageByEuid (euid, qrbuf); +} + +long CtdlLocateMessageByEuid(char *euid, struct ctdlroom *qrbuf) { + char *key; + int key_len; + struct cdbdata *cdb_euid; + long msgnum = (-1L); + + syslog(LOG_DEBUG, "euidindex: searching for EUID <%s> in <%s>", euid, qrbuf->QRname); + + key_len = strlen(euid) + sizeof(long) + 1; + key = malloc(key_len); + memcpy(key, &qrbuf->QRnumber, sizeof(long)); + strcpy(&key[sizeof(long)], euid); + + cdb_euid = cdb_fetch(CDB_EUIDINDEX, key, key_len); + free(key); + + if (cdb_euid == NULL) { + msgnum = (-1L); + } + else { + /* The first (sizeof long) of the record is what we're + * looking for. Throw away the rest. + */ + memcpy(&msgnum, cdb_euid->ptr, sizeof(long)); + cdb_free(cdb_euid); + } + syslog(LOG_DEBUG, "euidindex: returning msgnum = %ld", msgnum); + 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; + char *data; + int data_len; - lprintf(CTDL_DEBUG, "Indexing message #%ld <%s> in <%s>\n", msgnum, euid, qrbuf->QRname); + syslog(LOG_DEBUG, "euidindex: ndexing message #%ld <%s> in <%s>", msgnum, euid, qrbuf->QRname); key_len = strlen(euid) + sizeof(long) + 1; key = malloc(key_len); memcpy(key, &qrbuf->QRnumber, sizeof(long)); strcpy(&key[sizeof(long)], euid); - cdb_store(CDB_EUIDINDEX, key, key_len, &msgnum, sizeof(long)); + data_len = sizeof(long) + key_len; + data = malloc(data_len); + + memcpy(data, &msgnum, sizeof(long)); + memcpy(&data[sizeof(long)], key, key_len); + + cdb_store(CDB_EUIDINDEX, key, key_len, data, data_len); + free(key); + free(data); } @@ -70,14 +125,14 @@ void index_message_by_euid(char *euid, struct ctdlroom *qrbuf, long msgnum) { * Called by rebuild_euid_index_for_room() to index one message. */ void rebuild_euid_index_for_msg(long msgnum, void *userdata) { - struct CtdlMessage *msg; + struct CtdlMessage *msg = NULL; - msg = CtdlFetchMessage(msgnum, 0); + msg = CtdlFetchMessage(msgnum, 0, 1); if (msg == NULL) return; - if (msg->cm_fields['E'] != NULL) { - index_message_by_euid(msg->cm_fields['E'], &CC->room, msgnum); + if (!CM_IsEmpty(msg, eExclusiveID)) { + index_message_by_euid(msg->cm_fields[eExclusiveID], &CC->room, msgnum); } - CtdlFreeMessage(msg); + CM_Free(msg); } @@ -86,7 +141,7 @@ void rebuild_euid_index_for_room(struct ctdlroom *qrbuf, void *data) { struct RoomProcList *ptr; struct ctdlroom qr; - /* Lazy programming here. Call this function as a ForEachRoom backend + /* Lazy programming here. Call this function as a CtdlForEachRoom backend * in order to queue up the room names, or call it with a null room * to make it do the processing. */ @@ -102,10 +157,15 @@ void rebuild_euid_index_for_room(struct ctdlroom *qrbuf, void *data) { } while (rplist != NULL) { - if (getroom(&qr, rplist->name) == 0) { - lprintf(CTDL_DEBUG, "Rebuilding EUID index for <%s>\n", rplist->name); - usergoto(rplist->name, 0, 0, NULL, NULL); - CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, rebuild_euid_index_for_msg, NULL); + if (CtdlGetRoom(&qr, rplist->name) == 0) { + if (DoesThisRoomNeedEuidIndexing(&qr)) { + syslog(LOG_DEBUG, + "euidindex: rebuilding EUID index for <%s>", + rplist->name); + CtdlUserGoto(rplist->name, 0, 0, NULL, NULL, NULL, NULL); + CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, + rebuild_euid_index_for_msg, NULL); + } } ptr = rplist; rplist = rplist->next; @@ -118,8 +178,55 @@ void rebuild_euid_index_for_room(struct ctdlroom *qrbuf, void *data) { * Globally rebuild the EUID indices in every room. */ void rebuild_euid_index(void) { - cdb_trunc(CDB_EUIDINDEX); + cdb_trunc(CDB_EUIDINDEX); /* delete the old indices */ + CtdlForEachRoom(rebuild_euid_index_for_room, NULL); /* enumerate rm names */ + rebuild_euid_index_for_room(NULL, NULL); /* and index them */ +} + + + +/* + * Server command to fetch a message number given an euid. + */ +void cmd_euid(char *cmdbuf) { + char euid[256]; + long msgnum; + struct cdbdata *cdbfr; + long *msglist = NULL; + int num_msgs = 0; + int i; + + if (CtdlAccessCheck(ac_logged_in_or_guest)) return; + + extract_token(euid, cmdbuf, 0, '|', sizeof euid); + msgnum = CtdlLocateMessageByEuid(euid, &CC->room); + if (msgnum <= 0L) { + cprintf("%d not found\n", ERROR + MESSAGE_NOT_FOUND); + return; + } + + cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long)); + if (cdbfr != NULL) { + num_msgs = cdbfr->len / sizeof(long); + msglist = (long *) cdbfr->ptr; + for (i = 0; i < num_msgs; ++i) { + if (msglist[i] == msgnum) { + cdb_free(cdbfr); + cprintf("%d %ld\n", CIT_OK, msgnum); + return; + } + } + cdb_free(cdbfr); + } - ForEachRoom(rebuild_euid_index_for_room, NULL); - rebuild_euid_index_for_room(NULL, NULL); + cprintf("%d not found\n", ERROR + MESSAGE_NOT_FOUND); +} + +CTDL_MODULE_INIT(euidindex) +{ + if (!threading) { + CtdlRegisterProtoHook(cmd_euid, "EUID", "Perform operations on Extended IDs for messages"); + } + /* return our Subversion id for the Log */ + return "euidindex"; }