citadel
About: Citadel is an advanced messaging and collaboration system for groupware and BBS applications (preferred OS: Linux).
  Fossies Dox: citadel.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

Loading...
Searching...
No Matches
euidindex.c
Go to the documentation of this file.
1// Index messages by EUID per room.
2//
3// Copyright (c) 1987-2022 by the citadel.org team
4//
5// This program is open source software. Use, duplication, or disclosure
6// is subject to the terms of the GNU General Public License, version 3.
7
8#include "sysdep.h"
9#include <stdio.h>
10#include <libcitadel.h>
11#include "citserver.h"
12#include "room_ops.h"
13
14// The structure of an euidindex record *key* is:
15//
16// |----room_number----|----------EUID-------------|
17// (sizeof long) (actual length of euid)
18//
19//
20// The structure of an euidindex record *value* is:
21//
22// |-----msg_number----|----room_number----|----------EUID-------------|
23// (sizeof long) (sizeof long) (actual length of euid)
24
25// Return nonzero if the supplied room is one which should have
26// an EUID index.
28
29 switch(qrbuf->QRdefaultview) {
30 case VIEW_BBS: return(0);
31 case VIEW_MAILBOX: return(0);
32 case VIEW_ADDRESSBOOK: return(1);
33 case VIEW_DRAFTS: return(0);
34 case VIEW_CALENDAR: return(1);
35 case VIEW_TASKS: return(1);
36 case VIEW_NOTES: return(1);
37 case VIEW_WIKI: return(1);
38 case VIEW_BLOG: return(1);
39 }
40
41 return(0);
42}
43
44
45// Locate a message in a given room with a given euid, and return
46// its message number.
47long locate_message_by_euid(char *euid, struct ctdlroom *qrbuf) {
48 return CtdlLocateMessageByEuid (euid, qrbuf);
49}
50
51
52long CtdlLocateMessageByEuid(char *euid, struct ctdlroom *qrbuf) {
53 char *key;
54 int key_len;
55 struct cdbdata *cdb_euid;
56 long msgnum = (-1L);
57
58 syslog(LOG_DEBUG, "euidindex: searching for EUID <%s> in <%s>", euid, qrbuf->QRname);
59
60 key_len = strlen(euid) + sizeof(long) + 1;
61 key = malloc(key_len);
62 memcpy(key, &qrbuf->QRnumber, sizeof(long));
63 strcpy(&key[sizeof(long)], euid);
64
65 cdb_euid = cdb_fetch(CDB_EUIDINDEX, key, key_len);
66 free(key);
67
68 if (cdb_euid == NULL) {
69 msgnum = (-1L);
70 }
71 else {
72 // The first (sizeof long) of the record is what we're looking for. Throw away the rest.
73 memcpy(&msgnum, cdb_euid->ptr, sizeof(long));
74 cdb_free(cdb_euid);
75 }
76 syslog(LOG_DEBUG, "euidindex: returning msgnum = %ld", msgnum);
77 return(msgnum);
78}
79
80
81// Store the euid index for a message, which has presumably just been
82// stored in this room by the caller.
83void index_message_by_euid(char *euid, struct ctdlroom *qrbuf, long msgnum) {
84 char *key;
85 int key_len;
86 char *data;
87 int data_len;
88
89 syslog(LOG_DEBUG, "euidindex: indexing message #%ld <%s> in <%s>", msgnum, euid, qrbuf->QRname);
90
91 key_len = strlen(euid) + sizeof(long) + 1;
92 key = malloc(key_len);
93 memcpy(key, &qrbuf->QRnumber, sizeof(long));
94 strcpy(&key[sizeof(long)], euid);
95
96 data_len = sizeof(long) + key_len;
97 data = malloc(data_len);
98
99 memcpy(data, &msgnum, sizeof(long));
100 memcpy(&data[sizeof(long)], key, key_len);
101
102 cdb_store(CDB_EUIDINDEX, key, key_len, data, data_len);
103 free(key);
104 free(data);
105}
106
107
108// Called by rebuild_euid_index_for_room() to index one message.
109void rebuild_euid_index_for_msg(long msgnum, void *userdata) {
110 struct CtdlMessage *msg = NULL;
111
112 msg = CtdlFetchMessage(msgnum, 0);
113 if (msg == NULL) return;
114 if (!CM_IsEmpty(msg, eExclusiveID)) {
115 index_message_by_euid(msg->cm_fields[eExclusiveID], &CC->room, msgnum);
116 }
117 CM_Free(msg);
118}
119
120
121void rebuild_euid_index_for_room(struct ctdlroom *qrbuf, void *data) {
122 static struct RoomProcList *rplist = NULL;
123 struct RoomProcList *ptr;
124 struct ctdlroom qr;
125
126 // Lazy programming here. Call this function as a CtdlForEachRoom backend
127 // in order to queue up the room names, or call it with a null room
128 // to make it do the processing.
129 if (qrbuf != NULL) {
130 ptr = (struct RoomProcList *)
131 malloc(sizeof (struct RoomProcList));
132 if (ptr == NULL) return;
133
134 safestrncpy(ptr->name, qrbuf->QRname, sizeof ptr->name);
135 ptr->next = rplist;
136 rplist = ptr;
137 return;
138 }
139
140 while (rplist != NULL) {
141 if (CtdlGetRoom(&qr, rplist->name) == 0) {
143 syslog(LOG_DEBUG,
144 "euidindex: rebuilding EUID index for <%s>",
145 rplist->name);
146 CtdlUserGoto(rplist->name, 0, 0, NULL, NULL, NULL, NULL);
147 CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, rebuild_euid_index_for_msg, NULL);
148 }
149 }
150 ptr = rplist;
151 rplist = rplist->next;
152 free(ptr);
153 }
154}
155
156
157// Globally rebuild the EUID indices in every room.
159 cdb_trunc(CDB_EUIDINDEX); // delete the old indices
160 CtdlForEachRoom(rebuild_euid_index_for_room, NULL); // enumerate room names
161 rebuild_euid_index_for_room(NULL, NULL); // and index them
162}
163
164
165// Server command to fetch a message number given an euid.
166void cmd_euid(char *cmdbuf) {
167 char euid[256];
168 long msgnum;
169 struct cdbdata *cdbfr;
170 long *msglist = NULL;
171 int num_msgs = 0;
172 int i;
173
175
176 extract_token(euid, cmdbuf, 0, '|', sizeof euid);
177 msgnum = CtdlLocateMessageByEuid(euid, &CC->room);
178 if (msgnum <= 0L) {
179 cprintf("%d not found\n", ERROR + MESSAGE_NOT_FOUND);
180 return;
181 }
182
183 cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long));
184 if (cdbfr != NULL) {
185 num_msgs = cdbfr->len / sizeof(long);
186 msglist = (long *) cdbfr->ptr;
187 for (i = 0; i < num_msgs; ++i) {
188 if (msglist[i] == msgnum) {
189 cdb_free(cdbfr);
190 cprintf("%d %ld\n", CIT_OK, msgnum);
191 return;
192 }
193 }
194 cdb_free(cdbfr);
195 }
196
197 cprintf("%d not found\n", ERROR + MESSAGE_NOT_FOUND);
198}
199
200
202 if (!threading) {
203 CtdlRegisterProtoHook(cmd_euid, "EUID", "Perform operations on Extended IDs for messages");
204 }
205 // return our id for the log
206 return "euidindex";
207}
#define CC
Definition: context.h:140
int CtdlAccessCheck(int)
Definition: user_ops.c:334
int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name)
Definition: room_ops.c:309
int threading
Definition: modules_init.c:24
void CtdlForEachRoom(ForEachRoomCallBack CB, void *in_data)
Definition: room_ops.c:542
@ ac_logged_in_or_guest
Definition: ctdl_module.h:246
void CtdlUserGoto(char *where, int display_result, int transiently, int *msgs, int *new, long *oldest, long *newest)
Definition: room_ops.c:623
void CtdlRegisterProtoHook(void(*handler)(char *), char *cmd, char *desc)
void cdb_free(struct cdbdata *cdb)
Definition: database.c:604
int cdb_store(int cdb, const void *ckey, int ckeylen, void *cdata, int cdatalen)
Definition: database.c:392
struct cdbdata * cdb_fetch(int cdb, const void *key, int keylen)
Definition: database.c:541
void cdb_trunc(int cdb)
Definition: database.c:721
void rebuild_euid_index(void)
Definition: euidindex.c:158
long CtdlLocateMessageByEuid(char *euid, struct ctdlroom *qrbuf)
Definition: euidindex.c:52
void cmd_euid(char *cmdbuf)
Definition: euidindex.c:166
long locate_message_by_euid(char *euid, struct ctdlroom *qrbuf)
Definition: euidindex.c:47
void index_message_by_euid(char *euid, struct ctdlroom *qrbuf, long msgnum)
Definition: euidindex.c:83
void rebuild_euid_index_for_room(struct ctdlroom *qrbuf, void *data)
Definition: euidindex.c:121
int DoesThisRoomNeedEuidIndexing(struct ctdlroom *qrbuf)
Definition: euidindex.c:27
char * ctdl_module_init_euidindex(void)
Definition: euidindex.c:201
void rebuild_euid_index_for_msg(long msgnum, void *userdata)
Definition: euidindex.c:109
#define CIT_OK
Definition: ipcdef.h:6
#define ERROR
Definition: ipcdef.h:9
#define MESSAGE_NOT_FOUND
Definition: ipcdef.h:34
void CM_Free(struct CtdlMessage *msg)
Definition: msgbase.c:305
int CtdlForEachMessage(int mode, long ref, char *search_string, char *content_type, struct CtdlMessage *compare, ForEachMsgCallback CallBack, void *userdata)
Definition: msgbase.c:621
struct CtdlMessage * CtdlFetchMessage(long msgnum, int with_body)
Definition: msgbase.c:1128
int CM_IsEmpty(struct CtdlMessage *Msg, eMsgField which)
Definition: msgbase.c:132
@ MSGS_ALL
Definition: msgbase.h:6
void * malloc(unsigned)
void free(void *)
struct ctdlroom qrbuf
Definition: serv_migrate.c:497
@ eExclusiveID
Definition: server.h:309
@ CDB_EUIDINDEX
Definition: server.h:195
@ CDB_MSGLISTS
Definition: server.h:189
char * cm_fields[256]
Definition: server.h:37
struct RoomProcList * next
Definition: citserver.h:18
char name[128]
Definition: citserver.h:19
size_t len
Definition: server.h:203
char * ptr
Definition: server.h:204
char QRname[128]
Definition: citadel.h:94
long QRnumber
Definition: citadel.h:105
int QRdefaultview
Definition: citadel.h:108
void cprintf(const char *format,...)
Definition: sysdep.c:369