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.
421{
422 bool use_mailcap = false;
423 bool use_pipe = false;
424 bool use_pager = true;
425 char type[256] = { 0 };
426 char desc[512] = { 0 };
427 char *fname = NULL;
429 int rc = -1;
430 bool has_tempfile = false;
431 bool unlink_pagerfile = false;
432
436 {
437 return rc;
438 }
439
443
448
449 char columns[16] = { 0 };
450 snprintf(columns,
sizeof(columns),
"%d", win->
state.
cols);
452
453 if (use_mailcap)
454 {
458 {
460 {
461
463 mutt_error(
_(
"No matching mailcap entry found. Viewing as text."));
465 use_mailcap = false;
466 }
467 else
468 {
469 goto return_error;
470 }
471 }
472 }
473
474 if (use_mailcap)
475 {
477 {
478 mutt_error(
_(
"MIME type not defined. Can't view attachment."));
479 goto return_error;
480 }
482
484
485
489
491 goto return_error;
492 has_tempfile = true;
493
495
496
498 {
499 struct Body *related_ancestor = NULL;
502 else
504 if (related_ancestor)
505 {
508
510
512
514 }
515 }
516
519 }
520
521 if (use_pager)
522 {
523 if (fp && !use_mailcap && b->
filename)
524 {
525
528 }
529 else
530 {
532 }
533 }
534
535 if (use_mailcap)
536 {
537 pid_t pid = 0;
538 int fd_temp = -1;
539 int fd_pager = -1;
540
541 if (!use_pager)
543
545 if (use_pager || use_pipe)
546 {
547 if (use_pager &&
549 O_CREAT | O_EXCL | O_WRONLY, 0600)) == -1))
550 {
552 goto return_error;
553 }
554 unlink_pagerfile = true;
555
556 if (use_pipe && ((fd_temp = open(
buf_string(tempfile), 0)) == -1))
557 {
558 if (fd_pager != -1)
559 close(fd_pager);
561 goto return_error;
562 }
563 unlink_pagerfile = true;
564
567
568 if (pid == -1)
569 {
570 if (fd_pager != -1)
571 close(fd_pager);
572
573 if (fd_temp != -1)
574 close(fd_temp);
575
577 goto return_error;
578 }
579
580 if (use_pager)
581 {
583 {
584 snprintf(desc,
sizeof(desc),
_(
"---Command: %-20.20s Description: %s"),
586 }
587 else
588 {
589 snprintf(desc,
sizeof(desc),
_(
"---Command: %-30.30s Attachment: %s"),
591 }
593 }
594 else
595 {
598 }
599
600 if (fd_temp != -1)
601 close(fd_temp);
602 if (fd_pager != -1)
603 close(fd_pager);
604 }
605 else
606 {
607
609 if (rv == -1)
611
614 }
615 }
616 else
617 {
618
619
621 {
622
623 if (fp)
624 {
625
626
627
628
629 struct State state = { 0 };
630
633 {
635 buf_string(pagerfile), errno, strerror(errno));
637 goto return_error;
638 }
643 }
644 else
645 {
646
647
648
650 goto return_error;
651 unlink_pagerfile = true;
652 }
654 }
655 else
656 {
659 if (!c_pager)
661
662
664 {
665 goto return_error;
666 }
667 unlink_pagerfile = true;
668 }
669
673 snprintf(desc,
sizeof(desc),
_(
"---Attachment: %s: %s"), b->
filename, type);
674 else
675 snprintf(desc,
sizeof(desc),
_(
"---Attachment: %s"), type);
676 }
677
678
679
680 if (use_pager)
681 {
684
689
695
697
699 unlink_pagerfile = false;
700 }
701 else
702 {
703 rc = 0;
704 }
705
706return_error:
707
709 {
711 {
712
714 }
715 }
716
718
719 if (unlink_pagerfile)
721
726
727 return rc;
728}
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.