NeoMutt  2025-12-11-435-g4ac674
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 <stdio.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

void postponed_init_keys (struct SubMenu *sm_generic)
 Initialise the Postponed Keybindings - Implements ::init_keys_api.
 
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

◆ postponed_init_keys()

void postponed_init_keys ( struct SubMenu * sm_generic)

Initialise the Postponed Keybindings - Implements ::init_keys_api.

Definition at line 70 of file functions.c.

71{
72 struct MenuDefinition *md = NULL;
73 struct SubMenu *sm = NULL;
74
76 md = km_register_menu(MENU_POSTPONE, "postpone");
77 km_menu_add_submenu(md, sm);
78 km_menu_add_submenu(md, sm_generic);
80
81 MdPostpone = md;
82}
void km_menu_add_submenu(struct MenuDefinition *md, struct SubMenu *sm)
Add a SubMenu to a Menu Definition.
Definition init.c:123
struct SubMenu * km_register_submenu(const struct MenuFuncOp functions[])
Register a submenu.
Definition init.c:91
struct MenuDefinition * km_register_menu(int menu, const char *name)
Register a menu.
Definition init.c:107
void km_menu_add_bindings(struct MenuDefinition *md, const struct MenuOpSeq bindings[])
Add Keybindings to a Menu.
Definition init.c:136
static const struct MenuFuncOp OpPostponed[]
Functions for the Postpone Menu.
Definition functions.c:49
static const struct MenuOpSeq PostponedDefaultBindings[]
Key bindings for the Postpone Menu.
Definition functions.c:59
struct MenuDefinition * MdPostpone
Postpone Menu Definition.
Definition functions.c:43
Functions for a Dialog or Window.
Definition menu.h:80
Collection of related functions.
Definition menu.h:68
@ MENU_POSTPONE
Select a postponed email.
Definition type.h:47
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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 667 of file postpone.c.

669{
670 const char *const c_postponed = cs_subset_string(NeoMutt->sub, "postponed");
671 if (!c_postponed)
672 return -1;
673
674 struct Email *e = NULL;
675 int rc = SEND_POSTPONED;
676 const char *p = NULL;
677
678 struct Mailbox *m = mx_path_resolve(c_postponed);
679 if (m_cur != m)
680 {
681 if (!mx_mbox_open(m, MUTT_NOSORT))
682 {
683 PostCount = 0;
684 mutt_error(_("No postponed messages"));
685 mailbox_free(&m);
686 return -1;
687 }
688 }
689
690 mx_mbox_check(m);
691
692 if (m->msg_count == 0)
693 {
694 PostCount = 0;
695 mutt_error(_("No postponed messages"));
696 if (m_cur != m)
697 {
698 mx_fastclose_mailbox(m, false);
699 mailbox_free(&m);
700 }
701 return -1;
702 }
703
704 /* avoid the "purge deleted messages" prompt */
705 const enum QuadOption c_delete = cs_subset_quad(NeoMutt->sub, "delete");
706 cs_subset_str_native_set(NeoMutt->sub, "delete", MUTT_YES, NULL);
707
708 if (m->msg_count == 1)
709 {
710 /* only one message, so just use that one. */
711 e = m->emails[0];
712 }
713 else if (!(e = dlg_postponed(m)))
714 {
715 rc = -1;
716 goto cleanup;
717 }
718
719 if (mutt_prepare_template(NULL, m, hdr, e, false) < 0)
720 {
721 rc = -1;
722 goto cleanup;
723 }
724
725 /* finished with this message, so delete it. */
726 mutt_set_flag(m, e, MUTT_DELETE, true, true);
727 mutt_set_flag(m, e, MUTT_PURGE, true, true);
728
729 /* update the count for the status display */
731
732 struct ListNode *np = NULL, *tmp = NULL;
733 STAILQ_FOREACH_SAFE(np, &hdr->env->userhdrs, entries, tmp)
734 {
735 size_t plen = 0;
736 // Check for header names: most specific first
737 if ((plen = mutt_istr_startswith(np->data, "X-Mutt-References:")) ||
738 (plen = mutt_istr_startswith(np->data, "Mutt-References:")))
739 {
740 /* if a mailbox is currently open, look to see if the original message
741 * the user attempted to reply to is in this mailbox */
742 if (m_cur)
743 {
744 p = mutt_str_skip_email_wsp(np->data + plen);
745 if (!m_cur->id_hash)
746 m_cur->id_hash = mutt_make_id_hash(m_cur);
747 *cur = mutt_hash_find(m_cur->id_hash, p);
748
749 if (*cur)
750 rc |= SEND_REPLY;
751 }
752 }
753 // Check for header names: most specific first
754 else if ((plen = mutt_istr_startswith(np->data, "X-Mutt-Fcc:")) ||
755 (plen = mutt_istr_startswith(np->data, "Mutt-Fcc:")))
756 {
757 p = mutt_str_skip_email_wsp(np->data + plen);
758 buf_strcpy(fcc, p);
759 pretty_mailbox(fcc);
760
761 /* note that mutt-fcc was present. we do this because we want to add a
762 * default fcc if the header was missing, but preserve the request of the
763 * user to not make a copy if the header field is present, but empty. */
764 rc |= SEND_POSTPONED_FCC;
765 }
766 // Check for header names: most specific first
767 else if (((WithCrypto & APPLICATION_PGP) != 0) &&
768 ((plen = mutt_istr_startswith(np->data, "X-Mutt-PGP:")) ||
769 (plen = mutt_istr_startswith(np->data, "Mutt-PGP:")) ||
770 (plen = mutt_istr_startswith(np->data, "Pgp:"))))
771 {
772 hdr->security = mutt_parse_crypt_hdr(np->data + plen, true, APPLICATION_PGP);
774 }
775 // Check for header names: most specific first
776 else if (((WithCrypto & APPLICATION_SMIME) != 0) &&
777 ((plen = mutt_istr_startswith(np->data, "X-Mutt-SMIME:")) ||
778 (plen = mutt_istr_startswith(np->data, "Mutt-SMIME:"))))
779 {
780 hdr->security = mutt_parse_crypt_hdr(np->data + plen, true, APPLICATION_SMIME);
782 }
783 else
784 {
785 // skip header removal
786 continue;
787 }
788
789 // remove the header
790 STAILQ_REMOVE(&hdr->env->userhdrs, np, ListNode, entries);
791 FREE(&np->data);
792 FREE(&np);
793 }
794
795 const bool c_crypt_opportunistic_encrypt = cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt");
796 if (c_crypt_opportunistic_encrypt)
798
799cleanup:
800 if (m_cur != m)
801 {
802 hardclose(m);
803 mailbox_free(&m);
804 }
805
806 cs_subset_str_native_set(NeoMutt->sub, "delete", c_delete, NULL);
807 return rc;
808}
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition helpers.c:192
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition mailbox.c:90
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition crypt.c:1045
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:54
struct Email * dlg_postponed(struct Mailbox *m)
Create a Menu to select a postponed message -.
#define mutt_error(...)
Definition logging2.h:94
struct HashTable * mutt_make_id_hash(struct Mailbox *m)
Create a Hash Table for message-ids.
Definition thread.c:1700
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:364
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define _(a)
Definition message.h:28
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition string.c:610
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition string.c:246
short PostCount
Number of postponed (draft) emails.
Definition postpone.c:55
@ MUTT_PURGE
Messages to be purged (bypass trash)
Definition mutt.h:96
@ MUTT_DELETE
Messages to be deleted.
Definition mutt.h:94
void pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition muttlib.c:427
void mx_fastclose_mailbox(struct Mailbox *m, bool keep_account)
Free up memory associated with the Mailbox.
Definition mx.c:411
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition mx.c:285
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition mx.c:1647
enum MxStatus mx_mbox_check(struct Mailbox *m)
Check for new mail - Wrapper for MxOps::mbox_check()
Definition mx.c:1107
#define MUTT_NOSORT
Do not sort the mailbox after opening it.
Definition mxapi.h:40
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition lib.h:98
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition lib.h:99
#define WithCrypto
Definition lib.h:124
SecurityFlags mutt_parse_crypt_hdr(const char *p, bool set_empty_signas, SecurityFlags crypt_app)
Parse a crypto header string.
Definition postpone.c:201
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:492
static void hardclose(struct Mailbox *m)
Try hard to close a mailbox.
Definition postpone.c:183
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:441
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition queue.h:400
#define SEND_POSTPONED_FCC
Used by mutt_get_postponed() to signal that the Mutt-Fcc header field was present.
Definition send.h:50
#define SEND_POSTPONED
Recall a postponed email.
Definition send.h:46
#define SEND_REPLY
Reply to sender.
Definition send.h:42
The envelope/body of an email.
Definition email.h:39
struct Envelope * env
Envelope information.
Definition email.h:68
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition email.h:43
struct ListHead userhdrs
user defined headers
Definition envelope.h:85
A List node for strings.
Definition list.h:37
char * data
String.
Definition list.h:38
A mailbox.
Definition mailbox.h:78
int msg_count
Total number of messages.
Definition mailbox.h:87
struct Email ** emails
Array of Emails.
Definition mailbox.h:95
struct HashTable * id_hash
Hash Table: "message-id" -> Email.
Definition mailbox.h:122
int msg_deleted
Number of deleted messages.
Definition mailbox.h:92
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
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:303
+ 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 67 of file postpone.c.

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

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

494{
495 struct Message *msg = NULL;
496 struct Body *b = NULL;
497 FILE *fp_body = NULL;
498 int rc = -1;
499 struct Envelope *protected_headers = NULL;
500 struct Buffer *file = NULL;
501
502 if (!fp && !(msg = mx_msg_open(m, e)))
503 return -1;
504
505 if (!fp)
506 fp = msg->fp;
507
508 fp_body = fp;
509
510 /* parse the message header and MIME structure */
511
512 if (!mutt_file_seek(fp, e->offset, SEEK_SET))
513 {
514 goto bail;
515 }
516 e_new->offset = e->offset;
517 /* enable header weeding for resent messages */
518 e_new->env = mutt_rfc822_read_header(fp, e_new, true, resend);
519 e_new->body->length = e->body->length;
520 mutt_parse_part(fp, e_new->body);
521
522 /* If resending a message, don't keep message_id or mail_followup_to.
523 * Otherwise, we are resuming a postponed message, and want to keep those
524 * headers if they exist. */
525 if (resend)
526 {
527 FREE(&e_new->env->message_id);
529 }
530
531 SecurityFlags sec_type = SEC_NO_FLAGS;
532 if (((WithCrypto & APPLICATION_PGP) != 0) && sec_type == SEC_NO_FLAGS)
533 sec_type = mutt_is_multipart_encrypted(e_new->body);
534 if (((WithCrypto & APPLICATION_SMIME) != 0) && sec_type == SEC_NO_FLAGS)
535 sec_type = mutt_is_application_smime(e_new->body);
536 if (sec_type != SEC_NO_FLAGS)
537 {
538 e_new->security |= sec_type;
539 if (!crypt_valid_passphrase(sec_type))
540 goto bail;
541
542 mutt_message(_("Decrypting message..."));
543 int ret = -1;
544 if (sec_type & APPLICATION_PGP)
545 ret = crypt_pgp_decrypt_mime(fp, &fp_body, e_new->body, &b);
546 else if (sec_type & APPLICATION_SMIME)
547 ret = crypt_smime_decrypt_mime(fp, &fp_body, e_new->body, &b);
548 if ((ret == -1) || !b)
549 {
550 mutt_error(_("Could not decrypt postponed message"));
551 goto bail;
552 }
553
554 /* throw away the outer layer and keep only the (now decrypted) inner part
555 * with its headers. */
556 mutt_body_free(&e_new->body);
557 e_new->body = b;
558
559 if (b->mime_headers)
560 {
561 protected_headers = b->mime_headers;
562 b->mime_headers = NULL;
563 }
564
566 }
567
568 /* remove a potential multipart/signed layer - useful when
569 * resending messages */
570 if ((WithCrypto != 0) && mutt_is_multipart_signed(e_new->body) && e_new->body->parts)
571 {
572 e_new->security |= SEC_SIGN;
573 if (((WithCrypto & APPLICATION_PGP) != 0) &&
574 mutt_istr_equal(mutt_param_get(&e_new->body->parameter, "protocol"), "application/pgp-signature"))
575 {
576 e_new->security |= APPLICATION_PGP;
577 }
578 else if (WithCrypto & APPLICATION_SMIME)
579 {
580 e_new->security |= APPLICATION_SMIME;
581 }
582
583 /* destroy the signature */
584 mutt_body_free(&e_new->body->parts->next);
585 e_new->body = mutt_remove_multipart(e_new->body);
586
587 if (e_new->body->mime_headers)
588 {
589 mutt_env_free(&protected_headers);
590 protected_headers = e_new->body->mime_headers;
591 e_new->body->mime_headers = NULL;
592 }
593 }
594
595 /* We don't need no primary multipart/mixed. */
596 if ((e_new->body->type == TYPE_MULTIPART) && mutt_istr_equal(e_new->body->subtype, "mixed"))
597 e_new->body = mutt_remove_multipart(e_new->body);
598
599 file = buf_pool_get();
600
601 /* create temporary files for all attachments */
602 if (create_tmp_files_for_attachments(fp_body, file, e_new, e_new->body,
603 protected_headers, 0) < 0)
604 {
605 goto bail;
606 }
607
608 const bool c_crypt_protected_headers_read = cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_read");
609 if (c_crypt_protected_headers_read && protected_headers && protected_headers->subject &&
610 !mutt_str_equal(e_new->env->subject, protected_headers->subject))
611 {
612 mutt_env_set_subject(e_new->env, protected_headers->subject);
613 }
614 mutt_env_free(&protected_headers);
615
616 /* Fix encryption flags. */
617
618 /* No inline if multipart. */
619 if ((WithCrypto != 0) && (e_new->security & SEC_INLINE) && e_new->body->next)
620 e_new->security &= ~SEC_INLINE;
621
622 /* Do we even support multiple mechanisms? */
624
625 /* Theoretically, both could be set. Take the one the user wants to set by default. */
626 if ((e_new->security & APPLICATION_PGP) && (e_new->security & APPLICATION_SMIME))
627 {
628 const bool c_smime_is_default = cs_subset_bool(NeoMutt->sub, "smime_is_default");
629 if (c_smime_is_default)
630 e_new->security &= ~APPLICATION_PGP;
631 else
633 }
634
636
637 rc = 0;
638
639bail:
640
641 /* that's it. */
642 buf_pool_release(&file);
643 if (fp_body != fp)
644 mutt_file_fclose(&fp_body);
645 if (msg)
646 mx_msg_close(m, &msg);
647
648 if (rc == -1)
649 {
650 mutt_env_free(&e_new->env);
651 mutt_body_free(&e_new->body);
652 }
653
654 return rc;
655}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition address.c:1464
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition crypt.c:408
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition crypt.c:609
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition crypt.c:131
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition crypt.c:443
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:210
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:432
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition body.c:58
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition parse.c:1833
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
Parses an RFC822 header.
Definition parse.c:1210
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition envelope.c:125
void mutt_env_set_subject(struct Envelope *env, const char *subj)
Set both subject and real_subj to subj.
Definition envelope.c:68
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition file.c:652
#define mutt_file_fclose(FP)
Definition file.h:139
#define mutt_message(...)
Definition logging2.h:93
@ 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:674
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
int mx_msg_close(struct Mailbox *m, struct Message **ptr)
Close a message.
Definition mx.c:1182
struct Message * mx_msg_open(struct Mailbox *m, struct Email *e)
Return a stream pointer for a message.
Definition mx.c:1136
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition parameter.c:85
static int create_tmp_files_for_attachments(FILE *fp_body, struct Buffer *file, struct Email *e_new, struct Body *body, struct Envelope *protected_headers, int depth)
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:503
The body of an email.
Definition body.h:36
struct Body * parts
parts of a multipart or message/rfc822
Definition body.h:73
struct Envelope * mime_headers
Memory hole protected headers.
Definition body.h:76
LOFF_T length
length (in bytes) of attachment
Definition body.h:53
struct ParameterList parameter
Parameters of the content-type.
Definition body.h:63
struct Body * next
next attachment in the list
Definition body.h:72
char * subtype
content-type subtype
Definition body.h:61
unsigned int type
content-type primary type, ContentType
Definition body.h:40
struct Body * body
List of MIME parts.
Definition email.h:69
LOFF_T offset
Where in the stream does this message begin?
Definition email.h:71
The header of an Email.
Definition envelope.h:57
char *const subject
Email's subject.
Definition envelope.h:70
char * message_id
Message ID.
Definition envelope.h:73
struct AddressList mail_followup_to
Email's 'mail-followup-to'.
Definition envelope.h:65
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 174 of file postpone.c.

175{
176 UpdateNumPostponed = true;
177}
+ 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 229 of file functions.c.

230{
231 if (!dlg)
232 return NULL;
233
234 struct Menu *menu = dlg->wdata;
235 struct PostponeData *pd = menu->mdata;
236 if (!pd)
237 return NULL;
238
239 return pd->mailbox_view;
240}
Definition lib.h:80
void * mdata
Private data.
Definition lib.h:149
void * wdata
Private data.
Data to pass to the Postpone Functions.
Definition functions.h:37
struct MailboxView * mailbox_view
Postponed Mailbox view.
Definition functions.h:38
struct Menu * menu
Postponed Menu.
Definition functions.h:39
+ Here is the caller graph for this function: