NeoMutt  2018-07-16 +1360-3df4a2
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 "mutt_attach.h"
#include "mutt_logging.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 "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, 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 (char *buf, size_t bufsize)
 Add C_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 *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_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

#define CHECK_READONLY
Value:
{ \
break; \
}
The "current" mailbox.
Definition: context.h:37
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:51
bool readonly
don&#39;t allow changes to the mailbox
Definition: mailbox.h:120
#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 1268 of file recvattach.c.

1269 {
1270  if (init)
1271  {
1272  mutt_generate_recvattach_list(actx, actx->email, actx->email->content,
1273  actx->fp_root, -1, 0, 0);
1274  mutt_attach_init(actx);
1275  menu->data = actx;
1276  }
1277 
1278  mutt_update_tree(actx);
1279 
1280  menu->max = actx->vcount;
1281 
1282  if (menu->current >= menu->max)
1283  menu->current = menu->max - 1;
1284  menu_check_recenter(menu);
1285  menu->redraw |= REDRAW_INDEX;
1286 }
struct Email * email
used by recvattach for updating
Definition: attach.h:51
struct Body * content
list of MIME parts
Definition: email.h:93
FILE * fp_root
used by recvattach for updating
Definition: attach.h:52
static 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:1135
void mutt_attach_init(struct AttachCtx *actx)
Create a new Attachment context.
Definition: recvattach.c:1243
int max
the 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:

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:98
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[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:58
Right arrow.
Definition: mutt_menu.h:67
char * tree
Definition: attach.h:39
static void mutt_update_v2r(struct AttachCtx *actx)
Update the virtual list of attachments.
Definition: recvattach.c:115
int num
Definition: attach.h:41
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:459
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383
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
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:611
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:

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  int 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 = 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  C_MessageFormat && aptr->content->email)
259  {
260  char s[128];
261  mutt_make_string_flags(s, sizeof(s), C_MessageFormat, NULL, NULL,
262  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 = 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(LL_DEBUG1, "ERROR: invalid content-disposition %d\n",
336  aptr->content->disposition);
337  ch = '!';
338  }
339  snprintf(buf, buflen, "%c", ch);
340  }
341  break;
342  case 'm':
343  if (!optional)
344  mutt_format_s(buf, buflen, prec, TYPE(aptr->content));
345  break;
346  case 'M':
347  if (!optional)
348  mutt_format_s(buf, buflen, prec, aptr->content->subtype);
349  else if (!aptr->content->subtype)
350  optional = 0;
351  break;
352  case 'n':
353  if (!optional)
354  {
355  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
356  snprintf(buf, buflen, fmt, aptr->num + 1);
357  }
358  break;
359  case 'Q':
360  if (optional)
361  optional = aptr->content->attach_qualifies;
362  else
363  {
364  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
365  mutt_format_s(buf, buflen, fmt, "Q");
366  }
367  break;
368  case 's':
369  {
370  size_t l;
371  if (flags & MUTT_FORMAT_STAT_FILE)
372  {
373  struct stat st;
374  stat(aptr->content->filename, &st);
375  l = st.st_size;
376  }
377  else
378  l = aptr->content->length;
379 
380  if (!optional)
381  {
382  char tmp[128];
383  mutt_str_pretty_size(tmp, sizeof(tmp), l);
384  mutt_format_s(buf, buflen, prec, tmp);
385  }
386  else if (l == 0)
387  optional = 0;
388 
389  break;
390  }
391  case 't':
392  if (!optional)
393  snprintf(buf, buflen, "%c", aptr->content->tagged ? '*' : ' ');
394  else if (!aptr->content->tagged)
395  optional = 0;
396  break;
397  case 'T':
398  if (!optional)
399  mutt_format_s_tree(buf, buflen, prec, NONULL(aptr->tree));
400  else if (!aptr->tree)
401  optional = 0;
402  break;
403  case 'u':
404  if (!optional)
405  snprintf(buf, buflen, "%c", aptr->content->unlink ? '-' : ' ');
406  else if (!aptr->content->unlink)
407  optional = 0;
408  break;
409  case 'X':
410  if (optional)
411  optional = (aptr->content->attach_count + aptr->content->attach_qualifies) != 0;
412  else
413  {
414  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
415  snprintf(buf, buflen, fmt, aptr->content->attach_count + aptr->content->attach_qualifies);
416  }
417  break;
418  default:
419  *buf = '\0';
420  }
421 
422  if (optional)
423  mutt_expando_format(buf, buflen, col, cols, if_str, attach_format_str, data, 0);
424  else if (flags & MUTT_FORMAT_OPTIONAL)
425  mutt_expando_format(buf, buflen, col, cols, else_str, attach_format_str, data, 0);
426  return src;
427 }
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:811
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:48
#define NONULL(x)
Definition: string2.h:36
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:77
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1255
void mutt_pretty_mailbox(char *s, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:605
#define MUTT_FORMAT_FORCESUBJ
Print the subject even if unchanged.
Definition: format_flags.h:31
#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:80
#define MUTT_FORMAT_STAT_FILE
Used by attach_format_str.
Definition: format_flags.h:34
unsigned int disposition
content-disposition
Definition: body.h:72
char * tree
Definition: attach.h:39
bool attach_qualifies
Definition: body.h:99
#define ENCODING(x)
Definition: mime.h:85
void mutt_make_string_flags(char *buf, size_t buflen, const char *s, struct Context *ctx, struct Mailbox *m, struct Email *e, MuttFormatFlags flags)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1466
signed short attach_count
Definition: body.h:64
bool tagged
Definition: body.h:77
unsigned int encoding
content-transfer-encoding
Definition: body.h:71
char * subtype
content-type subtype
Definition: body.h:37
LOFF_T length
length (in bytes) of attachment
Definition: body.h:47
#define PATH_MAX
Definition: mutt.h:48
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:741
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:40
bool mutt_is_text_part(struct Body *b)
Is this part of an email in plain text?
Definition: muttlib.c:427
unsigned int type
content-type primary type
Definition: body.h:70
bool deleted
attachment marked for deletion
Definition: body.h:78
#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:1061
Log at debug level 1.
Definition: logging.h:56
struct Body * content
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
flag to indicate the file named by "filename" should be unlink()ed before free()ing this structure ...
Definition: body.h:74
#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:50
#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:1014
struct Email * email
header information for message/rfc822
Definition: body.h:60
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

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

433 {
434  struct AttachCtx *actx = menu->data;
435 
437  attach_format_str, (unsigned long) (actx->idx[actx->v2r[line]]),
439 }
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:811
#define NONULL(x)
Definition: string2.h:36
WHERE char * C_AttachFormat
Config: printf-like format string for the attachment menu.
Definition: globals.h:106
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
const char * line
Definition: common.c:35
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
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
Definition: attach.h:54

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

445 {
446  struct AttachCtx *actx = menu->data;
447  struct Body *cur = actx->idx[actx->v2r[sel]]->content;
448  bool ot = cur->tagged;
449 
450  cur->tagged = ((act >= 0) ? act : !cur->tagged);
451  return cur->tagged - ot;
452 }
The body of an email.
Definition: body.h:34
bool tagged
Definition: body.h:77
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: mutt_menu.h:86
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 C_AttachSaveDir to the beginning of a path.

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

Definition at line 459 of file recvattach.c.

460 {
461  const char *savedir = C_AttachSaveDir;
462 
463  if (!savedir || !*savedir)
464  savedir = "./";
465 
466  size_t savedirlen = strlen(savedir);
467  size_t buflen = strlen(buf);
468  bool addsep = (savedir[savedirlen - 1] != '/');
469  size_t newbuflen = savedirlen + buflen + addsep;
470 
471  if (bufsize < newbuflen)
472  {
473  return;
474  }
475 
476  memmove(buf + savedirlen + addsep, buf, buflen);
477  memcpy(buf, savedir, savedirlen);
478  if (addsep)
479  {
480  buf[savedirlen] = '/';
481  }
482  buf[newbuflen] = '\0';
483 }
char * C_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 494 of file recvattach.c.

495 {
496  char *prompt = NULL;
497  char buf[PATH_MAX], tfile[PATH_MAX];
498  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
499  int rc;
500 
501  if (body->filename)
502  {
503  if (directory && *directory)
504  {
505  mutt_path_concat(buf, *directory, mutt_path_basename(body->filename), sizeof(buf));
506  }
507  else
508  mutt_str_strfcpy(buf, body->filename, sizeof(buf));
509  }
510  else if (body->email && (body->encoding != ENC_BASE64) &&
511  (body->encoding != ENC_QUOTED_PRINTABLE) &&
512  mutt_is_message_type(body->type, body->subtype))
513  {
514  mutt_default_save(buf, sizeof(buf), body->email);
515  }
516  else
517  buf[0] = '\0';
518 
519  prepend_savedir(buf, sizeof(buf));
520 
521  prompt = _("Save to file: ");
522  while (prompt)
523  {
524  if ((mutt_get_field(prompt, buf, sizeof(buf), MUTT_FILE) != 0) || (buf[0] == '\0'))
525  {
527  return -1;
528  }
529 
530  prompt = NULL;
531  mutt_expand_path(buf, sizeof(buf));
532 
533  bool is_message = (fp && body->email && (body->encoding != ENC_BASE64) &&
534  (body->encoding != ENC_QUOTED_PRINTABLE) &&
535  mutt_is_message_type(body->type, body->subtype));
536 
537  if (is_message)
538  {
539  struct stat st;
540 
541  /* check to make sure that this file is really the one the user wants */
542  rc = mutt_save_confirm(buf, &st);
543  if (rc == 1)
544  {
545  prompt = _("Save to file: ");
546  continue;
547  }
548  else if (rc == -1)
549  return -1;
550  mutt_str_strfcpy(tfile, buf, sizeof(tfile));
551  }
552  else
553  {
554  rc = mutt_check_overwrite(body->filename, buf, tfile, sizeof(tfile), &opt, directory);
555  if (rc == -1)
556  return -1;
557  else if (rc == 1)
558  {
559  prompt = _("Save to file: ");
560  continue;
561  }
562  }
563 
564  mutt_message(_("Saving..."));
565  if (mutt_save_attachment(fp, body, tfile, opt, (e || !is_message) ? e : body->email) == 0)
566  {
567  mutt_message(_("Attachment saved"));
568  return 0;
569  }
570  else
571  {
572  prompt = _("Save to file: ");
573  continue;
574  }
575  }
576  return 0;
577 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:48
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1255
const char * mutt_path_basename(const char *f)
Find the last component for a pathname.
Definition: path.c:304
#define mutt_message(...)
Definition: logging.h:87
No flags set.
Definition: mutt_attach.h:54
#define _(a)
Definition: message.h:28
static void prepend_savedir(char *buf, size_t bufsize)
Add C_AttachSaveDir to the beginning of a path.
Definition: recvattach.c:459
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:525
int mutt_save_confirm(const char *s, struct stat *st)
Ask the user to save.
Definition: muttlib.c:1377
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:77
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:71
Base-64 encoded text.
Definition: mime.h:52
int mutt_check_overwrite(const char *attname, const char *path, char *fname, size_t flen, enum SaveAttach *opt, char **directory)
Ask the user if overwriting is necessary.
Definition: muttlib.c:684
char * subtype
content-type subtype
Definition: body.h:37
#define PATH_MAX
Definition: mutt.h:48
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:741
int mutt_save_attachment(FILE *fp, struct Body *m, char *path, enum SaveAttach opt, struct Email *e)
Save an attachment.
Definition: mutt_attach.c:783
#define MUTT_FILE
Do file completion.
Definition: mutt.h:62
unsigned int type
content-type primary type
Definition: body.h:70
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:324
struct Email * email
header information for message/rfc822
Definition: body.h:60
SaveAttach
Options for saving attachments.
Definition: mutt_attach.h:52

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

590 {
591  char buf[PATH_MAX], tfile[PATH_MAX];
592  char *directory = NULL;
593  int rc = 1;
594  int last = menu ? menu->current : -1;
595  FILE *fp_out = NULL;
596 
597  buf[0] = '\0';
598 
599  for (int i = 0; !tag || (i < actx->idxlen); i++)
600  {
601  if (tag)
602  {
603  fp = actx->idx[i]->fp;
604  top = actx->idx[i]->content;
605  }
606  if (!tag || top->tagged)
607  {
608  if (!C_AttachSplit)
609  {
610  if (buf[0] == '\0')
611  {
612  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
613 
614  mutt_str_strfcpy(buf, mutt_path_basename(NONULL(top->filename)), sizeof(buf));
615  prepend_savedir(buf, sizeof(buf));
616 
617  if ((mutt_get_field(_("Save to file: "), buf, sizeof(buf), MUTT_FILE) != 0) ||
618  !buf[0])
619  {
620  return;
621  }
622  mutt_expand_path(buf, sizeof(buf));
623  if (mutt_check_overwrite(top->filename, buf, tfile, sizeof(tfile), &opt, NULL))
624  return;
625  rc = mutt_save_attachment(fp, top, tfile, opt, e);
626  if ((rc == 0) && C_AttachSep && (fp_out = fopen(tfile, "a")))
627  {
628  fprintf(fp_out, "%s", C_AttachSep);
629  mutt_file_fclose(&fp_out);
630  }
631  }
632  else
633  {
634  rc = mutt_save_attachment(fp, top, tfile, MUTT_SAVE_APPEND, e);
635  if ((rc == 0) && C_AttachSep && (fp_out = fopen(tfile, "a")))
636  {
637  fprintf(fp_out, "%s", C_AttachSep);
638  mutt_file_fclose(&fp_out);
639  }
640  }
641  }
642  else
643  {
644  if (tag && menu && top->aptr)
645  {
646  menu->oldcurrent = menu->current;
647  menu->current = top->aptr->num;
648  menu_check_recenter(menu);
649  menu->redraw |= REDRAW_MOTION;
650 
651  menu_redraw(menu);
652  }
653  if (query_save_attachment(fp, top, e, &directory) == -1)
654  break;
655  }
656  }
657  if (!tag)
658  break;
659  }
660 
661  FREE(&directory);
662 
663  if (tag && menu)
664  {
665  menu->oldcurrent = menu->current;
666  menu->current = last;
667  menu_check_recenter(menu);
668  menu->redraw |= REDRAW_MOTION;
669  }
670 
671  if (!C_AttachSplit && (rc == 0))
672  mutt_message(_("Attachment saved"));
673 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:48
#define NONULL(x)
Definition: string2.h:36
const char * mutt_path_basename(const char *f)
Find the last component for a pathname.
Definition: path.c:304
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
#define mutt_message(...)
Definition: logging.h:87
int oldcurrent
for driver use only
Definition: mutt_menu.h:110
No flags set.
Definition: mutt_attach.h:54
char * C_AttachSep
Config: Separator to add between saved/printed/piped attachments.
Definition: recvattach.c:74
#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:494
static void prepend_savedir(char *buf, size_t bufsize)
Add C_AttachSaveDir to the beginning of a path.
Definition: recvattach.c:459
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:77
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:157
bool tagged
Definition: body.h:77
#define REDRAW_MOTION
Redraw after moving the menu list.
Definition: mutt_menu.h:43
int mutt_check_overwrite(const char *attname, const char *path, char *fname, size_t flen, enum SaveAttach *opt, char **directory)
Ask the user if overwriting is necessary.
Definition: muttlib.c:684
#define PATH_MAX
Definition: mutt.h:48
int num
Definition: attach.h:41
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition: body.h:62
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:741
FILE * fp
used in the recvattach menu.
Definition: attach.h:37
int mutt_save_attachment(FILE *fp, struct Body *m, char *path, enum SaveAttach opt, struct Email *e)
Save an attachment.
Definition: mutt_attach.c:783
#define MUTT_FILE
Do file completion.
Definition: mutt.h:62
MuttRedrawFlags redraw
when to redraw the screen
Definition: mutt_menu.h:89
struct Body * content
Definition: attach.h:36
Append to existing file.
Definition: mutt_attach.h:55
#define FREE(x)
Definition: memory.h:40
int current
current entry
Definition: mutt_menu.h:87
struct AttachPtr ** idx
Definition: attach.h:54
SaveAttach
Options for saving attachments.
Definition: mutt_attach.h:52

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

683 {
684  char tfile[PATH_MAX];
685 
686  if (filter)
687  {
688  char warning[PATH_MAX + 256];
689  snprintf(warning, sizeof(warning),
690  _("WARNING! You are about to overwrite %s, continue?"), body->filename);
691  if (mutt_yesorno(warning, MUTT_NO) != MUTT_YES)
692  {
694  return;
695  }
696  mutt_mktemp(tfile, sizeof(tfile));
697  }
698  else
699  tfile[0] = '\0';
700 
701  if (mutt_pipe_attachment(fp, body, command, tfile))
702  {
703  if (filter)
704  {
705  mutt_file_unlink(body->filename);
706  mutt_file_rename(tfile, body->filename);
707  mutt_update_encoding(body);
708  mutt_message(_("Attachment filtered"));
709  }
710  }
711  else
712  {
713  if (filter && tfile[0])
714  mutt_file_unlink(tfile);
715  }
716 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:48
#define mutt_message(...)
Definition: logging.h:87
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:191
#define _(a)
Definition: message.h:28
int mutt_file_rename(const char *oldfile, const char *newfile)
Rename a file.
Definition: file.c:1238
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:330
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(buf, buflen)
Definition: muttlib.h:72
#define PATH_MAX
Definition: mutt.h:48
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
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:666

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

725 {
726  if (!state || !state->fp_out)
727  return;
728 
729  if (fp)
730  {
731  state->fp_in = fp;
732  mutt_decode_attachment(b, state);
733  if (C_AttachSep)
734  state_puts(C_AttachSep, state);
735  }
736  else
737  {
738  FILE *fp_in = fopen(b->filename, "r");
739  if (!fp_in)
740  {
741  mutt_perror("fopen");
742  return;
743  }
744  mutt_file_copy_stream(fp_in, state->fp_out);
745  mutt_file_fclose(&fp_in);
746  if (C_AttachSep)
747  state_puts(C_AttachSep, state);
748  }
749 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1748
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:48
#define mutt_perror(...)
Definition: logging.h:89
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
char * C_AttachSep
Config: Separator to add between saved/printed/piped attachments.
Definition: recvattach.c:74
FILE * fp_out
File to write to.
Definition: state.h:47
FILE * fp_in
File to read from.
Definition: state.h:46
#define state_puts(str, state)
Definition: state.h:54
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:263

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

763 {
764  for (int i = 0; !tag || (i < actx->idxlen); i++)
765  {
766  if (tag)
767  {
768  fp = actx->idx[i]->fp;
769  top = actx->idx[i]->content;
770  }
771  if (!tag || top->tagged)
772  {
773  if (!filter && !C_AttachSplit)
774  pipe_attachment(fp, top, state);
775  else
776  query_pipe_attachment(command, fp, top, filter);
777  }
778  if (!tag)
779  break;
780  }
781 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:77
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:682
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:724
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 791 of file recvattach.c.

793 {
794  struct State state = { 0 };
795  char buf[128];
796 
797  if (fp)
798  filter = false; /* sanity check: we can't filter in the recv case yet */
799 
800  buf[0] = '\0';
801  /* perform charset conversion on text attachments when piping */
802  state.flags = MUTT_CHARCONV;
803 
804  if ((mutt_get_field((filter ? _("Filter through: ") : _("Pipe to: ")), buf,
805  sizeof(buf), MUTT_CMD) != 0) ||
806  (buf[0] == '\0'))
807  {
808  return;
809  }
810 
811  mutt_expand_path(buf, sizeof(buf));
812 
813  if (!filter && !C_AttachSplit)
814  {
815  mutt_endwin();
816  pid_t pid = mutt_create_filter(buf, &state.fp_out, NULL, NULL);
817  pipe_attachment_list(buf, actx, fp, tag, top, filter, &state);
818  mutt_file_fclose(&state.fp_out);
819  if ((mutt_wait_filter(pid) != 0) || C_WaitKey)
821  }
822  else
823  pipe_attachment_list(buf, actx, fp, tag, top, filter, &state);
824 }
pid_t mutt_create_filter(const char *s, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:216
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
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:761
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
#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:77
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:157
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:64
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: globals.h:266
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:497
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:530
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: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 833 of file recvattach.c.

834 {
835  char type[256];
836 
837  for (int i = 0; !tag || (i < actx->idxlen); i++)
838  {
839  if (tag)
840  top = actx->idx[i]->content;
841  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
842  if (!tag || top->tagged)
843  {
844  if (!rfc1524_mailcap_lookup(top, type, NULL, MUTT_MC_PRINT))
845  {
846  if ((mutt_str_strcasecmp("text/plain", top->subtype) != 0) &&
847  (mutt_str_strcasecmp("application/postscript", top->subtype) != 0))
848  {
849  if (!mutt_can_decode(top))
850  {
851  /* L10N: s gets replaced by a MIME type, e.g. "text/plain" or
852  application/octet-stream. */
853  mutt_error(_("I don't know how to print %s attachments"), type);
854  return false;
855  }
856  }
857  }
858  }
859  if (!tag)
860  break;
861  }
862  return true;
863 }
bool rfc1524_mailcap_lookup(struct Body *a, char *type, struct Rfc1524MailcapEntry *entry, enum MailcapLookup opt)
Find given type in the list of mailcap files.
Definition: rfc1524.c:437
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
Mailcap print field.
Definition: rfc1524.h:60
bool tagged
Definition: body.h:77
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:1707
#define TYPE(body)
Definition: mime.h:83
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:624
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 873 of file recvattach.c.

875 {
876  char type[256];
877 
878  for (int i = 0; !tag || (i < actx->idxlen); i++)
879  {
880  if (tag)
881  {
882  fp = actx->idx[i]->fp;
883  top = actx->idx[i]->content;
884  }
885  if (!tag || top->tagged)
886  {
887  snprintf(type, sizeof(type), "%s/%s", TYPE(top), top->subtype);
888  if (!C_AttachSplit && !rfc1524_mailcap_lookup(top, type, NULL, MUTT_MC_PRINT))
889  {
890  if ((mutt_str_strcasecmp("text/plain", top->subtype) == 0) ||
891  (mutt_str_strcasecmp("application/postscript", top->subtype) == 0))
892  {
893  pipe_attachment(fp, top, state);
894  }
895  else if (mutt_can_decode(top))
896  {
897  /* decode and print */
898 
899  char newfile[PATH_MAX] = "";
900  FILE *fp_in = NULL;
901 
902  mutt_mktemp(newfile, sizeof(newfile));
903  if (mutt_decode_save_attachment(fp, top, newfile, MUTT_PRINTING,
904  MUTT_SAVE_NO_FLAGS) == 0)
905  {
906  if (!state->fp_out)
907  {
908  mutt_error(
909  "BUG in print_attachment_list(). Please report this. ");
910  return;
911  }
912 
913  fp_in = fopen(newfile, "r");
914  if (fp_in)
915  {
916  mutt_file_copy_stream(fp_in, state->fp_out);
917  mutt_file_fclose(&fp_in);
918  if (C_AttachSep)
919  state_puts(C_AttachSep, state);
920  }
921  }
922  mutt_file_unlink(newfile);
923  }
924  }
925  else
926  mutt_print_attachment(fp, top);
927  }
928  if (!tag)
929  break;
930  }
931 }
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
bool rfc1524_mailcap_lookup(struct Body *a, char *type, struct Rfc1524MailcapEntry *entry, enum MailcapLookup opt)
Find given type in the list of mailcap files.
Definition: rfc1524.c:437
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
No flags set.
Definition: mutt_attach.h:54
char * C_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:191
short idxlen
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
Mailcap print field.
Definition: rfc1524.h:60
bool tagged
Definition: body.h:77
char * subtype
content-type subtype
Definition: body.h:37
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:72
#define PATH_MAX
Definition: mutt.h:48
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1707
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:724
#define TYPE(body)
Definition: mime.h:83
#define state_puts(str, state)
Definition: state.h:54
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:624
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:263
struct AttachPtr ** idx
Definition: attach.h:54
int mutt_decode_save_attachment(FILE *fp, struct Body *m, char *path, int displaying, enum SaveAttach opt)
Decode, then save an attachment.
Definition: mutt_attach.c:913
int mutt_print_attachment(FILE *fp, struct Body *a)
Print out an attachment.
Definition: mutt_attach.c:1012

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

941 {
942  char prompt[128];
943  struct State state = { 0 };
944  int tagmsgcount = 0;
945 
946  if (tag)
947  for (int i = 0; i < actx->idxlen; i++)
948  if (actx->idx[i]->content->tagged)
949  tagmsgcount++;
950 
951  snprintf(prompt, sizeof(prompt),
952  /* L10N: Although we now the precise number of tagged messages, we
953  do not show it to the user. So feel free to use a "generic
954  plural" as plural translation if your language has one. */
955  tag ? ngettext("Print tagged attachment?", "Print %d tagged attachments?", tagmsgcount) :
956  _("Print attachment?"),
957  tagmsgcount);
958  if (query_quadoption(C_Print, prompt) != MUTT_YES)
959  return;
960 
961  if (!C_AttachSplit)
962  {
963  if (!can_print(actx, top, tag))
964  return;
965  mutt_endwin();
966  pid_t pid = mutt_create_filter(NONULL(C_PrintCommand), &state.fp_out, NULL, NULL);
967  print_attachment_list(actx, fp, tag, top, &state);
968  mutt_file_fclose(&state.fp_out);
969  if ((mutt_wait_filter(pid) != 0) || C_WaitKey)
971  }
972  else
973  print_attachment_list(actx, fp, tag, top, &state);
974 }
pid_t mutt_create_filter(const char *s, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:216
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
#define NONULL(x)
Definition: string2.h:36
WHERE unsigned char C_Print
Config: Confirm before printing a message.
Definition: globals.h:192
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3369
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:873
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
FILE * fp_out
File to write to.
Definition: state.h:47
bool tagged
Definition: body.h:77
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: globals.h:266
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:497
static bool can_print(struct AttachCtx *actx, struct Body *top, bool tag)
Do we know how to print this attachment type?
Definition: recvattach.c:833
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:530
struct Body * content
Definition: attach.h:36
WHERE char * C_PrintCommand
Config: External command to print a message.
Definition: globals.h:142
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: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 981 of file recvattach.c.

982 {
983  if (!menu->tagprefix)
985  else
986  {
987  for (int i = 0; i < actx->idxlen; i++)
988  {
989  if (actx->idx[i]->content->tagged)
990  {
992  }
993  }
994  }
995 }
#define CURATTACH
Definition: recvattach.c:91
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:77
void crypt_pgp_extract_key_from_attachment(FILE *fp, struct Body *top)
Wrapper for CryptModuleSpecs::pgp_extract_key_from_attachment()
Definition: cryptglue.c:334
bool tagprefix
Definition: mutt_menu.h:93
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 1005 of file recvattach.c.

1006 {
1007  int rc = 0;
1008 
1009  if (!menu->tagprefix)
1010  rc = crypt_pgp_check_traditional(CURATTACH->fp, CURATTACH->content, true);
1011  else
1012  {
1013  for (int i = 0; i < actx->idxlen; i++)
1014  if (actx->idx[i]->content->tagged)
1015  rc = rc || crypt_pgp_check_traditional(actx->idx[i]->fp, actx->idx[i]->content, true);
1016  }
1017 
1018  return rc;
1019 }
#define CURATTACH
Definition: recvattach.c:91
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:77
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:237
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 1027 of file recvattach.c.

1029 {
1030  if (!mutt_edit_content_type(e, CURATTACH->content, CURATTACH->fp))
1031  return;
1032 
1033  /* The mutt_update_recvattach_menu() will overwrite any changes
1034  * made to a decrypted CURATTACH->content, so warn the user. */
1035  if (CURATTACH->decrypted)
1036  {
1037  mutt_message(
1038  _("Structural changes to decrypted attachments are not supported"));
1039  mutt_sleep(1);
1040  }
1041  /* Editing the content type can rewrite the body structure. */
1042  for (int i = 0; i < actx->idxlen; i++)
1043  actx->idx[i]->content = NULL;
1044  mutt_actx_free_entries(actx);
1045  mutt_update_recvattach_menu(actx, menu, true);
1046 }
#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:1471
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:1268
struct Body * content
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:1175
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 1057 of file recvattach.c.

1059 {
1060  do
1061  {
1062  switch (op)
1063  {
1064  case OP_DISPLAY_HEADERS:
1065  bool_str_toggle(Config, "weed", NULL);
1066  /* fallthrough */
1067 
1068  case OP_VIEW_ATTACH:
1069  op = mutt_view_attachment(CURATTACH->fp, CURATTACH->content,
1070  MUTT_VA_REGULAR, e, actx);
1071  break;
1072 
1073  case OP_NEXT_ENTRY:
1074  case OP_MAIN_NEXT_UNDELETED: /* hack */
1075  if (menu->current < menu->max - 1)
1076  {
1077  menu->current++;
1078  op = OP_VIEW_ATTACH;
1079  }
1080  else
1081  op = OP_NULL;
1082  break;
1083  case OP_PREV_ENTRY:
1084  case OP_MAIN_PREV_UNDELETED: /* hack */
1085  if (menu->current > 0)
1086  {
1087  menu->current--;
1088  op = OP_VIEW_ATTACH;
1089  }
1090  else
1091  op = OP_NULL;
1092  break;
1093  case OP_EDIT_TYPE:
1094  /* when we edit the content-type, we should redisplay the attachment
1095  * immediately */
1096  mutt_edit_content_type(e, CURATTACH->content, CURATTACH->fp);
1097  if (recv)
1098  recvattach_edit_content_type(actx, menu, e);
1099  else
1100  mutt_edit_content_type(e, CURATTACH->content, CURATTACH->fp);
1101 
1102  menu->redraw |= REDRAW_INDEX;
1103  op = OP_VIEW_ATTACH;
1104  break;
1105  /* functions which are passed through from the pager */
1106  case OP_CHECK_TRADITIONAL:
1108  {
1109  op = OP_NULL;
1110  break;
1111  }
1112  /* fallthrough */
1113  case OP_ATTACH_COLLAPSE:
1114  if (recv)
1115  return op;
1116  /* fallthrough */
1117  default:
1118  op = OP_NULL;
1119  }
1120  } while (op != OP_NULL);
1121 
1122  return op;
1123 }
#define CURATTACH
Definition: recvattach.c:91
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: ncrypt.h:131
WHERE struct ConfigSet * Config
Wrapper around the user&#39;s config settings.
Definition: globals.h:39
View using default method.
Definition: mutt_attach.h:41
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:1027
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
int max
the number of entries in the menu
Definition: mutt_menu.h:88
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:129
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:243
int mutt_view_attachment(FILE *fp, struct Body *a, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx)
View an attachment.
Definition: mutt_attach.c:379
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1175
int current
current entry
Definition: mutt_menu.h:87
#define WithCrypto
Definition: ncrypt.h:155

+ 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 parts,
FILE *  fp,
int  parent_type,
int  level,
bool  decrypted 
)
static

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

1138 {
1139  struct AttachPtr *new = NULL;
1140  struct Body *m = NULL;
1141  struct Body *new_body = NULL;
1142  FILE *fp_new = NULL;
1144  int need_secured, secured;
1145 
1146  for (m = parts; m; m = m->next)
1147  {
1148  need_secured = 0;
1149  secured = 0;
1150 
1151  if (((WithCrypto & APPLICATION_SMIME) != 0) && (type = mutt_is_application_smime(m)))
1152  {
1153  need_secured = 1;
1154 
1155  if (type & SEC_ENCRYPT)
1156  {
1157  if (!crypt_valid_passphrase(APPLICATION_SMIME))
1158  goto decrypt_failed;
1159 
1160  if (e->env)
1162  }
1163 
1164  secured = !crypt_smime_decrypt_mime(fp, &fp_new, m, &new_body);
1165  /* If the decrypt/verify-opaque doesn't generate mime output, an empty
1166  * text/plain type will still be returned by mutt_read_mime_header().
1167  * We can't distinguish an actual part from a failure, so only use a
1168  * text/plain that results from a single top-level part. */
1169  if (secured && (new_body->type == TYPE_TEXT) &&
1170  (mutt_str_strcasecmp("plain", new_body->subtype) == 0) &&
1171  ((parts != m) || m->next))
1172  {
1173  mutt_body_free(&new_body);
1174  mutt_file_fclose(&fp_new);
1175  goto decrypt_failed;
1176  }
1177 
1178  if (secured && (type & SEC_ENCRYPT))
1179  e->security |= SMIME_ENCRYPT;
1180  }
1181 
1182  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1184  {
1185  need_secured = 1;
1186 
1187  if (!crypt_valid_passphrase(APPLICATION_PGP))
1188  goto decrypt_failed;
1189 
1190  secured = !crypt_pgp_decrypt_mime(fp, &fp_new, m, &new_body);
1191 
1192  if (secured)
1193  e->security |= PGP_ENCRYPT;
1194  }
1195 
1196  if (need_secured && secured)
1197  {
1198  mutt_actx_add_fp(actx, fp_new);
1199  mutt_actx_add_body(actx, new_body);
1200  mutt_generate_recvattach_list(actx, e, new_body, fp_new, parent_type, level, 1);
1201  continue;
1202  }
1203 
1204  decrypt_failed:
1205  /* Fall through and show the original parts if decryption fails */
1206  if (need_secured && !secured)
1207  mutt_error(_("Can't decrypt encrypted message"));
1208 
1209  /* Strip out the top level multipart */
1210  if ((m->type == TYPE_MULTIPART) && m->parts && !need_secured &&
1211  ((parent_type == -1) && mutt_str_strcasecmp("alternative", m->subtype)))
1212  {
1213  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level, decrypted);
1214  }
1215  else
1216  {
1217  new = mutt_mem_calloc(1, sizeof(struct AttachPtr));
1218  mutt_actx_add_attach(actx, new);
1219 
1220  new->content = m;
1221  new->fp = fp;
1222  m->aptr = new;
1223  new->parent_type = parent_type;
1224  new->level = level;
1225  new->decrypted = decrypted;
1226 
1227  if (m->type == TYPE_MULTIPART)
1228  mutt_generate_recvattach_list(actx, e, m->parts, fp, m->type, level + 1, decrypted);
1229  else if (mutt_is_message_type(m->type, m->subtype))
1230  {
1231  mutt_generate_recvattach_list(actx, m->email, m->parts, fp, m->type,
1232  level + 1, decrypted);
1233  e->security |= m->email->security;
1234  }
1235  }
1236  }
1237 }
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:1255
void mutt_actx_add_fp(struct AttachCtx *actx, FILE *fp_new)
Save a File handle to the Attachment Context.
Definition: attach.c:59
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:58
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:120
The body of an email.
Definition: body.h:34
int crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:144
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:418
int parent_type
Definition: attach.h:38
struct Envelope * env
envelope information
Definition: email.h:92
char * subtype
content-type subtype
Definition: body.h:37
static 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:1135
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition: body.h:62
Type: &#39;text/*&#39;.
Definition: mime.h:38
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition: cryptglue.c:405
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:59
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:480
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:372
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:584
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
unsigned int type
content-type primary type
Definition: body.h:70
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:129
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:191
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
#define SMIME_ENCRYPT
Definition: ncrypt.h:141
#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:624
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: ncrypt.h:118
struct Email * email
header information for message/rfc822
Definition: body.h:60
#define WithCrypto
Definition: ncrypt.h:155
#define PGP_ENCRYPT
Definition: ncrypt.h:135
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
Use SMIME to encrypt/sign.
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 1243 of file recvattach.c.

1244 {
1245  /* Collapse the attachments if '$digest_collapse' is set AND if...
1246  * the outer container is of type 'multipart/digest' */
1247  bool digest = (mutt_str_strcasecmp(actx->email->content->subtype, "digest") == 0);
1248 
1249  for (int i = 0; i < actx->idxlen; i++)
1250  {
1251  actx->idx[i]->content->tagged = false;
1252 
1253  /* OR an inner container is of type 'multipart/digest' */
1254  actx->idx[i]->content->collapsed =
1255  (C_DigestCollapse &&
1256  (digest ||
1257  ((actx->idx[i]->content->type == TYPE_MULTIPART) &&
1258  (mutt_str_strcasecmp(actx->idx[i]->content->subtype, "digest") == 0))));
1259  }
1260 }
struct Email * email
used by recvattach for updating
Definition: attach.h:51
struct Body * content
list of MIME parts
Definition: email.h:93
bool C_DigestCollapse
Config: Hide the subparts of a multipart/digest.
Definition: recvattach.c:76
short idxlen
Definition: attach.h:55
bool tagged
Definition: body.h:77
bool collapsed
used by recvattach
Definition: body.h:98
char * subtype
content-type subtype
Definition: body.h:37
unsigned int type
content-type primary type
Definition: body.h:70
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:624
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 1293 of file recvattach.c.

1294 {
1295  int rindex, curlevel;
1296 
1297  CURATTACH->content->collapsed = !CURATTACH->content->collapsed;
1298  /* When expanding, expand all the children too */
1299  if (CURATTACH->content->collapsed)
1300  return;
1301 
1302  curlevel = CURATTACH->level;
1303  rindex = actx->v2r[menu->current] + 1;
1304 
1305  while ((rindex < actx->idxlen) && (actx->idx[rindex]->level > curlevel))
1306  {
1307  if (C_DigestCollapse && (actx->idx[rindex]->content->type == TYPE_MULTIPART) &&
1308  !mutt_str_strcasecmp(actx->idx[rindex]->content->subtype, "digest"))
1309  {
1310  actx->idx[rindex]->content->collapsed = true;
1311  }
1312  else
1313  {
1314  actx->idx[rindex]->content->collapsed = false;
1315  }
1316  rindex++;
1317  }
1318 }
#define CURATTACH
Definition: recvattach.c:91
bool C_DigestCollapse
Config: Hide the subparts of a multipart/digest.
Definition: recvattach.c:76
bool collapsed
used by recvattach
Definition: body.h:98
char * subtype
content-type subtype
Definition: body.h:37
unsigned int type
content-type primary type
Definition: body.h:70
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:624
int current
current entry
Definition: mutt_menu.h:87
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 1324 of file recvattach.c.

1325 {
1326  char helpstr[1024];
1327  int op = OP_NULL;
1328 
1329  struct Mailbox *m = Context ? Context->mailbox : NULL;
1330 
1331  /* make sure we have parsed this message */
1333 
1335 
1336  struct Message *msg = mx_msg_open(m, e->msgno);
1337  if (!msg)
1338  return;
1339 
1340  struct Menu *menu = mutt_menu_new(MENU_ATTACH);
1341  menu->title = _("Attachments");
1343  menu->menu_tag = attach_tag;
1344  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_ATTACH, AttachHelp);
1345  mutt_menu_push_current(menu);
1346 
1347  struct AttachCtx *actx = mutt_mem_calloc(sizeof(struct AttachCtx), 1);
1348  actx->email = e;
1349  actx->fp_root = msg->fp;
1350  mutt_update_recvattach_menu(actx, menu, true);
1351 
1352  while (true)
1353  {
1354  if (op == OP_NULL)
1355  op = mutt_menu_loop(menu);
1356  if (!Context)
1357  return;
1358  switch (op)
1359  {
1360  case OP_ATTACH_VIEW_MAILCAP:
1361  mutt_view_attachment(CURATTACH->fp, CURATTACH->content, MUTT_VA_MAILCAP, e, actx);
1362  menu->redraw = REDRAW_FULL;
1363  break;
1364 
1365  case OP_ATTACH_VIEW_TEXT:
1366  mutt_view_attachment(CURATTACH->fp, CURATTACH->content, MUTT_VA_AS_TEXT, e, actx);
1367  menu->redraw = REDRAW_FULL;
1368  break;
1369 
1370  case OP_DISPLAY_HEADERS:
1371  case OP_VIEW_ATTACH:
1372  op = mutt_attach_display_loop(menu, op, e, actx, true);
1373  menu->redraw = REDRAW_FULL;
1374  continue;
1375 
1376  case OP_ATTACH_COLLAPSE:
1377  if (!CURATTACH->content->parts)
1378  {
1379  mutt_error(_("There are no subparts to show"));
1380  break;
1381  }
1382  attach_collapse(actx, menu);
1383  mutt_update_recvattach_menu(actx, menu, false);
1384  break;
1385 
1386  case OP_FORGET_PASSPHRASE:
1388  break;
1389 
1390  case OP_EXTRACT_KEYS:
1392  {
1393  recvattach_extract_pgp_keys(actx, menu);
1394  menu->redraw = REDRAW_FULL;
1395  }
1396  break;
1397 
1398  case OP_CHECK_TRADITIONAL:
1399  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1401  {
1402  e->security = crypt_query(NULL);
1403  menu->redraw = REDRAW_FULL;
1404  }
1405  break;
1406 
1407  case OP_PRINT:
1409  CURATTACH->content);
1410  break;
1411 
1412  case OP_PIPE:
1414  CURATTACH->content, false);
1415  break;
1416 
1417  case OP_SAVE:
1419  CURATTACH->content, e, menu);
1420 
1421  if (!menu->tagprefix && C_Resolve && (menu->current < menu->max - 1))
1422  menu->current++;
1423 
1425  break;
1426 
1427  case OP_DELETE:
1429 
1430 #ifdef USE_POP
1431  if (m->magic == MUTT_POP)
1432  {
1433  mutt_flushinp();
1434  mutt_error(_("Can't delete attachment from POP server"));
1435  break;
1436  }
1437 #endif
1438 
1439 #ifdef USE_NNTP
1440  if (m->magic == MUTT_NNTP)
1441  {
1442  mutt_flushinp();
1443  mutt_error(_("Can't delete attachment from news server"));
1444  break;
1445  }
1446 #endif
1447 
1448  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
1449  {
1450  mutt_message(_("Deletion of attachments from encrypted messages is "
1451  "unsupported"));
1452  break;
1453  }
1454  if ((WithCrypto != 0) && (e->security & (SEC_SIGN | SEC_PARTSIGN)))
1455  {
1456  mutt_message(_("Deletion of attachments from signed messages may "
1457  "invalidate the signature"));
1458  }
1459  if (!menu->tagprefix)
1460  {
1461  if (CURATTACH->parent_type == TYPE_MULTIPART)
1462  {
1463  CURATTACH->content->deleted = true;
1464  if (C_Resolve && (menu->current < menu->max - 1))
1465  {
1466  menu->current++;
1467  menu->redraw = REDRAW_MOTION_RESYNC;
1468  }
1469  else
1470  menu->redraw = REDRAW_CURRENT;
1471  }
1472  else
1473  {
1474  mutt_message(
1475  _("Only deletion of multipart attachments is supported"));
1476  }
1477  }
1478  else
1479  {
1480  for (int i = 0; i < menu->max; i++)
1481  {
1482  if (actx->idx[i]->content->tagged)
1483  {
1484  if (actx->idx[i]->parent_type == TYPE_MULTIPART)
1485  {
1486  actx->idx[i]->content->deleted = true;
1487  menu->redraw = REDRAW_INDEX;
1488  }
1489  else
1490  {
1491  mutt_message(
1492  _("Only deletion of multipart attachments is supported"));
1493  }
1494  }
1495  }
1496  }
1497  break;
1498 
1499  case OP_UNDELETE:
1501  if (!menu->tagprefix)
1502  {
1503  CURATTACH->content->deleted = false;
1504  if (C_Resolve && (menu->current < menu->max - 1))
1505  {
1506  menu->current++;
1507  menu->redraw = REDRAW_MOTION_RESYNC;
1508  }
1509  else
1510  menu->redraw = REDRAW_CURRENT;
1511  }
1512  else
1513  {
1514  for (int i = 0; i < menu->max; i++)
1515  {
1516  if (actx->idx[i]->content->tagged)
1517  {
1518  actx->idx[i]->content->deleted = false;
1519  menu->redraw = REDRAW_INDEX;
1520  }
1521  }
1522  }
1523  break;
1524 
1525  case OP_RESEND:
1526  CHECK_ATTACH;
1527  mutt_attach_resend(CURATTACH->fp, actx,
1528  menu->tagprefix ? NULL : CURATTACH->content);
1529  menu->redraw = REDRAW_FULL;
1530  break;
1531 
1532  case OP_BOUNCE_MESSAGE:
1533  CHECK_ATTACH;
1534  mutt_attach_bounce(m, CURATTACH->fp, actx,
1535  menu->tagprefix ? NULL : CURATTACH->content);
1536  menu->redraw = REDRAW_FULL;
1537  break;
1538 
1539  case OP_FORWARD_MESSAGE:
1540  CHECK_ATTACH;
1541  mutt_attach_forward(CURATTACH->fp, e, actx,
1542  menu->tagprefix ? NULL : CURATTACH->content, 0);
1543  menu->redraw = REDRAW_FULL;
1544  break;
1545 
1546 #ifdef USE_NNTP
1547  case OP_FORWARD_TO_GROUP:
1548  CHECK_ATTACH;
1549  mutt_attach_forward(CURATTACH->fp, e, actx,
1550  menu->tagprefix ? NULL : CURATTACH->content, SEND_NEWS);
1551  menu->redraw = REDRAW_FULL;
1552  break;
1553 
1554  case OP_FOLLOWUP:
1555  CHECK_ATTACH;
1556 
1557  if (!CURATTACH->content->email->env->followup_to ||
1558  (mutt_str_strcasecmp(CURATTACH->content->email->env->followup_to, "poster") != 0) ||
1560  _("Reply by mail as poster prefers?")) != MUTT_YES))
1561  {
1562  mutt_attach_reply(CURATTACH->fp, e, actx,
1563  menu->tagprefix ? NULL : CURATTACH->content,
1564  SEND_NEWS | SEND_REPLY);
1565  menu->redraw = REDRAW_FULL;
1566  break;
1567  }
1568 #endif
1569  /* fallthrough */
1570  case OP_REPLY:
1571  case OP_GROUP_REPLY:
1572  case OP_GROUP_CHAT_REPLY:
1573  case OP_LIST_REPLY:
1574  {
1575  CHECK_ATTACH;
1576 
1577  SendFlags flags = SEND_REPLY | (op == OP_GROUP_REPLY ? SEND_GROUP_REPLY : 0) |
1578  (op == OP_GROUP_CHAT_REPLY ? SEND_GROUP_CHAT_REPLY : 0) |
1579  (op == OP_LIST_REPLY ? SEND_LIST_REPLY : 0);
1580  mutt_attach_reply(CURATTACH->fp, e, actx,
1581  menu->tagprefix ? NULL : CURATTACH->content, flags);
1582  menu->redraw = REDRAW_FULL;
1583  break;
1584  }
1585 
1586  case OP_COMPOSE_TO_SENDER:
1587  CHECK_ATTACH;
1588  mutt_attach_mail_sender(CURATTACH->fp, e, actx,
1589  menu->tagprefix ? NULL : CURATTACH->content);
1590  menu->redraw = REDRAW_FULL;
1591  break;
1592 
1593  case OP_EDIT_TYPE:
1594  recvattach_edit_content_type(actx, menu, e);
1595  menu->redraw |= REDRAW_INDEX;
1596  break;
1597 
1598  case OP_EXIT:
1599  mx_msg_close(m, &msg);
1600 
1601  e->attach_del = false;
1602  for (int i = 0; i < actx->idxlen; i++)
1603  {
1604  if (actx->idx[i]->content && actx->idx[i]->content->deleted)
1605  {
1606  e->attach_del = true;
1607  break;
1608  }
1609  }
1610  if (e->attach_del)
1611  e->changed = true;
1612 
1613  mutt_actx_free(&actx);
1614 
1615  mutt_menu_pop_current(menu);
1616  mutt_menu_destroy(&menu);
1617  return;
1618  }
1619 
1620  op = OP_NULL;
1621  }
1622 
1623  /* not reached */
1624 }
The "current" mailbox.
Definition: context.h:37
#define CURATTACH
Definition: recvattach.c:91
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
static const struct Mapping AttachHelp[]
Definition: recvattach.c:93
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:432
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: magic.h:41
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3369
#define mutt_message(...)
Definition: logging.h:87
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:199
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:753
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:102
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:50
#define _(a)
Definition: message.h:28
bool changed
Definition: email.h:48
short idxlen
Definition: attach.h:55
Force viewing as text.
Definition: mutt_attach.h:43
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:51
int menu
menu definition for keymap entries.
Definition: mutt_menu.h:90
uint16_t SendFlags
Flags for ci_send_message(), e.g. SEND_REPLY.
Definition: send.h:84
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: ncrypt.h:124
void(* menu_make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:121
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:444
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1058
struct Mailbox * mailbox
Definition: context.h:51
enum MailboxType magic
mailbox type
Definition: mailbox.h:106
int parent_type
Definition: attach.h:38
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:88
bool tagged
Definition: body.h:77
#define REDRAW_MOTION_RESYNC
Redraw any changing the menu selection.
Definition: mutt_menu.h:44
void mutt_actx_free(struct AttachCtx **pactx)
Free an Attachment Context.
Definition: attach.c:119
void mutt_attach_bounce(struct Mailbox *m, FILE *fp, struct AttachCtx *actx, struct Body *cur)
Bounce function, from the attachment menu.
Definition: recvcmd.c:164
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:121
A local copy of an email.
Definition: mx.h:81
Select an attachment.
Definition: keymap.h:69
A mailbox.
Definition: mailbox.h:83
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:1027
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:1057
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:981
WHERE bool C_Resolve
Config: Move to the next email whenever a command modifies an email.
Definition: globals.h:252
static void mutt_update_recvattach_menu(struct AttachCtx *actx, struct Menu *menu, bool init)
Update the Attachment Menu.
Definition: recvattach.c:1268
#define SEND_NEWS
Reply to a news article.
Definition: send.h:100
void mutt_attach_reply(FILE *fp, struct Email *e, struct AttachCtx *actx, struct Body *cur, SendFlags flags)
Attach a reply.
Definition: recvcmd.c:894
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
static int recvattach_pgp_check_traditional(struct AttachCtx *actx, struct Menu *menu)
Is the Attachment inline PGP?
Definition: recvattach.c:1005
Force viewing using mailcap entry.
Definition: mutt_attach.h:42
#define SEND_REPLY
Reply to sender.
Definition: send.h:86
#define CHECK_READONLY
Definition: recvattach.c:83
int max
the 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:138
#define APPLICATION_PGP
Use PGP to encrypt/sign.
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:940
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:746
char * title
the title of this menu
Definition: mutt_menu.h:84
bool deleted
attachment marked for deletion
Definition: body.h:78
static void attach_collapse(struct AttachCtx *actx, struct Menu *menu)
Close the tree of the current attachment.
Definition: recvattach.c:1293
#define SEND_GROUP_REPLY
Reply to all.
Definition: send.h:87
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
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:624
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:588
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:1055
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:441
#define SEND_GROUP_CHAT_REPLY
Reply to all recipients preserving To/Cc.
Definition: send.h:99
int mutt_view_attachment(FILE *fp, struct Body *a, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx)
View an attachment.
Definition: mutt_attach.c:379
int current
current entry
Definition: mutt_menu.h:87
#define CHECK_ATTACH
Definition: recvattach.c:101
#define WithCrypto
Definition: ncrypt.h:155
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Definition: attach.h:54
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:661
void mutt_attach_resend(FILE *fp, struct AttachCtx *actx, struct Body *cur)
resend-message, from the attachment menu
Definition: recvcmd.c:287
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:1010
#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:791
int msgno
number displayed to the user
Definition: email.h:89
&#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* C_AttachSaveDir

Config: Default directory where attachments are saved.

Definition at line 73 of file recvattach.c.

char* C_AttachSep

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

Definition at line 74 of file recvattach.c.

bool C_AttachSplit

Config: Save/print/pipe tagged messages individually.

Definition at line 75 of file recvattach.c.

bool C_DigestCollapse

Config: Hide the subparts of a multipart/digest.

Definition at line 76 of file recvattach.c.

char* C_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.