NeoMutt  2020-06-26-30-g76c339
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 <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 "commands.h"
#include "context.h"
#include "format_flags.h"
#include "globals.h"
#include "handler.h"
#include "hdrline.h"
#include "hook.h"
#include "init.h"
#include "keymap.h"
#include "mailcap.h"
#include "mutt_attach.h"
#include "mutt_menu.h"
#include "mutt_parse.h"
#include "muttlib.h"
#include "mx.h"
#include "opcodes.h"
#include "options.h"
#include "recvcmd.h"
#include "send.h"
#include "sendlib.h"
#include "state.h"
#include "ncrypt/lib.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 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 mutt_view_attachments (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 []
 
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:37
static const char * Mailbox_is_read_only
Definition: recvattach.c:79
#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 81 of file recvattach.c.

◆ CUR_ATTACH

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

Definition at line 89 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:96

Definition at line 99 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 1358 of file recvattach.c.

1359 {
1360  if (init)
1361  {
1362  mutt_generate_recvattach_list(actx, actx->email, actx->email->content,
1363  actx->fp_root, -1, 0, 0);
1364  mutt_attach_init(actx);
1365  menu->mdata = actx;
1366  }
1367 
1368  mutt_update_tree(actx);
1369 
1370  menu->max = actx->vcount;
1371 
1372  if (menu->current >= menu->max)
1373  menu->current = menu->max - 1;
1374  menu_check_recenter(menu);
1375  menu->redraw |= REDRAW_INDEX;
1376 }
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:1228
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
struct Body * content
List of MIME parts.
Definition: email.h:90
FILE * fp_root
Used by recvattach for updating.
Definition: attach.h:52
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:84
void mutt_attach_init(struct AttachCtx *actx)
Create a new Attachment context.
Definition: recvattach.c:1334
int max
Number of entries in the menu.
Definition: mutt_menu.h:86
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:87
#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:142
int current
Current entry.
Definition: mutt_menu.h:85
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 113 of file recvattach.c.

114 {
115  int vindex, rindex, curlevel;
116 
117  vindex = 0;
118  rindex = 0;
119 
120  while (rindex < actx->idxlen)
121  {
122  actx->v2r[vindex++] = rindex;
123  if (actx->idx[rindex]->content->collapsed)
124  {
125  curlevel = actx->idx[rindex]->level;
126  do
127  {
128  rindex++;
129  } while ((rindex < actx->idxlen) && (actx->idx[rindex]->level > curlevel));
130  }
131  else
132  rindex++;
133  }
134 
135  actx->vcount = vindex;
136 }
bool collapsed
Used by recvattach.
Definition: body.h:82
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
struct Body * content
Attachment.
Definition: attach.h:36
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
+ 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 142 of file recvattach.c.

143 {
144  char buf[256];
145  char *s = NULL;
146 
147  mutt_update_v2r(actx);
148 
149  for (int vindex = 0; vindex < actx->vcount; vindex++)
150  {
151  const int rindex = actx->v2r[vindex];
152  actx->idx[rindex]->num = vindex;
153  if ((2 * (actx->idx[rindex]->level + 2)) < sizeof(buf))
154  {
155  if (actx->idx[rindex]->level)
156  {
157  s = buf + 2 * (actx->idx[rindex]->level - 1);
158  *s++ = (actx->idx[rindex]->content->next) ? MUTT_TREE_LTEE : MUTT_TREE_LLCORNER;
159  *s++ = MUTT_TREE_HLINE;
160  *s++ = MUTT_TREE_RARROW;
161  }
162  else
163  s = buf;
164  *s = '\0';
165  }
166 
167  if (actx->idx[rindex]->tree)
168  {
169  if (!mutt_str_equal(actx->idx[rindex]->tree, buf))
170  mutt_str_replace(&actx->idx[rindex]->tree, buf);
171  }
172  else
173  actx->idx[rindex]->tree = mutt_str_dup(buf);
174 
175  if (((2 * (actx->idx[rindex]->level + 2)) < sizeof(buf)) &&
176  actx->idx[rindex]->level)
177  {
178  s = buf + 2 * (actx->idx[rindex]->level - 1);
179  *s++ = (actx->idx[rindex]->content->next) ? '\005' : '\006';
180  *s++ = '\006';
181  }
182  }
183 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:879
Lower left corner.
Definition: mutt_menu.h:59
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
struct Body * next
next attachment in the list
Definition: body.h:53
Right arrow.
Definition: mutt_menu.h:65
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:113
int num
Attachment index number.
Definition: attach.h:41
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:450
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
struct Body * content
Attachment.
Definition: attach.h:36
int level
Nesting depth of attachment.
Definition: attach.h:40
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
Left T-piece.
Definition: mutt_menu.h:61
short vcount
The number of virtual attachments.
Definition: attach.h:59
Horizontal line.
Definition: mutt_menu.h:62
+ 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 208 of file recvattach.c.

211 {
212  char fmt[128];
213  char charset[128];
214  struct AttachPtr *aptr = (struct AttachPtr *) data;
215  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
216 
217  switch (op)
218  {
219  case 'C':
220  if (!optional)
221  {
222  if (mutt_is_text_part(aptr->content) &&
223  mutt_body_get_charset(aptr->content, charset, sizeof(charset)))
224  {
225  mutt_format_s(buf, buflen, prec, charset);
226  }
227  else
228  mutt_format_s(buf, buflen, prec, "");
229  }
230  else if (!mutt_is_text_part(aptr->content) ||
231  !mutt_body_get_charset(aptr->content, charset, sizeof(charset)))
232  {
233  optional = false;
234  }
235  break;
236  case 'c':
237  /* XXX */
238  if (!optional)
239  {
240  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
241  snprintf(buf, buflen, fmt,
242  ((aptr->content->type != TYPE_TEXT) || aptr->content->noconv) ? 'n' : 'c');
243  }
244  else if ((aptr->content->type != TYPE_TEXT) || aptr->content->noconv)
245  optional = false;
246  break;
247  case 'd':
248  if (!optional)
249  {
250  if (aptr->content->description)
251  {
252  mutt_format_s(buf, buflen, prec, aptr->content->description);
253  break;
254  }
255  if (mutt_is_message_type(aptr->content->type, aptr->content->subtype) &&
256  C_MessageFormat && aptr->content->email)
257  {
258  char s[128];
259  mutt_make_string_flags(s, sizeof(s), cols, C_MessageFormat, NULL,
260  NULL, aptr->content->email,
262  if (*s)
263  {
264  mutt_format_s(buf, buflen, prec, s);
265  break;
266  }
267  }
268  if (!aptr->content->d_filename && !aptr->content->filename)
269  {
270  mutt_format_s(buf, buflen, prec, "<no description>");
271  break;
272  }
273  }
274  else if (aptr->content->description ||
275  (mutt_is_message_type(aptr->content->type, aptr->content->subtype) &&
276  C_MessageFormat && aptr->content->email))
277  {
278  break;
279  }
280  /* fallthrough */
281  case 'F':
282  if (!optional)
283  {
284  if (aptr->content->d_filename)
285  {
286  mutt_format_s(buf, buflen, prec, aptr->content->d_filename);
287  break;
288  }
289  }
290  else if (!aptr->content->d_filename && !aptr->content->filename)
291  {
292  optional = false;
293  break;
294  }
295  /* fallthrough */
296  case 'f':
297  if (!optional)
298  {
299  if (aptr->content->filename && (*aptr->content->filename == '/'))
300  {
301  struct Buffer *path = mutt_buffer_pool_get();
302 
303  mutt_buffer_strcpy(path, aptr->content->filename);
305  mutt_format_s(buf, buflen, prec, mutt_b2s(path));
307  }
308  else
309  mutt_format_s(buf, buflen, prec, NONULL(aptr->content->filename));
310  }
311  else if (!aptr->content->filename)
312  optional = false;
313  break;
314  case 'D':
315  if (!optional)
316  snprintf(buf, buflen, "%c", aptr->content->deleted ? 'D' : ' ');
317  else if (!aptr->content->deleted)
318  optional = false;
319  break;
320  case 'e':
321  if (!optional)
322  mutt_format_s(buf, buflen, prec, ENCODING(aptr->content->encoding));
323  break;
324  case 'I':
325  if (optional)
326  break;
327 
328  const char dispchar[] = { 'I', 'A', 'F', '-' };
329  char ch;
330 
331  if (aptr->content->disposition < sizeof(dispchar))
332  ch = dispchar[aptr->content->disposition];
333  else
334  {
335  mutt_debug(LL_DEBUG1, "ERROR: invalid content-disposition %d\n",
336  aptr->content->disposition);
337  ch = '!';
338  }
339  snprintf(buf, buflen, "%c", ch);
340  break;
341  case 'm':
342  if (!optional)
343  mutt_format_s(buf, buflen, prec, TYPE(aptr->content));
344  break;
345  case 'M':
346  if (!optional)
347  mutt_format_s(buf, buflen, prec, aptr->content->subtype);
348  else if (!aptr->content->subtype)
349  optional = false;
350  break;
351  case 'n':
352  if (optional)
353  break;
354 
355  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
356  snprintf(buf, buflen, fmt, aptr->num + 1);
357  break;
358  case 'Q':
359  if (optional)
360  optional = aptr->content->attach_qualifies;
361  else
362  {
363  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
364  mutt_format_s(buf, buflen, fmt, "Q");
365  }
366  break;
367  case 's':
368  {
369  size_t l;
370  if (flags & MUTT_FORMAT_STAT_FILE)
371  {
372  struct stat st;
373  stat(aptr->content->filename, &st);
374  l = st.st_size;
375  }
376  else
377  l = aptr->content->length;
378 
379  if (!optional)
380  {
381  char tmp[128];
382  mutt_str_pretty_size(tmp, sizeof(tmp), l);
383  mutt_format_s(buf, buflen, prec, tmp);
384  }
385  else if (l == 0)
386  optional = false;
387 
388  break;
389  }
390  case 't':
391  if (!optional)
392  snprintf(buf, buflen, "%c", aptr->content->tagged ? '*' : ' ');
393  else if (!aptr->content->tagged)
394  optional = false;
395  break;
396  case 'T':
397  if (!optional)
398  mutt_format_s_tree(buf, buflen, prec, NONULL(aptr->tree));
399  else if (!aptr->tree)
400  optional = false;
401  break;
402  case 'u':
403  if (!optional)
404  snprintf(buf, buflen, "%c", aptr->content->unlink ? '-' : ' ');
405  else if (!aptr->content->unlink)
406  optional = false;
407  break;
408  case 'X':
409  if (optional)
410  optional = ((aptr->content->attach_count + aptr->content->attach_qualifies) != 0);
411  else
412  {
413  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
414  snprintf(buf, buflen, fmt, aptr->content->attach_count + aptr->content->attach_qualifies);
415  }
416  break;
417  default:
418  *buf = '\0';
419  }
420 
421  if (optional)
422  {
423  mutt_expando_format(buf, buflen, col, cols, if_str, attach_format_str, data,
425  }
426  else if (flags & MUTT_FORMAT_OPTIONAL)
427  {
428  mutt_expando_format(buf, buflen, col, cols, else_str, attach_format_str,
429  data, MUTT_FORMAT_NO_FLAGS);
430  }
431  return src;
432 }
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:75
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1360
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
static int const char * fmt
Definition: acutest.h:488
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:688
#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
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:862
void mutt_make_string_flags(char *buf, size_t buflen, int cols, const char *s, struct Context *ctx, struct Mailbox *m, struct Email *e, MuttFormatFlags flags)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1407
#define ENCODING(x)
Definition: mime.h:85
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:1749
char * mutt_body_get_charset(struct Body *b, char *buf, size_t buflen)
Get a body&#39;s character set.
Definition: sendlib.c:1462
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:437
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:83
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:1223
Log at debug level 1.
Definition: logging.h:40
struct Body * content
Attachment.
Definition: attach.h:36
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:208
#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:1235
+ 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 437 of file recvattach.c.

438 {
439  struct AttachCtx *actx = menu->mdata;
440 
441  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
443  (intptr_t)(actx->idx[actx->v2r[line]]), MUTT_FORMAT_ARROWCURSOR);
444 }
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_AttachFormat
Config: printf-like format string for the attachment menu.
Definition: globals.h:99
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
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:862
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:113
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:84
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
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:208
int const char int line
Definition: acutest.h:617
struct MuttWindow * win_index
Definition: mutt_menu.h:92
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 449 of file recvattach.c.

450 {
451  struct AttachCtx *actx = menu->mdata;
452  struct Body *cur = actx->idx[actx->v2r[sel]]->content;
453  bool ot = cur->tagged;
454 
455  cur->tagged = ((act >= 0) ? act : !cur->tagged);
456  return cur->tagged - ot;
457 }
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:84
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
struct Body * content
Attachment.
Definition: attach.h:36
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
+ 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 463 of file recvattach.c.

464 {
465  if (!buf || !buf->data || (buf->data[0] == '/'))
466  return;
467 
468  struct Buffer *tmp = mutt_buffer_pool_get();
469  if (C_AttachSaveDir)
470  {
472  if (tmp->dptr[-1] != '/')
473  mutt_buffer_addch(tmp, '/');
474  }
475  else
476  mutt_buffer_addstr(tmp, "./");
477 
478  mutt_buffer_addstr(tmp, mutt_b2s(buf));
479  mutt_buffer_copy(buf, tmp);
481 }
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:70
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 488 of file recvattach.c.

489 {
490  return (body->email && (body->encoding != ENC_BASE64) &&
491  (body->encoding != ENC_QUOTED_PRINTABLE) &&
492  mutt_is_message_type(body->type, body->subtype));
493 }
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1360
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:

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

505 {
506  char *prompt = NULL;
507  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
508  int rc = -1;
509 
510  struct Buffer *buf = mutt_buffer_pool_get();
511  struct Buffer *tfile = mutt_buffer_pool_get();
512 
513  if (body->filename)
514  {
515  if (directory && *directory)
516  {
517  mutt_buffer_concat_path(buf, *directory, mutt_path_basename(body->filename));
518  }
519  else
520  mutt_buffer_strcpy(buf, body->filename);
521  }
522  else if (has_a_message(body))
523  {
524  mutt_default_save(buf->data, buf->dsize, body->email);
526  }
527 
528  prepend_savedir(buf);
529 
530  prompt = _("Save to file: ");
531  while (prompt)
532  {
533  if ((mutt_buffer_get_field(prompt, buf, MUTT_FILE | MUTT_CLEAR) != 0) ||
535  {
536  goto cleanup;
537  }
538 
539  prompt = NULL;
541 
542  bool is_message = (fp && has_a_message(body));
543 
544  if (is_message)
545  {
546  struct stat st;
547 
548  /* check to make sure that this file is really the one the user wants */
549  rc = mutt_save_confirm(mutt_b2s(buf), &st);
550  if (rc == 1)
551  {
552  prompt = _("Save to file: ");
553  continue;
554  }
555  else if (rc == -1)
556  goto cleanup;
557  mutt_buffer_copy(tfile, buf);
558  }
559  else
560  {
561  rc = mutt_check_overwrite(body->filename, mutt_b2s(buf), tfile, &opt, directory);
562  if (rc == -1)
563  goto cleanup;
564  else if (rc == 1)
565  {
566  prompt = _("Save to file: ");
567  continue;
568  }
569  }
570 
571  mutt_message(_("Saving..."));
572  if (mutt_save_attachment(fp, body, mutt_b2s(tfile), opt,
573  (e || !is_message) ? e : body->email) == 0)
574  {
575  mutt_message(_("Attachment saved"));
576  rc = 0;
577  goto cleanup;
578  }
579  else
580  {
581  prompt = _("Save to file: ");
582  continue;
583  }
584  }
585 
586 cleanup:
588  mutt_buffer_pool_release(&tfile);
589  return rc;
590 }
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:488
#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:463
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
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:830
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:653
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1439
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:710
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:84
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:327
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 600 of file recvattach.c.

601 {
602  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
603  int rc = -1;
604  struct Buffer *buf = mutt_buffer_pool_get();
605  struct Buffer *tfile = mutt_buffer_pool_get();
606 
607  if (body->filename)
608  {
609  mutt_buffer_strcpy(buf, body->filename);
610  }
611  else if (has_a_message(body))
612  {
613  mutt_default_save(buf->data, buf->dsize, body->email);
614  }
615 
616  prepend_savedir(buf);
618 
619  bool is_message = (fp && has_a_message(body));
620 
621  if (is_message)
622  {
623  mutt_buffer_copy(tfile, buf);
624  }
625  else
626  {
627  rc = mutt_check_overwrite(body->filename, mutt_b2s(buf), tfile, &opt, NULL);
628  if (rc == -1) // abort or cancel
629  goto cleanup;
630  }
631 
632  rc = mutt_save_attachment(fp, body, mutt_b2s(tfile), opt,
633  (e || !is_message) ? e : body->email);
634 
635 cleanup:
637  mutt_buffer_pool_release(&tfile);
638  return rc;
639 }
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:488
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:463
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:830
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:653
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:710
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:327
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 650 of file recvattach.c.

652 {
653  char *directory = NULL;
654  int rc = 1;
655  int last = menu ? menu->current : -1;
656  FILE *fp_out = NULL;
657  int saved_attachments = 0;
658 
659  struct Buffer *buf = mutt_buffer_pool_get();
660  struct Buffer *tfile = mutt_buffer_pool_get();
661 
662  for (int i = 0; !tag || (i < actx->idxlen); i++)
663  {
664  if (tag)
665  {
666  fp = actx->idx[i]->fp;
667  top = actx->idx[i]->content;
668  }
669  if (!tag || top->tagged)
670  {
671  if (!C_AttachSplit)
672  {
673  if (mutt_buffer_is_empty(buf))
674  {
675  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
676 
678  prepend_savedir(buf);
679 
680  if ((mutt_buffer_get_field(_("Save to file: "), buf, MUTT_FILE | MUTT_CLEAR) != 0) ||
682  {
683  goto cleanup;
684  }
686  if (mutt_check_overwrite(top->filename, mutt_b2s(buf), tfile, &opt, NULL))
687  goto cleanup;
688  rc = mutt_save_attachment(fp, top, mutt_b2s(tfile), opt, e);
689  if ((rc == 0) && C_AttachSep && (fp_out = fopen(mutt_b2s(tfile), "a")))
690  {
691  fprintf(fp_out, "%s", C_AttachSep);
692  mutt_file_fclose(&fp_out);
693  }
694  }
695  else
696  {
697  rc = mutt_save_attachment(fp, top, mutt_b2s(tfile), MUTT_SAVE_APPEND, e);
698  if ((rc == 0) && C_AttachSep && (fp_out = fopen(mutt_b2s(tfile), "a")))
699  {
700  fprintf(fp_out, "%s", C_AttachSep);
701  mutt_file_fclose(&fp_out);
702  }
703  }
704  }
705  else
706  {
707  if (tag && menu && top->aptr)
708  {
709  menu->oldcurrent = menu->current;
710  menu->current = top->aptr->num;
711  menu_check_recenter(menu);
712  menu->redraw |= REDRAW_MOTION;
713 
714  menu_redraw(menu);
715  }
717  {
718  // Save each file, with no prompting, using the configured 'AttachSaveDir'
719  rc = save_without_prompting(fp, top, e);
720  if (rc == 0)
721  saved_attachments++;
722  }
723  else
724  {
725  // Save each file, prompting the user for the location each time.
726  if (query_save_attachment(fp, top, e, &directory) == -1)
727  break;
728  }
729  }
730  }
731  if (!tag)
732  break;
733  }
734 
735  FREE(&directory);
736 
737  if (tag && menu)
738  {
739  menu->oldcurrent = menu->current;
740  menu->current = last;
741  menu_check_recenter(menu);
742  menu->redraw |= REDRAW_MOTION;
743  }
744 
745  if (!C_AttachSplit && (rc == 0))
746  mutt_message(_("Attachment saved"));
747 
748  if (C_AttachSaveWithoutPrompting && (rc == 0))
749  {
750  mutt_message(ngettext("Attachment saved", "%d attachments saved", saved_attachments),
751  saved_attachments);
752  }
753 
754 cleanup:
756  mutt_buffer_pool_release(&tfile);
757 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:73
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:106
char * C_AttachSaveWithoutPrompting
Config: If true, then don&#39;t prompt to save.
Definition: recvattach.c:71
No flags set.
Definition: mutt_attach.h:55
char * C_AttachSep
Config: Separator to add between saved/printed/piped attachments.
Definition: recvattach.c:72
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:463
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:504
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:830
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:600
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:710
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:84
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:87
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:327
struct Body * content
Attachment.
Definition: attach.h:36
Append to existing file.
Definition: mutt_attach.h:56
#define FREE(x)
Definition: memory.h:40
int current
Current entry.
Definition: mutt_menu.h:85
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
+ 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 766 of file recvattach.c.

767 {
768  char tfile[PATH_MAX];
769 
770  if (filter)
771  {
772  char warning[PATH_MAX + 256];
773  snprintf(warning, sizeof(warning),
774  _("WARNING! You are about to overwrite %s, continue?"), body->filename);
775  if (mutt_yesorno(warning, MUTT_NO) != MUTT_YES)
776  {
778  return;
779  }
780  mutt_mktemp(tfile, sizeof(tfile));
781  }
782  else
783  tfile[0] = '\0';
784 
785  if (mutt_pipe_attachment(fp, body, command, tfile))
786  {
787  if (filter)
788  {
789  mutt_file_unlink(body->filename);
790  mutt_file_rename(tfile, body->filename);
791  mutt_update_encoding(body);
792  mutt_message(_("Attachment filtered"));
793  }
794  }
795  else
796  {
797  if (filter && tfile[0])
798  mutt_file_unlink(tfile);
799  }
800 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define mutt_message(...)
Definition: logging.h:83
int mutt_file_rename(const char *oldfile, const char *newfile)
Rename a file.
Definition: file.c:1340
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
#define _(a)
Definition: message.h:28
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:377
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1486
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:190
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:78
#define PATH_MAX
Definition: mutt.h:44
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:46
int mutt_pipe_attachment(FILE *fp, struct Body *b, const char *path, char *outfile)
Pipe an attachment to a command.
Definition: mutt_attach.c:713
+ 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 808 of file recvattach.c.

809 {
810  if (!state || !state->fp_out)
811  return;
812 
813  if (fp)
814  {
815  state->fp_in = fp;
816  mutt_decode_attachment(b, state);
817  if (C_AttachSep)
818  state_puts(state, C_AttachSep);
819  }
820  else
821  {
822  FILE *fp_in = fopen(b->filename, "r");
823  if (!fp_in)
824  {
825  mutt_perror("fopen");
826  return;
827  }
828  mutt_file_copy_stream(fp_in, state->fp_out);
829  mutt_file_fclose(&fp_in);
830  if (C_AttachSep)
831  state_puts(state, C_AttachSep);
832  }
833 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1835
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
#define mutt_perror(...)
Definition: logging.h:85
char * C_AttachSep
Config: Separator to add between saved/printed/piped attachments.
Definition: recvattach.c:72
FILE * fp_out
File to write to.
Definition: state.h:47
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
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
+ 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 845 of file recvattach.c.

848 {
849  for (int i = 0; !tag || (i < actx->idxlen); i++)
850  {
851  if (tag)
852  {
853  fp = actx->idx[i]->fp;
854  top = actx->idx[i]->content;
855  }
856  if (!tag || top->tagged)
857  {
858  if (!filter && !C_AttachSplit)
859  pipe_attachment(fp, top, state);
860  else
861  query_pipe_attachment(command, fp, top, filter);
862  }
863  if (!tag)
864  break;
865  }
866 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:73
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:766
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:808
struct Body * content
Attachment.
Definition: attach.h:36
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:

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

878 {
879  struct State state = { 0 };
880  struct Buffer *buf = NULL;
881 
882  if (fp)
883  filter = false; /* sanity check: we can't filter in the recv case yet */
884 
885  buf = mutt_buffer_pool_get();
886  /* perform charset conversion on text attachments when piping */
887  state.flags = MUTT_CHARCONV;
888 
889  if (mutt_buffer_get_field((filter ? _("Filter through: ") : _("Pipe to: ")),
890  buf, MUTT_CMD) != 0)
891  {
892  goto cleanup;
893  }
894 
895  if (mutt_buffer_len(buf) == 0)
896  goto cleanup;
897 
899 
900  if (!filter && !C_AttachSplit)
901  {
902  mutt_endwin();
903  pid_t pid = filter_create(mutt_b2s(buf), &state.fp_out, NULL, NULL);
904  pipe_attachment_list(mutt_b2s(buf), actx, fp, tag, top, filter, &state);
905  mutt_file_fclose(&state.fp_out);
906  if ((filter_wait(pid) != 0) || C_WaitKey)
908  }
909  else
910  pipe_attachment_list(mutt_b2s(buf), actx, fp, tag, top, filter, &state);
911 
912 cleanup:
914 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:73
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
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
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: globals.h:252
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:546
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:845
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:84
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:579
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:327
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
+ 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 923 of file recvattach.c.

924 {
925  char type[256];
926 
927  for (int i = 0; !tag || (i < actx->idxlen); i++)
928  {
929  if (tag)
930  top = actx->idx[i]->content;
931  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
932  if (!tag || top->tagged)
933  {
934  if (!mailcap_lookup(top, type, sizeof(type), NULL, MUTT_MC_PRINT))
935  {
936  if (!mutt_istr_equal("text/plain", top->subtype) &&
937  !mutt_istr_equal("application/postscript", top->subtype))
938  {
939  if (!mutt_can_decode(top))
940  {
941  /* L10N: s gets replaced by a MIME type, e.g. "text/plain" or
942  application/octet-stream. */
943  mutt_error(_("I don't know how to print %s attachments"), type);
944  return false;
945  }
946  }
947  }
948  }
949  if (!tag)
950  break;
951  }
952  return true;
953 }
#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:891
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:1795
#define TYPE(body)
Definition: mime.h:83
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
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:

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

965 {
966  char type[256];
967 
968  for (int i = 0; !tag || (i < actx->idxlen); i++)
969  {
970  if (tag)
971  {
972  fp = actx->idx[i]->fp;
973  top = actx->idx[i]->content;
974  }
975  if (!tag || top->tagged)
976  {
977  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
978  if (!C_AttachSplit && !mailcap_lookup(top, type, sizeof(type), NULL, MUTT_MC_PRINT))
979  {
980  if (mutt_istr_equal("text/plain", top->subtype) ||
981  mutt_istr_equal("application/postscript", top->subtype))
982  {
983  pipe_attachment(fp, top, state);
984  }
985  else if (mutt_can_decode(top))
986  {
987  /* decode and print */
988 
989  FILE *fp_in = NULL;
990  struct Buffer *newfile = mutt_buffer_pool_get();
991 
992  mutt_buffer_mktemp(newfile);
993  if (mutt_decode_save_attachment(fp, top, mutt_b2s(newfile),
995  {
996  if (!state->fp_out)
997  {
998  mutt_error(
999  "BUG in print_attachment_list(). Please report this. ");
1000  return;
1001  }
1002 
1003  fp_in = fopen(mutt_b2s(newfile), "r");
1004  if (fp_in)
1005  {
1006  mutt_file_copy_stream(fp_in, state->fp_out);
1007  mutt_file_fclose(&fp_in);
1008  if (C_AttachSep)
1009  state_puts(state, C_AttachSep);
1010  }
1011  }
1012  mutt_file_unlink(mutt_b2s(newfile));
1013  mutt_buffer_pool_release(&newfile);
1014  }
1015  }
1016  else
1017  mutt_print_attachment(fp, top);
1018  }
1019  if (!tag)
1020  break;
1021  }
1022 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:73
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:81
#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:72
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:891
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:961
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1795
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:808
#define TYPE(body)
Definition: mime.h:83
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
struct Body * content
Attachment.
Definition: attach.h:36
#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:1060
+ 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 1031 of file recvattach.c.

1032 {
1033  char prompt[128];
1034  struct State state = { 0 };
1035  int tagmsgcount = 0;
1036 
1037  if (tag)
1038  for (int i = 0; i < actx->idxlen; i++)
1039  if (actx->idx[i]->content->tagged)
1040  tagmsgcount++;
1041 
1042  snprintf(prompt, sizeof(prompt),
1043  /* L10N: Although we now the precise number of tagged messages, we
1044  do not show it to the user. So feel free to use a "generic
1045  plural" as plural translation if your language has one. */
1046  tag ? ngettext("Print tagged attachment?", "Print %d tagged attachments?", tagmsgcount) :
1047  _("Print attachment?"),
1048  tagmsgcount);
1049  if (query_quadoption(C_Print, prompt) != MUTT_YES)
1050  return;
1051 
1052  if (C_AttachSplit)
1053  {
1054  print_attachment_list(actx, fp, tag, top, &state);
1055  }
1056  else
1057  {
1058  if (!can_print(actx, top, tag))
1059  return;
1060  mutt_endwin();
1061  pid_t pid = filter_create(NONULL(C_PrintCommand), &state.fp_out, NULL, NULL);
1062  print_attachment_list(actx, fp, tag, top, &state);
1063  mutt_file_fclose(&state.fp_out);
1064  if ((filter_wait(pid) != 0) || C_WaitKey)
1066  }
1067 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:73
#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
WHERE unsigned char C_Print
Config: Confirm before printing a message.
Definition: globals.h:179
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1112
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
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:963
#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 bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: globals.h:252
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:546
static bool can_print(struct AttachCtx *actx, struct Body *top, bool tag)
Do we know how to print this attachment type?
Definition: recvattach.c:923
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:579
struct Body * content
Attachment.
Definition: attach.h:36
WHERE char * C_PrintCommand
Config: External command to print a message.
Definition: globals.h:132
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
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:

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

1075 {
1076  if (!menu->tagprefix)
1078  else
1079  {
1080  for (int i = 0; i < actx->idxlen; i++)
1081  {
1082  if (actx->idx[i]->content->tagged)
1083  {
1084  crypt_pgp_extract_key_from_attachment(actx->idx[i]->fp, actx->idx[i]->content);
1085  }
1086  }
1087  }
1088 }
short idxlen
Number of attachmentes.
Definition: attach.h:55
#define CUR_ATTACH
Definition: recvattach.c:89
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:398
bool tagprefix
Definition: mutt_menu.h:90
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
struct Body * content
Attachment.
Definition: attach.h:36
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:

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

1099 {
1100  int rc = 0;
1101 
1102  if (!menu->tagprefix)
1103  rc = crypt_pgp_check_traditional(CUR_ATTACH->fp, CUR_ATTACH->content, true);
1104  else
1105  {
1106  for (int i = 0; i < actx->idxlen; i++)
1107  if (actx->idx[i]->content->tagged)
1108  rc = rc || crypt_pgp_check_traditional(actx->idx[i]->fp, actx->idx[i]->content, true);
1109  }
1110 
1111  return rc;
1112 }
short idxlen
Number of attachmentes.
Definition: attach.h:55
#define CUR_ATTACH
Definition: recvattach.c:89
bool tagged
This attachment is tagged.
Definition: body.h:70
bool tagprefix
Definition: mutt_menu.h:90
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:286
struct Body * content
Attachment.
Definition: attach.h:36
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:

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

1122 {
1123  if (!mutt_edit_content_type(e, CUR_ATTACH->content, CUR_ATTACH->fp))
1124  return;
1125 
1126  /* The mutt_update_recvattach_menu() will overwrite any changes
1127  * made to a decrypted CUR_ATTACH->content, so warn the user. */
1128  if (CUR_ATTACH->decrypted)
1129  {
1130  mutt_message(
1131  _("Structural changes to decrypted attachments are not supported"));
1132  mutt_sleep(1);
1133  }
1134  /* Editing the content type can rewrite the body structure. */
1135  for (int i = 0; i < actx->idxlen; i++)
1136  actx->idx[i]->content = NULL;
1137  mutt_actx_entries_free(actx);
1138  mutt_update_recvattach_menu(actx, menu, true);
1139 }
#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:89
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1536
static void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1358
void mutt_actx_entries_free(struct AttachCtx *actx)
Free entries in an Attachment Context.
Definition: attach.c:103
struct Body * content
Attachment.
Definition: attach.h:36
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1249
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:

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

1152 {
1153  do
1154  {
1155  switch (op)
1156  {
1157  case OP_DISPLAY_HEADERS:
1158  bool_str_toggle(NeoMutt->sub, "weed", NULL);
1159  /* fallthrough */
1160 
1161  case OP_VIEW_ATTACH:
1162  op = mutt_view_attachment(CUR_ATTACH->fp, CUR_ATTACH->content,
1163  MUTT_VA_REGULAR, e, actx, menu->win_index);
1164  break;
1165 
1166  case OP_NEXT_ENTRY:
1167  case OP_MAIN_NEXT_UNDELETED: /* hack */
1168  if (menu->current < menu->max - 1)
1169  {
1170  menu->current++;
1171  op = OP_VIEW_ATTACH;
1172  }
1173  else
1174  op = OP_NULL;
1175  break;
1176  case OP_PREV_ENTRY:
1177  case OP_MAIN_PREV_UNDELETED: /* hack */
1178  if (menu->current > 0)
1179  {
1180  menu->current--;
1181  op = OP_VIEW_ATTACH;
1182  }
1183  else
1184  op = OP_NULL;
1185  break;
1186  case OP_EDIT_TYPE:
1187  /* when we edit the content-type, we should redisplay the attachment
1188  * immediately */
1189  mutt_edit_content_type(e, CUR_ATTACH->content, CUR_ATTACH->fp);
1190  if (recv)
1191  recvattach_edit_content_type(actx, menu, e);
1192  else
1193  mutt_edit_content_type(e, CUR_ATTACH->content, CUR_ATTACH->fp);
1194 
1195  menu->redraw |= REDRAW_INDEX;
1196  op = OP_VIEW_ATTACH;
1197  break;
1198  /* functions which are passed through from the pager */
1199  case OP_CHECK_TRADITIONAL:
1201  {
1202  op = OP_NULL;
1203  break;
1204  }
1205  /* fallthrough */
1206  case OP_ATTACH_COLLAPSE:
1207  if (recv)
1208  return op;
1209  /* fallthrough */
1210  default:
1211  op = OP_NULL;
1212  }
1213  } while (op != OP_NULL);
1214 
1215  return op;
1216 }
#define WithCrypto
Definition: lib.h:163
View using default method.
Definition: mutt_attach.h:42
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define CUR_ATTACH
Definition: recvattach.c:89
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
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:1120
int bool_str_toggle(struct ConfigSubset *sub, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:240
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:86
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:87
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:40
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: lib.h:139
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:1249
int current
Current entry.
Definition: mutt_menu.h:85
struct MuttWindow * win_index
Definition: mutt_menu.h:92
int mutt_view_attachment(FILE *fp, struct Body *a, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx, struct MuttWindow *win)
View an attachment.
Definition: mutt_attach.c:415
+ 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 1228 of file recvattach.c.

1231 {
1232  struct Body *m = NULL;
1233  struct Body *new_body = NULL;
1234  FILE *fp_new = NULL;
1236  int need_secured, secured;
1237 
1238  for (m = parts; m; m = m->next)
1239  {
1240  need_secured = 0;
1241  secured = 0;
1242 
1243  if (((WithCrypto & APPLICATION_SMIME) != 0) && (type = mutt_is_application_smime(m)))
1244  {
1245  need_secured = 1;
1246 
1247  if (type & SEC_ENCRYPT)
1248  {
1249  if (!crypt_valid_passphrase(APPLICATION_SMIME))
1250  goto decrypt_failed;
1251 
1252  if (e->env)
1254  }
1255 
1256  secured = !crypt_smime_decrypt_mime(fp, &fp_new, m, &new_body);
1257  /* If the decrypt/verify-opaque doesn't generate mime output, an empty
1258  * text/plain type will still be returned by mutt_read_mime_header().
1259  * We can't distinguish an actual part from a failure, so only use a
1260  * text/plain that results from a single top-level part. */
1261  if (secured && (new_body->type == TYPE_TEXT) &&
1262  mutt_istr_equal("plain", new_body->subtype) && ((parts != m) || m->next))
1263  {
1264  mutt_body_free(&new_body);
1265  mutt_file_fclose(&fp_new);
1266  goto decrypt_failed;
1267  }
1268 
1269  if (secured && (type & SEC_ENCRYPT))
1270  e->security |= SMIME_ENCRYPT;
1271  }
1272 
1273  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1275  {
1276  need_secured = 1;
1277 
1278  if (!crypt_valid_passphrase(APPLICATION_PGP))
1279  goto decrypt_failed;
1280 
1281  secured = !crypt_pgp_decrypt_mime(fp, &fp_new, m, &new_body);
1282 
1283  if (secured)
1284  e->security |= PGP_ENCRYPT;
1285  }
1286 
1287  if (need_secured && secured)
1288  {
1289  mutt_actx_add_fp(actx, fp_new);
1290  mutt_actx_add_body(actx, new_body);
1291  mutt_generate_recvattach_list(actx, e, new_body, fp_new, parent_type, level, 1);
1292  continue;
1293  }
1294 
1295  decrypt_failed:
1296  /* Fall through and show the original parts if decryption fails */
1297  if (need_secured && !secured)
1298  mutt_error(_("Can't decrypt encrypted message"));
1299 
1300  /* Strip out the top level multipart */
1301  if ((m->type == TYPE_MULTIPART) && m->parts && !need_secured &&
1302  ((parent_type == -1) && !mutt_istr_equal("alternative", m->subtype)))
1303  {
1304  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level, decrypted);
1305  }
1306  else
1307  {
1308  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1309  mutt_actx_add_attach(actx, ap);
1310 
1311  ap->content = m;
1312  ap->fp = fp;
1313  m->aptr = ap;
1314  ap->parent_type = parent_type;
1315  ap->level = level;
1316  ap->decrypted = decrypted;
1317 
1318  if (m->type == TYPE_MULTIPART)
1319  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level + 1, decrypted);
1320  else if (mutt_is_message_type(m->type, m->subtype))
1321  {
1322  mutt_generate_recvattach_list(actx, m->email, m->parts, fp, m->type,
1323  level + 1, decrypted);
1324  e->security |= m->email->security;
1325  }
1326  }
1327  }
1328 }
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:163
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1360
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:1228
#define SMIME_ENCRYPT
Definition: lib.h:149
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
#define PGP_ENCRYPT
Definition: lib.h:143
#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:123
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:146
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:457
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:89
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:891
char * subtype
content-type subtype
Definition: body.h:37
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:138
bool decrypted
Not part of message as stored in the email->content.
Definition: attach.h:43
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
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:460
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:518
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:436
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:620
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:212
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
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
+ 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 1334 of file recvattach.c.

1335 {
1336  /* Collapse the attachments if '$digest_collapse' is set AND if...
1337  * the outer container is of type 'multipart/digest' */
1338  bool digest = mutt_istr_equal(actx->email->content->subtype, "digest");
1339 
1340  for (int i = 0; i < actx->idxlen; i++)
1341  {
1342  actx->idx[i]->content->tagged = false;
1343 
1344  /* OR an inner container is of type 'multipart/digest' */
1345  actx->idx[i]->content->collapsed =
1346  (C_DigestCollapse && (digest ||
1347  ((actx->idx[i]->content->type == TYPE_MULTIPART) &&
1348  mutt_istr_equal(actx->idx[i]->content->subtype, "digest"))));
1349  }
1350 }
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
struct Body * content
List of MIME parts.
Definition: email.h:90
bool C_DigestCollapse
Config: Hide the subparts of a multipart/digest.
Definition: recvattach.c:74
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:891
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 Body * content
Attachment.
Definition: attach.h:36
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_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 1383 of file recvattach.c.

1384 {
1385  int rindex, curlevel;
1386 
1387  CUR_ATTACH->content->collapsed = !CUR_ATTACH->content->collapsed;
1388  /* When expanding, expand all the children too */
1389  if (CUR_ATTACH->content->collapsed)
1390  return;
1391 
1392  curlevel = CUR_ATTACH->level;
1393  rindex = actx->v2r[menu->current] + 1;
1394 
1395  while ((rindex < actx->idxlen) && (actx->idx[rindex]->level > curlevel))
1396  {
1397  if (C_DigestCollapse && (actx->idx[rindex]->content->type == TYPE_MULTIPART) &&
1398  mutt_istr_equal(actx->idx[rindex]->content->subtype, "digest"))
1399  {
1400  actx->idx[rindex]->content->collapsed = true;
1401  }
1402  else
1403  {
1404  actx->idx[rindex]->content->collapsed = false;
1405  }
1406  rindex++;
1407  }
1408 }
bool C_DigestCollapse
Config: Hide the subparts of a multipart/digest.
Definition: recvattach.c:74
#define CUR_ATTACH
Definition: recvattach.c:89
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:891
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
struct Body * content
Attachment.
Definition: attach.h:36
int current
Current entry.
Definition: mutt_menu.h:85
int level
Nesting depth of attachment.
Definition: attach.h:40
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:

◆ mutt_view_attachments()

void mutt_view_attachments ( struct Email e)

Show the attachments in a Menu.

Parameters
eEmail

Definition at line 1414 of file recvattach.c.

1415 {
1416  char helpstr[1024];
1417  int op = OP_NULL;
1418 
1419  struct Mailbox *m = Context ? Context->mailbox : NULL;
1420 
1421  /* make sure we have parsed this message */
1423 
1425 
1426  struct Message *msg = mx_msg_open(m, e->msgno);
1427  if (!msg)
1428  return;
1429 
1430  struct MuttWindow *dlg =
1433  dlg->notify = notify_new();
1434 
1435  struct MuttWindow *index =
1438  index->notify = notify_new();
1439  notify_set_parent(index->notify, dlg->notify);
1440 
1441  struct MuttWindow *ibar =
1444  ibar->notify = notify_new();
1445  notify_set_parent(ibar->notify, dlg->notify);
1446 
1447  if (C_StatusOnTop)
1448  {
1449  mutt_window_add_child(dlg, ibar);
1450  mutt_window_add_child(dlg, index);
1451  }
1452  else
1453  {
1454  mutt_window_add_child(dlg, index);
1455  mutt_window_add_child(dlg, ibar);
1456  }
1457 
1458  dialog_push(dlg);
1459 
1460  struct Menu *menu = mutt_menu_new(MENU_ATTACH);
1461 
1462  menu->pagelen = index->state.rows;
1463  menu->win_index = index;
1464  menu->win_ibar = ibar;
1465 
1466  menu->title = _("Attachments");
1467  menu->make_entry = attach_make_entry;
1468  menu->tag = attach_tag;
1469  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_ATTACH, AttachHelp);
1470  mutt_menu_push_current(menu);
1471 
1472  struct AttachCtx *actx = mutt_actx_new();
1473  actx->email = e;
1474  actx->fp_root = msg->fp;
1475  mutt_update_recvattach_menu(actx, menu, true);
1476 
1477  while (true)
1478  {
1479  if (op == OP_NULL)
1480  op = mutt_menu_loop(menu);
1481  if (!Context)
1482  return;
1483  switch (op)
1484  {
1485  case OP_ATTACH_VIEW_MAILCAP:
1487  MUTT_VA_MAILCAP, e, actx, menu->win_index);
1488  menu->redraw = REDRAW_FULL;
1489  break;
1490 
1491  case OP_ATTACH_VIEW_TEXT:
1493  MUTT_VA_AS_TEXT, e, actx, menu->win_index);
1494  menu->redraw = REDRAW_FULL;
1495  break;
1496 
1497  case OP_DISPLAY_HEADERS:
1498  case OP_VIEW_ATTACH:
1499  op = mutt_attach_display_loop(menu, op, e, actx, true);
1500  menu->redraw = REDRAW_FULL;
1501  continue;
1502 
1503  case OP_ATTACH_COLLAPSE:
1504  if (!CUR_ATTACH->content->parts)
1505  {
1506  mutt_error(_("There are no subparts to show"));
1507  break;
1508  }
1509  attach_collapse(actx, menu);
1510  mutt_update_recvattach_menu(actx, menu, false);
1511  break;
1512 
1513  case OP_FORGET_PASSPHRASE:
1515  break;
1516 
1517  case OP_EXTRACT_KEYS:
1519  {
1520  recvattach_extract_pgp_keys(actx, menu);
1521  menu->redraw = REDRAW_FULL;
1522  }
1523  break;
1524 
1525  case OP_CHECK_TRADITIONAL:
1526  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1528  {
1529  e->security = crypt_query(NULL);
1530  menu->redraw = REDRAW_FULL;
1531  }
1532  break;
1533 
1534  case OP_PRINT:
1536  CUR_ATTACH->content);
1537  break;
1538 
1539  case OP_PIPE:
1541  CUR_ATTACH->content, false);
1542  break;
1543 
1544  case OP_SAVE:
1546  CUR_ATTACH->content, e, menu);
1547 
1548  if (!menu->tagprefix && C_Resolve && (menu->current < menu->max - 1))
1549  menu->current++;
1550 
1552  break;
1553 
1554  case OP_DELETE:
1556 
1557 #ifdef USE_POP
1558  if (m->type == MUTT_POP)
1559  {
1560  mutt_flushinp();
1561  mutt_error(_("Can't delete attachment from POP server"));
1562  break;
1563  }
1564 #endif
1565 
1566 #ifdef USE_NNTP
1567  if (m->type == MUTT_NNTP)
1568  {
1569  mutt_flushinp();
1570  mutt_error(_("Can't delete attachment from news server"));
1571  break;
1572  }
1573 #endif
1574 
1575  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
1576  {
1577  mutt_message(_("Deletion of attachments from encrypted messages is "
1578  "unsupported"));
1579  break;
1580  }
1581  if ((WithCrypto != 0) && (e->security & (SEC_SIGN | SEC_PARTSIGN)))
1582  {
1583  mutt_message(_("Deletion of attachments from signed messages may "
1584  "invalidate the signature"));
1585  }
1586  if (!menu->tagprefix)
1587  {
1588  if (CUR_ATTACH->parent_type == TYPE_MULTIPART)
1589  {
1590  CUR_ATTACH->content->deleted = true;
1591  if (C_Resolve && (menu->current < menu->max - 1))
1592  {
1593  menu->current++;
1594  menu->redraw = REDRAW_MOTION_RESYNC;
1595  }
1596  else
1597  menu->redraw = REDRAW_CURRENT;
1598  }
1599  else
1600  {
1601  mutt_message(
1602  _("Only deletion of multipart attachments is supported"));
1603  }
1604  }
1605  else
1606  {
1607  for (int i = 0; i < menu->max; i++)
1608  {
1609  if (actx->idx[i]->content->tagged)
1610  {
1611  if (actx->idx[i]->parent_type == TYPE_MULTIPART)
1612  {
1613  actx->idx[i]->content->deleted = true;
1614  menu->redraw = REDRAW_INDEX;
1615  }
1616  else
1617  {
1618  mutt_message(
1619  _("Only deletion of multipart attachments is supported"));
1620  }
1621  }
1622  }
1623  }
1624  break;
1625 
1626  case OP_UNDELETE:
1628  if (!menu->tagprefix)
1629  {
1630  CUR_ATTACH->content->deleted = false;
1631  if (C_Resolve && (menu->current < menu->max - 1))
1632  {
1633  menu->current++;
1634  menu->redraw = REDRAW_MOTION_RESYNC;
1635  }
1636  else
1637  menu->redraw = REDRAW_CURRENT;
1638  }
1639  else
1640  {
1641  for (int i = 0; i < menu->max; i++)
1642  {
1643  if (actx->idx[i]->content->tagged)
1644  {
1645  actx->idx[i]->content->deleted = false;
1646  menu->redraw = REDRAW_INDEX;
1647  }
1648  }
1649  }
1650  break;
1651 
1652  case OP_RESEND:
1653  CHECK_ATTACH;
1654  mutt_attach_resend(CUR_ATTACH->fp, actx,
1655  menu->tagprefix ? NULL : CUR_ATTACH->content);
1656  menu->redraw = REDRAW_FULL;
1657  break;
1658 
1659  case OP_BOUNCE_MESSAGE:
1660  CHECK_ATTACH;
1661  mutt_attach_bounce(m, CUR_ATTACH->fp, actx,
1662  menu->tagprefix ? NULL : CUR_ATTACH->content);
1663  menu->redraw = REDRAW_FULL;
1664  break;
1665 
1666  case OP_FORWARD_MESSAGE:
1667  CHECK_ATTACH;
1668  mutt_attach_forward(CUR_ATTACH->fp, e, actx,
1669  menu->tagprefix ? NULL : CUR_ATTACH->content, SEND_NO_FLAGS);
1670  menu->redraw = REDRAW_FULL;
1671  break;
1672 
1673 #ifdef USE_NNTP
1674  case OP_FORWARD_TO_GROUP:
1675  CHECK_ATTACH;
1676  mutt_attach_forward(CUR_ATTACH->fp, e, actx,
1677  menu->tagprefix ? NULL : CUR_ATTACH->content, SEND_NEWS);
1678  menu->redraw = REDRAW_FULL;
1679  break;
1680 
1681  case OP_FOLLOWUP:
1682  CHECK_ATTACH;
1683 
1684  if (!CUR_ATTACH->content->email->env->followup_to ||
1685  !mutt_istr_equal(CUR_ATTACH->content->email->env->followup_to,
1686  "poster") ||
1688  _("Reply by mail as poster prefers?")) != MUTT_YES))
1689  {
1690  mutt_attach_reply(CUR_ATTACH->fp, e, actx,
1691  menu->tagprefix ? NULL : CUR_ATTACH->content,
1692  SEND_NEWS | SEND_REPLY);
1693  menu->redraw = REDRAW_FULL;
1694  break;
1695  }
1696 #endif
1697  /* fallthrough */
1698  case OP_REPLY:
1699  case OP_GROUP_REPLY:
1700  case OP_GROUP_CHAT_REPLY:
1701  case OP_LIST_REPLY:
1702  {
1703  CHECK_ATTACH;
1704 
1705  SendFlags flags = SEND_REPLY;
1706  if (op == OP_GROUP_REPLY)
1707  flags |= SEND_GROUP_REPLY;
1708  else if (op == OP_GROUP_CHAT_REPLY)
1709  flags |= SEND_GROUP_CHAT_REPLY;
1710  else if (op == OP_LIST_REPLY)
1711  flags |= SEND_LIST_REPLY;
1712 
1713  mutt_attach_reply(CUR_ATTACH->fp, e, actx,
1714  menu->tagprefix ? NULL : CUR_ATTACH->content, flags);
1715  menu->redraw = REDRAW_FULL;
1716  break;
1717  }
1718 
1719  case OP_COMPOSE_TO_SENDER:
1720  CHECK_ATTACH;
1721  mutt_attach_mail_sender(CUR_ATTACH->fp, e, actx,
1722  menu->tagprefix ? NULL : CUR_ATTACH->content);
1723  menu->redraw = REDRAW_FULL;
1724  break;
1725 
1726  case OP_EDIT_TYPE:
1727  recvattach_edit_content_type(actx, menu, e);
1728  menu->redraw |= REDRAW_INDEX;
1729  break;
1730 
1731  case OP_EXIT:
1732  mx_msg_close(m, &msg);
1733 
1734  e->attach_del = false;
1735  for (int i = 0; i < actx->idxlen; i++)
1736  {
1737  if (actx->idx[i]->content && actx->idx[i]->content->deleted)
1738  {
1739  e->attach_del = true;
1740  break;
1741  }
1742  }
1743  if (e->attach_del)
1744  e->changed = true;
1745 
1746  mutt_actx_free(&actx);
1747 
1748  mutt_menu_pop_current(menu);
1749  mutt_menu_free(&menu);
1750  dialog_pop();
1751  mutt_window_free(&dlg);
1752  return;
1753  }
1754 
1755  op = OP_NULL;
1756  }
1757 
1758  /* not reached */
1759 }
The "current" mailbox.
Definition: context.h:37
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: globals.h:247
#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:163
static const struct Mapping AttachHelp[]
Definition: recvattach.c:91
GUI selectable list of items.
Definition: mutt_menu.h:80
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:437
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1112
#define mutt_message(...)
Definition: logging.h:83
Attach Dialog, mutt_view_attachments()
Definition: mutt_window.h:75
Window uses all available vertical space.
Definition: mutt_window.h:35
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void dialog_pop(void)
Hide a Window from the user.
Definition: mutt_window.c:722
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
WHERE unsigned char C_FollowupToPoster
Config: (nntp) Reply to the poster if &#39;poster&#39; is in the &#39;Followup-To&#39; header.
Definition: globals.h:186
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:898
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition: mutt_window.c:697
void crypt_forget_passphrase(void)
Forget a passphrase and display a message.
Definition: crypt.c:104
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:108
#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:86
#define CUR_ATTACH
Definition: recvattach.c:89
An Index Window containing a selection list.
Definition: mutt_window.h:93
int attach_tag(struct Menu *menu, int sel, int act)
Tag an attachment - Implements Menu::tag()
Definition: recvattach.c:449
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:150
#define SEND_NO_FLAGS
No flags are set.
Definition: send.h:87
void mutt_attach_reply(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *e_cur, SendFlags flags)
Attach a reply.
Definition: recvcmd.c:903
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1181
struct Notify * notify
Notifications system.
Definition: mutt_window.h:123
struct Mailbox * mailbox
Definition: context.h:50
struct MuttWindow * win_ibar
Definition: mutt_menu.h:93
const char * title
Title of this menu.
Definition: mutt_menu.h:82
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:90
bool tagged
This attachment is tagged.
Definition: body.h:70
Window has a fixed size.
Definition: mutt_window.h:44
const char * help
Quickref for the current menu.
Definition: mutt_menu.h:83
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:891
#define REDRAW_MOTION_RESYNC
Redraw any changing the menu selection.
Definition: mutt_menu.h:42
struct Notify * notify_new(void)
Create a new notifications handler.
Definition: notify.c:49
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
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:113
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:55
A local copy of an email.
Definition: mx.h:83
Select an attachment.
Definition: keymap.h:73
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:1120
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:1150
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:49
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
bool tagprefix
Definition: mutt_menu.h:90
static void recvattach_extract_pgp_keys(struct AttachCtx *actx, struct Menu *menu)
Extract PGP keys from attachments.
Definition: recvattach.c:1074
WHERE bool C_Resolve
Config: Move to the next email whenever a command modifies an email.
Definition: globals.h:238
static void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1358
#define SEND_NEWS
Reply to a news article.
Definition: send.h:102
int(* tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:136
int pagelen
Number of entries per screen.
Definition: mutt_menu.h:89
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:1098
Force viewing using mailcap entry.
Definition: mutt_attach.h:43
#define SEND_REPLY
Reply to sender.
Definition: send.h:88
#define CHECK_READONLY
Definition: recvattach.c:81
int max
Number of entries in the menu.
Definition: mutt_menu.h:86
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:564
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
Definition: recvattach.c:1031
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:87
void mutt_attach_forward(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur, SendFlags flags)
Forward an Attachment.
Definition: recvcmd.c:756
#define SEC_SIGN
Email is signed.
Definition: lib.h:126
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:1383
#define SEND_GROUP_REPLY
Reply to all.
Definition: send.h:89
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:40
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
FILE * fp
pointer to the message data
Definition: mx.h:85
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:650
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:1073
void notify_set_parent(struct Notify *notify, struct Notify *parent)
Set the parent notification handler.
Definition: notify.c:82
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:573
struct MuttWindow * mutt_window_new(enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows)
Create a new Window.
Definition: mutt_window.c:131
#define SEND_GROUP_CHAT_REPLY
Reply to all recipients preserving To/Cc.
Definition: send.h:101
int current
Current entry.
Definition: mutt_menu.h:85
struct MuttWindow * win_index
Definition: mutt_menu.h:92
char * mutt_compile_help(char *buf, size_t buflen, enum MenuType menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:110
Window wants as much space as possible.
Definition: mutt_window.h:45
#define CHECK_ATTACH
Definition: recvattach.c:99
Index Bar containing status info about the Index.
Definition: mutt_window.h:94
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:695
void(* make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:117
void mutt_attach_resend(FILE *fp, struct AttachCtx *actx, struct Body *cur)
resend-message, from the attachment menu
Definition: recvcmd.c:291
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1133
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: lib.h:129
#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:876
int msgno
Number displayed to the user.
Definition: email.h:86
int mutt_view_attachment(FILE *fp, struct Body *a, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx, struct MuttWindow *win)
View an attachment.
Definition: mutt_attach.c:415
+ 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 70 of file recvattach.c.

◆ C_AttachSaveWithoutPrompting

char* C_AttachSaveWithoutPrompting

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

Definition at line 71 of file recvattach.c.

◆ C_AttachSep

char* C_AttachSep

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

Definition at line 72 of file recvattach.c.

◆ C_AttachSplit

bool C_AttachSplit

Config: Save/print/pipe tagged messages individually.

Definition at line 73 of file recvattach.c.

◆ C_DigestCollapse

bool C_DigestCollapse

Config: Hide the subparts of a multipart/digest.

Definition at line 74 of file recvattach.c.

◆ C_MessageFormat

char* C_MessageFormat

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

Definition at line 75 of file recvattach.c.

◆ Mailbox_is_read_only

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

Definition at line 79 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

Definition at line 91 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 96 of file recvattach.c.