NeoMutt  2019-12-07-60-g0cfa53
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/mutt.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 "filter.h"
#include "format_flags.h"
#include "globals.h"
#include "handler.h"
#include "hdrline.h"
#include "hook.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 "ncrypt/ncrypt.h"
#include "opcodes.h"
#include "options.h"
#include "recvcmd.h"
#include "send.h"
#include "sendlib.h"
#include "state.h"
#include <libintl.h>
+ Include dependency graph for recvattach.c:

Go to the source code of this file.

Macros

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

Functions

static void mutt_update_recvattach_menu (struct AttachCtx *actx, struct Menu *menu, bool init)
 Update the Attachment Menu. More...
 
static void mutt_update_v2r (struct AttachCtx *actx)
 Update the virtual list of attachments. More...
 
void mutt_update_tree (struct AttachCtx *actx)
 Refresh the list of attachments. More...
 
const char * attach_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, 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::menu_make_entry() More...
 
int attach_tag (struct Menu *menu, int sel, int act)
 Tag an attachment - Implements Menu::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:36
static const char * Mailbox_is_read_only
Definition: recvattach.c:79
#define _(a)
Definition: message.h:28
struct Mailbox * mailbox
Definition: context.h:50
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:118

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

1352 {
1353  if (init)
1354  {
1355  mutt_generate_recvattach_list(actx, actx->email, actx->email->content,
1356  actx->fp_root, -1, 0, 0);
1357  mutt_attach_init(actx);
1358  menu->data = actx;
1359  }
1360 
1361  mutt_update_tree(actx);
1362 
1363  menu->max = actx->vcount;
1364 
1365  if (menu->current >= menu->max)
1366  menu->current = menu->max - 1;
1367  menu_check_recenter(menu);
1368  menu->redraw |= REDRAW_INDEX;
1369 }
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:1219
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:1326
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:615
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  {
328  const char dispchar[] = { 'I', 'A', 'F', '-' };
329  char ch;
330 
331  if (aptr->content->disposition < sizeof(dispchar))
332  ch = dispchar[aptr->content->disposition];
333  else
334  {
335  mutt_debug(LL_DEBUG1, "ERROR: invalid content-disposition %d\n",
336  aptr->content->disposition);
337  ch = '!';
338  }
339  snprintf(buf, buflen, "%c", ch);
340  }
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  {
355  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
356  snprintf(buf, buflen, fmt, aptr->num + 1);
357  }
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  mutt_expando_format(buf, buflen, col, cols, if_str, attach_format_str, data,
425  else if (flags & MUTT_FORMAT_OPTIONAL)
426  mutt_expando_format(buf, buflen, col, cols, else_str, attach_format_str,
427  data, MUTT_FORMAT_NO_FLAGS);
428  return src;
429 }
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:877
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
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:703
#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:1778
char * mutt_body_get_charset(struct Body *b, char *buf, size_t buflen)
Get a body&#39;s character set.
Definition: sendlib.c:1461
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:452
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:1244
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:1256
+ 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::menu_make_entry()

Definition at line 434 of file recvattach.c.

435 {
436  struct AttachCtx *actx = menu->data;
437 
438  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
440  (unsigned long) (actx->idx[actx->v2r[line]]), MUTT_FORMAT_ARROWCURSOR);
441 }
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:877
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_AttachFormat
Config: printf-like format string for the attachment menu.
Definition: globals.h:99
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:56
const char * line
Definition: common.c:36
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:91
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
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::menu_tag()

Definition at line 446 of file recvattach.c.

447 {
448  struct AttachCtx *actx = menu->data;
449  struct Body *cur = actx->idx[actx->v2r[sel]]->content;
450  bool ot = cur->tagged;
451 
452  cur->tagged = ((act >= 0) ? act : !cur->tagged);
453  return cur->tagged - ot;
454 }
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 460 of file recvattach.c.

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

486 {
487  return (body->email && (body->encoding != ENC_BASE64) &&
488  (body->encoding != ENC_QUOTED_PRINTABLE) &&
489  mutt_is_message_type(body->type, body->subtype));
490 }
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 501 of file recvattach.c.

502 {
503  char *prompt = NULL;
504  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
505  int rc = -1;
506 
507  struct Buffer *buf = mutt_buffer_pool_get();
508  struct Buffer *tfile = mutt_buffer_pool_get();
509 
510  if (body->filename)
511  {
512  if (directory && *directory)
513  {
514  mutt_buffer_concat_path(buf, *directory, mutt_path_basename(body->filename));
515  }
516  else
517  mutt_buffer_strcpy(buf, body->filename);
518  }
519  else if (has_a_message(body))
520  {
521  mutt_default_save(buf->data, buf->dsize, body->email);
523  }
524 
525  prepend_savedir(buf);
526 
527  prompt = _("Save to file: ");
528  while (prompt)
529  {
530  if ((mutt_buffer_get_field(prompt, buf, MUTT_FILE | MUTT_CLEAR) != 0) ||
532  {
533  goto cleanup;
534  }
535 
536  prompt = NULL;
538 
539  bool is_message = (fp && has_a_message(body));
540 
541  if (is_message)
542  {
543  struct stat st;
544 
545  /* check to make sure that this file is really the one the user wants */
546  rc = mutt_save_confirm(mutt_b2s(buf), &st);
547  if (rc == 1)
548  {
549  prompt = _("Save to file: ");
550  continue;
551  }
552  else if (rc == -1)
553  goto cleanup;
554  mutt_buffer_copy(tfile, buf);
555  }
556  else
557  {
558  rc = mutt_check_overwrite(body->filename, mutt_b2s(buf), tfile, &opt, directory);
559  if (rc == -1)
560  goto cleanup;
561  else if (rc == 1)
562  {
563  prompt = _("Save to file: ");
564  continue;
565  }
566  }
567 
568  mutt_message(_("Saving..."));
569  if (mutt_save_attachment(fp, body, mutt_b2s(tfile), opt,
570  (e || !is_message) ? e : body->email) == 0)
571  {
572  mutt_message(_("Attachment saved"));
573  rc = 0;
574  goto cleanup;
575  }
576  else
577  {
578  prompt = _("Save to file: ");
579  continue;
580  }
581  }
582 
583 cleanup:
585  mutt_buffer_pool_release(&tfile);
586  return rc;
587 }
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:485
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:68
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
#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:460
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:796
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:656
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1448
size_t dsize
Length of data.
Definition: buffer.h:37
const char * mutt_path_basename(const char *f)
Find the last component for a pathname.
Definition: path.c:307
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:64
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:725
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:85
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:342
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 597 of file recvattach.c.

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

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

764 {
765  char tfile[PATH_MAX];
766 
767  if (filter)
768  {
769  char warning[PATH_MAX + 256];
770  snprintf(warning, sizeof(warning),
771  _("WARNING! You are about to overwrite %s, continue?"), body->filename);
772  if (mutt_yesorno(warning, MUTT_NO) != MUTT_YES)
773  {
775  return;
776  }
777  mutt_mktemp(tfile, sizeof(tfile));
778  }
779  else
780  tfile[0] = '\0';
781 
782  if (mutt_pipe_attachment(fp, body, command, tfile))
783  {
784  if (filter)
785  {
786  mutt_file_unlink(body->filename);
787  mutt_file_rename(tfile, body->filename);
788  mutt_update_encoding(body);
789  mutt_message(_("Attachment filtered"));
790  }
791  }
792  else
793  {
794  if (filter && tfile[0])
795  mutt_file_unlink(tfile);
796  }
797 }
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:1338
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:194
#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:376
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1485
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:113
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:75
#define PATH_MAX
Definition: mutt.h:50
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:47
int mutt_pipe_attachment(FILE *fp, struct Body *b, const char *path, char *outfile)
Pipe an attachment to a command.
Definition: mutt_attach.c:679
+ 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 805 of file recvattach.c.

806 {
807  if (!state || !state->fp_out)
808  return;
809 
810  if (fp)
811  {
812  state->fp_in = fp;
813  mutt_decode_attachment(b, state);
814  if (C_AttachSep)
815  state_puts(state, C_AttachSep);
816  }
817  else
818  {
819  FILE *fp_in = fopen(b->filename, "r");
820  if (!fp_in)
821  {
822  mutt_perror("fopen");
823  return;
824  }
825  mutt_file_copy_stream(fp_in, state->fp_out);
826  mutt_file_fclose(&fp_in);
827  if (C_AttachSep)
828  state_puts(state, C_AttachSep);
829  }
830 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1795
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:152
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:270
+ 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 842 of file recvattach.c.

844 {
845  for (int i = 0; !tag || (i < actx->idxlen); i++)
846  {
847  if (tag)
848  {
849  fp = actx->idx[i]->fp;
850  top = actx->idx[i]->content;
851  }
852  if (!tag || top->tagged)
853  {
854  if (!filter && !C_AttachSplit)
855  pipe_attachment(fp, top, state);
856  else
857  query_pipe_attachment(command, fp, top, filter);
858  }
859  if (!tag)
860  break;
861  }
862 }
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:763
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:805
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 872 of file recvattach.c.

874 {
875  struct State state = { 0 };
876  char buf[PATH_MAX];
877 
878  if (fp)
879  filter = false; /* sanity check: we can't filter in the recv case yet */
880 
881  buf[0] = '\0';
882  /* perform charset conversion on text attachments when piping */
883  state.flags = MUTT_CHARCONV;
884 
885  if ((mutt_get_field((filter ? _("Filter through: ") : _("Pipe to: ")), buf,
886  sizeof(buf), MUTT_CMD) != 0) ||
887  (buf[0] == '\0'))
888  {
889  return;
890  }
891 
892  mutt_expand_path(buf, sizeof(buf));
893 
894  if (!filter && !C_AttachSplit)
895  {
896  mutt_endwin();
897  pid_t pid = mutt_create_filter(buf, &state.fp_out, NULL, NULL);
898  pipe_attachment_list(buf, actx, fp, tag, top, filter, &state);
899  mutt_file_fclose(&state.fp_out);
900  if ((mutt_wait_filter(pid) != 0) || C_WaitKey)
902  }
903  else
904  pipe_attachment_list(buf, actx, fp, tag, top, filter, &state);
905 }
pid_t mutt_create_filter(const char *s, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:209
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:842
#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:92
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:152
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:66
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: globals.h:260
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:545
#define PATH_MAX
Definition: mutt.h:50
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:578
Keep track when processing files.
Definition: state.h:44
int mutt_wait_filter(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:220
+ 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 914 of file recvattach.c.

915 {
916  char type[256];
917 
918  for (int i = 0; !tag || (i < actx->idxlen); i++)
919  {
920  if (tag)
921  top = actx->idx[i]->content;
922  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
923  if (!tag || top->tagged)
924  {
925  if (!mailcap_lookup(top, type, sizeof(type), NULL, MUTT_MC_PRINT))
926  {
927  if ((mutt_str_strcasecmp("text/plain", top->subtype) != 0) &&
928  (mutt_str_strcasecmp("application/postscript", top->subtype) != 0))
929  {
930  if (!mutt_can_decode(top))
931  {
932  /* L10N: s gets replaced by a MIME type, e.g. "text/plain" or
933  application/octet-stream. */
934  mutt_error(_("I don't know how to print %s attachments"), type);
935  return false;
936  }
937  }
938  }
939  }
940  if (!tag)
941  break;
942  }
943  return true;
944 }
#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:1754
#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:628
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 954 of file recvattach.c.

956 {
957  char type[256];
958 
959  for (int i = 0; !tag || (i < actx->idxlen); i++)
960  {
961  if (tag)
962  {
963  fp = actx->idx[i]->fp;
964  top = actx->idx[i]->content;
965  }
966  if (!tag || top->tagged)
967  {
968  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
969  if (!C_AttachSplit && !mailcap_lookup(top, type, sizeof(type), NULL, MUTT_MC_PRINT))
970  {
971  if ((mutt_str_strcasecmp("text/plain", top->subtype) == 0) ||
972  (mutt_str_strcasecmp("application/postscript", top->subtype) == 0))
973  {
974  pipe_attachment(fp, top, state);
975  }
976  else if (mutt_can_decode(top))
977  {
978  /* decode and print */
979 
980  FILE *fp_in = NULL;
981  struct Buffer *newfile = mutt_buffer_pool_get();
982 
983  mutt_buffer_mktemp(newfile);
984  if (mutt_decode_save_attachment(fp, top, mutt_b2s(newfile),
986  {
987  if (!state->fp_out)
988  {
989  mutt_error(
990  "BUG in print_attachment_list(). Please report this. ");
991  return;
992  }
993 
994  fp_in = fopen(mutt_b2s(newfile), "r");
995  if (fp_in)
996  {
997  mutt_file_copy_stream(fp_in, state->fp_out);
998  mutt_file_fclose(&fp_in);
999  if (C_AttachSep)
1000  state_puts(state, C_AttachSep);
1001  }
1002  }
1003  mutt_file_unlink(mutt_b2s(newfile));
1004  mutt_buffer_pool_release(&newfile);
1005  }
1006  }
1007  else
1008  mutt_print_attachment(fp, top);
1009  }
1010  if (!tag)
1011  break;
1012  }
1013 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:73
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:78
#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:194
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:152
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:927
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1754
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:805
#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:270
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:628
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:1026
+ 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 1022 of file recvattach.c.

1023 {
1024  char prompt[128];
1025  struct State state = { 0 };
1026  int tagmsgcount = 0;
1027 
1028  if (tag)
1029  for (int i = 0; i < actx->idxlen; i++)
1030  if (actx->idx[i]->content->tagged)
1031  tagmsgcount++;
1032 
1033  snprintf(prompt, sizeof(prompt),
1034  /* L10N: Although we now the precise number of tagged messages, we
1035  do not show it to the user. So feel free to use a "generic
1036  plural" as plural translation if your language has one. */
1037  tag ? ngettext("Print tagged attachment?", "Print %d tagged attachments?", tagmsgcount) :
1038  _("Print attachment?"),
1039  tagmsgcount);
1040  if (query_quadoption(C_Print, prompt) != MUTT_YES)
1041  return;
1042 
1043  if (C_AttachSplit)
1044  {
1045  print_attachment_list(actx, fp, tag, top, &state);
1046  }
1047  else
1048  {
1049  if (!can_print(actx, top, tag))
1050  return;
1051  mutt_endwin();
1052  pid_t pid = mutt_create_filter(NONULL(C_PrintCommand), &state.fp_out, NULL, NULL);
1053  print_attachment_list(actx, fp, tag, top, &state);
1054  mutt_file_fclose(&state.fp_out);
1055  if ((mutt_wait_filter(pid) != 0) || C_WaitKey)
1057  }
1058 }
pid_t mutt_create_filter(const char *s, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:209
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:73
#define NONULL(x)
Definition: string2.h:37
WHERE unsigned char C_Print
Config: Confirm before printing a message.
Definition: globals.h:183
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3360
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:954
#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:152
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:260
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:545
static bool can_print(struct AttachCtx *actx, struct Body *top, bool tag)
Do we know how to print this attachment type?
Definition: recvattach.c:914
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:578
struct Body * content
Attachment.
Definition: attach.h:36
WHERE char * C_PrintCommand
Config: External command to print a message.
Definition: globals.h:136
Keep track when processing files.
Definition: state.h:44
int mutt_wait_filter(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:220
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 1065 of file recvattach.c.

1066 {
1067  if (!menu->tagprefix)
1069  else
1070  {
1071  for (int i = 0; i < actx->idxlen; i++)
1072  {
1073  if (actx->idx[i]->content->tagged)
1074  {
1075  crypt_pgp_extract_key_from_attachment(actx->idx[i]->fp, actx->idx[i]->content);
1076  }
1077  }
1078  }
1079 }
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:389
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 1089 of file recvattach.c.

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

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

1143 {
1144  do
1145  {
1146  switch (op)
1147  {
1148  case OP_DISPLAY_HEADERS:
1149  bool_str_toggle(NeoMutt->sub, "weed", NULL);
1150  /* fallthrough */
1151 
1152  case OP_VIEW_ATTACH:
1153  op = mutt_view_attachment(CUR_ATTACH->fp, CUR_ATTACH->content,
1154  MUTT_VA_REGULAR, e, actx, menu->win_index);
1155  break;
1156 
1157  case OP_NEXT_ENTRY:
1158  case OP_MAIN_NEXT_UNDELETED: /* hack */
1159  if (menu->current < menu->max - 1)
1160  {
1161  menu->current++;
1162  op = OP_VIEW_ATTACH;
1163  }
1164  else
1165  op = OP_NULL;
1166  break;
1167  case OP_PREV_ENTRY:
1168  case OP_MAIN_PREV_UNDELETED: /* hack */
1169  if (menu->current > 0)
1170  {
1171  menu->current--;
1172  op = OP_VIEW_ATTACH;
1173  }
1174  else
1175  op = OP_NULL;
1176  break;
1177  case OP_EDIT_TYPE:
1178  /* when we edit the content-type, we should redisplay the attachment
1179  * immediately */
1180  mutt_edit_content_type(e, CUR_ATTACH->content, CUR_ATTACH->fp);
1181  if (recv)
1182  recvattach_edit_content_type(actx, menu, e);
1183  else
1184  mutt_edit_content_type(e, CUR_ATTACH->content, CUR_ATTACH->fp);
1185 
1186  menu->redraw |= REDRAW_INDEX;
1187  op = OP_VIEW_ATTACH;
1188  break;
1189  /* functions which are passed through from the pager */
1190  case OP_CHECK_TRADITIONAL:
1192  {
1193  op = OP_NULL;
1194  break;
1195  }
1196  /* fallthrough */
1197  case OP_ATTACH_COLLAPSE:
1198  if (recv)
1199  return op;
1200  /* fallthrough */
1201  default:
1202  op = OP_NULL;
1203  }
1204  } while (op != OP_NULL);
1205 
1206  return op;
1207 }
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: ncrypt.h:136
View using default method.
Definition: mutt_attach.h:42
Container for Accounts, Notifications.
Definition: neomutt.h:35
#define CUR_ATTACH
Definition: recvattach.c:89
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:1111
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/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
int max
Number of entries in the menu.
Definition: mutt_menu.h:88
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
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:1237
int current
Current entry.
Definition: mutt_menu.h:87
struct MuttWindow * win_index
Definition: mutt_menu.h:95
#define WithCrypto
Definition: ncrypt.h:160
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:385
+ 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 1219 of file recvattach.c.

1222 {
1223  struct Body *m = NULL;
1224  struct Body *new_body = NULL;
1225  FILE *fp_new = NULL;
1227  int need_secured, secured;
1228 
1229  for (m = parts; m; m = m->next)
1230  {
1231  need_secured = 0;
1232  secured = 0;
1233 
1234  if (((WithCrypto & APPLICATION_SMIME) != 0) && (type = mutt_is_application_smime(m)))
1235  {
1236  need_secured = 1;
1237 
1238  if (type & SEC_ENCRYPT)
1239  {
1240  if (!crypt_valid_passphrase(APPLICATION_SMIME))
1241  goto decrypt_failed;
1242 
1243  if (e->env)
1245  }
1246 
1247  secured = !crypt_smime_decrypt_mime(fp, &fp_new, m, &new_body);
1248  /* If the decrypt/verify-opaque doesn't generate mime output, an empty
1249  * text/plain type will still be returned by mutt_read_mime_header().
1250  * We can't distinguish an actual part from a failure, so only use a
1251  * text/plain that results from a single top-level part. */
1252  if (secured && (new_body->type == TYPE_TEXT) &&
1253  (mutt_str_strcasecmp("plain", new_body->subtype) == 0) &&
1254  ((parts != m) || m->next))
1255  {
1256  mutt_body_free(&new_body);
1257  mutt_file_fclose(&fp_new);
1258  goto decrypt_failed;
1259  }
1260 
1261  if (secured && (type & SEC_ENCRYPT))
1262  e->security |= SMIME_ENCRYPT;
1263  }
1264 
1265  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1267  {
1268  need_secured = 1;
1269 
1270  if (!crypt_valid_passphrase(APPLICATION_PGP))
1271  goto decrypt_failed;
1272 
1273  secured = !crypt_pgp_decrypt_mime(fp, &fp_new, m, &new_body);
1274 
1275  if (secured)
1276  e->security |= PGP_ENCRYPT;
1277  }
1278 
1279  if (need_secured && secured)
1280  {
1281  mutt_actx_add_fp(actx, fp_new);
1282  mutt_actx_add_body(actx, new_body);
1283  mutt_generate_recvattach_list(actx, e, new_body, fp_new, parent_type, level, 1);
1284  continue;
1285  }
1286 
1287  decrypt_failed:
1288  /* Fall through and show the original parts if decryption fails */
1289  if (need_secured && !secured)
1290  mutt_error(_("Can't decrypt encrypted message"));
1291 
1292  /* Strip out the top level multipart */
1293  if ((m->type == TYPE_MULTIPART) && m->parts && !need_secured &&
1294  ((parent_type == -1) && mutt_str_strcasecmp("alternative", m->subtype)))
1295  {
1296  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level, decrypted);
1297  }
1298  else
1299  {
1300  struct AttachPtr *ap = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1301  mutt_actx_add_attach(actx, ap);
1302 
1303  ap->content = m;
1304  ap->fp = fp;
1305  m->aptr = ap;
1306  ap->parent_type = parent_type;
1307  ap->level = level;
1308  ap->decrypted = decrypted;
1309 
1310  if (m->type == TYPE_MULTIPART)
1311  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level + 1, decrypted);
1312  else if (mutt_is_message_type(m->type, m->subtype))
1313  {
1314  mutt_generate_recvattach_list(actx, m->email, m->parts, fp, m->type,
1315  level + 1, decrypted);
1316  e->security |= m->email->security;
1317  }
1318  }
1319  }
1320 }
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
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:1219
#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
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
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:145
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:451
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
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
bool decrypted
Not part of message as stored in the email->content.
Definition: attach.h:43
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:451
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:512
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:427
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:616
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
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:203
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Attachment.
Definition: attach.h:36
#define SMIME_ENCRYPT
Definition: ncrypt.h:146
#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:628
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: ncrypt.h:120
struct Email * email
header information for message/rfc822
Definition: body.h:55
#define WithCrypto
Definition: ncrypt.h:160
int level
Nesting depth of attachment.
Definition: attach.h:40
#define PGP_ENCRYPT
Definition: ncrypt.h:140
void mutt_actx_add_body(struct AttachCtx *actx, struct Body *new_body)
Add an email box to an Attachment Context.
Definition: attach.c:83
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 1326 of file recvattach.c.

1327 {
1328  /* Collapse the attachments if '$digest_collapse' is set AND if...
1329  * the outer container is of type 'multipart/digest' */
1330  bool digest = (mutt_str_strcasecmp(actx->email->content->subtype, "digest") == 0);
1331 
1332  for (int i = 0; i < actx->idxlen; i++)
1333  {
1334  actx->idx[i]->content->tagged = false;
1335 
1336  /* OR an inner container is of type 'multipart/digest' */
1337  actx->idx[i]->content->collapsed =
1338  (C_DigestCollapse &&
1339  (digest ||
1340  ((actx->idx[i]->content->type == TYPE_MULTIPART) &&
1341  (mutt_str_strcasecmp(actx->idx[i]->content->subtype, "digest") == 0))));
1342  }
1343 }
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:628
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 1376 of file recvattach.c.

1377 {
1378  int rindex, curlevel;
1379 
1380  CUR_ATTACH->content->collapsed = !CUR_ATTACH->content->collapsed;
1381  /* When expanding, expand all the children too */
1382  if (CUR_ATTACH->content->collapsed)
1383  return;
1384 
1385  curlevel = CUR_ATTACH->level;
1386  rindex = actx->v2r[menu->current] + 1;
1387 
1388  while ((rindex < actx->idxlen) && (actx->idx[rindex]->level > curlevel))
1389  {
1390  if (C_DigestCollapse && (actx->idx[rindex]->content->type == TYPE_MULTIPART) &&
1391  !mutt_str_strcasecmp(actx->idx[rindex]->content->subtype, "digest"))
1392  {
1393  actx->idx[rindex]->content->collapsed = true;
1394  }
1395  else
1396  {
1397  actx->idx[rindex]->content->collapsed = false;
1398  }
1399  rindex++;
1400  }
1401 }
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:628
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 1407 of file recvattach.c.

1408 {
1409  char helpstr[1024];
1410  int op = OP_NULL;
1411 
1412  struct Mailbox *m = Context ? Context->mailbox : NULL;
1413 
1414  /* make sure we have parsed this message */
1416 
1418 
1419  struct Message *msg = mx_msg_open(m, e->msgno);
1420  if (!msg)
1421  return;
1422 
1423  struct MuttWindow *dlg =
1426  dlg->type = WT_DIALOG;
1427  struct MuttWindow *index =
1430  index->type = WT_INDEX;
1431  struct MuttWindow *ibar = mutt_window_new(
1433  ibar->type = WT_INDEX_BAR;
1434 
1435  if (C_StatusOnTop)
1436  {
1437  mutt_window_add_child(dlg, ibar);
1438  mutt_window_add_child(dlg, index);
1439  }
1440  else
1441  {
1442  mutt_window_add_child(dlg, index);
1443  mutt_window_add_child(dlg, ibar);
1444  }
1445 
1446  dialog_push(dlg);
1447 
1448  struct Menu *menu = mutt_menu_new(MENU_ATTACH);
1449 
1450  menu->pagelen = index->state.rows;
1451  menu->win_index = index;
1452  menu->win_ibar = ibar;
1453 
1454  menu->title = _("Attachments");
1456  menu->menu_tag = attach_tag;
1457  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_ATTACH, AttachHelp);
1458  mutt_menu_push_current(menu);
1459 
1460  struct AttachCtx *actx = mutt_actx_new();
1461  actx->email = e;
1462  actx->fp_root = msg->fp;
1463  mutt_update_recvattach_menu(actx, menu, true);
1464 
1465  while (true)
1466  {
1467  if (op == OP_NULL)
1468  op = mutt_menu_loop(menu);
1469  if (!Context)
1470  return;
1471  switch (op)
1472  {
1473  case OP_ATTACH_VIEW_MAILCAP:
1475  MUTT_VA_MAILCAP, e, actx, menu->win_index);
1476  menu->redraw = REDRAW_FULL;
1477  break;
1478 
1479  case OP_ATTACH_VIEW_TEXT:
1481  MUTT_VA_AS_TEXT, e, actx, menu->win_index);
1482  menu->redraw = REDRAW_FULL;
1483  break;
1484 
1485  case OP_DISPLAY_HEADERS:
1486  case OP_VIEW_ATTACH:
1487  op = mutt_attach_display_loop(menu, op, e, actx, true);
1488  menu->redraw = REDRAW_FULL;
1489  continue;
1490 
1491  case OP_ATTACH_COLLAPSE:
1492  if (!CUR_ATTACH->content->parts)
1493  {
1494  mutt_error(_("There are no subparts to show"));
1495  break;
1496  }
1497  attach_collapse(actx, menu);
1498  mutt_update_recvattach_menu(actx, menu, false);
1499  break;
1500 
1501  case OP_FORGET_PASSPHRASE:
1503  break;
1504 
1505  case OP_EXTRACT_KEYS:
1507  {
1508  recvattach_extract_pgp_keys(actx, menu);
1509  menu->redraw = REDRAW_FULL;
1510  }
1511  break;
1512 
1513  case OP_CHECK_TRADITIONAL:
1514  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1516  {
1517  e->security = crypt_query(NULL);
1518  menu->redraw = REDRAW_FULL;
1519  }
1520  break;
1521 
1522  case OP_PRINT:
1524  CUR_ATTACH->content);
1525  break;
1526 
1527  case OP_PIPE:
1529  CUR_ATTACH->content, false);
1530  break;
1531 
1532  case OP_SAVE:
1534  CUR_ATTACH->content, e, menu);
1535 
1536  if (!menu->tagprefix && C_Resolve && (menu->current < menu->max - 1))
1537  menu->current++;
1538 
1540  break;
1541 
1542  case OP_DELETE:
1544 
1545 #ifdef USE_POP
1546  if (m->magic == MUTT_POP)
1547  {
1548  mutt_flushinp();
1549  mutt_error(_("Can't delete attachment from POP server"));
1550  break;
1551  }
1552 #endif
1553 
1554 #ifdef USE_NNTP
1555  if (m->magic == MUTT_NNTP)
1556  {
1557  mutt_flushinp();
1558  mutt_error(_("Can't delete attachment from news server"));
1559  break;
1560  }
1561 #endif
1562 
1563  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
1564  {
1565  mutt_message(_("Deletion of attachments from encrypted messages is "
1566  "unsupported"));
1567  break;
1568  }
1569  if ((WithCrypto != 0) && (e->security & (SEC_SIGN | SEC_PARTSIGN)))
1570  {
1571  mutt_message(_("Deletion of attachments from signed messages may "
1572  "invalidate the signature"));
1573  }
1574  if (!menu->tagprefix)
1575  {
1576  if (CUR_ATTACH->parent_type == TYPE_MULTIPART)
1577  {
1578  CUR_ATTACH->content->deleted = true;
1579  if (C_Resolve && (menu->current < menu->max - 1))
1580  {
1581  menu->current++;
1582  menu->redraw = REDRAW_MOTION_RESYNC;
1583  }
1584  else
1585  menu->redraw = REDRAW_CURRENT;
1586  }
1587  else
1588  {
1589  mutt_message(
1590  _("Only deletion of multipart attachments is supported"));
1591  }
1592  }
1593  else
1594  {
1595  for (int i = 0; i < menu->max; i++)
1596  {
1597  if (actx->idx[i]->content->tagged)
1598  {
1599  if (actx->idx[i]->parent_type == TYPE_MULTIPART)
1600  {
1601  actx->idx[i]->content->deleted = true;
1602  menu->redraw = REDRAW_INDEX;
1603  }
1604  else
1605  {
1606  mutt_message(
1607  _("Only deletion of multipart attachments is supported"));
1608  }
1609  }
1610  }
1611  }
1612  break;
1613 
1614  case OP_UNDELETE:
1616  if (!menu->tagprefix)
1617  {
1618  CUR_ATTACH->content->deleted = false;
1619  if (C_Resolve && (menu->current < menu->max - 1))
1620  {
1621  menu->current++;
1622  menu->redraw = REDRAW_MOTION_RESYNC;
1623  }
1624  else
1625  menu->redraw = REDRAW_CURRENT;
1626  }
1627  else
1628  {
1629  for (int i = 0; i < menu->max; i++)
1630  {
1631  if (actx->idx[i]->content->tagged)
1632  {
1633  actx->idx[i]->content->deleted = false;
1634  menu->redraw = REDRAW_INDEX;
1635  }
1636  }
1637  }
1638  break;
1639 
1640  case OP_RESEND:
1641  CHECK_ATTACH;
1642  mutt_attach_resend(CUR_ATTACH->fp, actx,
1643  menu->tagprefix ? NULL : CUR_ATTACH->content);
1644  menu->redraw = REDRAW_FULL;
1645  break;
1646 
1647  case OP_BOUNCE_MESSAGE:
1648  CHECK_ATTACH;
1649  mutt_attach_bounce(m, CUR_ATTACH->fp, actx,
1650  menu->tagprefix ? NULL : CUR_ATTACH->content);
1651  menu->redraw = REDRAW_FULL;
1652  break;
1653 
1654  case OP_FORWARD_MESSAGE:
1655  CHECK_ATTACH;
1656  mutt_attach_forward(CUR_ATTACH->fp, e, actx,
1657  menu->tagprefix ? NULL : CUR_ATTACH->content, SEND_NO_FLAGS);
1658  menu->redraw = REDRAW_FULL;
1659  break;
1660 
1661 #ifdef USE_NNTP
1662  case OP_FORWARD_TO_GROUP:
1663  CHECK_ATTACH;
1664  mutt_attach_forward(CUR_ATTACH->fp, e, actx,
1665  menu->tagprefix ? NULL : CUR_ATTACH->content, SEND_NEWS);
1666  menu->redraw = REDRAW_FULL;
1667  break;
1668 
1669  case OP_FOLLOWUP:
1670  CHECK_ATTACH;
1671 
1672  if (!CUR_ATTACH->content->email->env->followup_to ||
1673  (mutt_str_strcasecmp(CUR_ATTACH->content->email->env->followup_to, "poster") != 0) ||
1675  _("Reply by mail as poster prefers?")) != MUTT_YES))
1676  {
1677  mutt_attach_reply(CUR_ATTACH->fp, e, actx,
1678  menu->tagprefix ? NULL : CUR_ATTACH->content,
1679  SEND_NEWS | SEND_REPLY);
1680  menu->redraw = REDRAW_FULL;
1681  break;
1682  }
1683 #endif
1684  /* fallthrough */
1685  case OP_REPLY:
1686  case OP_GROUP_REPLY:
1687  case OP_GROUP_CHAT_REPLY:
1688  case OP_LIST_REPLY:
1689  {
1690  CHECK_ATTACH;
1691 
1692  SendFlags flags = SEND_REPLY;
1693  if (op == OP_GROUP_REPLY)
1694  flags |= SEND_GROUP_REPLY;
1695  else if (op == OP_GROUP_CHAT_REPLY)
1696  flags |= SEND_GROUP_CHAT_REPLY;
1697  else if (op == OP_LIST_REPLY)
1698  flags |= SEND_LIST_REPLY;
1699 
1700  mutt_attach_reply(CUR_ATTACH->fp, e, actx,
1701  menu->tagprefix ? NULL : CUR_ATTACH->content, flags);
1702  menu->redraw = REDRAW_FULL;
1703  break;
1704  }
1705 
1706  case OP_COMPOSE_TO_SENDER:
1707  CHECK_ATTACH;
1708  mutt_attach_mail_sender(CUR_ATTACH->fp, e, actx,
1709  menu->tagprefix ? NULL : CUR_ATTACH->content);
1710  menu->redraw = REDRAW_FULL;
1711  break;
1712 
1713  case OP_EDIT_TYPE:
1714  recvattach_edit_content_type(actx, menu, e);
1715  menu->redraw |= REDRAW_INDEX;
1716  break;
1717 
1718  case OP_EXIT:
1719  mx_msg_close(m, &msg);
1720 
1721  e->attach_del = false;
1722  for (int i = 0; i < actx->idxlen; i++)
1723  {
1724  if (actx->idx[i]->content && actx->idx[i]->content->deleted)
1725  {
1726  e->attach_del = true;
1727  break;
1728  }
1729  }
1730  if (e->attach_del)
1731  e->changed = true;
1732 
1733  mutt_actx_free(&actx);
1734 
1735  mutt_menu_pop_current(menu);
1736  mutt_menu_free(&menu);
1737  dialog_pop();
1738  mutt_window_free(&dlg);
1739  return;
1740  }
1741 
1742  op = OP_NULL;
1743  }
1744 
1745  /* not reached */
1746 }
The "current" mailbox.
Definition: context.h:36
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: globals.h:255
#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
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::menu_make_entry()
Definition: recvattach.c:434
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:51
Dialog (nested Windows) displayed to the user.
Definition: mutt_window.h:68
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3360
#define mutt_message(...)
Definition: logging.h:83
Window uses all available vertical space.
Definition: mutt_window.h:33
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:623
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:190
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:919
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition: mutt_window.c:603
void crypt_forget_passphrase(void)
Forget a passphrase and display a message.
Definition: crypt.c:103
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:86
#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 SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: ncrypt.h:126
void(* menu_make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:120
#define CUR_ATTACH
Definition: recvattach.c:89
An Index Window containing a selection list.
Definition: mutt_window.h:72
int attach_tag(struct Menu *menu, int sel, int act)
Tag an attachment - Implements Menu::menu_tag()
Definition: recvattach.c:446
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:75
#define SEND_NO_FLAGS
No flags are set.
Definition: send.h:87
void mutt_attach_reply(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *e_cur, SendFlags flags)
Attach a reply.
Definition: recvcmd.c:903
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1140
struct Mailbox * mailbox
Definition: context.h:50
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
struct MuttWindow * win_ibar
Definition: mutt_menu.h:96
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:42
#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:167
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:91
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:54
A local copy of an email.
Definition: mx.h:81
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:57
A mailbox.
Definition: mailbox.h:80
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:1111
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:1141
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:47
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:55
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:1065
WHERE bool C_Resolve
Config: Move to the next email whenever a command modifies an email.
Definition: globals.h:246
static void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1351
#define SEND_NEWS
Reply to a news article.
Definition: send.h:102
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/ncrypt.h pgplib.h, smime.h
Definition: email.h:39
static int recvattach_pgp_check_traditional(struct AttachCtx *actx, struct Menu *menu)
Is the Attachment inline PGP?
Definition: recvattach.c:1089
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:471
int(* menu_tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:137
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
Definition: recvattach.c:1022
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:755
char * title
Title of this menu.
Definition: mutt_menu.h:84
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:1376
#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:628
FILE * fp
pointer to the message data
Definition: mx.h:83
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:647
void mutt_attach_mail_sender(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur)
Compose an email to the sender in the email attachment.
Definition: recvcmd.c:1073
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:573
#define SEND_GROUP_CHAT_REPLY
Reply to all recipients preserving To/Cc.
Definition: send.h: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:115
Window wants as much space as possible.
Definition: mutt_window.h:43
#define CHECK_ATTACH
Definition: recvattach.c:99
Index Bar containing status info about the Index.
Definition: mutt_window.h:73
enum WindowType type
Window type, e.g. WT_SIDEBAR.
Definition: mutt_window.h:101
#define WithCrypto
Definition: ncrypt.h:160
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:692
void mutt_attach_resend(FILE *fp, struct AttachCtx *actx, struct Body *cur)
resend-message, from the attachment menu
Definition: recvcmd.c:290
char * help
Quickref for the current menu.
Definition: mutt_menu.h:85
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1092
#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:872
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:385
+ 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.