s1 = rfc822parse_query_parameter (field, "charset", 0); if (s1 && !strcmp (s1, "utf-8")) ctx->is_utf8 = 1;
message_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg){  pgpmime_context_t ctx = opaque;  HRESULT hr;  debug_message_event (ctx, event);  if (event == RFC822PARSE_T2BODY)    {      rfc822parse_field_t field;      const char *s1, *s2;      size_t off;      char *p;      int is_text = 0;      field = rfc822parse_parse_field (msg, "Content-Type", -1);      if (field)        {          s1 = rfc822parse_query_media_type (field, &s2);          if (s1)            {              log_debug ("%s: ctx=%p, media `%s' `%s'\n",                         __FILE__, ctx, s1, s2);              if (!strcmp (s1, "multipart"))                {                  /* We don't care about the top level multipart layer                     but wait until it comes to the actual parts which                     then will get stored as attachments.                     For now encapsulated signed or encrypted                     containers are not processed in a special way as                     they should. */                }              else if (!strcmp (s1, "text"))                {                  is_text = 1;                }              else /* Other type. */                {                  ctx->collect_attachment = 1;                }            }                    rfc822parse_release_field (field);        }      else        {          /* No content-type at all indicates text/plain. */          is_text = 1;        }      ctx->in_data = 1;      /* Need to figure out the encoding. */      ctx->is_qp_encoded = 0;      ctx->is_base64_encoded = 0;      p = rfc822parse_get_field (msg, "Content-Transfer-Encoding", -1, &off);      if (p)        {          if (!stricmp (p+off, "quoted-printable"))            ctx->is_qp_encoded = 1;          else if (!stricmp (p+off, "base64"))            {              ctx->is_base64_encoded = 1;              ctx->base64.idx = 0;              ctx->base64.val = 0;              ctx->base64.stop_seen = 0;              ctx->base64.invalid_encoding = 0;            }          free (p);        }      /* If this is a text part, decide whether we treat it as our body. */      if (is_text)        {          /* If this is the first text part at all we will             start to collect it and use it later as the             regular body.  An initialized ctx->BODY is an             indication that this is not the first text part -             we treat such a part like any other             attachment. */          if (!ctx->body)            {              if (!gpgme_data_new (&ctx->body))                ctx->collect_body = 1;            }          else            ctx->collect_attachment = 1;        }      /* Now that if we have an attachment prepare for writing it out. */      if (ctx->collect_attachment)        {          p = NULL;          field = rfc822parse_parse_field (msg, "Content-Disposition", -1);          if (field)            {              s1 = rfc822parse_query_parameter (field, "filename", 0);              if (s1)                p = xstrdup (s1);              rfc822parse_release_field (field);            }          if (!p)            {              p = xmalloc (50);              snprintf (p, 49, "unnamed-%d.dat", ctx->part_counter);            }          if (ctx->outstream)            {              IStream_Release (ctx->outstream);              ctx->outstream = NULL;            }        tryagain:          xfree (ctx->filename);          ctx->filename = get_save_filename (ctx->hwnd, p);          if (!ctx->filename)            ctx->collect_attachment = 0; /* User das not want to save it. */          else            {              hr = OpenStreamOnFile (MAPIAllocateBuffer, MAPIFreeBuffer,                                     (STGM_CREATE | STGM_READWRITE),                                     ctx->filename, NULL, &ctx->outstream);               if (FAILED (hr))                 {                  log_error ("%s:%s: can't create file `%s': hr=%#lx\n",                             __FILE__, __func__, ctx->filename, hr);                   MessageBox (ctx->hwnd, "Error creating file\n"                              "Please select anther one",                              "I/O-Error", MB_ICONERROR|MB_OK);                  goto tryagain;                }              log_debug ("%s:%s: writing attachment to `%s'\n",                         __FILE__, __func__, ctx->filename);             }          xfree (p);        }    }  else if (event == RFC822PARSE_LEVEL_DOWN)    {      ctx->nesting_level++;    }  else if (event == RFC822PARSE_LEVEL_UP)    {      if (ctx->nesting_level)        ctx->nesting_level--;      else         {          log_error ("%s: ctx=%p, invalid structure: bad nesting level\n",                     __FILE__, ctx);          ctx->parser_error = 1;        }    }  else if (event == RFC822PARSE_BOUNDARY || event == RFC822PARSE_LAST_BOUNDARY)    {      ctx->in_data = 0;      ctx->collect_body = 0;      ctx->collect_attachment = 0;      xfree (ctx->filename);      ctx->filename = NULL;      if (ctx->outstream)        {          IStream_Commit (ctx->outstream, 0);          IStream_Release (ctx->outstream);          ctx->outstream = NULL;        }    }  else if (event == RFC822PARSE_BEGIN_HEADER)    {      ctx->part_counter++;    }  return 0;}