$Log$
+Revision 654.1 2005/08/05 21:31:01 ajc
+* Any "delete message" operation which is synchronous to a client is now
+ deferred. This is accomplished by copying the message pointer to
+ the __CitadelDeletedMessages__ room, which keeps the reference count at
+ least 1. THE DREADED AUTO-PURGER can sweep it up later.
+
Revision 654.0 2005/08/05 16:22:38 ajc
* THIS IS 6.54
Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
* Initial CVS import
-
lputroom(&qrbuf);
}
+ /*
+ * Create a room in which we can deposit "deleted" messages for
+ * deferred deletion. This will silently fail if the room already
+ * exists, and that's perfectly ok, because we want it to exist.
+ */
+ create_room(DELETED_MSGS_ROOM, 3, "", 0, 1, 0, VIEW_MAILBOX);
+
+ /*
+ * Make sure it's set to be a "system room" so it doesn't show up
+ * in the <K>nown rooms list for Aides. Also set the message expire
+ * policy to "by count, 1 message" so everything gets deleted all
+ * the time (we can't set it to 0 because that's invalid, so we keep
+ * a single message around).
+ */
+ if (lgetroom(&qrbuf, DELETED_MSGS_ROOM) == 0) {
+ qrbuf.QRflags2 |= QR2_SYSTEM;
+ qrbuf.QRep.expire_mode = EXPIRE_NUMMSGS;
+ qrbuf.QRep.expire_value = 1;
+ lputroom(&qrbuf);
+ }
+
lprintf(CTDL_INFO, "Seeding the pseudo-random number generator...\n");
urandom = fopen("/dev/urandom", "r");
if (urandom != NULL) {
*/
void check_repl(long msgnum, void *userdata) {
lprintf(CTDL_DEBUG, "check_repl() replacing message %ld\n", msgnum);
- CtdlDeleteMessages(CC->room.QRname, msgnum, "");
+ CtdlDeleteMessages(CC->room.QRname, msgnum, "", 0);
}
* (returns the actual number of messages deleted)
*/
int CtdlDeleteMessages(char *room_name, /* which room */
- long dmsgnum, /* or "0" for any */
- char *content_type /* or "" for any */
+ long dmsgnum, /* or "0" for any */
+ char *content_type, /* or "" for any */
+ int deferred /* let TDAP sweep it later */
)
{
int delete_this;
struct MetaData smi;
- lprintf(CTDL_DEBUG, "CtdlDeleteMessages(%s, %ld, %s)\n",
- room_name, dmsgnum, content_type);
+ lprintf(CTDL_DEBUG, "CtdlDeleteMessages(%s, %ld, %s, %d)\n",
+ room_name, dmsgnum, content_type, deferred);
/* get room record, obtaining a lock... */
if (lgetroom(&qrbuf, room_name) != 0) {
}
lputroom(&qrbuf);
+ /*
+ * If the delete operation is "deferred" (and technically, any delete
+ * operation not performed by THE DREADED AUTO-PURGER ought to be
+ * a deferred delete) then we save a pointer to the message in the
+ * DELETED_MSGS_ROOM. This will cause the reference count to remain
+ * at least 1, which will save the user from having to synchronously
+ * wait for various disk-intensive operations to complete.
+ */
+ if ( (deferred) && (num_deleted) ) {
+ for (i=0; i<num_deleted; ++i) {
+ CtdlCopyMsgToRoom(dellist[i], DELETED_MSGS_ROOM);
+ }
+ }
+
/* 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
}
delnum = extract_long(delstr, 0);
- num_deleted = CtdlDeleteMessages(CC->room.QRname, delnum, "");
+ num_deleted = CtdlDeleteMessages(CC->room.QRname, delnum, "", 1);
if (num_deleted) {
cprintf("%d %d message%s deleted.\n", CIT_OK,
* if this is a 'move' rather than a 'copy' operation.
*/
if (is_copy == 0) {
- CtdlDeleteMessages(CC->room.QRname, num, "");
+ CtdlDeleteMessages(CC->room.QRname, num, "", 0);
}
cprintf("%d Message %s.\n", CIT_OK, (is_copy ? "copied" : "moved") );
*/
if (is_unique) {
lprintf(CTDL_DEBUG, "Deleted %d other msgs of this type\n",
- CtdlDeleteMessages(roomname, 0L, content_type));
+ CtdlDeleteMessages(roomname, 0L, content_type, 0)
+ );
}
/* Now write the data */
CtdlSubmitMsg(msg, NULL, roomname);
struct CtdlMessage *compare,
void (*CallBack) (long, void *),
void *userdata);
-int CtdlDeleteMessages(char *, long, char *);
+int CtdlDeleteMessages(char *, long, char *, int);
void CtdlWriteObject(char *, char *, char *, struct ctdluser *,
int, int, unsigned int);
struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body);
/* Delete the messages in the room
* (Careful: this opens an S_ROOMS critical section!)
*/
- CtdlDeleteMessages(qrbuf->QRname, 0L, "");
+ CtdlDeleteMessages(qrbuf->QRname, 0L, "", 0);
/* Flag the room record as not in use */
lgetroom(qrbuf, qrbuf->QRname);
/* Now that we've processed this message, we don't need it
* anymore. So delete it.
*/
- CtdlDeleteMessages(CC->room.QRname, msgnum, "");
+ CtdlDeleteMessages(CC->room.QRname, msgnum, "", 1);
/* Free the memory we allocated and return a response. */
icalcomponent_free(ird.cal);
/* Now that we've processed this message, we don't need it
* anymore. So delete it. (Maybe make this optional?)
*/
- CtdlDeleteMessages(CC->room.QRname, msgnum, "");
+ CtdlDeleteMessages(CC->room.QRname, msgnum, "", 1);
/* Free the memory we allocated and return a response. */
icalcomponent_free(ird.cal);
if (!strncasecmp(buf, "m=", 2)) {
msgnum = atol(&buf[2]);
if (msgnum > 0L) {
- CtdlDeleteMessages(roomname, msgnum, "");
+ CtdlDeleteMessages(roomname, msgnum, "", 0);
}
}
}
for (i = 0; i < IMAP->num_msgs; ++i) {
if (IMAP->flags[i] & IMAP_DELETED) {
CtdlDeleteMessages(CC->room.QRname,
- IMAP->msgids[i], "");
+ IMAP->msgids[i], "", 1);
++num_expunged;
}
}
/* Delete this message if delete-after-send is set */
if (delete_after_send) {
- CtdlDeleteMessages(CC->room.QRname, msgnum, "");
+ CtdlDeleteMessages(CC->room.QRname, msgnum, "", 0);
}
}
if (POP3->num_msgs > 0) for (i=0; i<POP3->num_msgs; ++i) {
if (POP3->msgs[i].deleted) {
CtdlDeleteMessages(MAILROOM,
- POP3->msgs[i].msgnum, "");
+ POP3->msgs[i].msgnum, "", 1);
}
}
* message and the message message.
*/
if (incomplete_deliveries_remaining <= 0) {
- CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "");
- CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, text_msgid, "");
+ CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "", 0);
+ CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, text_msgid, "", 0);
}
* instructions and replace with the updated ones.
*/
if (incomplete_deliveries_remaining > 0) {
- CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "");
+ CtdlDeleteMessages(SMTP_SPOOLOUT_ROOM, msgnum, "", 0);
msg = malloc(sizeof(struct CtdlMessage));
memset(msg, 0, sizeof(struct CtdlMessage));
msg->cm_magic = CTDLMESSAGE_MAGIC;
* vCard in the user's config room at all times.
*/
CtdlDeleteMessages(CC->room.QRname,
- 0L, "text/x-vcard");
+ 0L, "text/x-vcard", 1);
/* Make the author of the message the name of the user.
*/
#define PAGELOGROOM "Sent/Received Pages"
#define SYSCONFIGROOM "Local System Configuration"
#define SMTP_SPOOLOUT_ROOM "__CitadelSMTPspoolout__"
+#define DELETED_MSGS_ROOM "__CitadelDeletedMessages__"
/*
* How long (in seconds) to retain message entries in the use table