NeoMutt  2020-08-21-74-g346364
Teaching an old dog new tricks
DOXYGEN
recvattach.c File Reference

Routines for managing attachments. 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 "ncrypt/lib.h"
#include "nntp/lib.h"
#include "send/lib.h"
#include "commands.h"
#include "context.h"
#include "format_flags.h"
#include "handler.h"
#include "hdrline.h"
#include "hook.h"
#include "keymap.h"
#include "mailcap.h"
#include "mutt_attach.h"
#include "mutt_globals.h"
#include "mutt_menu.h"
#include "mutt_parse.h"
#include "mutt_thread.h"
#include "muttlib.h"
#include "mx.h"
#include "opcodes.h"
#include "options.h"
#include "recvcmd.h"
#include "rfc3676.h"
#include "state.h"
#include <libintl.h>
+ Include dependency graph for recvattach.c:

Go to the source code of this file.

Macros

#define CHECK_READONLY
 
#define CUR_ATTACH   actx->idx[actx->v2r[menu->current]]
 
#define CHECK_ATTACH
 

Functions

static void mutt_update_recvattach_menu (struct AttachCtx *actx, struct Menu *menu, bool init)
 Update the Attachment Menu. 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. More...
 
static void attach_make_entry (char *buf, size_t buflen, struct Menu *menu, 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 C_AttachSaveDir 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 AttachCtx *actx, struct Menu *menu, struct Email *e)
 Edit the content type of an attachment. More...
 
int mutt_attach_display_loop (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...
 
void dlg_select_attachment (struct Email *e)
 Show the attachments in a Menu. More...
 

Variables

char * C_AttachSaveDir
 Config: Default directory where attachments are saved. More...
 
char * C_AttachSaveWithoutPrompting
 Config: If true, then don't prompt to save. More...
 
char * C_AttachSep
 Config: Separator to add between saved/printed/piped attachments. More...
 
bool C_AttachSplit
 Config: Save/print/pipe tagged messages individually. More...
 
bool C_DigestCollapse
 Config: Hide the subparts of a multipart/digest. More...
 
char * C_MessageFormat
 Config: printf-like format string for listing attached messages. More...
 
static const char * Mailbox_is_read_only = N_("Mailbox is read-only")
 
static const struct Mapping AttachHelp []
 Help Bar for the Attachment selection dialog. More...
 
static const char * Function_not_permitted
 

Detailed Description

Routines for managing attachments.

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.

Macro Definition Documentation

◆ CHECK_READONLY

#define CHECK_READONLY
Value:
{ \
mutt_flushinp(); \
mutt_error(_(Mailbox_is_read_only)); \
break; \
}
The "current" mailbox.
Definition: context.h:38
static const char * Mailbox_is_read_only
Definition: recvattach.c:81
#define _(a)
Definition: message.h:28
struct Mailbox * mailbox
Definition: context.h:50
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:119

Definition at line 83 of file recvattach.c.

◆ CUR_ATTACH

#define CUR_ATTACH   actx->idx[actx->v2r[menu->current]]

Definition at line 91 of file recvattach.c.

◆ CHECK_ATTACH

#define CHECK_ATTACH
Value:
{ \
mutt_flushinp(); \
mutt_error(_(Function_not_permitted)); \
break; \
}
#define _(a)
Definition: message.h:28
WHERE bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:31
static const char * Function_not_permitted
Definition: recvattach.c:105

Definition at line 108 of file recvattach.c.

Function Documentation

◆ mutt_update_recvattach_menu()

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

Update the Attachment Menu.

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

Definition at line 1489 of file recvattach.c.

1490 {
1491  if (init)
1492  {
1493  mutt_generate_recvattach_list(actx, actx->email, actx->email->body,
1494  actx->fp_root, -1, 0, 0);
1495  mutt_attach_init(actx);
1496  menu->mdata = actx;
1497  }
1498 
1499  mutt_update_tree(actx);
1500 
1501  menu->max = actx->vcount;
1502 
1503  if (menu->current >= menu->max)
1504  menu->current = menu->max - 1;
1505  menu_check_recenter(menu);
1506  menu->redraw |= REDRAW_INDEX;
1507 }
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:1359
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
Extra data for the current menu.
Definition: mutt_menu.h:55
void mutt_attach_init(struct AttachCtx *actx)
Create a new Attachment context.
Definition: recvattach.c:1465
int max
Number of entries in the menu.
Definition: mutt_menu.h:57
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:58
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:40
void mutt_update_tree(struct AttachCtx *actx)
Refresh the list of attachments.
Definition: recvattach.c:151
int current
Current entry.
Definition: mutt_menu.h:56
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:

◆ 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 122 of file recvattach.c.

123 {
124  int vindex, rindex, curlevel;
125 
126  vindex = 0;
127  rindex = 0;
128 
129  while (rindex < actx->idxlen)
130  {
131  actx->v2r[vindex++] = rindex;
132  if (actx->idx[rindex]->body->collapsed)
133  {
134  curlevel = actx->idx[rindex]->level;
135  do
136  {
137  rindex++;
138  } while ((rindex < actx->idxlen) && (actx->idx[rindex]->level > curlevel));
139  }
140  else
141  rindex++;
142  }
143 
144  actx->vcount = vindex;
145 }
bool collapsed
Used by recvattach.
Definition: body.h:82
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 151 of file recvattach.c.

152 {
153  char buf[256];
154  char *s = NULL;
155 
156  mutt_update_v2r(actx);
157 
158  for (int vindex = 0; vindex < actx->vcount; vindex++)
159  {
160  const int rindex = actx->v2r[vindex];
161  actx->idx[rindex]->num = vindex;
162  if ((2 * (actx->idx[rindex]->level + 2)) < sizeof(buf))
163  {
164  if (actx->idx[rindex]->level)
165  {
166  s = buf + 2 * (actx->idx[rindex]->level - 1);
167  *s++ = (actx->idx[rindex]->body->next) ? MUTT_TREE_LTEE : MUTT_TREE_LLCORNER;
168  *s++ = MUTT_TREE_HLINE;
169  *s++ = MUTT_TREE_RARROW;
170  }
171  else
172  s = buf;
173  *s = '\0';
174  }
175 
176  if (actx->idx[rindex]->tree)
177  {
178  if (!mutt_str_equal(actx->idx[rindex]->tree, buf))
179  mutt_str_replace(&actx->idx[rindex]->tree, buf);
180  }
181  else
182  actx->idx[rindex]->tree = mutt_str_dup(buf);
183 
184  if (((2 * (actx->idx[rindex]->level + 2)) < sizeof(buf)) &&
185  actx->idx[rindex]->level)
186  {
187  s = buf + 2 * (actx->idx[rindex]->level - 1);
188  *s++ = (actx->idx[rindex]->body->next) ? '\005' : '\006';
189  *s++ = '\006';
190  }
191  }
192 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
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:56
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:122
Right arrow.
Definition: mutt_thread.h:62
int num
Attachment index number.
Definition: attach.h:41
Left T-piece.
Definition: mutt_thread.h:58
Horizontal line.
Definition: mutt_thread.h:59
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:

◆ attach_format_str()

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

Definition at line 217 of file recvattach.c.

220 {
221  char fmt[128];
222  char charset[128];
223  struct AttachPtr *aptr = (struct AttachPtr *) data;
224  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
225 
226  switch (op)
227  {
228  case 'C':
229  if (!optional)
230  {
231  if (mutt_is_text_part(aptr->body) &&
232  mutt_body_get_charset(aptr->body, charset, sizeof(charset)))
233  {
234  mutt_format_s(buf, buflen, prec, charset);
235  }
236  else
237  mutt_format_s(buf, buflen, prec, "");
238  }
239  else if (!mutt_is_text_part(aptr->body) ||
240  !mutt_body_get_charset(aptr->body, charset, sizeof(charset)))
241  {
242  optional = false;
243  }
244  break;
245  case 'c':
246  /* XXX */
247  if (!optional)
248  {
249  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
250  snprintf(buf, buflen, fmt,
251  ((aptr->body->type != TYPE_TEXT) || aptr->body->noconv) ? 'n' : 'c');
252  }
253  else if ((aptr->body->type != TYPE_TEXT) || aptr->body->noconv)
254  optional = false;
255  break;
256  case 'd':
257  if (!optional)
258  {
259  if (aptr->body->description)
260  {
261  mutt_format_s(buf, buflen, prec, aptr->body->description);
262  break;
263  }
264  if (mutt_is_message_type(aptr->body->type, aptr->body->subtype) &&
265  C_MessageFormat && aptr->body->email)
266  {
267  char s[128];
268  mutt_make_string_flags(s, sizeof(s), cols, C_MessageFormat, NULL, -1,
269  aptr->body->email,
271  if (*s)
272  {
273  mutt_format_s(buf, buflen, prec, s);
274  break;
275  }
276  }
277  if (!aptr->body->d_filename && !aptr->body->filename)
278  {
279  mutt_format_s(buf, buflen, prec, "<no description>");
280  break;
281  }
282  }
283  else if (aptr->body->description ||
284  (mutt_is_message_type(aptr->body->type, aptr->body->subtype) &&
285  C_MessageFormat && aptr->body->email))
286  {
287  break;
288  }
289  /* fallthrough */
290  case 'F':
291  if (!optional)
292  {
293  if (aptr->body->d_filename)
294  {
295  mutt_format_s(buf, buflen, prec, aptr->body->d_filename);
296  break;
297  }
298  }
299  else if (!aptr->body->d_filename && !aptr->body->filename)
300  {
301  optional = false;
302  break;
303  }
304  /* fallthrough */
305  case 'f':
306  if (!optional)
307  {
308  if (aptr->body->filename && (*aptr->body->filename == '/'))
309  {
310  struct Buffer *path = mutt_buffer_pool_get();
311 
312  mutt_buffer_strcpy(path, aptr->body->filename);
314  mutt_format_s(buf, buflen, prec, mutt_b2s(path));
316  }
317  else
318  mutt_format_s(buf, buflen, prec, NONULL(aptr->body->filename));
319  }
320  else if (!aptr->body->filename)
321  optional = false;
322  break;
323  case 'D':
324  if (!optional)
325  snprintf(buf, buflen, "%c", aptr->body->deleted ? 'D' : ' ');
326  else if (!aptr->body->deleted)
327  optional = false;
328  break;
329  case 'e':
330  if (!optional)
331  mutt_format_s(buf, buflen, prec, ENCODING(aptr->body->encoding));
332  break;
333  case 'I':
334  if (optional)
335  break;
336 
337  const char dispchar[] = { 'I', 'A', 'F', '-' };
338  char ch;
339 
340  if (aptr->body->disposition < sizeof(dispchar))
341  ch = dispchar[aptr->body->disposition];
342  else
343  {
344  mutt_debug(LL_DEBUG1, "ERROR: invalid content-disposition %d\n",
345  aptr->body->disposition);
346  ch = '!';
347  }
348  snprintf(buf, buflen, "%c", ch);
349  break;
350  case 'm':
351  if (!optional)
352  mutt_format_s(buf, buflen, prec, TYPE(aptr->body));
353  break;
354  case 'M':
355  if (!optional)
356  mutt_format_s(buf, buflen, prec, aptr->body->subtype);
357  else if (!aptr->body->subtype)
358  optional = false;
359  break;
360  case 'n':
361  if (optional)
362  break;
363 
364  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
365  snprintf(buf, buflen, fmt, aptr->num + 1);
366  break;
367  case 'Q':
368  if (optional)
369  optional = aptr->body->attach_qualifies;
370  else
371  {
372  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
373  mutt_format_s(buf, buflen, fmt, "Q");
374  }
375  break;
376  case 's':
377  {
378  size_t l;
379  if (aptr->body->filename && (flags & MUTT_FORMAT_STAT_FILE))
380  {
381  struct stat st;
382  stat(aptr->body->filename, &st);
383  l = st.st_size;
384  }
385  else
386  l = aptr->body->length;
387 
388  if (!optional)
389  {
390  char tmp[128];
391  mutt_str_pretty_size(tmp, sizeof(tmp), l);
392  mutt_format_s(buf, buflen, prec, tmp);
393  }
394  else if (l == 0)
395  optional = false;
396 
397  break;
398  }
399  case 't':
400  if (!optional)
401  snprintf(buf, buflen, "%c", aptr->body->tagged ? '*' : ' ');
402  else if (!aptr->body->tagged)
403  optional = false;
404  break;
405  case 'T':
406  if (!optional)
407  mutt_format_s_tree(buf, buflen, prec, NONULL(aptr->tree));
408  else if (!aptr->tree)
409  optional = false;
410  break;
411  case 'u':
412  if (!optional)
413  snprintf(buf, buflen, "%c", aptr->body->unlink ? '-' : ' ');
414  else if (!aptr->body->unlink)
415  optional = false;
416  break;
417  case 'X':
418  if (optional)
419  optional = ((aptr->body->attach_count + aptr->body->attach_qualifies) != 0);
420  else
421  {
422  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
423  snprintf(buf, buflen, fmt, aptr->body->attach_count + aptr->body->attach_qualifies);
424  }
425  break;
426  default:
427  *buf = '\0';
428  }
429 
430  if (optional)
431  {
432  mutt_expando_format(buf, buflen, col, cols, if_str, attach_format_str, data,
434  }
435  else if (flags & MUTT_FORMAT_OPTIONAL)
436  {
437  mutt_expando_format(buf, buflen, col, cols, else_str, attach_format_str,
438  data, MUTT_FORMAT_NO_FLAGS);
439  }
440  return src;
441 }
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
An email to which things will be attached.
Definition: attach.h:34
char * C_MessageFormat
Config: printf-like format string for listing attached messages.
Definition: recvattach.c:77
void mutt_make_string_flags(char *buf, size_t buflen, int cols, const char *s, struct Mailbox *m, int inpgr, struct Email *e, MuttFormatFlags flags)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1403
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1366
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define MUTT_FORMAT_FORCESUBJ
Print the subject even if unchanged.
Definition: format_flags.h:31
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
bool noconv
Don&#39;t do character set conversion.
Definition: body.h:73
String manipulation buffer.
Definition: buffer.h:33
#define MUTT_FORMAT_STAT_FILE
Used by attach_format_str.
Definition: format_flags.h:34
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:598
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
unsigned int disposition
content-disposition, ContentDisposition
Definition: body.h:67
char * tree
Tree characters to display.
Definition: attach.h:39
bool attach_qualifies
This attachment should be counted.
Definition: body.h:83
#define ENCODING(x)
Definition: mime.h:92
char * mutt_body_get_charset(struct Body *b, char *buf, size_t buflen)
Get a body&#39;s character set.
Definition: body.c:131
signed short attach_count
Number of attachments.
Definition: body.h:59
bool tagged
This attachment is tagged.
Definition: body.h:70
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:66
char * subtype
content-type subtype
Definition: body.h:37
#define mutt_b2s(buf)
Definition: buffer.h:41
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
int num
Attachment index number.
Definition: attach.h:41
Type: &#39;text/*&#39;.
Definition: mime.h:38
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: muttlib.c:1659
char * description
content-description
Definition: body.h:40
bool mutt_is_text_part(struct Body *b)
Is this part of an email in plain text?
Definition: muttlib.c:433
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
bool deleted
Attachment marked for deletion.
Definition: body.h:71
#define TYPE(body)
Definition: mime.h:89
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:1244
Log at debug level 1.
Definition: logging.h:40
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:772
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
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.
Definition: recvattach.c:217
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct Email * email
header information for message/rfc822
Definition: body.h:55
void mutt_format_s_tree(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string with tree characters.
Definition: curs_lib.c:1256
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_make_entry()

static void attach_make_entry ( char *  buf,
size_t  buflen,
struct Menu menu,
int  line 
)
static

Format a menu item for the attachment list - Implements Menu::make_entry()

Definition at line 446 of file recvattach.c.

447 {
448  struct AttachCtx *actx = menu->mdata;
449 
450  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
452  (intptr_t)(actx->idx[actx->v2r[line]]), MUTT_FORMAT_ARROWCURSOR);
453 }
#define NONULL(x)
Definition: string2.h:37
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:120
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:55
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:772
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.
Definition: recvattach.c:217
WHERE char * C_AttachFormat
Config: printf-like format string for the attachment menu.
Definition: mutt_globals.h:87
struct MuttWindow * win_index
Definition: mutt_menu.h:63
A set of attachments.
Definition: attach.h:49
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:

◆ attach_tag()

int attach_tag ( struct Menu menu,
int  sel,
int  act 
)

Tag an attachment - Implements Menu::tag()

Definition at line 458 of file recvattach.c.

459 {
460  struct AttachCtx *actx = menu->mdata;
461  struct Body *cur = actx->idx[actx->v2r[sel]]->body;
462  bool ot = cur->tagged;
463 
464  cur->tagged = ((act >= 0) ? act : !cur->tagged);
465  return cur->tagged - ot;
466 }
The body of an email.
Definition: body.h:34
bool tagged
This attachment is tagged.
Definition: body.h:70
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:55
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
struct Body * body
Attachment.
Definition: attach.h:36
+ Here is the caller graph for this function:

◆ prepend_savedir()

static void prepend_savedir ( struct Buffer buf)
static

Add C_AttachSaveDir to the beginning of a path.

Parameters
bufBuffer for the result

Definition at line 472 of file recvattach.c.

473 {
474  if (!buf || !buf->data || (buf->data[0] == '/'))
475  return;
476 
477  struct Buffer *tmp = mutt_buffer_pool_get();
478  if (C_AttachSaveDir)
479  {
481  if (tmp->dptr[-1] != '/')
482  mutt_buffer_addch(tmp, '/');
483  }
484  else
485  mutt_buffer_addstr(tmp, "./");
486 
487  mutt_buffer_addstr(tmp, mutt_b2s(buf));
488  mutt_buffer_copy(buf, tmp);
490 }
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
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
#define mutt_b2s(buf)
Definition: buffer.h:41
char * dptr
Current read/write position.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:35
char * C_AttachSaveDir
Config: Default directory where attachments are saved.
Definition: recvattach.c:72
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
+ 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
trueif suitable for saving

Definition at line 497 of file recvattach.c.

498 {
499  return (body->email && (body->encoding != ENC_BASE64) &&
500  (body->encoding != ENC_QUOTED_PRINTABLE) &&
501  mutt_is_message_type(body->type, body->subtype));
502 }
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1366
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 529 of file recvattach.c.

531 {
532  int rc = -1;
533 
535  {
536  struct Body b_fake = { 0 };
537 
538  struct Buffer *tempfile = mutt_buffer_pool_get();
539  mutt_buffer_mktemp(tempfile);
540 
541  /* Pass MUTT_SAVE_NO_FLAGS to force mutt_file_fopen("w") */
542  rc = mutt_save_attachment(fp, b, mutt_b2s(tempfile), MUTT_SAVE_NO_FLAGS, e);
543  if (rc != 0)
544  goto cleanup;
545 
547 
548  /* Now "really" save it. Send mode does this without touching anything,
549  * so force send-mode. */
550  memset(&b_fake, 0, sizeof(struct Body));
551  b_fake.filename = tempfile->data;
552  rc = mutt_save_attachment(NULL, &b_fake, path, flags, e);
553 
554  mutt_file_unlink(mutt_b2s(tempfile));
555 
556  cleanup:
557  mutt_buffer_pool_release(&tempfile);
558  }
559  else
560  {
561  rc = mutt_save_attachment(fp, b, path, flags, e);
562  }
563 
564  return rc;
565 }
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
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:387
No flags set.
Definition: mutt_attach.h:55
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:869
The body of an email.
Definition: body.h:34
#define mutt_b2s(buf)
Definition: buffer.h:41
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:511
+ 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 576 of file recvattach.c.

577 {
578  char *prompt = NULL;
579  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
580  int rc = -1;
581 
582  struct Buffer *buf = mutt_buffer_pool_get();
583  struct Buffer *tfile = mutt_buffer_pool_get();
584 
585  if (body->filename)
586  {
587  if (directory && *directory)
588  {
589  mutt_buffer_concat_path(buf, *directory, mutt_path_basename(body->filename));
590  }
591  else
592  mutt_buffer_strcpy(buf, body->filename);
593  }
594  else if (has_a_message(body))
595  {
596  mutt_default_save(buf->data, buf->dsize, body->email);
598  }
599 
600  prepend_savedir(buf);
601 
602  prompt = _("Save to file: ");
603  while (prompt)
604  {
605  if ((mutt_buffer_get_field(prompt, buf, MUTT_FILE | MUTT_CLEAR) != 0) ||
607  {
608  goto cleanup;
609  }
610 
611  prompt = NULL;
613 
614  bool is_message = (fp && has_a_message(body));
615 
616  if (is_message)
617  {
618  struct stat st;
619 
620  /* check to make sure that this file is really the one the user wants */
621  rc = mutt_save_confirm(mutt_b2s(buf), &st);
622  if (rc == 1)
623  {
624  prompt = _("Save to file: ");
625  continue;
626  }
627  else if (rc == -1)
628  goto cleanup;
629  mutt_buffer_copy(tfile, buf);
630  }
631  else
632  {
633  rc = mutt_check_overwrite(body->filename, mutt_b2s(buf), tfile, &opt, directory);
634  if (rc == -1)
635  goto cleanup;
636  else if (rc == 1)
637  {
638  prompt = _("Save to file: ");
639  continue;
640  }
641  }
642 
643  mutt_message(_("Saving..."));
644  if (save_attachment_flowed_helper(fp, body, mutt_b2s(tfile), opt,
645  (e || !is_message) ? e : body->email) == 0)
646  {
647  mutt_message(_("Attachment saved"));
648  rc = 0;
649  goto cleanup;
650  }
651  else
652  {
653  prompt = _("Save to file: ");
654  continue;
655  }
656  }
657 
658 cleanup:
660  mutt_buffer_pool_release(&tfile);
661  return rc;
662 }
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:497
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:62
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
#define mutt_message(...)
Definition: logging.h:83
No flags set.
Definition: mutt_attach.h:55
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 C_AttachSaveDir to the beginning of a path.
Definition: recvattach.c:472
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:654
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1349
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
#define mutt_b2s(buf)
Definition: buffer.h:41
char * data
Pointer to data.
Definition: buffer.h:35
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
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:620
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:85
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:323
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:529
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:53
+ 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 672 of file recvattach.c.

673 {
674  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
675  int rc = -1;
676  struct Buffer *buf = mutt_buffer_pool_get();
677  struct Buffer *tfile = mutt_buffer_pool_get();
678 
679  if (body->filename)
680  {
681  mutt_buffer_strcpy(buf, body->filename);
682  }
683  else if (has_a_message(body))
684  {
685  mutt_default_save(buf->data, buf->dsize, body->email);
686  }
687 
688  prepend_savedir(buf);
690 
691  bool is_message = (fp && has_a_message(body));
692 
693  if (is_message)
694  {
695  mutt_buffer_copy(tfile, buf);
696  }
697  else
698  {
699  rc = mutt_check_overwrite(body->filename, mutt_b2s(buf), tfile, &opt, NULL);
700  if (rc == -1) // abort or cancel
701  goto cleanup;
702  }
703 
704  rc = save_attachment_flowed_helper(fp, body, mutt_b2s(tfile), opt,
705  (e || !is_message) ? e : body->email);
706 
707 cleanup:
709  mutt_buffer_pool_release(&tfile);
710  return rc;
711 }
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:497
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:55
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 C_AttachSaveDir to the beginning of a path.
Definition: recvattach.c:472
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:654
size_t dsize
Length of data.
Definition: buffer.h:37
#define mutt_b2s(buf)
Definition: buffer.h:41
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:620
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:323
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:529
struct Email * email
header information for message/rfc822
Definition: body.h:55
SaveAttach
Options for saving attachments.
Definition: mutt_attach.h:53
+ 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 722 of file recvattach.c.

724 {
725  char *directory = NULL;
726  int rc = 1;
727  int last = menu ? menu->current : -1;
728  FILE *fp_out = NULL;
729  int saved_attachments = 0;
730 
731  struct Buffer *buf = mutt_buffer_pool_get();
732  struct Buffer *tfile = mutt_buffer_pool_get();
733 
734  for (int i = 0; !tag || (i < actx->idxlen); i++)
735  {
736  if (tag)
737  {
738  fp = actx->idx[i]->fp;
739  top = actx->idx[i]->body;
740  }
741  if (!tag || top->tagged)
742  {
743  if (!C_AttachSplit)
744  {
745  if (mutt_buffer_is_empty(buf))
746  {
747  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
748 
750  prepend_savedir(buf);
751 
752  if ((mutt_buffer_get_field(_("Save to file: "), buf, MUTT_FILE | MUTT_CLEAR) != 0) ||
754  {
755  goto cleanup;
756  }
758  if (mutt_check_overwrite(top->filename, mutt_b2s(buf), tfile, &opt, NULL))
759  goto cleanup;
760  rc = save_attachment_flowed_helper(fp, top, mutt_b2s(tfile), opt, e);
761  if ((rc == 0) && C_AttachSep && (fp_out = fopen(mutt_b2s(tfile), "a")))
762  {
763  fprintf(fp_out, "%s", C_AttachSep);
764  mutt_file_fclose(&fp_out);
765  }
766  }
767  else
768  {
769  rc = save_attachment_flowed_helper(fp, top, mutt_b2s(tfile), MUTT_SAVE_APPEND, e);
770  if ((rc == 0) && C_AttachSep && (fp_out = fopen(mutt_b2s(tfile), "a")))
771  {
772  fprintf(fp_out, "%s", C_AttachSep);
773  mutt_file_fclose(&fp_out);
774  }
775  }
776  }
777  else
778  {
779  if (tag && menu && top->aptr)
780  {
781  menu->oldcurrent = menu->current;
782  menu->current = top->aptr->num;
783  menu_check_recenter(menu);
784  menu->redraw |= REDRAW_MOTION;
785 
786  menu_redraw(menu);
787  }
789  {
790  // Save each file, with no prompting, using the configured 'AttachSaveDir'
791  rc = save_without_prompting(fp, top, e);
792  if (rc == 0)
793  saved_attachments++;
794  }
795  else
796  {
797  // Save each file, prompting the user for the location each time.
798  if (query_save_attachment(fp, top, e, &directory) == -1)
799  break;
800  }
801  }
802  }
803  if (!tag)
804  break;
805  }
806 
807  FREE(&directory);
808 
809  if (tag && menu)
810  {
811  menu->oldcurrent = menu->current;
812  menu->current = last;
813  menu_check_recenter(menu);
814  menu->redraw |= REDRAW_MOTION;
815  }
816 
817  if (!C_AttachSplit && (rc == 0))
818  mutt_message(_("Attachment saved"));
819 
820  if (C_AttachSaveWithoutPrompting && (rc == 0))
821  {
822  mutt_message(ngettext("Attachment saved", "%d attachments saved", saved_attachments),
823  saved_attachments);
824  }
825 
826 cleanup:
828  mutt_buffer_pool_release(&tfile);
829 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
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
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:62
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
#define mutt_message(...)
Definition: logging.h:83
int oldcurrent
For driver use only.
Definition: mutt_menu.h:76
char * C_AttachSaveWithoutPrompting
Config: If true, then don&#39;t prompt to save.
Definition: recvattach.c:73
No flags set.
Definition: mutt_attach.h:55
char * C_AttachSep
Config: Separator to add between saved/printed/piped attachments.
Definition: recvattach.c:74
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 C_AttachSaveDir to the beginning of a path.
Definition: recvattach.c:472
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
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:576
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
#define REDRAW_MOTION
Redraw after moving the menu list.
Definition: mutt_menu.h:41
#define mutt_b2s(buf)
Definition: buffer.h:41
static int save_without_prompting(FILE *fp, struct Body *body, struct Email *e)
Save the attachment, without prompting each time.
Definition: recvattach.c:672
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
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
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:620
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:85
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:58
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:323
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:529
Append to existing file.
Definition: mutt_attach.h:56
#define FREE(x)
Definition: memory.h:40
int current
Current entry.
Definition: mutt_menu.h:56
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:53
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 838 of file recvattach.c.

839 {
840  char tfile[PATH_MAX];
841 
842  if (filter)
843  {
844  char warning[PATH_MAX + 256];
845  snprintf(warning, sizeof(warning),
846  _("WARNING! You are about to overwrite %s, continue?"), body->filename);
847  if (mutt_yesorno(warning, MUTT_NO) != MUTT_YES)
848  {
850  return;
851  }
852  mutt_mktemp(tfile, sizeof(tfile));
853  }
854  else
855  tfile[0] = '\0';
856 
857  if (mutt_pipe_attachment(fp, body, command, tfile))
858  {
859  if (filter)
860  {
861  mutt_file_unlink(body->filename);
862  mutt_file_rename(tfile, body->filename);
864  mutt_message(_("Attachment filtered"));
865  }
866  }
867  else
868  {
869  if (filter && tfile[0])
870  mutt_file_unlink(tfile);
871  }
872 }
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:903
#define mutt_message(...)
Definition: logging.h:83
int mutt_file_rename(const char *oldfile, const char *newfile)
Rename a file.
Definition: file.c:1347
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
#define _(a)
Definition: message.h:28
Container for Accounts, Notifications.
Definition: neomutt.h:36
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:379
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:232
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:74
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:47
#define PATH_MAX
Definition: mutt.h:44
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
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:705
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
+ 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 880 of file recvattach.c.

881 {
882  if (!state || !state->fp_out)
883  return;
884 
885  FILE *fp_in = NULL;
886  FILE *fp_unstuff = NULL;
887  bool is_flowed = false, unlink_unstuff = false;
888  struct Buffer *unstuff_tempfile = NULL;
889 
891  {
892  is_flowed = true;
893  unstuff_tempfile = mutt_buffer_pool_get();
894  mutt_buffer_mktemp(unstuff_tempfile);
895  }
896 
897  if (fp)
898  {
899  state->fp_in = fp;
900 
901  if (is_flowed)
902  {
903  fp_unstuff = mutt_file_fopen(mutt_b2s(unstuff_tempfile), "w");
904  if (fp_unstuff == NULL)
905  {
906  mutt_perror("mutt_file_fopen");
907  goto bail;
908  }
909  unlink_unstuff = true;
910 
911  FILE *filter_fp = state->fp_out;
912  state->fp_out = fp_unstuff;
913  mutt_decode_attachment(b, state);
914  mutt_file_fclose(&fp_unstuff);
915  state->fp_out = filter_fp;
916 
917  fp_unstuff = mutt_file_fopen(mutt_b2s(unstuff_tempfile), "r");
918  if (fp_unstuff == NULL)
919  {
920  mutt_perror("mutt_file_fopen");
921  goto bail;
922  }
923  mutt_file_copy_stream(fp_unstuff, filter_fp);
924  mutt_file_fclose(&fp_unstuff);
925  }
926  else
927  mutt_decode_attachment(b, state);
928  }
929  else
930  {
931  const char *infile = NULL;
932 
933  if (is_flowed)
934  {
935  if (mutt_save_attachment(fp, b, mutt_b2s(unstuff_tempfile), 0, NULL) == -1)
936  goto bail;
937  unlink_unstuff = true;
938  mutt_rfc3676_space_unstuff_attachment(b, mutt_b2s(unstuff_tempfile));
939  infile = mutt_b2s(unstuff_tempfile);
940  }
941  else
942  infile = b->filename;
943 
944  fp_in = fopen(infile, "r");
945  if (!fp_in)
946  {
947  mutt_perror("fopen");
948  goto bail;
949  }
950  mutt_file_copy_stream(fp_in, state->fp_out);
951  mutt_file_fclose(&fp_in);
952  }
953 
954  if (C_AttachSep)
955  state_puts(state, C_AttachSep);
956 
957 bail:
958  mutt_file_fclose(&fp_unstuff);
959  mutt_file_fclose(&fp_in);
960 
961  if (unlink_unstuff)
962  mutt_file_unlink(mutt_b2s(unstuff_tempfile));
963  mutt_buffer_pool_release(&unstuff_tempfile);
964 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1843
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
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
#define mutt_perror(...)
Definition: logging.h:85
bool mutt_rfc3676_is_format_flowed(struct Body *b)
Is the Email "format-flowed"?
Definition: rfc3676.c:387
char * C_AttachSep
Config: Separator to add between saved/printed/piped attachments.
Definition: recvattach.c:74
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:869
FILE * fp_in
File to read from.
Definition: state.h:46
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
#define mutt_b2s(buf)
Definition: buffer.h:41
void mutt_rfc3676_space_unstuff_attachment(struct Body *b, const char *filename)
Unstuff attachments.
Definition: rfc3676.c:511
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
+ 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 976 of file recvattach.c.

979 {
980  for (int i = 0; !tag || (i < actx->idxlen); i++)
981  {
982  if (tag)
983  {
984  fp = actx->idx[i]->fp;
985  top = actx->idx[i]->body;
986  }
987  if (!tag || top->tagged)
988  {
989  if (!filter && !C_AttachSplit)
990  pipe_attachment(fp, top, state);
991  else
992  query_pipe_attachment(command, fp, top, filter);
993  }
994  if (!tag)
995  break;
996  }
997 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
short idxlen
Number of attachmentes.
Definition: attach.h:55
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:838
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:880
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 1007 of file recvattach.c.

1009 {
1010  struct State state = { 0 };
1011  struct Buffer *buf = NULL;
1012 
1013  if (fp)
1014  filter = false; /* sanity check: we can't filter in the recv case yet */
1015 
1016  buf = mutt_buffer_pool_get();
1017  /* perform charset conversion on text attachments when piping */
1018  state.flags = MUTT_CHARCONV;
1019 
1020  if (mutt_buffer_get_field((filter ? _("Filter through: ") : _("Pipe to: ")),
1021  buf, MUTT_CMD) != 0)
1022  {
1023  goto cleanup;
1024  }
1025 
1026  if (mutt_buffer_len(buf) == 0)
1027  goto cleanup;
1028 
1030 
1031  if (!filter && !C_AttachSplit)
1032  {
1033  mutt_endwin();
1034  pid_t pid = filter_create(mutt_b2s(buf), &state.fp_out, NULL, NULL);
1035  pipe_attachment_list(mutt_b2s(buf), actx, fp, tag, top, filter, &state);
1036  mutt_file_fclose(&state.fp_out);
1037  if ((filter_wait(pid) != 0) || C_WaitKey)
1039  }
1040  else
1041  pipe_attachment_list(mutt_b2s(buf), actx, fp, tag, top, filter, &state);
1042 
1043 cleanup:
1045 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
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
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
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:60
#define mutt_b2s(buf)
Definition: buffer.h:41
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:571
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:976
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:85
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:604
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:323
Keep track when processing files.
Definition: state.h:44
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: mutt_globals.h:168
+ 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
trueIf (all) the Attachment(s) are printable

Definition at line 1054 of file recvattach.c.

1055 {
1056  char type[256];
1057 
1058  for (int i = 0; !tag || (i < actx->idxlen); i++)
1059  {
1060  if (tag)
1061  top = actx->idx[i]->body;
1062  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
1063  if (!tag || top->tagged)
1064  {
1065  if (!mailcap_lookup(top, type, sizeof(type), NULL, MUTT_MC_PRINT))
1066  {
1067  if (!mutt_istr_equal("text/plain", top->subtype) &&
1068  !mutt_istr_equal("application/postscript", top->subtype))
1069  {
1070  if (!mutt_can_decode(top))
1071  {
1072  /* L10N: s gets replaced by a MIME type, e.g. "text/plain" or
1073  application/octet-stream. */
1074  mutt_error(_("I don't know how to print %s attachments"), type);
1075  return false;
1076  }
1077  }
1078  }
1079  }
1080  if (!tag)
1081  break;
1082  }
1083  return true;
1084 }
#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:465
Mailcap print field.
Definition: mailcap.h:61
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:883
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:1803
#define TYPE(body)
Definition: mime.h:89
#define mutt_error(...)
Definition: logging.h:84
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 1094 of file recvattach.c.

1096 {
1097  char type[256];
1098 
1099  for (int i = 0; !tag || (i < actx->idxlen); i++)
1100  {
1101  if (tag)
1102  {
1103  fp = actx->idx[i]->fp;
1104  top = actx->idx[i]->body;
1105  }
1106  if (!tag || top->tagged)
1107  {
1108  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
1109  if (!C_AttachSplit && !mailcap_lookup(top, type, sizeof(type), NULL, MUTT_MC_PRINT))
1110  {
1111  if (mutt_istr_equal("text/plain", top->subtype) ||
1112  mutt_istr_equal("application/postscript", top->subtype))
1113  {
1114  pipe_attachment(fp, top, state);
1115  }
1116  else if (mutt_can_decode(top))
1117  {
1118  /* decode and print */
1119 
1120  FILE *fp_in = NULL;
1121  struct Buffer *newfile = mutt_buffer_pool_get();
1122 
1123  mutt_buffer_mktemp(newfile);
1124  if (mutt_decode_save_attachment(fp, top, mutt_b2s(newfile),
1126  {
1127  if (!state->fp_out)
1128  {
1129  mutt_error(
1130  "BUG in print_attachment_list(). Please report this. ");
1131  return;
1132  }
1133 
1134  fp_in = fopen(mutt_b2s(newfile), "r");
1135  if (fp_in)
1136  {
1137  mutt_file_copy_stream(fp_in, state->fp_out);
1138  mutt_file_fclose(&fp_in);
1139  if (C_AttachSep)
1140  state_puts(state, C_AttachSep);
1141  }
1142  }
1143  mutt_file_unlink(mutt_b2s(newfile));
1144  mutt_buffer_pool_release(&newfile);
1145  }
1146  }
1147  else
1148  mutt_print_attachment(fp, top);
1149  }
1150  if (!tag)
1151  break;
1152  }
1153 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
#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
No flags set.
Definition: mutt_attach.h:55
char * C_AttachSep
Config: Separator to add between saved/printed/piped attachments.
Definition: recvattach.c:74
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
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:465
Mailcap print field.
Definition: mailcap.h:61
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:883
char * subtype
content-type subtype
Definition: body.h:37
#define mutt_b2s(buf)
Definition: buffer.h:41
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:1000
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1803
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:880
#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
#define mutt_error(...)
Definition: logging.h:84
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:1099
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 1162 of file recvattach.c.

1163 {
1164  char prompt[128];
1165  struct State state = { 0 };
1166  int tagmsgcount = 0;
1167 
1168  if (tag)
1169  for (int i = 0; i < actx->idxlen; i++)
1170  if (actx->idx[i]->body->tagged)
1171  tagmsgcount++;
1172 
1173  snprintf(prompt, sizeof(prompt),
1174  /* L10N: Although we now the precise number of tagged messages, we
1175  do not show it to the user. So feel free to use a "generic
1176  plural" as plural translation if your language has one. */
1177  tag ? ngettext("Print tagged attachment?", "Print %d tagged attachments?", tagmsgcount) :
1178  _("Print attachment?"),
1179  tagmsgcount);
1180  if (query_quadoption(C_Print, prompt) != MUTT_YES)
1181  return;
1182 
1183  if (C_AttachSplit)
1184  {
1185  print_attachment_list(actx, fp, tag, top, &state);
1186  }
1187  else
1188  {
1189  if (!can_print(actx, top, tag))
1190  return;
1191  mutt_endwin();
1192  pid_t pid = filter_create(NONULL(C_PrintCommand), &state.fp_out, NULL, NULL);
1193  print_attachment_list(actx, fp, tag, top, &state);
1194  mutt_file_fclose(&state.fp_out);
1195  if ((filter_wait(pid) != 0) || C_WaitKey)
1197  }
1198 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
#define NONULL(x)
Definition: string2.h:37
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:1094
#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
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
WHERE char * C_PrintCommand
Config: External command to print a message.
Definition: mutt_globals.h:103
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:571
static bool can_print(struct AttachCtx *actx, struct Body *top, bool tag)
Do we know how to print this attachment type?
Definition: recvattach.c:1054
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:604
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:517
Keep track when processing files.
Definition: state.h:44
WHERE unsigned char C_Print
Config: Confirm before printing a message.
Definition: mutt_globals.h:128
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:40
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: mutt_globals.h:168
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 1205 of file recvattach.c.

1206 {
1207  if (!menu->tagprefix)
1209  else
1210  {
1211  for (int i = 0; i < actx->idxlen; i++)
1212  {
1213  if (actx->idx[i]->body->tagged)
1214  {
1215  crypt_pgp_extract_key_from_attachment(actx->idx[i]->fp, actx->idx[i]->body);
1216  }
1217  }
1218  }
1219 }
short idxlen
Number of attachmentes.
Definition: attach.h:55
#define CUR_ATTACH
Definition: recvattach.c:91
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:393
bool tagprefix
Definition: mutt_menu.h:61
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
1If the (tagged) Attachment(s) are inline PGP
Note
If the menu->tagprefix is set, all the tagged attachments will be checked.

Definition at line 1229 of file recvattach.c.

1230 {
1231  int rc = 0;
1232 
1233  if (!menu->tagprefix)
1234  rc = crypt_pgp_check_traditional(CUR_ATTACH->fp, CUR_ATTACH->body, true);
1235  else
1236  {
1237  for (int i = 0; i < actx->idxlen; i++)
1238  if (actx->idx[i]->body->tagged)
1239  rc = rc || crypt_pgp_check_traditional(actx->idx[i]->fp, actx->idx[i]->body, true);
1240  }
1241 
1242  return rc;
1243 }
short idxlen
Number of attachmentes.
Definition: attach.h:55
#define CUR_ATTACH
Definition: recvattach.c:91
bool tagged
This attachment is tagged.
Definition: body.h:70
bool tagprefix
Definition: mutt_menu.h:61
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
int crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
Wrapper for CryptModuleSpecs::pgp_check_traditional()
Definition: cryptglue.c:281
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 AttachCtx actx,
struct Menu menu,
struct Email e 
)
static

Edit the content type of an attachment.

Parameters
actxAttachment context
menuMenu listing Attachments
eEmail

Definition at line 1251 of file recvattach.c.

1253 {
1254  if (!mutt_edit_content_type(e, CUR_ATTACH->body, CUR_ATTACH->fp))
1255  return;
1256 
1257  /* The mutt_update_recvattach_menu() will overwrite any changes
1258  * made to a decrypted CUR_ATTACH->body, so warn the user. */
1259  if (CUR_ATTACH->decrypted)
1260  {
1261  mutt_message(
1262  _("Structural changes to decrypted attachments are not supported"));
1263  mutt_sleep(1);
1264  }
1265  /* Editing the content type can rewrite the body structure. */
1266  for (int i = 0; i < actx->idxlen; i++)
1267  actx->idx[i]->body = NULL;
1268  mutt_actx_entries_free(actx);
1269  mutt_update_recvattach_menu(actx, menu, true);
1270 }
#define mutt_message(...)
Definition: logging.h:83
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
#define CUR_ATTACH
Definition: recvattach.c:91
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1446
static void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1489
void mutt_actx_entries_free(struct AttachCtx *actx)
Free entries in an Attachment Context.
Definition: attach.c:103
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1272
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 Menu menu,
int  op,
struct Email e,
struct AttachCtx actx,
bool  recv 
)

Event loop for the Attachment menu.

Parameters
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 1281 of file recvattach.c.

1283 {
1284  do
1285  {
1286  switch (op)
1287  {
1288  case OP_DISPLAY_HEADERS:
1289  bool_str_toggle(NeoMutt->sub, "weed", NULL);
1290  /* fallthrough */
1291 
1292  case OP_VIEW_ATTACH:
1293  op = mutt_view_attachment(CUR_ATTACH->fp, CUR_ATTACH->body,
1294  MUTT_VA_REGULAR, e, actx, menu->win_index);
1295  break;
1296 
1297  case OP_NEXT_ENTRY:
1298  case OP_MAIN_NEXT_UNDELETED: /* hack */
1299  if (menu->current < menu->max - 1)
1300  {
1301  menu->current++;
1302  op = OP_VIEW_ATTACH;
1303  }
1304  else
1305  op = OP_NULL;
1306  break;
1307  case OP_PREV_ENTRY:
1308  case OP_MAIN_PREV_UNDELETED: /* hack */
1309  if (menu->current > 0)
1310  {
1311  menu->current--;
1312  op = OP_VIEW_ATTACH;
1313  }
1314  else
1315  op = OP_NULL;
1316  break;
1317  case OP_EDIT_TYPE:
1318  /* when we edit the content-type, we should redisplay the attachment
1319  * immediately */
1321  if (recv)
1322  recvattach_edit_content_type(actx, menu, e);
1323  else
1325 
1326  menu->redraw |= REDRAW_INDEX;
1327  op = OP_VIEW_ATTACH;
1328  break;
1329  /* functions which are passed through from the pager */
1330  case OP_CHECK_TRADITIONAL:
1332  {
1333  op = OP_NULL;
1334  break;
1335  }
1336  /* fallthrough */
1337  case OP_ATTACH_COLLAPSE:
1338  if (recv)
1339  return op;
1340  /* fallthrough */
1341  default:
1342  op = OP_NULL;
1343  }
1344  } while (op != OP_NULL);
1345 
1346  return op;
1347 }
#define WithCrypto
Definition: lib.h:123
View using default method.
Definition: mutt_attach.h:42
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define CUR_ATTACH
Definition: recvattach.c:91
int bool_str_toggle(struct ConfigSubset *sub, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:213
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:97
static void recvattach_edit_content_type(struct AttachCtx *actx, struct Menu *menu, struct Email *e)
Edit the content type of an attachment.
Definition: recvattach.c:1251
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
int max
Number of entries in the menu.
Definition: mutt_menu.h:57
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:58
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:40
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: lib.h:99
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:1272
int current
Current entry.
Definition: mutt_menu.h:56
struct MuttWindow * win_index
Definition: mutt_menu.h:63
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:416
+ 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 1359 of file recvattach.c.

1362 {
1363  struct Body *m = NULL;
1364  struct Body *new_body = NULL;
1365  FILE *fp_new = NULL;
1367  int need_secured, secured;
1368 
1369  for (m = parts; m; m = m->next)
1370  {
1371  need_secured = 0;
1372  secured = 0;
1373 
1374  if (((WithCrypto & APPLICATION_SMIME) != 0) && (type = mutt_is_application_smime(m)))
1375  {
1376  need_secured = 1;
1377 
1378  if (type & SEC_ENCRYPT)
1379  {
1380  if (!crypt_valid_passphrase(APPLICATION_SMIME))
1381  goto decrypt_failed;
1382 
1383  if (e->env)
1385  }
1386 
1387  secured = !crypt_smime_decrypt_mime(fp, &fp_new, m, &new_body);
1388  /* If the decrypt/verify-opaque doesn't generate mime output, an empty
1389  * text/plain type will still be returned by mutt_read_mime_header().
1390  * We can't distinguish an actual part from a failure, so only use a
1391  * text/plain that results from a single top-level part. */
1392  if (secured && (new_body->type == TYPE_TEXT) &&
1393  mutt_istr_equal("plain", new_body->subtype) && ((parts != m) || m->next))
1394  {
1395  mutt_body_free(&new_body);
1396  mutt_file_fclose(&fp_new);
1397  goto decrypt_failed;
1398  }
1399 
1400  if (secured && (type & SEC_ENCRYPT))
1401  e->security |= SMIME_ENCRYPT;
1402  }
1403 
1404  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1406  {
1407  need_secured = 1;
1408 
1409  if (!crypt_valid_passphrase(APPLICATION_PGP))
1410  goto decrypt_failed;
1411 
1412  secured = !crypt_pgp_decrypt_mime(fp, &fp_new, m, &new_body);
1413 
1414  if (secured)
1415  e->security |= PGP_ENCRYPT;
1416  }
1417 
1418  if (need_secured && secured)
1419  {
1420  mutt_actx_add_fp(actx, fp_new);
1421  mutt_actx_add_body(actx, new_body);
1422  mutt_generate_recvattach_list(actx, e, new_body, fp_new, parent_type, level, 1);
1423  continue;
1424  }
1425 
1426  decrypt_failed:
1427  /* Fall through and show the original parts if decryption fails */
1428  if (need_secured && !secured)
1429  mutt_error(_("Can't decrypt encrypted message"));
1430 
1431  /* Strip out the top level multipart */
1432  if ((m->type == TYPE_MULTIPART) && m->parts && !need_secured &&
1433  ((parent_type == -1) && !mutt_istr_equal("alternative", m->subtype)))
1434  {
1435  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level, decrypted);
1436  }
1437  else
1438  {
1439  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1440  mutt_actx_add_attach(actx, ap);
1441 
1442  ap->body = m;
1443  ap->fp = fp;
1444  m->aptr = ap;
1445  ap->parent_type = parent_type;
1446  ap->level = level;
1447  ap->decrypted = decrypted;
1448 
1449  if (m->type == TYPE_MULTIPART)
1450  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level + 1, decrypted);
1451  else if (mutt_is_message_type(m->type, m->subtype))
1452  {
1453  mutt_generate_recvattach_list(actx, m->email, m->parts, fp, m->type,
1454  level + 1, decrypted);
1455  e->security |= m->email->security;
1456  }
1457  }
1458  }
1459 }
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:123
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1366
void mutt_actx_add_fp(struct AttachCtx *actx, FILE *fp_new)
Save a File handle to the Attachment Context.
Definition: attach.c:62
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:1359
#define SMIME_ENCRYPT
Definition: lib.h:109
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:85
#define PGP_ENCRYPT
Definition: lib.h:103
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
void mutt_actx_add_attach(struct AttachCtx *actx, struct AttachPtr *attach)
Add an Attachment to an Attachment Context.
Definition: attach.c:40
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: lib.h:83
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:134
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:447
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
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:883
char * subtype
content-type subtype
Definition: body.h:37
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:98
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:97
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:455
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:508
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:431
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:610
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
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:207
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
#define mutt_error(...)
Definition: logging.h:84
struct Email * email
header information for message/rfc822
Definition: body.h:55
int level
Nesting depth of attachment.
Definition: attach.h:40
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 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 1465 of file recvattach.c.

1466 {
1467  /* Collapse the attachments if '$digest_collapse' is set AND if...
1468  * the outer container is of type 'multipart/digest' */
1469  bool digest = mutt_istr_equal(actx->email->body->subtype, "digest");
1470 
1471  for (int i = 0; i < actx->idxlen; i++)
1472  {
1473  actx->idx[i]->body->tagged = false;
1474 
1475  /* OR an inner container is of type 'multipart/digest' */
1476  actx->idx[i]->body->collapsed =
1477  (C_DigestCollapse &&
1478  (digest || ((actx->idx[i]->body->type == TYPE_MULTIPART) &&
1479  mutt_istr_equal(actx->idx[i]->body->subtype, "digest"))));
1480  }
1481 }
struct Body * body
List of MIME parts.
Definition: email.h:91
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
bool C_DigestCollapse
Config: Hide the subparts of a multipart/digest.
Definition: recvattach.c:76
short idxlen
Number of attachmentes.
Definition: attach.h:55
bool tagged
This attachment is tagged.
Definition: body.h:70
bool collapsed
Used by recvattach.
Definition: body.h:82
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
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 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 1514 of file recvattach.c.

1515 {
1516  int rindex, curlevel;
1517 
1518  CUR_ATTACH->body->collapsed = !CUR_ATTACH->body->collapsed;
1519  /* When expanding, expand all the children too */
1520  if (CUR_ATTACH->body->collapsed)
1521  return;
1522 
1523  curlevel = CUR_ATTACH->level;
1524  rindex = actx->v2r[menu->current] + 1;
1525 
1526  while ((rindex < actx->idxlen) && (actx->idx[rindex]->level > curlevel))
1527  {
1528  if (C_DigestCollapse && (actx->idx[rindex]->body->type == TYPE_MULTIPART) &&
1529  mutt_istr_equal(actx->idx[rindex]->body->subtype, "digest"))
1530  {
1531  actx->idx[rindex]->body->collapsed = true;
1532  }
1533  else
1534  {
1535  actx->idx[rindex]->body->collapsed = false;
1536  }
1537  rindex++;
1538  }
1539 }
bool C_DigestCollapse
Config: Hide the subparts of a multipart/digest.
Definition: recvattach.c:76
#define CUR_ATTACH
Definition: recvattach.c:91
bool collapsed
Used by recvattach.
Definition: body.h:82
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
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
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
int current
Current entry.
Definition: mutt_menu.h:56
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:

◆ dlg_select_attachment()

void dlg_select_attachment ( struct Email e)

Show the attachments in a Menu.

Parameters
eEmail

Definition at line 1545 of file recvattach.c.

1546 {
1547  int op = OP_NULL;
1548 
1549  struct Mailbox *m = Context ? Context->mailbox : NULL;
1550 
1551  /* make sure we have parsed this message */
1553 
1555 
1556  struct Message *msg = mx_msg_open(m, e->msgno);
1557  if (!msg)
1558  return;
1559 
1560  struct Menu *menu = mutt_menu_new(MENU_ATTACH);
1562  dlg->help_data = AttachHelp;
1563  dlg->help_menu = MENU_ATTACH;
1564 
1565  menu->title = _("Attachments");
1566  menu->make_entry = attach_make_entry;
1567  menu->tag = attach_tag;
1568  mutt_menu_push_current(menu);
1569 
1570  struct AttachCtx *actx = mutt_actx_new();
1571  actx->email = e;
1572  actx->fp_root = msg->fp;
1573  mutt_update_recvattach_menu(actx, menu, true);
1574 
1575  while (true)
1576  {
1577  if (op == OP_NULL)
1578  op = mutt_menu_loop(menu);
1579  window_redraw(dlg, true);
1580  if (!Context)
1581  return;
1582  switch (op)
1583  {
1584  case OP_ATTACH_VIEW_MAILCAP:
1586  e, actx, menu->win_index);
1587  menu->redraw = REDRAW_FULL;
1588  break;
1589 
1590  case OP_ATTACH_VIEW_TEXT:
1592  e, actx, menu->win_index);
1593  menu->redraw = REDRAW_FULL;
1594  break;
1595 
1596  case OP_DISPLAY_HEADERS:
1597  case OP_VIEW_ATTACH:
1598  op = mutt_attach_display_loop(menu, op, e, actx, true);
1599  menu->redraw = REDRAW_FULL;
1600  continue;
1601 
1602  case OP_ATTACH_COLLAPSE:
1603  if (!CUR_ATTACH->body->parts)
1604  {
1605  mutt_error(_("There are no subparts to show"));
1606  break;
1607  }
1608  attach_collapse(actx, menu);
1609  mutt_update_recvattach_menu(actx, menu, false);
1610  break;
1611 
1612  case OP_FORGET_PASSPHRASE:
1614  break;
1615 
1616  case OP_EXTRACT_KEYS:
1618  {
1619  recvattach_extract_pgp_keys(actx, menu);
1620  menu->redraw = REDRAW_FULL;
1621  }
1622  break;
1623 
1624  case OP_CHECK_TRADITIONAL:
1625  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1627  {
1628  e->security = crypt_query(NULL);
1629  menu->redraw = REDRAW_FULL;
1630  }
1631  break;
1632 
1633  case OP_PRINT:
1635  CUR_ATTACH->body);
1636  break;
1637 
1638  case OP_PIPE:
1640  CUR_ATTACH->body, false);
1641  break;
1642 
1643  case OP_SAVE:
1645  CUR_ATTACH->body, e, menu);
1646 
1647  if (!menu->tagprefix && C_Resolve && (menu->current < menu->max - 1))
1648  menu->current++;
1649 
1651  break;
1652 
1653  case OP_DELETE:
1655 
1656 #ifdef USE_POP
1657  if (m->type == MUTT_POP)
1658  {
1659  mutt_flushinp();
1660  mutt_error(_("Can't delete attachment from POP server"));
1661  break;
1662  }
1663 #endif
1664 
1665 #ifdef USE_NNTP
1666  if (m->type == MUTT_NNTP)
1667  {
1668  mutt_flushinp();
1669  mutt_error(_("Can't delete attachment from news server"));
1670  break;
1671  }
1672 #endif
1673 
1674  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
1675  {
1676  mutt_message(_("Deletion of attachments from encrypted messages is "
1677  "unsupported"));
1678  break;
1679  }
1680  if ((WithCrypto != 0) && (e->security & (SEC_SIGN | SEC_PARTSIGN)))
1681  {
1682  mutt_message(_("Deletion of attachments from signed messages may "
1683  "invalidate the signature"));
1684  }
1685  if (!menu->tagprefix)
1686  {
1687  if (CUR_ATTACH->parent_type == TYPE_MULTIPART)
1688  {
1689  CUR_ATTACH->body->deleted = true;
1690  if (C_Resolve && (menu->current < menu->max - 1))
1691  {
1692  menu->current++;
1693  menu->redraw = REDRAW_MOTION_RESYNC;
1694  }
1695  else
1696  menu->redraw = REDRAW_CURRENT;
1697  }
1698  else
1699  {
1700  mutt_message(
1701  _("Only deletion of multipart attachments is supported"));
1702  }
1703  }
1704  else
1705  {
1706  for (int i = 0; i < menu->max; i++)
1707  {
1708  if (actx->idx[i]->body->tagged)
1709  {
1710  if (actx->idx[i]->parent_type == TYPE_MULTIPART)
1711  {
1712  actx->idx[i]->body->deleted = true;
1713  menu->redraw = REDRAW_INDEX;
1714  }
1715  else
1716  {
1717  mutt_message(
1718  _("Only deletion of multipart attachments is supported"));
1719  }
1720  }
1721  }
1722  }
1723  break;
1724 
1725  case OP_UNDELETE:
1727  if (!menu->tagprefix)
1728  {
1729  CUR_ATTACH->body->deleted = false;
1730  if (C_Resolve && (menu->current < menu->max - 1))
1731  {
1732  menu->current++;
1733  menu->redraw = REDRAW_MOTION_RESYNC;
1734  }
1735  else
1736  menu->redraw = REDRAW_CURRENT;
1737  }
1738  else
1739  {
1740  for (int i = 0; i < menu->max; i++)
1741  {
1742  if (actx->idx[i]->body->tagged)
1743  {
1744  actx->idx[i]->body->deleted = false;
1745  menu->redraw = REDRAW_INDEX;
1746  }
1747  }
1748  }
1749  break;
1750 
1751  case OP_RESEND:
1752  CHECK_ATTACH;
1753  mutt_attach_resend(CUR_ATTACH->fp, actx,
1754  menu->tagprefix ? NULL : CUR_ATTACH->body);
1755  menu->redraw = REDRAW_FULL;
1756  break;
1757 
1758  case OP_BOUNCE_MESSAGE:
1759  CHECK_ATTACH;
1760  mutt_attach_bounce(m, CUR_ATTACH->fp, actx,
1761  menu->tagprefix ? NULL : CUR_ATTACH->body);
1762  menu->redraw = REDRAW_FULL;
1763  break;
1764 
1765  case OP_FORWARD_MESSAGE:
1766  CHECK_ATTACH;
1767  mutt_attach_forward(CUR_ATTACH->fp, e, actx,
1768  menu->tagprefix ? NULL : CUR_ATTACH->body, SEND_NO_FLAGS);
1769  menu->redraw = REDRAW_FULL;
1770  break;
1771 
1772 #ifdef USE_NNTP
1773  case OP_FORWARD_TO_GROUP:
1774  CHECK_ATTACH;
1775  mutt_attach_forward(CUR_ATTACH->fp, e, actx,
1776  menu->tagprefix ? NULL : CUR_ATTACH->body, SEND_NEWS);
1777  menu->redraw = REDRAW_FULL;
1778  break;
1779 
1780  case OP_FOLLOWUP:
1781  CHECK_ATTACH;
1782 
1783  if (!CUR_ATTACH->body->email->env->followup_to ||
1784  !mutt_istr_equal(CUR_ATTACH->body->email->env->followup_to,
1785  "poster") ||
1787  _("Reply by mail as poster prefers?")) != MUTT_YES))
1788  {
1789  mutt_attach_reply(CUR_ATTACH->fp, e, actx,
1790  menu->tagprefix ? NULL : CUR_ATTACH->body,
1791  SEND_NEWS | SEND_REPLY);
1792  menu->redraw = REDRAW_FULL;
1793  break;
1794  }
1795 #endif
1796  /* fallthrough */
1797  case OP_REPLY:
1798  case OP_GROUP_REPLY:
1799  case OP_GROUP_CHAT_REPLY:
1800  case OP_LIST_REPLY:
1801  {
1802  CHECK_ATTACH;
1803 
1804  SendFlags flags = SEND_REPLY;
1805  if (op == OP_GROUP_REPLY)
1806  flags |= SEND_GROUP_REPLY;
1807  else if (op == OP_GROUP_CHAT_REPLY)
1808  flags |= SEND_GROUP_CHAT_REPLY;
1809  else if (op == OP_LIST_REPLY)
1810  flags |= SEND_LIST_REPLY;
1811 
1812  mutt_attach_reply(CUR_ATTACH->fp, e, actx,
1813  menu->tagprefix ? NULL : CUR_ATTACH->body, flags);
1814  menu->redraw = REDRAW_FULL;
1815  break;
1816  }
1817 
1818  case OP_COMPOSE_TO_SENDER:
1819  CHECK_ATTACH;
1820  mutt_attach_mail_sender(CUR_ATTACH->fp, e, actx,
1821  menu->tagprefix ? NULL : CUR_ATTACH->body);
1822  menu->redraw = REDRAW_FULL;
1823  break;
1824 
1825  case OP_EDIT_TYPE:
1826  recvattach_edit_content_type(actx, menu, e);
1827  menu->redraw |= REDRAW_INDEX;
1828  break;
1829 
1830  case OP_EXIT:
1831  mx_msg_close(m, &msg);
1832 
1833  e->attach_del = false;
1834  for (int i = 0; i < actx->idxlen; i++)
1835  {
1836  if (actx->idx[i]->body && actx->idx[i]->body->deleted)
1837  {
1838  e->attach_del = true;
1839  break;
1840  }
1841  }
1842  if (e->attach_del)
1843  e->changed = true;
1844 
1845  mutt_actx_free(&actx);
1846 
1847  mutt_menu_pop_current(menu);
1848  mutt_menu_free(&menu);
1850  return;
1851  }
1852 
1853  op = OP_NULL;
1854  }
1855 
1856  /* not reached */
1857 }
The "current" mailbox.
Definition: context.h:38
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:45
void mutt_actx_free(struct AttachCtx **ptr)
Free an Attachment Context.
Definition: attach.c:140
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define WithCrypto
Definition: lib.h:123
static const struct Mapping AttachHelp[]
Help Bar for the Attachment selection dialog.
Definition: recvattach.c:94
GUI selectable list of items.
Definition: mutt_menu.h:52
static void attach_make_entry(char *buf, size_t buflen, struct Menu *menu, int line)
Format a menu item for the attachment list - Implements Menu::make_entry()
Definition: recvattach.c:446
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
#define mutt_message(...)
Definition: logging.h:83
int help_menu
Menu for key bindings, e.g. MENU_PAGER.
Definition: mutt_window.h:134
Attach Dialog, dlg_select_attachment()
Definition: mutt_window.h:75
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:85
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:919
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:92
FILE * fp_root
Used by recvattach for updating.
Definition: attach.h:52
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:48
#define _(a)
Definition: message.h:28
bool changed
Email has been edited.
Definition: email.h:48
short idxlen
Number of attachmentes.
Definition: attach.h:55
Force viewing as text.
Definition: mutt_attach.h:44
A division of the screen.
Definition: mutt_window.h:115
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:52
uint16_t SendFlags
Flags for mutt_send_message(), e.g. SEND_REPLY.
Definition: send.h:37
struct MuttWindow * dialog_create_simple_index(struct Menu *menu, enum WindowType type)
Create a simple index Dialog.
Definition: dialog.c:165
#define CUR_ATTACH
Definition: recvattach.c:91
int attach_tag(struct Menu *menu, int sel, int act)
Tag an attachment - Implements Menu::tag()
Definition: recvattach.c:458
#define SEND_NO_FLAGS
No flags are set.
Definition: send.h:40
void mutt_attach_reply(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *e_cur, SendFlags flags)
Attach a reply.
Definition: recvcmd.c:917
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1206
struct Mailbox * mailbox
Definition: context.h:50
const char * title
Title of this menu.
Definition: mutt_menu.h:54
int parent_type
Type of parent attachment, e.g. TYPE_MULTIPART.
Definition: attach.h:38
struct AttachCtx * mutt_actx_new(void)
Create a new Attachment Context.
Definition: attach.c:131
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:43
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:883
#define REDRAW_MOTION_RESYNC
Redraw any changing the menu selection.
Definition: mutt_menu.h:42
void mutt_attach_bounce(struct Mailbox *m, FILE *fp, struct AttachCtx *actx, struct Body *cur)
Bounce function, from the attachment menu.
Definition: recvcmd.c:168
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:97
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:55
A local copy of an email.
Definition: mx.h:82
Select an attachment.
Definition: keymap.h:75
A mailbox.
Definition: mailbox.h:81
static void recvattach_edit_content_type(struct AttachCtx *actx, struct Menu *menu, struct Email *e)
Edit the content type of an attachment.
Definition: recvattach.c:1251
int mutt_attach_display_loop(struct Menu *menu, int op, struct Email *e, struct AttachCtx *actx, bool recv)
Event loop for the Attachment menu.
Definition: recvattach.c:1281
bool tagprefix
Definition: mutt_menu.h:61
static void recvattach_extract_pgp_keys(struct AttachCtx *actx, struct Menu *menu)
Extract PGP keys from attachments.
Definition: recvattach.c:1205
const struct Mapping * help_data
Data for the Help Bar.
Definition: mutt_window.h:135
void dialog_destroy_simple_index(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: dialog.c:209
static void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1489
#define SEND_NEWS
Reply to a news article.
Definition: send.h:54
int(* tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:107
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:1229
Force viewing using mailcap entry.
Definition: mutt_attach.h:43
#define SEND_REPLY
Reply to sender.
Definition: send.h:41
#define CHECK_READONLY
Definition: recvattach.c:83
int max
Number of entries in the menu.
Definition: mutt_menu.h:57
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
Definition: recvattach.c:1162
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:58
void mutt_attach_forward(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur, SendFlags flags)
Forward an Attachment.
Definition: recvcmd.c:766
#define SEC_SIGN
Email is signed.
Definition: lib.h:86
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:1514
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:517
#define SEND_GROUP_REPLY
Reply to all.
Definition: send.h:42
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:40
#define mutt_error(...)
Definition: logging.h:84
FILE * fp
pointer to the message data
Definition: mx.h:84
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:722
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:1086
void window_redraw(struct MuttWindow *win, bool force)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:757
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:573
#define SEND_GROUP_CHAT_REPLY
Reply to all recipients preserving To/Cc.
Definition: send.h:53
int current
Current entry.
Definition: mutt_menu.h:56
struct MuttWindow * win_index
Definition: mutt_menu.h:63
#define CHECK_ATTACH
Definition: recvattach.c:108
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:685
void(* make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:88
void mutt_attach_resend(FILE *fp, struct AttachCtx *actx, struct Body *cur)
resend-message, from the attachment menu
Definition: recvcmd.c:295
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1158
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: lib.h:89
#define REDRAW_CURRENT
Redraw the current line of the menu.
Definition: mutt_menu.h:43
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:1007
unsigned char C_FollowupToPoster
Config: (nntp) Reply to the poster if &#39;poster&#39; is in the &#39;Followup-To&#39; header.
Definition: config.c:38
WHERE bool C_Resolve
Config: Move to the next email whenever a command modifies an email.
Definition: mutt_globals.h:154
int msgno
Number displayed to the user.
Definition: email.h:87
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
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:416
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

◆ C_AttachSaveDir

char* C_AttachSaveDir

Config: Default directory where attachments are saved.

Definition at line 72 of file recvattach.c.

◆ C_AttachSaveWithoutPrompting

char* C_AttachSaveWithoutPrompting

Config: If true, then don't prompt to save.

Definition at line 73 of file recvattach.c.

◆ C_AttachSep

char* C_AttachSep

Config: Separator to add between saved/printed/piped attachments.

Definition at line 74 of file recvattach.c.

◆ C_AttachSplit

bool C_AttachSplit

Config: Save/print/pipe tagged messages individually.

Definition at line 75 of file recvattach.c.

◆ C_DigestCollapse

bool C_DigestCollapse

Config: Hide the subparts of a multipart/digest.

Definition at line 76 of file recvattach.c.

◆ C_MessageFormat

char* C_MessageFormat

Config: printf-like format string for listing attached messages.

Definition at line 77 of file recvattach.c.

◆ Mailbox_is_read_only

const char* Mailbox_is_read_only = N_("Mailbox is read-only")
static

Definition at line 81 of file recvattach.c.

◆ 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 94 of file recvattach.c.

◆ Function_not_permitted

const char* Function_not_permitted
static
Initial value:
=
N_("Function not permitted in attach-message mode")
#define N_(a)
Definition: message.h:32

Definition at line 105 of file recvattach.c.