View an attachment.
Display a message attachment using the viewer program configured in mailcap. If there is no mailcap entry for a file type, view the image as text. Viewer processes are opened and waited on synchronously so viewing an attachment this way will block the main neomutt process until the viewer process exits.
420{
421 bool use_mailcap = false;
422 bool use_pipe = false;
423 bool use_pager = true;
424 char type[256] = { 0 };
425 char desc[512] = { 0 };
426 char *fname = NULL;
428 int rc = -1;
429 bool has_tempfile = false;
430 bool unlink_pagerfile = false;
431
435 {
436 return rc;
437 }
438
442
447
448 char columns[16] = { 0 };
449 snprintf(columns,
sizeof(columns),
"%d", win->
state.
cols);
451
452 if (use_mailcap)
453 {
457 {
459 {
460
462 mutt_error(
_(
"No matching mailcap entry found. Viewing as text."));
464 use_mailcap = false;
465 }
466 else
467 {
468 goto return_error;
469 }
470 }
471 }
472
473 if (use_mailcap)
474 {
476 {
477 mutt_error(
_(
"MIME type not defined. Can't view attachment."));
478 goto return_error;
479 }
481
483
484
488
490 goto return_error;
491 has_tempfile = true;
492
494
495
497 {
498 struct Body *related_ancestor = NULL;
501 else
503 if (related_ancestor)
504 {
507
509
511
513 }
514 }
515
518 }
519
520 if (use_pager)
521 {
522 if (fp && !use_mailcap && b->
filename)
523 {
524
527 }
528 else
529 {
531 }
532 }
533
534 if (use_mailcap)
535 {
536 pid_t pid = 0;
537 int fd_temp = -1, fd_pager = -1;
538
539 if (!use_pager)
541
543 if (use_pager || use_pipe)
544 {
545 if (use_pager &&
547 O_CREAT | O_EXCL | O_WRONLY, 0600)) == -1))
548 {
550 goto return_error;
551 }
552 unlink_pagerfile = true;
553
554 if (use_pipe && ((fd_temp = open(
buf_string(tempfile), 0)) == -1))
555 {
556 if (fd_pager != -1)
557 close(fd_pager);
559 goto return_error;
560 }
561 unlink_pagerfile = true;
562
565
566 if (pid == -1)
567 {
568 if (fd_pager != -1)
569 close(fd_pager);
570
571 if (fd_temp != -1)
572 close(fd_temp);
573
575 goto return_error;
576 }
577
578 if (use_pager)
579 {
581 {
582 snprintf(desc,
sizeof(desc),
_(
"---Command: %-20.20s Description: %s"),
584 }
585 else
586 {
587 snprintf(desc,
sizeof(desc),
_(
"---Command: %-30.30s Attachment: %s"),
589 }
591 }
592 else
593 {
596 }
597
598 if (fd_temp != -1)
599 close(fd_temp);
600 if (fd_pager != -1)
601 close(fd_pager);
602 }
603 else
604 {
605
607 if (rv == -1)
609
612 }
613 }
614 else
615 {
616
617
619 {
620
621 if (fp)
622 {
623
624
625
626
627 struct State state = { 0 };
628
631 {
633 buf_string(pagerfile), errno, strerror(errno));
635 goto return_error;
636 }
641 }
642 else
643 {
644
645
646
648 goto return_error;
649 unlink_pagerfile = true;
650 }
652 }
653 else
654 {
657 if (!c_pager)
659
660
662 {
663 goto return_error;
664 }
665 unlink_pagerfile = true;
666 }
667
671 snprintf(desc,
sizeof(desc),
_(
"---Attachment: %s: %s"), b->
filename, type);
672 else
673 snprintf(desc,
sizeof(desc),
_(
"---Attachment: %s"), type);
674 }
675
676
677
678 if (use_pager)
679 {
682
687
693
695
697 unlink_pagerfile = false;
698 }
699 else
700 {
701 rc = 0;
702 }
703
704return_error:
705
707 {
709 {
710
712 }
713 }
714
716
717 if (unlink_pagerfile)
719
724
725 return rc;
726}
struct Body * attach_body_ancestor(struct Body *start, struct Body *body, const char *subtype)
Find the ancestor of a body with specified subtype.
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
void cid_save_attachments(struct Body *body, struct CidMapList *cid_map_list)
Save all attachments in a "multipart/related" group with a Content-ID.
void cid_to_filename(struct Buffer *filename, const struct CidMapList *cid_map_list)
Replace Content-IDs with filenames.
void cid_map_list_clear(struct CidMapList *cid_map_list)
Empty a CidMapList.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
bool envlist_set(char ***envp, const char *name, const char *value, bool overwrite)
Set an environment variable.
bool envlist_unset(char ***envp, const char *name)
Unset an environment variable.
void mutt_file_sanitize_filename(char *path, bool slash)
Replace unsafe characters in a filename.
int mutt_file_open(const char *path, uint32_t flags, mode_t mode)
Open a file.
void mutt_decode_attachment(const struct Body *b, struct State *state)
Decode an email's attachment.
@ LL_DEBUG2
Log at debug level 2.
MailcapLookup
Mailcap actions.
@ MUTT_MC_AUTOVIEW
Mailcap autoview field.
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
pid_t filter_create_fd(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err, int fdin, int fdout, int fderr, char **envlist)
Run a command on a pipe (optionally connect stdin/stdout)
@ STATE_CHARCONV
Do character set conversions.
@ STATE_PAGER
Output will be displayed in the Pager.
@ STATE_DISPLAY_ATTACH
We are displaying an attachment.
@ STATE_DISPLAY
Output is displayed to the user.
char * mutt_str_dup(const char *str)
Copy a string, safely.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
static int wait_interactive_filter(pid_t pid)
Wait after an interactive filter.
int mutt_save_attachment(FILE *fp, struct Body *b, const char *path, enum SaveAttach opt, struct Email *e)
Save an attachment.
int mutt_decode_save_attachment(FILE *fp, struct Body *b, const char *path, StateFlags flags, enum SaveAttach opt)
Decode, then save an attachment.
void mutt_add_temp_attachment(const char *filename)
Add file to list of temporary attachments.
@ MUTT_SAVE_NONE
Overwrite existing file (the default)
@ MUTT_VA_MAILCAP
Force viewing using mailcap entry.
@ MUTT_VA_REGULAR
View using default method.
@ MUTT_VA_PAGER
View attachment in pager using copiousoutput mailcap.
@ MUTT_VA_AS_TEXT
Force viewing as text.
bool mutt_needs_mailcap(struct Body *b)
Does this type need a mailcap entry do display.
#define mutt_adv_mktemp(buf)
@ SEC_ENCRYPT
Email is encrypted.
#define STAILQ_HEAD_INITIALIZER(head)
void mutt_rfc3676_space_unstuff_attachment(struct Body *b, const char *filename)
Unstuff attachments.
struct Body ** body_idx
Extra struct Body* used for decryption.
struct Body * parts
parts of a multipart or message/rfc822
struct Email * email
header information for message/rfc822
char * data
Pointer to data.
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
struct Body * body
List of MIME parts.
bool needsterminal
endwin() and system
char * command
Command to run.
bool copiousoutput
needs pager, basically
bool xneomuttkeep
do not remove the file on command exit
bool xneomuttnowrap
do not wrap the output in the pager
struct WindowState state
Current state of the Window.
char ** env
Private copy of the environment variables.
Keep track when processing files.
StateFlags flags
Flags, e.g. STATE_DISPLAY.
FILE * fp_out
File to write to.
FILE * fp_in
File to read from.
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.