1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999-2021 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 #include "mail.h"
18
19 /*
20 * q[uit]
21 * <EOF>
22 */
23
24 int
mail_quit(int argc MU_ARG_UNUSED,char ** argv MU_ARG_UNUSED)25 mail_quit (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
26 {
27 if (mail_mbox_close ())
28 return 1;
29 exit (0);
30 }
31
32 int
mail_mbox_close(void)33 mail_mbox_close (void)
34 {
35 mu_url_t url = NULL;
36 size_t held_count = 0;
37
38 if (!mbox)
39 return 0;
40
41 if (!mailvar_is_true (mailvar_name_readonly))
42 {
43 if (mail_mbox_commit ())
44 return 1;
45
46 mu_mailbox_flush (mbox, 1);
47 }
48
49 mu_mailbox_get_url (mbox, &url);
50 mu_mailbox_messages_count (mbox, &held_count);
51 mu_printf (
52 ngettext ("Held %lu message in %s\n",
53 "Held %lu messages in %s\n",
54 held_count),
55 (unsigned long) held_count, util_url_to_string (url));
56 mu_mailbox_close (mbox);
57 mu_mailbox_destroy (&mbox);
58 return 0;
59 }
60
61 enum mailbox_class
62 {
63 MBX_SYSTEM,
64 MBX_MBOX,
65 MBX_USER
66 };
67
68 static enum mailbox_class
mailbox_classify(void)69 mailbox_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
89 int
mail_mbox_commit(void)90 mail_mbox_commit (void)
91 {
92 unsigned int i;
93 mu_mailbox_t dest_mbox = NULL;
94 int saved_count = 0;
95 mu_message_t msg;
96 mu_attribute_t attr;
97 int keepsave = mailvar_is_true (mailvar_name_keepsave);
98 int hold = mailvar_is_true (mailvar_name_hold);
99
100 enum mailbox_class class = mailbox_classify ();
101 if (class != MBX_SYSTEM)
102 {
103 /* The mailbox we are closing is not a system one (%). Stay on the
104 safe side: retain both read and saved messages in the mailbox. */
105 hold = 1;
106 keepsave = 1;
107 }
108
109 for (i = 1; i <= total; i++)
110 {
111 int status;
112 enum { ACT_KEEP, ACT_MBOX, ACT_DELETE } action = ACT_KEEP;
113
114 if (util_get_message (mbox, i, &msg))
115 return 1;
116
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 }
138
139 switch (action)
140 {
141 case ACT_KEEP:
142 if (mu_attribute_is_read (attr))
143 mu_attribute_set_seen (attr);
144 break;
145
146 case ACT_MBOX:
147 if (!dest_mbox)
148 {
149 char *name = getenv ("MBOX");
150
151 if ((status = mu_mailbox_create_default (&dest_mbox, name)) != 0)
152 {
153 mu_error (_("Cannot create mailbox %s: %s"), name,
154 mu_strerror (status));
155 return 1;
156 }
157 if ((status = mu_mailbox_open (dest_mbox,
158 MU_STREAM_WRITE | MU_STREAM_CREAT))
159 != 0)
160 {
161 mu_error (_("Cannot open mailbox %s: %s"), name,
162 mu_strerror (status));
163 return 1;
164 }
165 }
166
167 status = mu_mailbox_append_message (dest_mbox, msg);
168 if (status)
169 {
170 mu_url_t url = NULL;
171 mu_mailbox_get_url (dest_mbox, &url);
172 mu_error (_("Cannot append message to %s: %s"),
173 util_url_to_string (url),
174 mu_strerror (status));
175 }
176 else
177 {
178 mu_attribute_set_deleted (attr);
179 saved_count++;
180 }
181 break;
182
183 case ACT_DELETE:
184 mu_attribute_set_deleted (attr);
185 break;
186 }
187 }
188
189 if (saved_count)
190 {
191 mu_url_t u = NULL;
192
193 mu_mailbox_get_url (dest_mbox, &u);
194 mu_printf (
195 ngettext ("Saved %d message in %s\n",
196 "Saved %d messages in %s\n",
197 saved_count),
198 saved_count, util_url_to_string (u));
199 mu_mailbox_close (dest_mbox);
200 mu_mailbox_destroy (&dest_mbox);
201 }
202 return 0;
203 }
204