NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
recvattach.c File Reference

Attachment Selection Dialog. More...

#include "config.h"
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "recvattach.h"
#include "menu/lib.h"
#include "ncrypt/lib.h"
#include "question/lib.h"
#include "send/lib.h"
#include "attachments.h"
#include "commands.h"
#include "format_flags.h"
#include "handler.h"
#include "hdrline.h"
#include "hook.h"
#include "mailcap.h"
#include "mutt_attach.h"
#include "mutt_thread.h"
#include "muttlib.h"
#include "opcodes.h"
#include "options.h"
#include "recvcmd.h"
#include "rfc3676.h"
#include <libintl.h>
+ Include dependency graph for recvattach.c:

Go to the source code of this file.

Functions

static void mutt_update_recvattach_menu (struct ConfigSubset *sub, struct AttachCtx *actx, struct Menu *menu, bool init)
 Update the Attachment Menu. More...
 
static struct AttachPtrcurrent_attachment (struct AttachCtx *actx, struct Menu *menu)
 Get the current attachment. More...
 
static bool check_attach (void)
 Check if in attach-message mode. More...
 
static bool check_readonly (struct Mailbox *m)
 Check if the Mailbox is readonly. More...
 
static void mutt_update_v2r (struct AttachCtx *actx)
 Update the virtual list of attachments. More...
 
void mutt_update_tree (struct AttachCtx *actx)
 Refresh the list of attachments. More...
 
const char * attach_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the attachment menu - Implements format_t -
Expando Description
%C Character set
%c Character set: convert?
%D Deleted flag
%d Description
%e MIME content-transfer-encoding
%f Filename
%F Filename for content-disposition header
%I Content-disposition, either I (inline) or A (attachment)
%m Major MIME type
%M MIME subtype
%n Attachment number
%Q 'Q', if MIME part qualifies for attachment counting
%s Size
%t Tagged flag
%T Tree chars
%u Unlink
%X Number of qualifying MIME parts in this part and its children
More...
 
static void attach_make_entry (struct Menu *menu, char *buf, size_t buflen, int line)
 Format a menu item for the attachment list - Implements Menu::make_entry() -. More...
 
int attach_tag (struct Menu *menu, int sel, int act)
 Tag an attachment - Implements Menu::tag() -. More...
 
static void prepend_savedir (struct Buffer *buf)
 Add $attach_save_dir to the beginning of a path. More...
 
static bool has_a_message (struct Body *body)
 Determine if the Body has a message (to save) More...
 
static int save_attachment_flowed_helper (FILE *fp, struct Body *b, const char *path, enum SaveAttach flags, struct Email *e)
 Helper for unstuffing attachments. More...
 
static int query_save_attachment (FILE *fp, struct Body *body, struct Email *e, char **directory)
 Ask the user if we should save the attachment. More...
 
static int save_without_prompting (FILE *fp, struct Body *body, struct Email *e)
 Save the attachment, without prompting each time. More...
 
void mutt_save_attachment_list (struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, struct Email *e, struct Menu *menu)
 Save a list of attachments. More...
 
static void query_pipe_attachment (const char *command, FILE *fp, struct Body *body, bool filter)
 Ask the user if we should pipe the attachment. More...
 
static void pipe_attachment (FILE *fp, struct Body *b, struct State *state)
 Pipe the attachment to a command. More...
 
static void pipe_attachment_list (const char *command, struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, bool filter, struct State *state)
 Pipe a list of attachments to a command. More...
 
void mutt_pipe_attachment_list (struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, bool filter)
 Pipe a list of attachments to a command. More...
 
static bool can_print (struct AttachCtx *actx, struct Body *top, bool tag)
 Do we know how to print this attachment type? More...
 
static void print_attachment_list (struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, struct State *state)
 Print a list of Attachments. More...
 
void mutt_print_attachment_list (struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
 Print a list of Attachments. More...
 
static void recvattach_extract_pgp_keys (struct AttachCtx *actx, struct Menu *menu)
 Extract PGP keys from attachments. More...
 
static int recvattach_pgp_check_traditional (struct AttachCtx *actx, struct Menu *menu)
 Is the Attachment inline PGP? More...
 
static void recvattach_edit_content_type (struct ConfigSubset *sub, struct AttachCtx *actx, struct Menu *menu, struct Email *e)
 Edit the content type of an attachment. More...
 
int mutt_attach_display_loop (struct ConfigSubset *sub, struct Menu *menu, int op, struct Email *e, struct AttachCtx *actx, bool recv)
 Event loop for the Attachment menu. More...
 
void mutt_generate_recvattach_list (struct AttachCtx *actx, struct Email *e, struct Body *parts, FILE *fp, int parent_type, int level, bool decrypted)
 Create a list of attachments. More...
 
void mutt_attach_init (struct AttachCtx *actx)
 Create a new Attachment context. More...
 
static void attach_collapse (struct AttachCtx *actx, struct Menu *menu)
 Close the tree of the current attachment. More...
 
static int attach_config_observer (struct NotifyCallback *nc)
 Notification that a Config Variable has changed - Implements observer_t. More...
 
static int attach_window_observer (struct NotifyCallback *nc)
 Notification that a Window has changed - Implements observer_t. More...
 
void dlg_select_attachment (struct ConfigSubset *sub, struct Mailbox *m, struct Email *e, FILE *fp)
 Show the attachments in a Menu. More...
 

Variables

static const struct Mapping AttachHelp []
 Help Bar for the Attachment selection dialog. More...
 

Detailed Description

Attachment Selection Dialog.

Authors
  • Michael R. Elkins
  • Thomas Roessler

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 recvattach.c.

Function Documentation

◆ mutt_update_recvattach_menu()

static void mutt_update_recvattach_menu ( struct ConfigSubset sub,
struct AttachCtx actx,
struct Menu menu,
bool  init 
)
static

Update the Attachment Menu.

Parameters
subConfig Subset
actxAttachment context
menuMenu listing Attachments
initIf true, create a new Attachments context

Definition at line 1598 of file recvattach.c.

1600 {
1601  if (init)
1602  {
1603  mutt_generate_recvattach_list(actx, actx->email, actx->email->body,
1604  actx->fp_root, -1, 0, 0);
1605  mutt_attach_init(actx);
1606  menu->mdata = actx;
1607  }
1608 
1609  mutt_update_tree(actx);
1610 
1611  menu->max = actx->vcount;
1612 
1613  const int index = menu_get_index(menu);
1614  if (index >= menu->max)
1615  menu_set_index(menu, menu->max - 1);
1617 }
struct Body * body
List of MIME parts.
Definition: email.h:91
void mutt_generate_recvattach_list(struct AttachCtx *actx, struct Email *e, struct Body *parts, FILE *fp, int parent_type, int level, bool decrypted)
Create a list of attachments.
Definition: recvattach.c:1465
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
FILE * fp_root
Used by recvattach for updating.
Definition: attach.h:52
void * mdata
Private data.
Definition: lib.h:155
void mutt_attach_init(struct AttachCtx *actx)
Create a new Attachment context.
Definition: recvattach.c:1571
int max
Number of entries in the menu.
Definition: lib.h:71
void mutt_update_tree(struct AttachCtx *actx)
Refresh the list of attachments.
Definition: recvattach.c:204
short vcount
The number of virtual attachments.
Definition: attach.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ current_attachment()

static struct AttachPtr* current_attachment ( struct AttachCtx actx,
struct Menu menu 
)
static

Get the current attachment.

Parameters
actxAttachment context
menuMenu
Return values
ptrCurrent Attachment

Definition at line 128 of file recvattach.c.

129 {
130  const int virt = menu_get_index(menu);
131  const int index = actx->v2r[virt];
132 
133  return actx->idx[index];
134 }
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_attach()

static bool check_attach ( void  )
static

Check if in attach-message mode.

Return values
trueMailbox is readonly

Definition at line 140 of file recvattach.c.

141 {
142  if (OptAttachMsg)
143  {
144  mutt_flushinp();
145  mutt_error(_("Function not permitted in attach-message mode"));
146  return true;
147  }
148 
149  return false;
150 }
#define mutt_error(...)
Definition: logging.h:88
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:668
#define _(a)
Definition: message.h:28
WHERE bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:31
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ check_readonly()

static bool check_readonly ( struct Mailbox m)
static

Check if the Mailbox is readonly.

Parameters
mMailbox
Return values
trueMailbox is readonly

Definition at line 157 of file recvattach.c.

158 {
159  if (!m || m->readonly)
160  {
161  mutt_flushinp();
162  mutt_error(_("Mailbox is read-only"));
163  return true;
164  }
165 
166  return false;
167 }
#define mutt_error(...)
Definition: logging.h:88
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:668
#define _(a)
Definition: message.h:28
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_update_v2r()

static void mutt_update_v2r ( struct AttachCtx actx)
static

Update the virtual list of attachments.

Parameters
actxAttachment context

Update the record of the number of attachments and the status of the tree.

Definition at line 175 of file recvattach.c.

176 {
177  int vindex, rindex, curlevel;
178 
179  vindex = 0;
180  rindex = 0;
181 
182  while (rindex < actx->idxlen)
183  {
184  actx->v2r[vindex++] = rindex;
185  if (actx->idx[rindex]->body->collapsed)
186  {
187  curlevel = actx->idx[rindex]->level;
188  do
189  {
190  rindex++;
191  } while ((rindex < actx->idxlen) && (actx->idx[rindex]->level > curlevel));
192  }
193  else
194  rindex++;
195  }
196 
197  actx->vcount = vindex;
198 }
bool collapsed
Used by recvattach.
Definition: body.h:83
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
int level
Nesting depth of attachment.
Definition: attach.h:40
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
short vcount
The number of virtual attachments.
Definition: attach.h:59
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the caller graph for this function:

◆ mutt_update_tree()

void mutt_update_tree ( struct AttachCtx actx)

Refresh the list of attachments.

Parameters
actxAttachment context

Definition at line 204 of file recvattach.c.

205 {
206  char buf[256];
207  char *s = NULL;
208 
209  mutt_update_v2r(actx);
210 
211  for (int vindex = 0; vindex < actx->vcount; vindex++)
212  {
213  const int rindex = actx->v2r[vindex];
214  actx->idx[rindex]->num = vindex;
215  if ((2 * (actx->idx[rindex]->level + 2)) < sizeof(buf))
216  {
217  if (actx->idx[rindex]->level)
218  {
219  s = buf + 2 * (actx->idx[rindex]->level - 1);
220  *s++ = (actx->idx[rindex]->body->next) ? MUTT_TREE_LTEE : MUTT_TREE_LLCORNER;
221  *s++ = MUTT_TREE_HLINE;
222  *s++ = MUTT_TREE_RARROW;
223  }
224  else
225  s = buf;
226  *s = '\0';
227  }
228 
229  if (actx->idx[rindex]->tree)
230  {
231  if (!mutt_str_equal(actx->idx[rindex]->tree, buf))
232  mutt_str_replace(&actx->idx[rindex]->tree, buf);
233  }
234  else
235  actx->idx[rindex]->tree = mutt_str_dup(buf);
236 
237  if (((2 * (actx->idx[rindex]->level + 2)) < sizeof(buf)) &&
238  actx->idx[rindex]->level)
239  {
240  s = buf + 2 * (actx->idx[rindex]->level - 1);
241  *s++ = (actx->idx[rindex]->body->next) ? '\005' : '\006';
242  *s++ = '\006';
243  }
244  }
245 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
struct Body * next
next attachment in the list
Definition: body.h:53
Lower left corner.
Definition: mutt_thread.h:42
char * tree
Tree characters to display.
Definition: attach.h:39
static void mutt_update_v2r(struct AttachCtx *actx)
Update the virtual list of attachments.
Definition: recvattach.c:175
Right arrow.
Definition: mutt_thread.h:48
int num
Attachment index number.
Definition: attach.h:41
Left T-piece.
Definition: mutt_thread.h:44
Horizontal line.
Definition: mutt_thread.h:45
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
int level
Nesting depth of attachment.
Definition: attach.h:40
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
short vcount
The number of virtual attachments.
Definition: attach.h:59
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ prepend_savedir()

static void prepend_savedir ( struct Buffer buf)
static

Add $attach_save_dir to the beginning of a path.

Parameters
bufBuffer for the result

Definition at line 533 of file recvattach.c.

534 {
535  if (!buf || !buf->data || (buf->data[0] == '/'))
536  return;
537 
538  struct Buffer *tmp = mutt_buffer_pool_get();
539  const char *const c_attach_save_dir =
540  cs_subset_path(NeoMutt->sub, "attach_save_dir");
541  if (c_attach_save_dir)
542  {
543  mutt_buffer_addstr(tmp, c_attach_save_dir);
544  if (tmp->dptr[-1] != '/')
545  mutt_buffer_addch(tmp, '/');
546  }
547  else
548  mutt_buffer_addstr(tmp, "./");
549 
551  mutt_buffer_copy(buf, tmp);
553 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
Container for Accounts, Notifications.
Definition: neomutt.h:36
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
char * dptr
Current read/write position.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:35
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ has_a_message()

static bool has_a_message ( struct Body body)
static

Determine if the Body has a message (to save)

Parameters
[in]bodyBody of the message
Return values
trueSuitable for saving

Definition at line 560 of file recvattach.c.

561 {
562  return (body->email && (body->encoding != ENC_BASE64) &&
563  (body->encoding != ENC_QUOTED_PRINTABLE) &&
564  mutt_is_message_type(body->type, body->subtype));
565 }
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1385
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:66
Base-64 encoded text.
Definition: mime.h:52
char * subtype
content-type subtype
Definition: body.h:37
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
Quoted-printable text.
Definition: mime.h:51
struct Email * email
header information for message/rfc822
Definition: body.h:55
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ save_attachment_flowed_helper()

static int save_attachment_flowed_helper ( FILE *  fp,
struct Body b,
const char *  path,
enum SaveAttach  flags,
struct Email e 
)
static

Helper for unstuffing attachments.

Parameters
fpAttachment to work on
bBody of email
pathPath to save the attachment
flagsFlags, e.g. MUTT_SAVE_APPEND
eEmail
Return values
0Success
-1Failure

This is a proxy between the mutt_save_attachment_list() calls and mutt_save_attachment(). It (currently) exists solely to unstuff format=flowed text attachments.

Direct modification of mutt_save_attachment() wasn't easily possible because: 1) other callers of mutt_save_attachment() should not have unstuffing performed, such as replying/forwarding attachments. 2) the attachment saving can append to a file, making the unstuffing inside difficult with current functions. 3) we can't unstuff before-hand because decoding hasn't occurred.

So, I apologize for this horrific proxy, but it was the most straightforward method.

Definition at line 592 of file recvattach.c.

594 {
595  int rc = -1;
596 
598  {
599  struct Body b_fake = { 0 };
600 
601  struct Buffer *tempfile = mutt_buffer_pool_get();
602  mutt_buffer_mktemp(tempfile);
603 
604  /* Pass MUTT_SAVE_NO_FLAGS to force mutt_file_fopen("w") */
606  if (rc != 0)
607  goto cleanup;
608 
610 
611  /* Now "really" save it. Send mode does this without touching anything,
612  * so force send-mode. */
613  memset(&b_fake, 0, sizeof(struct Body));
614  b_fake.filename = tempfile->data;
615  rc = mutt_save_attachment(NULL, &b_fake, path, flags, e);
616 
618 
619  cleanup:
620  mutt_buffer_pool_release(&tempfile);
621  }
622  else
623  {
624  rc = mutt_save_attachment(fp, b, path, flags, e);
625  }
626 
627  return rc;
628 }
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:74
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
bool mutt_rfc3676_is_format_flowed(struct Body *b)
Is the Email "format-flowed"?
Definition: rfc3676.c:391
No flags set.
Definition: mutt_attach.h:57
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
String manipulation buffer.
Definition: buffer.h:33
int mutt_save_attachment(FILE *fp, struct Body *m, const char *path, enum SaveAttach opt, struct Email *e)
Save an attachment.
Definition: mutt_attach.c:879
The body of an email.
Definition: body.h:34
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
char * data
Pointer to data.
Definition: buffer.h:35
void mutt_rfc3676_space_unstuff_attachment(struct Body *b, const char *filename)
Unstuff attachments.
Definition: rfc3676.c:515
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ query_save_attachment()

static int query_save_attachment ( FILE *  fp,
struct Body body,
struct Email e,
char **  directory 
)
static

Ask the user if we should save the attachment.

Parameters
[in]fpFile handle to the attachment (OPTIONAL)
[in]bodyAttachment
[in]eEmail
[out]directoryWhere the attachment was saved
Return values
0Success
-1Failure

Definition at line 639 of file recvattach.c.

640 {
641  char *prompt = NULL;
642  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
643  int rc = -1;
644 
645  struct Buffer *buf = mutt_buffer_pool_get();
646  struct Buffer *tfile = mutt_buffer_pool_get();
647 
648  if (body->filename)
649  {
650  if (directory && *directory)
651  {
652  mutt_buffer_concat_path(buf, *directory, mutt_path_basename(body->filename));
653  }
654  else
655  mutt_buffer_strcpy(buf, body->filename);
656  }
657  else if (has_a_message(body))
658  {
659  mutt_default_save(buf->data, buf->dsize, body->email);
661  }
662 
663  prepend_savedir(buf);
664 
665  prompt = _("Save to file: ");
666  while (prompt)
667  {
668  if ((mutt_buffer_get_field(prompt, buf, MUTT_FILE | MUTT_CLEAR, false, NULL,
669  NULL, NULL) != 0) ||
671  {
672  goto cleanup;
673  }
674 
675  prompt = NULL;
677 
678  bool is_message = (fp && has_a_message(body));
679 
680  if (is_message)
681  {
682  struct stat st;
683 
684  /* check to make sure that this file is really the one the user wants */
685  rc = mutt_save_confirm(mutt_buffer_string(buf), &st);
686  if (rc == 1)
687  {
688  prompt = _("Save to file: ");
689  continue;
690  }
691  else if (rc == -1)
692  goto cleanup;
693  mutt_buffer_copy(tfile, buf);
694  }
695  else
696  {
697  rc = mutt_check_overwrite(body->filename, mutt_buffer_string(buf), tfile,
698  &opt, directory);
699  if (rc == -1)
700  goto cleanup;
701  else if (rc == 1)
702  {
703  prompt = _("Save to file: ");
704  continue;
705  }
706  }
707 
708  mutt_message(_("Saving..."));
709  if (save_attachment_flowed_helper(fp, body, mutt_buffer_string(tfile), opt,
710  (e || !is_message) ? e : body->email) == 0)
711  {
712  // This uses ngettext to avoid duplication of messages
713  mutt_message(ngettext("Attachment saved", "%d attachments saved", 1), 1);
714  rc = 0;
715  goto cleanup;
716  }
717  else
718  {
719  prompt = _("Save to file: ");
720  continue;
721  }
722  }
723 
724 cleanup:
726  mutt_buffer_pool_release(&tfile);
727  return rc;
728 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
static bool has_a_message(struct Body *body)
Determine if the Body has a message (to save)
Definition: recvattach.c:560
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:58
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
const char * mutt_path_basename(const char *f)
Find the last component for a pathname.
Definition: path.c:329
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:268
No flags set.
Definition: mutt_attach.h:57
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
static void prepend_savedir(struct Buffer *buf)
Add $attach_save_dir to the beginning of a path.
Definition: recvattach.c:533
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:677
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1360
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
size_t dsize
Length of data.
Definition: buffer.h:37
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
char * data
Pointer to data.
Definition: buffer.h:35
#define MUTT_FILE
Do file completion.
Definition: mutt.h:54
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
int mutt_check_overwrite(const char *attname, const char *path, struct Buffer *fname, enum SaveAttach *opt, char **directory)
Ask the user if overwriting is necessary.
Definition: muttlib.c:625
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
static int save_attachment_flowed_helper(FILE *fp, struct Body *b, const char *path, enum SaveAttach flags, struct Email *e)
Helper for unstuffing attachments.
Definition: recvattach.c:592
#define mutt_message(...)
Definition: logging.h:87
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
struct Email * email
header information for message/rfc822
Definition: body.h:55
SaveAttach
Options for saving attachments.
Definition: mutt_attach.h:55
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ save_without_prompting()

static int save_without_prompting ( FILE *  fp,
struct Body body,
struct Email e 
)
static

Save the attachment, without prompting each time.

Parameters
[in]fpFile handle to the attachment (OPTIONAL)
[in]bodyAttachment
[in]eEmail
Return values
0Success
-1Failure

Definition at line 738 of file recvattach.c.

739 {
740  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
741  int rc = -1;
742  struct Buffer *buf = mutt_buffer_pool_get();
743  struct Buffer *tfile = mutt_buffer_pool_get();
744 
745  if (body->filename)
746  {
747  mutt_buffer_strcpy(buf, body->filename);
748  }
749  else if (has_a_message(body))
750  {
751  mutt_default_save(buf->data, buf->dsize, body->email);
752  }
753 
754  prepend_savedir(buf);
756 
757  bool is_message = (fp && has_a_message(body));
758 
759  if (is_message)
760  {
761  mutt_buffer_copy(tfile, buf);
762  }
763  else
764  {
765  rc = mutt_check_overwrite(body->filename, mutt_buffer_string(buf), tfile, &opt, NULL);
766  if (rc == -1) // abort or cancel
767  goto cleanup;
768  }
769 
770  rc = save_attachment_flowed_helper(fp, body, mutt_buffer_string(tfile), opt,
771  (e || !is_message) ? e : body->email);
772 
773 cleanup:
775  mutt_buffer_pool_release(&tfile);
776  return rc;
777 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
static bool has_a_message(struct Body *body)
Determine if the Body has a message (to save)
Definition: recvattach.c:560
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
No flags set.
Definition: mutt_attach.h:57
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
static void prepend_savedir(struct Buffer *buf)
Add $attach_save_dir to the beginning of a path.
Definition: recvattach.c:533
String manipulation buffer.
Definition: buffer.h:33
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:677
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
size_t dsize
Length of data.
Definition: buffer.h:37
char * data
Pointer to data.
Definition: buffer.h:35
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
int mutt_check_overwrite(const char *attname, const char *path, struct Buffer *fname, enum SaveAttach *opt, char **directory)
Ask the user if overwriting is necessary.
Definition: muttlib.c:625
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
static int save_attachment_flowed_helper(FILE *fp, struct Body *b, const char *path, enum SaveAttach flags, struct Email *e)
Helper for unstuffing attachments.
Definition: recvattach.c:592
struct Email * email
header information for message/rfc822
Definition: body.h:55
SaveAttach
Options for saving attachments.
Definition: mutt_attach.h:55
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_save_attachment_list()

void mutt_save_attachment_list ( struct AttachCtx actx,
FILE *  fp,
bool  tag,
struct Body top,
struct Email e,
struct Menu menu 
)

Save a list of attachments.

Parameters
actxAttachment context
fpFile handle for the attachment (OPTIONAL)
tagIf true, only save the tagged attachments
topFirst Attachment
eEmail
menuMenu listing attachments

Definition at line 788 of file recvattach.c.

790 {
791  char *directory = NULL;
792  int rc = 1;
793  int last = menu_get_index(menu);
794  FILE *fp_out = NULL;
795  int saved_attachments = 0;
796 
797  struct Buffer *buf = mutt_buffer_pool_get();
798  struct Buffer *tfile = mutt_buffer_pool_get();
799 
800  const bool c_attach_split = cs_subset_bool(NeoMutt->sub, "attach_split");
801  const char *const c_attach_sep = cs_subset_string(NeoMutt->sub, "attach_sep");
802  const bool c_attach_save_without_prompting =
803  cs_subset_bool(NeoMutt->sub, "attach_save_without_prompting");
804 
805  for (int i = 0; !tag || (i < actx->idxlen); i++)
806  {
807  if (tag)
808  {
809  fp = actx->idx[i]->fp;
810  top = actx->idx[i]->body;
811  }
812  if (!tag || top->tagged)
813  {
814  if (!c_attach_split)
815  {
816  if (mutt_buffer_is_empty(buf))
817  {
818  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
819 
821  prepend_savedir(buf);
822 
823  if ((mutt_buffer_get_field(_("Save to file: "), buf, MUTT_FILE | MUTT_CLEAR,
824  false, NULL, NULL, NULL) != 0) ||
826  {
827  goto cleanup;
828  }
830  if (mutt_check_overwrite(top->filename, mutt_buffer_string(buf), tfile, &opt, NULL))
831  goto cleanup;
832  rc = save_attachment_flowed_helper(fp, top, mutt_buffer_string(tfile), opt, e);
833  if ((rc == 0) && c_attach_sep && (fp_out = fopen(mutt_buffer_string(tfile), "a")))
834  {
835  fprintf(fp_out, "%s", c_attach_sep);
836  mutt_file_fclose(&fp_out);
837  }
838  }
839  else
840  {
842  MUTT_SAVE_APPEND, e);
843  if ((rc == 0) && c_attach_sep && (fp_out = fopen(mutt_buffer_string(tfile), "a")))
844  {
845  fprintf(fp_out, "%s", c_attach_sep);
846  mutt_file_fclose(&fp_out);
847  }
848  }
849  }
850  else
851  {
852  if (tag && menu && top->aptr)
853  {
854  menu_set_index(menu, top->aptr->num);
856 
857  menu_redraw(menu);
858  }
859  if (c_attach_save_without_prompting)
860  {
861  // Save each file, with no prompting, using the configured 'AttachSaveDir'
862  rc = save_without_prompting(fp, top, e);
863  if (rc == 0)
864  saved_attachments++;
865  }
866  else
867  {
868  // Save each file, prompting the user for the location each time.
869  if (query_save_attachment(fp, top, e, &directory) == -1)
870  break;
871  }
872  }
873  }
874  if (!tag)
875  break;
876  }
877 
878  FREE(&directory);
879 
880  if (tag && menu)
881  {
882  menu_set_index(menu, last);
884  }
885 
886  if (rc == 0)
887  {
888  if (!c_attach_split)
889  saved_attachments = 1;
890 
891  if (!c_attach_split || c_attach_save_without_prompting)
892  {
893  mutt_message(ngettext("Attachment saved", "%d attachments saved", saved_attachments),
894  saved_attachments);
895  }
896  }
897 
898 cleanup:
900  mutt_buffer_pool_release(&tfile);
901 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define NONULL(x)
Definition: string2.h:37
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:58
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
const char * mutt_path_basename(const char *f)
Find the last component for a pathname.
Definition: path.c:329
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:268
No flags set.
Definition: mutt_attach.h:57
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
static void prepend_savedir(struct Buffer *buf)
Add $attach_save_dir to the beginning of a path.
Definition: recvattach.c:533
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
int menu_redraw(struct Menu *menu)
Redraw the parts of the screen that have been flagged to be redrawn.
Definition: draw.c:546
short idxlen
Number of attachmentes.
Definition: attach.h:55
static int query_save_attachment(FILE *fp, struct Body *body, struct Email *e, char **directory)
Ask the user if we should save the attachment.
Definition: recvattach.c:639
Container for Accounts, Notifications.
Definition: neomutt.h:36
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
bool tagged
This attachment is tagged.
Definition: body.h:70
static int save_without_prompting(FILE *fp, struct Body *body, struct Email *e)
Save the attachment, without prompting each time.
Definition: recvattach.c:738
int num
Attachment index number.
Definition: attach.h:41
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition: body.h:57
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
#define MUTT_FILE
Do file completion.
Definition: mutt.h:54
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
int mutt_check_overwrite(const char *attname, const char *path, struct Buffer *fname, enum SaveAttach *opt, char **directory)
Ask the user if overwriting is necessary.
Definition: muttlib.c:625
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
static int save_attachment_flowed_helper(FILE *fp, struct Body *b, const char *path, enum SaveAttach flags, struct Email *e)
Helper for unstuffing attachments.
Definition: recvattach.c:592
Append to existing file.
Definition: mutt_attach.h:58
#define mutt_message(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:40
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
SaveAttach
Options for saving attachments.
Definition: mutt_attach.h:55
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ query_pipe_attachment()

static void query_pipe_attachment ( const char *  command,
FILE *  fp,
struct Body body,
bool  filter 
)
static

Ask the user if we should pipe the attachment.

Parameters
commandCommand to pipe the attachment to
fpFile handle to the attachment (OPTIONAL)
bodyAttachment
filterIs this command a filter?

Definition at line 910 of file recvattach.c.

911 {
912  char tfile[PATH_MAX];
913 
914  if (filter)
915  {
916  char warning[PATH_MAX + 256];
917  snprintf(warning, sizeof(warning),
918  _("WARNING! You are about to overwrite %s, continue?"), body->filename);
919  if (mutt_yesorno(warning, MUTT_NO) != MUTT_YES)
920  {
922  return;
923  }
924  mutt_mktemp(tfile, sizeof(tfile));
925  }
926  else
927  tfile[0] = '\0';
928 
929  if (mutt_pipe_attachment(fp, body, command, tfile))
930  {
931  if (filter)
932  {
933  mutt_file_unlink(body->filename);
934  mutt_file_rename(tfile, body->filename);
936  mutt_message(_("Attachment filtered"));
937  }
938  }
939  else
940  {
941  if (filter && tfile[0])
942  mutt_file_unlink(tfile);
943  }
944 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
void mutt_update_encoding(struct Body *a, struct ConfigSubset *sub)
Update the encoding type.
Definition: sendlib.c:904
int mutt_file_rename(const char *oldfile, const char *newfile)
Rename a file.
Definition: file.c:1350
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
#define _(a)
Definition: message.h:28
void msgwin_clear_text(void)
Clear the text in the Message Window.
Definition: msgwin.c:242
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:71
#define PATH_MAX
Definition: mutt.h:40
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:180
#define mutt_message(...)
Definition: logging.h:87
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int mutt_pipe_attachment(FILE *fp, struct Body *b, const char *path, char *outfile)
Pipe an attachment to a command.
Definition: mutt_attach.c:712
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pipe_attachment()

static void pipe_attachment ( FILE *  fp,
struct Body b,
struct State state 
)
static

Pipe the attachment to a command.

Parameters
fpFile handle to the attachment (OPTIONAL)
bAttachment
stateFile state for decoding the attachment

Definition at line 952 of file recvattach.c.

953 {
954  if (!state || !state->fp_out)
955  return;
956 
957  FILE *fp_in = NULL;
958  FILE *fp_unstuff = NULL;
959  bool is_flowed = false, unlink_unstuff = false;
960  struct Buffer *unstuff_tempfile = NULL;
961 
963  {
964  is_flowed = true;
965  unstuff_tempfile = mutt_buffer_pool_get();
966  mutt_buffer_mktemp(unstuff_tempfile);
967  }
968 
969  if (fp)
970  {
971  state->fp_in = fp;
972 
973  if (is_flowed)
974  {
975  fp_unstuff = mutt_file_fopen(mutt_buffer_string(unstuff_tempfile), "w");
976  if (fp_unstuff == NULL)
977  {
978  mutt_perror("mutt_file_fopen");
979  goto bail;
980  }
981  unlink_unstuff = true;
982 
983  FILE *filter_fp = state->fp_out;
984  state->fp_out = fp_unstuff;
985  mutt_decode_attachment(b, state);
986  mutt_file_fclose(&fp_unstuff);
987  state->fp_out = filter_fp;
988 
989  fp_unstuff = mutt_file_fopen(mutt_buffer_string(unstuff_tempfile), "r");
990  if (fp_unstuff == NULL)
991  {
992  mutt_perror("mutt_file_fopen");
993  goto bail;
994  }
995  mutt_file_copy_stream(fp_unstuff, filter_fp);
996  mutt_file_fclose(&fp_unstuff);
997  }
998  else
999  mutt_decode_attachment(b, state);
1000  }
1001  else
1002  {
1003  const char *infile = NULL;
1004 
1005  if (is_flowed)
1006  {
1007  if (mutt_save_attachment(fp, b, mutt_buffer_string(unstuff_tempfile), 0, NULL) == -1)
1008  goto bail;
1009  unlink_unstuff = true;
1011  infile = mutt_buffer_string(unstuff_tempfile);
1012  }
1013  else
1014  infile = b->filename;
1015 
1016  fp_in = fopen(infile, "r");
1017  if (!fp_in)
1018  {
1019  mutt_perror("fopen");
1020  goto bail;
1021  }
1022  mutt_file_copy_stream(fp_in, state->fp_out);
1023  mutt_file_fclose(&fp_in);
1024  }
1025 
1026  const char *const c_attach_sep = cs_subset_string(NeoMutt->sub, "attach_sep");
1027  if (c_attach_sep)
1028  state_puts(state, c_attach_sep);
1029 
1030 bail:
1031  mutt_file_fclose(&fp_unstuff);
1032  mutt_file_fclose(&fp_in);
1033 
1034  if (unlink_unstuff)
1035  mutt_file_unlink(mutt_buffer_string(unstuff_tempfile));
1036  mutt_buffer_pool_release(&unstuff_tempfile);
1037 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1861
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:74
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define state_puts(STATE, STR)
Definition: state.h:55
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
bool mutt_rfc3676_is_format_flowed(struct Body *b)
Is the Email "format-flowed"?
Definition: rfc3676.c:391
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
String manipulation buffer.
Definition: buffer.h:33
FILE * fp_out
File to write to.
Definition: state.h:47
int mutt_save_attachment(FILE *fp, struct Body *m, const char *path, enum SaveAttach opt, struct Email *e)
Save an attachment.
Definition: mutt_attach.c:879
#define mutt_perror(...)
Definition: logging.h:89
Container for Accounts, Notifications.
Definition: neomutt.h:36
FILE * fp_in
File to read from.
Definition: state.h:46
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
void mutt_rfc3676_space_unstuff_attachment(struct Body *b, const char *filename)
Unstuff attachments.
Definition: rfc3676.c:515
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pipe_attachment_list()

static void pipe_attachment_list ( const char *  command,
struct AttachCtx actx,
FILE *  fp,
bool  tag,
struct Body top,
bool  filter,
struct State state 
)
static

Pipe a list of attachments to a command.

Parameters
commandCommand to pipe the attachment to
actxAttachment context
fpFile handle to the attachment (OPTIONAL)
tagIf true, only save the tagged attachments
topFirst Attachment
filterIs this command a filter?
stateFile state for decoding the attachments

Definition at line 1049 of file recvattach.c.

1052 {
1053  for (int i = 0; !tag || (i < actx->idxlen); i++)
1054  {
1055  if (tag)
1056  {
1057  fp = actx->idx[i]->fp;
1058  top = actx->idx[i]->body;
1059  }
1060  if (!tag || top->tagged)
1061  {
1062  const bool c_attach_split = cs_subset_bool(NeoMutt->sub, "attach_split");
1063  if (!filter && !c_attach_split)
1064  pipe_attachment(fp, top, state);
1065  else
1066  query_pipe_attachment(command, fp, top, filter);
1067  }
1068  if (!tag)
1069  break;
1070  }
1071 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
short idxlen
Number of attachmentes.
Definition: attach.h:55
Container for Accounts, Notifications.
Definition: neomutt.h:36
bool tagged
This attachment is tagged.
Definition: body.h:70
static void query_pipe_attachment(const char *command, FILE *fp, struct Body *body, bool filter)
Ask the user if we should pipe the attachment.
Definition: recvattach.c:910
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
static void pipe_attachment(FILE *fp, struct Body *b, struct State *state)
Pipe the attachment to a command.
Definition: recvattach.c:952
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pipe_attachment_list()

void mutt_pipe_attachment_list ( struct AttachCtx actx,
FILE *  fp,
bool  tag,
struct Body top,
bool  filter 
)

Pipe a list of attachments to a command.

Parameters
actxAttachment context
fpFile handle to the attachment (OPTIONAL)
tagIf true, only save the tagged attachments
topFirst Attachment
filterIs this command a filter?

Definition at line 1081 of file recvattach.c.

1083 {
1084  struct State state = { 0 };
1085  struct Buffer *buf = NULL;
1086 
1087  if (fp)
1088  filter = false; /* sanity check: we can't filter in the recv case yet */
1089 
1090  buf = mutt_buffer_pool_get();
1091  /* perform charset conversion on text attachments when piping */
1092  state.flags = MUTT_CHARCONV;
1093 
1094  if (mutt_buffer_get_field((filter ? _("Filter through: ") : _("Pipe to: ")),
1095  buf, MUTT_CMD, false, NULL, NULL, NULL) != 0)
1096  {
1097  goto cleanup;
1098  }
1099 
1100  if (mutt_buffer_len(buf) == 0)
1101  goto cleanup;
1102 
1104 
1105  const bool c_attach_split = cs_subset_bool(NeoMutt->sub, "attach_split");
1106  if (!filter && !c_attach_split)
1107  {
1108  mutt_endwin();
1109  pid_t pid = filter_create(mutt_buffer_string(buf), &state.fp_out, NULL, NULL);
1110  pipe_attachment_list(mutt_buffer_string(buf), actx, fp, tag, top, filter, &state);
1111  mutt_file_fclose(&state.fp_out);
1112  const bool c_wait_key = cs_subset_bool(NeoMutt->sub, "wait_key");
1113  if ((filter_wait(pid) != 0) || c_wait_key)
1115  }
1116  else
1117  pipe_attachment_list(mutt_buffer_string(buf), actx, fp, tag, top, filter, &state);
1118 
1119 cleanup:
1121 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:268
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
FILE * fp_out
File to write to.
Definition: state.h:47
Container for Accounts, Notifications.
Definition: neomutt.h:36
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:56
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:422
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
static void pipe_attachment_list(const char *command, struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, bool filter, struct State *state)
Pipe a list of attachments to a command.
Definition: recvattach.c:1049
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:455
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
Keep track when processing files.
Definition: state.h:44
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ can_print()

static bool can_print ( struct AttachCtx actx,
struct Body top,
bool  tag 
)
static

Do we know how to print this attachment type?

Parameters
actxAttachment
topBody of email
tagApply to all tagged Attachments
Return values
true(all) the Attachment(s) are printable

Definition at line 1130 of file recvattach.c.

1131 {
1132  char type[256];
1133 
1134  for (int i = 0; !tag || (i < actx->idxlen); i++)
1135  {
1136  if (tag)
1137  top = actx->idx[i]->body;
1138  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
1139  if (!tag || top->tagged)
1140  {
1141  if (!mailcap_lookup(top, type, sizeof(type), NULL, MUTT_MC_PRINT))
1142  {
1143  if (!mutt_istr_equal("text/plain", top->subtype) &&
1144  !mutt_istr_equal("application/postscript", top->subtype))
1145  {
1146  if (!mutt_can_decode(top))
1147  {
1148  /* L10N: s gets replaced by a MIME type, e.g. "text/plain" or
1149  application/octet-stream. */
1150  mutt_error(_("I don't know how to print %s attachments"), type);
1151  return false;
1152  }
1153  }
1154  }
1155  }
1156  if (!tag)
1157  break;
1158  }
1159  return true;
1160 }
#define mutt_error(...)
Definition: logging.h:88
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
bool mailcap_lookup(struct Body *a, char *type, size_t typelen, struct MailcapEntry *entry, enum MailcapLookup opt)
Find given type in the list of mailcap files.
Definition: mailcap.c:475
Mailcap print field.
Definition: mailcap.h:59
bool tagged
This attachment is tagged.
Definition: body.h:70
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
char * subtype
content-type subtype
Definition: body.h:37
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1821
#define TYPE(body)
Definition: mime.h:89
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_attachment_list()

static void print_attachment_list ( struct AttachCtx actx,
FILE *  fp,
bool  tag,
struct Body top,
struct State state 
)
static

Print a list of Attachments.

Parameters
actxAttachment context
fpFile handle to the attachment (OPTIONAL)
tagApply to all tagged Attachments
topFirst Attachment
stateFile state for decoding the attachments

Definition at line 1170 of file recvattach.c.

1172 {
1173  char type[256];
1174 
1175  for (int i = 0; !tag || (i < actx->idxlen); i++)
1176  {
1177  if (tag)
1178  {
1179  fp = actx->idx[i]->fp;
1180  top = actx->idx[i]->body;
1181  }
1182  if (!tag || top->tagged)
1183  {
1184  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
1185  const bool c_attach_split = cs_subset_bool(NeoMutt->sub, "attach_split");
1186  if (!c_attach_split && !mailcap_lookup(top, type, sizeof(type), NULL, MUTT_MC_PRINT))
1187  {
1188  if (mutt_istr_equal("text/plain", top->subtype) ||
1189  mutt_istr_equal("application/postscript", top->subtype))
1190  {
1191  pipe_attachment(fp, top, state);
1192  }
1193  else if (mutt_can_decode(top))
1194  {
1195  /* decode and print */
1196 
1197  FILE *fp_in = NULL;
1198  struct Buffer *newfile = mutt_buffer_pool_get();
1199 
1200  mutt_buffer_mktemp(newfile);
1201  if (mutt_decode_save_attachment(fp, top, mutt_buffer_string(newfile),
1203  {
1204  if (!state->fp_out)
1205  {
1206  mutt_error(
1207  "BUG in print_attachment_list(). Please report this. ");
1208  return;
1209  }
1210 
1211  fp_in = fopen(mutt_buffer_string(newfile), "r");
1212  if (fp_in)
1213  {
1214  mutt_file_copy_stream(fp_in, state->fp_out);
1215  mutt_file_fclose(&fp_in);
1216  const char *const c_attach_sep = cs_subset_string(NeoMutt->sub, "attach_sep");
1217  if (c_attach_sep)
1218  state_puts(state, c_attach_sep);
1219  }
1220  }
1222  mutt_buffer_pool_release(&newfile);
1223  }
1224  }
1225  else
1226  mutt_print_attachment(fp, top);
1227  }
1228  if (!tag)
1229  break;
1230  }
1231 }
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:74
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define state_puts(STATE, STR)
Definition: state.h:55
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_error(...)
Definition: logging.h:88
No flags set.
Definition: mutt_attach.h:57
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
String manipulation buffer.
Definition: buffer.h:33
short idxlen
Number of attachmentes.
Definition: attach.h:55
FILE * fp_out
File to write to.
Definition: state.h:47
#define MUTT_PRINTING
Are we printing? - MUTT_DISPLAY "light".
Definition: state.h:37
Container for Accounts, Notifications.
Definition: neomutt.h:36
bool mailcap_lookup(struct Body *a, char *type, size_t typelen, struct MailcapEntry *entry, enum MailcapLookup opt)
Find given type in the list of mailcap files.
Definition: mailcap.c:475
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
Mailcap print field.
Definition: mailcap.h:59
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
bool tagged
This attachment is tagged.
Definition: body.h:70
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
char * subtype
content-type subtype
Definition: body.h:37
int mutt_decode_save_attachment(FILE *fp, struct Body *m, const char *path, int displaying, enum SaveAttach opt)
Decode, then save an attachment.
Definition: mutt_attach.c:1009
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1821
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
static void pipe_attachment(FILE *fp, struct Body *b, struct State *state)
Pipe the attachment to a command.
Definition: recvattach.c:952
#define TYPE(body)
Definition: mime.h:89
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
int mutt_print_attachment(FILE *fp, struct Body *a)
Print out an attachment.
Definition: mutt_attach.c:1108
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_print_attachment_list()

void mutt_print_attachment_list ( struct AttachCtx actx,
FILE *  fp,
bool  tag,
struct Body top 
)

Print a list of Attachments.

Parameters
actxAttachment context
fpFile handle to the attachment (OPTIONAL)
tagApply to all tagged Attachments
topFirst Attachment

Definition at line 1240 of file recvattach.c.

1241 {
1242  char prompt[128];
1243  struct State state = { 0 };
1244  int tagmsgcount = 0;
1245 
1246  if (tag)
1247  for (int i = 0; i < actx->idxlen; i++)
1248  if (actx->idx[i]->body->tagged)
1249  tagmsgcount++;
1250 
1251  snprintf(prompt, sizeof(prompt),
1252  /* L10N: Although we now the precise number of tagged messages, we
1253  do not show it to the user. So feel free to use a "generic
1254  plural" as plural translation if your language has one. */
1255  tag ? ngettext("Print tagged attachment?", "Print %d tagged attachments?", tagmsgcount) :
1256  _("Print attachment?"),
1257  tagmsgcount);
1258  const enum QuadOption c_print = cs_subset_quad(NeoMutt->sub, "print");
1259  if (query_quadoption(c_print, prompt) != MUTT_YES)
1260  return;
1261 
1262  const bool c_attach_split = cs_subset_bool(NeoMutt->sub, "attach_split");
1263  if (c_attach_split)
1264  {
1265  print_attachment_list(actx, fp, tag, top, &state);
1266  }
1267  else
1268  {
1269  if (!can_print(actx, top, tag))
1270  return;
1271  mutt_endwin();
1272  const char *const c_print_command =
1273  cs_subset_string(NeoMutt->sub, "print_command");
1274  pid_t pid = filter_create(NONULL(c_print_command), &state.fp_out, NULL, NULL);
1275  print_attachment_list(actx, fp, tag, top, &state);
1276  mutt_file_fclose(&state.fp_out);
1277  const bool c_wait_key = cs_subset_bool(NeoMutt->sub, "wait_key");
1278  if ((filter_wait(pid) != 0) || c_wait_key)
1280  }
1281 }
#define NONULL(x)
Definition: string2.h:37
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
static void print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, struct State *state)
Print a list of Attachments.
Definition: recvattach.c:1170
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
FILE * fp_out
File to write to.
Definition: state.h:47
Container for Accounts, Notifications.
Definition: neomutt.h:36
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: question.c:347
bool tagged
This attachment is tagged.
Definition: body.h:70
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:422
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
static bool can_print(struct AttachCtx *actx, struct Body *top, bool tag)
Do we know how to print this attachment type?
Definition: recvattach.c:1130
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:218
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:455
Keep track when processing files.
Definition: state.h:44
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ recvattach_extract_pgp_keys()

static void recvattach_extract_pgp_keys ( struct AttachCtx actx,
struct Menu menu 
)
static

Extract PGP keys from attachments.

Parameters
actxAttachment context
menuMenu listing attachments

Definition at line 1288 of file recvattach.c.

1289 {
1290  if (!menu->tagprefix)
1291  {
1292  struct AttachPtr *cur_att = current_attachment(actx, menu);
1293  crypt_pgp_extract_key_from_attachment(cur_att->fp, cur_att->body);
1294  }
1295  else
1296  {
1297  for (int i = 0; i < actx->idxlen; i++)
1298  {
1299  if (actx->idx[i]->body->tagged)
1300  {
1301  crypt_pgp_extract_key_from_attachment(actx->idx[i]->fp, actx->idx[i]->body);
1302  }
1303  }
1304  }
1305 }
An email to which things will be attached.
Definition: attach.h:34
short idxlen
Number of attachmentes.
Definition: attach.h:55
bool tagged
This attachment is tagged.
Definition: body.h:70
void crypt_pgp_extract_key_from_attachment(FILE *fp, struct Body *top)
Wrapper for CryptModuleSpecs::pgp_extract_key_from_attachment()
Definition: cryptglue.c:401
static struct AttachPtr * current_attachment(struct AttachCtx *actx, struct Menu *menu)
Get the current attachment.
Definition: recvattach.c:128
bool tagprefix
User has pressed <tag-prefix>
Definition: lib.h:75
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ recvattach_pgp_check_traditional()

static int recvattach_pgp_check_traditional ( struct AttachCtx actx,
struct Menu menu 
)
static

Is the Attachment inline PGP?

Parameters
actxAttachment to check
menuMenu listing Attachments
Return values
1The (tagged) Attachment(s) are inline PGP
Note
If the menu->tagprefix is set, all the tagged attachments will be checked.

Definition at line 1315 of file recvattach.c.

1316 {
1317  int rc = 0;
1318 
1319  if (!menu->tagprefix)
1320  {
1321  struct AttachPtr *cur_att = current_attachment(actx, menu);
1322  rc = crypt_pgp_check_traditional(cur_att->fp, cur_att->body, true);
1323  }
1324  else
1325  {
1326  for (int i = 0; i < actx->idxlen; i++)
1327  if (actx->idx[i]->body->tagged)
1328  rc = rc || crypt_pgp_check_traditional(actx->idx[i]->fp, actx->idx[i]->body, true);
1329  }
1330 
1331  return rc;
1332 }
An email to which things will be attached.
Definition: attach.h:34
short idxlen
Number of attachmentes.
Definition: attach.h:55
bool tagged
This attachment is tagged.
Definition: body.h:70
bool crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
Wrapper for CryptModuleSpecs::pgp_check_traditional()
Definition: cryptglue.c:288
static struct AttachPtr * current_attachment(struct AttachCtx *actx, struct Menu *menu)
Get the current attachment.
Definition: recvattach.c:128
bool tagprefix
User has pressed <tag-prefix>
Definition: lib.h:75
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ recvattach_edit_content_type()

static void recvattach_edit_content_type ( struct ConfigSubset sub,
struct AttachCtx actx,
struct Menu menu,
struct Email e 
)
static

Edit the content type of an attachment.

Parameters
subConfig Subset
actxAttachment context
menuMenu listing Attachments
eEmail

Definition at line 1341 of file recvattach.c.

1343 {
1344  struct AttachPtr *cur_att = current_attachment(actx, menu);
1345  if (!mutt_edit_content_type(e, cur_att->body, cur_att->fp))
1346  return;
1347 
1348  /* The mutt_update_recvattach_menu() will overwrite any changes
1349  * made to a decrypted cur_att->body, so warn the user. */
1350  if (cur_att->decrypted)
1351  {
1352  mutt_message(
1353  _("Structural changes to decrypted attachments are not supported"));
1354  mutt_sleep(1);
1355  }
1356  /* Editing the content type can rewrite the body structure. */
1357  for (int i = 0; i < actx->idxlen; i++)
1358  actx->idx[i]->body = NULL;
1359  mutt_actx_entries_free(actx);
1360  mutt_update_recvattach_menu(sub, actx, menu, true);
1361 }
An email to which things will be attached.
Definition: attach.h:34
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
static void mutt_update_recvattach_menu(struct ConfigSubset *sub, struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1598
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1461
void mutt_actx_entries_free(struct AttachCtx *actx)
Free entries in an Attachment Context.
Definition: attach.c:103
bool decrypted
Not part of message as stored in the email->body.
Definition: attach.h:43
static struct AttachPtr * current_attachment(struct AttachCtx *actx, struct Menu *menu)
Get the current attachment.
Definition: recvattach.c:128
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
#define mutt_message(...)
Definition: logging.h:87
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1433
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_attach_display_loop()

int mutt_attach_display_loop ( struct ConfigSubset sub,
struct Menu menu,
int  op,
struct Email e,
struct AttachCtx actx,
bool  recv 
)

Event loop for the Attachment menu.

Parameters
subConfig Subset
menuMenu listing Attachments
opOperation, e.g. OP_VIEW_ATTACH
eEmail
actxAttachment context
recvtrue if these are received attachments (rather than in compose)
Return values
numOperation performed

Definition at line 1373 of file recvattach.c.

1375 {
1376  do
1377  {
1378  switch (op)
1379  {
1380  case OP_DISPLAY_HEADERS:
1381  bool_str_toggle(NeoMutt->sub, "weed", NULL);
1382  /* fallthrough */
1383 
1384  case OP_VIEW_ATTACH:
1385  {
1386  struct AttachPtr *cur_att = current_attachment(actx, menu);
1387  op = mutt_view_attachment(cur_att->fp, cur_att->body, MUTT_VA_REGULAR,
1388  e, actx, menu->win);
1389  break;
1390  }
1391 
1392  case OP_NEXT_ENTRY:
1393  case OP_MAIN_NEXT_UNDELETED: /* hack */
1394  {
1395  const int index = menu_get_index(menu) + 1;
1396  if (index < menu->max)
1397  {
1398  menu_set_index(menu, index);
1399  op = OP_VIEW_ATTACH;
1400  }
1401  else
1402  op = OP_NULL;
1403  break;
1404  }
1405 
1406  case OP_PREV_ENTRY:
1407  case OP_MAIN_PREV_UNDELETED: /* hack */
1408  {
1409  const int index = menu_get_index(menu) - 1;
1410  if (index >= 0)
1411  {
1412  menu_set_index(menu, index);
1413  op = OP_VIEW_ATTACH;
1414  }
1415  else
1416  op = OP_NULL;
1417  break;
1418  }
1419 
1420  case OP_EDIT_TYPE:
1421  {
1422  struct AttachPtr *cur_att = current_attachment(actx, menu);
1423  /* when we edit the content-type, we should redisplay the attachment
1424  * immediately */
1425  mutt_edit_content_type(e, cur_att->body, cur_att->fp);
1426  if (recv)
1427  recvattach_edit_content_type(sub, actx, menu, e);
1428  else
1429  mutt_edit_content_type(e, cur_att->body, cur_att->fp);
1430 
1432  op = OP_VIEW_ATTACH;
1433  break;
1434  }
1435  /* functions which are passed through from the pager */
1436  case OP_CHECK_TRADITIONAL:
1438  {
1439  op = OP_NULL;
1440  break;
1441  }
1442  /* fallthrough */
1443  case OP_ATTACH_COLLAPSE:
1444  if (recv)
1445  return op;
1446  /* fallthrough */
1447  default:
1448  op = OP_NULL;
1449  }
1450  } while (op != OP_NULL);
1451 
1452  return op;
1453 }
An email to which things will be attached.
Definition: attach.h:34
#define WithCrypto
Definition: lib.h:113
View using default method.
Definition: mutt_attach.h:43
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:76
int bool_str_toggle(struct ConfigSubset *sub, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:214
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:87
static struct AttachPtr * current_attachment(struct AttachCtx *actx, struct Menu *menu)
Get the current attachment.
Definition: recvattach.c:128
static void recvattach_edit_content_type(struct ConfigSubset *sub, struct AttachCtx *actx, struct Menu *menu, struct Email *e)
Edit the content type of an attachment.
Definition: recvattach.c:1341
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: lib.h:89
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1433
int mutt_view_attachment(FILE *fp, struct Body *a, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx, struct MuttWindow *win)
View an attachment.
Definition: mutt_attach.c:415
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_generate_recvattach_list()

void mutt_generate_recvattach_list ( struct AttachCtx actx,
struct Email e,
struct Body parts,
FILE *  fp,
int  parent_type,
int  level,
bool  decrypted 
)

Create a list of attachments.

Parameters
actxAttachment context
eEmail
partsBody of email
fpFile to read from
parent_typeType, e.g. TYPE_MULTIPART
levelAttachment depth
decryptedTrue if attachment has been decrypted

Definition at line 1465 of file recvattach.c.

1468 {
1469  struct Body *m = NULL;
1470  struct Body *new_body = NULL;
1471  FILE *fp_new = NULL;
1473  int need_secured, secured;
1474 
1475  for (m = parts; m; m = m->next)
1476  {
1477  need_secured = 0;
1478  secured = 0;
1479 
1480  if (((WithCrypto & APPLICATION_SMIME) != 0) && (type = mutt_is_application_smime(m)))
1481  {
1482  need_secured = 1;
1483 
1484  if (type & SEC_ENCRYPT)
1485  {
1486  if (!crypt_valid_passphrase(APPLICATION_SMIME))
1487  goto decrypt_failed;
1488 
1489  if (e->env)
1491  }
1492 
1493  secured = !crypt_smime_decrypt_mime(fp, &fp_new, m, &new_body);
1494  /* If the decrypt/verify-opaque doesn't generate mime output, an empty
1495  * text/plain type will still be returned by mutt_read_mime_header().
1496  * We can't distinguish an actual part from a failure, so only use a
1497  * text/plain that results from a single top-level part. */
1498  if (secured && (new_body->type == TYPE_TEXT) &&
1499  mutt_istr_equal("plain", new_body->subtype) && ((parts != m) || m->next))
1500  {
1501  mutt_body_free(&new_body);
1502  mutt_file_fclose(&fp_new);
1503  goto decrypt_failed;
1504  }
1505 
1506  if (secured && (type & SEC_ENCRYPT))
1507  e->security |= SMIME_ENCRYPT;
1508  }
1509 
1510  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1512  {
1513  need_secured = 1;
1514 
1515  if (!crypt_valid_passphrase(APPLICATION_PGP))
1516  goto decrypt_failed;
1517 
1518  secured = !crypt_pgp_decrypt_mime(fp, &fp_new, m, &new_body);
1519 
1520  if (secured)
1521  e->security |= PGP_ENCRYPT;
1522  }
1523 
1524  if (need_secured && secured)
1525  {
1526  mutt_actx_add_fp(actx, fp_new);
1527  mutt_actx_add_body(actx, new_body);
1528  mutt_generate_recvattach_list(actx, e, new_body, fp_new, parent_type, level, 1);
1529  continue;
1530  }
1531 
1532  decrypt_failed:
1533  /* Fall through and show the original parts if decryption fails */
1534  if (need_secured && !secured)
1535  mutt_error(_("Can't decrypt encrypted message"));
1536 
1537  /* Strip out the top level multipart */
1538  if ((m->type == TYPE_MULTIPART) && m->parts && !need_secured &&
1539  ((parent_type == -1) && !mutt_istr_equal("alternative", m->subtype)))
1540  {
1541  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level, decrypted);
1542  }
1543  else
1544  {
1545  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1546  mutt_actx_add_attach(actx, ap);
1547 
1548  ap->body = m;
1549  ap->fp = fp;
1550  m->aptr = ap;
1551  ap->parent_type = parent_type;
1552  ap->level = level;
1553  ap->decrypted = decrypted;
1554 
1555  if (m->type == TYPE_MULTIPART)
1556  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level + 1, decrypted);
1557  else if (mutt_is_message_type(m->type, m->subtype))
1558  {
1559  mutt_generate_recvattach_list(actx, m->email, m->parts, fp, m->type,
1560  level + 1, decrypted);
1561  e->security |= m->email->security;
1562  }
1563  }
1564  }
1565 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
An email to which things will be attached.
Definition: attach.h:34
#define WithCrypto
Definition: lib.h:113
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1385
#define mutt_error(...)
Definition: logging.h:88
void mutt_generate_recvattach_list(struct AttachCtx *actx, struct Email *e, struct Body *parts, FILE *fp, int parent_type, int level, bool decrypted)
Create a list of attachments.
Definition: recvattach.c:1465
#define SMIME_ENCRYPT
Definition: lib.h:99
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:75
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition: crypt.c:623
#define PGP_ENCRYPT
Definition: lib.h:93
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: lib.h:71
The body of an email.
Definition: body.h:34
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:135
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:460
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
int parent_type
Type of parent attachment, e.g. TYPE_MULTIPART.
Definition: attach.h:38
void mutt_actx_add_body(struct AttachCtx *actx, struct Body *new_body)
Add an email box to an Attachment Context.
Definition: attach.c:83
struct Envelope * env
Envelope information.
Definition: email.h:90
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
char * subtype
content-type subtype
Definition: body.h:37
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:88
bool decrypted
Not part of message as stored in the email->body.
Definition: attach.h:43
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:87
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition: body.h:57
Type: &#39;text/*&#39;.
Definition: mime.h:38
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition: cryptglue.c:463
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:521
int crypt_smime_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:439
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
void mutt_actx_add_attach(struct AttachCtx *actx, struct AttachPtr *attach)
Add an Attachment to an Attachment Context.
Definition: attach.c:40
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
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:212
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
void mutt_actx_add_fp(struct AttachCtx *actx, FILE *fp_new)
Save a File handle to the Attachment Context.
Definition: attach.c:62
struct Email * email
header information for message/rfc822
Definition: body.h:55
int level
Nesting depth of attachment.
Definition: attach.h:40
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_attach_init()

void mutt_attach_init ( struct AttachCtx actx)

Create a new Attachment context.

Parameters
actxAttachment context

Definition at line 1571 of file recvattach.c.

1572 {
1573  /* Collapse the attachments if '$digest_collapse' is set AND if...
1574  * the outer container is of type 'multipart/digest' */
1575  bool digest = mutt_istr_equal(actx->email->body->subtype, "digest");
1576 
1577  const bool c_digest_collapse =
1578  cs_subset_bool(NeoMutt->sub, "digest_collapse");
1579  for (int i = 0; i < actx->idxlen; i++)
1580  {
1581  actx->idx[i]->body->tagged = false;
1582 
1583  /* OR an inner container is of type 'multipart/digest' */
1584  actx->idx[i]->body->collapsed =
1585  (c_digest_collapse &&
1586  (digest || ((actx->idx[i]->body->type == TYPE_MULTIPART) &&
1587  mutt_istr_equal(actx->idx[i]->body->subtype, "digest"))));
1588  }
1589 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
struct Body * body
List of MIME parts.
Definition: email.h:91
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
short idxlen
Number of attachmentes.
Definition: attach.h:55
Container for Accounts, Notifications.
Definition: neomutt.h:36
bool tagged
This attachment is tagged.
Definition: body.h:70
bool collapsed
Used by recvattach.
Definition: body.h:83
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
char * subtype
content-type subtype
Definition: body.h:37
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ attach_collapse()

static void attach_collapse ( struct AttachCtx actx,
struct Menu menu 
)
static

Close the tree of the current attachment.

Parameters
actxAttachment context
menuMenu listing Attachments

Definition at line 1624 of file recvattach.c.

1625 {
1626  int rindex, curlevel;
1627 
1628  struct AttachPtr *cur_att = current_attachment(actx, menu);
1629  cur_att->body->collapsed = !cur_att->body->collapsed;
1630  /* When expanding, expand all the children too */
1631  if (cur_att->body->collapsed)
1632  return;
1633 
1634  curlevel = cur_att->level;
1635  const int index = menu_get_index(menu);
1636  rindex = actx->v2r[index] + 1;
1637 
1638  const bool c_digest_collapse =
1639  cs_subset_bool(NeoMutt->sub, "digest_collapse");
1640  while ((rindex < actx->idxlen) && (actx->idx[rindex]->level > curlevel))
1641  {
1642  if (c_digest_collapse && (actx->idx[rindex]->body->type == TYPE_MULTIPART) &&
1643  mutt_istr_equal(actx->idx[rindex]->body->subtype, "digest"))
1644  {
1645  actx->idx[rindex]->body->collapsed = true;
1646  }
1647  else
1648  {
1649  actx->idx[rindex]->body->collapsed = false;
1650  }
1651  rindex++;
1652  }
1653 }
An email to which things will be attached.
Definition: attach.h:34
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
Container for Accounts, Notifications.
Definition: neomutt.h:36
bool collapsed
Used by recvattach.
Definition: body.h:83
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
char * subtype
content-type subtype
Definition: body.h:37
static struct AttachPtr * current_attachment(struct AttachCtx *actx, struct Menu *menu)
Get the current attachment.
Definition: recvattach.c:128
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int level
Nesting depth of attachment.
Definition: attach.h:40
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ attach_config_observer()

static int attach_config_observer ( struct NotifyCallback nc)
static

Notification that a Config Variable has changed - Implements observer_t.

The Address Book Window is affected by changes to $sort_attach.

Definition at line 1660 of file recvattach.c.

1661 {
1662  if ((nc->event_type != NT_CONFIG) || !nc->global_data || !nc->event_data)
1663  return -1;
1664 
1665  struct EventConfig *ev_c = nc->event_data;
1666 
1667  if (!mutt_str_equal(ev_c->name, "attach_format") && !mutt_str_equal(ev_c->name, "message_format"))
1668  return 0;
1669 
1670  struct Menu *menu = nc->global_data;
1672  mutt_debug(LL_DEBUG5, "config done, request WA_RECALC, MENU_REDRAW_FULL\n");
1673 
1674  return 0;
1675 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
Definition: lib.h:67
A config-change event.
Definition: subset.h:69
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
void * global_data
Data from notify_observer_add()
Definition: observer.h:45
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
void * event_data
Data from notify_send()
Definition: observer.h:44
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:42
Log at debug level 5.
Definition: logging.h:44
const char * name
Name of config item that changed.
Definition: subset.h:72
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ attach_window_observer()

static int attach_window_observer ( struct NotifyCallback nc)
static

Notification that a Window has changed - Implements observer_t.

This function is triggered by changes to the windows.

  • Delete (this window): clean up the resources held by the Help Bar

Definition at line 1684 of file recvattach.c.

1685 {
1686  if ((nc->event_type != NT_WINDOW) || !nc->global_data || !nc->event_data)
1687  return -1;
1688 
1689  if (nc->event_subtype != NT_WINDOW_DELETE)
1690  return 0;
1691 
1692  struct MuttWindow *win_menu = nc->global_data;
1693  struct EventWindow *ev_w = nc->event_data;
1694  if (ev_w->win != win_menu)
1695  return 0;
1696 
1697  struct Menu *menu = win_menu->wdata;
1698 
1701 
1702  mutt_debug(LL_DEBUG5, "window delete done\n");
1703  return 0;
1704 }
Definition: lib.h:67
struct MuttWindow * win
Window that changed.
Definition: mutt_window.h:217
An Event that happened to a Window.
Definition: mutt_window.h:215
Window is about to be deleted.
Definition: mutt_window.h:206
Container for Accounts, Notifications.
Definition: neomutt.h:36
static int attach_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t.
Definition: recvattach.c:1684
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:53
int event_subtype
Send: Event subtype, e.g. NT_ACCOUNT_ADD.
Definition: observer.h:43
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
void * global_data
Data from notify_observer_add()
Definition: observer.h:45
static int attach_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t.
Definition: recvattach.c:1660
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
void * event_data
Data from notify_send()
Definition: observer.h:44
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:228
Log at debug level 5.
Definition: logging.h:44
void * wdata
Private data.
Definition: mutt_window.h:145
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_select_attachment()

void dlg_select_attachment ( struct ConfigSubset sub,
struct Mailbox m,
struct Email e,
FILE *  fp 
)

Show the attachments in a Menu.

Parameters
subConfig Subset
mMailbox
eEmail
fpFile with the content of the email, or NULL

Definition at line 1713 of file recvattach.c.

1715 {
1716  if (!m || !e || !fp)
1717  {
1718  return;
1719  }
1720 
1721  int op = OP_NULL;
1722 
1723  /* make sure we have parsed this message */
1724  mutt_parse_mime_message(m, e, fp);
1726 
1728 
1729  struct Menu *menu = dlg->wdata;
1730  menu->make_entry = attach_make_entry;
1731  menu->tag = attach_tag;
1732 
1733  struct MuttWindow *win_menu = menu->win;
1734 
1735  // NT_COLOR is handled by the SimpleDialog
1738 
1739  struct MuttWindow *sbar = window_find_child(dlg, WT_STATUS_BAR);
1740  sbar_set_title(sbar, _("Attachments"));
1741 
1742  struct AttachCtx *actx = mutt_actx_new();
1743  actx->email = e;
1744  actx->fp_root = fp;
1745  mutt_update_recvattach_menu(sub, actx, menu, true);
1746 
1747  while (true)
1748  {
1749  if (op == OP_NULL)
1750  op = menu_loop(menu);
1751  window_redraw(dlg);
1752  if (!m)
1753  return;
1754  switch (op)
1755  {
1756  case OP_ATTACH_VIEW_MAILCAP:
1757  {
1758  struct AttachPtr *cur_att = current_attachment(actx, menu);
1759  mutt_view_attachment(cur_att->fp, cur_att->body, MUTT_VA_MAILCAP, e,
1760  actx, menu->win);
1762  break;
1763  }
1764 
1765  case OP_ATTACH_VIEW_TEXT:
1766  {
1767  struct AttachPtr *cur_att = current_attachment(actx, menu);
1768  mutt_view_attachment(cur_att->fp, cur_att->body, MUTT_VA_AS_TEXT, e,
1769  actx, menu->win);
1771  break;
1772  }
1773 
1774  case OP_ATTACH_VIEW_PAGER:
1775  {
1776  struct AttachPtr *cur_att = current_attachment(actx, menu);
1777  mutt_view_attachment(cur_att->fp, cur_att->body, MUTT_VA_PAGER, e, actx, menu->win);
1779  break;
1780  }
1781 
1782  case OP_DISPLAY_HEADERS:
1783  case OP_VIEW_ATTACH:
1784  op = mutt_attach_display_loop(sub, menu, op, e, actx, true);
1786  continue;
1787 
1788  case OP_ATTACH_COLLAPSE:
1789  {
1790  struct AttachPtr *cur_att = current_attachment(actx, menu);
1791  if (!cur_att->body->parts)
1792  {
1793  mutt_error(_("There are no subparts to show"));
1794  break;
1795  }
1796  attach_collapse(actx, menu);
1797  mutt_update_recvattach_menu(sub, actx, menu, false);
1798  break;
1799  }
1800 
1801  case OP_FORGET_PASSPHRASE:
1803  break;
1804 
1805  case OP_EXTRACT_KEYS:
1807  {
1808  recvattach_extract_pgp_keys(actx, menu);
1810  }
1811  break;
1812 
1813  case OP_CHECK_TRADITIONAL:
1814  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1816  {
1817  e->security = crypt_query(NULL);
1819  }
1820  break;
1821 
1822  case OP_PRINT:
1823  {
1824  struct AttachPtr *cur_att = current_attachment(actx, menu);
1825  mutt_print_attachment_list(actx, cur_att->fp, menu->tagprefix, cur_att->body);
1826  break;
1827  }
1828 
1829  case OP_PIPE:
1830  {
1831  struct AttachPtr *cur_att = current_attachment(actx, menu);
1832  mutt_pipe_attachment_list(actx, cur_att->fp, menu->tagprefix, cur_att->body, false);
1833  break;
1834  }
1835 
1836  case OP_SAVE:
1837  {
1838  struct AttachPtr *cur_att = current_attachment(actx, menu);
1839  mutt_save_attachment_list(actx, cur_att->fp, menu->tagprefix,
1840  cur_att->body, e, menu);
1841 
1842  const bool c_resolve = cs_subset_bool(NeoMutt->sub, "resolve");
1843  const int index = menu_get_index(menu) + 1;
1844  if (!menu->tagprefix && c_resolve && (index < menu->max))
1845  menu_set_index(menu, index);
1846  break;
1847  }
1848 
1849  case OP_DELETE:
1850  if (check_readonly(m))
1851  break;
1852 
1853 #ifdef USE_POP
1854  if (m->type == MUTT_POP)
1855  {
1856  mutt_flushinp();
1857  mutt_error(_("Can't delete attachment from POP server"));
1858  break;
1859  }
1860 #endif
1861 
1862 #ifdef USE_NNTP
1863  if (m->type == MUTT_NNTP)
1864  {
1865  mutt_flushinp();
1866  mutt_error(_("Can't delete attachment from news server"));
1867  break;
1868  }
1869 #endif
1870 
1871  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
1872  {
1873  mutt_message(_("Deletion of attachments from encrypted messages is "
1874  "unsupported"));
1875  break;
1876  }
1877  if ((WithCrypto != 0) && (e->security & (SEC_SIGN | SEC_PARTSIGN)))
1878  {
1879  mutt_message(_("Deletion of attachments from signed messages may "
1880  "invalidate the signature"));
1881  }
1882  if (!menu->tagprefix)
1883  {
1884  struct AttachPtr *cur_att = current_attachment(actx, menu);
1885  if (cur_att->parent_type == TYPE_MULTIPART)
1886  {
1887  cur_att->body->deleted = true;
1888  const bool c_resolve = cs_subset_bool(NeoMutt->sub, "resolve");
1889  const int index = menu_get_index(menu) + 1;
1890  if (c_resolve && (index < menu->max))
1891  {
1892  menu_set_index(menu, index);
1893  }
1894  else
1896  }
1897  else
1898  {
1899  mutt_message(
1900  _("Only deletion of multipart attachments is supported"));
1901  }
1902  }
1903  else
1904  {
1905  for (int i = 0; i < menu->max; i++)
1906  {
1907  if (actx->idx[i]->body->tagged)
1908  {
1909  if (actx->idx[i]->parent_type == TYPE_MULTIPART)
1910  {
1911  actx->idx[i]->body->deleted = true;
1913  }
1914  else
1915  {
1916  mutt_message(
1917  _("Only deletion of multipart attachments is supported"));
1918  }
1919  }
1920  }
1921  }
1922  break;
1923 
1924  case OP_UNDELETE:
1925  if (check_readonly(m))
1926  break;
1927  if (!menu->tagprefix)
1928  {
1929  struct AttachPtr *cur_att = current_attachment(actx, menu);
1930  cur_att->body->deleted = false;
1931  const bool c_resolve = cs_subset_bool(NeoMutt->sub, "resolve");
1932  const int index = menu_get_index(menu) + 1;
1933  if (c_resolve && (index < menu->max))
1934  {
1935  menu_set_index(menu, index);
1936  }
1937  else
1939  }
1940  else
1941  {
1942  for (int i = 0; i < menu->max; i++)
1943  {
1944  if (actx->idx[i]->body->tagged)
1945  {
1946  actx->idx[i]->body->deleted = false;
1948  }
1949  }
1950  }
1951  break;
1952 
1953  case OP_RESEND:
1954  {
1955  if (check_attach())
1956  break;
1957  struct AttachPtr *cur_att = current_attachment(actx, menu);
1958  mutt_attach_resend(cur_att->fp, m, actx,
1959  menu->tagprefix ? NULL : cur_att->body);
1961  break;
1962  }
1963 
1964  case OP_BOUNCE_MESSAGE:
1965  {
1966  if (check_attach())
1967  break;
1968  struct AttachPtr *cur_att = current_attachment(actx, menu);
1969  mutt_attach_bounce(m, cur_att->fp, actx,
1970  menu->tagprefix ? NULL : cur_att->body);
1972  break;
1973  }
1974 
1975  case OP_FORWARD_MESSAGE:
1976  {
1977  if (check_attach())
1978  break;
1979  struct AttachPtr *cur_att = current_attachment(actx, menu);
1980  mutt_attach_forward(cur_att->fp, e, actx,
1981  menu->tagprefix ? NULL : cur_att->body, SEND_NO_FLAGS);
1983  break;
1984  }
1985 
1986 #ifdef USE_NNTP
1987  case OP_FORWARD_TO_GROUP:
1988  {
1989  if (check_attach())
1990  break;
1991  struct AttachPtr *cur_att = current_attachment(actx, menu);
1992  mutt_attach_forward(cur_att->fp, e, actx,
1993  menu->tagprefix ? NULL : cur_att->body, SEND_NEWS);
1995  break;
1996  }
1997 
1998  case OP_FOLLOWUP:
1999  {
2000  if (check_attach())
2001  break;
2002 
2003  const enum QuadOption c_followup_to_poster =
2004  cs_subset_quad(NeoMutt->sub, "followup_to_poster");
2005  struct AttachPtr *cur_att = current_attachment(actx, menu);
2006  if (!cur_att->body->email->env->followup_to ||
2007  !mutt_istr_equal(cur_att->body->email->env->followup_to,
2008  "poster") ||
2009  (query_quadoption(c_followup_to_poster,
2010  _("Reply by mail as poster prefers?")) != MUTT_YES))
2011  {
2012  mutt_attach_reply(cur_att->fp, m, e, actx,
2013  menu->tagprefix ? NULL : cur_att->body, SEND_NEWS | SEND_REPLY);
2015  break;
2016  }
2017  }
2018 #endif
2019  /* fallthrough */
2020  case OP_REPLY:
2021  case OP_GROUP_REPLY:
2022  case OP_GROUP_CHAT_REPLY:
2023  case OP_LIST_REPLY:
2024  {
2025  if (check_attach())
2026  break;
2027 
2028  SendFlags flags = SEND_REPLY;
2029  if (op == OP_GROUP_REPLY)
2030  flags |= SEND_GROUP_REPLY;
2031  else if (op == OP_GROUP_CHAT_REPLY)
2032  flags |= SEND_GROUP_CHAT_REPLY;
2033  else if (op == OP_LIST_REPLY)
2034  flags |= SEND_LIST_REPLY;
2035 
2036  struct AttachPtr *cur_att = current_attachment(actx, menu);
2037  mutt_attach_reply(cur_att->fp, m, e, actx,
2038  menu->tagprefix ? NULL : cur_att->body, flags);
2040  break;
2041  }
2042 
2043  case OP_COMPOSE_TO_SENDER:
2044  {
2045  if (check_attach())
2046  break;
2047  struct AttachPtr *cur_att = current_attachment(actx, menu);
2048  mutt_attach_mail_sender(cur_att->fp, e, actx,
2049  menu->tagprefix ? NULL : cur_att->body);
2051  break;
2052  }
2053 
2054  case OP_EDIT_TYPE:
2055  recvattach_edit_content_type(sub, actx, menu, e);
2057  break;
2058 
2059  case OP_EXIT:
2060  e->attach_del = false;
2061  for (int i = 0; i < actx->idxlen; i++)
2062  {
2063  if (actx->idx[i]->body && actx->idx[i]->body->deleted)
2064  {
2065  e->attach_del = true;
2066  break;
2067  }
2068  }
2069  if (e->attach_del)
2070  e->changed = true;
2071 
2072  mutt_actx_free(&actx);
2073 
2074  simple_dialog_free(&dlg);
2075  return;
2076  }
2077 
2078  op = OP_NULL;
2079  }
2080 
2081  /* not reached */
2082 }
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:591
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:550
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
An email to which things will be attached.
Definition: attach.h:34
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
#define WithCrypto
Definition: lib.h:113
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: simple.c:165
static const struct Mapping AttachHelp[]
Help Bar for the Attachment selection dialog.
Definition: recvattach.c:111
Definition: lib.h:67
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
#define mutt_error(...)
Definition: logging.h:88
Attach Dialog, dlg_select_attachment()
Definition: mutt_window.h:78
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:75
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:668
static void attach_make_entry(struct Menu *menu, char *buf, size_t buflen, int line)
Format a menu item for the attachment list - Implements Menu::make_entry() -.
Definition: recvattach.c:505
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
void crypt_forget_passphrase(void)
Forget a passphrase and display a message.
Definition: crypt.c:93
FILE * fp_root
Used by recvattach for updating.
Definition: attach.h:52
#define _(a)
Definition: message.h:28
bool changed
Email has been edited.
Definition: email.h:48
static bool check_readonly(struct Mailbox *m)
Check if the Mailbox is readonly.
Definition: recvattach.c:157
short idxlen
Number of attachmentes.
Definition: attach.h:55
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:632
Force viewing as text.
Definition: mutt_attach.h:45
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:46
uint16_t SendFlags
Flags for mutt_send_message(), e.g. SEND_REPLY.
Definition: send.h:36
static void mutt_update_recvattach_menu(struct ConfigSubset *sub, struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1598
Container for Accounts, Notifications.
Definition: neomutt.h:36
static int attach_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t.
Definition: recvattach.c:1684
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:53
Status Bar containing extra info about the Index/Pager/etc.
Definition: mutt_window.h:102
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Definition: lib.h:105
#define SEND_NO_FLAGS
No flags are set.
Definition: send.h:39
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:76
int parent_type
Type of parent attachment, e.g. TYPE_MULTIPART.
Definition: attach.h:38
struct Envelope * env
Envelope information.
Definition: email.h:90
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: question.c:347
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:42
Select an attachment.
Definition: type.h:38
bool tagged
This attachment is tagged.
Definition: body.h:70
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
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
int mutt_attach_display_loop(struct ConfigSubset *sub, struct Menu *menu, int op, struct Email *e, struct AttachCtx *actx, bool recv)
Event loop for the Attachment menu.
Definition: recvattach.c:1373
void mutt_attach_bounce(struct Mailbox *m, FILE *fp, struct AttachCtx *actx, struct Body *cur)
Bounce function, from the attachment menu.
Definition: recvcmd.c:161
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:87
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:55
void mutt_attach_reply(FILE *fp, struct Mailbox *m, struct Email *e, struct AttachCtx *actx, struct Body *e_cur, SendFlags flags)
Attach a reply.
Definition: recvcmd.c:938
static struct AttachPtr * current_attachment(struct AttachCtx *actx, struct Menu *menu)
Get the current attachment.
Definition: recvattach.c:128
static int attach_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t.
Definition: recvattach.c:1660
static void recvattach_edit_content_type(struct ConfigSubset *sub, struct AttachCtx *actx, struct Menu *menu, struct Email *e)
Edit the content type of an attachment.
Definition: recvattach.c:1341
bool tagprefix
User has pressed <tag-prefix>
Definition: lib.h:75
static void recvattach_extract_pgp_keys(struct AttachCtx *actx, struct Menu *menu)
Extract PGP keys from attachments.
Definition: recvattach.c:1288
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
#define SEND_NEWS
Reply to a news article.
Definition: send.h:53
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:221
int(* tag)(struct Menu *menu, int sel, int act)
Definition: lib.h:130
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
static int recvattach_pgp_check_traditional(struct AttachCtx *actx, struct Menu *menu)
Is the Attachment inline PGP?
Definition: recvattach.c:1315
View attachment in pager using copiousoutput mailcap.
Definition: mutt_attach.h:46
Force viewing using mailcap entry.
Definition: mutt_attach.h:44
#define SEND_REPLY
Reply to sender.
Definition: send.h:40
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:218
int max
Number of entries in the menu.
Definition: lib.h:71
void mutt_attach_resend(FILE *fp, struct Mailbox *m, struct AttachCtx *actx, struct Body *cur)
resend-message, from the attachment menu
Definition: recvcmd.c:294
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
Definition: recvattach.c:1240
void mutt_attach_forward(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur, SendFlags flags)
Forward an Attachment.
Definition: recvcmd.c:784
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:42
#define SEC_SIGN
Email is signed.
Definition: lib.h:76
bool deleted
Attachment marked for deletion.
Definition: body.h:71
static void attach_collapse(struct AttachCtx *actx, struct Menu *menu)
Close the tree of the current attachment.
Definition: recvattach.c:1624
static bool check_attach(void)
Check if in attach-message mode.
Definition: recvattach.c:140
#define SEND_GROUP_REPLY
Reply to all.
Definition: send.h:41
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct AttachCtx * mutt_actx_new(void)
Create a new Attachment Context.
Definition: attach.c:131
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:77
SecurityFlags crypt_query(struct Body *b)
Check out the type of encryption used.
Definition: crypt.c:698
#define mutt_message(...)
Definition: logging.h:87
void mutt_save_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, struct Email *e, struct Menu *menu)
Save a list of attachments.
Definition: recvattach.c:788
void mutt_attach_mail_sender(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur)
Compose an email to the sender in the email attachment.
Definition: recvcmd.c:1115
struct MuttWindow * simple_dialog_new(enum MenuType mtype, enum WindowType wtype, const struct Mapping *help_data)
Create a simple index Dialog.
Definition: simple.c:128
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:598
#define SEND_GROUP_CHAT_REPLY
Reply to all recipients preserving To/Cc.
Definition: send.h:52
int attach_tag(struct Menu *menu, int sel, int act)
Tag an attachment - Implements Menu::tag() -.
Definition: recvattach.c:519
void * wdata
Private data.
Definition: mutt_window.h:145
struct Email * email
header information for message/rfc822
Definition: body.h:55
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: lib.h:79
void mutt_pipe_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top, bool filter)
Pipe a list of attachments to a command.
Definition: recvattach.c:1081
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
int mutt_view_attachment(FILE *fp, struct Body *a, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx, struct MuttWindow *win)
View an attachment.
Definition: mutt_attach.c:415
void mutt_actx_free(struct AttachCtx **ptr)
Free an Attachment Context.
Definition: attach.c:140
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ AttachHelp

const struct Mapping AttachHelp[]
static
Initial value:
= {
{ N_("Exit"), OP_EXIT },
{ N_("Save"), OP_SAVE },
{ N_("Pipe"), OP_PIPE },
{ N_("Print"), OP_PRINT },
{ N_("Help"), OP_HELP },
{ NULL, 0 },
}
#define N_(a)
Definition: message.h:32

Help Bar for the Attachment selection dialog.

Definition at line 111 of file recvattach.c.