NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
mutt_attach.h File Reference
#include <stdbool.h>
#include <stdio.h>
+ Include dependency graph for mutt_attach.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  ViewAttachMode { MUTT_VA_REGULAR = 1, MUTT_VA_MAILCAP, MUTT_VA_AS_TEXT, MUTT_VA_PAGER }
 Options for mutt_view_attachment() More...
 
enum  SaveAttach { MUTT_SAVE_NO_FLAGS = 0, MUTT_SAVE_APPEND, MUTT_SAVE_OVERWRITE }
 Options for saving attachments. More...
 

Functions

int attach_tag (struct Menu *menu, int sel, int act)
 Tag an attachment - Implements Menu::tag() More...
 
int mutt_attach_display_loop (struct Menu *menu, int op, struct Email *e, struct AttachCtx *actx, bool recv)
 Event loop for the Attachment menu. More...
 
void mutt_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...
 
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...
 
void mutt_print_attachment_list (struct AttachCtx *actx, FILE *fp, bool tag, struct Body *top)
 Print a list of Attachments. More...
 
int mutt_view_attachment (FILE *fp, struct Body *a, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx, struct MuttWindow *win)
 View an attachment. More...
 
void mutt_check_lookup_list (struct Body *b, char *type, size_t len)
 Update the mime type. More...
 
int mutt_compose_attachment (struct Body *a)
 Create an attachment. More...
 
int mutt_decode_save_attachment (FILE *fp, struct Body *m, const char *path, int displaying, enum SaveAttach opt)
 Decode, then save an attachment. More...
 
int mutt_edit_attachment (struct Body *a)
 Edit an attachment. More...
 
int mutt_get_tmp_attachment (struct Body *a)
 Get a temporary copy of an attachment. More...
 
int mutt_pipe_attachment (FILE *fp, struct Body *b, const char *path, char *outfile)
 Pipe an attachment to a command. More...
 
int mutt_print_attachment (FILE *fp, struct Body *a)
 Print out an attachment. More...
 
int mutt_save_attachment (FILE *fp, struct Body *m, const char *path, enum SaveAttach opt, struct Email *e)
 Save an attachment. More...
 
void mutt_add_temp_attachment (const char *filename)
 Add file to list of temporary attachments. More...
 
void mutt_unlink_temp_attachments (void)
 Delete all temporary attachments. More...
 

Detailed Description

Handling of email attachments

Authors
  • Michael R. Elkins

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 mutt_attach.h.

Enumeration Type Documentation

◆ ViewAttachMode

Options for mutt_view_attachment()

Enumerator
MUTT_VA_REGULAR 

View using default method.

MUTT_VA_MAILCAP 

Force viewing using mailcap entry.

MUTT_VA_AS_TEXT 

Force viewing as text.

MUTT_VA_PAGER 

View attachment in pager using copiousoutput mailcap.

Definition at line 40 of file mutt_attach.h.

41 {
42  MUTT_VA_REGULAR = 1,
46 };

◆ SaveAttach

enum SaveAttach

Options for saving attachments.

See also
mutt_save_attachment(), mutt_decode_save_attachment(), save_attachment_open(), mutt_check_overwrite()
Enumerator
MUTT_SAVE_NO_FLAGS 

No flags set.

MUTT_SAVE_APPEND 

Append to existing file.

MUTT_SAVE_OVERWRITE 

Overwrite existing file.

Definition at line 54 of file mutt_attach.h.

55 {
56  MUTT_SAVE_NO_FLAGS = 0,
59 };

Function Documentation

◆ attach_tag()

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

Tag an attachment - Implements Menu::tag()

Definition at line 458 of file recvattach.c.

459 {
460  struct AttachCtx *actx = menu->mdata;
461  struct Body *cur = actx->idx[actx->v2r[sel]]->body;
462  bool ot = cur->tagged;
463 
464  cur->tagged = ((act >= 0) ? act : !cur->tagged);
465  return cur->tagged - ot;
466 }
+ Here is the caller graph for this function:

◆ mutt_attach_display_loop()

int mutt_attach_display_loop ( struct Menu menu,
int  op,
struct Email e,
struct AttachCtx actx,
bool  recv 
)

Event loop for the Attachment menu.

Parameters
menuMenu listing Attachments
opOperation, e.g. OP_VIEW_ATTACH
eEmail
actxAttachment context
recvtrue if these are received attachments (rather than in compose)
Return values
numOperation performed

Definition at line 1285 of file recvattach.c.

1287 {
1288  do
1289  {
1290  switch (op)
1291  {
1292  case OP_DISPLAY_HEADERS:
1293  bool_str_toggle(NeoMutt->sub, "weed", NULL);
1294  /* fallthrough */
1295 
1296  case OP_VIEW_ATTACH:
1297  op = mutt_view_attachment(CUR_ATTACH->fp, CUR_ATTACH->body,
1298  MUTT_VA_REGULAR, e, actx, menu->win_index);
1299  break;
1300 
1301  case OP_NEXT_ENTRY:
1302  case OP_MAIN_NEXT_UNDELETED: /* hack */
1303  if (menu->current < menu->max - 1)
1304  {
1305  menu->current++;
1306  op = OP_VIEW_ATTACH;
1307  }
1308  else
1309  op = OP_NULL;
1310  break;
1311  case OP_PREV_ENTRY:
1312  case OP_MAIN_PREV_UNDELETED: /* hack */
1313  if (menu->current > 0)
1314  {
1315  menu->current--;
1316  op = OP_VIEW_ATTACH;
1317  }
1318  else
1319  op = OP_NULL;
1320  break;
1321  case OP_EDIT_TYPE:
1322  /* when we edit the content-type, we should redisplay the attachment
1323  * immediately */
1325  if (recv)
1326  recvattach_edit_content_type(actx, menu, e);
1327  else
1329 
1330  menu->redraw |= REDRAW_INDEX;
1331  op = OP_VIEW_ATTACH;
1332  break;
1333  /* functions which are passed through from the pager */
1334  case OP_CHECK_TRADITIONAL:
1336  {
1337  op = OP_NULL;
1338  break;
1339  }
1340  /* fallthrough */
1341  case OP_ATTACH_COLLAPSE:
1342  if (recv)
1343  return op;
1344  /* fallthrough */
1345  default:
1346  op = OP_NULL;
1347  }
1348  } while (op != OP_NULL);
1349 
1350  return op;
1351 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_save_attachment_list()

void mutt_save_attachment_list ( struct AttachCtx actx,
FILE *  fp,
bool  tag,
struct Body top,
struct Email e,
struct Menu menu 
)

Save a list of attachments.

Parameters
actxAttachment context
fpFile handle for the attachment (OPTIONAL)
tagIf true, only save the tagged attachments
topFirst Attachment
eEmail
menuMenu listing attachments

Definition at line 724 of file recvattach.c.

726 {
727  char *directory = NULL;
728  int rc = 1;
729  int last = menu ? menu->current : -1;
730  FILE *fp_out = NULL;
731  int saved_attachments = 0;
732 
733  struct Buffer *buf = mutt_buffer_pool_get();
734  struct Buffer *tfile = mutt_buffer_pool_get();
735 
736  for (int i = 0; !tag || (i < actx->idxlen); i++)
737  {
738  if (tag)
739  {
740  fp = actx->idx[i]->fp;
741  top = actx->idx[i]->body;
742  }
743  if (!tag || top->tagged)
744  {
745  if (!C_AttachSplit)
746  {
747  if (mutt_buffer_is_empty(buf))
748  {
749  enum SaveAttach opt = MUTT_SAVE_NO_FLAGS;
750 
752  prepend_savedir(buf);
753 
754  if ((mutt_buffer_get_field(_("Save to file: "), buf, MUTT_FILE | MUTT_CLEAR,
755  false, NULL, NULL, NULL) != 0) ||
757  {
758  goto cleanup;
759  }
761  if (mutt_check_overwrite(top->filename, mutt_buffer_string(buf), tfile, &opt, NULL))
762  goto cleanup;
763  rc = save_attachment_flowed_helper(fp, top, mutt_buffer_string(tfile), opt, e);
764  if ((rc == 0) && C_AttachSep && (fp_out = fopen(mutt_buffer_string(tfile), "a")))
765  {
766  fprintf(fp_out, "%s", C_AttachSep);
767  mutt_file_fclose(&fp_out);
768  }
769  }
770  else
771  {
773  MUTT_SAVE_APPEND, e);
774  if ((rc == 0) && C_AttachSep && (fp_out = fopen(mutt_buffer_string(tfile), "a")))
775  {
776  fprintf(fp_out, "%s", C_AttachSep);
777  mutt_file_fclose(&fp_out);
778  }
779  }
780  }
781  else
782  {
783  if (tag && menu && top->aptr)
784  {
785  menu->oldcurrent = menu->current;
786  menu->current = top->aptr->num;
787  menu_check_recenter(menu);
788  menu->redraw |= REDRAW_MOTION;
789 
790  menu_redraw(menu);
791  }
793  {
794  // Save each file, with no prompting, using the configured 'AttachSaveDir'
795  rc = save_without_prompting(fp, top, e);
796  if (rc == 0)
797  saved_attachments++;
798  }
799  else
800  {
801  // Save each file, prompting the user for the location each time.
802  if (query_save_attachment(fp, top, e, &directory) == -1)
803  break;
804  }
805  }
806  }
807  if (!tag)
808  break;
809  }
810 
811  FREE(&directory);
812 
813  if (tag && menu)
814  {
815  menu->oldcurrent = menu->current;
816  menu->current = last;
817  menu_check_recenter(menu);
818  menu->redraw |= REDRAW_MOTION;
819  }
820 
821  if (!C_AttachSplit && (rc == 0))
822  mutt_message(_("Attachment saved"));
823 
824  if (C_AttachSaveWithoutPrompting && (rc == 0))
825  {
826  mutt_message(ngettext("Attachment saved", "%d attachments saved", saved_attachments),
827  saved_attachments);
828  }
829 
830 cleanup:
832  mutt_buffer_pool_release(&tfile);
833 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pipe_attachment_list()

void mutt_pipe_attachment_list ( struct AttachCtx actx,
FILE *  fp,
bool  tag,
struct Body top,
bool  filter 
)

Pipe a list of attachments to a command.

Parameters
actxAttachment context
fpFile handle to the attachment (OPTIONAL)
tagIf true, only save the tagged attachments
topFirst Attachment
filterIs this command a filter?

Definition at line 1011 of file recvattach.c.

1013 {
1014  struct State state = { 0 };
1015  struct Buffer *buf = NULL;
1016 
1017  if (fp)
1018  filter = false; /* sanity check: we can't filter in the recv case yet */
1019 
1020  buf = mutt_buffer_pool_get();
1021  /* perform charset conversion on text attachments when piping */
1022  state.flags = MUTT_CHARCONV;
1023 
1024  if (mutt_buffer_get_field((filter ? _("Filter through: ") : _("Pipe to: ")),
1025  buf, MUTT_CMD, false, NULL, NULL, NULL) != 0)
1026  {
1027  goto cleanup;
1028  }
1029 
1030  if (mutt_buffer_len(buf) == 0)
1031  goto cleanup;
1032 
1034 
1035  if (!filter && !C_AttachSplit)
1036  {
1037  mutt_endwin();
1038  pid_t pid = filter_create(mutt_buffer_string(buf), &state.fp_out, NULL, NULL);
1039  pipe_attachment_list(mutt_buffer_string(buf), actx, fp, tag, top, filter, &state);
1040  mutt_file_fclose(&state.fp_out);
1041  if ((filter_wait(pid) != 0) || C_WaitKey)
1043  }
1044  else
1045  pipe_attachment_list(mutt_buffer_string(buf), actx, fp, tag, top, filter, &state);
1046 
1047 cleanup:
1049 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_print_attachment_list()

void mutt_print_attachment_list ( struct AttachCtx actx,
FILE *  fp,
bool  tag,
struct Body top 
)

Print a list of Attachments.

Parameters
actxAttachment context
fpFile handle to the attachment (OPTIONAL)
tagApply to all tagged Attachments
topFirst Attachment

Definition at line 1166 of file recvattach.c.

1167 {
1168  char prompt[128];
1169  struct State state = { 0 };
1170  int tagmsgcount = 0;
1171 
1172  if (tag)
1173  for (int i = 0; i < actx->idxlen; i++)
1174  if (actx->idx[i]->body->tagged)
1175  tagmsgcount++;
1176 
1177  snprintf(prompt, sizeof(prompt),
1178  /* L10N: Although we now the precise number of tagged messages, we
1179  do not show it to the user. So feel free to use a "generic
1180  plural" as plural translation if your language has one. */
1181  tag ? ngettext("Print tagged attachment?", "Print %d tagged attachments?", tagmsgcount) :
1182  _("Print attachment?"),
1183  tagmsgcount);
1184  if (query_quadoption(C_Print, prompt) != MUTT_YES)
1185  return;
1186 
1187  if (C_AttachSplit)
1188  {
1189  print_attachment_list(actx, fp, tag, top, &state);
1190  }
1191  else
1192  {
1193  if (!can_print(actx, top, tag))
1194  return;
1195  mutt_endwin();
1196  pid_t pid = filter_create(NONULL(C_PrintCommand), &state.fp_out, NULL, NULL);
1197  print_attachment_list(actx, fp, tag, top, &state);
1198  mutt_file_fclose(&state.fp_out);
1199  if ((filter_wait(pid) != 0) || C_WaitKey)
1201  }
1202 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_view_attachment()

int mutt_view_attachment ( FILE *  fp,
struct Body a,
enum ViewAttachMode  mode,
struct Email e,
struct AttachCtx actx,
struct MuttWindow win 
)

View an attachment.

Parameters
fpSource file stream. Can be NULL
aThe message body containing the attachment
modeHow the attachment should be viewed, see ViewAttachMode
eCurrent Email. Can be NULL
actxAttachment context
winWindow
Return values
0If the viewer is run and exited successfully
-1Error
numReturn value of mutt_do_pager() when it is used

Display a message attachment using the viewer program configured in mailcap. If there is no mailcap entry for a file type, view the image as text. Viewer processes are opened and waited on synchronously so viewing an attachment this way will block the main neomutt process until the viewer process exits.

Definition at line 414 of file mutt_attach.c.

416 {
417  bool use_mailcap = false;
418  bool use_pipe = false;
419  bool use_pager = true;
420  char type[256];
421  char desc[256];
422  char *fname = NULL;
423  struct MailcapEntry *entry = NULL;
424  int rc = -1;
425  bool unlink_tempfile = false;
426  bool unlink_pagerfile = false;
427 
428  bool is_message = mutt_is_message_type(a->type, a->subtype);
429  if ((WithCrypto != 0) && is_message && a->email &&
431  {
432  return rc;
433  }
434 
435  struct Buffer *tmpfile = mutt_buffer_pool_get();
436  struct Buffer *pagerfile = mutt_buffer_pool_get();
437  struct Buffer *cmd = mutt_buffer_pool_get();
438 
439  use_mailcap = ((mode == MUTT_VA_MAILCAP) ||
440  ((mode == MUTT_VA_REGULAR) && mutt_needs_mailcap(a)) ||
441  (mode == MUTT_VA_PAGER));
442  snprintf(type, sizeof(type), "%s/%s", TYPE(a), a->subtype);
443 
444  char columns[16];
445  snprintf(columns, sizeof(columns), "%d", win->state.cols);
446  mutt_envlist_set("COLUMNS", columns, true);
447 
448  if (use_mailcap)
449  {
450  entry = mailcap_entry_new();
451  enum MailcapLookup mailcap_opt =
453  if (!mailcap_lookup(a, type, sizeof(type), entry, mailcap_opt))
454  {
455  if ((mode == MUTT_VA_REGULAR) || (mode == MUTT_VA_PAGER))
456  {
457  /* fallback to view as text */
458  mailcap_entry_free(&entry);
459  mutt_error(_("No matching mailcap entry found. Viewing as text."));
460  mode = MUTT_VA_AS_TEXT;
461  use_mailcap = false;
462  }
463  else
464  goto return_error;
465  }
466  }
467 
468  if (use_mailcap)
469  {
470  if (!entry->command)
471  {
472  mutt_error(_("MIME type not defined. Can't view attachment."));
473  goto return_error;
474  }
475  mutt_buffer_strcpy(cmd, entry->command);
476 
477  fname = mutt_str_dup(a->filename);
478  /* In send mode(!fp), we allow slashes because those are part of
479  * the tmpfile. The path will be removed in expand_filename */
480  mutt_file_sanitize_filename(fname, fp ? true : false);
481  mailcap_expand_filename(entry->nametemplate, fname, tmpfile);
482  FREE(&fname);
483 
484  if (mutt_save_attachment(fp, a, mutt_buffer_string(tmpfile), 0, NULL) == -1)
485  goto return_error;
486  unlink_tempfile = true;
487 
489 
490  use_pipe = mailcap_expand_command(a, mutt_buffer_string(tmpfile), type, cmd);
491  use_pager = entry->copiousoutput;
492  }
493 
494  if (use_pager)
495  {
496  if (fp && !use_mailcap && a->filename)
497  {
498  /* recv case */
499  mutt_buffer_strcpy(pagerfile, a->filename);
500  mutt_adv_mktemp(pagerfile);
501  }
502  else
503  mutt_buffer_mktemp(pagerfile);
504  }
505 
506  if (use_mailcap)
507  {
508  pid_t pid = 0;
509  int fd_temp = -1, fd_pager = -1;
510 
511  if (!use_pager)
512  mutt_endwin();
513 
514  if (use_pager || use_pipe)
515  {
516  if (use_pager && ((fd_pager = mutt_file_open(mutt_buffer_string(pagerfile),
517  O_CREAT | O_EXCL | O_WRONLY)) == -1))
518  {
519  mutt_perror("open");
520  goto return_error;
521  }
522  unlink_pagerfile = true;
523 
524  if (use_pipe && ((fd_temp = open(mutt_buffer_string(tmpfile), 0)) == -1))
525  {
526  if (fd_pager != -1)
527  close(fd_pager);
528  mutt_perror("open");
529  goto return_error;
530  }
531  unlink_pagerfile = true;
532 
533  pid = filter_create_fd(mutt_buffer_string(cmd), NULL, NULL, NULL,
534  use_pipe ? fd_temp : -1, use_pager ? fd_pager : -1, -1);
535 
536  if (pid == -1)
537  {
538  if (fd_pager != -1)
539  close(fd_pager);
540 
541  if (fd_temp != -1)
542  close(fd_temp);
543 
544  mutt_error(_("Can't create filter"));
545  goto return_error;
546  }
547 
548  if (use_pager)
549  {
550  if (a->description)
551  {
552  snprintf(desc, sizeof(desc), _("---Command: %-20.20s Description: %s"),
554  }
555  else
556  {
557  snprintf(desc, sizeof(desc), _("---Command: %-30.30s Attachment: %s"),
558  mutt_buffer_string(cmd), type);
559  }
560  filter_wait(pid);
561  }
562  else
563  {
564  if (wait_interactive_filter(pid) || (entry->needsterminal && C_WaitKey))
566  }
567 
568  if (fd_temp != -1)
569  close(fd_temp);
570  if (fd_pager != -1)
571  close(fd_pager);
572  }
573  else
574  {
575  /* interactive cmd */
576  int rv = mutt_system(mutt_buffer_string(cmd));
577  if (rv == -1)
578  mutt_debug(LL_DEBUG1, "Error running \"%s\"", cmd->data);
579 
580  if ((rv != 0) || (entry->needsterminal && C_WaitKey))
582  }
583  }
584  else
585  {
586  /* Don't use mailcap; the attachment is viewed in the pager */
587 
588  if (mode == MUTT_VA_AS_TEXT)
589  {
590  /* just let me see the raw data */
591  if (fp)
592  {
593  /* Viewing from a received message.
594  *
595  * Don't use mutt_save_attachment() because we want to perform charset
596  * conversion since this will be displayed by the internal pager. */
597  struct State decode_state = { 0 };
598 
599  decode_state.fp_out = mutt_file_fopen(mutt_buffer_string(pagerfile), "w");
600  if (!decode_state.fp_out)
601  {
602  mutt_debug(LL_DEBUG1, "mutt_file_fopen(%s) errno=%d %s\n",
603  mutt_buffer_string(pagerfile), errno, strerror(errno));
604  mutt_perror(mutt_buffer_string(pagerfile));
605  goto return_error;
606  }
607  decode_state.fp_in = fp;
608  decode_state.flags = MUTT_CHARCONV;
609  mutt_decode_attachment(a, &decode_state);
610  if (mutt_file_fclose(&decode_state.fp_out) == EOF)
611  {
612  mutt_debug(LL_DEBUG1, "fclose(%s) errno=%d %s\n",
613  mutt_buffer_string(pagerfile), errno, strerror(errno));
614  }
615  }
616  else
617  {
618  /* in compose mode, just copy the file. we can't use
619  * mutt_decode_attachment() since it assumes the content-encoding has
620  * already been applied */
621  if (mutt_save_attachment(fp, a, mutt_buffer_string(pagerfile), MUTT_SAVE_NO_FLAGS, NULL))
622  goto return_error;
623  unlink_pagerfile = true;
624  }
626  }
627  else
628  {
629  /* Use built-in handler */
630  OptViewAttach = true; /* disable the "use 'v' to view this part"
631  * message in case of error */
632  if (mutt_decode_save_attachment(fp, a, mutt_buffer_string(pagerfile),
634  {
635  OptViewAttach = false;
636  goto return_error;
637  }
638  unlink_pagerfile = true;
639  OptViewAttach = false;
640  }
641 
642  if (a->description)
643  mutt_str_copy(desc, a->description, sizeof(desc));
644  else if (a->filename)
645  snprintf(desc, sizeof(desc), _("---Attachment: %s: %s"), a->filename, type);
646  else
647  snprintf(desc, sizeof(desc), _("---Attachment: %s"), type);
648  }
649 
650  /* We only reach this point if there have been no errors */
651 
652  if (use_pager)
653  {
654  struct Pager info = { 0 };
655  info.fp = fp;
656  info.body = a;
657  info.ctx = Context;
658  info.actx = actx;
659  info.email = e;
660 
661  rc = mutt_do_pager(desc, mutt_buffer_string(pagerfile),
663  &info);
664  mutt_buffer_reset(pagerfile);
665  unlink_pagerfile = false;
666  }
667  else
668  rc = 0;
669 
670 return_error:
671 
672  if (!entry || !entry->xneomuttkeep)
673  {
674  if (fp && !mutt_buffer_is_empty(tmpfile))
675  {
676  /* add temporary file to TempAttachmentsList to be deleted on timeout hook */
678  }
679  else if (unlink_tempfile)
680  {
681  unlink(mutt_buffer_string(tmpfile));
682  }
683  }
684 
685  mailcap_entry_free(&entry);
686 
687  if (unlink_pagerfile)
689 
690  mutt_buffer_pool_release(&tmpfile);
691  mutt_buffer_pool_release(&pagerfile);
693  mutt_envlist_unset("COLUMNS");
694 
695  return rc;
696 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_check_lookup_list()

void mutt_check_lookup_list ( struct Body b,
char *  type,
size_t  len 
)

Update the mime type.

Parameters
bMessage attachment body
typeBuffer with mime type of attachment in "type/subtype" format
lenBuffer length

Definition at line 335 of file mutt_attach.c.

336 {
337  struct ListNode *np = NULL;
338  STAILQ_FOREACH(np, &MimeLookupList, entries)
339  {
340  const int i = mutt_str_len(np->data) - 1;
341  if (((i > 0) && (np->data[i - 1] == '/') && (np->data[i] == '*') &&
342  mutt_istrn_equal(type, np->data, i)) ||
343  mutt_istr_equal(type, np->data))
344  {
345  struct Body tmp = { 0 };
346  enum ContentType n;
347  if ((n = mutt_lookup_mime_type(&tmp, b->filename)) != TYPE_OTHER ||
348  (n = mutt_lookup_mime_type(&tmp, b->description)) != TYPE_OTHER)
349  {
350  snprintf(type, len, "%s/%s",
351  (n == TYPE_AUDIO) ? "audio" :
352  (n == TYPE_APPLICATION) ? "application" :
353  (n == TYPE_IMAGE) ? "image" :
354  (n == TYPE_MESSAGE) ? "message" :
355  (n == TYPE_MODEL) ? "model" :
356  (n == TYPE_MULTIPART) ? "multipart" :
357  (n == TYPE_TEXT) ? "text" :
358  (n == TYPE_VIDEO) ? "video" :
359  "other",
360  tmp.subtype);
361  mutt_debug(LL_DEBUG1, "\"%s\" -> %s\n", b->filename, type);
362  }
363  FREE(&tmp.subtype);
364  FREE(&tmp.xtype);
365  }
366  }
367 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_compose_attachment()

int mutt_compose_attachment ( struct Body a)

Create an attachment.

Parameters
aBody of email
Return values
1if require full screen redraw
0otherwise

Definition at line 119 of file mutt_attach.c.

120 {
121  char type[256];
122  struct MailcapEntry *entry = mailcap_entry_new();
123  bool unlink_newfile = false;
124  int rc = 0;
125  struct Buffer *cmd = mutt_buffer_pool_get();
126  struct Buffer *newfile = mutt_buffer_pool_get();
127  struct Buffer *tmpfile = mutt_buffer_pool_get();
128 
129  snprintf(type, sizeof(type), "%s/%s", TYPE(a), a->subtype);
130  if (mailcap_lookup(a, type, sizeof(type), entry, MUTT_MC_COMPOSE))
131  {
132  if (entry->composecommand || entry->composetypecommand)
133  {
134  if (entry->composetypecommand)
136  else
137  mutt_buffer_strcpy(cmd, entry->composecommand);
138 
139  mailcap_expand_filename(entry->nametemplate, a->filename, newfile);
140  mutt_debug(LL_DEBUG1, "oldfile: %s newfile: %s\n", a->filename,
141  mutt_buffer_string(newfile));
142  if (mutt_file_symlink(a->filename, mutt_buffer_string(newfile)) == -1)
143  {
144  if (mutt_yesorno(_("Can't match 'nametemplate', continue?"), MUTT_YES) != MUTT_YES)
145  goto bailout;
146  mutt_buffer_strcpy(newfile, a->filename);
147  }
148  else
149  unlink_newfile = true;
150 
151  if (mailcap_expand_command(a, mutt_buffer_string(newfile), type, cmd))
152  {
153  /* For now, editing requires a file, no piping */
154  mutt_error(_("Mailcap compose entry requires %%s"));
155  }
156  else
157  {
158  int r;
159 
160  mutt_endwin();
162  if (r == -1)
163  mutt_error(_("Error running \"%s\""), mutt_buffer_string(cmd));
164 
165  if ((r != -1) && entry->composetypecommand)
166  {
167  struct Body *b = NULL;
168 
169  FILE *fp = mutt_file_fopen(a->filename, "r");
170  if (!fp)
171  {
172  mutt_perror(_("Failure to open file to parse headers"));
173  goto bailout;
174  }
175 
176  b = mutt_read_mime_header(fp, 0);
177  if (b)
178  {
179  if (!TAILQ_EMPTY(&b->parameter))
180  {
182  a->parameter = b->parameter;
183  TAILQ_INIT(&b->parameter);
184  }
185  if (b->description)
186  {
187  FREE(&a->description);
188  a->description = b->description;
189  b->description = NULL;
190  }
191  if (b->form_name)
192  {
193  FREE(&a->form_name);
194  a->form_name = b->form_name;
195  b->form_name = NULL;
196  }
197 
198  /* Remove headers by copying out data to another file, then
199  * copying the file back */
200  fseeko(fp, b->offset, SEEK_SET);
201  mutt_body_free(&b);
202  mutt_buffer_mktemp(tmpfile);
203  FILE *fp_tmp = mutt_file_fopen(mutt_buffer_string(tmpfile), "w");
204  if (!fp_tmp)
205  {
206  mutt_perror(_("Failure to open file to strip headers"));
207  mutt_file_fclose(&fp);
208  goto bailout;
209  }
210  mutt_file_copy_stream(fp, fp_tmp);
211  mutt_file_fclose(&fp);
212  mutt_file_fclose(&fp_tmp);
214  if (mutt_file_rename(mutt_buffer_string(tmpfile), a->filename) != 0)
215  {
216  mutt_perror(_("Failure to rename file"));
217  goto bailout;
218  }
219  }
220  }
221  }
222  }
223  }
224  else
225  {
226  mutt_message(_("No mailcap compose entry for %s, creating empty file"), type);
227  rc = 1;
228  goto bailout;
229  }
230 
231  rc = 1;
232 
233 bailout:
234 
235  if (unlink_newfile)
236  unlink(mutt_buffer_string(newfile));
237 
239  mutt_buffer_pool_release(&newfile);
240  mutt_buffer_pool_release(&tmpfile);
241 
242  mailcap_entry_free(&entry);
243  return rc;
244 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_decode_save_attachment()

int mutt_decode_save_attachment ( FILE *  fp,
struct Body m,
const char *  path,
int  displaying,
enum SaveAttach  opt 
)

Decode, then save an attachment.

Parameters
fpFile to read from (OPTIONAL)
mAttachment
pathPath to save the Attachment to
displayingFlags, e.g. MUTT_DISPLAY
optSave option, see SaveAttach
Return values
0Success
-1Error

Definition at line 1004 of file mutt_attach.c.

1006 {
1007  struct State s = { 0 };
1008  unsigned int saved_encoding = 0;
1009  struct Body *saved_parts = NULL;
1010  struct Email *e_saved = NULL;
1011  int rc = 0;
1012 
1013  s.flags = displaying;
1014 
1015  if (opt == MUTT_SAVE_APPEND)
1016  s.fp_out = fopen(path, "a");
1017  else if (opt == MUTT_SAVE_OVERWRITE)
1018  s.fp_out = fopen(path, "w");
1019  else
1020  s.fp_out = mutt_file_fopen(path, "w");
1021 
1022  if (!s.fp_out)
1023  {
1024  mutt_perror("fopen");
1025  return -1;
1026  }
1027 
1028  if (!fp)
1029  {
1030  /* When called from the compose menu, the attachment isn't parsed,
1031  * so we need to do it here. */
1032  struct stat st;
1033 
1034  if (stat(m->filename, &st) == -1)
1035  {
1036  mutt_perror("stat");
1038  return -1;
1039  }
1040 
1041  s.fp_in = fopen(m->filename, "r");
1042  if (!s.fp_in)
1043  {
1044  mutt_perror("fopen");
1045  return -1;
1046  }
1047 
1048  saved_encoding = m->encoding;
1049  if (!is_multipart(m))
1050  m->encoding = ENC_8BIT;
1051 
1052  m->length = st.st_size;
1053  m->offset = 0;
1054  saved_parts = m->parts;
1055  e_saved = m->email;
1056  mutt_parse_part(s.fp_in, m);
1057 
1058  if (m->noconv || is_multipart(m))
1059  s.flags |= MUTT_CHARCONV;
1060  }
1061  else
1062  {
1063  s.fp_in = fp;
1064  s.flags |= MUTT_CHARCONV;
1065  }
1066 
1067  mutt_body_handler(m, &s);
1068 
1069  if (mutt_file_fsync_close(&s.fp_out) != 0)
1070  {
1071  mutt_perror("fclose");
1072  rc = -1;
1073  }
1074  if (!fp)
1075  {
1076  m->length = 0;
1077  m->encoding = saved_encoding;
1078  if (saved_parts)
1079  {
1080  email_free(&m->email);
1081  m->parts = saved_parts;
1082  m->email = e_saved;
1083  }
1084  mutt_file_fclose(&s.fp_in);
1085  }
1086 
1087  return rc;
1088 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_edit_attachment()

int mutt_edit_attachment ( struct Body a)

Edit an attachment.

Parameters
aEmail containing attachment
Return values
1if editor found
0if not

Currently, this only works for send mode, as it assumes that the Body->filename actually contains the information. I'm not sure we want to deal with editing attachments we've already received, so this should be ok.

Returning 0 is useful to tell the calling menu to redraw

Definition at line 259 of file mutt_attach.c.

260 {
261  char type[256];
262  struct MailcapEntry *entry = mailcap_entry_new();
263  bool unlink_newfile = false;
264  int rc = 0;
265  struct Buffer *cmd = mutt_buffer_pool_get();
266  struct Buffer *newfile = mutt_buffer_pool_get();
267 
268  snprintf(type, sizeof(type), "%s/%s", TYPE(a), a->subtype);
269  if (mailcap_lookup(a, type, sizeof(type), entry, MUTT_MC_EDIT))
270  {
271  if (entry->editcommand)
272  {
273  mutt_buffer_strcpy(cmd, entry->editcommand);
274  mailcap_expand_filename(entry->nametemplate, a->filename, newfile);
275  mutt_debug(LL_DEBUG1, "oldfile: %s newfile: %s\n", a->filename,
276  mutt_buffer_string(newfile));
277  if (mutt_file_symlink(a->filename, mutt_buffer_string(newfile)) == -1)
278  {
279  if (mutt_yesorno(_("Can't match 'nametemplate', continue?"), MUTT_YES) != MUTT_YES)
280  goto bailout;
281  mutt_buffer_strcpy(newfile, a->filename);
282  }
283  else
284  unlink_newfile = true;
285 
286  if (mailcap_expand_command(a, mutt_buffer_string(newfile), type, cmd))
287  {
288  /* For now, editing requires a file, no piping */
289  mutt_error(_("Mailcap Edit entry requires %%s"));
290  goto bailout;
291  }
292  else
293  {
294  mutt_endwin();
295  if (mutt_system(mutt_buffer_string(cmd)) == -1)
296  {
297  mutt_error(_("Error running \"%s\""), mutt_buffer_string(cmd));
298  goto bailout;
299  }
300  }
301  }
302  }
303  else if (a->type == TYPE_TEXT)
304  {
305  /* On text, default to editor */
307  }
308  else
309  {
310  mutt_error(_("No mailcap edit entry for %s"), type);
311  rc = 0;
312  goto bailout;
313  }
314 
315  rc = 1;
316 
317 bailout:
318 
319  if (unlink_newfile)
320  unlink(mutt_buffer_string(newfile));
321 
323  mutt_buffer_pool_release(&newfile);
324 
325  mailcap_entry_free(&entry);
326  return rc;
327 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_get_tmp_attachment()

int mutt_get_tmp_attachment ( struct Body a)

Get a temporary copy of an attachment.

Parameters
aAttachment to copy
Return values
0Success
-1Error

Definition at line 69 of file mutt_attach.c.

70 {
71  char type[256];
72  struct stat st;
73 
74  if (a->unlink)
75  return 0;
76 
77  struct Buffer *tmpfile = mutt_buffer_pool_get();
78  struct MailcapEntry *entry = mailcap_entry_new();
79  snprintf(type, sizeof(type), "%s/%s", TYPE(a), a->subtype);
80  mailcap_lookup(a, type, sizeof(type), entry, MUTT_MC_NO_FLAGS);
81  mailcap_expand_filename(entry->nametemplate, a->filename, tmpfile);
82 
83  mailcap_entry_free(&entry);
84 
85  if (stat(a->filename, &st) == -1)
86  {
87  mutt_buffer_pool_release(&tmpfile);
88  return -1;
89  }
90 
91  FILE *fp_in = NULL, *fp_out = NULL;
92  if ((fp_in = fopen(a->filename, "r")) &&
93  (fp_out = mutt_file_fopen(mutt_buffer_string(tmpfile), "w")))
94  {
95  mutt_file_copy_stream(fp_in, fp_out);
97  a->unlink = true;
98 
99  if (a->stamp >= st.st_mtime)
101  }
102  else
103  mutt_perror(fp_in ? mutt_buffer_string(tmpfile) : a->filename);
104 
105  mutt_file_fclose(&fp_in);
106  mutt_file_fclose(&fp_out);
107 
108  mutt_buffer_pool_release(&tmpfile);
109 
110  return a->unlink ? 0 : -1;
111 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pipe_attachment()

int mutt_pipe_attachment ( FILE *  fp,
struct Body b,
const char *  path,
char *  outfile 
)

Pipe an attachment to a command.

Parameters
fpFile to pipe into the command
bAttachment
pathPath to command
outfileFile to save output to
Return values
1Success
0Error

Definition at line 707 of file mutt_attach.c.

708 {
709  pid_t pid = 0;
710  int out = -1, rc = 0;
711  bool is_flowed = false;
712  bool unlink_unstuff = false;
713  FILE *fp_filter = NULL, *fp_unstuff = NULL, *fp_in = NULL;
714  struct Buffer *unstuff_tempfile = NULL;
715 
716  if (outfile && *outfile)
717  {
718  out = mutt_file_open(outfile, O_CREAT | O_EXCL | O_WRONLY);
719  if (out < 0)
720  {
721  mutt_perror("open");
722  return 0;
723  }
724  }
725 
727  {
728  is_flowed = true;
729  unstuff_tempfile = mutt_buffer_pool_get();
730  mutt_buffer_mktemp(unstuff_tempfile);
731  }
732 
733  mutt_endwin();
734 
735  if (outfile && *outfile)
736  pid = filter_create_fd(path, &fp_filter, NULL, NULL, -1, out, -1);
737  else
738  pid = filter_create(path, &fp_filter, NULL, NULL);
739  if (pid < 0)
740  {
741  mutt_perror(_("Can't create filter"));
742  goto bail;
743  }
744 
745  /* recv case */
746  if (fp)
747  {
748  struct State s = { 0 };
749 
750  /* perform charset conversion on text attachments when piping */
751  s.flags = MUTT_CHARCONV;
752 
753  if (is_flowed)
754  {
755  fp_unstuff = mutt_file_fopen(mutt_buffer_string(unstuff_tempfile), "w");
756  if (fp_unstuff == NULL)
757  {
758  mutt_perror("mutt_file_fopen");
759  goto bail;
760  }
761  unlink_unstuff = true;
762 
763  s.fp_in = fp;
764  s.fp_out = fp_unstuff;
765  mutt_decode_attachment(b, &s);
766  mutt_file_fclose(&fp_unstuff);
767 
769 
770  fp_unstuff = mutt_file_fopen(mutt_buffer_string(unstuff_tempfile), "r");
771  if (fp_unstuff == NULL)
772  {
773  mutt_perror("mutt_file_fopen");
774  goto bail;
775  }
776  mutt_file_copy_stream(fp_unstuff, fp_filter);
777  mutt_file_fclose(&fp_unstuff);
778  }
779  else
780  {
781  s.fp_in = fp;
782  s.fp_out = fp_filter;
783  mutt_decode_attachment(b, &s);
784  }
785  }
786 
787  /* send case */
788  else
789  {
790  const char *infile = NULL;
791 
792  if (is_flowed)
793  {
794  if (mutt_save_attachment(fp, b, mutt_buffer_string(unstuff_tempfile),
795  MUTT_SAVE_NO_FLAGS, NULL) == -1)
796  {
797  goto bail;
798  }
799  unlink_unstuff = true;
801  infile = mutt_buffer_string(unstuff_tempfile);
802  }
803  else
804  infile = b->filename;
805 
806  fp_in = fopen(infile, "r");
807  if (!fp_in)
808  {
809  mutt_perror("fopen");
810  goto bail;
811  }
812 
813  mutt_file_copy_stream(fp_in, fp_filter);
815  }
816 
817  mutt_file_fclose(&fp_filter);
818  rc = 1;
819 
820 bail:
821  if (outfile && *outfile)
822  {
823  close(out);
824  if (rc == 0)
825  unlink(outfile);
826  else if (is_flowed)
828  }
829 
830  mutt_file_fclose(&fp_unstuff);
831  mutt_file_fclose(&fp_filter);
833 
834  if (unlink_unstuff)
835  mutt_file_unlink(mutt_buffer_string(unstuff_tempfile));
836  mutt_buffer_pool_release(&unstuff_tempfile);
837 
838  /* check for error exit from child process */
839  if ((pid > 0) && (filter_wait(pid) != 0))
840  rc = 0;
841 
842  if ((rc == 0) || C_WaitKey)
844  return rc;
845 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_print_attachment()

int mutt_print_attachment ( FILE *  fp,
struct Body a 
)

Print out an attachment.

Parameters
fpFile to write to
aAttachment
Return values
1Success
0Error

Ok, the difference between send and receive: recv: Body->filename is a suggested name, and Mailbox|Email points to the attachment in mailbox which is encoded send: Body->filename points to the un-encoded file which contains the attachment

Definition at line 1103 of file mutt_attach.c.

1104 {
1105  char type[256];
1106  pid_t pid;
1107  FILE *fp_in = NULL, *fp_out = NULL;
1108  bool unlink_newfile = false;
1109  struct Buffer *newfile = mutt_buffer_pool_get();
1110  struct Buffer *cmd = mutt_buffer_pool_get();
1111 
1112  int rc = 0;
1113 
1114  snprintf(type, sizeof(type), "%s/%s", TYPE(a), a->subtype);
1115 
1116  if (mailcap_lookup(a, type, sizeof(type), NULL, MUTT_MC_PRINT))
1117  {
1118  int piped = false;
1119 
1120  mutt_debug(LL_DEBUG2, "Using mailcap\n");
1121 
1122  struct MailcapEntry *entry = mailcap_entry_new();
1123  mailcap_lookup(a, type, sizeof(type), entry, MUTT_MC_PRINT);
1124  mailcap_expand_filename(entry->nametemplate, a->filename, newfile);
1125 
1126  if (mutt_save_attachment(fp, a, mutt_buffer_string(newfile),
1127  MUTT_SAVE_NO_FLAGS, NULL) == -1)
1128  {
1129  goto mailcap_cleanup;
1130  }
1131  unlink_newfile = 1;
1132 
1134 
1135  mutt_buffer_strcpy(cmd, entry->printcommand);
1136  piped = mailcap_expand_command(a, mutt_buffer_string(newfile), type, cmd);
1137 
1138  mutt_endwin();
1139 
1140  /* interactive program */
1141  if (piped)
1142  {
1143  fp_in = fopen(mutt_buffer_string(newfile), "r");
1144  if (!fp_in)
1145  {
1146  mutt_perror("fopen");
1147  mailcap_entry_free(&entry);
1148  goto mailcap_cleanup;
1149  }
1150 
1151  pid = filter_create(mutt_buffer_string(cmd), &fp_out, NULL, NULL);
1152  if (pid < 0)
1153  {
1154  mutt_perror(_("Can't create filter"));
1155  mailcap_entry_free(&entry);
1156  mutt_file_fclose(&fp_in);
1157  goto mailcap_cleanup;
1158  }
1159  mutt_file_copy_stream(fp_in, fp_out);
1160  mutt_file_fclose(&fp_out);
1161  mutt_file_fclose(&fp_in);
1162  if (filter_wait(pid) || C_WaitKey)
1164  }
1165  else
1166  {
1167  int rc2 = mutt_system(mutt_buffer_string(cmd));
1168  if (rc2 == -1)
1169  mutt_debug(LL_DEBUG1, "Error running \"%s\"", cmd->data);
1170 
1171  if ((rc2 != 0) || C_WaitKey)
1173  }
1174 
1175  rc = 1;
1176 
1177  mailcap_cleanup:
1178  if (unlink_newfile)
1180 
1181  mailcap_entry_free(&entry);
1182  goto out;
1183  }
1184 
1185  if (mutt_istr_equal("text/plain", type) ||
1186  mutt_istr_equal("application/postscript", type))
1187  {
1188  rc = (mutt_pipe_attachment(fp, a, NONULL(C_PrintCommand), NULL));
1189  goto out;
1190  }
1191  else if (mutt_can_decode(a))
1192  {
1193  /* decode and print */
1194 
1195  fp_in = NULL;
1196  fp_out = NULL;
1197 
1198  mutt_buffer_mktemp(newfile);
1199  if (mutt_decode_save_attachment(fp, a, mutt_buffer_string(newfile),
1201  {
1202  unlink_newfile = true;
1203  mutt_debug(LL_DEBUG2, "successfully decoded %s type attachment to %s\n",
1204  type, mutt_buffer_string(newfile));
1205 
1206  fp_in = fopen(mutt_buffer_string(newfile), "r");
1207  if (!fp_in)
1208  {
1209  mutt_perror("fopen");
1210  goto decode_cleanup;
1211  }
1212 
1213  mutt_debug(LL_DEBUG2, "successfully opened %s read-only\n",
1214  mutt_buffer_string(newfile));
1215 
1216  mutt_endwin();
1217  pid = filter_create(NONULL(C_PrintCommand), &fp_out, NULL, NULL);
1218  if (pid < 0)
1219  {
1220  mutt_perror(_("Can't create filter"));
1221  goto decode_cleanup;
1222  }
1223 
1224  mutt_debug(LL_DEBUG2, "Filter created\n");
1225 
1226  mutt_file_copy_stream(fp_in, fp_out);
1227 
1228  mutt_file_fclose(&fp_out);
1229  mutt_file_fclose(&fp_in);
1230 
1231  if ((filter_wait(pid) != 0) || C_WaitKey)
1233  rc = 1;
1234  }
1235  decode_cleanup:
1236  mutt_file_fclose(&fp_in);
1237  mutt_file_fclose(&fp_out);
1238  if (unlink_newfile)
1240  }
1241  else
1242  {
1243  mutt_error(_("I don't know how to print that"));
1244  rc = 0;
1245  }
1246 
1247 out:
1248  mutt_buffer_pool_release(&newfile);
1250 
1251  return rc;
1252 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_save_attachment()

int mutt_save_attachment ( FILE *  fp,
struct Body m,
const char *  path,
enum SaveAttach  opt,
struct Email e 
)

Save an attachment.

Parameters
fpSource file stream. Can be NULL
mEmail Body
pathWhere to save the attachment
optSave option, see SaveAttach
eCurrent Email. Can be NULL
Return values
0Success
-1Error

Definition at line 873 of file mutt_attach.c.

875 {
876  if (!m)
877  return -1;
878 
879  if (fp)
880  {
881  /* recv mode */
882 
883  if (e && m->email && (m->encoding != ENC_BASE64) &&
885  {
886  /* message type attachments are written to mail folders. */
887 
888  char buf[8192];
889  struct Message *msg = NULL;
890  CopyHeaderFlags chflags = CH_NO_FLAGS;
891  int rc = -1;
892 
893  struct Email *e_new = m->email;
894  e_new->msgno = e->msgno; /* required for MH/maildir */
895  e_new->read = true;
896 
897  if (fseeko(fp, m->offset, SEEK_SET) < 0)
898  return -1;
899  if (!fgets(buf, sizeof(buf), fp))
900  return -1;
901  struct Mailbox *m_att = mx_path_resolve(path);
902  struct Context *ctx = mx_mbox_open(m_att, MUTT_APPEND | MUTT_QUIET);
903  if (!ctx)
904  {
905  mailbox_free(&m_att);
906  return -1;
907  }
908  msg = mx_msg_open_new(ctx->mailbox, e_new,
909  is_from(buf, NULL, 0, NULL) ? MUTT_MSG_NO_FLAGS : MUTT_ADD_FROM);
910  if (!msg)
911  {
912  mx_mbox_close(&ctx);
913  return -1;
914  }
915  if ((ctx->mailbox->type == MUTT_MBOX) || (ctx->mailbox->type == MUTT_MMDF))
916  chflags = CH_FROM | CH_UPDATE_LEN;
917  chflags |= ((ctx->mailbox->type == MUTT_MAILDIR) ? CH_NOSTATUS : CH_UPDATE);
918  if ((mutt_copy_message_fp(msg->fp, fp, e_new, MUTT_CM_NO_FLAGS, chflags, 0) == 0) &&
919  (mx_msg_commit(ctx->mailbox, msg) == 0))
920  {
921  rc = 0;
922  }
923  else
924  {
925  rc = -1;
926  }
927 
928  mx_msg_close(ctx->mailbox, &msg);
929  mx_mbox_close(&ctx);
930  return rc;
931  }
932  else
933  {
934  /* In recv mode, extract from folder and decode */
935 
936  struct State s = { 0 };
937 
938  s.fp_out = save_attachment_open(path, opt);
939  if (!s.fp_out)
940  {
941  mutt_perror("fopen");
942  return -1;
943  }
944  fseeko((s.fp_in = fp), m->offset, SEEK_SET);
945  mutt_decode_attachment(m, &s);
946 
947  if (mutt_file_fsync_close(&s.fp_out) != 0)
948  {
949  mutt_perror("fclose");
950  return -1;
951  }
952  }
953  }
954  else
955  {
956  if (!m->filename)
957  return -1;
958 
959  /* In send mode, just copy file */
960 
961  FILE *fp_old = fopen(m->filename, "r");
962  if (!fp_old)
963  {
964  mutt_perror("fopen");
965  return -1;
966  }
967 
968  FILE *fp_new = save_attachment_open(path, opt);
969  if (!fp_new)
970  {
971  mutt_perror("fopen");
972  mutt_file_fclose(&fp_old);
973  return -1;
974  }
975 
976  if (mutt_file_copy_stream(fp_old, fp_new) == -1)
977  {
978  mutt_error(_("Write fault"));
979  mutt_file_fclose(&fp_old);
980  mutt_file_fclose(&fp_new);
981  return -1;
982  }
983  mutt_file_fclose(&fp_old);
984  if (mutt_file_fsync_close(&fp_new) != 0)
985  {
986  mutt_error(_("Write fault"));
987  return -1;
988  }
989  }
990 
991  return 0;
992 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_add_temp_attachment()

void mutt_add_temp_attachment ( const char *  filename)

Add file to list of temporary attachments.

Parameters
filenamefilename with full path

Definition at line 1258 of file mutt_attach.c.

1259 {
1260  mutt_list_insert_tail(&TempAttachmentsList, mutt_str_dup(filename));
1261 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_unlink_temp_attachments()

void mutt_unlink_temp_attachments ( void  )

Delete all temporary attachments.

Definition at line 1266 of file mutt_attach.c.

1267 {
1268  struct ListNode *np = NULL;
1269 
1270  STAILQ_FOREACH(np, &TempAttachmentsList, entries)
1271  {
1272  mutt_file_chmod_add(np->data, S_IWUSR);
1273  mutt_file_unlink(np->data);
1274  }
1275 
1276  mutt_list_free(&TempAttachmentsList);
1277 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:
can_print
static bool can_print(struct AttachCtx *actx, struct Body *top, bool tag)
Do we know how to print this attachment type?
Definition: recvattach.c:1058
Menu::oldcurrent
int oldcurrent
For driver use only.
Definition: mutt_menu.h:76
MailcapEntry::composecommand
char * composecommand
Definition: mailcap.h:42
CH_FROM
#define CH_FROM
Retain the "From " message separator?
Definition: copy.h:55
CopyHeaderFlags
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
mutt_endwin
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:572
Email::msgno
int msgno
Number displayed to the user.
Definition: email.h:87
mutt_rfc3676_is_format_flowed
bool mutt_rfc3676_is_format_flowed(struct Body *b)
Is the Email "format-flowed"?
Definition: rfc3676.c:387
AttachCtx
A set of attachments.
Definition: attach.h:49
MailcapEntry::composetypecommand
char * composetypecommand
Definition: mailcap.h:43
ENC_QUOTED_PRINTABLE
@ ENC_QUOTED_PRINTABLE
Quoted-printable text.
Definition: mime.h:51
Body::noconv
bool noconv
Don't do character set conversion.
Definition: body.h:73
print_attachment_list
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:1098
query_save_attachment
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:576
MUTT_MSG_NO_FLAGS
#define MUTT_MSG_NO_FLAGS
No flags are set.
Definition: mx.h:64
MUTT_MC_COMPOSE
@ MUTT_MC_COMPOSE
Mailcap compose field.
Definition: mailcap.h:60
MailcapEntry::xneomuttkeep
bool xneomuttkeep
do not remove the file on command exit
Definition: mailcap.h:50
MUTT_MMDF
@ MUTT_MMDF
'mmdf' Mailbox type
Definition: mailbox.h:49
State::fp_in
FILE * fp_in
File to read from.
Definition: state.h:46
TAILQ_INIT
#define TAILQ_INIT(head)
Definition: queue.h:758
mutt_stamp_attachment
void mutt_stamp_attachment(struct Body *a)
Timestamp an Attachment.
Definition: sendlib.c:893
_
#define _(a)
Definition: message.h:28
NONULL
#define NONULL(x)
Definition: string2.h:37
Mailbox
A mailbox.
Definition: mailbox.h:81
save_attachment_open
static FILE * save_attachment_open(const char *path, enum SaveAttach opt)
Open a file to write an attachment to.
Definition: mutt_attach.c:853
mutt_system
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
AttachPtr::num
int num
Attachment index number.
Definition: attach.h:41
filter_create_fd
pid_t filter_create_fd(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err, int fdin, int fdout, int fderr)
Run a command on a pipe (optionally connect stdin/stdout)
Definition: filter.c:61
MUTT_DISPLAY
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
Pager::actx
struct AttachCtx * actx
Attachment information.
Definition: lib.h:70
ListNode
A List node for strings.
Definition: list.h:34
Buffer
String manipulation buffer.
Definition: buffer.h:33
mutt_rfc3676_space_stuff_attachment
void mutt_rfc3676_space_stuff_attachment(struct Body *b, const char *filename)
Stuff attachments.
Definition: rfc3676.c:532
mutt_file_sanitize_filename
void mutt_file_sanitize_filename(char *path, bool slash)
Replace unsafe characters in a filename.
Definition: file.c:618
MUTT_MC_EDIT
@ MUTT_MC_EDIT
Mailcap edit field.
Definition: mailcap.h:59
Body::offset
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
MailcapEntry::editcommand
char * editcommand
Definition: mailcap.h:44
mailcap_lookup
bool mailcap_lookup(struct Body *a, char *type, size_t typelen, struct MailcapEntry *entry, enum MailcapLookup opt)
Find given type in the list of mailcap files.
Definition: mailcap.c:465
mutt_file_fclose
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
mutt_buffer_is_empty
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
Body
The body of an email.
Definition: body.h:34
SEC_ENCRYPT
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:85
mailcap_expand_command
int mailcap_expand_command(struct Body *a, const char *filename, const char *type, struct Buffer *command)
Expand expandos in a command.
Definition: mailcap.c:69
AttachPtr::fp
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
Pager::email
struct Email * email
Current message.
Definition: lib.h:67
mutt_buffer_mktemp
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
mutt_parse_part
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition: parse.c:1659
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:714
C_AttachSplit
bool C_AttachSplit
Config: Save/print/pipe tagged messages individually.
Definition: recvattach.c:75
TYPE_VIDEO
@ TYPE_VIDEO
Type: 'video/*'.
Definition: mime.h:39
MUTT_YES
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:40
CUR_ATTACH
#define CUR_ATTACH
Definition: recvattach.c:91
Context
The "current" mailbox.
Definition: context.h:38
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
mutt_file_fopen
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
mutt_file_unlink
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
LL_DEBUG1
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
FREE
#define FREE(x)
Definition: memory.h:40
C_AttachSep
char * C_AttachSep
Config: Separator to add between saved/printed/piped attachments.
Definition: recvattach.c:74
mutt_perror
#define mutt_perror(...)
Definition: logging.h:85
MUTT_MC_PRINT
@ MUTT_MC_PRINT
Mailcap print field.
Definition: mailcap.h:61
ContentType
ContentType
Content-Type.
Definition: mime.h:29
Email::path
char * path
Path of Email (for local Mailboxes)
Definition: email.h:92
Body::encoding
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:66
mutt_param_free
void mutt_param_free(struct ParameterList *pl)
Free a ParameterList.
Definition: parameter.c:61
mutt_pipe_attachment
int mutt_pipe_attachment(FILE *fp, struct Body *b, const char *path, char *outfile)
Pipe an attachment to a command.
Definition: mutt_attach.c:707
mutt_buffer_reset
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
Body::tagged
bool tagged
This attachment is tagged.
Definition: body.h:70
mailbox_free
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:71
mutt_decode_save_attachment
int mutt_decode_save_attachment(FILE *fp, struct Body *m, const char *path, int displaying, enum SaveAttach opt)
Decode, then save an attachment.
Definition: mutt_attach.c:1004
Context
WHERE struct Context * Context
Definition: mutt_globals.h:42
mutt_body_free
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
Body::subtype
char * subtype
content-type subtype
Definition: body.h:37
mx_path_resolve
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1681
mutt_list_insert_tail
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
STAILQ_FOREACH
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
mutt_file_chmod_add
int mutt_file_chmod_add(const char *path, mode_t mode)
Add permissions to a file.
Definition: file.c:1067
MUTT_PAGER_MESSAGE
#define MUTT_PAGER_MESSAGE
Definition: lib.h:57
SaveAttach
SaveAttach
Options for saving attachments.
Definition: mutt_attach.h:54
MailcapEntry
A mailcap entry.
Definition: mailcap.h:38
State::fp_out
FILE * fp_out
File to write to.
Definition: state.h:47
TYPE_AUDIO
@ TYPE_AUDIO
Type: 'audio/*'.
Definition: mime.h:32
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
C_Editor
WHERE char * C_Editor
Config: External command to use as an email editor.
Definition: mutt_globals.h:90
MUTT_MC_AUTOVIEW
@ MUTT_MC_AUTOVIEW
Mailcap autoview field.
Definition: mailcap.h:62
mutt_copy_message_fp
int mutt_copy_message_fp(FILE *fp_out, FILE *fp_in, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
make a copy of a message from a FILE pointer
Definition: copy.c:616
MailcapEntry::printcommand
char * printcommand
Definition: mailcap.h:45
PGP_TRADITIONAL_CHECKED
#define PGP_TRADITIONAL_CHECKED
Email has a traditional (inline) signature.
Definition: lib.h:99
MUTT_FILE
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
mutt_any_key_to_continue
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:605
filter_create
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
C_AttachSaveWithoutPrompting
char * C_AttachSaveWithoutPrompting
Config: If true, then don't prompt to save.
Definition: recvattach.c:73
query_quadoption
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:518
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
mutt_path_basename
const char * mutt_path_basename(const char *f)
Find the last component for a pathname.
Definition: path.c:329
Body::xtype
char * xtype
content-type if x-unknown
Definition: body.h:36
mutt_can_decode
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1805
Body::form_name
char * form_name
Content-Disposition form-data name param.
Definition: body.h:41
mutt_edit_file
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition: curs_lib.c:356
Mailbox::type
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
menu_check_recenter
void menu_check_recenter(struct Menu *menu)
Recentre the menu on screen.
Definition: menu.c:544
save_attachment_flowed_helper
static int save_attachment_flowed_helper(FILE *fp, struct Body *b, const char *path, enum SaveAttach flags, struct Email *e)
Helper for unstuffing attachments.
Definition: recvattach.c:529
mutt_edit_content_type
bool mutt_edit_content_type(struct Email *e, struct Body *b, FILE *fp)
Edit the content type of an attachment.
Definition: commands.c:1324
mutt_view_attachment
int mutt_view_attachment(FILE *fp, struct Body *a, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx, struct MuttWindow *win)
View an attachment.
Definition: mutt_attach.c:414
mx_msg_commit
int mx_msg_commit(struct Mailbox *m, struct Message *msg)
Commit a message to a folder - Wrapper for MxOps::msg_commit()
Definition: mx.c:1183
MailcapEntry::command
char * command
Definition: mailcap.h:40
MailcapEntry::needsterminal
bool needsterminal
endwin() and system
Definition: mailcap.h:48
MUTT_VA_PAGER
@ MUTT_VA_PAGER
View attachment in pager using copiousoutput mailcap.
Definition: mutt_attach.h:45
MUTT_VA_AS_TEXT
@ MUTT_VA_AS_TEXT
Force viewing as text.
Definition: mutt_attach.h:44
mutt_do_pager
int mutt_do_pager(const char *banner, const char *tempfile, PagerFlags do_color, struct Pager *info)
Display some page-able text to the user.
Definition: curs_lib.c:691
MUTT_CHARCONV
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
mutt_file_copy_stream
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
TYPE
#define TYPE(body)
Definition: mime.h:89
mx_mbox_close
enum MxStatus mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:632
Body::length
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
save_without_prompting
static int save_without_prompting(FILE *fp, struct Body *body, struct Email *e)
Save the attachment, without prompting each time.
Definition: recvattach.c:674
mutt_rfc3676_space_unstuff_attachment
void mutt_rfc3676_space_unstuff_attachment(struct Body *b, const char *filename)
Unstuff attachments.
Definition: rfc3676.c:511
ENC_8BIT
@ ENC_8BIT
8-bit text
Definition: mime.h:50
APPLICATION_PGP
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:97
MUTT_CM_NO_FLAGS
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
is_from
bool is_from(const char *s, char *path, size_t pathlen, time_t *tp)
Is a string a 'From' header line?
Definition: from.c:48
CH_NO_FLAGS
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:50
Pager::ctx
struct Context * ctx
Current mailbox.
Definition: lib.h:66
mutt_file_symlink
int mutt_file_symlink(const char *oldpath, const char *newpath)
Create a symlink.
Definition: file.c:299
MUTT_PAGER_NO_FLAGS
#define MUTT_PAGER_NO_FLAGS
No flags are set.
Definition: lib.h:42
mailcap_expand_filename
void mailcap_expand_filename(const char *nametemplate, const char *oldfile, struct Buffer *newfile)
Expand a new filename from a template or existing filename.
Definition: mailcap.c:533
MUTT_MC_NO_FLAGS
@ MUTT_MC_NO_FLAGS
No flags set.
Definition: mailcap.h:58
CH_NOSTATUS
#define CH_NOSTATUS
Suppress the status and x-status fields.
Definition: copy.h:57
Body::description
char * description
content-description
Definition: body.h:40
TYPE_MODEL
@ TYPE_MODEL
Type: 'model/*'.
Definition: mime.h:36
mutt_is_message_type
bool mutt_is_message_type(int type, const char *subtype)
Determine if a mime type matches a message or not.
Definition: parse.c:1368
mutt_read_mime_header
struct Body * mutt_read_mime_header(FILE *fp, bool digest)
Parse a MIME header.
Definition: parse.c:1269
Body::parts
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
TYPE_MESSAGE
@ TYPE_MESSAGE
Type: 'message/*'.
Definition: mime.h:35
AttachPtr::body
struct Body * body
Attachment.
Definition: attach.h:36
Context::mailbox
struct Mailbox * mailbox
Definition: context.h:50
MUTT_SAVE_APPEND
@ MUTT_SAVE_APPEND
Append to existing file.
Definition: mutt_attach.h:57
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
MUTT_PAGER_ATTACHMENT
#define MUTT_PAGER_ATTACHMENT
Attachments may exist.
Definition: lib.h:54
MUTT_ADD_FROM
#define MUTT_ADD_FROM
add a From_ line
Definition: mx.h:65
TYPE_IMAGE
@ TYPE_IMAGE
Type: 'image/*'.
Definition: mime.h:34
CH_UPDATE
#define CH_UPDATE
Update the status and x-status fields?
Definition: copy.h:51
C_PrintCommand
WHERE char * C_PrintCommand
Config: External command to print a message.
Definition: mutt_globals.h:103
bool_str_toggle
int bool_str_toggle(struct ConfigSubset *sub, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:213
mutt_buffer_expand_path
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:323
REDRAW_INDEX
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:40
Message::fp
FILE * fp
pointer to the message data
Definition: mx.h:96
mutt_envlist_unset
bool mutt_envlist_unset(const char *name)
Unset an environment variable.
Definition: envlist.c:132
MUTT_QUIET
#define MUTT_QUIET
Do not print any messages.
Definition: mx.h:55
mutt_buffer_get_field
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:260
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
Email::security
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:39
MailcapEntry::copiousoutput
bool copiousoutput
needs pager, basically
Definition: mailcap.h:49
mutt_str_replace
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
filter_wait
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
mutt_adv_mktemp
void mutt_adv_mktemp(struct Buffer *buf)
Create a temporary file.
Definition: muttlib.c:90
WithCrypto
#define WithCrypto
Definition: lib.h:123
MuttWindow::state
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:120
mutt_check_overwrite
int mutt_check_overwrite(const char *attname, const char *path, struct Buffer *fname, enum SaveAttach *opt, char **directory)
Ask the user if overwriting is necessary.
Definition: muttlib.c:621
TYPE_APPLICATION
@ TYPE_APPLICATION
Type: 'application/*'.
Definition: mime.h:33
State
Keep track when processing files.
Definition: state.h:44
mailcap_entry_free
void mailcap_entry_free(struct MailcapEntry **ptr)
Deallocate an struct MailcapEntry.
Definition: mailcap.c:436
MUTT_VA_REGULAR
@ MUTT_VA_REGULAR
View using default method.
Definition: mutt_attach.h:42
Body::stamp
time_t stamp
Time stamp of last encoding update.
Definition: body.h:61
Menu::mdata
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:55
Body::aptr
struct AttachPtr * aptr
Menu information, used in recvattach.c.
Definition: body.h:57
is_multipart
#define is_multipart(body)
Definition: mime.h:82
ENC_BASE64
@ ENC_BASE64
Base-64 encoded text.
Definition: mime.h:52
Menu::max
int max
Number of entries in the menu.
Definition: mutt_menu.h:57
TYPE_TEXT
@ TYPE_TEXT
Type: 'text/*'.
Definition: mime.h:38
menu_redraw
int menu_redraw(struct Menu *menu)
Redraw the parts of the screen that have been flagged to be redrawn.
Definition: menu.c:1270
MailcapLookup
MailcapLookup
Mailcap actions.
Definition: mailcap.h:56
MUTT_SAVE_NO_FLAGS
@ MUTT_SAVE_NO_FLAGS
No flags set.
Definition: mutt_attach.h:56
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
mutt_file_open
int mutt_file_open(const char *path, uint32_t flags)
Open a file.
Definition: file.c:522
Body::type
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
mx_mbox_open
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:309
TYPE_OTHER
@ TYPE_OTHER
Unknown Content-Type.
Definition: mime.h:31
mutt_file_rename
int mutt_file_rename(const char *oldfile, const char *newfile)
Rename a file.
Definition: file.c:1347
OptViewAttach
WHERE bool OptViewAttach
(pseudo) signals that we are viewing attachments
Definition: options.h:55
Menu::redraw
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:58
MUTT_CMD
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:60
mutt_body_handler
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1595
AttachCtx::v2r
short * v2r
Mapping from virtual to real attachment.
Definition: attach.h:58
mutt_buffer_len
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
ListNode::data
char * data
String.
Definition: list.h:36
recvattach_edit_content_type
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:1255
MUTT_CLEAR
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:62
AttachCtx::idx
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
Pager::fp
FILE * fp
Source stream.
Definition: lib.h:69
NeoMutt::sub
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
email_free
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:43
mutt_istrn_equal
bool mutt_istrn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings ignoring case (to a maximum), safely.
Definition: string.c:621
mutt_needs_mailcap
bool mutt_needs_mailcap(struct Body *m)
Does this type need a mailcap entry do display.
Definition: muttlib.c:405
MUTT_MAILDIR
@ MUTT_MAILDIR
'Maildir' Mailbox type
Definition: mailbox.h:51
Body::email
struct Email * email
header information for message/rfc822
Definition: body.h:55
prepend_savedir
static void prepend_savedir(struct Buffer *buf)
Add $attach_save_dir to the beginning of a path.
Definition: recvattach.c:472
WindowState::cols
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
Body::unlink
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
MUTT_APPEND
#define MUTT_APPEND
Open mailbox for appending messages.
Definition: mx.h:53
Menu::current
int current
Current entry.
Definition: mutt_menu.h:56
Body::parameter
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
MUTT_SAVE_OVERWRITE
@ MUTT_SAVE_OVERWRITE
Overwrite existing file.
Definition: mutt_attach.h:58
Pager
An email being displayed.
Definition: lib.h:64
mutt_decode_attachment
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email's attachment.
Definition: handler.c:1845
mx_msg_close
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1204
State::flags
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
mutt_yesorno
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:380
Buffer::data
char * data
Pointer to data.
Definition: buffer.h:35
wait_interactive_filter
static int wait_interactive_filter(pid_t pid)
Wait after an interactive filter.
Definition: mutt_attach.c:382
TYPE_MULTIPART
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition: mime.h:37
Email
The envelope/body of an email.
Definition: email.h:37
mutt_envlist_set
bool mutt_envlist_set(const char *name, const char *value, bool overwrite)
Set an environment variable.
Definition: envlist.c:85
REDRAW_MOTION
#define REDRAW_MOTION
Redraw after moving the menu list.
Definition: mutt_menu.h:41
mutt_add_temp_attachment
void mutt_add_temp_attachment(const char *filename)
Add file to list of temporary attachments.
Definition: mutt_attach.c:1258
mutt_message
#define mutt_message(...)
Definition: logging.h:83
mx_msg_open_new
struct Message * mx_msg_open_new(struct Mailbox *m, const struct Email *e, MsgOpenFlags flags)
Open a new message.
Definition: mx.c:1072
pipe_attachment_list
static void pipe_attachment_list(const 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:980
mutt_lookup_mime_type
enum ContentType mutt_lookup_mime_type(struct Body *att, const char *path)
Find the MIME type for an attachment.
Definition: sendlib.c:565
MUTT_VA_MAILCAP
@ MUTT_VA_MAILCAP
Force viewing using mailcap entry.
Definition: mutt_attach.h:43
Menu::win_index
struct MuttWindow * win_index
Definition: mutt_menu.h:63
mutt_file_fsync_close
int mutt_file_fsync_close(FILE **fp)
Flush the data, before closing a file (and NULL the pointer)
Definition: file.c:169
mutt_list_free
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
MUTT_PRINTING
#define MUTT_PRINTING
Are we printing? - MUTT_DISPLAY "light".
Definition: state.h:37
crypt_valid_passphrase
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:135
CH_UPDATE_LEN
#define CH_UPDATE_LEN
Update Lines: and Content-Length:
Definition: copy.h:61
mutt_save_attachment
int mutt_save_attachment(FILE *fp, struct Body *m, const char *path, enum SaveAttach opt, struct Email *e)
Save an attachment.
Definition: mutt_attach.c:873
Email::read
bool read
Email is read.
Definition: email.h:51
Pager::body
struct Body * body
Current attachment.
Definition: lib.h:68
MUTT_MBOX
@ MUTT_MBOX
'mbox' Mailbox type
Definition: mailbox.h:48
C_Print
WHERE unsigned char C_Print
Config: Confirm before printing a message.
Definition: mutt_globals.h:128
mutt_buffer_strcpy
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
MailcapEntry::nametemplate
char * nametemplate
Definition: mailcap.h:46
LL_DEBUG2
@ LL_DEBUG2
Log at debug level 2.
Definition: logging.h:41
C_WaitKey
WHERE bool C_WaitKey
Config: Prompt to press a key after running external commands.
Definition: mutt_globals.h:169
mailcap_entry_new
struct MailcapEntry * mailcap_entry_new(void)
Allocate memory for a new rfc1524 entry.
Definition: mailcap.c:427
AttachCtx::idxlen
short idxlen
Number of attachmentes.
Definition: attach.h:55
Message
A local copy of an email.
Definition: mx.h:94
Body::filename
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
mutt_error
#define mutt_error(...)
Definition: logging.h:84
mutt_str_copy
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:716