NeoMutt  2023-03-22-27-g3cb248
Teaching an old dog new tricks
DOXYGEN
message.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <errno.h>
31#include <stdbool.h>
32#include <stdio.h>
33#include <unistd.h>
34#include "mutt/lib.h"
35#include "config/lib.h"
36#include "email/lib.h"
37#include "core/lib.h"
38#include "gui/lib.h"
39#include "mutt.h"
40#include "attach/lib.h"
41#include "index/lib.h"
42#include "menu/lib.h"
43#include "ncrypt/lib.h"
44#include "pager/lib.h"
45#include "question/lib.h"
46#include "copy.h"
47#include "format_flags.h"
48#include "globals.h" // IWYU pragma: keep
49#include "hdrline.h"
50#include "hook.h"
51#include "keymap.h"
52#include "mx.h"
53#include "protos.h"
54#ifdef USE_AUTOCRYPT
55#include "autocrypt/lib.h"
56#endif
57
58static const char *ExtPagerProgress = N_("all");
59
65static void process_protected_headers(struct Mailbox *m, struct Email *e)
66{
67 struct Envelope *prot_headers = NULL;
68 regmatch_t pmatch[1];
69
70 const bool c_crypt_protected_headers_read = cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_read");
71#ifdef USE_AUTOCRYPT
72 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
73 if (!c_crypt_protected_headers_read && !c_autocrypt)
74 return;
75#else
76 if (!c_crypt_protected_headers_read)
77 return;
78#endif
79
80 /* Grab protected headers to update in the index */
81 if (e->security & SEC_SIGN)
82 {
83 /* Don't update on a bad signature.
84 *
85 * This is a simplification. It's possible the headers are in the
86 * encrypted part of a nested encrypt/signed. But properly handling that
87 * case would require more complexity in the decryption handlers, which
88 * I'm not sure is worth it. */
89 if (!(e->security & SEC_GOODSIGN))
90 return;
91
93 {
94 prot_headers = e->body->parts->mime_headers;
95 }
97 {
98 prot_headers = e->body->mime_headers;
99 }
100 }
101 if (!prot_headers && (e->security & SEC_ENCRYPT))
102 {
103 if (((WithCrypto & APPLICATION_PGP) != 0) &&
106 {
107 prot_headers = e->body->mime_headers;
108 }
110 {
111 prot_headers = e->body->mime_headers;
112 }
113 }
114
115 /* Update protected headers in the index and header cache. */
116 if (c_crypt_protected_headers_read && prot_headers && prot_headers->subject &&
117 !mutt_str_equal(e->env->subject, prot_headers->subject))
118 {
119 if (m->subj_hash && e->env->real_subj)
121
122 mutt_str_replace(&e->env->subject, prot_headers->subject);
123 FREE(&e->env->disp_subj);
124 const struct Regex *c_reply_regex = cs_subset_regex(NeoMutt->sub, "reply_regex");
125 if (mutt_regex_capture(c_reply_regex, e->env->subject, 1, pmatch))
126 {
127 e->env->real_subj = e->env->subject + pmatch[0].rm_eo;
128 if (e->env->real_subj[0] == '\0')
129 e->env->real_subj = NULL;
130 }
131 else
132 {
133 e->env->real_subj = e->env->subject;
134 }
135
136 if (m->subj_hash)
138
139 mx_save_hcache(m, e);
140
141 /* Also persist back to the message headers if this is set */
142 const bool c_crypt_protected_headers_save = cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_save");
143 if (c_crypt_protected_headers_save)
144 {
146 e->changed = true;
147 m->changed = true;
148 }
149 }
150
151#ifdef USE_AUTOCRYPT
152 if (c_autocrypt && (e->security & SEC_ENCRYPT) && prot_headers && prot_headers->autocrypt_gossip)
153 {
155 }
156#endif
157}
158
173static int email_to_file(struct Message *msg, struct Buffer *tempfile,
174 struct Mailbox *m, struct Email *e, const char *header,
175 int wrap_len, CopyMessageFlags *cmflags)
176{
177 int rc = 0;
178 pid_t filterpid = -1;
179
182
183 char columns[16] = { 0 };
184 // win_pager might not be visible and have a size yet, so use win_index
185 snprintf(columns, sizeof(columns), "%d", wrap_len);
186 mutt_envlist_set("COLUMNS", columns, true);
187
188 /* see if crypto is needed for this message. if so, we should exit curses */
189 if ((WithCrypto != 0) && e->security)
190 {
191 if (e->security & SEC_ENCRYPT)
192 {
196 goto cleanup;
197
198 *cmflags |= MUTT_CM_VERIFY;
199 }
200 else if (e->security & SEC_SIGN)
201 {
202 /* find out whether or not the verify signature */
203 /* L10N: Used for the $crypt_verify_sig prompt */
204 const enum QuadOption c_crypt_verify_sig = cs_subset_quad(NeoMutt->sub, "crypt_verify_sig");
205 if (query_quadoption(c_crypt_verify_sig, _("Verify signature?")) == MUTT_YES)
206 {
207 *cmflags |= MUTT_CM_VERIFY;
208 }
209 }
210 }
211
212 if (*cmflags & MUTT_CM_VERIFY || e->security & SEC_ENCRYPT)
213 {
214 if (e->security & APPLICATION_PGP)
215 {
216 if (!TAILQ_EMPTY(&e->env->from))
218
220 }
221
224 }
225
226 FILE *fp_filter_out = NULL;
227 mutt_buffer_mktemp(tempfile);
228 FILE *fp_out = mutt_file_fopen(mutt_buffer_string(tempfile), "w");
229 if (!fp_out)
230 {
231 mutt_error(_("Could not create temporary file"));
232 goto cleanup;
233 }
234
235 const char *const c_display_filter = cs_subset_string(NeoMutt->sub, "display_filter");
236 if (c_display_filter)
237 {
238 fp_filter_out = fp_out;
239 fp_out = NULL;
240 filterpid = filter_create_fd(c_display_filter, &fp_out, NULL, NULL, -1,
241 fileno(fp_filter_out), -1);
242 if (filterpid < 0)
243 {
244 mutt_error(_("Can't create display filter"));
245 mutt_file_fclose(&fp_filter_out);
246 unlink(mutt_buffer_string(tempfile));
247 goto cleanup;
248 }
249 }
250
251 if (header)
252 {
253 fputs(header, fp_out);
254 fputs("\n\n", fp_out);
255 }
256
257 const bool c_weed = cs_subset_bool(NeoMutt->sub, "weed");
258 CopyHeaderFlags chflags = (c_weed ? (CH_WEED | CH_REORDER) : CH_NO_FLAGS) |
260#ifdef USE_NOTMUCH
261 if (m->type == MUTT_NOTMUCH)
262 chflags |= CH_VIRTUAL;
263#endif
264 rc = mutt_copy_message(fp_out, e, msg, *cmflags, chflags, wrap_len);
265
266 if (((mutt_file_fclose(&fp_out) != 0) && (errno != EPIPE)) || (rc < 0))
267 {
268 mutt_error(_("Could not copy message"));
269 if (fp_filter_out)
270 {
271 filter_wait(filterpid);
272 mutt_file_fclose(&fp_filter_out);
273 }
275 goto cleanup;
276 }
277
278 if (fp_filter_out && (filter_wait(filterpid) != 0))
280
281 mutt_file_fclose(&fp_filter_out); /* XXX - check result? */
282
283 if (WithCrypto)
284 {
285 /* update crypto information for this message */
287 e->security |= crypt_query(e->body);
288
289 /* Remove color cache for this message, in case there
290 * are color patterns for both ~g and ~V */
291 e->attr_color = NULL;
292
293 /* Process protected headers and autocrypt gossip headers */
295 }
296
297cleanup:
298 mutt_envlist_unset("COLUMNS");
299 return rc;
300}
301
310int external_pager(struct Mailbox *m, struct Email *e, const char *command)
311{
312 struct Message *msg = mx_msg_open(m, e->msgno);
313 if (!msg)
314 return -1;
315
316 char buf[1024] = { 0 };
317 const char *const c_pager_format = cs_subset_string(NeoMutt->sub, "pager_format");
318 const int screen_width = RootWindow->state.cols;
319 mutt_make_string(buf, sizeof(buf), screen_width, NONULL(c_pager_format), m,
321
322 struct Buffer *tempfile = mutt_buffer_pool_get();
323
325 int rc = email_to_file(msg, tempfile, m, e, buf, screen_width, &cmflags);
326 if (rc < 0)
327 goto cleanup;
328
329 mutt_endwin();
330
331 struct Buffer *cmd = mutt_buffer_pool_get();
332 mutt_buffer_printf(cmd, "%s %s", command, mutt_buffer_string(tempfile));
333 int r = mutt_system(mutt_buffer_string(cmd));
334 if (r == -1)
335 mutt_error(_("Error running \"%s\""), mutt_buffer_string(cmd));
336 unlink(mutt_buffer_string(tempfile));
338
339 if (!OptNoCurses)
340 keypad(stdscr, true);
341 if (r != -1)
342 mutt_set_flag(m, e, MUTT_READ, true);
343 const bool c_prompt_after = cs_subset_bool(NeoMutt->sub, "prompt_after");
344 if ((r != -1) && c_prompt_after)
345 {
347 rc = km_dokey(MENU_PAGER);
348 }
349 else
350 {
351 rc = 0;
352 }
353
354cleanup:
355 mx_msg_close(m, &msg);
356 mutt_buffer_pool_release(&tempfile);
357 return rc;
358}
359
366static void notify_crypto(struct Email *e, struct Message *msg, CopyMessageFlags cmflags)
367{
368 if ((WithCrypto != 0) && (e->security & APPLICATION_SMIME) && (cmflags & MUTT_CM_VERIFY))
369 {
370 if (e->security & SEC_GOODSIGN)
371 {
372 if (crypt_smime_verify_sender(e, msg) == 0)
373 mutt_message(_("S/MIME signature successfully verified"));
374 else
375 mutt_error(_("S/MIME certificate owner does not match sender"));
376 }
377 else if (e->security & SEC_PARTSIGN)
378 mutt_message(_("Warning: Part of this message has not been signed"));
379 else if (e->security & SEC_SIGN || e->security & SEC_BADSIGN)
380 mutt_error(_("S/MIME signature could NOT be verified"));
381 }
382
383 if ((WithCrypto != 0) && (e->security & APPLICATION_PGP) && (cmflags & MUTT_CM_VERIFY))
384 {
385 if (e->security & SEC_GOODSIGN)
386 mutt_message(_("PGP signature successfully verified"));
387 else if (e->security & SEC_PARTSIGN)
388 mutt_message(_("Warning: Part of this message has not been signed"));
389 else if (e->security & SEC_SIGN)
390 mutt_message(_("PGP signature could NOT be verified"));
391 }
392}
393
400static void squash_index_panel(struct Mailbox *m, struct MuttWindow *win_index,
401 struct MuttWindow *win_pager)
402{
403 const short c_pager_index_lines = cs_subset_number(NeoMutt->sub, "pager_index_lines");
404
405 const int index_space = MIN(c_pager_index_lines, m->vcount);
406 if (index_space > 0)
407 {
408 win_index->size = MUTT_WIN_SIZE_FIXED;
409 win_index->req_rows = index_space;
410 win_index->parent->size = MUTT_WIN_SIZE_MINIMISE;
411 }
412 window_set_visible(win_index->parent, (index_space > 0));
413
414 window_set_visible(win_pager->parent, true);
415
416 struct MuttWindow *dlg = dialog_find(win_index);
418
419 // Force the menu to reframe itself
420 struct Menu *menu = win_index->wdata;
421 menu_set_index(menu, menu_get_index(menu));
422}
423
429static void expand_index_panel(struct MuttWindow *win_index, struct MuttWindow *win_pager)
430{
431 win_index->size = MUTT_WIN_SIZE_MAXIMISE;
433 win_index->parent->size = MUTT_WIN_SIZE_MAXIMISE;
435 window_set_visible(win_index->parent, true);
436
437 window_set_visible(win_pager->parent, false);
438
439 struct MuttWindow *dlg = dialog_find(win_index);
441}
442
450int mutt_display_message(struct MuttWindow *win_index, struct IndexSharedData *shared)
451{
452 struct MuttWindow *dlg = dialog_find(win_index);
453 struct MuttWindow *win_pager = window_find_child(dlg, WT_CUSTOM);
454 struct MuttWindow *win_pbar = window_find_child(dlg, WT_STATUS_BAR);
455 struct Buffer *tempfile = mutt_buffer_pool_get();
456 struct Message *msg = NULL;
457
458 squash_index_panel(shared->mailbox, win_index, win_pager);
459
460 int rc = PAGER_LOOP_QUIT;
461 do
462 {
463 msg = mx_msg_open(shared->mailbox, shared->email->msgno);
464 if (!msg)
465 break;
466
468
469 mutt_buffer_reset(tempfile);
470 // win_pager might not be visible and have a size yet, so use win_index
471 rc = email_to_file(msg, tempfile, shared->mailbox, shared->email, NULL,
472 win_index->state.cols, &cmflags);
473 if (rc < 0)
474 break;
475
476 notify_crypto(shared->email, msg, cmflags);
477
478 /* Invoke the builtin pager */
479 struct PagerData pdata = { 0 };
480 struct PagerView pview = { &pdata };
481
482 pdata.fp = msg->fp;
483 pdata.fname = mutt_buffer_string(tempfile);
484
485 pview.mode = PAGER_MODE_EMAIL;
486 pview.banner = NULL;
487 pview.flags = MUTT_PAGER_MESSAGE |
488 (shared->email->body->nowrap ? MUTT_PAGER_NOWRAP : 0);
489 pview.win_index = win_index;
490 pview.win_pbar = win_pbar;
491 pview.win_pager = win_pager;
492
493 rc = mutt_pager(&pview);
494 mx_msg_close(shared->mailbox, &msg);
495 } while (rc == PAGER_LOOP_RELOAD);
496
498
499 mx_msg_close(shared->mailbox, &msg);
500 mutt_buffer_pool_release(&tempfile);
501 return rc;
502}
GUI display the mailboxes in a side panel.
void mutt_parse_mime_message(struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:592
Autocrypt end-to-end encryption.
int mutt_autocrypt_process_gossip_header(struct Email *e, struct Envelope *prot_headers)
Parse an Autocrypt email gossip header.
Definition: autocrypt.c:415
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:168
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:85
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:78
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
Definition: helpers.c:243
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
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
Convenience wrapper for the config headers.
int mutt_copy_message(FILE *fp_out, struct Email *e, struct Message *msg, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition: copy.c:875
Duplicate the structure of an entire email.
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:54
#define MUTT_CM_VERIFY
Do signature verification.
Definition: copy.h:47
#define CH_FROM
Retain the "From " message separator?
Definition: copy.h:56
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:38
#define CH_WEED
Weed the headers?
Definition: copy.h:53
#define CH_REORDER
Re-order output of headers (specified by 'hdr_order')
Definition: copy.h:59
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:42
#define CH_DISPLAY
Display result to user.
Definition: copy.h:70
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:50
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:34
#define CH_VIRTUAL
Write virtual header lines too.
Definition: copy.h:73
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:51
#define MUTT_CM_DISPLAY
Output is displayed to the user.
Definition: copy.h:39
Convenience wrapper for the core headers.
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:401
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:133
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:460
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:497
SecurityFlags crypt_query(struct Body *b)
Check out the type of encryption used.
Definition: crypt.c:672
void crypt_invoke_message(SecurityFlags type)
Display an informative message.
Definition: cryptglue.c:157
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition: cryptglue.c:455
void crypt_pgp_invoke_getkeys(struct Address *addr)
Wrapper for CryptModuleSpecs::pgp_invoke_getkeys()
Definition: cryptglue.c:274
int crypt_smime_verify_sender(struct Email *e, struct Message *msg)
Wrapper for CryptModuleSpecs::smime_verify_sender()
Definition: cryptglue.c:464
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:386
void mutt_endwin(void)
Shutdown curses.
Definition: curs_lib.c:353
void mutt_unget_ch(int ch)
Return a keystroke to the input buffer.
Definition: curs_lib.c:520
struct MuttWindow * dialog_find(struct MuttWindow *win)
Find the parent Dialog of a Window.
Definition: dialog.c:83
int mutt_pager(struct PagerView *pview)
Display an email, attachment, or help, in a window.
Definition: dlg_pager.c:222
Structs that make up an email.
#define MUTT_ENV_CHANGED_SUBJECT
Protected header update.
Definition: envelope.h:37
bool mutt_envlist_unset(const char *name)
Unset an environment variable.
Definition: envlist.c:132
bool mutt_envlist_set(const char *name, const char *value, bool overwrite)
Set an environment variable.
Definition: envlist.c:85
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:634
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:193
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
pid_t filter_create_fd(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err, int fdin, int fdout, int fderr)
Run a command on a pipe (optionally connect stdin/stdout)
Definition: filter.c:61
Flags to control mutt_expando_format()
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: globals.c:81
#define mutt_error(...)
Definition: logging.h:87
#define mutt_message(...)
Definition: logging.h:86
Convenience wrapper for the gui headers.
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:335
void mutt_hash_delete(struct HashTable *table, const char *strkey, const void *data)
Remove an element from a Hash Table.
Definition: hash.c:427
void mutt_make_string(char *buf, size_t buflen, int cols, const char *s, struct Mailbox *m, int inpgr, struct Email *e, MuttFormatFlags flags, const char *progress)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1443
String processing routines to generate the mail index.
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:656
Parse and execute user-defined hooks.
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:45
GUI manage the main index (list of emails)
int km_dokey(enum MenuType mtype)
Determine what a keypress should do.
Definition: keymap.c:797
Manage keymappings.
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition: mailbox.h:51
#define FREE(x)
Definition: memory.h:43
#define MIN(a, b)
Definition: memory.h:31
GUI present the user with a selectable list.
int menu_get_index(struct Menu *menu)
Get the current selection in the Menu.
Definition: menu.c:154
MenuRedrawFlags menu_set_index(struct Menu *menu, int index)
Set the current selection in the Menu.
Definition: menu.c:168
Convenience wrapper for the library headers.
#define N_(a)
Definition: message.h:32
#define _(a)
Definition: message.h:28
bool mutt_regex_capture(const struct Regex *regex, const char *str, size_t nmatch, regmatch_t matches[])
Match a regex against a string, with provided options.
Definition: regex.c:618
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:326
Many unsorted constants and some structs.
@ MUTT_READ
Messages that have been read.
Definition: mutt.h:81
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:341
void window_set_visible(struct MuttWindow *win, bool visible)
Set a Window visible or hidden.
Definition: mutt_window.c:163
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:523
@ WT_CUSTOM
Window with a custom drawing function.
Definition: mutt_window.h:95
@ WT_STATUS_BAR
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:52
@ MUTT_WIN_SIZE_FIXED
Window has a fixed size.
Definition: mutt_window.h:47
@ MUTT_WIN_SIZE_MINIMISE
Window size depends on its children.
Definition: mutt_window.h:49
@ MUTT_WIN_SIZE_MAXIMISE
Window wants as much space as possible.
Definition: mutt_window.h:48
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1200
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
Return a stream pointer for a message.
Definition: mx.c:1154
int mx_save_hcache(struct Mailbox *m, struct Email *e)
Save message to the header cache - Wrapper for MxOps::msg_save_hcache()
Definition: mx.c:1831
API for mailboxes.
API for encryption/signing of emails.
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:80
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define SEC_BADSIGN
Email has a bad signature.
Definition: lib.h:81
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:91
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: lib.h:82
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:78
#define WithCrypto
Definition: lib.h:116
#define SEC_SIGN
Email is signed.
Definition: lib.h:79
GUI display a file/email/help in a viewport with paging.
@ PAGER_LOOP_RELOAD
Reload the Pager from scratch.
Definition: lib.h:151
@ PAGER_LOOP_QUIT
Quit the Pager.
Definition: lib.h:150
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition: lib.h:71
@ PAGER_MODE_EMAIL
Pager is invoked via 1st path. The mime part is selected automatically.
Definition: lib.h:135
#define MUTT_PAGER_MESSAGE
Definition: lib.h:74
static int email_to_file(struct Message *msg, struct Buffer *tempfile, struct Mailbox *m, struct Email *e, const char *header, int wrap_len, CopyMessageFlags *cmflags)
Decrypt, decode and weed an Email into a file.
Definition: message.c:173
static void expand_index_panel(struct MuttWindow *win_index, struct MuttWindow *win_pager)
Restore the Index Panel.
Definition: message.c:429
static const char * ExtPagerProgress
Definition: message.c:58
static void process_protected_headers(struct Mailbox *m, struct Email *e)
Get the protected header and update the index.
Definition: message.c:65
int mutt_display_message(struct MuttWindow *win_index, struct IndexSharedData *shared)
Display a message in the pager.
Definition: message.c:450
int external_pager(struct Mailbox *m, struct Email *e, const char *command)
Display a message in an external program.
Definition: message.c:310
static void notify_crypto(struct Email *e, struct Message *msg, CopyMessageFlags cmflags)
Notify the user about the crypto status of the Email.
Definition: message.c:366
static void squash_index_panel(struct Mailbox *m, struct MuttWindow *win_index, struct MuttWindow *win_pager)
Shrink or hide the Index Panel.
Definition: message.c:400
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
Prototypes for many functions.
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:63
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:39
Ask the user a question.
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: question.c:386
#define TAILQ_FIRST(head)
Definition: queue.h:723
#define TAILQ_EMPTY(head)
Definition: queue.h:721
struct MuttWindow * RootWindow
Parent of all Windows.
Definition: rootwin.c:104
#define NONULL(x)
Definition: string2.h:37
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
bool nowrap
Do not wrap the output in the pager.
Definition: body.h:88
String manipulation buffer.
Definition: buffer.h:34
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 Body * body
List of MIME parts.
Definition: email.h:67
struct AttrColor * attr_color
Color-pair to use when displaying in the index.
Definition: email.h:111
bool changed
Email has been edited.
Definition: email.h:75
int msgno
Number displayed to the user.
Definition: email.h:110
The header of an Email.
Definition: envelope.h:57
unsigned char changed
Changed fields, e.g. MUTT_ENV_CHANGED_SUBJECT.
Definition: envelope.h:92
struct AutocryptHeader * autocrypt_gossip
Autocrypt Gossip header.
Definition: envelope.h:90
char * subject
Email's subject.
Definition: envelope.h:70
char * real_subj
Offset of the real subject.
Definition: envelope.h:71
char * disp_subj
Display subject (modified copy of subject)
Definition: envelope.h:72
struct AddressList from
Email's 'From' list.
Definition: envelope.h:59
Data shared between Index, Pager and Sidebar.
Definition: shared_data.h:37
struct Email * email
Currently selected Email.
Definition: shared_data.h:42
struct Mailbox * mailbox
Current Mailbox.
Definition: shared_data.h:41
A mailbox.
Definition: mailbox.h:79
int vcount
The number of virtual messages.
Definition: mailbox.h:99
bool changed
Mailbox has been modified.
Definition: mailbox.h:110
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
struct HashTable * subj_hash
Hash Table by subject.
Definition: mailbox.h:124
Definition: lib.h:70
A local copy of an email.
Definition: mxapi.h:43
FILE * fp
pointer to the message data
Definition: mxapi.h:44
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
void * wdata
Private data.
Definition: mutt_window.h:145
short req_rows
Number of rows required.
Definition: mutt_window.h:125
struct MuttWindow * parent
Parent Window.
Definition: mutt_window.h:135
enum MuttWindowSize size
Type of Window, e.g. MUTT_WIN_SIZE_FIXED.
Definition: mutt_window.h:131
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Data to be displayed by PagerView.
Definition: lib.h:158
const char * fname
Name of the file to read.
Definition: lib.h:162
FILE * fp
Source stream.
Definition: lib.h:160
Paged view into some data.
Definition: lib.h:169
struct MuttWindow * win_index
Index Window.
Definition: lib.h:175
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:170
enum PagerMode mode
Pager mode.
Definition: lib.h:171
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:172
const char * banner
Title to display in status bar.
Definition: lib.h:173
struct MuttWindow * win_pbar
Pager Bar Window.
Definition: lib.h:176
struct MuttWindow * win_pager
Pager Window.
Definition: lib.h:177
Cached regular expression.
Definition: regex3.h:89
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:60
#define mutt_buffer_mktemp(buf)
Definition: tmp.h:37
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:54