summarylogtreecommitdiffstats
path: root/imap_fast_trash.patch
blob: 670f828edc7ada59a8d8495a235048f4ef55ab86 (plain)
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++)