summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2019-09-10 18:23:06 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2019-09-10 18:23:06 +0300
commit6f8dd761ad8d21a2f69a9f077a4de5d21e99273b (patch)
tree189aa1a5d396ec70013ad7bff43c448814f86f30
parent4e6cf8005d0a1a11baa8b42ea298a24a7d19cc37 (diff)
downloadmailutils-6f8dd761ad8d21a2f69a9f077a4de5d21e99273b.tar.gz
mailutils-6f8dd761ad8d21a2f69a9f077a4de5d21e99273b.tar.bz2
Fix the semantics of the hold and keepsave variables in mail
* mail/delete.c (mail_delete_msg): Set MAIL_ATTRIBUTE_PRESERVED. This is not necessary, stricto sensu, because mail_mbox_close skips messages marked for deletion anyway. But it's good for clarity. * mail/quit.c (mailbox_classify): New function. (mail_mbox_commit): Rewrite * mail/tests/Makefile.am: Add new test * mail/tests/testsuite.at: Include new tests. * mail/tests/atlocal.in (catmbox): New function. * mail/tests/hold.at: New test.
-rw-r--r--mail/delete.c1
-rw-r--r--mail/quit.c116
-rw-r--r--mail/tests/Makefile.am1
-rw-r--r--mail/tests/atlocal.in3
-rw-r--r--mail/tests/copy00.at2
-rw-r--r--mail/tests/hold.at349
-rw-r--r--mail/tests/testsuite.at3
7 files changed, 430 insertions, 45 deletions
diff --git a/mail/delete.c b/mail/delete.c
index 344857246..567fd4e03 100644
--- a/mail/delete.c
+++ b/mail/delete.c
@@ -27,6 +27,7 @@ mail_delete_msg (msgset_t *mspec, mu_message_t msg, void *data)
27 27
28 mu_message_get_attribute (msg, &attr); 28 mu_message_get_attribute (msg, &attr);
29 mu_attribute_set_deleted (attr); 29 mu_attribute_set_deleted (attr);
30 mu_attribute_unset_userflag (attr, MAIL_ATTRIBUTE_PRESERVED);
30 cond_page_invalidate (mspec->msg_part[0]); 31 cond_page_invalidate (mspec->msg_part[0]);
31 return 0; 32 return 0;
32} 33}
diff --git a/mail/quit.c b/mail/quit.c
index 2e8b5a1cd..161582959 100644
--- a/mail/quit.c
+++ b/mail/quit.c
@@ -30,7 +30,7 @@ mail_quit (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
30} 30}
31 31
32int 32int
33mail_mbox_close () 33mail_mbox_close (void)
34{ 34{
35 mu_url_t url = NULL; 35 mu_url_t url = NULL;
36 size_t held_count = 0; 36 size_t held_count = 0;
@@ -58,8 +58,36 @@ mail_mbox_close ()
58 return 0; 58 return 0;
59} 59}
60 60
61enum mailbox_class
62 {
63 MBX_SYSTEM,
64 MBX_MBOX,
65 MBX_USER
66 };
67
68static enum mailbox_class
69mailbox_classify (void)
70{
71 mu_url_t url;
72
73 mu_mailbox_get_url (mbox, &url);
74 if (strcmp (util_url_to_string (url), getenv ("MBOX")) == 0)
75 return MBX_MBOX;
76 else
77 {
78 mu_mailbox_t mb;
79 mu_url_t u;
80 mu_mailbox_create_default (&mb, NULL);
81 mu_mailbox_get_url (mb, &u);
82 if (strcmp (mu_url_to_string (u), mu_url_to_string (url)) == 0)
83 return MBX_SYSTEM;
84 }
85
86 return MBX_USER;
87}
88
61int 89int
62mail_mbox_commit () 90mail_mbox_commit (void)
63{ 91{
64 unsigned int i; 92 unsigned int i;
65 mu_mailbox_t dest_mbox = NULL; 93 mu_mailbox_t dest_mbox = NULL;
@@ -68,49 +96,54 @@ mail_mbox_commit ()
68 mu_attribute_t attr; 96 mu_attribute_t attr;
69 int keepsave = mailvar_is_true (mailvar_name_keepsave); 97 int keepsave = mailvar_is_true (mailvar_name_keepsave);
70 int hold = mailvar_is_true (mailvar_name_hold); 98 int hold = mailvar_is_true (mailvar_name_hold);
71 mu_url_t url;
72 int is_user_mbox;
73 99
74 mu_mailbox_get_url (mbox, &url); 100 enum mailbox_class class = mailbox_classify ();
75 is_user_mbox = strcmp (util_url_to_string (url), getenv ("MBOX")) == 0; 101 if (class != MBX_SYSTEM)
76 102 {
77 { 103 /* The mailbox we are closing is not a system one (%). Stay on the
78 mu_mailbox_t mb; 104 safe side: retain both read and saved messages in the mailbox. */
79 mu_url_t u; 105 hold = 1;
80 mu_mailbox_create_default (&mb, NULL); 106 keepsave = 1;
81 mu_mailbox_get_url (mb, &u); 107 }
82 if (strcmp (mu_url_to_string (u), mu_url_to_string (url)) != 0)
83 {
84 /* The mailbox we are closing is not a system one (%). Raise
85 hold flag */
86 hold = 1;
87 keepsave = 1;
88 }
89 mu_mailbox_destroy (&mb);
90 }
91 108
92 for (i = 1; i <= total; i++) 109 for (i = 1; i <= total; i++)
93 { 110 {
111 int status;
112 enum { ACT_KEEP, ACT_MBOX, ACT_DELETE } action = ACT_KEEP;
113
94 if (util_get_message (mbox, i, &msg)) 114 if (util_get_message (mbox, i, &msg))
95 return 1; 115 return 1;
96 116
97 mu_message_get_attribute (msg, &attr); 117 mu_message_get_attribute (msg, &attr);
118 if (mu_attribute_is_deleted (attr))
119 continue;
120
121 if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_PRESERVED))
122 action = ACT_KEEP;
123 else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_MBOXED))
124 action = ACT_MBOX;
125 else if (class == MBX_SYSTEM)
126 {
127 if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SHOWN
128 | MAIL_ATTRIBUTE_TOUCHED))
129 action = hold ? ACT_KEEP : ACT_MBOX;
130 else if (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED))
131 {
132 if (keepsave)
133 action = hold ? ACT_KEEP : ACT_MBOX;
134 else
135 action = ACT_DELETE;
136 }
137 }
98 138
99 if (!is_user_mbox 139 switch (action)
100 && (mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_MBOXED)
101 || (!hold
102 && !mu_attribute_is_deleted (attr)
103 && !mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_PRESERVED)
104 && ((mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED)
105 && keepsave)
106 || (!mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED)
107 && (mu_attribute_is_userflag (attr,
108 MAIL_ATTRIBUTE_SHOWN)
109 || mu_attribute_is_userflag (attr,
110 MAIL_ATTRIBUTE_TOUCHED)))))))
111 { 140 {
112 int status; 141 case ACT_KEEP:
113 142 if (mu_attribute_is_read (attr))
143 mu_attribute_set_seen (attr);
144 break;
145
146 case ACT_MBOX:
114 if (!dest_mbox) 147 if (!dest_mbox)
115 { 148 {
116 char *name = getenv ("MBOX"); 149 char *name = getenv ("MBOX");
@@ -139,15 +172,12 @@ mail_mbox_commit ()
139 mu_attribute_set_deleted (attr); 172 mu_attribute_set_deleted (attr);
140 saved_count++; 173 saved_count++;
141 } 174 }
175 break;
176
177 case ACT_DELETE:
178 mu_attribute_set_deleted (attr);
179 break;
142 } 180 }
143 else if (mu_attribute_is_deleted (attr))
144 /* Skip this one */;
145 else if (!keepsave
146 && !mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_PRESERVED)
147 && mu_attribute_is_userflag (attr, MAIL_ATTRIBUTE_SAVED))
148 mu_attribute_set_deleted (attr);
149 else if (mu_attribute_is_read (attr))
150 mu_attribute_set_seen (attr);
151 } 181 }
152 182
153 if (saved_count) 183 if (saved_count)
diff --git a/mail/tests/Makefile.am b/mail/tests/Makefile.am
index 867ca1856..bf3762f7f 100644
--- a/mail/tests/Makefile.am
+++ b/mail/tests/Makefile.am
@@ -49,6 +49,7 @@ TESTSUITE_AT =\
49 copy03.at\ 49 copy03.at\
50 copy04.at\ 50 copy04.at\
51 nohome.at\ 51 nohome.at\
52 hold.at\
52 testsuite.at\ 53 testsuite.at\
53 version.at 54 version.at
54 55
diff --git a/mail/tests/atlocal.in b/mail/tests/atlocal.in
index f8b2cc84d..80e3ea021 100644
--- a/mail/tests/atlocal.in
+++ b/mail/tests/atlocal.in
@@ -6,3 +6,6 @@ PATH=@abs_builddir@:@abs_top_builddir@/mail:$top_srcdir:$srcdir:$PATH
6testsuitedir=@abs_top_srcdir@/testsuite 6testsuitedir=@abs_top_srcdir@/testsuite
7MALLOC_CHECK_=2 7MALLOC_CHECK_=2
8export MALLOC_CHECK_ 8export MALLOC_CHECK_
9catmbox() {
10 sed -e /^X-IMAPbase:/d -e /^X-UID:/d $1
11}
diff --git a/mail/tests/copy00.at b/mail/tests/copy00.at
index ae003dd01..21f60d574 100644
--- a/mail/tests/copy00.at
+++ b/mail/tests/copy00.at
@@ -27,7 +27,7 @@ test -f /dev/stdout || AT_SKIP_TEST
27MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox) 27MUT_MBCOPY($abs_top_srcdir/testsuite/spool/mbox)
28echo 'copy 1 /dev/stdout' | \ 28echo 'copy 1 /dev/stdout' | \
29 MUT_MAIL_CMD -N -E 'set readonly' -f ./mbox 2>err | \ 29 MUT_MAIL_CMD -N -E 'set readonly' -f ./mbox 2>err | \
30 sed 's/ *$//;/^Held 1 message/d' 30 sed -e 's/ *$//' -e '/^Held 1 message/d'
31 31
32if test -s err; then 32if test -s err; then
33 # On OSX. /dev/stdout cannot be locked. 33 # On OSX. /dev/stdout cannot be locked.
diff --git a/mail/tests/hold.at b/mail/tests/hold.at
new file mode 100644
index 000000000..1bf2531e8
--- /dev/null
+++ b/mail/tests/hold.at
@@ -0,0 +1,349 @@
1# This file is part of GNU Mailutils. -*- Autotest -*-
2# Copyright (C) 2015-2019 Free Software Foundation, Inc.
3#
4# GNU Mailutils is free software; you can redistribute it and/or
5# modify it under the terms of the GNU General Public License as
6# published by the Free Software Foundation; either version 3, or (at
7# your option) any later version.
8#
9# GNU Mailutils is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU