NeoMutt  2018-07-16 +952-a2da0a
Teaching an old dog new tricks
DOXYGEN
recvattach.c File Reference

Routines for managing attachments. More...

#include "config.h"
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mutt/mutt.h"
#include "config/lib.h"
#include "email/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 "mailbox.h"
#include "menu.h"
#include "mutt_attach.h"
#include "mutt_logging.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 "rfc1524.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 CURATTACH   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, enum FormatFlag 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 (char *buf, size_t bufsize)
 Add AttachSaveDir to the beginning of a path. 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...
 
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...
 
static void mutt_generate_recvattach_list (struct AttachCtx *actx, struct Email *e, struct Body *m, 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 * AttachSaveDir
 Config: Default directory where attachments are saved. More...
 
char * AttachSep
 Config: Separator to add between saved/printed/piped attachments. More...
 
bool AttachSplit
 Config: Save/print/pipe tagged messages individually. More...
 
bool DigestCollapse
 Config: Hide the subparts of a multipart/digest. More...
 
char * 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

#define CHECK_READONLY
Value:
{ \
break; \
}
The "current" mailbox.
Definition: context.h:36
static const char * Mailbox_is_read_only
Definition: recvattach.c:81
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:753
#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:113
#define mutt_error(...)
Definition: logging.h:88

Definition at line 83 of file recvattach.c.

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

Definition at line 91 of file recvattach.c.

#define CHECK_ATTACH
Value:
{ \
break; \
}
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:753
#define _(a)
Definition: message.h:28
WHERE bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:31
#define mutt_error(...)
Definition: logging.h:88
static const char * Function_not_permitted
Definition: recvattach.c:98

Definition at line 101 of file recvattach.c.

Function Documentation

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

1262 {
1263  if (init)
1264  {
1265  mutt_generate_recvattach_list(actx, actx->email, actx->email->content,
1266  actx->root_fp, -1, 0, 0);
1267  mutt_attach_init(actx);
1268  menu->data = actx;
1269  }
1270 
1271  mutt_update_tree(actx);
1272 
1273  menu->max = actx->vcount;
1274 
1275  if (menu->current >= menu->max)
1276  menu->current = menu->max - 1;
1277  menu_check_recenter(menu);
1278  menu->redraw |= REDRAW_INDEX;
1279 }
int redraw
when to redraw the screen
Definition: menu.h:63
struct Email * email
used by recvattach for updating
Definition: attach.h:51
struct Body * content
list of MIME parts
Definition: email.h:92
void mutt_attach_init(struct AttachCtx *actx)
Create a new Attachment context.
Definition: recvattach.c:1236
FILE * root_fp
used by recvattach for updating
Definition: attach.h:52
int max
the number of entries in the menu
Definition: menu.h:62
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: menu.h:60
static void mutt_generate_recvattach_list(struct AttachCtx *actx, struct Email *e, struct Body *m, FILE *fp, int parent_type, int level, bool decrypted)
Create a list of attachments.
Definition: recvattach.c:1130
int current
current entry
Definition: menu.h:61
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:

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

116 {
117  int vindex, rindex, curlevel;
118 
119  vindex = 0;
120  rindex = 0;
121 
122  while (rindex < actx->idxlen)
123  {
124  actx->v2r[vindex++] = rindex;
125  if (actx->idx[rindex]->content->collapsed)
126  {
127  curlevel = actx->idx[rindex]->level;
128  do
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:95
short * v2r
mapping from virtual to real attachment
Definition: attach.h:58
struct Body * content
Definition: attach.h:36
int level
Definition: attach.h:40
struct AttachPtr ** idx
Definition: attach.h:54
short vcount
the number of virtual attachments
Definition: attach.h:59

+ Here is the caller graph for this function:

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[STRING];
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) && actx->idx[rindex]->level)
177  {
178  s = buf + 2 * (actx->idx[rindex]->level - 1);
179  *s++ = (actx->idx[rindex]->content->next) ? '\005' : '\006';
180  *s++ = '\006';
181  }
182  }
183 }
struct Body * next
next attachment in the list
Definition: body.h:57
char * tree
Definition: attach.h:39
#define MUTT_TREE_LTEE
Definition: mutt.h:85
static void mutt_update_v2r(struct AttachCtx *actx)
Update the virtual list of attachments.
Definition: recvattach.c:115
int num
Definition: attach.h:41
#define MUTT_TREE_HLINE
Definition: mutt.h:86
#define MUTT_TREE_LLCORNER
Definition: mutt.h:83
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:460
#define STRING
Definition: string2.h:35
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:384
short * v2r
mapping from virtual to real attachment
Definition: attach.h:58
struct Body * content
Definition: attach.h:36
#define MUTT_TREE_RARROW
Definition: mutt.h:89
int level
Definition: attach.h:40
struct AttachPtr ** idx
Definition: attach.h:54
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:612
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:

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,
enum FormatFlag  flags 
)

Format a string for the attachment menu - Implements format_t.

Expando Description
%C Character set
%c Character set: convert?
%D Deleted flag
%d Description
%e MIME content-transfer-encoding
%f Filename
%F Filename for content-disposition header
%I Content-disposition, either I (inline) or A (attachment)
%m Major MIME type
%M MIME subtype
%n Attachment number
%Q 'Q', if MIME part qualifies for attachment counting
%s Size
%t Tagged flag
%T Tree chars
%u Unlink
%X Number of qualifying MIME parts in this part and its children

Definition at line 208 of file recvattach.c.

212 {
213  char fmt[SHORT_STRING];
214  char charset[SHORT_STRING];
215  struct AttachPtr *aptr = (struct AttachPtr *) data;
216  int optional = (flags & MUTT_FORMAT_OPTIONAL);
217  size_t l;
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 = 0;
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 = 0;
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  MessageFormat && aptr->content->email)
259  {
260  char s[SHORT_STRING];
262  s, sizeof(s), MessageFormat, 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  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 = 0;
295  break;
296  }
297  /* fallthrough */
298  case 'f':
299  if (!optional)
300  {
301  if (aptr->content->filename && *aptr->content->filename == '/')
302  {
303  char path[PATH_MAX];
304 
305  mutt_str_strfcpy(path, aptr->content->filename, sizeof(path));
306  mutt_pretty_mailbox(path, sizeof(path));
307  mutt_format_s(buf, buflen, prec, path);
308  }
309  else
310  mutt_format_s(buf, buflen, prec, NONULL(aptr->content->filename));
311  }
312  else if (!aptr->content->filename)
313  optional = 0;
314  break;
315  case 'D':
316  if (!optional)
317  snprintf(buf, buflen, "%c", aptr->content->deleted ? 'D' : ' ');
318  else if (!aptr->content->deleted)
319  optional = 0;
320  break;
321  case 'e':
322  if (!optional)
323  mutt_format_s(buf, buflen, prec, ENCODING(aptr->content->encoding));
324  break;
325  case 'I':
326  if (!optional)
327  {
328  const char dispchar[] = { 'I', 'A', 'F', '-' };
329  char ch;
330 
331  if (aptr->content->disposition < sizeof(dispchar))
332  ch = dispchar[aptr->content->disposition];
333  else
334  {
335  mutt_debug(1, "ERROR: invalid content-disposition %d\n", aptr->content->disposition);
336  ch = '!';
337  }
338  snprintf(buf, buflen, "%c", ch);
339  }
340  break;
341  case 'm':
342  if (!optional)
343  mutt_format_s(buf, buflen, prec, TYPE(aptr->content));
344  break;
345  case 'M':
346  if (!optional)
347  mutt_format_s(buf, buflen, prec, aptr->content->subtype);
348  else if (!aptr->content->subtype)
349  optional = 0;
350  break;
351  case 'n':
352  if (!optional)
353  {
354  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
355  snprintf(buf, buflen, fmt, aptr->num + 1);
356  }
357  break;
358  case 'Q':
359  if (optional)
360  optional = aptr->content->attach_qualifies;
361  else
362  {
363  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
364  mutt_format_s(buf, buflen, fmt, "Q");
365  }
366  break;
367  case 's':
368  if (flags & MUTT_FORMAT_STAT_FILE)
369  {
370  struct stat st;
371  stat(aptr->content->filename, &st);
372  l = st.st_size;
373  }
374  else
375  l = aptr->content->length;
376 
377  if (!optional)
378  {
379  char tmp[SHORT_STRING];
380  mutt_str_pretty_size(tmp, sizeof(tmp), l);
381  mutt_format_s(buf, buflen, prec, tmp);
382  }
383  else if (l == 0)
384  optional = 0;
385 
386  break;
387  case 't':
388  if (!optional)
389  snprintf(buf, buflen, "%c", aptr->content->tagged ? '*' : ' ');
390  else if (!aptr->content->tagged)
391  optional = 0;
392  break;
393  case 'T':
394  if (!optional)
395  mutt_format_s_tree(buf, buflen, prec, NONULL(aptr->tree));
396  else if (!aptr->tree)
397  optional = 0;
398  break;
399  case 'u':
400  if (!optional)
401  snprintf(buf, buflen, "%c", aptr->content->unlink ? '-' : ' ');
402  else if (!aptr->content->unlink)
403  optional = 0;
404  break;
405  case 'X':
406  if (optional)
407  optional = (aptr->content->attach_count + aptr->content->attach_qualifies) != 0;
408  else
409  {
410  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
411  snprintf(buf, buflen, fmt, aptr->content->attach_count + aptr->content->attach_qualifies);
412  }
413  break;
414  default:
415  *buf = 0;
416  }
417 
418  if (optional)
419  mutt_expando_format(buf, buflen, col, cols, if_str, attach_format_str, data, 0);
420  else if (flags & MUTT_FORMAT_OPTIONAL)
421  mutt_expando_format(buf, buflen, col, cols, else_str, attach_format_str, data, 0);
422  return src;
423 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:47
#define NONULL(x)
Definition: string2.h:39
An email to which things will be attached.
Definition: attach.h:34
#define SHORT_STRING
Definition: string2.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:1214
void mutt_pretty_mailbox(char *s, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:606
bool noconv
don&#39;t do character set conversion
Definition: body.h:77
used by attach_format_str
Definition: format_flags.h:37
make sure that all chars are printable
Definition: format_flags.h:35
unsigned int disposition
content-disposition
Definition: body.h:69
char * tree
Definition: attach.h:39
bool attach_qualifies
Definition: body.h:96
#define ENCODING(X)
Definition: mime.h:84
allow optional field processing
Definition: format_flags.h:36
signed short attach_count
Definition: body.h:63
bool tagged
Definition: body.h:74
unsigned int encoding
content-transfer-encoding
Definition: body.h:68
char * subtype
content-type subtype
Definition: body.h:36
LOFF_T length
length (in bytes) of attachment
Definition: body.h:46
#define PATH_MAX
Definition: mutt.h:46
int num
Definition: attach.h:41
Type: &#39;text/*&#39;.
Definition: mime.h:38
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:742
#define TYPE(X)
Definition: mime.h:82
reserve space for arrow_cursor
Definition: format_flags.h:38
char * mutt_body_get_charset(struct Body *b, char *buf, size_t buflen)
Get a body&#39;s character set.
Definition: sendlib.c:1404
char * description
content-description
Definition: body.h:39
bool mutt_is_text_part(struct Body *b)
Is this part of an email in plain text?
Definition: muttlib.c:429
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, enum FormatFlag flags)
Format a string for the attachment menu - Implements format_t.
Definition: recvattach.c:208
unsigned int type
content-type primary type
Definition: body.h:67
bool deleted
attachment marked for deletion
Definition: body.h:75
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:1061
struct Body * content
Definition: attach.h:36
bool unlink
flag to indicate the file named by "filename" should be unlink()ed before free()ing this structure ...
Definition: body.h:71
void mutt_make_string_flags(char *buf, size_t buflen, const char *s, struct Context *ctx, struct Email *e, enum FormatFlag flags)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1454
char * MessageFormat
Config: printf-like format string for listing attached messages.
Definition: recvattach.c:77
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:49
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: string.c:1015
struct Email * email
header information for message/rfc822
Definition: body.h:59
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, enum FormatFlag flags)
Expand expandos (x) in a string.
Definition: muttlib.c:816
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:1073
print the subject even if unchanged
Definition: format_flags.h:33

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

429 {
430  struct AttachCtx *actx = menu->data;
431 
433  attach_format_str, (unsigned long) (actx->idx[actx->v2r[line]]),
435 }
#define NONULL(x)
Definition: string2.h:39
const char * line
Definition: common.c:35
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
reserve space for arrow_cursor
Definition: format_flags.h:38
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, enum FormatFlag flags)
Format a string for the attachment menu - Implements format_t.
Definition: recvattach.c:208
short * v2r
mapping from virtual to real attachment
Definition: attach.h:58
WHERE char * AttachFormat
Config: printf-like format string for the attachment menu.
Definition: globals.h:105
void * data
extra data for the current menu
Definition: menu.h:60
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Definition: attach.h:54
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, enum FormatFlag flags)
Expand expandos (x) in a string.
Definition: muttlib.c:816

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

Tag an attachment - Implements Menu::menu_tag()

Definition at line 440 of file recvattach.c.

441 {
442  struct AttachCtx *actx = menu->data;
443  struct Body *cur = actx->idx[actx->v2r[sel]]->content;
444  bool ot = cur->tagged;
445 
446  cur->tagged = ((act >= 0) ? act : !cur->tagged);
447  return cur->tagged - ot;
448 }
The body of an email.
Definition: body.h:33
bool tagged
Definition: body.h:74
short * v2r
mapping from virtual to real attachment
Definition: attach.h:58
struct Body * content
Definition: attach.h:36
void * data
extra data for the current menu
Definition: menu.h:60
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the caller graph for this function:

static void prepend_savedir ( char *  buf,
size_t  bufsize 
)
static

Add AttachSaveDir to the beginning of a path.

Parameters
bufBuffer for the result, must be valid
bufsizeSize of the buffer

Definition at line 455 of file recvattach.c.

456 {
457  const char *savedir = AttachSaveDir;
458 
459  if (!savedir || !*savedir)
460  savedir = "./";
461 
462  size_t savedirlen = strlen(savedir);
463  size_t buflen = strlen(buf);
464  bool addsep = (savedir[savedirlen - 1] != '/');
465  size_t newbuflen = savedirlen + buflen + addsep;
466 
467  if (bufsize < newbuflen)
468  {
469  return;
470  }
471 
472  memmove(buf + savedirlen + addsep, buf, buflen);
473  memcpy(buf, savedir, savedirlen);
474  if (addsep)
475  {
476  buf[savedirlen] = '/';
477  }
478  buf[newbuflen] = '\0';
479 }
char * AttachSaveDir
Config: Default directory where attachments are saved.
Definition: recvattach.c:73

+ Here is the caller graph for this function:

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

491 {
492  char *prompt = NULL;
493  char buf[PATH_MAX], tfile[PATH_MAX];
494  int append = 0;
495  int rc;
496 
497  if (body->filename)
498  {
499  if (directory && *directory)
500  {
501  mutt_path_concat(buf, *directory, mutt_path_basename(body->filename), sizeof(buf));
502  }
503  else
504  mutt_str_strfcpy(buf, body->filename, sizeof(buf));
505  }
506  else if (body->email && body->encoding != ENC_BASE64 && body->encoding != ENC_QUOTED_PRINTABLE &&
507  mutt_is_message_type(body->type, body->subtype))
508  {
509  mutt_default_save(buf, sizeof(buf), body->email);
510  }
511  else
512  buf[0] = 0;
513 
514  prepend_savedir(buf, sizeof(buf));
515 
516  prompt = _("Save to file: ");
517  while (prompt)
518  {
519  if (mutt_get_field(prompt, buf, sizeof(buf), MUTT_FILE) != 0 || !buf[0])
520  {
522  return -1;
523  }
524 
525  prompt = NULL;
526  mutt_expand_path(buf, sizeof(buf));
527 
528  const int is_message = (fp && body->email && body->encoding != ENC_BASE64 &&
529  body->encoding != ENC_QUOTED_PRINTABLE &&
530  mutt_is_message_type(body->type, body->subtype));
531 
532  if (is_message)
533  {
534  struct stat st;
535 
536  /* check to make sure that this file is really the one the user wants */
537  rc = mutt_save_confirm(buf, &st);
538  if (rc == 1)
539  {
540  prompt = _("Save to file: ");
541  continue;
542  }
543  else if (rc == -1)
544  return -1;
545  mutt_str_strfcpy(tfile, buf, sizeof(tfile));
546  }
547  else
548  {
549  rc = mutt_check_overwrite(body->filename, buf, tfile, sizeof(tfile), &append, directory);
550  if (rc == -1)
551  return -1;
552  else if (rc == 1)
553  {
554  prompt = _("Save to file: ");
555  continue;
556  }
557  }
558 
559  mutt_message(_("Saving..."));
560  if (mutt_save_attachment(fp, body, tfile, append, (e || !is_message) ? e : body->email) == 0)
561  {
562  mutt_message(_("Attachment saved"));
563  return 0;
564  }
565  else
566  {
567  prompt = _("Save to file: ");
568  continue;
569  }
570  }
571  return 0;
572 }
int mutt_save_attachment(FILE *fp, struct Body *m, char *path, int flags, struct Email *e)
Save an attachment.
Definition: mutt_attach.c:791
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:47
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1214
int mutt_check_overwrite(const char *attname, const char *path, char *fname, size_t flen, int *append, char **directory)
Ask the user if overwriting is necessary.
Definition: muttlib.c:685
const char * mutt_path_basename(const char *f)
Find the last component for a pathname.
Definition: path.c:303
#define mutt_message(...)
Definition: logging.h:87
#define _(a)
Definition: message.h:28
static void prepend_savedir(char *buf, size_t bufsize)
Add AttachSaveDir to the beginning of a path.
Definition: recvattach.c:455
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:523
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1383
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:157
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:141
unsigned int encoding
content-transfer-encoding
Definition: body.h:68
Base-64 encoded text.
Definition: mime.h:52
char * subtype
content-type subtype
Definition: body.h:36
#define PATH_MAX
Definition: mutt.h:46
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:742
#define mutt_get_field(A, B, C, D)
Definition: curs_lib.h:78
#define MUTT_FILE
do file completion
Definition: mutt.h:59
unsigned int type
content-type primary type
Definition: body.h:67
Quoted-printable text.
Definition: mime.h:51
char * mutt_path_concat(char *d, const char *dir, const char *fname, size_t l)
Join a directory name and a filename.
Definition: path.c:323
struct Email * email
header information for message/rfc822
Definition: body.h:59

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

585 {
586  char buf[PATH_MAX], tfile[PATH_MAX];
587  char *directory = NULL;
588  int rc = 1;
589  int last = menu ? menu->current : -1;
590  FILE *fpout = NULL;
591 
592  buf[0] = 0;
593 
594  for (int i = 0; !tag || (i < actx->idxlen); i++)
595  {
596  if (tag)
597  {
598  fp = actx->idx[i]->fp;
599  top = actx->idx[i]->content;
600  }
601  if (!tag || top->tagged)
602  {
603  if (!AttachSplit)
604  {
605  if (!buf[0])
606  {
607  int append = 0;
608 
609  mutt_str_strfcpy(buf, mutt_path_basename(NONULL(top->filename)), sizeof(buf));
610  prepend_savedir(buf, sizeof(buf));
611 
612  if (mutt_get_field(_("Save to file: "), buf, sizeof(buf), MUTT_FILE) != 0 ||
613  !buf[0])
614  {
615  return;
616  }
617  mutt_expand_path(buf, sizeof(buf));
618  if (mutt_check_overwrite(top->filename, buf, tfile, sizeof(tfile), &append, NULL))
619  return;
620  rc = mutt_save_attachment(fp, top, tfile, append, e);
621  if ((rc == 0) && AttachSep && (fpout = fopen(tfile, "a")))
622  {
623  fprintf(fpout, "%s", AttachSep);
624  mutt_file_fclose(&fpout);
625  }
626  }
627  else
628  {
629  rc = mutt_save_attachment(fp, top, tfile, MUTT_SAVE_APPEND, e);
630  if ((rc == 0) && AttachSep && (fpout = fopen(tfile, "a")))
631  {
632  fprintf(fpout, "%s", AttachSep);
633  mutt_file_fclose(&fpout);
634  }
635  }
636  }
637  else
638  {
639  if (tag && menu && top->aptr)
640  {
641  menu->oldcurrent = menu->current;
642  menu->current = top->aptr->num;
643  menu_check_recenter(menu);
644  menu->redraw |= REDRAW_MOTION;
645 
646  menu_redraw(menu);
647  }
648  if (query_save_attachment(fp, top, e, &directory) == -1)
649  break;
650  }
651  }
652  if (!tag)
653  break;
654  }
655 
656  FREE(&directory);
657 
658  if (tag && menu)
659  {
660  menu->oldcurrent = menu->current;
661  menu->current = last;
662  menu_check_recenter(menu);
663  menu->redraw |= REDRAW_MOTION;
664  }
665 
666  if (!AttachSplit && (rc == 0))
667  mutt_message(_("Attachment saved"));
668 }
int mutt_save_attachment(FILE *fp, struct Body *m, char *path, int flags, struct Email *e)
Save an attachment.
Definition: mutt_attach.c:791
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:47
#define NONULL(x)
Definition: string2.h:39
int redraw
when to redraw the screen
Definition: menu.h:63
int mutt_check_overwrite(const char *attname, const char *path, char *fname, size_t flen, int *append, char **directory)
Ask the user if overwriting is necessary.
Definition: muttlib.c:685
char * AttachSep
Config: Separator to add between saved/printed/piped attachments.
Definition: recvattach.c:74
const char * mutt_path_basename(const char *f)
Find the last component for a pathname.
Definition: path.c:303
#define mutt_message(...)
Definition: logging.h:87
int oldcurrent
for driver use only
Definition: menu.h:85
#define _(a)
Definition: message.h:28
short idxlen
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:490
static void prepend_savedir(char *buf, size_t bufsize)
Add AttachSaveDir to the beginning of a path.
Definition: recvattach.c:455
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:157
bool tagged
Definition: body.h:74
#define PATH_MAX
Definition: mutt.h:46
int num
Definition: attach.h:41
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition: body.h:61
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:742
FILE * fp
used in the recvattach menu.
Definition: attach.h:37
Append to existing file - mutt_save_attachment()
Definition: mutt.h:181
#define mutt_get_field(A, B, C, D)
Definition: curs_lib.h:78
#define MUTT_FILE
do file completion
Definition: mutt.h:59
bool AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
struct Body * content
Definition: attach.h:36
int mutt_file_fclose(FILE **f)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
#define FREE(x)
Definition: memory.h:46
int current
current entry
Definition: menu.h:61
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

678 {
679  char tfile[PATH_MAX];
680 
681  if (filter)
682  {
683  char warning[PATH_MAX + STRING];
684  snprintf(warning, sizeof(warning),
685  _("WARNING! You are about to overwrite %s, continue?"), body->filename);
686  if (mutt_yesorno(warning, MUTT_NO) != MUTT_YES)
687  {
689  return;
690  }
691  mutt_mktemp(tfile, sizeof(tfile));
692  }
693  else
694  tfile[0] = 0;
695 
696  if (mutt_pipe_attachment(fp, body, command, tfile))
697  {
698  if (filter)
699  {
700  mutt_file_unlink(body->filename);
701  mutt_file_rename(tfile, body->filename);
702  mutt_update_encoding(body);
703  mutt_message(_("Attachment filtered"));
704  }
705  }
706  else
707  {
708  if (filter && tfile[0])
709  mutt_file_unlink(tfile);
710  }
711 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:47
#define mutt_message(...)
Definition: logging.h:87
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
int mutt_yesorno(const char *msg, int def)
Ask the user a Yes/No question.
Definition: curs_lib.c:330
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:192
#define _(a)
Definition: message.h:28
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1428
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:69
#define mutt_mktemp(a, b)
Definition: muttlib.h:71
#define PATH_MAX
Definition: mutt.h:46
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
int mutt_file_rename(char *oldfile, char *newfile)
Rename a file.
Definition: file.c:1240
#define STRING
Definition: string2.h:35
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:41
int mutt_pipe_attachment(FILE *fp, struct Body *b, const char *path, char *outfile)
Pipe an attachment to a command.
Definition: mutt_attach.c:672

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

720 {
721  if (!state || !state->fpout)
722  return;
723 
724  if (fp)
725  {
726  state->fpin = fp;
727  mutt_decode_attachment(b, state);
728  if (AttachSep)
729  state_puts(AttachSep, state);
730  }
731  else
732  {
733  FILE *ifp = fopen(b->filename, "r");
734  if (!ifp)
735  {
736  mutt_perror("fopen");
737  return;
738  }
739  mutt_file_copy_stream(ifp, state->fpout);
740  mutt_file_fclose(&ifp);
741  if (AttachSep)
742  state_puts(AttachSep, state);
743  }
744 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1728
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:47
#define mutt_perror(...)
Definition: logging.h:89
char * AttachSep
Config: Separator to add between saved/printed/piped attachments.
Definition: recvattach.c:74
FILE * fpout
Definition: state.h:34
int mutt_file_copy_stream(FILE *fin, FILE *fout)
Copy the contents of one file into another.
Definition: file.c:264
#define state_puts(x, y)
Definition: state.h:51
FILE * fpin
Definition: state.h:33
int mutt_file_fclose(FILE **f)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

758 {
759  for (int i = 0; !tag || (i < actx->idxlen); i++)
760  {
761  if (tag)
762  {
763  fp = actx->idx[i]->fp;
764  top = actx->idx[i]->content;
765  }
766  if (!tag || top->tagged)
767  {
768  if (!filter && !AttachSplit)
769  pipe_attachment(fp, top, state);
770  else
771  query_pipe_attachment(command, fp, top, filter);
772  }
773  if (!tag)
774  break;
775  }
776 }
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:74
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:677
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:719
bool AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
struct Body * content
Definition: attach.h:36
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

788 {
789  struct State state = { 0 };
790  char buf[SHORT_STRING];
791 
792  if (fp)
793  filter = false; /* sanity check: we can't filter in the recv case yet */
794 
795  buf[0] = 0;
796  /* perform charset conversion on text attachments when piping */
797  state.flags = MUTT_CHARCONV;
798 
799  if (mutt_get_field((filter ? _("Filter through: ") : _("Pipe to: ")), buf,
800  sizeof(buf), MUTT_CMD) != 0 ||
801  !buf[0])
802  {
803  return;
804  }
805 
806  mutt_expand_path(buf, sizeof(buf));
807 
808  if (!filter && !AttachSplit)
809  {
810  mutt_endwin();
811  pid_t thepid = mutt_create_filter(buf, &state.fpout, NULL, NULL);
812  pipe_attachment_list(buf, actx, fp, tag, top, filter, &state);
813  mutt_file_fclose(&state.fpout);
814  if (mutt_wait_filter(thepid) != 0 || WaitKey)
816  }
817  else
818  pipe_attachment_list(buf, actx, fp, tag, top, filter, &state);
819 }
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:756
#define SHORT_STRING
Definition: string2.h:34
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:44
#define _(a)
Definition: message.h:28
WHERE bool WaitKey
Config: Prompt to press a key after running external commands.
Definition: globals.h:262
FILE * fpout
Definition: state.h:34
int flags
Definition: state.h:36
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:157
#define MUTT_CMD
do completion on previous word
Definition: mutt.h:61
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:498
#define mutt_get_field(A, B, C, D)
Definition: curs_lib.h:78
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:531
bool AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
int mutt_file_fclose(FILE **f)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
pid_t mutt_create_filter(const char *s, FILE **in, FILE **out, FILE **err)
Set up filter program.
Definition: filter.c:216
Keep track when processing files.
Definition: state.h:31
int mutt_wait_filter(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:227

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

829 {
830  char type[STRING];
831 
832  for (int i = 0; !tag || (i < actx->idxlen); i++)
833  {
834  if (tag)
835  top = actx->idx[i]->content;
836  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
837  if (!tag || top->tagged)
838  {
839  if (!rfc1524_mailcap_lookup(top, type, NULL, MUTT_PRINT))
840  {
841  if ((mutt_str_strcasecmp("text/plain", top->subtype) != 0) &&
842  (mutt_str_strcasecmp("application/postscript", top->subtype) != 0))
843  {
844  if (!mutt_can_decode(top))
845  {
846  /* L10N:
847  %s gets replaced by a MIME type, e.g. "text/plain" or
848  application/octet-stream.
849  */
850  mutt_error(_("I don't know how to print %s attachments"), type);
851  return false;
852  }
853  }
854  }
855  }
856  if (!tag)
857  break;
858  }
859  return true;
860 }
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:74
char * subtype
content-type subtype
Definition: body.h:36
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1687
#define TYPE(X)
Definition: mime.h:82
Mailcap print field.
Definition: mutt.h:178
#define STRING
Definition: string2.h:35
struct Body * content
Definition: attach.h:36
int rfc1524_mailcap_lookup(struct Body *a, char *type, struct Rfc1524MailcapEntry *entry, int opt)
Find given type in the list of mailcap files.
Definition: rfc1524.c:437
#define mutt_error(...)
Definition: logging.h:88
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:625
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

872 {
873  char type[STRING];
874 
875  for (int i = 0; !tag || (i < actx->idxlen); i++)
876  {
877  if (tag)
878  {
879  fp = actx->idx[i]->fp;
880  top = actx->idx[i]->content;
881  }
882  if (!tag || top->tagged)
883  {
884  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
885  if (!AttachSplit && !rfc1524_mailcap_lookup(top, type, NULL, MUTT_PRINT))
886  {
887  if ((mutt_str_strcasecmp("text/plain", top->subtype) == 0) ||
888  (mutt_str_strcasecmp("application/postscript", top->subtype) == 0))
889  {
890  pipe_attachment(fp, top, state);
891  }
892  else if (mutt_can_decode(top))
893  {
894  /* decode and print */
895 
896  char newfile[PATH_MAX] = "";
897  FILE *ifp = NULL;
898 
899  mutt_mktemp(newfile, sizeof(newfile));
900  if (mutt_decode_save_attachment(fp, top, newfile, MUTT_PRINTING, 0) == 0)
901  {
902  if (!state->fpout)
903  {
904  mutt_error(
905  "BUG in print_attachment_list(). Please report this. ");
906  return;
907  }
908 
909  ifp = fopen(newfile, "r");
910  if (ifp)
911  {
912  mutt_file_copy_stream(ifp, state->fpout);
913  mutt_file_fclose(&ifp);
914  if (AttachSep)
915  state_puts(AttachSep, state);
916  }
917  }
918  mutt_file_unlink(newfile);
919  }
920  }
921  else
922  mutt_print_attachment(fp, top);
923  }
924  if (!tag)
925  break;
926  }
927 }
char * AttachSep
Config: Separator to add between saved/printed/piped attachments.
Definition: recvattach.c:74
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:192
short idxlen
Definition: attach.h:55
#define MUTT_PRINTING
are we printing? - MUTT_DISPLAY "light"
Definition: state.h:45
FILE * fpout
Definition: state.h:34
bool tagged
Definition: body.h:74
char * subtype
content-type subtype
Definition: body.h:36
#define mutt_mktemp(a, b)
Definition: muttlib.h:71
int mutt_file_copy_stream(FILE *fin, FILE *fout)
Copy the contents of one file into another.
Definition: file.c:264
#define PATH_MAX
Definition: mutt.h:46
#define state_puts(x, y)
Definition: state.h:51
int mutt_decode_save_attachment(FILE *fp, struct Body *m, char *path, int displaying, int flags)
Decode, then save an attachment.
Definition: mutt_attach.c:916
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1687
FILE * fp
used in the recvattach menu.
Definition: attach.h:37
#define TYPE(X)
Definition: mime.h:82
static void pipe_attachment(FILE *fp, struct Body *b, struct State *state)
Pipe the attachment to a command.
Definition: recvattach.c:719
Mailcap print field.
Definition: mutt.h:178
#define STRING
Definition: string2.h:35
bool AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
struct Body * content
Definition: attach.h:36
int mutt_file_fclose(FILE **f)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
int rfc1524_mailcap_lookup(struct Body *a, char *type, struct Rfc1524MailcapEntry *entry, int opt)
Find given type in the list of mailcap files.
Definition: rfc1524.c:437
#define mutt_error(...)
Definition: logging.h:88
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:625
struct AttachPtr ** idx
Definition: attach.h:54
int mutt_print_attachment(FILE *fp, struct Body *a)
Print out an attachment.
Definition: mutt_attach.c:1014

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

937 {
938  char prompt[SHORT_STRING];
939  struct State state = { 0 };
940  int tagmsgcount = 0;
941 
942  if (tag)
943  for (int i = 0; i < actx->idxlen; i++)
944  if (actx->idx[i]->content->tagged)
945  tagmsgcount++;
946 
947  snprintf(prompt, sizeof(prompt),
948  /* L10N: Although we now the precise number of tagged messages, we
949  do not show it to the user. So feel free to use a "generic
950  plural" as plural translation if your language has one. */
951  tag ? ngettext("Print tagged attachment?", "Print %d tagged attachments?", tagmsgcount) :
952  _("Print attachment?"),
953  tagmsgcount);
954  if (query_quadoption(Print, prompt) != MUTT_YES)
955  return;
956 
957  if (!AttachSplit)
958  {
959  if (!can_print(actx, top, tag))
960  return;
961  mutt_endwin();
962  pid_t thepid = mutt_create_filter(NONULL(PrintCommand), &state.fpout, NULL, NULL);
963  print_attachment_list(actx, fp, tag, top, &state);
964  mutt_file_fclose(&state.fpout);
965  if (mutt_wait_filter(thepid) != 0 || WaitKey)
967  }
968  else
969  print_attachment_list(actx, fp, tag, top, &state);
970 }
#define NONULL(x)
Definition: string2.h:39
#define SHORT_STRING
Definition: string2.h:34
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:870
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
WHERE bool WaitKey
Config: Prompt to press a key after running external commands.
Definition: globals.h:262
WHERE unsigned char Print
Config: Confirm before printing a message.
Definition: globals.h:189
FILE * fpout
Definition: state.h:34
bool tagged
Definition: body.h:74
WHERE char * PrintCommand
Config: External command to print a message.
Definition: globals.h:139
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:498
int query_quadoption(int opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3227
static bool can_print(struct AttachCtx *actx, struct Body *top, bool tag)
Do we know how to print this attachment type?
Definition: recvattach.c:828
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:531
bool AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
struct Body * content
Definition: attach.h:36
int mutt_file_fclose(FILE **f)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
pid_t mutt_create_filter(const char *s, FILE **in, FILE **out, FILE **err)
Set up filter program.
Definition: filter.c:216
Keep track when processing files.
Definition: state.h:31
int mutt_wait_filter(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:227
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

978 {
979  if (!menu->tagprefix)
981  else
982  {
983  for (int i = 0; i < actx->idxlen; i++)
984  {
985  if (actx->idx[i]->content->tagged)
986  {
988  }
989  }
990  }
991 }
#define CURATTACH
Definition: recvattach.c:91
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:74
void crypt_pgp_extract_key_from_attachment(FILE *fp, struct Body *top)
Wrapper for CryptModuleSpecs::pgp_extract_key_from_attachment()
Definition: cryptglue.c:335
bool tagprefix
Definition: menu.h:67
FILE * fp
used in the recvattach menu.
Definition: attach.h:37
struct Body * content
Definition: attach.h:36
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

1002 {
1003  int rc = 0;
1004 
1005  if (!menu->tagprefix)
1006  rc = crypt_pgp_check_traditional(CURATTACH->fp, CURATTACH->content, true);
1007  else
1008  {
1009  for (int i = 0; i < actx->idxlen; i++)
1010  if (actx->idx[i]->content->tagged)
1011  rc = rc || crypt_pgp_check_traditional(actx->idx[i]->fp, actx->idx[i]->content, true);
1012  }
1013 
1014  return rc;
1015 }
#define CURATTACH
Definition: recvattach.c:91
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:74
bool tagprefix
Definition: menu.h:67
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:238
struct Body * content
Definition: attach.h:36
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

1025 {
1026  if (mutt_edit_content_type(e, CURATTACH->content, CURATTACH->fp) != 1)
1027  return;
1028 
1029  /* The mutt_update_recvattach_menu() will overwrite any changes
1030  * made to a decrypted CURATTACH->content, so warn the user. */
1031  if (CURATTACH->decrypted)
1032  {
1033  mutt_message(
1034  _("Structural changes to decrypted attachments are not supported"));
1035  mutt_sleep(1);
1036  }
1037  /* Editing the content type can rewrite the body structure. */
1038  for (int i = 0; i < actx->idxlen; i++)
1039  actx->idx[i]->content = NULL;
1040  mutt_actx_free_entries(actx);
1041  mutt_update_recvattach_menu(actx, menu, true);
1042 }
#define CURATTACH
Definition: recvattach.c:91
#define mutt_message(...)
Definition: logging.h:87
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1478
void mutt_actx_free_entries(struct AttachCtx *actx)
Free entries in an Attachment Context.
Definition: attach.c:94
static void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1261
struct Body * content
Definition: attach.h:36
int mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1106
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

1055 {
1056  do
1057  {
1058  switch (op)
1059  {
1060  case OP_DISPLAY_HEADERS:
1061  bool_str_toggle(Config, "weed", NULL);
1062  /* fallthrough */
1063 
1064  case OP_VIEW_ATTACH:
1065  op = mutt_view_attachment(CURATTACH->fp, CURATTACH->content, MUTT_REGULAR, e, actx);
1066  break;
1067 
1068  case OP_NEXT_ENTRY:
1069  case OP_MAIN_NEXT_UNDELETED: /* hack */
1070  if (menu->current < menu->max - 1)
1071  {
1072  menu->current++;
1073  op = OP_VIEW_ATTACH;
1074  }
1075  else
1076  op = OP_NULL;
1077  break;
1078  case OP_PREV_ENTRY:
1079  case OP_MAIN_PREV_UNDELETED: /* hack */
1080  if (menu->current > 0)
1081  {
1082  menu->current--;
1083  op = OP_VIEW_ATTACH;
1084  }
1085  else
1086  op = OP_NULL;
1087  break;
1088  case OP_EDIT_TYPE:
1089  /* when we edit the content-type, we should redisplay the attachment
1090  immediately */
1091  mutt_edit_content_type(e, CURATTACH->content, CURATTACH->fp);
1092  if (recv)
1093  recvattach_edit_content_type(actx, menu, e);
1094  else
1095  mutt_edit_content_type(e, CURATTACH->content, CURATTACH->fp);
1096 
1097  menu->redraw |= REDRAW_INDEX;
1098  op = OP_VIEW_ATTACH;
1099  break;
1100  /* functions which are passed through from the pager */
1101  case OP_CHECK_TRADITIONAL:
1103  {
1104  op = OP_NULL;
1105  break;
1106  }
1107  /* fallthrough */
1108  case OP_ATTACH_COLLAPSE:
1109  if (recv)
1110  return op;
1111  /* fallthrough */
1112  default:
1113  op = OP_NULL;
1114  }
1115  } while (op != OP_NULL);
1116 
1117  return op;
1118 }
#define CURATTACH
Definition: recvattach.c:91
int redraw
when to redraw the screen
Definition: menu.h:63
unsigned int security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:37
#define PGP_TRADITIONAL_CHECKED
Definition: ncrypt.h:132
WHERE struct ConfigSet * Config
Wrapper around the user&#39;s config settings.
Definition: globals.h:39
View using default method.
Definition: mutt.h:106
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:1023
int max
the number of entries in the menu
Definition: menu.h:62
#define APPLICATION_PGP
Definition: ncrypt.h:129
int mutt_view_attachment(FILE *fp, struct Body *a, int flag, struct Email *e, struct AttachCtx *actx)
View an attachment.
Definition: mutt_attach.c:383
int bool_str_toggle(struct ConfigSet *cs, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:247
int current
current entry
Definition: menu.h:61
int mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1106
#define WithCrypto
Definition: ncrypt.h:154

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void mutt_generate_recvattach_list ( struct AttachCtx actx,
struct Email e,
struct Body m,
FILE *  fp,
int  parent_type,
int  level,
bool  decrypted 
)
static

Create a list of attachments.

Parameters
actxAttachment context
eEmail
mBody of email
fpFile to read from
parent_typeType, e.g. TYPE_MULTIPART
levelAttachment depth
decryptedTrue if attachment has been decrypted

Definition at line 1130 of file recvattach.c.

1133 {
1134  struct AttachPtr *new = NULL;
1135  struct Body *new_body = NULL;
1136  FILE *new_fp = NULL;
1137  int need_secured, secured;
1138 
1139  for (; m; m = m->next)
1140  {
1141  need_secured = 0;
1142  secured = 0;
1143 
1145  {
1146  need_secured = 1;
1147 
1148  if (!crypt_valid_passphrase(APPLICATION_SMIME))
1149  goto decrypt_failed;
1150 
1151  if (e->env)
1153 
1154  secured = !crypt_smime_decrypt_mime(fp, &new_fp, m, &new_body);
1155 
1156  /* S/MIME nesting */
1157  if ((mutt_is_application_smime(new_body) & SMIME_OPAQUE) == SMIME_OPAQUE)
1158  {
1159  struct Body *outer_new_body = new_body;
1160  FILE *outer_fp = new_fp;
1161 
1162  new_body = NULL;
1163  new_fp = NULL;
1164 
1165  secured = !crypt_smime_decrypt_mime(outer_fp, &new_fp, outer_new_body, &new_body);
1166 
1167  mutt_body_free(&outer_new_body);
1168  mutt_file_fclose(&outer_fp);
1169  }
1170 
1171  if (secured)
1172  e->security |= SMIME_ENCRYPT;
1173  }
1174 
1175  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1177  {
1178  need_secured = 1;
1179 
1180  if (!crypt_valid_passphrase(APPLICATION_PGP))
1181  goto decrypt_failed;
1182 
1183  secured = !crypt_pgp_decrypt_mime(fp, &new_fp, m, &new_body);
1184 
1185  if (secured)
1186  e->security |= PGP_ENCRYPT;
1187  }
1188 
1189  if (need_secured && secured)
1190  {
1191  mutt_actx_add_fp(actx, new_fp);
1192  mutt_actx_add_body(actx, new_body);
1193  mutt_generate_recvattach_list(actx, e, new_body, new_fp, parent_type, level, 1);
1194  continue;
1195  }
1196 
1197  decrypt_failed:
1198  /* Fall through and show the original parts if decryption fails */
1199  if (need_secured && !secured)
1200  mutt_error(_("Can't decrypt encrypted message"));
1201 
1202  /* Strip out the top level multipart */
1203  if (m->type == TYPE_MULTIPART && m->parts && !need_secured &&
1204  (parent_type == -1 && mutt_str_strcasecmp("alternative", m->subtype)))
1205  {
1206  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level, decrypted);
1207  }
1208  else
1209  {
1210  new = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1211  mutt_actx_add_attach(actx, new);
1212 
1213  new->content = m;
1214  new->fp = fp;
1215  m->aptr = new;
1216  new->parent_type = parent_type;
1217  new->level = level;
1218  new->decrypted = decrypted;
1219 
1220  if (m->type == TYPE_MULTIPART)
1221  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level + 1, decrypted);
1222  else if (mutt_is_message_type(m->type, m->subtype))
1223  {
1224  mutt_generate_recvattach_list(actx, m->email, m->parts, fp, m->type,
1225  level + 1, decrypted);
1226  e->security |= m->email->security;
1227  }
1228  }
1229  }
1230 }
void mutt_actx_add_fp(struct AttachCtx *actx, FILE *new_fp)
Save a File handle to the Attachment Context.
Definition: attach.c:59
int mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:403
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
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:1214
unsigned int security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:37
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:57
void mutt_actx_add_attach(struct AttachCtx *actx, struct AttachPtr *attach)
Add an Attachment to an Attachment Context.
Definition: attach.c:40
int crypt_pgp_decrypt_mime(FILE *a, FILE **b, struct Body *c, struct Body **d)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:192
int mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:465
The body of an email.
Definition: body.h:33
#define SMIME_OPAQUE
Definition: ncrypt.h:144
int parent_type
Definition: attach.h:38
struct Envelope * env
envelope information
Definition: email.h:91
char * subtype
content-type subtype
Definition: body.h:36
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition: body.h:61
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition: cryptglue.c:406
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:58
unsigned int type
content-type primary type
Definition: body.h:67
#define APPLICATION_PGP
Definition: ncrypt.h:129
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:56
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
#define SMIME_ENCRYPT
Definition: ncrypt.h:140
int mutt_file_fclose(FILE **f)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
#define mutt_error(...)
Definition: logging.h:88
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:625
int crypt_valid_passphrase(int flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:144
int mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:569
static void mutt_generate_recvattach_list(struct AttachCtx *actx, struct Email *e, struct Body *m, FILE *fp, int parent_type, int level, bool decrypted)
Create a list of attachments.
Definition: recvattach.c:1130
int crypt_smime_decrypt_mime(FILE *a, FILE **b, struct Body *c, struct Body **d)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:373
struct Email * email
header information for message/rfc822
Definition: body.h:59
#define WithCrypto
Definition: ncrypt.h:154
#define PGP_ENCRYPT
Definition: ncrypt.h:134
void mutt_actx_add_body(struct AttachCtx *actx, struct Body *new_body)
Add an email box to an Attachment Context.
Definition: attach.c:77
#define APPLICATION_SMIME
Definition: ncrypt.h:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_attach_init ( struct AttachCtx actx)

Create a new Attachment context.

Parameters
actxAttachment context

Definition at line 1236 of file recvattach.c.

1237 {
1238  /* Collapse the attachments if '$digest_collapse' is set AND if...
1239  * the outer container is of type 'multipart/digest' */
1240  bool digest = (mutt_str_strcasecmp(actx->email->content->subtype, "digest") == 0);
1241 
1242  for (int i = 0; i < actx->idxlen; i++)
1243  {
1244  actx->idx[i]->content->tagged = false;
1245 
1246  /* OR an inner container is of type 'multipart/digest' */
1247  actx->idx[i]->content->collapsed =
1248  (DigestCollapse &&
1249  (digest ||
1250  ((actx->idx[i]->content->type == TYPE_MULTIPART) &&
1251  (mutt_str_strcasecmp(actx->idx[i]->content->subtype, "digest") == 0))));
1252  }
1253 }
struct Email * email
used by recvattach for updating
Definition: attach.h:51
struct Body * content
list of MIME parts
Definition: email.h:92
short idxlen
Definition: attach.h:55
bool DigestCollapse
Config: Hide the subparts of a multipart/digest.
Definition: recvattach.c:76
bool tagged
Definition: body.h:74
bool collapsed
used by recvattach
Definition: body.h:95
char * subtype
content-type subtype
Definition: body.h:36
unsigned int type
content-type primary type
Definition: body.h:67
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Definition: attach.h:36
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:625
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

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

1287 {
1288  int rindex, curlevel;
1289 
1290  CURATTACH->content->collapsed = !CURATTACH->content->collapsed;
1291  /* When expanding, expand all the children too */
1292  if (CURATTACH->content->collapsed)
1293  return;
1294 
1295  curlevel = CURATTACH->level;
1296  rindex = actx->v2r[menu->current] + 1;
1297 
1298  while ((rindex < actx->idxlen) && (actx->idx[rindex]->level > curlevel))
1299  {
1300  if (DigestCollapse && actx->idx[rindex]->content->type == TYPE_MULTIPART &&
1301  !mutt_str_strcasecmp(actx->idx[rindex]->content->subtype, "digest"))
1302  {
1303  actx->idx[rindex]->content->collapsed = true;
1304  }
1305  else
1306  {
1307  actx->idx[rindex]->content->collapsed = false;
1308  }
1309  rindex++;
1310  }
1311 }
#define CURATTACH
Definition: recvattach.c:91
bool DigestCollapse
Config: Hide the subparts of a multipart/digest.
Definition: recvattach.c:76
bool collapsed
used by recvattach
Definition: body.h:95
char * subtype
content-type subtype
Definition: body.h:36
unsigned int type
content-type primary type
Definition: body.h:67
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
short * v2r
mapping from virtual to real attachment
Definition: attach.h:58
struct Body * content
Definition: attach.h:36
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:625
int current
current entry
Definition: menu.h:61
int level
Definition: attach.h:40
struct AttachPtr ** idx
Definition: attach.h:54

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_view_attachments ( struct Email e)

Show the attachments in a Menu.

Parameters
eEmail

Definition at line 1317 of file recvattach.c.

1318 {
1319  char helpstr[LONG_STRING];
1320  struct Body *cur = NULL;
1321  int flags = 0;
1322  int op = OP_NULL;
1323 
1324  struct Mailbox *m = Context ? Context->mailbox : NULL;
1325 
1326  /* make sure we have parsed this message */
1328 
1330 
1331  struct Message *msg = mx_msg_open(m, e->msgno);
1332  if (!msg)
1333  return;
1334 
1335  struct Menu *menu = mutt_menu_new(MENU_ATTACH);
1336  menu->title = _("Attachments");
1338  menu->menu_tag = attach_tag;
1339  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_ATTACH, AttachHelp);
1340  mutt_menu_push_current(menu);
1341 
1342  struct AttachCtx *actx = mutt_mem_calloc(sizeof(struct AttachCtx), 1);
1343  actx->email = e;
1344  actx->root_fp = msg->fp;
1345  mutt_update_recvattach_menu(actx, menu, true);
1346 
1347  while (true)
1348  {
1349  if (op == OP_NULL)
1350  op = mutt_menu_loop(menu);
1351  if (!Context)
1352  return;
1353  switch (op)
1354  {
1355  case OP_ATTACH_VIEW_MAILCAP:
1356  mutt_view_attachment(CURATTACH->fp, CURATTACH->content, MUTT_MAILCAP, e, actx);
1357  menu->redraw = REDRAW_FULL;
1358  break;
1359 
1360  case OP_ATTACH_VIEW_TEXT:
1361  mutt_view_attachment(CURATTACH->fp, CURATTACH->content, MUTT_AS_TEXT, e, actx);
1362  menu->redraw = REDRAW_FULL;
1363  break;
1364 
1365  case OP_DISPLAY_HEADERS:
1366  case OP_VIEW_ATTACH:
1367  op = mutt_attach_display_loop(menu, op, e, actx, true);
1368  menu->redraw = REDRAW_FULL;
1369  continue;
1370 
1371  case OP_ATTACH_COLLAPSE:
1372  if (!CURATTACH->content->parts)
1373  {
1374  mutt_error(_("There are no subparts to show"));
1375  break;
1376  }
1377  attach_collapse(actx, menu);
1378  mutt_update_recvattach_menu(actx, menu, false);
1379  break;
1380 
1381  case OP_FORGET_PASSPHRASE:
1383  break;
1384 
1385  case OP_EXTRACT_KEYS:
1387  {
1388  recvattach_extract_pgp_keys(actx, menu);
1389  menu->redraw = REDRAW_FULL;
1390  }
1391  break;
1392 
1393  case OP_CHECK_TRADITIONAL:
1394  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1396  {
1397  e->security = crypt_query(cur);
1398  menu->redraw = REDRAW_FULL;
1399  }
1400  break;
1401 
1402  case OP_PRINT:
1404  CURATTACH->content);
1405  break;
1406 
1407  case OP_PIPE:
1409  CURATTACH->content, false);
1410  break;
1411 
1412  case OP_SAVE:
1414  CURATTACH->content, e, menu);
1415 
1416  if (!menu->tagprefix && Resolve && menu->current < menu->max - 1)
1417  menu->current++;
1418 
1420  break;
1421 
1422  case OP_DELETE:
1424 
1425 #ifdef USE_POP
1426  if (m->magic == MUTT_POP)
1427  {
1428  mutt_flushinp();
1429  mutt_error(_("Can't delete attachment from POP server"));
1430  break;
1431  }
1432 #endif
1433 
1434 #ifdef USE_NNTP
1435  if (m->magic == MUTT_NNTP)
1436  {
1437  mutt_flushinp();
1438  mutt_error(_("Can't delete attachment from news server"));
1439  break;
1440  }
1441 #endif
1442 
1443  if ((WithCrypto != 0) && (e->security & ENCRYPT))
1444  {
1445  mutt_message(_("Deletion of attachments from encrypted messages is "
1446  "unsupported"));
1447  break;
1448  }
1449  if ((WithCrypto != 0) && (e->security & (SIGN | PARTSIGN)))
1450  {
1451  mutt_message(_("Deletion of attachments from signed messages may "
1452  "invalidate the signature"));
1453  }
1454  if (!menu->tagprefix)
1455  {
1456  if (CURATTACH->parent_type == TYPE_MULTIPART)
1457  {
1458  CURATTACH->content->deleted = true;
1459  if (Resolve && menu->current < menu->max - 1)
1460  {
1461  menu->current++;
1462  menu->redraw = REDRAW_MOTION_RESYNCH;
1463  }
1464  else
1465  menu->redraw = REDRAW_CURRENT;
1466  }
1467  else
1468  {
1469  mutt_message(
1470  _("Only deletion of multipart attachments is supported"));
1471  }
1472  }
1473  else
1474  {
1475  for (int i = 0; i < menu->max; i++)
1476  {
1477  if (actx->idx[i]->content->tagged)
1478  {
1479  if (actx->idx[i]->parent_type == TYPE_MULTIPART)
1480  {
1481  actx->idx[i]->content->deleted = true;
1482  menu->redraw = REDRAW_INDEX;
1483  }
1484  else
1485  {
1486  mutt_message(
1487  _("Only deletion of multipart attachments is supported"));
1488  }
1489  }
1490  }
1491  }
1492  break;
1493 
1494  case OP_UNDELETE:
1496  if (!menu->tagprefix)
1497  {
1498  CURATTACH->content->deleted = false;
1499  if (Resolve && menu->current < menu->max - 1)
1500  {
1501  menu->current++;
1502  menu->redraw = REDRAW_MOTION_RESYNCH;
1503  }
1504  else
1505  menu->redraw = REDRAW_CURRENT;
1506  }
1507  else
1508  {
1509  for (int i = 0; i < menu->max; i++)
1510  {
1511  if (actx->idx[i]->content->tagged)
1512  {
1513  actx->idx[i]->content->deleted = false;
1514  menu->redraw = REDRAW_INDEX;
1515  }
1516  }
1517  }
1518  break;
1519 
1520  case OP_RESEND:
1521  CHECK_ATTACH;
1522  mutt_attach_resend(CURATTACH->fp, actx,
1523  menu->tagprefix ? NULL : CURATTACH->content);
1524  menu->redraw = REDRAW_FULL;
1525  break;
1526 
1527  case OP_BOUNCE_MESSAGE:
1528  CHECK_ATTACH;
1529  mutt_attach_bounce(CURATTACH->fp, actx,
1530  menu->tagprefix ? NULL : CURATTACH->content);
1531  menu->redraw = REDRAW_FULL;
1532  break;
1533 
1534  case OP_FORWARD_MESSAGE:
1535  CHECK_ATTACH;
1536  mutt_attach_forward(CURATTACH->fp, e, actx,
1537  menu->tagprefix ? NULL : CURATTACH->content, 0);
1538  menu->redraw = REDRAW_FULL;
1539  break;
1540 
1541 #ifdef USE_NNTP
1542  case OP_FORWARD_TO_GROUP:
1543  CHECK_ATTACH;
1544  mutt_attach_forward(CURATTACH->fp, e, actx,
1545  menu->tagprefix ? NULL : CURATTACH->content, SEND_NEWS);
1546  menu->redraw = REDRAW_FULL;
1547  break;
1548 
1549  case OP_FOLLOWUP:
1550  CHECK_ATTACH;
1551 
1552  if (!CURATTACH->content->email->env->followup_to ||
1553  (mutt_str_strcasecmp(CURATTACH->content->email->env->followup_to, "poster") != 0) ||
1555  _("Reply by mail as poster prefers?")) != MUTT_YES))
1556  {
1557  mutt_attach_reply(CURATTACH->fp, e, actx,
1558  menu->tagprefix ? NULL : CURATTACH->content,
1559  SEND_NEWS | SEND_REPLY);
1560  menu->redraw = REDRAW_FULL;
1561  break;
1562  }
1563 #endif
1564  /* fallthrough */
1565  case OP_REPLY:
1566  case OP_GROUP_REPLY:
1567  case OP_LIST_REPLY:
1568 
1569  CHECK_ATTACH;
1570 
1571  flags = SEND_REPLY | (op == OP_GROUP_REPLY ? SEND_GROUP_REPLY : 0) |
1572  (op == OP_LIST_REPLY ? SEND_LIST_REPLY : 0);
1573  mutt_attach_reply(CURATTACH->fp, e, actx,
1574  menu->tagprefix ? NULL : CURATTACH->content, flags);
1575  menu->redraw = REDRAW_FULL;
1576  break;
1577 
1578  case OP_COMPOSE_TO_SENDER:
1579  CHECK_ATTACH;
1580  mutt_attach_mail_sender(CURATTACH->fp, e, actx,
1581  menu->tagprefix ? NULL : CURATTACH->content);
1582  menu->redraw = REDRAW_FULL;
1583  break;
1584 
1585  case OP_EDIT_TYPE:
1586  recvattach_edit_content_type(actx, menu, e);
1587  menu->redraw |= REDRAW_INDEX;
1588  break;
1589 
1590  case OP_EXIT:
1591  mx_msg_close(m, &msg);
1592 
1593  e->attach_del = false;
1594  for (int i = 0; i < actx->idxlen; i++)
1595  {
1596  if (actx->idx[i]->content && actx->idx[i]->content->deleted)
1597  {
1598  e->attach_del = true;
1599  break;
1600  }
1601  }
1602  if (e->attach_del)
1603  e->changed = true;
1604 
1605  mutt_actx_free(&actx);
1606 
1607  mutt_menu_pop_current(menu);
1608  mutt_menu_destroy(&menu);
1609  return;
1610  }
1611 
1612  op = OP_NULL;
1613  }
1614 
1615  /* not reached */
1616 }
WHERE unsigned char FollowupToPoster
Config: (nntp) Reply to the poster if &#39;poster&#39; is in the &#39;Followup-To&#39; header.
Definition: globals.h:196
The "current" mailbox.
Definition: context.h:36
#define CURATTACH
Definition: recvattach.c:91
#define SIGN
Definition: ncrypt.h:120
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
int redraw
when to redraw the screen
Definition: menu.h:63
static const struct Mapping AttachHelp[]
Definition: recvattach.c:93
GUI selectable list of items.
Definition: menu.h:56
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:428
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: magic.h:41
#define mutt_message(...)
Definition: logging.h:87
unsigned int security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:37
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
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:753
void mutt_attach_reply(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur, int flags)
Attach a reply.
Definition: recvcmd.c:894
bool attach_del
has an attachment marked for deletion
Definition: email.h:47
void crypt_forget_passphrase(void)
Forget a passphrase and display a message.
Definition: crypt.c:102
#define _(a)
Definition: message.h:28
bool changed
Definition: email.h:46
void mutt_attach_bounce(FILE *fp, struct AttachCtx *actx, struct Body *cur)
Bounce function, from the attachment menu.
Definition: recvcmd.c:163
short idxlen
Definition: attach.h:55
#define MUTT_MESSAGE_HOOK
Definition: hook.h:48
int menu
menu definition for keymap entries.
Definition: menu.h:64
#define LONG_STRING
Definition: string2.h:36
void(* menu_make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: menu.h:96
The body of an email.
Definition: body.h:33
char * mutt_compile_help(char *buf, size_t buflen, int menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:115
int attach_tag(struct Menu *menu, int sel, int act)
Tag an attachment - Implements Menu::menu_tag()
Definition: recvattach.c:440
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1187
Select an attachment.
Definition: keymap.h:68
struct Mailbox * mailbox
Definition: context.h:50
enum MailboxType magic
mailbox type
Definition: mailbox.h:99
int parent_type
Definition: attach.h:38
void mutt_parse_mime_message(struct Mailbox *m, struct Email *cur)
Parse a MIME email.
Definition: mutt_parse.c:50
WHERE bool Resolve
Config: Move to the next email whenever a command modifies an email.
Definition: globals.h:248
#define SEND_LIST_REPLY
Definition: send.h:84
bool tagged
Definition: body.h:74
void mutt_attach_forward(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur, int flags)
Forward an Attachment.
Definition: recvcmd.c:742
void mutt_actx_free(struct AttachCtx **pactx)
Free an Attachment Context.
Definition: attach.c:119
#define ENCRYPT
Definition: ncrypt.h:119
#define PARTSIGN
Definition: ncrypt.h:123
A local copy of an email.
Definition: mx.h:81
A mailbox.
Definition: mailbox.h:76
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:1023
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:1053
int query_quadoption(int opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3227
bool tagprefix
Definition: menu.h:67
static void recvattach_extract_pgp_keys(struct AttachCtx *actx, struct Menu *menu)
Extract PGP keys from attachments.
Definition: recvattach.c:977
static void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1261
FILE * root_fp
used by recvattach for updating
Definition: attach.h:52
#define SEND_NEWS
Definition: send.h:95
static int recvattach_pgp_check_traditional(struct AttachCtx *actx, struct Menu *menu)
Is the Attachment inline PGP?
Definition: recvattach.c:1001
#define SEND_REPLY
Definition: send.h:82
#define CHECK_READONLY
Definition: recvattach.c:83
int max
the number of entries in the menu
Definition: menu.h:62
int(* menu_tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: menu.h:113
#define APPLICATION_PGP
Definition: ncrypt.h:129
void mutt_print_attachment_list(struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
Print a list of Attachments.
Definition: recvattach.c:936
char * title
the title of this menu
Definition: menu.h:58
bool deleted
attachment marked for deletion
Definition: body.h:75
static void attach_collapse(struct AttachCtx *actx, struct Menu *menu)
Close the tree of the current attachment.
Definition: recvattach.c:1286
Force viewing using mailcap entry.
Definition: mutt.h:107
#define SEND_GROUP_REPLY
Definition: send.h:83
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
int crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:647
struct Body * content
Definition: attach.h:36
#define mutt_error(...)
Definition: logging.h:88
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:625
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:583
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:1053
int mutt_view_attachment(FILE *fp, struct Body *a, int flag, struct Email *e, struct AttachCtx *actx)
View an attachment.
Definition: mutt_attach.c:383
int current
current entry
Definition: menu.h:61
#define CHECK_ATTACH
Definition: recvattach.c:101
void mutt_message_hook(struct Mailbox *m, struct Email *e, int type)
Perform a message hook.
Definition: hook.c:438
#define WithCrypto
Definition: ncrypt.h:154
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Definition: attach.h:54
void mutt_attach_resend(FILE *fp, struct AttachCtx *actx, struct Body *cur)
resend-message, from the attachment menu
Definition: recvcmd.c:283
char * help
quickref for the current menu
Definition: menu.h:59
Force viewing as text.
Definition: mutt.h:108
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1139
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:786
int msgno
number displayed to the user
Definition: email.h:88
&#39;POP3&#39; Mailbox type
Definition: magic.h:44

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

char* AttachSaveDir

Config: Default directory where attachments are saved.

Definition at line 73 of file recvattach.c.

char* AttachSep

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

Definition at line 74 of file recvattach.c.

bool AttachSplit

Config: Save/print/pipe tagged messages individually.

Definition at line 75 of file recvattach.c.

bool DigestCollapse

Config: Hide the subparts of a multipart/digest.

Definition at line 76 of file recvattach.c.

char* MessageFormat

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

Definition at line 77 of file recvattach.c.

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

Definition at line 81 of file recvattach.c.

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

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