NeoMutt  2022-04-29-247-gc6aae8
Teaching an old dog new tricks
DOXYGEN
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_select_postponed_email (struct Mailbox *m)
 Create a Menu to select a postponed message. More...
 
int mutt_get_postponed (struct Mailbox *m_cur, struct Email *hdr, struct Email **cur, struct Buffer *fcc)
 Recall a postponed message. More...
 
int mutt_num_postponed (struct Mailbox *m, bool force)
 Return the number of postponed messages. More...
 
SecurityFlags mutt_parse_crypt_hdr (const char *p, bool set_empty_signas, SecurityFlags crypt_app)
 Parse a crypto header string. More...
 
int mutt_prepare_template (FILE *fp, struct Mailbox *m, struct Email *e_new, struct Email *e, bool resend)
 Prepare a message template. More...
 
void mutt_update_num_postponed (void)
 Force the update of the number of postponed messages. More...
 

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

◆ dlg_select_postponed_email()

struct Email * dlg_select_postponed_email ( struct Mailbox m)

Create a Menu to select a postponed message.

Parameters
mMailbox
Return values
ptrEmail

Definition at line 169 of file dlg_postpone.c.

170{
172
173 struct Menu *menu = dlg->wdata;
175 menu->max = m->msg_count;
176 menu->mdata = m;
177 menu->mdata_free = NULL; // Menu doesn't own the data
178 menu->custom_search = true;
179
180 struct PostponeData pd = { false, m, menu, NULL };
181 dlg->wdata = &pd;
182
183 // NT_COLOR is handled by the SimpleDialog
186
187 struct MuttWindow *sbar = window_find_child(dlg, WT_STATUS_BAR);
188 sbar_set_title(sbar, _("Postponed Messages"));
189
190 /* The postponed mailbox is setup to have sorting disabled, but the global
191 * `$sort` variable may indicate something different. Sorting has to be
192 * disabled while the postpone menu is being displayed. */
193 const short c_sort = cs_subset_sort(NeoMutt->sub, "sort");
195
196 // ---------------------------------------------------------------------------
197 // Event Loop
198 int op = OP_NULL;
199 do
200 {
201 menu_tagging_dispatcher(menu->win, op);
202 window_redraw(NULL);
203
205 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
206 if (op < 0)
207 continue;
208 if (op == OP_NULL)
209 {
211 continue;
212 }
214
215 int rc = postpone_function_dispatcher(dlg, op);
216
217 if (rc == FR_UNKNOWN)
218 rc = menu_function_dispatcher(menu->win, op);
219 if (rc == FR_UNKNOWN)
220 rc = global_function_dispatcher(NULL, op);
221 } while (!pd.done);
222 // ---------------------------------------------------------------------------
223
224 cs_subset_str_native_set(NeoMutt->sub, "sort", c_sort, NULL);
225 simple_dialog_free(&dlg);
226
227 return pd.email;
228}
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
@ FR_UNKNOWN
Unknown function.
Definition: dispatcher.h:33
static const struct Mapping PostponeHelp[]
Help Bar for the Postponed email selection dialog.
Definition: dlg_postpone.c:88
int menu_tagging_dispatcher(struct MuttWindow *win, int op)
Perform tagging operations on the Menu - Implements function_dispatcher_t -.
Definition: tagging.c:223
int postpone_function_dispatcher(struct MuttWindow *win, int op)
Perform a Postpone function - Implements function_dispatcher_t -.
Definition: functions.c:129
int global_function_dispatcher(struct MuttWindow *win, int op)
Perform a Global function - Implements function_dispatcher_t -.
Definition: global.c:164
int menu_function_dispatcher(struct MuttWindow *win, int op)
Perform a Menu function - Implements function_dispatcher_t -.
Definition: functions.c:320
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
static void post_make_entry(struct Menu *menu, char *buf, size_t buflen, int line)
Format a menu item for the email list - Implements Menu::make_entry() -.
Definition: dlg_postpone.c:101
static int postponed_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition: dlg_postpone.c:141
static int postponed_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: dlg_postpone.c:115
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: simple.c:166
struct MuttWindow * simple_dialog_new(enum MenuType mtype, enum WindowType wtype, const struct Mapping *help_data)
Create a simple index Dialog.
Definition: simple.c:129
int km_dokey(enum MenuType mtype)
Determine what a keypress should do.
Definition: keymap.c:795
void km_error_key(enum MenuType mtype)
Handle an unbound key sequence.
Definition: keymap.c:1061
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
#define _(a)
Definition: message.h:28
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:189
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:74
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:604
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:522
@ WT_STATUS_BAR
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
@ WT_DLG_POSTPONE
Postpone Dialog, dlg_select_postponed_email()
Definition: mutt_window.h:89
@ NT_WINDOW
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:55
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:43
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition: opcodes.c:46
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:224
@ SORT_ORDER
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:48
int msg_count
Total number of messages.
Definition: mailbox.h:88
Definition: lib.h:69
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:76
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Definition: lib.h:96
void(* mdata_free)(struct Menu *menu, void **ptr)
Definition: lib.h:152
void * mdata
Private data.
Definition: lib.h:137
int max
Number of entries in the menu.
Definition: lib.h:71
bool custom_search
The menu implements its own non-Menusearch()-compatible search, trickle OP_SEARCH*.
Definition: lib.h:84
void * wdata
Private data.
Definition: mutt_window.h:145
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Data to pass to the Postpone Functions.
Definition: functions.h:34
struct Email * email
Selected Email.
Definition: functions.h:38
bool done
Should we close the Dialog?
Definition: functions.h:35
struct Menu * menu
Postponed Menu.
Definition: functions.h:37
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:305
@ MENU_POSTPONE
Select a postponed email.
Definition: type.h:56
+ 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 struct MailboxView *mv = (m_cur != m) ? mview_new(m) : NULL;
709 if (m->msg_count == 1)
710 {
711 /* only one message, so just use that one. */
712 e = m->emails[0];
713 }
714 else if (!(e = dlg_select_postponed_email(m)))
715 {
716 rc = -1;
717 goto cleanup;
718 }
719
720 if (mutt_prepare_template(NULL, m, hdr, e, false) < 0)
721 {
722 rc = -1;
723 goto cleanup;
724 }
725
726 /* finished with this message, so delete it. */
727 mutt_set_flag(m, e, MUTT_DELETE, true);
728 mutt_set_flag(m, e, MUTT_PURGE, true);
729
730 /* update the count for the status display */
732
733 struct ListNode *np = NULL, *tmp = NULL;
734 STAILQ_FOREACH_SAFE(np, &hdr->env->userhdrs, entries, tmp)
735 {
736 size_t plen = mutt_istr_startswith(np->data, "X-Mutt-References:");
737 if (plen)
738 {
739 /* if a mailbox is currently open, look to see if the original message
740 * the user attempted to reply to is in this mailbox */
741 if (m_cur)
742 {
744 if (!m_cur->id_hash)
745 m_cur->id_hash = mutt_make_id_hash(m_cur);
746 *cur = mutt_hash_find(m_cur->id_hash, p);
747
748 if (*cur)
749 rc |= SEND_REPLY;
750 }
751 }
752 else if ((plen = mutt_istr_startswith(np->data, "X-Mutt-Fcc:")))
753 {
755 mutt_buffer_strcpy(fcc, p);
757
758 /* note that x-mutt-fcc was present. we do this because we want to add a
759 * default fcc if the header was missing, but preserve the request of the
760 * user to not make a copy if the header field is present, but empty.
761 * see http://dev.mutt.org/trac/ticket/3653 */
762 rc |= SEND_POSTPONED_FCC;
763 }
764 else if (((WithCrypto & APPLICATION_PGP) != 0) &&
765 /* this is generated by old neomutt versions */
766 (mutt_str_startswith(np->data, "Pgp:") ||
767 /* this is the new way */
768 mutt_str_startswith(np->data, "X-Mutt-PGP:")))
769 {
770 hdr->security = mutt_parse_crypt_hdr(strchr(np->data, ':') + 1, true, APPLICATION_PGP);
772 }
773 else if (((WithCrypto & APPLICATION_SMIME) != 0) &&
774 mutt_str_startswith(np->data, "X-Mutt-SMIME:"))
775 {
776 hdr->security = mutt_parse_crypt_hdr(strchr(np->data, ':') + 1, true, APPLICATION_SMIME);
778 }
779#ifdef MIXMASTER
780 else if (mutt_str_startswith(np->data, "X-Mutt-Mix:"))
781 {
782 mutt_list_free(&hdr->chain);
783
784 char *t = strtok(np->data + 11, " \t\n");
785 while (t)
786 {
788 t = strtok(NULL, " \t\n");
789 }
790 }
791#endif
792 else
793 {
794 // skip header removal
795 continue;
796 }
797
798 // remove the header
799 STAILQ_REMOVE(&hdr->env->userhdrs, np, ListNode, entries);
800 FREE(&np->data);
801 FREE(&np);
802 }
803
804 const bool c_crypt_opportunistic_encrypt = cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt");
805 if (c_crypt_opportunistic_encrypt)
807
808cleanup:
809 if (m_cur != m)
810 {
811 hardclose(m);
812 mview_free(&mv);
813 mailbox_free(&m);
814 }
815
816 cs_subset_str_native_set(NeoMutt->sub, "delete", c_delete, NULL);
817 return rc;
818}
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:327
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:218
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1025
struct Email * dlg_select_postponed_email(struct Mailbox *m)
Create a Menu to select a postponed message.
Definition: dlg_postpone.c:169
#define mutt_error(...)
Definition: logging.h:87
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:87
#define FREE(x)
Definition: memory.h:43
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:679
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:227
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:239
@ MUTT_PURGE
Messages to be purged (bypass trash)
Definition: mutt.h:97
@ MUTT_DELETE
Messages to be deleted.
Definition: mutt.h:95
struct HashTable * mutt_make_id_hash(struct Mailbox *m)
Create a Hash Table for message-ids.
Definition: mutt_thread.c:1651
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:599
void mview_free(struct MailboxView **ptr)
Free a MailboxView.
Definition: mview.c:49
struct MailboxView * mview_new(struct Mailbox *m)
Create a new MailboxView.
Definition: mview.c:77
void mx_fastclose_mailbox(struct Mailbox *m, bool keep_account)
Free up memory associated with the Mailbox.
Definition: mx.c:430
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:304
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1677
enum MxStatus mx_mbox_check(struct Mailbox *m)
Check for new mail - Wrapper for MxOps::mbox_check()
Definition: mx.c:1126
#define MUTT_NOSORT
Do not sort the mailbox after opening it.
Definition: mxapi.h:62
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:91
#define WithCrypto
Definition: lib.h:116
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
SecurityFlags mutt_parse_crypt_hdr(const char *p, bool set_empty_signas, SecurityFlags crypt_app)
Parse a crypto header string.
Definition: postpone.c:210
short PostCount
Definition: postpone.c:58
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:503
static void hardclose(struct Mailbox *m)
Try hard to close a mailbox.
Definition: postpone.c:192
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:63
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 x-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:90
struct ListHead userhdrs
user defined headers
Definition: envelope.h:87
A List node for strings.
Definition: list.h:35
char * data
String.
Definition: list.h:36
The "current" mailbox.
Definition: mview.h:38
A mailbox.
Definition: mailbox.h:79
struct Email ** emails
Array of Emails.
Definition: mailbox.h:96
struct HashTable * id_hash
Hash Table by msg id.
Definition: mailbox.h:123
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:93
+ 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 69 of file postpone.c.

70{
71 struct stat st = { 0 };
72
73 static time_t LastModify = 0;
74 static char *OldPostponed = NULL;
75
77 {
78 UpdateNumPostponed = false;
79 force = true;
80 }
81
82 const char *const c_postponed = cs_subset_string(NeoMutt->sub, "postponed");
83 if (!mutt_str_equal(c_postponed, OldPostponed))
84 {
85 FREE(&OldPostponed);
86 OldPostponed = mutt_str_dup(c_postponed);
87 LastModify = 0;
88 force = true;
89 }
90
91 if (!c_postponed)
92 return 0;
93
94 // We currently are in the `$postponed` mailbox so just pick the current status
95 if (m && mutt_str_equal(c_postponed, m->realpath))
96 {
98 return PostCount;
99 }
100
101#ifdef USE_IMAP
102 /* LastModify is useless for IMAP */
103 if (imap_path_probe(c_postponed, NULL) == MUTT_IMAP)
104 {
105 if (force)
106 {
107 short newpc;
108
109 newpc = imap_path_status(c_postponed, false);
110 if (newpc >= 0)
111 {
112 PostCount = newpc;
113 mutt_debug(LL_DEBUG3, "%d postponed IMAP messages found\n", PostCount);
114 }
115 else
116 mutt_debug(LL_DEBUG3, "using old IMAP postponed count\n");
117 }
118 return PostCount;
119 }
120#endif
121
122 if (stat(c_postponed, &st) == -1)
123 {
124 PostCount = 0;
125 LastModify = 0;
126 return 0;
127 }
128
129 if (S_ISDIR(st.st_mode))
130 {
131 /* if we have a maildir mailbox, we need to stat the "new" dir */
132 struct Buffer *buf = mutt_buffer_pool_get();
133
134 mutt_buffer_printf(buf, "%s/new", c_postponed);
135 if ((access(mutt_buffer_string(buf), F_OK) == 0) &&
136 (stat(mutt_buffer_string(buf), &st) == -1))
137 {
138 PostCount = 0;
139 LastModify = 0;
141 return 0;
142 }
144 }
145
146 if (LastModify < st.st_mtime)
147 {
148#ifdef USE_NNTP
149 int optnews = OptNews;
150#endif
151 LastModify = st.st_mtime;
152
153 if (access(c_postponed, R_OK | F_OK) != 0)
154 return PostCount = 0;
155#ifdef USE_NNTP
156 if (optnews)
157 OptNews = false;
158#endif
159 struct Mailbox *m_post = mx_path_resolve(c_postponed);
160 if (mx_mbox_open(m_post, MUTT_NOSORT | MUTT_QUIET))
161 {
162 PostCount = m_post->msg_count;
163 mx_fastclose_mailbox(m_post, false);
164 }
165 else
166 {
167 PostCount = 0;
168 }
169 mailbox_free(&m_post);
170
171#ifdef USE_NNTP
172 if (optnews)
173 OptNews = true;
174#endif
175 }
176
177 return PostCount;
178}
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:168
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe() -.
Definition: imap.c:2400
int imap_path_status(const char *path, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1238
@ LL_DEBUG3
Log at debug level 3.
Definition: logging.h:42
@ 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:807
#define MUTT_QUIET
Do not print any messages.
Definition: mxapi.h:65
bool OptNews
(pseudo) used to change reader mode
Definition: options.h:50
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
static bool UpdateNumPostponed
Definition: postpone.c:59
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 210 of file postpone.c.

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

505{
506 struct Message *msg = NULL;
507 struct Body *b = NULL;
508 FILE *fp_body = NULL;
509 int rc = -1;
510 SecurityFlags sec_type;
511 struct Envelope *protected_headers = NULL;
512 struct Buffer *file = NULL;
513
514 if (!fp && !(msg = mx_msg_open(m, e->msgno)))
515 return -1;
516
517 if (!fp)
518 fp = msg->fp;
519
520 fp_body = fp;
521
522 /* parse the message header and MIME structure */
523
524 if (!mutt_file_seek(fp, e->offset, SEEK_SET))
525 {
526 return -1;
527 }
528 e_new->offset = e->offset;
529 /* enable header weeding for resent messages */
530 e_new->env = mutt_rfc822_read_header(fp, e_new, true, resend);
531 e_new->body->length = e->body->length;
532 mutt_parse_part(fp, e_new->body);
533
534 /* If resending a message, don't keep message_id or mail_followup_to.
535 * Otherwise, we are resuming a postponed message, and want to keep those
536 * headers if they exist. */
537 if (resend)
538 {
539 FREE(&e_new->env->message_id);
541 }
542
543 /* decrypt pgp/mime encoded messages */
544
545 if (((WithCrypto & APPLICATION_PGP) != 0) &&
546 (sec_type = mutt_is_multipart_encrypted(e_new->body)))
547 {
548 e_new->security |= sec_type;
549 if (!crypt_valid_passphrase(sec_type))
550 goto bail;
551
552 mutt_message(_("Decrypting message..."));
553 if ((crypt_pgp_decrypt_mime(fp, &fp_body, e_new->body, &b) == -1) || !b)
554 {
555 mutt_error(_("Could not decrypt PGP message"));
556 goto bail;
557 }
558
559 mutt_body_free(&e_new->body);
560 e_new->body = b;
561
562 if (b->mime_headers)
563 {
564 protected_headers = b->mime_headers;
565 b->mime_headers = NULL;
566 }
567
569 }
570
571 /* remove a potential multipart/signed layer - useful when
572 * resending messages */
573 if ((WithCrypto != 0) && mutt_is_multipart_signed(e_new->body))
574 {
575 e_new->security |= SEC_SIGN;
576 if (((WithCrypto & APPLICATION_PGP) != 0) &&
577 mutt_istr_equal(mutt_param_get(&e_new->body->parameter, "protocol"), "application/pgp-signature"))
578 {
579 e_new->security |= APPLICATION_PGP;
580 }
581 else if (WithCrypto & APPLICATION_SMIME)
582 e_new->security |= APPLICATION_SMIME;
583
584 /* destroy the signature */
585 mutt_body_free(&e_new->body->parts->next);
586 e_new->body = mutt_remove_multipart(e_new->body);
587
588 if (e_new->body->mime_headers)
589 {
590 mutt_env_free(&protected_headers);
591 protected_headers = e_new->body->mime_headers;
592 e_new->body->mime_headers = NULL;
593 }
594 }
595
596 /* We don't need no primary multipart/mixed. */
597 if ((e_new->body->type == TYPE_MULTIPART) && mutt_istr_equal(e_new->body->subtype, "mixed"))
598 e_new->body = mutt_remove_multipart(e_new->body);
599
600 file = mutt_buffer_pool_get();
601
602 /* create temporary files for all attachments */
603 if (create_tmp_files_for_attachments(fp_body, file, e_new, e_new->body, protected_headers) < 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_str_replace(&e_new->env->subject, 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
632 e_new->security &= ~APPLICATION_SMIME;
633 }
634
636
637 rc = 0;
638
639bail:
640
641 /* that's it. */
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:1470
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:402
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:134
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:439
int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:211
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
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:690
#define mutt_message(...)
Definition: logging.h:86
@ 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:819
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:326
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1193
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
Return a stream pointer for a message.
Definition: mx.c:1147
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition: parse.c:1736
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
Parses an RFC822 header.
Definition: parse.c:1157
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:364
void mutt_rfc3676_space_unstuff(struct Email *e)
Remove RFC3676 space stuffing.
Definition: rfc3676.c:494
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
int msgno
Number displayed to the user.
Definition: email.h:111
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: mxapi.h:43
FILE * fp
pointer to the message data
Definition: mxapi.h:44
+ 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 183 of file postpone.c.

184{
185 UpdateNumPostponed = true;
186}
+ Here is the caller graph for this function: