NeoMutt  2020-03-20-65-g141838
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, unsigned long 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 (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 (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:51
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 1355 of file recvattach.c.

1356 {
1357  if (init)
1358  {
1359  mutt_generate_recvattach_list(actx, actx->email, actx->email->content,
1360  actx->fp_root, -1, 0, 0);
1361  mutt_attach_init(actx);
1362  menu->data = actx;
1363  }
1364 
1365  mutt_update_tree(actx);
1366 
1367  menu->max = actx->vcount;
1368 
1369  if (menu->current >= menu->max)
1370  menu->current = menu->max - 1;
1371  menu_check_recenter(menu);
1372  menu->redraw |= REDRAW_INDEX;
1373 }
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:1223
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 mutt_attach_init(struct AttachCtx *actx)
Create a new Attachment context.
Definition: recvattach.c:1330
int max
Number of entries in the menu.
Definition: mutt_menu.h:88
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
void mutt_update_tree(struct AttachCtx *actx)
Refresh the list of attachments.
Definition: recvattach.c:142
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
int current
Current entry.
Definition: mutt_menu.h:87
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_strcmp(actx->idx[rindex]->tree, buf) != 0)
170  mutt_str_replace(&actx->idx[rindex]->tree, buf);
171  }
172  else
173  actx->idx[rindex]->tree = mutt_str_strdup(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 }
Lower left corner.
Definition: mutt_menu.h:61
struct Body * next
next attachment in the list
Definition: body.h:53
Right arrow.
Definition: mutt_menu.h:67
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:453
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
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:63
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
short vcount
The number of virtual attachments.
Definition: attach.h:59
Horizontal line.
Definition: mutt_menu.h:64
+ 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,
unsigned long  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.

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

439 {
440  struct AttachCtx *actx = menu->data;
441 
442  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
444  (unsigned long) (actx->idx[actx->v2r[line]]), MUTT_FORMAT_ARROWCURSOR);
445 }
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:863
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_AttachFormat
Config: printf-like format string for the attachment menu.
Definition: globals.h:101
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:93
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, unsigned long data, MuttFormatFlags flags)
Format a string for the attachment menu - Implements format_t.
Definition: recvattach.c:208
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
int const char int line
Definition: acutest.h:602
struct MuttWindow * win_index
Definition: mutt_menu.h:95
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 450 of file recvattach.c.

451 {
452  struct AttachCtx *actx = menu->data;
453  struct Body *cur = actx->idx[actx->v2r[sel]]->content;
454  bool ot = cur->tagged;
455 
456  cur->tagged = ((act >= 0) ? act : !cur->tagged);
457  return cur->tagged - ot;
458 }
The body of an email.
Definition: body.h:34
bool tagged
This attachment is tagged.
Definition: body.h:70
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
struct Body * content
Attachment.
Definition: attach.h:36
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
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 464 of file recvattach.c.

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

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

506 {
507  char *prompt = NULL;
508  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
509  int rc = -1;
510 
511  struct Buffer *buf = mutt_buffer_pool_get();
512  struct Buffer *tfile = mutt_buffer_pool_get();
513 
514  if (body->filename)
515  {
516  if (directory && *directory)
517  {
518  mutt_buffer_concat_path(buf, *directory, mutt_path_basename(body->filename));
519  }
520  else
521  mutt_buffer_strcpy(buf, body->filename);
522  }
523  else if (has_a_message(body))
524  {
525  mutt_default_save(buf->data, buf->dsize, body->email);
527  }
528 
529  prepend_savedir(buf);
530 
531  prompt = _("Save to file: ");
532  while (prompt)
533  {
534  if ((mutt_buffer_get_field(prompt, buf, MUTT_FILE | MUTT_CLEAR) != 0) ||
536  {
537  goto cleanup;
538  }
539 
540  prompt = NULL;
542 
543  bool is_message = (fp && has_a_message(body));
544 
545  if (is_message)
546  {
547  struct stat st;
548 
549  /* check to make sure that this file is really the one the user wants */
550  rc = mutt_save_confirm(mutt_b2s(buf), &st);
551  if (rc == 1)
552  {
553  prompt = _("Save to file: ");
554  continue;
555  }
556  else if (rc == -1)
557  goto cleanup;
558  mutt_buffer_copy(tfile, buf);
559  }
560  else
561  {
562  rc = mutt_check_overwrite(body->filename, mutt_b2s(buf), tfile, &opt, directory);
563  if (rc == -1)
564  goto cleanup;
565  else if (rc == 1)
566  {
567  prompt = _("Save to file: ");
568  continue;
569  }
570  }
571 
572  mutt_message(_("Saving..."));
573  if (mutt_save_attachment(fp, body, mutt_b2s(tfile), opt,
574  (e || !is_message) ? e : body->email) == 0)
575  {
576  mutt_message(_("Attachment saved"));
577  rc = 0;
578  goto cleanup;
579  }
580  else
581  {
582  prompt = _("Save to file: ");
583  continue;
584  }
585  }
586 
587 cleanup:
589  mutt_buffer_pool_release(&tfile);
590  return rc;
591 }
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:489
#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:464
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:662
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1438
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:711
#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:328
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 601 of file recvattach.c.

602 {
603  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
604  int rc = -1;
605  struct Buffer *buf = mutt_buffer_pool_get();
606  struct Buffer *tfile = mutt_buffer_pool_get();
607 
608  if (body->filename)
609  {
610  mutt_buffer_strcpy(buf, body->filename);
611  }
612  else if (has_a_message(body))
613  {
614  mutt_default_save(buf->data, buf->dsize, body->email);
615  }
616 
617  prepend_savedir(buf);
619 
620  bool is_message = (fp && has_a_message(body));
621 
622  if (is_message)
623  {
624  mutt_buffer_copy(tfile, buf);
625  }
626  else
627  {
628  rc = mutt_check_overwrite(body->filename, mutt_b2s(buf), tfile, &opt, NULL);
629  if (rc == -1) // abort or cancel
630  goto cleanup;
631  }
632 
633  rc = mutt_save_attachment(fp, body, mutt_b2s(tfile), opt,
634  (e || !is_message) ? e : body->email);
635 
636 cleanup:
638  mutt_buffer_pool_release(&tfile);
639  return rc;
640 }
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:489
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:464
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:662
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:711
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:328
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 651 of file recvattach.c.

653 {
654  char *directory = NULL;
655  int rc = 1;
656  int last = menu ? menu->current : -1;
657  FILE *fp_out = NULL;
658  int saved_attachments = 0;
659 
660  struct Buffer *buf = mutt_buffer_pool_get();
661  struct Buffer *tfile = mutt_buffer_pool_get();
662 
663  for (int i = 0; !tag || (i < actx->idxlen); i++)
664  {
665  if (tag)
666  {
667  fp = actx->idx[i]->fp;
668  top = actx->idx[i]->content;
669  }
670  if (!tag || top->tagged)
671  {
672  if (!C_AttachSplit)
673  {
674  if (mutt_buffer_is_empty(buf))
675  {
676  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
677 
679  prepend_savedir(buf);
680 
681  if ((mutt_buffer_get_field(_("Save to file: "), buf, MUTT_FILE | MUTT_CLEAR) != 0) ||
683  {
684  goto cleanup;
685  }
687  if (mutt_check_overwrite(top->filename, mutt_b2s(buf), tfile, &opt, NULL))
688  goto cleanup;
689  rc = mutt_save_attachment(fp, top, mutt_b2s(tfile), opt, e);
690  if ((rc == 0) && C_AttachSep && (fp_out = fopen(mutt_b2s(tfile), "a")))
691  {
692  fprintf(fp_out, "%s", C_AttachSep);
693  mutt_file_fclose(&fp_out);
694  }
695  }
696  else
697  {
698  rc = mutt_save_attachment(fp, top, mutt_b2s(tfile), MUTT_SAVE_APPEND, e);
699  if ((rc == 0) && C_AttachSep && (fp_out = fopen(mutt_b2s(tfile), "a")))
700  {
701  fprintf(fp_out, "%s", C_AttachSep);
702  mutt_file_fclose(&fp_out);
703  }
704  }
705  }
706  else
707  {
708  if (tag && menu && top->aptr)
709  {
710  menu->oldcurrent = menu->current;
711  menu->current = top->aptr->num;
712  menu_check_recenter(menu);
713  menu->redraw |= REDRAW_MOTION;
714 
715  menu_redraw(menu);
716  }
718  {
719  // Save each file, with no prompting, using the configured 'AttachSaveDir'
720  rc = save_without_prompting(fp, top, e);
721  if (rc == 0)
722  saved_attachments++;
723  }
724  else
725  {
726  // Save each file, prompting the user for the location each time.
727  if (query_save_attachment(fp, top, e, &directory) == -1)
728  break;
729  }
730  }
731  }
732  if (!tag)
733  break;
734  }
735 
736  FREE(&directory);
737 
738  if (tag && menu)
739  {
740  menu->oldcurrent = menu->current;
741  menu->current = last;
742  menu_check_recenter(menu);
743  menu->redraw |= REDRAW_MOTION;
744  }
745 
746  if (!C_AttachSplit && (rc == 0))
747  mutt_message(_("Attachment saved"));
748 
749  if (C_AttachSaveWithoutPrompting && (rc == 0))
750  {
751  mutt_message(ngettext("Attachment saved", "%d attachments saved", saved_attachments),
752  saved_attachments);
753  }
754 
755 cleanup:
757  mutt_buffer_pool_release(&tfile);
758 }
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:109
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:464
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:505
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:43
#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:601
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:711
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:84
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:328
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:87
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 ( 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 767 of file recvattach.c.

768 {
769  char tfile[PATH_MAX];
770 
771  if (filter)
772  {
773  char warning[PATH_MAX + 256];
774  snprintf(warning, sizeof(warning),
775  _("WARNING! You are about to overwrite %s, continue?"), body->filename);
776  if (mutt_yesorno(warning, MUTT_NO) != MUTT_YES)
777  {
779  return;
780  }
781  mutt_mktemp(tfile, sizeof(tfile));
782  }
783  else
784  tfile[0] = '\0';
785 
786  if (mutt_pipe_attachment(fp, body, command, tfile))
787  {
788  if (filter)
789  {
790  mutt_file_unlink(body->filename);
791  mutt_file_rename(tfile, body->filename);
792  mutt_update_encoding(body);
793  mutt_message(_("Attachment filtered"));
794  }
795  }
796  else
797  {
798  if (filter && tfile[0])
799  mutt_file_unlink(tfile);
800  }
801 }
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:1341
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:378
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1480
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:112
#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 809 of file recvattach.c.

810 {
811  if (!state || !state->fp_out)
812  return;
813 
814  if (fp)
815  {
816  state->fp_in = fp;
817  mutt_decode_attachment(b, state);
818  if (C_AttachSep)
819  state_puts(state, C_AttachSep);
820  }
821  else
822  {
823  FILE *fp_in = fopen(b->filename, "r");
824  if (!fp_in)
825  {
826  mutt_perror("fopen");
827  return;
828  }
829  mutt_file_copy_stream(fp_in, state->fp_out);
830  mutt_file_fclose(&fp_in);
831  if (C_AttachSep)
832  state_puts(state, C_AttachSep);
833  }
834 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1794
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 ( 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 846 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(char *command, FILE *fp, struct Body *body, bool filter)
Ask the user if we should pipe the attachment.
Definition: recvattach.c:767
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:809
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  char buf[PATH_MAX];
881 
882  if (fp)
883  filter = false; /* sanity check: we can't filter in the recv case yet */
884 
885  buf[0] = '\0';
886  /* perform charset conversion on text attachments when piping */
887  state.flags = MUTT_CHARCONV;
888 
889  if ((mutt_get_field((filter ? _("Filter through: ") : _("Pipe to: ")), buf,
890  sizeof(buf), MUTT_CMD) != 0) ||
891  (buf[0] == '\0'))
892  {
893  return;
894  }
895 
896  mutt_expand_path(buf, sizeof(buf));
897 
898  if (!filter && !C_AttachSplit)
899  {
900  mutt_endwin();
901  pid_t pid = filter_create(buf, &state.fp_out, NULL, NULL);
902  pipe_attachment_list(buf, actx, fp, tag, top, filter, &state);
903  mutt_file_fclose(&state.fp_out);
904  if ((filter_wait(pid) != 0) || C_WaitKey)
906  }
907  else
908  pipe_attachment_list(buf, actx, fp, tag, top, filter, &state);
909 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:73
static void pipe_attachment_list(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:846
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
#define _(a)
Definition: message.h:28
FILE * fp_out
File to write to.
Definition: state.h:47
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:90
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:133
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
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: globals.h:257
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:547
#define PATH_MAX
Definition: mutt.h:44
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:580
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 918 of file recvattach.c.

919 {
920  char type[256];
921 
922  for (int i = 0; !tag || (i < actx->idxlen); i++)
923  {
924  if (tag)
925  top = actx->idx[i]->content;
926  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
927  if (!tag || top->tagged)
928  {
929  if (!mailcap_lookup(top, type, sizeof(type), NULL, MUTT_MC_PRINT))
930  {
931  if ((mutt_str_strcasecmp("text/plain", top->subtype) != 0) &&
932  (mutt_str_strcasecmp("application/postscript", top->subtype) != 0))
933  {
934  if (!mutt_can_decode(top))
935  {
936  /* L10N: s gets replaced by a MIME type, e.g. "text/plain" or
937  application/octet-stream. */
938  mutt_error(_("I don't know how to print %s attachments"), type);
939  return false;
940  }
941  }
942  }
943  }
944  if (!tag)
945  break;
946  }
947  return true;
948 }
#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:466
Mailcap print field.
Definition: mailcap.h:61
bool tagged
This attachment is tagged.
Definition: body.h:70
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:1753
#define TYPE(body)
Definition: mime.h:83
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
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 958 of file recvattach.c.

960 {
961  char type[256];
962 
963  for (int i = 0; !tag || (i < actx->idxlen); i++)
964  {
965  if (tag)
966  {
967  fp = actx->idx[i]->fp;
968  top = actx->idx[i]->content;
969  }
970  if (!tag || top->tagged)
971  {
972  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
973  if (!C_AttachSplit && !mailcap_lookup(top, type, sizeof(type), NULL, MUTT_MC_PRINT))
974  {
975  if ((mutt_str_strcasecmp("text/plain", top->subtype) == 0) ||
976  (mutt_str_strcasecmp("application/postscript", top->subtype) == 0))
977  {
978  pipe_attachment(fp, top, state);
979  }
980  else if (mutt_can_decode(top))
981  {
982  /* decode and print */
983 
984  FILE *fp_in = NULL;
985  struct Buffer *newfile = mutt_buffer_pool_get();
986 
987  mutt_buffer_mktemp(newfile);
988  if (mutt_decode_save_attachment(fp, top, mutt_b2s(newfile),
990  {
991  if (!state->fp_out)
992  {
993  mutt_error(
994  "BUG in print_attachment_list(). Please report this. ");
995  return;
996  }
997 
998  fp_in = fopen(mutt_b2s(newfile), "r");
999  if (fp_in)
1000  {
1001  mutt_file_copy_stream(fp_in, state->fp_out);
1002  mutt_file_fclose(&fp_in);
1003  if (C_AttachSep)
1004  state_puts(state, C_AttachSep);
1005  }
1006  }
1007  mutt_file_unlink(mutt_b2s(newfile));
1008  mutt_buffer_pool_release(&newfile);
1009  }
1010  }
1011  else
1012  mutt_print_attachment(fp, top);
1013  }
1014  if (!tag)
1015  break;
1016  }
1017 }
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
FILE * fp_in
File to read from.
Definition: state.h:46
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:466
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
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:1753
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:809
#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
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
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 1026 of file recvattach.c.

1027 {
1028  char prompt[128];
1029  struct State state = { 0 };
1030  int tagmsgcount = 0;
1031 
1032  if (tag)
1033  for (int i = 0; i < actx->idxlen; i++)
1034  if (actx->idx[i]->content->tagged)
1035  tagmsgcount++;
1036 
1037  snprintf(prompt, sizeof(prompt),
1038  /* L10N: Although we now the precise number of tagged messages, we
1039  do not show it to the user. So feel free to use a "generic
1040  plural" as plural translation if your language has one. */
1041  tag ? ngettext("Print tagged attachment?", "Print %d tagged attachments?", tagmsgcount) :
1042  _("Print attachment?"),
1043  tagmsgcount);
1044  if (query_quadoption(C_Print, prompt) != MUTT_YES)
1045  return;
1046 
1047  if (C_AttachSplit)
1048  {
1049  print_attachment_list(actx, fp, tag, top, &state);
1050  }
1051  else
1052  {
1053  if (!can_print(actx, top, tag))
1054  return;
1055  mutt_endwin();
1056  pid_t pid = filter_create(NONULL(C_PrintCommand), &state.fp_out, NULL, NULL);
1057  print_attachment_list(actx, fp, tag, top, &state);
1058  mutt_file_fclose(&state.fp_out);
1059  if ((filter_wait(pid) != 0) || C_WaitKey)
1061  }
1062 }
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:184
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
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:958
#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:257
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:547
static bool can_print(struct AttachCtx *actx, struct Body *top, bool tag)
Do we know how to print this attachment type?
Definition: recvattach.c:918
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:580
struct Body * content
Attachment.
Definition: attach.h:36
WHERE char * C_PrintCommand
Config: External command to print a message.
Definition: globals.h:137
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 1069 of file recvattach.c.

1070 {
1071  if (!menu->tagprefix)
1073  else
1074  {
1075  for (int i = 0; i < actx->idxlen; i++)
1076  {
1077  if (actx->idx[i]->content->tagged)
1078  {
1079  crypt_pgp_extract_key_from_attachment(actx->idx[i]->fp, actx->idx[i]->content);
1080  }
1081  }
1082  }
1083 }
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:386
bool tagprefix
Definition: mutt_menu.h:93
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 1093 of file recvattach.c.

1094 {
1095  int rc = 0;
1096 
1097  if (!menu->tagprefix)
1098  rc = crypt_pgp_check_traditional(CUR_ATTACH->fp, CUR_ATTACH->content, true);
1099  else
1100  {
1101  for (int i = 0; i < actx->idxlen; i++)
1102  if (actx->idx[i]->content->tagged)
1103  rc = rc || crypt_pgp_check_traditional(actx->idx[i]->fp, actx->idx[i]->content, true);
1104  }
1105 
1106  return rc;
1107 }
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:93
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:274
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 1115 of file recvattach.c.

1117 {
1118  if (!mutt_edit_content_type(e, CUR_ATTACH->content, CUR_ATTACH->fp))
1119  return;
1120 
1121  /* The mutt_update_recvattach_menu() will overwrite any changes
1122  * made to a decrypted CUR_ATTACH->content, so warn the user. */
1123  if (CUR_ATTACH->decrypted)
1124  {
1125  mutt_message(
1126  _("Structural changes to decrypted attachments are not supported"));
1127  mutt_sleep(1);
1128  }
1129  /* Editing the content type can rewrite the body structure. */
1130  for (int i = 0; i < actx->idxlen; i++)
1131  actx->idx[i]->content = NULL;
1132  mutt_actx_entries_free(actx);
1133  mutt_update_recvattach_menu(actx, menu, true);
1134 }
#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:1535
static void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1355
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:1239
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 1145 of file recvattach.c.

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

1226 {
1227  struct Body *m = NULL;
1228  struct Body *new_body = NULL;
1229  FILE *fp_new = NULL;
1231  int need_secured, secured;
1232 
1233  for (m = parts; m; m = m->next)
1234  {
1235  need_secured = 0;
1236  secured = 0;
1237 
1238  if (((WithCrypto & APPLICATION_SMIME) != 0) && (type = mutt_is_application_smime(m)))
1239  {
1240  need_secured = 1;
1241 
1242  if (type & SEC_ENCRYPT)
1243  {
1244  if (!crypt_valid_passphrase(APPLICATION_SMIME))
1245  goto decrypt_failed;
1246 
1247  if (e->env)
1249  }
1250 
1251  secured = !crypt_smime_decrypt_mime(fp, &fp_new, m, &new_body);
1252  /* If the decrypt/verify-opaque doesn't generate mime output, an empty
1253  * text/plain type will still be returned by mutt_read_mime_header().
1254  * We can't distinguish an actual part from a failure, so only use a
1255  * text/plain that results from a single top-level part. */
1256  if (secured && (new_body->type == TYPE_TEXT) &&
1257  (mutt_str_strcasecmp("plain", new_body->subtype) == 0) &&
1258  ((parts != m) || m->next))
1259  {
1260  mutt_body_free(&new_body);
1261  mutt_file_fclose(&fp_new);
1262  goto decrypt_failed;
1263  }
1264 
1265  if (secured && (type & SEC_ENCRYPT))
1266  e->security |= SMIME_ENCRYPT;
1267  }
1268 
1269  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1271  {
1272  need_secured = 1;
1273 
1274  if (!crypt_valid_passphrase(APPLICATION_PGP))
1275  goto decrypt_failed;
1276 
1277  secured = !crypt_pgp_decrypt_mime(fp, &fp_new, m, &new_body);
1278 
1279  if (secured)
1280  e->security |= PGP_ENCRYPT;
1281  }
1282 
1283  if (need_secured && secured)
1284  {
1285  mutt_actx_add_fp(actx, fp_new);
1286  mutt_actx_add_body(actx, new_body);
1287  mutt_generate_recvattach_list(actx, e, new_body, fp_new, parent_type, level, 1);
1288  continue;
1289  }
1290 
1291  decrypt_failed:
1292  /* Fall through and show the original parts if decryption fails */
1293  if (need_secured && !secured)
1294  mutt_error(_("Can't decrypt encrypted message"));
1295 
1296  /* Strip out the top level multipart */
1297  if ((m->type == TYPE_MULTIPART) && m->parts && !need_secured &&
1298  ((parent_type == -1) && mutt_str_strcasecmp("alternative", m->subtype)))
1299  {
1300  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level, decrypted);
1301  }
1302  else
1303  {
1304  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1305  mutt_actx_add_attach(actx, ap);
1306 
1307  ap->content = m;
1308  ap->fp = fp;
1309  m->aptr = ap;
1310  ap->parent_type = parent_type;
1311  ap->level = level;
1312  ap->decrypted = decrypted;
1313 
1314  if (m->type == TYPE_MULTIPART)
1315  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level + 1, decrypted);
1316  else if (mutt_is_message_type(m->type, m->subtype))
1317  {
1318  mutt_generate_recvattach_list(actx, m->email, m->parts, fp, m->type,
1319  level + 1, decrypted);
1320  e->security |= m->email->security;
1321  }
1322  }
1323  }
1324 }
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:1391
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:1223
#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:459
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
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:448
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:520
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:424
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:624
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
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:200
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
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 1330 of file recvattach.c.

1331 {
1332  /* Collapse the attachments if '$digest_collapse' is set AND if...
1333  * the outer container is of type 'multipart/digest' */
1334  bool digest = (mutt_str_strcasecmp(actx->email->content->subtype, "digest") == 0);
1335 
1336  for (int i = 0; i < actx->idxlen; i++)
1337  {
1338  actx->idx[i]->content->tagged = false;
1339 
1340  /* OR an inner container is of type 'multipart/digest' */
1341  actx->idx[i]->content->collapsed =
1342  (C_DigestCollapse &&
1343  (digest ||
1344  ((actx->idx[i]->content->type == TYPE_MULTIPART) &&
1345  (mutt_str_strcasecmp(actx->idx[i]->content->subtype, "digest") == 0))));
1346  }
1347 }
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
char * subtype
content-type subtype
Definition: body.h:37
unsigned int type
content-type primary type
Definition: body.h:65
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Attachment.
Definition: attach.h:36
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
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 1380 of file recvattach.c.

1381 {
1382  int rindex, curlevel;
1383 
1384  CUR_ATTACH->content->collapsed = !CUR_ATTACH->content->collapsed;
1385  /* When expanding, expand all the children too */
1386  if (CUR_ATTACH->content->collapsed)
1387  return;
1388 
1389  curlevel = CUR_ATTACH->level;
1390  rindex = actx->v2r[menu->current] + 1;
1391 
1392  while ((rindex < actx->idxlen) && (actx->idx[rindex]->level > curlevel))
1393  {
1394  if (C_DigestCollapse && (actx->idx[rindex]->content->type == TYPE_MULTIPART) &&
1395  !mutt_str_strcasecmp(actx->idx[rindex]->content->subtype, "digest"))
1396  {
1397  actx->idx[rindex]->content->collapsed = true;
1398  }
1399  else
1400  {
1401  actx->idx[rindex]->content->collapsed = false;
1402  }
1403  rindex++;
1404  }
1405 }
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
char * subtype
content-type subtype
Definition: body.h:37
unsigned int type
content-type primary type
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 mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
int current
Current entry.
Definition: mutt_menu.h:87
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 1411 of file recvattach.c.

1412 {
1413  char helpstr[1024];
1414  int op = OP_NULL;
1415 
1416  struct Mailbox *m = Context ? Context->mailbox : NULL;
1417 
1418  /* make sure we have parsed this message */
1420 
1422 
1423  struct Message *msg = mx_msg_open(m, e->msgno);
1424  if (!msg)
1425  return;
1426 
1427  struct MuttWindow *dlg =
1430 #ifdef USE_DEBUG_WINDOW
1431  dlg->name = "attach";
1432 #endif
1433  dlg->type = WT_DIALOG;
1434  struct MuttWindow *index =
1437  index->type = WT_INDEX;
1438  struct MuttWindow *ibar = mutt_window_new(
1440  ibar->type = WT_INDEX_BAR;
1441 
1442  if (C_StatusOnTop)
1443  {
1444  mutt_window_add_child(dlg, ibar);
1445  mutt_window_add_child(dlg, index);
1446  }
1447  else
1448  {
1449  mutt_window_add_child(dlg, index);
1450  mutt_window_add_child(dlg, ibar);
1451  }
1452 
1453  dialog_push(dlg);
1454 
1455  struct Menu *menu = mutt_menu_new(MENU_ATTACH);
1456 
1457  menu->pagelen = index->state.rows;
1458  menu->win_index = index;
1459  menu->win_ibar = ibar;
1460 
1461  menu->title = _("Attachments");
1462  menu->make_entry = attach_make_entry;
1463  menu->tag = attach_tag;
1464  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_ATTACH, AttachHelp);
1465  mutt_menu_push_current(menu);
1466 
1467  struct AttachCtx *actx = mutt_actx_new();
1468  actx->email = e;
1469  actx->fp_root = msg->fp;
1470  mutt_update_recvattach_menu(actx, menu, true);
1471 
1472  while (true)
1473  {
1474  if (op == OP_NULL)
1475  op = mutt_menu_loop(menu);
1476  if (!Context)
1477  return;
1478  switch (op)
1479  {
1480  case OP_ATTACH_VIEW_MAILCAP:
1482  MUTT_VA_MAILCAP, e, actx, menu->win_index);
1483  menu->redraw = REDRAW_FULL;
1484  break;
1485 
1486  case OP_ATTACH_VIEW_TEXT:
1488  MUTT_VA_AS_TEXT, e, actx, menu->win_index);
1489  menu->redraw = REDRAW_FULL;
1490  break;
1491 
1492  case OP_DISPLAY_HEADERS:
1493  case OP_VIEW_ATTACH:
1494  op = mutt_attach_display_loop(menu, op, e, actx, true);
1495  menu->redraw = REDRAW_FULL;
1496  continue;
1497 
1498  case OP_ATTACH_COLLAPSE:
1499  if (!CUR_ATTACH->content->parts)
1500  {
1501  mutt_error(_("There are no subparts to show"));
1502  break;
1503  }
1504  attach_collapse(actx, menu);
1505  mutt_update_recvattach_menu(actx, menu, false);
1506  break;
1507 
1508  case OP_FORGET_PASSPHRASE:
1510  break;
1511 
1512  case OP_EXTRACT_KEYS:
1514  {
1515  recvattach_extract_pgp_keys(actx, menu);
1516  menu->redraw = REDRAW_FULL;
1517  }
1518  break;
1519 
1520  case OP_CHECK_TRADITIONAL:
1521  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1523  {
1524  e->security = crypt_query(NULL);
1525  menu->redraw = REDRAW_FULL;
1526  }
1527  break;
1528 
1529  case OP_PRINT:
1531  CUR_ATTACH->content);
1532  break;
1533 
1534  case OP_PIPE:
1536  CUR_ATTACH->content, false);
1537  break;
1538 
1539  case OP_SAVE:
1541  CUR_ATTACH->content, e, menu);
1542 
1543  if (!menu->tagprefix && C_Resolve && (menu->current < menu->max - 1))
1544  menu->current++;
1545 
1547  break;
1548 
1549  case OP_DELETE:
1551 
1552 #ifdef USE_POP
1553  if (m->type == MUTT_POP)
1554  {
1555  mutt_flushinp();
1556  mutt_error(_("Can't delete attachment from POP server"));
1557  break;
1558  }
1559 #endif
1560 
1561 #ifdef USE_NNTP
1562  if (m->type == MUTT_NNTP)
1563  {
1564  mutt_flushinp();
1565  mutt_error(_("Can't delete attachment from news server"));
1566  break;
1567  }
1568 #endif
1569 
1570  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
1571  {
1572  mutt_message(_("Deletion of attachments from encrypted messages is "
1573  "unsupported"));
1574  break;
1575  }
1576  if ((WithCrypto != 0) && (e->security & (SEC_SIGN | SEC_PARTSIGN)))
1577  {
1578  mutt_message(_("Deletion of attachments from signed messages may "
1579  "invalidate the signature"));
1580  }
1581  if (!menu->tagprefix)
1582  {
1583  if (CUR_ATTACH->parent_type == TYPE_MULTIPART)
1584  {
1585  CUR_ATTACH->content->deleted = true;
1586  if (C_Resolve && (menu->current < menu->max - 1))
1587  {
1588  menu->current++;
1589  menu->redraw = REDRAW_MOTION_RESYNC;
1590  }
1591  else
1592  menu->redraw = REDRAW_CURRENT;
1593  }
1594  else
1595  {
1596  mutt_message(
1597  _("Only deletion of multipart attachments is supported"));
1598  }
1599  }
1600  else
1601  {
1602  for (int i = 0; i < menu->max; i++)
1603  {
1604  if (actx->idx[i]->content->tagged)
1605  {
1606  if (actx->idx[i]->parent_type == TYPE_MULTIPART)
1607  {
1608  actx->idx[i]->content->deleted = true;
1609  menu->redraw = REDRAW_INDEX;
1610  }
1611  else
1612  {
1613  mutt_message(
1614  _("Only deletion of multipart attachments is supported"));
1615  }
1616  }
1617  }
1618  }
1619  break;
1620 
1621  case OP_UNDELETE:
1623  if (!menu->tagprefix)
1624  {
1625  CUR_ATTACH->content->deleted = false;
1626  if (C_Resolve && (menu->current < menu->max - 1))
1627  {
1628  menu->current++;
1629  menu->redraw = REDRAW_MOTION_RESYNC;
1630  }
1631  else
1632  menu->redraw = REDRAW_CURRENT;
1633  }
1634  else
1635  {
1636  for (int i = 0; i < menu->max; i++)
1637  {
1638  if (actx->idx[i]->content->tagged)
1639  {
1640  actx->idx[i]->content->deleted = false;
1641  menu->redraw = REDRAW_INDEX;
1642  }
1643  }
1644  }
1645  break;
1646 
1647  case OP_RESEND:
1648  CHECK_ATTACH;
1649  mutt_attach_resend(CUR_ATTACH->fp, actx,
1650  menu->tagprefix ? NULL : CUR_ATTACH->content);
1651  menu->redraw = REDRAW_FULL;
1652  break;
1653 
1654  case OP_BOUNCE_MESSAGE:
1655  CHECK_ATTACH;
1656  mutt_attach_bounce(m, CUR_ATTACH->fp, actx,
1657  menu->tagprefix ? NULL : CUR_ATTACH->content);
1658  menu->redraw = REDRAW_FULL;
1659  break;
1660 
1661  case OP_FORWARD_MESSAGE:
1662  CHECK_ATTACH;
1663  mutt_attach_forward(CUR_ATTACH->fp, e, actx,
1664  menu->tagprefix ? NULL : CUR_ATTACH->content, SEND_NO_FLAGS);
1665  menu->redraw = REDRAW_FULL;
1666  break;
1667 
1668 #ifdef USE_NNTP
1669  case OP_FORWARD_TO_GROUP:
1670  CHECK_ATTACH;
1671  mutt_attach_forward(CUR_ATTACH->fp, e, actx,
1672  menu->tagprefix ? NULL : CUR_ATTACH->content, SEND_NEWS);
1673  menu->redraw = REDRAW_FULL;
1674  break;
1675 
1676  case OP_FOLLOWUP:
1677  CHECK_ATTACH;
1678 
1679  if (!CUR_ATTACH->content->email->env->followup_to ||
1680  (mutt_str_strcasecmp(CUR_ATTACH->content->email->env->followup_to, "poster") != 0) ||
1682  _("Reply by mail as poster prefers?")) != MUTT_YES))
1683  {
1684  mutt_attach_reply(CUR_ATTACH->fp, e, actx,
1685  menu->tagprefix ? NULL : CUR_ATTACH->content,
1686  SEND_NEWS | SEND_REPLY);
1687  menu->redraw = REDRAW_FULL;
1688  break;
1689  }
1690 #endif
1691  /* fallthrough */
1692  case OP_REPLY:
1693  case OP_GROUP_REPLY:
1694  case OP_GROUP_CHAT_REPLY:
1695  case OP_LIST_REPLY:
1696  {
1697  CHECK_ATTACH;
1698 
1699  SendFlags flags = SEND_REPLY;
1700  if (op == OP_GROUP_REPLY)
1701  flags |= SEND_GROUP_REPLY;
1702  else if (op == OP_GROUP_CHAT_REPLY)
1703  flags |= SEND_GROUP_CHAT_REPLY;
1704  else if (op == OP_LIST_REPLY)
1705  flags |= SEND_LIST_REPLY;
1706 
1707  mutt_attach_reply(CUR_ATTACH->fp, e, actx,
1708  menu->tagprefix ? NULL : CUR_ATTACH->content, flags);
1709  menu->redraw = REDRAW_FULL;
1710  break;
1711  }
1712 
1713  case OP_COMPOSE_TO_SENDER:
1714  CHECK_ATTACH;
1715  mutt_attach_mail_sender(CUR_ATTACH->fp, e, actx,
1716  menu->tagprefix ? NULL : CUR_ATTACH->content);
1717  menu->redraw = REDRAW_FULL;
1718  break;
1719 
1720  case OP_EDIT_TYPE:
1721  recvattach_edit_content_type(actx, menu, e);
1722  menu->redraw |= REDRAW_INDEX;
1723  break;
1724 
1725  case OP_EXIT:
1726  mx_msg_close(m, &msg);
1727 
1728  e->attach_del = false;
1729  for (int i = 0; i < actx->idxlen; i++)
1730  {
1731  if (actx->idx[i]->content && actx->idx[i]->content->deleted)
1732  {
1733  e->attach_del = true;
1734  break;
1735  }
1736  }
1737  if (e->attach_del)
1738  e->changed = true;
1739 
1740  mutt_actx_free(&actx);
1741 
1742  mutt_menu_pop_current(menu);
1743  mutt_menu_free(&menu);
1744  dialog_pop();
1745  mutt_window_free(&dlg);
1746  return;
1747  }
1748 
1749  op = OP_NULL;
1750  }
1751 
1752  /* not reached */
1753 }
The "current" mailbox.
Definition: context.h:37
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: globals.h:252
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
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:82
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:438
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
Dialog (nested Windows) displayed to the user.
Definition: mutt_window.h:70
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
#define mutt_message(...)
Definition: logging.h:83
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:628
#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:191
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:897
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:605
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:49
#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:88
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:52
uint16_t SendFlags
Flags for ci_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:74
int attach_tag(struct Menu *menu, int sel, int act)
Tag an attachment - Implements Menu::tag()
Definition: recvattach.c:450
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:74
#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:904
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1171
struct Mailbox * mailbox
Definition: context.h:51
struct MuttWindow * win_ibar
Definition: mutt_menu.h:96
const char * title
Title of this menu.
Definition: mutt_menu.h:84
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:85
#define REDRAW_MOTION_RESYNC
Redraw any changing the menu selection.
Definition: mutt_menu.h:44
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:93
#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:72
struct MuttWindow * mutt_window_new(enum MuttWindowOrientation orient, enum MuttWindowSize size, int rows, int cols)
Create a new Window.
Definition: mutt_window.c:56
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:1115
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:1145
#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:57
bool tagprefix
Definition: mutt_menu.h:93
static void recvattach_extract_pgp_keys(struct AttachCtx *actx, struct Menu *menu)
Extract PGP keys from attachments.
Definition: recvattach.c:1069
WHERE bool C_Resolve
Config: Move to the next email whenever a command modifies an email.
Definition: globals.h:243
static void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1355
#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:139
int pagelen
Number of entries per screen.
Definition: mutt_menu.h:92
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:1093
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:88
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:473
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
Definition: recvattach.c:1026
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
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:1380
#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:42
struct Body * content
Attachment.
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:84
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
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:651
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:1074
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:579
#define SEND_GROUP_CHAT_REPLY
Reply to all recipients preserving To/Cc.
Definition: send.h:101
int current
Current entry.
Definition: mutt_menu.h:87
struct MuttWindow * win_index
Definition: mutt_menu.h:95
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:116
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:75
enum WindowType type
Window type, e.g. WT_SIDEBAR.
Definition: mutt_window.h:103
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:700
void(* make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:120
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:1123
#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:45
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.