message is being deleted from a room.
* When deleting messages from a room, do the AdjRefCount() calls (and now,
the PerformDeleteHooks() calls) in a second pass. This keeps that stuff
outside of the S_QUICKROOM critical section.
$Log$
+ Revision 590.95 2002/01/30 19:03:41 ajc
+ * Added a new DeleteFunctionHook type of thing. These get called when a
+ message is being deleted from a room.
+ * When deleting messages from a room, do the AdjRefCount() calls (and now,
+ the PerformDeleteHooks() calls) in a second pass. This keeps that stuff
+ outside of the S_QUICKROOM critical section.
+
Revision 590.94 2002/01/27 06:39:45 error
* file_ops.c: fixed bug in cmd_read() which could cause server to report
the wrong number of bytes for the client to download
Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
* Initial CVS import
-
struct XmsgFunctionHook *XmsgHookTable = NULL;
struct MessageFunctionHook *MessageHookTable = NULL;
struct NetprocFunctionHook *NetprocHookTable = NULL;
+struct DeleteFunctionHook *DeleteHookTable = NULL;
struct ServiceFunctionHook *ServiceHookTable = NULL;
struct ProtoFunctionHook {
}
+void CtdlRegisterDeleteHook(int (*handler)(char *, long) )
+{
+ struct DeleteFunctionHook *newfcn;
+
+ newfcn = (struct DeleteFunctionHook *)
+ mallok(sizeof(struct DeleteFunctionHook));
+ newfcn->next = DeleteHookTable;
+ newfcn->h_function_pointer = handler;
+ DeleteHookTable = newfcn;
+
+ lprintf(5, "Registered a new netproc function\n");
+}
+
+
+void CtdlUnregisterDeleteHook(int (*handler)(char *, long) )
+{
+ struct DeleteFunctionHook *cur, *p;
+
+ for (cur = DeleteHookTable; cur != NULL; cur = cur->next) {
+ /* This will also remove duplicates if any */
+ while (cur != NULL &&
+ handler == cur->h_function_pointer ) {
+ lprintf(5, "Unregistered netproc function\n");
+ p = cur->next;
+ if (cur == DeleteHookTable) {
+ DeleteHookTable = p;
+ }
+ phree(cur);
+ cur = p;
+ }
+ }
+}
+
+
void CtdlRegisterXmsgHook(int (*fcn_ptr) (char *, char *, char *), int order)
{
}
+void PerformDeleteHooks(char *room, long msgnum)
+{
+ struct DeleteFunctionHook *fcn;
+
+ for (fcn = DeleteHookTable; fcn != NULL; fcn = fcn->next) {
+ (*fcn->h_function_pointer) (room, msgnum);
+ }
+}
+
+
int PerformXmsgHooks(char *sender, char *recp, char *msg)
{
void CtdlUnregisterNetprocHook(int (*handler)(struct CtdlMessage *, char *) );
int PerformNetprocHooks(struct CtdlMessage *, char *);
+void CtdlRegisterDeleteHook(int (*handler)(char *, long) );
+void CtdlUnregisterDeleteHook(int (*handler)(char *, long) );
+void PerformDeleteHooks(char *, long);
+
void CtdlRegisterCleanupHook(void (*fcn_ptr)(void));
void CtdlUnregisterCleanupHook(void (*fcn_ptr)(void));
struct quickroom qrbuf;
struct cdbdata *cdbfr;
long *msglist = NULL;
+ long *dellist = NULL;
int num_msgs = 0;
int i;
int num_deleted = 0;
if (cdbfr != NULL) {
msglist = mallok(cdbfr->len);
+ dellist = mallok(cdbfr->len);
memcpy(msglist, cdbfr->ptr, cdbfr->len);
num_msgs = cdbfr->len / sizeof(long);
cdb_free(cdbfr);
/* Delete message only if all bits are set */
if (delete_this == 0x03) {
- AdjRefCount(msglist[i], -1);
+ dellist[num_deleted++] = msglist[i];
msglist[i] = 0L;
- ++num_deleted;
}
}
msglist, (num_msgs * sizeof(long)));
qrbuf.QRhighest = msglist[num_msgs - 1];
- phree(msglist);
}
lputroom(&qrbuf);
+
+ /* Go through the messages we pulled out of the index, and decrement
+ * their reference counts by 1. If this is the only room the message
+ * was in, the reference count will reach zero and the message will
+ * automatically be deleted from the database. We do this in a
+ * separate pass because there might be plug-in hooks getting called,
+ * and we don't want that happening during an S_QUICKROOM critical
+ * section.
+ */
+ if (num_deleted) for (i=0; i<num_deleted; ++i) {
+ PerformDeleteHooks(qrbuf.QRname, dellist[i]);
+ AdjRefCount(dellist[i], -1);
+ }
+
+ /* Now free the memory we used, and go away. */
+ if (msglist != NULL) phree(msglist);
+ if (dellist != NULL) phree(dellist);
lprintf(9, "%d message(s) deleted.\n", num_deleted);
return (num_deleted);
}
extern DLEXP struct NetprocFunctionHook *NetprocHookTable;
+/*
+ * DeleteFunctionHook extensions are used for hooks which get called when a
+ * message is about to be deleted.
+ */
+struct DeleteFunctionHook {
+ struct DeleteFunctionHook *next;
+ int (*h_function_pointer) (char *target_room, long msgnum);
+};
+extern DLEXP struct DeleteFunctionHook *DeleteHookTable;
+
/*
* ExpressMessageFunctionHook extensions are used for hooks which implement