From 4d454acd152e463d5a6614b99e6e5bf12854a094 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 9 May 2005 22:17:30 +0000 Subject: [PATCH] * Interactive room deletions are now deferred. The server reconfigures the room to be a mailbox owned by a nonexistent user and immediately returns control back to the client. Later, THE DREADED AUTO-PURGER will see the dangling room and erase its contents. --- citadel/ChangeLog | 7 +++++++ citadel/room_ops.c | 41 ++++++++++++++++++++++++++++++++++++++++- citadel/room_ops.h | 1 + citadel/serv_imap.c | 2 +- 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 398e62aef..1348df277 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,10 @@ $Log$ + Revision 645.20 2005/05/09 22:17:30 ajc + * Interactive room deletions are now deferred. The server reconfigures the + room to be a mailbox owned by a nonexistent user and immediately returns + control back to the client. Later, THE DREADED AUTO-PURGER will see the + dangling room and erase its contents. + Revision 645.19 2005/05/08 03:43:22 ajc * Set the internal version number to 6.46 in preparation for a release @@ -6664,3 +6670,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import + diff --git a/citadel/room_ops.c b/citadel/room_ops.c index abdb7b5cd..f38368606 100644 --- a/citadel/room_ops.c +++ b/citadel/room_ops.c @@ -1478,8 +1478,47 @@ void cmd_rinf(void) fclose(info_fp); } +/* + * Asynchronously schedule a room for deletion. The room will appear + * deleted to the user(s), but it won't actually get purged from the + * database until THE DREADED AUTO-PURGER makes its next run. + */ +void schedule_room_for_deletion(struct ctdlroom *qrbuf) +{ + char old_name[ROOMNAMELEN]; + static int seq = 0; + + lprintf(CTDL_NOTICE, "Scheduling room <%s> for deletion\n", + qrbuf->QRname); + + safestrncpy(old_name, qrbuf->QRname, sizeof old_name); + + getroom(qrbuf, qrbuf->QRname); + + /* Turn the room into a private mailbox owned by a user who doesn't + * exist. This will immediately make the room invisible to everyone, + * and qualify the room for purging. + */ + snprintf(qrbuf->QRname, sizeof qrbuf->QRname, "9999999999.%08lx.%04d.%s", + time(NULL), + ++seq, + old_name + ); + qrbuf->QRflags |= QR_MAILBOX; + time(&qrbuf->QRgen); /* Use a timestamp as the new generation number */ + + putroom(qrbuf); + + b_deleteroom(old_name); +} + + + /* * Back end processing to delete a room and everything associated with it + * (This one is synchronous and should only get called by THE DREADED + * AUTO-PURGER in serv_expire.c. All user-facing code should call + * the asynchronous schedule_room_for_deletion() instead.) */ void delete_room(struct ctdlroom *qrbuf) { @@ -1582,7 +1621,7 @@ void cmd_kill(char *argbuf) } /* Do the dirty work */ - delete_room(&CC->room); + schedule_room_for_deletion(&CC->room); /* Return to the Lobby */ usergoto(config.c_baseroom, 0, 0, NULL, NULL); diff --git a/citadel/room_ops.h b/citadel/room_ops.h index 549459c60..f5b820a7f 100644 --- a/citadel/room_ops.h +++ b/citadel/room_ops.h @@ -51,6 +51,7 @@ void ForEachRoom(void (*CallBack)(struct ctdlroom *EachRoom, void *out_data), void *in_data); void assoc_file_name(char *buf, size_t n, struct ctdlroom *qrbuf, const char *prefix); +void schedule_room_for_deletion(struct ctdlroom *qrbuf); void delete_room(struct ctdlroom *qrbuf); void list_roomname(struct ctdlroom *qrbuf, int ra, int view); int is_noneditable(struct ctdlroom *qrbuf); diff --git a/citadel/serv_imap.c b/citadel/serv_imap.c index 2893bbff9..d40ca8745 100644 --- a/citadel/serv_imap.c +++ b/citadel/serv_imap.c @@ -1184,7 +1184,7 @@ void imap_delete(int num_parms, char *parms[]) * Now delete the room. */ if (CtdlDoIHavePermissionToDeleteThisRoom(&CC->room)) { - delete_room(&CC->room); + schedule_room_for_deletion(&CC->room); cprintf("%s OK DELETE completed\r\n", parms[0]); } else { cprintf("%s NO Can't delete this folder.\r\n", parms[0]); -- 2.39.2