NeoMutt  2019-11-11
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 "mutt.h"
#include "recvattach.h"
#include "commands.h"
#include "context.h"
#include "curs_lib.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 "mutt_window.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:80
#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:130

Definition at line 82 of file recvattach.c.

◆ CUR_ATTACH

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

Definition at line 90 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:97

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

1353 {
1354  if (init)
1355  {
1356  mutt_generate_recvattach_list(actx, actx->email, actx->email->content,
1357  actx->fp_root, -1, 0, 0);
1358  mutt_attach_init(actx);
1359  menu->data = actx;
1360  }
1361 
1362  mutt_update_tree(actx);
1363 
1364  menu->max = actx->vcount;
1365 
1366  if (menu->current >= menu->max)
1367  menu->current = menu->max - 1;
1368  menu_check_recenter(menu);
1369  menu->redraw |= REDRAW_INDEX;
1370 }
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:1220
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:1327
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:143
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 114 of file recvattach.c.

115 {
116  int vindex, rindex, curlevel;
117 
118  vindex = 0;
119  rindex = 0;
120 
121  while (rindex < actx->idxlen)
122  {
123  actx->v2r[vindex++] = rindex;
124  if (actx->idx[rindex]->content->collapsed)
125  {
126  curlevel = actx->idx[rindex]->level;
127  do
128  {
129  rindex++;
130  } while ((rindex < actx->idxlen) && (actx->idx[rindex]->level > curlevel));
131  }
132  else
133  rindex++;
134  }
135 
136  actx->vcount = vindex;
137 }
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 143 of file recvattach.c.

144 {
145  char buf[256];
146  char *s = NULL;
147 
148  mutt_update_v2r(actx);
149 
150  for (int vindex = 0; vindex < actx->vcount; vindex++)
151  {
152  const int rindex = actx->v2r[vindex];
153  actx->idx[rindex]->num = vindex;
154  if ((2 * (actx->idx[rindex]->level + 2)) < sizeof(buf))
155  {
156  if (actx->idx[rindex]->level)
157  {
158  s = buf + 2 * (actx->idx[rindex]->level - 1);
159  *s++ = (actx->idx[rindex]->content->next) ? MUTT_TREE_LTEE : MUTT_TREE_LLCORNER;
160  *s++ = MUTT_TREE_HLINE;
161  *s++ = MUTT_TREE_RARROW;
162  }
163  else
164  s = buf;
165  *s = '\0';
166  }
167 
168  if (actx->idx[rindex]->tree)
169  {
170  if (mutt_str_strcmp(actx->idx[rindex]->tree, buf) != 0)
171  mutt_str_replace(&actx->idx[rindex]->tree, buf);
172  }
173  else
174  actx->idx[rindex]->tree = mutt_str_strdup(buf);
175 
176  if (((2 * (actx->idx[rindex]->level + 2)) < sizeof(buf)) &&
177  actx->idx[rindex]->level)
178  {
179  s = buf + 2 * (actx->idx[rindex]->level - 1);
180  *s++ = (actx->idx[rindex]->content->next) ? '\005' : '\006';
181  *s++ = '\006';
182  }
183  }
184 }
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:114
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 209 of file recvattach.c.

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

436 {
437  struct AttachCtx *actx = menu->data;
438 
439  mutt_expando_format(buf, buflen, 0, menu->indexwin->cols, NONULL(C_AttachFormat),
440  attach_format_str, (unsigned long) (actx->idx[actx->v2r[line]]),
442 }
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:878
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_AttachFormat
Config: printf-like format string for the attachment menu.
Definition: globals.h:101
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
const char * line
Definition: common.c:36
struct MuttWindow * indexwin
Definition: mutt_menu.h:95
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:209
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 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 447 of file recvattach.c.

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

462 {
463  if (!buf || !buf->data || (buf->data[0] == '/'))
464  return;
465 
466  struct Buffer *tmp = mutt_buffer_pool_get();
467  if (C_AttachSaveDir)
468  {
470  if (tmp->dptr[-1] != '/')
471  mutt_buffer_addch(tmp, '/');
472  }
473  else
474  mutt_buffer_addstr(tmp, "./");
475 
476  mutt_buffer_addstr(tmp, mutt_b2s(buf));
477  mutt_buffer_copy(buf, tmp);
479 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:100
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:111
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:71
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 486 of file recvattach.c.

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

503 {
504  char *prompt = NULL;
505  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
506  int rc = -1;
507 
508  struct Buffer *buf = mutt_buffer_pool_get();
509  struct Buffer *tfile = mutt_buffer_pool_get();
510 
511  if (body->filename)
512  {
513  if (directory && *directory)
514  {
515  mutt_buffer_concat_path(buf, *directory, mutt_path_basename(body->filename));
516  }
517  else
518  mutt_buffer_strcpy(buf, body->filename);
519  }
520  else if (has_a_message(body))
521  {
522  mutt_default_save(buf->data, buf->dsize, body->email);
524  }
525 
526  prepend_savedir(buf);
527 
528  prompt = _("Save to file: ");
529  while (prompt)
530  {
531  if ((mutt_buffer_get_field(prompt, buf, MUTT_FILE | MUTT_CLEAR) != 0) ||
533  {
534  goto cleanup;
535  }
536 
537  prompt = NULL;
539 
540  bool is_message = (fp && has_a_message(body));
541 
542  if (is_message)
543  {
544  struct stat st;
545 
546  /* check to make sure that this file is really the one the user wants */
547  rc = mutt_save_confirm(mutt_b2s(buf), &st);
548  if (rc == 1)
549  {
550  prompt = _("Save to file: ");
551  continue;
552  }
553  else if (rc == -1)
554  goto cleanup;
555  mutt_buffer_copy(tfile, buf);
556  }
557  else
558  {
559  rc = mutt_check_overwrite(body->filename, mutt_b2s(buf), tfile, &opt, directory);
560  if (rc == -1)
561  goto cleanup;
562  else if (rc == 1)
563  {
564  prompt = _("Save to file: ");
565  continue;
566  }
567  }
568 
569  mutt_message(_("Saving..."));
570  if (mutt_save_attachment(fp, body, mutt_b2s(tfile), opt,
571  (e || !is_message) ? e : body->email) == 0)
572  {
573  mutt_message(_("Attachment saved"));
574  rc = 0;
575  goto cleanup;
576  }
577  else
578  {
579  prompt = _("Save to file: ");
580  continue;
581  }
582  }
583 
584 cleanup:
586  mutt_buffer_pool_release(&tfile);
587  return rc;
588 }
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:486
#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:100
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:111
static void prepend_savedir(struct Buffer *buf)
Add C_AttachSaveDir to the beginning of a path.
Definition: recvattach.c:461
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:797
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:1449
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:726
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:84
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:343
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 598 of file recvattach.c.

599 {
600  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
601  int rc = -1;
602  struct Buffer *buf = mutt_buffer_pool_get();
603  struct Buffer *tfile = mutt_buffer_pool_get();
604 
605  if (body->filename)
606  {
607  mutt_buffer_strcpy(buf, body->filename);
608  }
609  else if (has_a_message(body))
610  {
611  mutt_default_save(buf->data, buf->dsize, body->email);
612  }
613 
614  prepend_savedir(buf);
616 
617  bool is_message = (fp && has_a_message(body));
618 
619  if (is_message)
620  {
621  mutt_buffer_copy(tfile, buf);
622  }
623  else
624  {
625  rc = mutt_check_overwrite(body->filename, mutt_b2s(buf), tfile, &opt, NULL);
626  if (rc == -1) // abort or cancel
627  goto cleanup;
628  }
629 
630  rc = mutt_save_attachment(fp, body, mutt_b2s(tfile), opt,
631  (e || !is_message) ? e : body->email);
632 
633 cleanup:
635  mutt_buffer_pool_release(&tfile);
636  return rc;
637 }
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:486
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:100
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:111
static void prepend_savedir(struct Buffer *buf)
Add C_AttachSaveDir to the beginning of a path.
Definition: recvattach.c:461
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:797
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:726
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:343
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 648 of file recvattach.c.

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

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

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

845 {
846  for (int i = 0; !tag || (i < actx->idxlen); i++)
847  {
848  if (tag)
849  {
850  fp = actx->idx[i]->fp;
851  top = actx->idx[i]->content;
852  }
853  if (!tag || top->tagged)
854  {
855  if (!filter && !C_AttachSplit)
856  pipe_attachment(fp, top, state);
857  else
858  query_pipe_attachment(command, fp, top, filter);
859  }
860  if (!tag)
861  break;
862  }
863 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:74
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:764
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:806
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 873 of file recvattach.c.

875 {
876  struct State state = { 0 };
877  char buf[PATH_MAX];
878 
879  if (fp)
880  filter = false; /* sanity check: we can't filter in the recv case yet */
881 
882  buf[0] = '\0';
883  /* perform charset conversion on text attachments when piping */
884  state.flags = MUTT_CHARCONV;
885 
886  if ((mutt_get_field((filter ? _("Filter through: ") : _("Pipe to: ")), buf,
887  sizeof(buf), MUTT_CMD) != 0) ||
888  (buf[0] == '\0'))
889  {
890  return;
891  }
892 
893  mutt_expand_path(buf, sizeof(buf));
894 
895  if (!filter && !C_AttachSplit)
896  {
897  mutt_endwin();
898  pid_t pid = mutt_create_filter(buf, &state.fp_out, NULL, NULL);
899  pipe_attachment_list(buf, actx, fp, tag, top, filter, &state);
900  mutt_file_fclose(&state.fp_out);
901  if ((mutt_wait_filter(pid) != 0) || C_WaitKey)
903  }
904  else
905  pipe_attachment_list(buf, actx, fp, tag, top, filter, &state);
906 }
pid_t mutt_create_filter(const char *s, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:210
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:74
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:843
#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:91
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:134
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:269
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:544
#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:577
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:221
+ 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 915 of file recvattach.c.

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

957 {
958  char type[256];
959 
960  for (int i = 0; !tag || (i < actx->idxlen); i++)
961  {
962  if (tag)
963  {
964  fp = actx->idx[i]->fp;
965  top = actx->idx[i]->content;
966  }
967  if (!tag || top->tagged)
968  {
969  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
970  if (!C_AttachSplit && !mailcap_lookup(top, type, sizeof(type), NULL, MUTT_MC_PRINT))
971  {
972  if ((mutt_str_strcasecmp("text/plain", top->subtype) == 0) ||
973  (mutt_str_strcasecmp("application/postscript", top->subtype) == 0))
974  {
975  pipe_attachment(fp, top, state);
976  }
977  else if (mutt_can_decode(top))
978  {
979  /* decode and print */
980 
981  FILE *fp_in = NULL;
982  struct Buffer *newfile = mutt_buffer_pool_get();
983 
984  mutt_buffer_mktemp(newfile);
985  if (mutt_decode_save_attachment(fp, top, mutt_b2s(newfile),
987  {
988  if (!state->fp_out)
989  {
990  mutt_error(
991  "BUG in print_attachment_list(). Please report this. ");
992  return;
993  }
994 
995  fp_in = fopen(mutt_b2s(newfile), "r");
996  if (fp_in)
997  {
998  mutt_file_copy_stream(fp_in, state->fp_out);
999  mutt_file_fclose(&fp_in);
1000  if (C_AttachSep)
1001  state_puts(state, C_AttachSep);
1002  }
1003  }
1004  mutt_file_unlink(mutt_b2s(newfile));
1005  mutt_buffer_pool_release(&newfile);
1006  }
1007  }
1008  else
1009  mutt_print_attachment(fp, top);
1010  }
1011  if (!tag)
1012  break;
1013  }
1014 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:74
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:79
#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:100
No flags set.
Definition: mutt_attach.h:55
char * C_AttachSep
Config: Separator to add between saved/printed/piped attachments.
Definition: recvattach.c:73
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:111
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:467
Mailcap print field.
Definition: mailcap.h:60
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:928
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1756
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:806
#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:1027
+ 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 1023 of file recvattach.c.

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

1067 {
1068  if (!menu->tagprefix)
1070  else
1071  {
1072  for (int i = 0; i < actx->idxlen; i++)
1073  {
1074  if (actx->idx[i]->content->tagged)
1075  {
1076  crypt_pgp_extract_key_from_attachment(actx->idx[i]->fp, actx->idx[i]->content);
1077  }
1078  }
1079  }
1080 }
short idxlen
Number of attachmentes.
Definition: attach.h:55
#define CUR_ATTACH
Definition: recvattach.c:90
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:385
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 1090 of file recvattach.c.

1091 {
1092  int rc = 0;
1093 
1094  if (!menu->tagprefix)
1095  rc = crypt_pgp_check_traditional(CUR_ATTACH->fp, CUR_ATTACH->content, true);
1096  else
1097  {
1098  for (int i = 0; i < actx->idxlen; i++)
1099  if (actx->idx[i]->content->tagged)
1100  rc = rc || crypt_pgp_check_traditional(actx->idx[i]->fp, actx->idx[i]->content, true);
1101  }
1102 
1103  return rc;
1104 }
short idxlen
Number of attachmentes.
Definition: attach.h:55
#define CUR_ATTACH
Definition: recvattach.c:90
bool tagged
This attachment is tagged.
Definition: body.h:70
bool tagprefix
Definition: mutt_menu.h:93
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
int crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
Wrapper for CryptModuleSpecs::pgp_check_traditional()
Definition: cryptglue.c:274
struct Body * content
Attachment.
Definition: attach.h:36
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ recvattach_edit_content_type()

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

Edit the content type of an attachment.

Parameters
actxAttachment context
menuMenu listing Attachments
eEmail

Definition at line 1112 of file recvattach.c.

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

1144 {
1145  do
1146  {
1147  switch (op)
1148  {
1149  case OP_DISPLAY_HEADERS:
1150  bool_str_toggle(Config, "weed", NULL);
1151  /* fallthrough */
1152 
1153  case OP_VIEW_ATTACH:
1154  op = mutt_view_attachment(CUR_ATTACH->fp, CUR_ATTACH->content,
1155  MUTT_VA_REGULAR, e, actx, menu->indexwin);
1156  break;
1157 
1158  case OP_NEXT_ENTRY:
1159  case OP_MAIN_NEXT_UNDELETED: /* hack */
1160  if (menu->current < menu->max - 1)
1161  {
1162  menu->current++;
1163  op = OP_VIEW_ATTACH;
1164  }
1165  else
1166  op = OP_NULL;
1167  break;
1168  case OP_PREV_ENTRY:
1169  case OP_MAIN_PREV_UNDELETED: /* hack */
1170  if (menu->current > 0)
1171  {
1172  menu->current--;
1173  op = OP_VIEW_ATTACH;
1174  }
1175  else
1176  op = OP_NULL;
1177  break;
1178  case OP_EDIT_TYPE:
1179  /* when we edit the content-type, we should redisplay the attachment
1180  * immediately */
1181  mutt_edit_content_type(e, CUR_ATTACH->content, CUR_ATTACH->fp);
1182  if (recv)
1183  recvattach_edit_content_type(actx, menu, e);
1184  else
1185  mutt_edit_content_type(e, CUR_ATTACH->content, CUR_ATTACH->fp);
1186 
1187  menu->redraw |= REDRAW_INDEX;
1188  op = OP_VIEW_ATTACH;
1189  break;
1190  /* functions which are passed through from the pager */
1191  case OP_CHECK_TRADITIONAL:
1193  {
1194  op = OP_NULL;
1195  break;
1196  }
1197  /* fallthrough */
1198  case OP_ATTACH_COLLAPSE:
1199  if (recv)
1200  return op;
1201  /* fallthrough */
1202  default:
1203  op = OP_NULL;
1204  }
1205  } while (op != OP_NULL);
1206 
1207  return op;
1208 }
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: ncrypt.h:136
WHERE struct ConfigSet * Config
Wrapper around the user&#39;s config settings.
Definition: globals.h:41
View using default method.
Definition: mutt_attach.h:42
#define CUR_ATTACH
Definition: recvattach.c:90
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:1112
struct MuttWindow * indexwin
Definition: mutt_menu.h:95
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
int bool_str_toggle(struct ConfigSet *cs, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:240
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1229
int current
Current entry.
Definition: mutt_menu.h:87
#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:386
+ 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 1220 of file recvattach.c.

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

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

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

1409 {
1410  char helpstr[1024];
1411  int op = OP_NULL;
1412 
1413  struct Mailbox *m = Context ? Context->mailbox : NULL;
1414 
1415  /* make sure we have parsed this message */
1417 
1419 
1420  struct Message *msg = mx_msg_open(m, e->msgno);
1421  if (!msg)
1422  return;
1423 
1424  struct Menu *menu = mutt_menu_new(MENU_ATTACH);
1425  menu->title = _("Attachments");
1427  menu->menu_tag = attach_tag;
1428  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_ATTACH, AttachHelp);
1429  mutt_menu_push_current(menu);
1430 
1431  struct AttachCtx *actx = mutt_actx_new();
1432  actx->email = e;
1433  actx->fp_root = msg->fp;
1434  mutt_update_recvattach_menu(actx, menu, true);
1435 
1436  while (true)
1437  {
1438  if (op == OP_NULL)
1439  op = mutt_menu_loop(menu);
1440  if (!Context)
1441  return;
1442  switch (op)
1443  {
1444  case OP_ATTACH_VIEW_MAILCAP:
1446  MUTT_VA_MAILCAP, e, actx, menu->indexwin);
1447  menu->redraw = REDRAW_FULL;
1448  break;
1449 
1450  case OP_ATTACH_VIEW_TEXT:
1452  MUTT_VA_AS_TEXT, e, actx, menu->indexwin);
1453  menu->redraw = REDRAW_FULL;
1454  break;
1455 
1456  case OP_DISPLAY_HEADERS:
1457  case OP_VIEW_ATTACH:
1458  op = mutt_attach_display_loop(menu, op, e, actx, true);
1459  menu->redraw = REDRAW_FULL;
1460  continue;
1461 
1462  case OP_ATTACH_COLLAPSE:
1463  if (!CUR_ATTACH->content->parts)
1464  {
1465  mutt_error(_("There are no subparts to show"));
1466  break;
1467  }
1468  attach_collapse(actx, menu);
1469  mutt_update_recvattach_menu(actx, menu, false);
1470  break;
1471 
1472  case OP_FORGET_PASSPHRASE:
1474  break;
1475 
1476  case OP_EXTRACT_KEYS:
1478  {
1479  recvattach_extract_pgp_keys(actx, menu);
1480  menu->redraw = REDRAW_FULL;
1481  }
1482  break;
1483 
1484  case OP_CHECK_TRADITIONAL:
1485  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1487  {
1488  e->security = crypt_query(NULL);
1489  menu->redraw = REDRAW_FULL;
1490  }
1491  break;
1492 
1493  case OP_PRINT:
1495  CUR_ATTACH->content);
1496  break;
1497 
1498  case OP_PIPE:
1500  CUR_ATTACH->content, false);
1501  break;
1502 
1503  case OP_SAVE:
1505  CUR_ATTACH->content, e, menu);
1506 
1507  if (!menu->tagprefix && C_Resolve && (menu->current < menu->max - 1))
1508  menu->current++;
1509 
1511  break;
1512 
1513  case OP_DELETE:
1515 
1516 #ifdef USE_POP
1517  if (m->magic == MUTT_POP)
1518  {
1519  mutt_flushinp();
1520  mutt_error(_("Can't delete attachment from POP server"));
1521  break;
1522  }
1523 #endif
1524 
1525 #ifdef USE_NNTP
1526  if (m->magic == MUTT_NNTP)
1527  {
1528  mutt_flushinp();
1529  mutt_error(_("Can't delete attachment from news server"));
1530  break;
1531  }
1532 #endif
1533 
1534  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
1535  {
1536  mutt_message(_("Deletion of attachments from encrypted messages is "
1537  "unsupported"));
1538  break;
1539  }
1540  if ((WithCrypto != 0) && (e->security & (SEC_SIGN | SEC_PARTSIGN)))
1541  {
1542  mutt_message(_("Deletion of attachments from signed messages may "
1543  "invalidate the signature"));
1544  }
1545  if (!menu->tagprefix)
1546  {
1547  if (CUR_ATTACH->parent_type == TYPE_MULTIPART)
1548  {
1549  CUR_ATTACH->content->deleted = true;
1550  if (C_Resolve && (menu->current < menu->max - 1))
1551  {
1552  menu->current++;
1553  menu->redraw = REDRAW_MOTION_RESYNC;
1554  }
1555  else
1556  menu->redraw = REDRAW_CURRENT;
1557  }
1558  else
1559  {
1560  mutt_message(
1561  _("Only deletion of multipart attachments is supported"));
1562  }
1563  }
1564  else
1565  {
1566  for (int i = 0; i < menu->max; i++)
1567  {
1568  if (actx->idx[i]->content->tagged)
1569  {
1570  if (actx->idx[i]->parent_type == TYPE_MULTIPART)
1571  {
1572  actx->idx[i]->content->deleted = true;
1573  menu->redraw = REDRAW_INDEX;
1574  }
1575  else
1576  {
1577  mutt_message(
1578  _("Only deletion of multipart attachments is supported"));
1579  }
1580  }
1581  }
1582  }
1583  break;
1584 
1585  case OP_UNDELETE:
1587  if (!menu->tagprefix)
1588  {
1589  CUR_ATTACH->content->deleted = false;
1590  if (C_Resolve && (menu->current < menu->max - 1))
1591  {
1592  menu->current++;
1593  menu->redraw = REDRAW_MOTION_RESYNC;
1594  }
1595  else
1596  menu->redraw = REDRAW_CURRENT;
1597  }
1598  else
1599  {
1600  for (int i = 0; i < menu->max; i++)
1601  {
1602  if (actx->idx[i]->content->tagged)
1603  {
1604  actx->idx[i]->content->deleted = false;
1605  menu->redraw = REDRAW_INDEX;
1606  }
1607  }
1608  }
1609  break;
1610 
1611  case OP_RESEND:
1612  CHECK_ATTACH;
1613  mutt_attach_resend(CUR_ATTACH->fp, actx,
1614  menu->tagprefix ? NULL : CUR_ATTACH->content);
1615  menu->redraw = REDRAW_FULL;
1616  break;
1617 
1618  case OP_BOUNCE_MESSAGE:
1619  CHECK_ATTACH;
1620  mutt_attach_bounce(m, CUR_ATTACH->fp, actx,
1621  menu->tagprefix ? NULL : CUR_ATTACH->content);
1622  menu->redraw = REDRAW_FULL;
1623  break;
1624 
1625  case OP_FORWARD_MESSAGE:
1626  CHECK_ATTACH;
1627  mutt_attach_forward(CUR_ATTACH->fp, e, actx,
1628  menu->tagprefix ? NULL : CUR_ATTACH->content, SEND_NO_FLAGS);
1629  menu->redraw = REDRAW_FULL;
1630  break;
1631 
1632 #ifdef USE_NNTP
1633  case OP_FORWARD_TO_GROUP:
1634  CHECK_ATTACH;
1635  mutt_attach_forward(CUR_ATTACH->fp, e, actx,
1636  menu->tagprefix ? NULL : CUR_ATTACH->content, SEND_NEWS);
1637  menu->redraw = REDRAW_FULL;
1638  break;
1639 
1640  case OP_FOLLOWUP:
1641  CHECK_ATTACH;
1642 
1643  if (!CUR_ATTACH->content->email->env->followup_to ||
1644  (mutt_str_strcasecmp(CUR_ATTACH->content->email->env->followup_to, "poster") != 0) ||
1646  _("Reply by mail as poster prefers?")) != MUTT_YES))
1647  {
1648  mutt_attach_reply(CUR_ATTACH->fp, e, actx,
1649  menu->tagprefix ? NULL : CUR_ATTACH->content,
1650  SEND_NEWS | SEND_REPLY);
1651  menu->redraw = REDRAW_FULL;
1652  break;
1653  }
1654 #endif
1655  /* fallthrough */
1656  case OP_REPLY:
1657  case OP_GROUP_REPLY:
1658  case OP_GROUP_CHAT_REPLY:
1659  case OP_LIST_REPLY:
1660  {
1661  CHECK_ATTACH;
1662 
1663  SendFlags flags = SEND_REPLY;
1664  if (op == OP_GROUP_REPLY)
1665  flags |= SEND_GROUP_REPLY;
1666  else if (op == OP_GROUP_CHAT_REPLY)
1667  flags |= SEND_GROUP_CHAT_REPLY;
1668  else if (op == OP_LIST_REPLY)
1669  flags |= SEND_LIST_REPLY;
1670 
1671  mutt_attach_reply(CUR_ATTACH->fp, e, actx,
1672  menu->tagprefix ? NULL : CUR_ATTACH->content, flags);
1673  menu->redraw = REDRAW_FULL;
1674  break;
1675  }
1676 
1677  case OP_COMPOSE_TO_SENDER:
1678  CHECK_ATTACH;
1679  mutt_attach_mail_sender(CUR_ATTACH->fp, e, actx,
1680  menu->tagprefix ? NULL : CUR_ATTACH->content);
1681  menu->redraw = REDRAW_FULL;
1682  break;
1683 
1684  case OP_EDIT_TYPE:
1685  recvattach_edit_content_type(actx, menu, e);
1686  menu->redraw |= REDRAW_INDEX;
1687  break;
1688 
1689  case OP_EXIT:
1690  mx_msg_close(m, &msg);
1691 
1692  e->attach_del = false;
1693  for (int i = 0; i < actx->idxlen; i++)
1694  {
1695  if (actx->idx[i]->content && actx->idx[i]->content->deleted)
1696  {
1697  e->attach_del = true;
1698  break;
1699  }
1700  }
1701  if (e->attach_del)
1702  e->changed = true;
1703 
1704  mutt_actx_free(&actx);
1705 
1706  mutt_menu_pop_current(menu);
1707  mutt_menu_free(&menu);
1708  return;
1709  }
1710 
1711  op = OP_NULL;
1712  }
1713 
1714  /* not reached */
1715 }
The "current" mailbox.
Definition: context.h:36
#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:92
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:435
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:51
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3340
#define mutt_message(...)
Definition: logging.h:83
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:39
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:195
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:848
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
void crypt_forget_passphrase(void)
Forget a passphrase and display a message.
Definition: crypt.c:105
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
#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:90
int attach_tag(struct Menu *menu, int sel, int act)
Tag an attachment - Implements Menu::menu_tag()
Definition: recvattach.c:447
#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:1101
struct Mailbox * mailbox
Definition: context.h:50
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:116
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
#define REDRAW_MOTION_RESYNC
Redraw any changing the menu selection.
Definition: mutt_menu.h:44
void mutt_attach_bounce(struct Mailbox *m, FILE *fp, struct AttachCtx *actx, struct Body *cur)
Bounce function, from the attachment menu.
Definition: recvcmd.c:168
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
&#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
A mailbox.
Definition: mailbox.h:92
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:1112
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:1142
struct MuttWindow * indexwin
Definition: mutt_menu.h:95
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:1066
WHERE bool C_Resolve
Config: Move to the next email whenever a command modifies an email.
Definition: globals.h:251
static void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1352
#define SEND_NEWS
Reply to a news article.
Definition: send.h:102
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:1090
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:82
int max
Number of entries in the menu.
Definition: mutt_menu.h:88
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:1023
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:1377
#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:648
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
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
#define CHECK_ATTACH
Definition: recvattach.c:100
#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:694
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:1053
#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:873
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:386
+ 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 71 of file recvattach.c.

◆ C_AttachSaveWithoutPrompting

char* C_AttachSaveWithoutPrompting

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

Definition at line 72 of file recvattach.c.

◆ C_AttachSep

char* C_AttachSep

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

Definition at line 73 of file recvattach.c.

◆ C_AttachSplit

bool C_AttachSplit

Config: Save/print/pipe tagged messages individually.

Definition at line 74 of file recvattach.c.

◆ C_DigestCollapse

bool C_DigestCollapse

Config: Hide the subparts of a multipart/digest.

Definition at line 75 of file recvattach.c.

◆ C_MessageFormat

char* C_MessageFormat

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

Definition at line 76 of file recvattach.c.

◆ Mailbox_is_read_only

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

Definition at line 80 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 92 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 97 of file recvattach.c.