1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
From: Antonio Radici <antonio@debian.org>
Date: Thu, 27 Feb 2014 14:29:03 +0100
Subject: imap_fast_trash
Make "move to trash folder" use IMAP COPY.
By Paul Miller
Gbp-Pq: Topic features
---
imap/imap.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
imap/imap.h | 3 +++
mx.c | 5 +++++
3 files changed, 65 insertions(+)
diff --git a/imap/imap.c b/imap/imap.c
index ad15f5e..f476873 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -885,6 +885,12 @@ static int imap_make_msg_set (IMAP_DATA* idata, BUFFER* buf, int flag,
if (hdrs[n]->deleted != HEADER_DATA(hdrs[n])->deleted)
match = invert ^ hdrs[n]->deleted;
break;
+ case M_EXPIRED: /* imap_fast_trash version of M_DELETED */
+ if (hdrs[n]->purged)
+ break;
+ if (hdrs[n]->deleted != HEADER_DATA(hdrs[n])->deleted)
+ match = invert ^ (hdrs[n]->deleted && !hdrs[n]->appended);
+ break;
case M_FLAG:
if (hdrs[n]->flagged != HEADER_DATA(hdrs[n])->flagged)
match = invert ^ hdrs[n]->flagged;
@@ -2026,3 +2032,54 @@ int imap_complete(char* dest, size_t dlen, char* path) {
return -1;
}
+
+int imap_fast_trash() {
+
+ if( Context->magic == M_IMAP && mx_is_imap(TrashPath) ) {
+ IMAP_MBOX mx;
+ IMAP_DATA *idata = (IMAP_DATA *) Context->data;
+ char mbox[LONG_STRING];
+ char mmbox[LONG_STRING];
+ int rc;
+ dprint(1, (debugfile, "[itf] trashcan seems to be on imap.\n"));
+
+ if ( imap_parse_path(TrashPath, &mx) == 0 ) {
+ if( mutt_account_match(&(idata->conn->account), &(mx.account)) ) {
+ dprint(1, (debugfile, "[itf] trashcan seems to be on the same account.\n"));
+
+ imap_fix_path (idata, mx.mbox, mbox, sizeof (mbox));
+ if (!*mbox)
+ strfcpy (mbox, "INBOX", sizeof (mbox));
+ imap_munge_mbox_name (mmbox, sizeof (mmbox), mbox);
+
+ rc = imap_exec_msgset (idata, "UID COPY", mmbox, M_EXPIRED, 0, 0);
+ if (!rc) {
+ dprint (1, (debugfile, "imap_copy_messages: No messages del-tagged\n"));
+ rc = -1;
+ goto old_way;
+
+ } else if (rc < 0) {
+ dprint (1, (debugfile, "could not queue copy\n"));
+ goto old_way;
+
+ } else {
+ mutt_message (_("Copying %d messages to %s..."), rc, mbox);
+ return 0;
+ }
+
+ } else {
+ dprint(1, (debugfile, "[itf] trashcan seems to be on a different account.\n"));
+ }
+
+ old_way:
+ FREE (&mx.mbox); /* we probably only need to free this when the parse works */
+
+ } else {
+ dprint(1, (debugfile, "[itf] failed to parse TrashPath.\n" ));
+ }
+
+ dprint(1, (debugfile, "[itf] giving up and trying old fasioned way.\n" ));
+ }
+
+ return 1;
+}
diff --git a/imap/imap.h b/imap/imap.h
index 74d7e13..99cd454 100644
--- a/imap/imap.h
+++ b/imap/imap.h
@@ -72,4 +72,7 @@ void imap_keepalive (void);
int imap_account_match (const ACCOUNT* a1, const ACCOUNT* a2);
+/* trash */
+int imap_fast_trash();
+
#endif
diff --git a/mx.c b/mx.c
index 15c0a6b..fcb781f 100644
--- a/mx.c
+++ b/mx.c
@@ -802,6 +802,11 @@ static int trash_append (CONTEXT *ctx)
&& stc.st_dev == st.st_dev && stc.st_rdev == st.st_rdev)
return 0; /* we are in the trash folder: simple sync */
+ #ifdef USE_IMAP
+ if( !imap_fast_trash() )
+ return 0;
+ #endif
+
if ((ctx_trash = mx_open_mailbox (TrashPath, M_APPEND, NULL)) != NULL)
{
for (i = 0 ; i < ctx->msgcount ; i++)
|