]> granicus.if.org Git - neomutt/commitdiff
tidy handler.c
authorRichard Russon <rich@flatcap.org>
Sat, 2 Jun 2018 21:33:17 +0000 (22:33 +0100)
committerRichard Russon <rich@flatcap.org>
Wed, 6 Jun 2018 14:29:21 +0000 (15:29 +0100)
- Move the function prototypes to a new file `handler.h`
- Rearrange the functions

There are no changes to the code.

16 files changed:
attach.c
copy.c
handler.c
handler.h [new file with mode: 0644]
ncrypt/crypt.c
ncrypt/crypt_gpgme.c
ncrypt/pgp.c
ncrypt/pgpmicalg.c
ncrypt/smime.c
pattern.c
postpone.c
protos.h
recvattach.c
recvcmd.c
remailer.c
sendlib.c

index c9f8c99942e153dedcd4ebf42e33d9e89cda488c..6892e9ec4b0b789e61f009129ad81133e465a5b8 100644 (file)
--- a/attach.c
+++ b/attach.c
@@ -36,6 +36,7 @@
 #include "copy.h"
 #include "filter.h"
 #include "globals.h"
+#include "handler.h"
 #include "header.h"
 #include "mailbox.h"
 #include "mutt_curses.h"
diff --git a/copy.c b/copy.c
index f1d0ece287bb1a2040dceb37d12d99c20d866c8d..f6d9ef6b274f2cc871c3f08264e9d889785f88a2 100644 (file)
--- a/copy.c
+++ b/copy.c
@@ -38,6 +38,7 @@
 #include "context.h"
 #include "envelope.h"
 #include "globals.h"
+#include "handler.h"
 #include "header.h"
 #include "mailbox.h"
 #include "mutt_curses.h"
index 9a8e6250ca29632b05046689cb50599c37e8ef62..9490b53e894b299e9710985a83b4ab54bccdae0b 100644 (file)
--- a/handler.c
+++ b/handler.c
@@ -34,6 +34,7 @@
 #include <unistd.h>
 #include "mutt/mutt.h"
 #include "mutt.h"
+#include "handler.h"
 #include "body.h"
 #include "copy.h"
 #include "enriched.h"
 #include "rfc1524.h"
 #include "rfc3676.h"
 #include "state.h"
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#endif
 
 #define BUFI_SIZE 1000
 #define BUFO_SIZE 2000
 
+#define TXTHTML 1
+#define TXTPLAIN 2
+#define TXTENRICHED 3
+
 typedef int (*handler_t)(struct Body *b, struct State *s);
 
 /**
@@ -318,70 +326,6 @@ static void decode_quoted(struct State *s, long len, bool istext, iconv_t cd)
   state_reset_prefix(s);
 }
 
-/**
- * mutt_decode_base64 - Decode base64-encoded text
- * @param s      State to work with
- * @param len    Length of text to decode
- * @param istext Mime part is plain text
- * @param cd     Iconv conversion descriptor
- */
-void mutt_decode_base64(struct State *s, size_t len, bool istext, iconv_t cd)
-{
-  char buf[5];
-  int ch, i;
-  char bufi[BUFI_SIZE];
-  size_t l = 0;
-
-  buf[4] = '\0';
-
-  if (istext)
-    state_set_prefix(s);
-
-  while (len > 0)
-  {
-    for (i = 0; (i < 4) && (len > 0); len--)
-    {
-      ch = fgetc(s->fpin);
-      if (ch == EOF)
-        break;
-      if ((ch >= 0) && (ch < 128) && (base64val(ch) != -1 || ch == '='))
-        buf[i++] = ch;
-    }
-    if (i != 4)
-    {
-      /* "i" may be zero if there is trailing whitespace, which is not an error */
-      if (i != 0)
-        mutt_debug(2, "didn't get a multiple of 4 chars.\n");
-      break;
-    }
-
-    const int c1 = base64val(buf[0]);
-    const int c2 = base64val(buf[1]);
-    ch = (c1 << 2) | (c2 >> 4);
-    bufi[l++] = ch;
-
-    if (buf[2] == '=')
-      break;
-    const int c3 = base64val(buf[2]);
-    ch = ((c2 & 0xf) << 4) | (c3 >> 2);
-    bufi[l++] = ch;
-
-    if (buf[3] == '=')
-      break;
-    const int c4 = base64val(buf[3]);
-    ch = ((c3 & 0x3) << 6) | c4;
-    bufi[l++] = ch;
-
-    if ((l + 8) >= sizeof(bufi))
-      convert_to_state(cd, bufi, &l, s);
-  }
-
-  convert_to_state(cd, bufi, &l, s);
-  convert_to_state(cd, 0, 0, s);
-
-  state_reset_prefix(s);
-}
-
 /**
  * decode_byte - Decode a uuencoded byte
  * @param ch Character to decode
@@ -554,294 +498,176 @@ static bool is_autoview(struct Body *b)
   return false;
 }
 
-#define TXTHTML 1
-#define TXTPLAIN 2
-#define TXTENRICHED 3
-
 /**
- * alternative_handler - Handler for multipart alternative emails
+ * autoview_handler - Handler for autoviewable attachments
  * @param a Body of the email
  * @param s State of text being processed
  * @retval 0 Success
  * @retval -1 Error
  */
-static int alternative_handler(struct Body *a, struct State *s)
+static int autoview_handler(struct Body *a, struct State *s)
 {
-  struct Body *choice = NULL;
-  struct Body *b = NULL;
-  bool mustfree = false;
+  struct Rfc1524MailcapEntry *entry = rfc1524_new_entry();
+  char buffer[LONG_STRING];
+  char type[STRING];
+  char command[LONG_STRING];
+  char tempfile[_POSIX_PATH_MAX] = "";
+  char *fname = NULL;
+  FILE *fpin = NULL;
+  FILE *fpout = NULL;
+  FILE *fperr = NULL;
+  int piped = false;
+  pid_t thepid;
   int rc = 0;
 
-  if ((a->encoding == ENCBASE64) || (a->encoding == ENCQUOTEDPRINTABLE) ||
-      (a->encoding == ENCUUENCODED))
-  {
-    struct stat st;
-    mustfree = true;
-    fstat(fileno(s->fpin), &st);
-    b = mutt_body_new();
-    b->length = (long) st.st_size;
-    b->parts = mutt_parse_multipart(
-        s->fpin, mutt_param_get(&a->parameter, "boundary"), (long) st.st_size,
-        (mutt_str_strcasecmp("digest", a->subtype) == 0));
-  }
-  else
-    b = a;
+  snprintf(type, sizeof(type), "%s/%s", TYPE(a), a->subtype);
+  rfc1524_mailcap_lookup(a, type, entry, MUTT_AUTOVIEW);
 
-  a = b;
+  fname = mutt_str_strdup(a->filename);
+  mutt_file_sanitize_filename(fname, true);
+  rfc1524_expand_filename(entry->nametemplate, fname, tempfile, sizeof(tempfile));
+  FREE(&fname);
 
-  /* First, search list of preferred types */
-  struct ListNode *np;
-  STAILQ_FOREACH(np, &AlternativeOrderList, entries)
+  if (entry->command)
   {
-    int btlen; /* length of basetype */
-    bool wild; /* do we have a wildcard to match all subtypes? */
+    mutt_str_strfcpy(command, entry->command, sizeof(command));
 
-    char *c = strchr(np->data, '/');
-    if (c)
+    /* rfc1524_expand_command returns 0 if the file is required */
+    piped = rfc1524_expand_command(a, tempfile, type, command, sizeof(command));
+
+    if (s->flags & MUTT_DISPLAY)
     {
-      wild = ((c[1] == '*') && (c[2] == 0));
-      btlen = c - np->data;
+      state_mark_attach(s);
+      state_printf(s, _("[-- Autoview using %s --]\n"), command);
+      mutt_message(_("Invoking autoview command: %s"), command);
     }
-    else
+
+    fpin = mutt_file_fopen(tempfile, "w+");
+    if (!fpin)
     {
-      wild = true;
-      btlen = mutt_str_strlen(np->data);
+      mutt_perror("fopen");
+      rfc1524_free_entry(&entry);
+      return -1;
     }
 
-    if (a->parts)
-      b = a->parts;
+    mutt_file_copy_bytes(s->fpin, fpin, a->length);
+
+    if (!piped)
+    {
+      mutt_file_fclose(&fpin);
+      thepid = mutt_create_filter(command, NULL, &fpout, &fperr);
+    }
     else
-      b = a;
-    while (b)
     {
-      const char *bt = TYPE(b);
-      if ((mutt_str_strncasecmp(bt, np->data, btlen) == 0) && (bt[btlen] == 0))
-      {
-        /* the basetype matches */
-        if (wild || (mutt_str_strcasecmp(np->data + btlen + 1, b->subtype) == 0))
-        {
-          choice = b;
-        }
-      }
-      b = b->next;
+      unlink(tempfile);
+      fflush(fpin);
+      rewind(fpin);
+      thepid = mutt_create_filter_fd(command, NULL, &fpout, &fperr, fileno(fpin), -1, -1);
     }
 
-    if (choice)
-      break;
-  }
-
-  /* Next, look for an autoviewable type */
-  if (!choice)
-  {
-    if (a->parts)
-      b = a->parts;
-    else
-      b = a;
-    while (b)
+    if (thepid < 0)
     {
-      if (is_autoview(b))
-        choice = b;
-      b = b->next;
+      mutt_perror(_("Can't create filter"));
+      if (s->flags & MUTT_DISPLAY)
+      {
+        state_mark_attach(s);
+        state_printf(s, _("[-- Can't run %s. --]\n"), command);
+      }
+      rc = -1;
+      goto bail;
     }
-  }
 
-  /* Then, look for a text entry */
-  if (!choice)
-  {
-    if (a->parts)
-      b = a->parts;
-    else
-      b = a;
-    int type = 0;
-    while (b)
+    if (s->prefix)
     {
-      if (b->type == TYPETEXT)
+      while (fgets(buffer, sizeof(buffer), fpout) != NULL)
       {
-        if ((mutt_str_strcasecmp("plain", b->subtype) == 0) && (type <= TXTPLAIN))
-        {
-          choice = b;
-          type = TXTPLAIN;
-        }
-        else if ((mutt_str_strcasecmp("enriched", b->subtype) == 0) && (type <= TXTENRICHED))
+        state_puts(s->prefix, s);
+        state_puts(buffer, s);
+      }
+      /* check for data on stderr */
+      if (fgets(buffer, sizeof(buffer), fperr))
+      {
+        if (s->flags & MUTT_DISPLAY)
         {
-          choice = b;
-          type = TXTENRICHED;
+          state_mark_attach(s);
+          state_printf(s, _("[-- Autoview stderr of %s --]\n"), command);
         }
-        else if ((mutt_str_strcasecmp("html", b->subtype) == 0) && (type <= TXTHTML))
+
+        state_puts(s->prefix, s);
+        state_puts(buffer, s);
+        while (fgets(buffer, sizeof(buffer), fperr) != NULL)
         {
-          choice = b;
-          type = TXTHTML;
+          state_puts(s->prefix, s);
+          state_puts(buffer, s);
         }
       }
-      b = b->next;
     }
-  }
-
-  /* Finally, look for other possibilities */
-  if (!choice)
-  {
-    if (a->parts)
-      b = a->parts;
     else
-      b = a;
-    while (b)
     {
-      if (mutt_can_decode(b))
-        choice = b;
-      b = b->next;
+      mutt_file_copy_stream(fpout, s->fpout);
+      /* Check for stderr messages */
+      if (fgets(buffer, sizeof(buffer), fperr))
+      {
+        if (s->flags & MUTT_DISPLAY)
+        {
+          state_mark_attach(s);
+          state_printf(s, _("[-- Autoview stderr of %s --]\n"), command);
+        }
+
+        state_puts(buffer, s);
+        mutt_file_copy_stream(fperr, s->fpout);
+      }
     }
-  }
 
-  if (choice)
-  {
-    if (s->flags & MUTT_DISPLAY && !Weed)
-    {
-      fseeko(s->fpin, choice->hdr_offset, SEEK_SET);
-      mutt_file_copy_bytes(s->fpin, s->fpout, choice->offset - choice->hdr_offset);
-    }
-
-    if (mutt_str_strcmp("info", ShowMultipartAlternative) == 0)
-    {
-      print_part_line(s, choice, 0);
-    }
-    mutt_body_handler(choice, s);
+  bail:
+    mutt_file_fclose(&fpout);
+    mutt_file_fclose(&fperr);
 
-    if (mutt_str_strcmp("info", ShowMultipartAlternative) == 0)
-    {
-      if (a->parts)
-        b = a->parts;
-      else
-        b = a;
-      int count = 0;
-      while (b)
-      {
-        if (choice != b)
-        {
-          count += 1;
-          if (count == 1)
-            state_putc('\n', s);
+    mutt_wait_filter(thepid);
+    if (piped)
+      mutt_file_fclose(&fpin);
+    else
+      mutt_file_unlink(tempfile);
 
-          print_part_line(s, b, count);
-        }
-        b = b->next;
-      }
-    }
-  }
-  else if (s->flags & MUTT_DISPLAY)
-  {
-    /* didn't find anything that we could display! */
-    state_mark_attach(s);
-    state_puts(_("[-- Error:  Could not display any parts of "
-                 "Multipart/Alternative! --]\n"),
-               s);
-    rc = -1;
+    if (s->flags & MUTT_DISPLAY)
+      mutt_clear_error();
   }
-
-  if (mustfree)
-    mutt_body_free(&a);
+  rfc1524_free_entry(&entry);
 
   return rc;
 }
 
 /**
- * multilingual_handler - Handler for multi-lingual emails
- * @param a Body of the email
- * @param s State of text being processed
+ * text_plain_handler - Handler for plain text
+ * @param b Body of email (UNUSED)
+ * @param s State to work with
  * @retval 0 Always
+ *
+ * When generating format=flowed ($text_flowed is set) from format=fixed, strip
+ * all trailing spaces to improve interoperability; if $text_flowed is unset,
+ * simply verbatim copy input.
  */
-static int multilingual_handler(struct Body *a, struct State *s)
+static int text_plain_handler(struct Body *b, struct State *s)
 {
-  struct Body *choice = NULL;
-  struct Body *b = NULL;
-  bool mustfree = false;
-  int rc = 0;
-  struct Body *first_part = NULL;
-  struct Body *zxx_part = NULL;
-  char *lang = NULL;
-
-  mutt_debug(2, "RFC8255 >> entering in handler multilingual handler\n");
-  if ((a->encoding == ENCBASE64) || (a->encoding == ENCQUOTEDPRINTABLE) ||
-      (a->encoding == ENCUUENCODED))
-  {
-    struct stat st;
-    mustfree = true;
-    fstat(fileno(s->fpin), &st);
-    b = mutt_body_new();
-    b->length = (long) st.st_size;
-    b->parts = mutt_parse_multipart(
-        s->fpin, mutt_param_get(&a->parameter, "boundary"), (long) st.st_size,
-        (mutt_str_strcasecmp("digest", a->subtype) == 0));
-  }
-  else
-    b = a;
-
-  a = b;
-
-  if (a->parts)
-    b = a->parts;
-  else
-    b = a;
-
-  char *preferred_languages = NULL;
-  if (PreferredLanguages)
-  {
-    mutt_debug(2, "RFC8255 >> preferred_languages set in config to '%s'\n", PreferredLanguages);
-    preferred_languages = mutt_str_strdup(PreferredLanguages);
-    lang = strtok(preferred_languages, ",");
-  }
+  char *buf = NULL;
+  size_t l = 0, sz = 0;
 
-  while (lang)
+  while ((buf = mutt_file_read_line(buf, &sz, s->fpin, NULL, 0)))
   {
-    while (b)
+    if ((mutt_str_strcmp(buf, "-- ") != 0) && TextFlowed)
     {
-      if (mutt_can_decode(b))
-      {
-        if (!first_part)
-          first_part = b;
-
-        if (b->language && (mutt_str_strcmp("zxx", b->language) == 0))
-          zxx_part = b;
-
-        mutt_debug(2, "RFC8255 >> comparing configuration preferred_language='%s' to mail part content-language='%s'\n",
-                   lang, b->language);
-        if (lang && b->language && (mutt_str_strcmp(lang, b->language) == 0))
-        {
-          mutt_debug(2, "RFC8255 >> preferred_language='%s' matches content-language='%s' >> part selected to be displayed\n",
-                     lang, b->language);
-          choice = b;
-          break;
-        }
-      }
-
-      b = b->next;
+      l = mutt_str_strlen(buf);
+      while (l > 0 && buf[l - 1] == ' ')
+        buf[--l] = '\0';
     }
-
-    if (choice)
-      break;
-
-    lang = strtok(NULL, ",");
-
-    if (a->parts)
-      b = a->parts;
-    else
-      b = a;
-  }
-
-  if (choice)
-    mutt_body_handler(choice, s);
-  else
-  {
-    if (zxx_part)
-      mutt_body_handler(zxx_part, s);
-    else
-      mutt_body_handler(first_part, s);
+    if (s->prefix)
+      state_puts(s->prefix, s);
+    state_puts(buf, s);
+    state_putc('\n', s);
   }
 
-  if (mustfree)
-    mutt_body_free(&a);
-
-  FREE(&preferred_languages);
-  return rc;
+  FREE(&buf);
+  return 0;
 }
 
 /**
@@ -899,305 +725,48 @@ static int message_handler(struct Body *a, struct State *s)
 }
 
 /**
- * mutt_can_decode - Will decoding the attachment produce any output
- * @param a Body of email to test
- * @retval true Decoding the attachment will produce output
- */
-bool mutt_can_decode(struct Body *a)
-{
-  if (is_autoview(a))
-    return true;
-  else if (a->type == TYPETEXT)
-    return true;
-  else if (a->type == TYPEMESSAGE)
-    return true;
-  else if (a->type == TYPEMULTIPART)
-  {
-    if (WithCrypto)
-    {
-      if ((mutt_str_strcasecmp(a->subtype, "signed") == 0) ||
-          (mutt_str_strcasecmp(a->subtype, "encrypted") == 0))
-      {
-        return true;
-      }
-    }
-
-    for (struct Body *b = a->parts; b; b = b->next)
-    {
-      if (mutt_can_decode(b))
-        return true;
-    }
-  }
-  else if ((WithCrypto != 0) && a->type == TYPEAPPLICATION)
-  {
-    if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_is_application_pgp(a))
-      return true;
-    if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(a))
-      return true;
-  }
-
-  return false;
-}
-
-/**
- * multipart_handler - Handler for multipart emails
- * @param a Body of the email
+ * external_body_handler - Handler for external-body emails
+ * @param b Body of the email
  * @param s State of text being processed
  * @retval 0 Success
  * @retval -1 Error
  */
-static int multipart_handler(struct Body *a, struct State *s)
+static int external_body_handler(struct Body *b, struct State *s)
 {
-  struct Body *b = NULL, *p = NULL;
-  struct stat st;
-  int count;
-  int rc = 0;
+  const char *str = NULL;
+  char strbuf[LONG_STRING]; // STRING might be too short but LONG_STRING should be large enough
 
-  if ((a->encoding == ENCBASE64) || (a->encoding == ENCQUOTEDPRINTABLE) ||
-      (a->encoding == ENCUUENCODED))
+  const char *access_type = mutt_param_get(&b->parameter, "access-type");
+  if (!access_type)
   {
-    fstat(fileno(s->fpin), &st);
-    b = mutt_body_new();
-    b->length = (long) st.st_size;
-    b->parts = mutt_parse_multipart(
-        s->fpin, mutt_param_get(&a->parameter, "boundary"), (long) st.st_size,
-        (mutt_str_strcasecmp("digest", a->subtype) == 0));
+    if (s->flags & MUTT_DISPLAY)
+    {
+      state_mark_attach(s);
+      state_puts(_("[-- Error: message/external-body has no access-type "
+                   "parameter --]\n"),
+                 s);
+      return 0;
+    }
+    else
+      return -1;
   }
+
+  const char *expiration = mutt_param_get(&b->parameter, "expiration");
+  time_t expire;
+  if (expiration)
+    expire = mutt_date_parse_date(expiration, NULL);
   else
-    b = a;
+    expire = -1;
 
-  for (p = b->parts, count = 1; p; p = p->next, count++)
+  if (mutt_str_strcasecmp(access_type, "x-mutt-deleted") == 0)
   {
-    if (s->flags & MUTT_DISPLAY)
+    if (s->flags & (MUTT_DISPLAY | MUTT_PRINTING))
     {
-      state_mark_attach(s);
-      if (p->description || p->filename || p->form_name)
-      {
-        /* L10N: %s is the attachment description, filename or form_name. */
-        state_printf(s, _("[-- Attachment #%d: %s --]\n"), count,
-                     p->description ? p->description :
-                                      p->filename ? p->filename : p->form_name);
-      }
-      else
-        state_printf(s, _("[-- Attachment #%d --]\n"), count);
-      print_part_line(s, p, 0);
-      if (!Weed)
-      {
-        fseeko(s->fpin, p->hdr_offset, SEEK_SET);
-        mutt_file_copy_bytes(s->fpin, s->fpout, p->offset - p->hdr_offset);
-      }
-      else
-        state_putc('\n', s);
-    }
-
-    rc = mutt_body_handler(p, s);
-    state_putc('\n', s);
-
-    if (rc != 0)
-    {
-      mutt_error(_("One or more parts of this message could not be displayed"));
-      mutt_debug(1, "Failed on attachment #%d, type %s/%s.\n", count, TYPE(p),
-                 NONULL(p->subtype));
-    }
-
-    if ((s->flags & MUTT_REPLYING) && IncludeOnlyfirst && (s->flags & MUTT_FIRSTDONE))
-    {
-      break;
-    }
-  }
-
-  if ((a->encoding == ENCBASE64) || (a->encoding == ENCQUOTEDPRINTABLE) ||
-      (a->encoding == ENCUUENCODED))
-    mutt_body_free(&b);
-
-  /* make failure of a single part non-fatal */
-  if (rc < 0)
-    rc = 1;
-  return rc;
-}
-
-/**
- * autoview_handler - Handler for autoviewable attachments
- * @param a Body of the email
- * @param s State of text being processed
- * @retval 0 Success
- * @retval -1 Error
- */
-static int autoview_handler(struct Body *a, struct State *s)
-{
-  struct Rfc1524MailcapEntry *entry = rfc1524_new_entry();
-  char buffer[LONG_STRING];
-  char type[STRING];
-  char command[LONG_STRING];
-  char tempfile[_POSIX_PATH_MAX] = "";
-  char *fname = NULL;
-  FILE *fpin = NULL;
-  FILE *fpout = NULL;
-  FILE *fperr = NULL;
-  int piped = false;
-  pid_t thepid;
-  int rc = 0;
-
-  snprintf(type, sizeof(type), "%s/%s", TYPE(a), a->subtype);
-  rfc1524_mailcap_lookup(a, type, entry, MUTT_AUTOVIEW);
-
-  fname = mutt_str_strdup(a->filename);
-  mutt_file_sanitize_filename(fname, true);
-  rfc1524_expand_filename(entry->nametemplate, fname, tempfile, sizeof(tempfile));
-  FREE(&fname);
-
-  if (entry->command)
-  {
-    mutt_str_strfcpy(command, entry->command, sizeof(command));
-
-    /* rfc1524_expand_command returns 0 if the file is required */
-    piped = rfc1524_expand_command(a, tempfile, type, command, sizeof(command));
-
-    if (s->flags & MUTT_DISPLAY)
-    {
-      state_mark_attach(s);
-      state_printf(s, _("[-- Autoview using %s --]\n"), command);
-      mutt_message(_("Invoking autoview command: %s"), command);
-    }
-
-    fpin = mutt_file_fopen(tempfile, "w+");
-    if (!fpin)
-    {
-      mutt_perror("fopen");
-      rfc1524_free_entry(&entry);
-      return -1;
-    }
-
-    mutt_file_copy_bytes(s->fpin, fpin, a->length);
-
-    if (!piped)
-    {
-      mutt_file_fclose(&fpin);
-      thepid = mutt_create_filter(command, NULL, &fpout, &fperr);
-    }
-    else
-    {
-      unlink(tempfile);
-      fflush(fpin);
-      rewind(fpin);
-      thepid = mutt_create_filter_fd(command, NULL, &fpout, &fperr, fileno(fpin), -1, -1);
-    }
-
-    if (thepid < 0)
-    {
-      mutt_perror(_("Can't create filter"));
-      if (s->flags & MUTT_DISPLAY)
-      {
-        state_mark_attach(s);
-        state_printf(s, _("[-- Can't run %s. --]\n"), command);
-      }
-      rc = -1;
-      goto bail;
-    }
-
-    if (s->prefix)
-    {
-      while (fgets(buffer, sizeof(buffer), fpout) != NULL)
-      {
-        state_puts(s->prefix, s);
-        state_puts(buffer, s);
-      }
-      /* check for data on stderr */
-      if (fgets(buffer, sizeof(buffer), fperr))
-      {
-        if (s->flags & MUTT_DISPLAY)
-        {
-          state_mark_attach(s);
-          state_printf(s, _("[-- Autoview stderr of %s --]\n"), command);
-        }
-
-        state_puts(s->prefix, s);
-        state_puts(buffer, s);
-        while (fgets(buffer, sizeof(buffer), fperr) != NULL)
-        {
-          state_puts(s->prefix, s);
-          state_puts(buffer, s);
-        }
-      }
-    }
-    else
-    {
-      mutt_file_copy_stream(fpout, s->fpout);
-      /* Check for stderr messages */
-      if (fgets(buffer, sizeof(buffer), fperr))
-      {
-        if (s->flags & MUTT_DISPLAY)
-        {
-          state_mark_attach(s);
-          state_printf(s, _("[-- Autoview stderr of %s --]\n"), command);
-        }
-
-        state_puts(buffer, s);
-        mutt_file_copy_stream(fperr, s->fpout);
-      }
-    }
-
-  bail:
-    mutt_file_fclose(&fpout);
-    mutt_file_fclose(&fperr);
-
-    mutt_wait_filter(thepid);
-    if (piped)
-      mutt_file_fclose(&fpin);
-    else
-      mutt_file_unlink(tempfile);
-
-    if (s->flags & MUTT_DISPLAY)
-      mutt_clear_error();
-  }
-  rfc1524_free_entry(&entry);
-
-  return rc;
-}
-
-/**
- * external_body_handler - Handler for external-body emails
- * @param b Body of the email
- * @param s State of text being processed
- * @retval 0 Success
- * @retval -1 Error
- */
-static int external_body_handler(struct Body *b, struct State *s)
-{
-  const char *str = NULL;
-  char strbuf[LONG_STRING]; // STRING might be too short but LONG_STRING should be large enough
-
-  const char *access_type = mutt_param_get(&b->parameter, "access-type");
-  if (!access_type)
-  {
-    if (s->flags & MUTT_DISPLAY)
-    {
-      state_mark_attach(s);
-      state_puts(_("[-- Error: message/external-body has no access-type "
-                   "parameter --]\n"),
-                 s);
-      return 0;
-    }
-    else
-      return -1;
-  }
-
-  const char *expiration = mutt_param_get(&b->parameter, "expiration");
-  time_t expire;
-  if (expiration)
-    expire = mutt_date_parse_date(expiration, NULL);
-  else
-    expire = -1;
-
-  if (mutt_str_strcasecmp(access_type, "x-mutt-deleted") == 0)
-  {
-    if (s->flags & (MUTT_DISPLAY | MUTT_PRINTING))
-    {
-      char pretty_size[10];
-      long size = 0;
-
-      char *length = mutt_param_get(&b->parameter, "length");
-      if (length)
+      char pretty_size[10];
+      long size = 0;
+
+      char *length = mutt_param_get(&b->parameter, "length");
+      if (length)
       {
         size = strtol(length, NULL, 10);
         mutt_str_pretty_size(pretty_size, sizeof(pretty_size), size);
@@ -1328,90 +897,366 @@ static int external_body_handler(struct Body *b, struct State *s)
 }
 
 /**
- * mutt_decode_attachment - Decode an email's attachment
- * @param b Body of the email
+ * alternative_handler - Handler for multipart alternative emails
+ * @param a Body of the email
  * @param s State of text being processed
+ * @retval 0 Success
+ * @retval -1 Error
  */
-void mutt_decode_attachment(struct Body *b, struct State *s)
+static int alternative_handler(struct Body *a, struct State *s)
 {
-  int istext = mutt_is_text_part(b);
-  iconv_t cd = (iconv_t)(-1);
+  struct Body *choice = NULL;
+  struct Body *b = NULL;
+  bool mustfree = false;
+  int rc = 0;
 
-  if (istext && s->flags & MUTT_CHARCONV)
+  if ((a->encoding == ENCBASE64) || (a->encoding == ENCQUOTEDPRINTABLE) ||
+      (a->encoding == ENCUUENCODED))
   {
-    char *charset = mutt_param_get(&b->parameter, "charset");
-    if (!charset && AssumedCharset && *AssumedCharset)
-      charset = mutt_ch_get_default_charset();
-    if (charset && Charset)
-      cd = mutt_ch_iconv_open(Charset, charset, MUTT_ICONV_HOOK_FROM);
+    struct stat st;
+    mustfree = true;
+    fstat(fileno(s->fpin), &st);
+    b = mutt_body_new();
+    b->length = (long) st.st_size;
+    b->parts = mutt_parse_multipart(
+        s->fpin, mutt_param_get(&a->parameter, "boundary"), (long) st.st_size,
+        (mutt_str_strcasecmp("digest", a->subtype) == 0));
   }
-  else if (istext && b->charset)
-    cd = mutt_ch_iconv_open(Charset, b->charset, MUTT_ICONV_HOOK_FROM);
+  else
+    b = a;
 
-  fseeko(s->fpin, b->offset, SEEK_SET);
-  switch (b->encoding)
+  a = b;
+
+  /* First, search list of preferred types */
+  struct ListNode *np;
+  STAILQ_FOREACH(np, &AlternativeOrderList, entries)
   {
-    case ENCQUOTEDPRINTABLE:
-      decode_quoted(s, b->length,
-                    istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
-                               mutt_is_application_pgp(b)),
-                    cd);
-      break;
-    case ENCBASE64:
-      mutt_decode_base64(s, b->length,
-                         istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
-                                    mutt_is_application_pgp(b)),
-                         cd);
-      break;
-    case ENCUUENCODED:
-      decode_uuencoded(s, b->length,
-                       istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
-                                  mutt_is_application_pgp(b)),
-                       cd);
+    int btlen; /* length of basetype */
+    bool wild; /* do we have a wildcard to match all subtypes? */
+
+    char *c = strchr(np->data, '/');
+    if (c)
+    {
+      wild = ((c[1] == '*') && (c[2] == 0));
+      btlen = c - np->data;
+    }
+    else
+    {
+      wild = true;
+      btlen = mutt_str_strlen(np->data);
+    }
+
+    if (a->parts)
+      b = a->parts;
+    else
+      b = a;
+    while (b)
+    {
+      const char *bt = TYPE(b);
+      if ((mutt_str_strncasecmp(bt, np->data, btlen) == 0) && (bt[btlen] == 0))
+      {
+        /* the basetype matches */
+        if (wild || (mutt_str_strcasecmp(np->data + btlen + 1, b->subtype) == 0))
+        {
+          choice = b;
+        }
+      }
+      b = b->next;
+    }
+
+    if (choice)
       break;
-    default:
-      decode_xbit(s, b->length,
-                  istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
-                             mutt_is_application_pgp(b)),
-                  cd);
+  }
+
+  /* Next, look for an autoviewable type */
+  if (!choice)
+  {
+    if (a->parts)
+      b = a->parts;
+    else
+      b = a;
+    while (b)
+    {
+      if (is_autoview(b))
+        choice = b;
+      b = b->next;
+    }
+  }
+
+  /* Then, look for a text entry */
+  if (!choice)
+  {
+    if (a->parts)
+      b = a->parts;
+    else
+      b = a;
+    int type = 0;
+    while (b)
+    {
+      if (b->type == TYPETEXT)
+      {
+        if ((mutt_str_strcasecmp("plain", b->subtype) == 0) && (type <= TXTPLAIN))
+        {
+          choice = b;
+          type = TXTPLAIN;
+        }
+        else if ((mutt_str_strcasecmp("enriched", b->subtype) == 0) && (type <= TXTENRICHED))
+        {
+          choice = b;
+          type = TXTENRICHED;
+        }
+        else if ((mutt_str_strcasecmp("html", b->subtype) == 0) && (type <= TXTHTML))
+        {
+          choice = b;
+          type = TXTHTML;
+        }
+      }
+      b = b->next;
+    }
+  }
+
+  /* Finally, look for other possibilities */
+  if (!choice)
+  {
+    if (a->parts)
+      b = a->parts;
+    else
+      b = a;
+    while (b)
+    {
+      if (mutt_can_decode(b))
+        choice = b;
+      b = b->next;
+    }
+  }
+
+  if (choice)
+  {
+    if (s->flags & MUTT_DISPLAY && !Weed)
+    {
+      fseeko(s->fpin, choice->hdr_offset, SEEK_SET);
+      mutt_file_copy_bytes(s->fpin, s->fpout, choice->offset - choice->hdr_offset);
+    }
+
+    if (mutt_str_strcmp("info", ShowMultipartAlternative) == 0)
+    {
+      print_part_line(s, choice, 0);
+    }
+    mutt_body_handler(choice, s);
+
+    if (mutt_str_strcmp("info", ShowMultipartAlternative) == 0)
+    {
+      if (a->parts)
+        b = a->parts;
+      else
+        b = a;
+      int count = 0;
+      while (b)
+      {
+        if (choice != b)
+        {
+          count += 1;
+          if (count == 1)
+            state_putc('\n', s);
+
+          print_part_line(s, b, count);
+        }
+        b = b->next;
+      }
+    }
+  }
+  else if (s->flags & MUTT_DISPLAY)
+  {
+    /* didn't find anything that we could display! */
+    state_mark_attach(s);
+    state_puts(_("[-- Error:  Could not display any parts of "
+                 "Multipart/Alternative! --]\n"),
+               s);
+    rc = -1;
+  }
+
+  if (mustfree)
+    mutt_body_free(&a);
+
+  return rc;
+}
+
+/**
+ * multilingual_handler - Handler for multi-lingual emails
+ * @param a Body of the email
+ * @param s State of text being processed
+ * @retval 0 Always
+ */
+static int multilingual_handler(struct Body *a, struct State *s)
+{
+  struct Body *choice = NULL;
+  struct Body *b = NULL;
+  bool mustfree = false;
+  int rc = 0;
+  struct Body *first_part = NULL;
+  struct Body *zxx_part = NULL;
+  char *lang = NULL;
+
+  mutt_debug(2, "RFC8255 >> entering in handler multilingual handler\n");
+  if ((a->encoding == ENCBASE64) || (a->encoding == ENCQUOTEDPRINTABLE) ||
+      (a->encoding == ENCUUENCODED))
+  {
+    struct stat st;
+    mustfree = true;
+    fstat(fileno(s->fpin), &st);
+    b = mutt_body_new();
+    b->length = (long) st.st_size;
+    b->parts = mutt_parse_multipart(
+        s->fpin, mutt_param_get(&a->parameter, "boundary"), (long) st.st_size,
+        (mutt_str_strcasecmp("digest", a->subtype) == 0));
+  }
+  else
+    b = a;
+
+  a = b;
+
+  if (a->parts)
+    b = a->parts;
+  else
+    b = a;
+
+  char *preferred_languages = NULL;
+  if (PreferredLanguages)
+  {
+    mutt_debug(2, "RFC8255 >> preferred_languages set in config to '%s'\n", PreferredLanguages);
+    preferred_languages = mutt_str_strdup(PreferredLanguages);
+    lang = strtok(preferred_languages, ",");
+  }
+
+  while (lang)
+  {
+    while (b)
+    {
+      if (mutt_can_decode(b))
+      {
+        if (!first_part)
+          first_part = b;
+
+        if (b->language && (mutt_str_strcmp("zxx", b->language) == 0))
+          zxx_part = b;
+
+        mutt_debug(2, "RFC8255 >> comparing configuration preferred_language='%s' to mail part content-language='%s'\n",
+                   lang, b->language);
+        if (lang && b->language && (mutt_str_strcmp(lang, b->language) == 0))
+        {
+          mutt_debug(2, "RFC8255 >> preferred_language='%s' matches content-language='%s' >> part selected to be displayed\n",
+                     lang, b->language);
+          choice = b;
+          break;
+        }
+      }
+
+      b = b->next;
+    }
+
+    if (choice)
       break;
+
+    lang = strtok(NULL, ",");
+
+    if (a->parts)
+      b = a->parts;
+    else
+      b = a;
+  }
+
+  if (choice)
+    mutt_body_handler(choice, s);
+  else
+  {
+    if (zxx_part)
+      mutt_body_handler(zxx_part, s);
+    else
+      mutt_body_handler(first_part, s);
   }
 
-  if (cd != (iconv_t)(-1))
-    iconv_close(cd);
+  if (mustfree)
+    mutt_body_free(&a);
+
+  FREE(&preferred_languages);
+  return rc;
 }
 
 /**
- * text_plain_handler - Handler for plain text
- * @param b Body of email (UNUSED)
- * @param s State to work with
- * @retval 0 Always
- *
- * When generating format=flowed ($text_flowed is set) from format=fixed, strip
- * all trailing spaces to improve interoperability; if $text_flowed is unset,
- * simply verbatim copy input.
+ * multipart_handler - Handler for multipart emails
+ * @param a Body of the email
+ * @param s State of text being processed
+ * @retval 0 Success
+ * @retval -1 Error
  */
-static int text_plain_handler(struct Body *b, struct State *s)
+static int multipart_handler(struct Body *a, struct State *s)
 {
-  char *buf = NULL;
-  size_t l = 0, sz = 0;
+  struct Body *b = NULL, *p = NULL;
+  struct stat st;
+  int count;
+  int rc = 0;
 
-  while ((buf = mutt_file_read_line(buf, &sz, s->fpin, NULL, 0)))
+  if ((a->encoding == ENCBASE64) || (a->encoding == ENCQUOTEDPRINTABLE) ||
+      (a->encoding == ENCUUENCODED))
   {
-    if ((mutt_str_strcmp(buf, "-- ") != 0) && TextFlowed)
+    fstat(fileno(s->fpin), &st);
+    b = mutt_body_new();
+    b->length = (long) st.st_size;
+    b->parts = mutt_parse_multipart(
+        s->fpin, mutt_param_get(&a->parameter, "boundary"), (long) st.st_size,
+        (mutt_str_strcasecmp("digest", a->subtype) == 0));
+  }
+  else
+    b = a;
+
+  for (p = b->parts, count = 1; p; p = p->next, count++)
+  {
+    if (s->flags & MUTT_DISPLAY)
     {
-      l = mutt_str_strlen(buf);
-      while (l > 0 && buf[l - 1] == ' ')
-        buf[--l] = '\0';
+      state_mark_attach(s);
+      if (p->description || p->filename || p->form_name)
+      {
+        /* L10N: %s is the attachment description, filename or form_name. */
+        state_printf(s, _("[-- Attachment #%d: %s --]\n"), count,
+                     p->description ? p->description :
+                                      p->filename ? p->filename : p->form_name);
+      }
+      else
+        state_printf(s, _("[-- Attachment #%d --]\n"), count);
+      print_part_line(s, p, 0);
+      if (!Weed)
+      {
+        fseeko(s->fpin, p->hdr_offset, SEEK_SET);
+        mutt_file_copy_bytes(s->fpin, s->fpout, p->offset - p->hdr_offset);
+      }
+      else
+        state_putc('\n', s);
     }
-    if (s->prefix)
-      state_puts(s->prefix, s);
-    state_puts(buf, s);
+
+    rc = mutt_body_handler(p, s);
     state_putc('\n', s);
+
+    if (rc != 0)
+    {
+      mutt_error(_("One or more parts of this message could not be displayed"));
+      mutt_debug(1, "Failed on attachment #%d, type %s/%s.\n", count, TYPE(p),
+                 NONULL(p->subtype));
+    }
+
+    if ((s->flags & MUTT_REPLYING) && IncludeOnlyfirst && (s->flags & MUTT_FIRSTDONE))
+    {
+      break;
+    }
   }
 
-  FREE(&buf);
-  return 0;
+  if ((a->encoding == ENCBASE64) || (a->encoding == ENCQUOTEDPRINTABLE) ||
+      (a->encoding == ENCUUENCODED))
+    mutt_body_free(&b);
+
+  /* make failure of a single part non-fatal */
+  if (rc < 0)
+    rc = 1;
+  return rc;
 }
 
 /**
@@ -1590,6 +1435,70 @@ static int malformed_pgp_encrypted_handler(struct Body *b, struct State *s)
   return rc;
 }
 
+/**
+ * mutt_decode_base64 - Decode base64-encoded text
+ * @param s      State to work with
+ * @param len    Length of text to decode
+ * @param istext Mime part is plain text
+ * @param cd     Iconv conversion descriptor
+ */
+void mutt_decode_base64(struct State *s, size_t len, bool istext, iconv_t cd)
+{
+  char buf[5];
+  int ch, i;
+  char bufi[BUFI_SIZE];
+  size_t l = 0;
+
+  buf[4] = '\0';
+
+  if (istext)
+    state_set_prefix(s);
+
+  while (len > 0)
+  {
+    for (i = 0; (i < 4) && (len > 0); len--)
+    {
+      ch = fgetc(s->fpin);
+      if (ch == EOF)
+        break;
+      if ((ch >= 0) && (ch < 128) && (base64val(ch) != -1 || ch == '='))
+        buf[i++] = ch;
+    }
+    if (i != 4)
+    {
+      /* "i" may be zero if there is trailing whitespace, which is not an error */
+      if (i != 0)
+        mutt_debug(2, "didn't get a multiple of 4 chars.\n");
+      break;
+    }
+
+    const int c1 = base64val(buf[0]);
+    const int c2 = base64val(buf[1]);
+    ch = (c1 << 2) | (c2 >> 4);
+    bufi[l++] = ch;
+
+    if (buf[2] == '=')
+      break;
+    const int c3 = base64val(buf[2]);
+    ch = ((c2 & 0xf) << 4) | (c3 >> 2);
+    bufi[l++] = ch;
+
+    if (buf[3] == '=')
+      break;
+    const int c4 = base64val(buf[3]);
+    ch = ((c3 & 0x3) << 6) | c4;
+    bufi[l++] = ch;
+
+    if ((l + 8) >= sizeof(bufi))
+      convert_to_state(cd, bufi, &l, s);
+  }
+
+  convert_to_state(cd, bufi, &l, s);
+  convert_to_state(cd, 0, 0, s);
+
+  state_reset_prefix(s);
+}
+
 /**
  * mutt_body_handler - Handler for the Body of an email
  * @param b Body of the email
@@ -1774,3 +1683,99 @@ int mutt_body_handler(struct Body *b, struct State *s)
 
   return rc;
 }
+
+/**
+ * mutt_can_decode - Will decoding the attachment produce any output
+ * @param a Body of email to test
+ * @retval true Decoding the attachment will produce output
+ */
+bool mutt_can_decode(struct Body *a)
+{
+  if (is_autoview(a))
+    return true;
+  else if (a->type == TYPETEXT)
+    return true;
+  else if (a->type == TYPEMESSAGE)
+    return true;
+  else if (a->type == TYPEMULTIPART)
+  {
+    if (WithCrypto)
+    {
+      if ((mutt_str_strcasecmp(a->subtype, "signed") == 0) ||
+          (mutt_str_strcasecmp(a->subtype, "encrypted") == 0))
+      {
+        return true;
+      }
+    }
+
+    for (struct Body *b = a->parts; b; b = b->next)
+    {
+      if (mutt_can_decode(b))
+        return true;
+    }
+  }
+  else if ((WithCrypto != 0) && a->type == TYPEAPPLICATION)
+  {
+    if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_is_application_pgp(a))
+      return true;
+    if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_is_application_smime(a))
+      return true;
+  }
+
+  return false;
+}
+
+/**
+ * mutt_decode_attachment - Decode an email's attachment
+ * @param b Body of the email
+ * @param s State of text being processed
+ */
+void mutt_decode_attachment(struct Body *b, struct State *s)
+{
+  int istext = mutt_is_text_part(b);
+  iconv_t cd = (iconv_t)(-1);
+
+  if (istext && s->flags & MUTT_CHARCONV)
+  {
+    char *charset = mutt_param_get(&b->parameter, "charset");
+    if (!charset && AssumedCharset && *AssumedCharset)
+      charset = mutt_ch_get_default_charset();
+    if (charset && Charset)
+      cd = mutt_ch_iconv_open(Charset, charset, MUTT_ICONV_HOOK_FROM);
+  }
+  else if (istext && b->charset)
+    cd = mutt_ch_iconv_open(Charset, b->charset, MUTT_ICONV_HOOK_FROM);
+
+  fseeko(s->fpin, b->offset, SEEK_SET);
+  switch (b->encoding)
+  {
+    case ENCQUOTEDPRINTABLE:
+      decode_quoted(s, b->length,
+                    istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
+                               mutt_is_application_pgp(b)),
+                    cd);
+      break;
+    case ENCBASE64:
+      mutt_decode_base64(s, b->length,
+                         istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
+                                    mutt_is_application_pgp(b)),
+                         cd);
+      break;
+    case ENCUUENCODED:
+      decode_uuencoded(s, b->length,
+                       istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
+                                  mutt_is_application_pgp(b)),
+                       cd);
+      break;
+    default:
+      decode_xbit(s, b->length,
+                  istext || (((WithCrypto & APPLICATION_PGP) != 0) &&
+                             mutt_is_application_pgp(b)),
+                  cd);
+      break;
+  }
+
+  if (cd != (iconv_t)(-1))
+    iconv_close(cd);
+}
+
diff --git a/handler.h b/handler.h
new file mode 100644 (file)
index 0000000..e452c15
--- /dev/null
+++ b/handler.h
@@ -0,0 +1,38 @@
+/**
+ * @file
+ * Decide how to display email content
+ *
+ * @authors
+ * Copyright (C) 1996-2000,2002,2010,2013 Michael R. Elkins <me@mutt.org>
+ *
+ * @copyright
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * 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/>.
+ */
+
+#ifndef _MUTT_HANDLER_H
+#define _MUTT_HANDLER_H
+
+#include <stddef.h>
+#include <iconv.h>
+#include <stdbool.h>
+
+struct Body;
+struct State;
+
+int  mutt_body_handler(struct Body *b, struct State *s);
+bool mutt_can_decode(struct Body *a);
+void mutt_decode_attachment(struct Body *b, struct State *s);
+void mutt_decode_base64(struct State *s, size_t len, bool istext, iconv_t cd);
+
+#endif /* _MUTT_HANDLER_H */
index afdb41bf211cccba8f6c12db9ebf484fde17fa86..57bae2c97e874be66a3a9e057f755c1dfdc2d9cb 100644 (file)
@@ -48,6 +48,7 @@
 #include "cryptglue.h"
 #include "envelope.h"
 #include "globals.h"
+#include "handler.h"
 #include "header.h"
 #include "mutt_curses.h"
 #include "ncrypt.h"
index 7dedb16201c7e66f540b411b801f1a269b624b54..b86530835a3453be9f0770422c5cb48b9520a90c 100644 (file)
@@ -56,6 +56,7 @@
 #include "envelope.h"
 #include "format_flags.h"
 #include "globals.h"
+#include "handler.h"
 #include "header.h"
 #include "keymap.h"
 #include "mutt_curses.h"
index 55c4b862ece28f9d355aaa3650834293943099da..0d051e13effbcdf7ab764cae05d27b50f00a6a6f 100644 (file)
@@ -49,6 +49,7 @@
 #include "cryptglue.h"
 #include "filter.h"
 #include "globals.h"
+#include "handler.h"
 #include "header.h"
 #include "mutt_curses.h"
 #include "ncrypt.h"
index 2a8e91af7c761f1f8d1b6b55ea50648f99b9fa1d..875c9f9e110c1a087fd881368ac24484afc931ce 100644 (file)
@@ -35,6 +35,7 @@
 #include <unistd.h>
 #include "mutt/mutt.h"
 #include "mutt.h"
+#include "handler.h"
 #include "pgppacket.h"
 #include "protos.h"
 #include "state.h"
index 3f1e77aae6bab600f4b592c3de2c2ab085249610..f056d5f32c1ddd525e6cd310f63651e0652a5af1 100644 (file)
@@ -47,6 +47,7 @@
 #include "filter.h"
 #include "format_flags.h"
 #include "globals.h"
+#include "handler.h"
 #include "header.h"
 #include "keymap.h"
 #include "mutt_curses.h"
index e330600e4d66527cef009f70a745e3e7cbaed2b8..86f3f5f4d060caf7f43959909429ddc593478c86 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -43,6 +43,7 @@
 #include "envelope.h"
 #include "globals.h"
 #include "group.h"
+#include "handler.h"
 #include "header.h"
 #include "mailbox.h"
 #include "mutt_curses.h"
index 8b0cd255f8f52f5630912cc2acc1bd6bd6e05db2..5d1f2f8c3ea67ec5834fba3f28921b0d05c3009e 100644 (file)
@@ -43,6 +43,7 @@
 #include "envelope.h"
 #include "format_flags.h"
 #include "globals.h"
+#include "handler.h"
 #include "header.h"
 #include "keymap.h"
 #include "mailbox.h"
index 7ed029a60c0efc387fda7524acfcc5269039341f..8c0c5dc70515196d3bb2acc02c62e206f986cc4b 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -144,7 +144,6 @@ void mutt_add_to_reference_headers(struct Envelope *env, struct Envelope *curenv
 void mutt_adv_mktemp(char *s, size_t l);
 void mutt_alias_menu(char *buf, size_t buflen, struct AliasList *aliases);
 void mutt_sig_allow_interrupt(int disposition);
-int mutt_body_handler(struct Body *b, struct State *s);
 int mutt_bounce_message(FILE *fp, struct Header *h, struct Address *to);
 void mutt_buffy(char *s, size_t slen);
 int mutt_buffy_list(void);
@@ -152,8 +151,6 @@ int mutt_count_body_parts(struct Context *ctx, struct Header *hdr);
 void mutt_check_rescore(struct Context *ctx);
 void mutt_clear_error(void);
 void mutt_clear_pager_position(void);
-void mutt_decode_attachment(struct Body *b, struct State *s);
-void mutt_decode_base64(struct State *s, size_t len, bool istext, iconv_t cd);
 void mutt_default_save(char *path, size_t pathlen, struct Header *hdr);
 void mutt_display_address(struct Envelope *env);
 void mutt_draw_statusline(int cols, const char *buf, int buflen);
@@ -232,7 +229,6 @@ int mutt_any_key_to_continue(const char *s);
 int mutt_buffy_check(bool force);
 int mutt_buffy_notify(void);
 int mutt_builtin_editor(const char *path, struct Header *msg, struct Header *cur);
-bool mutt_can_decode(struct Body *a);
 int mutt_change_flag(struct Header *h, int bf);
 int mutt_check_encoding(const char *c);
 
index ed775c093a56bc56f708d09edaf26348926c3f54..b2f284c749311352af2ba2a506dd34a5008eb562 100644 (file)
@@ -37,6 +37,7 @@
 #include "filter.h"
 #include "format_flags.h"
 #include "globals.h"
+#include "handler.h"
 #include "header.h"
 #include "keymap.h"
 #include "mailbox.h"
index 52102aaee2d61a1fa20612dbac3220128d541c1a..45cfc6d7a047dac8f5fc4c23574b805a3b425fc4 100644 (file)
--- a/recvcmd.c
+++ b/recvcmd.c
@@ -33,6 +33,7 @@
 #include "copy.h"
 #include "envelope.h"
 #include "globals.h"
+#include "handler.h"
 #include "header.h"
 #include "mutt_curses.h"
 #include "mutt_window.h"
index 3795f25fd25d17d80d93f21a754025eda03efa2a..9e722abfc870f2db81996f06ab385e1a2b05f83f 100644 (file)
@@ -34,6 +34,7 @@
 #include "filter.h"
 #include "format_flags.h"
 #include "globals.h"
+#include "handler.h"
 #include "header.h"
 #include "keymap.h"
 #include "mutt_curses.h"
index b6ccdbddd46513a14a405741fe0794dd1c36c223..6f3ebdd7f3091338a8f23465ba88f3130907ba30 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
@@ -46,6 +46,7 @@
 #include "filter.h"
 #include "format_flags.h"
 #include "globals.h"
+#include "handler.h"
 #include "header.h"
 #include "mailbox.h"
 #include "mutt_curses.h"