NeoMutt  2023-11-03-107-g582dc1
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
lib.h File Reference

Postponed Emails. More...

#include <stdbool.h>
#include "ncrypt/lib.h"
+ Include dependency graph for lib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

struct Emaildlg_postponed (struct Mailbox *m)
 Create a Menu to select a postponed message -.
 
int mutt_get_postponed (struct Mailbox *m_cur, struct Email *hdr, struct Email **cur, struct Buffer *fcc)
 Recall a postponed message.
 
int mutt_num_postponed (struct Mailbox *m, bool force)
 Return the number of postponed messages.
 
SecurityFlags mutt_parse_crypt_hdr (const char *p, bool set_empty_signas, SecurityFlags crypt_app)
 Parse a crypto header string.
 
int mutt_prepare_template (FILE *fp, struct Mailbox *m, struct Email *e_new, struct Email *e, bool resend)
 Prepare a message template.
 
void mutt_update_num_postponed (void)
 Force the update of the number of postponed messages.
 
struct MailboxViewpostponed_get_mailbox_view (struct MuttWindow *dlg)
 Extract the Mailbox from the Postponed Dialog.
 

Detailed Description

Postponed Emails.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file lib.h.

Function Documentation

◆ mutt_get_postponed()

int mutt_get_postponed ( struct Mailbox m_cur,
struct Email hdr,
struct Email **  cur,
struct Buffer fcc 
)

Recall a postponed message.

Parameters
[in]m_curCurrent mailbox
[in]hdrenvelope/attachment info for recalled message
[out]curif message was a reply, 'cur' is set to the message which 'hdr' is in reply to
[in]fccfcc for the recalled message
Return values
-1Error/no messages
0Normal exit
SEND_REPLYRecalled message is a reply

Definition at line 655 of file postpone.c.

657{
658 const char *const c_postponed = cs_subset_string(NeoMutt->sub, "postponed");
659 if (!c_postponed)
660 return -1;
661
662 struct Email *e = NULL;
663 int rc = SEND_POSTPONED;
664 const char *p = NULL;
665
666 struct Mailbox *m = mx_path_resolve(c_postponed);
667 if (m_cur != m)
668 {
669 if (!mx_mbox_open(m, MUTT_NOSORT))
670 {
671 PostCount = 0;
672 mutt_error(_("No postponed messages"));
673 mailbox_free(&m);
674 return -1;
675 }
676 }
677
678 mx_mbox_check(m);
679
680 if (m->msg_count == 0)
681 {
682 PostCount = 0;
683 mutt_error(_("No postponed messages"));
684 if (m_cur != m)
685 {
686 mx_fastclose_mailbox(m, false);
687 mailbox_free(&m);
688 }
689 return -1;
690 }
691
692 /* avoid the "purge deleted messages" prompt */
693 const enum QuadOption c_delete = cs_subset_quad(NeoMutt->sub, "delete");
694 cs_subset_str_native_set(NeoMutt->sub, "delete", MUTT_YES, NULL);
695
696 if (m->msg_count == 1)
697 {
698 /* only one message, so just use that one. */
699 e = m->emails[0];
700 }
701 else if (!(e = dlg_postponed(m)))
702 {
703 rc = -1;
704 goto cleanup;
705 }
706
707 if (mutt_prepare_template(NULL, m, hdr, e, false) < 0)
708 {
709 rc = -1;
710 goto cleanup;
711 }
712
713 /* finished with this message, so delete it. */
714 mutt_set_flag(m, e, MUTT_DELETE, true, true);
715 mutt_set_flag(m, e, MUTT_PURGE, true, true);
716
717 /* update the count for the status display */
719
720 struct ListNode *np = NULL, *tmp = NULL;
721 STAILQ_FOREACH_SAFE(np, &hdr->env->userhdrs, entries, tmp)
722 {
723 size_t plen = 0;
724 // Check for header names: most specific first
725 if ((plen = mutt_istr_startswith(np->data, "X-Mutt-References:")) ||
726 (plen = mutt_istr_startswith(np->data, "Mutt-References:")))
727 {
728 /* if a mailbox is currently open, look to see if the original message
729 * the user attempted to reply to is in this mailbox */
730 if (m_cur)
731 {
732 p = mutt_str_skip_email_wsp(np->data + plen);
733 if (!m_cur->id_hash)
734 m_cur->id_hash = mutt_make_id_hash(m_cur);
735 *cur = mutt_hash_find(m_cur->id_hash, p);
736
737 if (*cur)
738 rc |= SEND_REPLY;
739 }
740 }
741 // Check for header names: most specific first
742 else if ((plen = mutt_istr_startswith(np->data, "X-Mutt-Fcc:")) ||
743 (plen = mutt_istr_startswith(np->data, "Mutt-Fcc:")))
744 {
745 p = mutt_str_skip_email_wsp(np->data + plen);
746 buf_strcpy(fcc, p);
748
749 /* note that mutt-fcc was present. we do this because we want to add a
750 * default fcc if the header was missing, but preserve the request of the
751 * user to not make a copy if the header field is present, but empty. */
752 rc |= SEND_POSTPONED_FCC;
753 }
754 // Check for header names: most specific first
755 else if (((WithCrypto & APPLICATION_PGP) != 0) &&
756 ((plen = mutt_istr_startswith(np->data, "X-Mutt-PGP:")) ||
757 (plen = mutt_istr_startswith(np->data, "Mutt-PGP:")) ||
758 (plen = mutt_istr_startswith(np->data, "Pgp:"))))
759 {
760 hdr->security = mutt_parse_crypt_hdr(np->data + plen, true, APPLICATION_PGP);
762 }
763 // Check for header names: most specific first
764 else if (((WithCrypto & APPLICATION_SMIME) != 0) &&
765 ((plen = mutt_istr_startswith(np->data, "X-Mutt-SMIME:")) ||
766 (plen = mutt_istr_startswith(np->data, "Mutt-SMIME:"))))
767 {
768 hdr->security = mutt_parse_crypt_hdr(np->data + plen, true, APPLICATION_SMIME);
770 }
771#ifdef MIXMASTER
772 // Check for header names: most specific first
773 else if ((plen = mutt_istr_startswith(np->data, "X-Mutt-Mix:")) ||
774 (plen = mutt_istr_startswith(np->data, "Mutt-Mix:")))
775 {
776 mutt_list_free(&hdr->chain);
777
778 char *t = strtok(np->data + plen, " \t\n");
779 while (t)
780 {
782 t = strtok(NULL, " \t\n");
783 }
784 }
785#endif
786 else
787 {
788 // skip header removal
789 continue;
790 }
791
792 // remove the header
793 STAILQ_REMOVE(&hdr->env->userhdrs, np, ListNode, entries);
794 FREE(&np->data);
795 FREE(&np);
796 }
797
798 const bool c_crypt_opportunistic_encrypt = cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt");
799 if (c_crypt_opportunistic_encrypt)
801
802cleanup:
803 if (m_cur != m)
804 {
805 hardclose(m);
806 mailbox_free(&m);
807 }
808
809 cs_subset_str_native_set(NeoMutt->sub, "delete", c_delete, NULL);
810 return rc;
811}
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:407
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:292
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:193
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:48
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1034
void mutt_set_flag(struct Mailbox *m, struct Email *e, enum MessageType flag, bool bf, bool upd_mbox)
Set a flag on an email.
Definition: flags.c:53
struct Email * dlg_postponed(struct Mailbox *m)
Create a Menu to select a postponed message -.
Definition: dlg_postpone.c:202
#define mutt_error(...)
Definition: logging2.h:92
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:362
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:90
#define FREE(x)
Definition: memory.h:45
#define _(a)
Definition: message.h:28
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:251
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:680
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:240
@ MUTT_PURGE
Messages to be purged (bypass trash)
Definition: mutt.h:76
@ MUTT_DELETE
Messages to be deleted.
Definition: mutt.h:74
struct HashTable * mutt_make_id_hash(struct Mailbox *m)
Create a Hash Table for message-ids.
Definition: mutt_thread.c:1699
void buf_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:556
void mx_fastclose_mailbox(struct Mailbox *m, bool keep_account)
Free up memory associated with the Mailbox.
Definition: mx.c:410
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:284
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1641
enum MxStatus mx_mbox_check(struct Mailbox *m)
Check for new mail - Wrapper for MxOps::mbox_check()
Definition: mx.c:1099
#define MUTT_NOSORT
Do not sort the mailbox after opening it.
Definition: mxapi.h:41
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:91
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:92
#define WithCrypto
Definition: lib.h:117
SecurityFlags mutt_parse_crypt_hdr(const char *p, bool set_empty_signas, SecurityFlags crypt_app)
Parse a crypto header string.
Definition: postpone.c:202
short PostCount
Number of postponed (draft) emails.
Definition: postpone.c:56
int mutt_prepare_template(FILE *fp, struct Mailbox *m, struct Email *e_new, struct Email *e, bool resend)
Prepare a message template.
Definition: postpone.c:481
static void hardclose(struct Mailbox *m)
Try hard to close a mailbox.
Definition: postpone.c:184
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:39
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:402
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
#define SEND_POSTPONED_FCC
Used by mutt_get_postponed() to signal that the Mutt-Fcc header field was present.
Definition: send.h:48
#define SEND_POSTPONED
Recall a postponed email.
Definition: send.h:44
#define SEND_REPLY
Reply to sender.
Definition: send.h:40
The envelope/body of an email.
Definition: email.h:37
struct Envelope * env
Envelope information.
Definition: email.h:66
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:41
struct ListHead chain
Mixmaster chain.
Definition: email.h:91
struct ListHead userhdrs
user defined headers
Definition: envelope.h:85
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36
A mailbox.
Definition: mailbox.h:79
int msg_count
Total number of messages.
Definition: mailbox.h:88
struct Email ** emails
Array of Emails.
Definition: mailbox.h:96
struct HashTable * id_hash
Hash Table: "message-id" -> Email.
Definition: mailbox.h:122
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:93
Container for Accounts, Notifications.
Definition: neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:304
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_num_postponed()

int mutt_num_postponed ( struct Mailbox m,
bool  force 
)

Return the number of postponed messages.

Parameters
mcurrently selected mailbox
force
  • false Use a cached value if costly to get a fresh count (IMAP)
  • true Force check
Return values
numPostponed messages

Definition at line 68 of file postpone.c.

69{
70 struct stat st = { 0 };
71
72 static time_t LastModify = 0;
73 static char *OldPostponed = NULL;
74
76 {
77 UpdateNumPostponed = false;
78 force = true;
79 }
80
81 const char *const c_postponed = cs_subset_string(NeoMutt->sub, "postponed");
82 if (!mutt_str_equal(c_postponed, OldPostponed))
83 {
84 FREE(&OldPostponed);
85 OldPostponed = mutt_str_dup(c_postponed);
86 LastModify = 0;
87 force = true;
88 }
89
90 if (!c_postponed)
91 return 0;
92
93 // We currently are in the `$postponed` mailbox so just pick the current status
94 if (m && mutt_str_equal(c_postponed, m->realpath))
95 {
97 return PostCount;
98 }
99
100 /* LastModify is useless for IMAP */
101 if (imap_path_probe(c_postponed, NULL) == MUTT_IMAP)
102 {
103 if (force)
104 {
105 short newpc;
106
107 newpc = imap_path_status(c_postponed, false);
108 if (newpc >= 0)
109 {
110 PostCount = newpc;
111 mutt_debug(LL_DEBUG3, "%d postponed IMAP messages found\n", PostCount);
112 }
113 else
114 {
115 mutt_debug(LL_DEBUG3, "using old IMAP postponed count\n");
116 }
117 }
118 return PostCount;
119 }
120
121 if (stat(c_postponed, &st) == -1)
122 {
123 PostCount = 0;
124 LastModify = 0;
125 return 0;
126 }
127
128 if (S_ISDIR(st.st_mode))
129 {
130 /* if we have a maildir mailbox, we need to stat the "new" dir */
131 struct Buffer *buf = buf_pool_get();
132
133 buf_printf(buf, "%s/new", c_postponed);
134 if ((access(buf_string(buf), F_OK) == 0) && (stat(buf_string(buf), &st) == -1))
135 {
136 PostCount = 0;
137 LastModify = 0;
138 buf_pool_release(&buf);
139 return 0;
140 }
141 buf_pool_release(&buf);
142 }
143
144 if (LastModify < st.st_mtime)
145 {
146 int optnews = OptNews;
147 LastModify = st.st_mtime;
148
149 if (access(c_postponed, R_OK | F_OK) != 0)
150 return PostCount = 0;
151 if (optnews)
152 OptNews = false;
153 struct Mailbox *m_post = mx_path_resolve(c_postponed);
154 if (mx_mbox_open(m_post, MUTT_NOSORT | MUTT_QUIET))
155 {
156 PostCount = m_post->msg_count;
157 mx_fastclose_mailbox(m_post, false);
158 }
159 else
160 {
161 PostCount = 0;
162 }
163 mailbox_free(&m_post);
164
165 if (optnews)
166 OptNews = true;
167 }
168
169 return PostCount;
170}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:173
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:93
bool OptNews
(pseudo) used to change reader mode
Definition: globals.c:75
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe() -.
Definition: imap.c:2327
int imap_path_status(const char *path, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1159
@ LL_DEBUG3
Log at debug level 3.
Definition: logging2.h:45
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:50
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:763
#define MUTT_QUIET
Do not print any messages.
Definition: mxapi.h:44
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
static bool UpdateNumPostponed
When true, force a recount of the postponed (draft) emails.
Definition: postpone.c:58
String manipulation buffer.
Definition: buffer.h:34
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_parse_crypt_hdr()

SecurityFlags mutt_parse_crypt_hdr ( const char *  p,
bool  set_empty_signas,
SecurityFlags  crypt_app 
)

Parse a crypto header string.

Parameters
pHeader string to parse
set_empty_signasAllow an empty "Sign as"
crypt_appApp, e.g. APPLICATION_PGP
Return values
numSecurityFlags, see SecurityFlags

Definition at line 202 of file postpone.c.

203{
204 char smime_cryptalg[1024] = { 0 };
205 char sign_as[1024] = { 0 };
206 char *q = NULL;
208
209 if (!WithCrypto)
210 return SEC_NO_FLAGS;
211
213 for (; p[0] != '\0'; p++)
214 {
215 switch (p[0])
216 {
217 case 'c':
218 case 'C':
219 q = smime_cryptalg;
220
221 if (p[1] == '<')
222 {
223 for (p += 2; (p[0] != '\0') && (p[0] != '>') &&
224 (q < (smime_cryptalg + sizeof(smime_cryptalg) - 1));
225 *q++ = *p++)
226 {
227 }
228
229 if (p[0] != '>')
230 {
231 mutt_error(_("Illegal S/MIME header"));
232 return SEC_NO_FLAGS;
233 }
234 }
235
236 *q = '\0';
237 break;
238
239 case 'e':
240 case 'E':
241 flags |= SEC_ENCRYPT;
242 break;
243
244 case 'i':
245 case 'I':
246 flags |= SEC_INLINE;
247 break;
248
249 /* This used to be the micalg parameter.
250 *
251 * It's no longer needed, so we just skip the parameter in order
252 * to be able to recall old messages. */
253 case 'm':
254 case 'M':
255 if (p[1] != '<')
256 break;
257
258 for (p += 2; (p[0] != '\0') && (p[0] != '>'); p++)
259 ; // do nothing
260
261 if (p[0] != '>')
262 {
263 mutt_error(_("Illegal crypto header"));
264 return SEC_NO_FLAGS;
265 }
266 break;
267
268 case 'o':
269 case 'O':
270 flags |= SEC_OPPENCRYPT;
271 break;
272
273 case 'a':
274 case 'A':
275#ifdef USE_AUTOCRYPT
276 flags |= SEC_AUTOCRYPT;
277#endif
278 break;
279
280 case 'z':
281 case 'Z':
282#ifdef USE_AUTOCRYPT
283 flags |= SEC_AUTOCRYPT_OVERRIDE;
284#endif
285 break;
286
287 case 's':
288 case 'S':
289 flags |= SEC_SIGN;
290 q = sign_as;
291
292 if (p[1] == '<')
293 {
294 for (p += 2;
295 (p[0] != '\0') && (*p != '>') && (q < (sign_as + sizeof(sign_as) - 1));
296 *q++ = *p++)
297 {
298 }
299
300 if (p[0] != '>')
301 {
302 mutt_error(_("Illegal crypto header"));
303 return SEC_NO_FLAGS;
304 }
305 }
306
307 q[0] = '\0';
308 break;
309
310 default:
311 mutt_error(_("Illegal crypto header"));
312 return SEC_NO_FLAGS;
313 }
314 }
315
316 /* the cryptalg field must not be empty */
317 if (((WithCrypto & APPLICATION_SMIME) != 0) && *smime_cryptalg)
318 {
319 struct Buffer errmsg = buf_make(0);
320 int rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
321 smime_cryptalg, &errmsg);
322
323 if ((CSR_RESULT(rc) != CSR_SUCCESS) && !buf_is_empty(&errmsg))
324 mutt_error("%s", buf_string(&errmsg));
325
326 buf_dealloc(&errmsg);
327 }
328
329 /* Set {Smime,Pgp}SignAs, if desired. */
330
331 if (((WithCrypto & APPLICATION_PGP) != 0) && (crypt_app == APPLICATION_PGP) &&
332 (flags & SEC_SIGN) && (set_empty_signas || *sign_as))
333 {
334 cs_subset_str_string_set(NeoMutt->sub, "pgp_sign_as", sign_as, NULL);
335 }
336
337 if (((WithCrypto & APPLICATION_SMIME) != 0) && (crypt_app == APPLICATION_SMIME) &&
338 (flags & SEC_SIGN) && (set_empty_signas || *sign_as))
339 {
340 cs_subset_str_string_set(NeoMutt->sub, "smime_sign_as", sign_as, NULL);
341 }
342
343 return flags;
344}
void buf_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:389
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:303
struct Buffer buf_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:70
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:86
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:88
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: lib.h:77
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:87
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:78
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:79
#define SEC_AUTOCRYPT_OVERRIDE
(Autocrypt) Indicates manual set/unset of encryption
Definition: lib.h:89
#define SEC_SIGN
Email is signed.
Definition: lib.h:80
int cs_subset_str_string_set(const struct ConfigSubset *sub, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
Definition: subset.c:407
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_prepare_template()

int mutt_prepare_template ( FILE *  fp,
struct Mailbox m,
struct Email e_new,
struct Email e,
bool  resend 
)

Prepare a message template.

Parameters
fpIf not NULL, file containing the template
mIf fp is NULL, the Mailbox containing the header with the template
e_newThe template is read into this Header
eEmail to recall/resend
resendSet if resending (as opposed to recalling a postponed msg) Resent messages enable header weeding, and also discard any existing Message-ID and Mail-Followup-To
Return values
0Success
-1Error

Definition at line 481 of file postpone.c.

483{
484 struct Message *msg = NULL;
485 struct Body *b = NULL;
486 FILE *fp_body = NULL;
487 int rc = -1;
488 struct Envelope *protected_headers = NULL;
489 struct Buffer *file = NULL;
490
491 if (!fp && !(msg = mx_msg_open(m, e)))
492 return -1;
493
494 if (!fp)
495 fp = msg->fp;
496
497 fp_body = fp;
498
499 /* parse the message header and MIME structure */
500
501 if (!mutt_file_seek(fp, e->offset, SEEK_SET))
502 {
503 return -1;
504 }
505 e_new->offset = e->offset;
506 /* enable header weeding for resent messages */
507 e_new->env = mutt_rfc822_read_header(fp, e_new, true, resend);
508 e_new->body->length = e->body->length;
509 mutt_parse_part(fp, e_new->body);
510
511 /* If resending a message, don't keep message_id or mail_followup_to.
512 * Otherwise, we are resuming a postponed message, and want to keep those
513 * headers if they exist. */
514 if (resend)
515 {
516 FREE(&e_new->env->message_id);
518 }
519
520 SecurityFlags sec_type = SEC_NO_FLAGS;
521 if (((WithCrypto & APPLICATION_PGP) != 0) && sec_type == SEC_NO_FLAGS)
522 sec_type = mutt_is_multipart_encrypted(e_new->body);
523 if (((WithCrypto & APPLICATION_SMIME) != 0) && sec_type == SEC_NO_FLAGS)
524 sec_type = mutt_is_application_smime(e_new->body);
525 if (sec_type != SEC_NO_FLAGS)
526 {
527 e_new->security |= sec_type;
528 if (!crypt_valid_passphrase(sec_type))
529 goto bail;
530
531 mutt_message(_("Decrypting message..."));
532 int ret = -1;
533 if (sec_type & APPLICATION_PGP)
534 ret = crypt_pgp_decrypt_mime(fp, &fp_body, e_new->body, &b);
535 else if (sec_type & APPLICATION_SMIME)
536 ret = crypt_smime_decrypt_mime(fp, &fp_body, e_new->body, &b);
537 if ((ret == -1) || !b)
538 {
539 mutt_error(_("Could not decrypt postponed message"));
540 goto bail;
541 }
542
543 /* throw away the outer layer and keep only the (now decrypted) inner part
544 * with its headers. */
545 mutt_body_free(&e_new->body);
546 e_new->body = b;
547
548 if (b->mime_headers)
549 {
550 protected_headers = b->mime_headers;
551 b->mime_headers = NULL;
552 }
553
555 }
556
557 /* remove a potential multipart/signed layer - useful when
558 * resending messages */
559 if ((WithCrypto != 0) && mutt_is_multipart_signed(e_new->body))
560 {
561 e_new->security |= SEC_SIGN;
562 if (((WithCrypto & APPLICATION_PGP) != 0) &&
563 mutt_istr_equal(mutt_param_get(&e_new->body->parameter, "protocol"), "application/pgp-signature"))
564 {
565 e_new->security |= APPLICATION_PGP;
566 }
567 else if (WithCrypto & APPLICATION_SMIME)
568 {
569 e_new->security |= APPLICATION_SMIME;
570 }
571
572 /* destroy the signature */
573 mutt_body_free(&e_new->body->parts->next);
574 e_new->body = mutt_remove_multipart(e_new->body);
575
576 if (e_new->body->mime_headers)
577 {
578 mutt_env_free(&protected_headers);
579 protected_headers = e_new->body->mime_headers;
580 e_new->body->mime_headers = NULL;
581 }
582 }
583
584 /* We don't need no primary multipart/mixed. */
585 if ((e_new->body->type == TYPE_MULTIPART) && mutt_istr_equal(e_new->body->subtype, "mixed"))
586 e_new->body = mutt_remove_multipart(e_new->body);
587
588 file = buf_pool_get();
589
590 /* create temporary files for all attachments */
591 if (create_tmp_files_for_attachments(fp_body, file, e_new, e_new->body, protected_headers) < 0)
592 {
593 goto bail;
594 }
595
596 const bool c_crypt_protected_headers_read = cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_read");
597 if (c_crypt_protected_headers_read && protected_headers && protected_headers->subject &&
598 !mutt_str_equal(e_new->env->subject, protected_headers->subject))
599 {
600 mutt_str_replace(&e_new->env->subject, protected_headers->subject);
601 }
602 mutt_env_free(&protected_headers);
603
604 /* Fix encryption flags. */
605
606 /* No inline if multipart. */
607 if ((WithCrypto != 0) && (e_new->security & SEC_INLINE) && e_new->body->next)
608 e_new->security &= ~SEC_INLINE;
609
610 /* Do we even support multiple mechanisms? */
612
613 /* Theoretically, both could be set. Take the one the user wants to set by default. */
614 if ((e_new->security & APPLICATION_PGP) && (e_new->security & APPLICATION_SMIME))
615 {
616 const bool c_smime_is_default = cs_subset_bool(NeoMutt->sub, "smime_is_default");
617 if (c_smime_is_default)
618 e_new->security &= ~APPLICATION_PGP;
619 else
620 e_new->security &= ~APPLICATION_SMIME;
621 }
622
624
625 rc = 0;
626
627bail:
628
629 /* that's it. */
630 buf_pool_release(&file);
631 if (fp_body != fp)
632 mutt_file_fclose(&fp_body);
633 if (msg)
634 mx_msg_close(m, &msg);
635
636 if (rc == -1)
637 {
638 mutt_env_free(&e_new->env);
639 mutt_body_free(&e_new->body);
640 }
641
642 return rc;
643}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1461
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:397
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition: crypt.c:598
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:135
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:432
int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:211
int crypt_smime_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:433
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition: parse.c:1760
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
Parses an RFC822 header.
Definition: parse.c:1156
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:97
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition: file.c:733
#define mutt_message(...)
Definition: logging2.h:91
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition: mime.h:37
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: multipart.c:126
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:775
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:327
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:73
int mx_msg_close(struct Mailbox *m, struct Message **ptr)
Close a message.
Definition: mx.c:1185
struct Message * mx_msg_open(struct Mailbox *m, struct Email *e)
Return a stream pointer for a message.
Definition: mx.c:1139
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
static int create_tmp_files_for_attachments(FILE *fp_body, struct Buffer *file, struct Email *e_new, struct Body *body, struct Envelope *protected_headers)
Create temporary files for all attachments.
Definition: postpone.c:356
void mutt_rfc3676_space_unstuff(struct Email *e)
Remove RFC3676 space stuffing.
Definition: rfc3676.c:496
The body of an email.
Definition: body.h:36
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:72
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:75
LOFF_T length
length (in bytes) of attachment
Definition: body.h:53
struct ParameterList parameter
Parameters of the content-type.
Definition: body.h:62
struct Body * next
next attachment in the list
Definition: body.h:71
char * subtype
content-type subtype
Definition: body.h:60
unsigned int type
content-type primary type, ContentType
Definition: body.h:40
struct Body * body
List of MIME parts.
Definition: email.h:67
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:69
The header of an Email.
Definition: envelope.h:57
char * message_id
Message ID.
Definition: envelope.h:73
struct AddressList mail_followup_to
Email's 'mail-followup-to'.
Definition: envelope.h:65
char * subject
Email's subject.
Definition: envelope.h:70
A local copy of an email.
Definition: message.h:34
FILE * fp
pointer to the message data
Definition: message.h:35
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_update_num_postponed()

void mutt_update_num_postponed ( void  )

Force the update of the number of postponed messages.

Definition at line 175 of file postpone.c.

176{
177 UpdateNumPostponed = true;
178}
+ Here is the caller graph for this function:

◆ postponed_get_mailbox_view()

struct MailboxView * postponed_get_mailbox_view ( struct MuttWindow dlg)

Extract the Mailbox from the Postponed Dialog.

Parameters
dlgPostponed Dialog
Return values
ptrMailbox view

Definition at line 212 of file functions.c.

213{
214 if (!dlg)
215 return NULL;
216
217 struct PostponeData *pd = dlg->wdata;
218 if (!pd)
219 return NULL;
220
221 return pd->mailbox_view;
222}
void * wdata
Private data.
Definition: mutt_window.h:145
Data to pass to the Postpone Functions.
Definition: functions.h:34
struct MailboxView * mailbox_view
Postponed Mailbox view.
Definition: functions.h:35
+ Here is the caller graph for this function: