Browse Source

make use of UID EXPUNGE

Oswald Buddenhagen 13 năm trước cách đây
mục cha
commit
18225344c6
2 tập tin đã thay đổi với 40 bổ sung10 xóa
  1. 34 4
      src/drv_imap.c
  2. 6 6
      src/mbsync.1

+ 34 - 4
src/drv_imap.c

@@ -1671,13 +1671,43 @@ imap_set_flags_p2( imap_store_t *ctx ATTR_UNUSED, struct imap_cmd *cmd, int resp
 /******************* imap_close *******************/
 /******************* imap_close *******************/
 
 
 static void
 static void
-imap_close( store_t *ctx,
+imap_close( store_t *gctx,
             void (*cb)( int sts, void *aux ), void *aux )
             void (*cb)( int sts, void *aux ), void *aux )
 {
 {
-	struct imap_cmd_simple *cmd;
+	imap_store_t *ctx = (imap_store_t *)gctx;
 
 
-	INIT_IMAP_CMD(imap_cmd_simple, cmd, cb, aux)
-	imap_exec( (imap_store_t *)ctx, &cmd->gen, imap_done_simple_box, "CLOSE" );
+	if (CAP(UIDPLUS)) {
+		struct imap_cmd_refcounted_state *sts = imap_refcounted_new_state( cb, aux );
+		message_t *msg, *fmsg, *nmsg;
+		int bl;
+		char buf[1000];
+
+		for (msg = ctx->gen.msgs; ; ) {
+			for (bl = 0; msg && bl < 960; msg = msg->next) {
+				if (!(msg->flags & F_DELETED))
+					continue;
+				if (bl)
+					buf[bl++] = ',';
+				bl += sprintf( buf + bl, "%d", msg->uid );
+				fmsg = msg;
+				for (; (nmsg = msg->next) && (nmsg->flags & F_DELETED); msg = nmsg) {}
+				if (msg != fmsg)
+					bl += sprintf( buf + bl, ":%d", msg->uid );
+			}
+			if (!bl)
+				break;
+			if (imap_exec( ctx, imap_refcounted_new_cmd( sts ), imap_refcounted_done_box,
+			               "UID EXPUNGE %s", buf ) < 0)
+				break;
+		}
+		imap_refcounted_done( sts );
+	} else {
+		/* This is inherently racy: it may cause messages which other clients
+		 * marked as deleted to be expunged without being trashed. */
+		struct imap_cmd_simple *cmd;
+		INIT_IMAP_CMD(imap_cmd_simple, cmd, cb, aux)
+		imap_exec( ctx, &cmd->gen, imap_done_simple_box, "CLOSE" );
+	}
 }
 }
 
 
 /******************* imap_trash_msg *******************/
 /******************* imap_trash_msg *******************/

+ 6 - 6
src/mbsync.1

@@ -484,13 +484,13 @@ times within a Group.
 .SH INHERENT PROBLEMS
 .SH INHERENT PROBLEMS
 Changes done after \fBmbsync\fR has retrieved the message list will not be
 Changes done after \fBmbsync\fR has retrieved the message list will not be
 synchronised until the next time \fBmbsync\fR is invoked.
 synchronised until the next time \fBmbsync\fR is invoked.
-..
-.SH BUGS
-Using \fBTrash\fR on IMAP Stores bears a race condition: messages will be
+.P
+Using \fBTrash\fR on IMAP Stores without the UIDPLUS extension (notably,
+M$ Exchange up to at least 2010) bears a race condition: messages will be
 lost if they are marked as deleted after the message list was retrieved but
 lost if they are marked as deleted after the message list was retrieved but
-before the mailbox is expunged. This can be fixed by using UID EXPUNGE.
-There is no risk as long as the IMAP mailbox is not simultaneously accessed
-by \fBmbsync\fR and another mail client.
+before the mailbox is expunged.
+There is no risk as long as the IMAP mailbox is accessed by only one client
+(including \fBmbsync\fR) at a time.
 ..
 ..
 .SH FILES
 .SH FILES
 .TP
 .TP