* Interactive room deletions are now deferred. The server reconfigures the
authorArt Cancro <ajc@citadel.org>
Mon, 9 May 2005 22:17:30 +0000 (22:17 +0000)
committerArt Cancro <ajc@citadel.org>
Mon, 9 May 2005 22:17:30 +0000 (22:17 +0000)
  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
citadel/room_ops.c
citadel/room_ops.h
citadel/serv_imap.c

index 398e62aefb2db19ed632f12e33a994ec93b5a9e2..1348df277de39fe138a7316e5a75a49de45132e7 100644 (file)
@@ -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 <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
+
index abdb7b5cdc5ef692922cb89c6b3535b90c2e1192..f383686064f2d4cd98140db4f3621de56e66bc08 100644 (file)
@@ -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);
index 549459c60c5514e30b96decc0d229a7bfb34b7f6..f5b820a7fd23a95713fbe0243f751279ed606d20 100644 (file)
@@ -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);
index 2893bbff9e8628572652ee0cb584481b0ad91006..d40ca8745cac46f6c74d71ddb058a89a8ac6bdce 100644 (file)
@@ -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]);