[svn] GPGol - r108 - in trunk: . src

svn author wk cvs at cvs.gnupg.org
Wed Sep 28 21:20:01 CEST 2005


Author: wk
Date: 2005-09-28 21:20:00 +0200 (Wed, 28 Sep 2005)
New Revision: 108

Modified:
   trunk/TODO
   trunk/src/ChangeLog
   trunk/src/common.c
   trunk/src/display.cpp
   trunk/src/gpgmsg.cpp
   trunk/src/main.c
   trunk/src/myexchext.h
   trunk/src/olflange.cpp
   trunk/src/passphrase-dialog.c
   trunk/src/pgpmime.c
   trunk/src/util.h
Log:
Yeah, that was a huge leap today. 
Got rid of the Save Changes? message 
and fixed the utf8 issues.  Although figured out possible ways of
overcoming the messy reply thing.


Modified: trunk/TODO
===================================================================
--- trunk/TODO	2005-09-27 16:45:50 UTC (rev 107)
+++ trunk/TODO	2005-09-28 19:20:00 UTC (rev 108)
@@ -7,7 +7,7 @@
 * find out why sometimes the new body cannot set to a MAPI object. In
   this case the body is empty but the W32 API said it was correctly set.
   This might be due to the length of the object.  HrGetOneProp has
-  such limitations adn thus it would be reasonable to assume that the
+  such limitations and thus it would be reasonable to assume that the
   same holds true for HrSetOneProp.  We might want to use OpenProperty
   for longer texts.
 

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2005-09-27 16:45:50 UTC (rev 107)
+++ trunk/src/ChangeLog	2005-09-28 19:20:00 UTC (rev 108)
@@ -1,3 +1,22 @@
+2005-09-28  Werner Koch  <wk at g10code.com>
+
+	* olflange.cpp (DoCommand): Catch close command and resend to
+	avoid the "save changes?".
+
+	* display.cpp (update_display): Take care of utf-8 issues.
+	* common.c (latin1_to_utf8): New.
+	* pgpmime.c (latin1_data_write): New.
+	(plaintext_handler): Use it here.
+	(message_cb): Detect utf-8 encoding.
+
+	* main.c (read_options): Make sure that compat flags are always
+	properly initialized.
+
+	* display.cpp (find_message_window): First try to find the window
+	by class name.
+
+	* common.c (wchar_to_utf8_2): New.
+
 2005-09-27  Werner Koch  <wk at g10code.com>
 
 	* pgpmime.c (pgpmime_decrypt): Pass a pseduo filename to the

Modified: trunk/src/common.c
===================================================================
--- trunk/src/common.c	2005-09-27 16:45:50 UTC (rev 107)
+++ trunk/src/common.c	2005-09-28 19:20:00 UTC (rev 108)
@@ -214,6 +214,30 @@
   return result;
 }
 
+
+/* Same as above, but only convert the first LEN wchars.  */
+char *
+wchar_to_utf8_2 (const wchar_t *string, size_t len)
+{
+  int n;
+  char *result;
+
+  /* Note, that CP_UTF8 is not defined in Windows versions earlier
+     than NT.*/
+  n = WideCharToMultiByte (CP_UTF8, 0, string, len, NULL, 0, NULL, NULL);
+  if (n < 0)
+    return NULL;
+
+  result = xmalloc (n+1);
+  n = WideCharToMultiByte (CP_UTF8, 0, string, len, result, n, NULL, NULL);
+  if (n < 0)
+    {
+      xfree (result);
+      return NULL;
+    }
+  return result;
+}
+
 /* Return a malloced wide char string from an UTF-8 encoded input
    string STRING.  Caller must xfree this value. On failure returns
    NULL; caller may use GetLastError to get the actual error number.
@@ -264,6 +288,37 @@
 }
 
 
+/* Assume STRING is a Latin-1 encoded and convert it to utf-8.
+   Returns a newly malloced UTF-8 string. */
+char *
+latin1_to_utf8 (const char *string)
+{
+  const char *s;
+  char *buffer, *p;
+  size_t n;
+
+  for (s=string, n=0; *s; s++) 
+    {
+      n++;
+      if (*s & 0x80)
+        n++;
+    }
+  buffer = xmalloc (n + 1);
+  for (s=string, p=buffer; *s; s++)
+    {
+      if (*s & 0x80)
+        {
+          *p++ = 0xc0 | ((*s >> 6) & 3);
+          *p++ = 0x80 | (*s & 0x3f);
+        }
+      else
+        *p++ = *s;
+    }
+  *p = 0;
+  return buffer;
+}
+
+
 /* Strip off trailing white spaces from STRING.  Returns STRING. */
 char *
 trim_trailing_spaces (char *string)

Modified: trunk/src/display.cpp
===================================================================
--- trunk/src/display.cpp	2005-09-27 16:45:50 UTC (rev 107)
+++ trunk/src/display.cpp	2005-09-28 19:20:00 UTC (rev 108)
@@ -98,6 +98,18 @@
       HWND w;
       size_t len;
       const char *s;
+
+      /* OL 2003 SP1 German uses this class name for the main
+         inspector window.  We hope that no other windows uses this
+         class name.  As a fallback we keep on testing for PGP
+         strings, but this does not work for PGP/MIME or already
+         decrypted messages. */
+      len = GetClassName (child, buf, sizeof buf - 1);
+      if (len && !strcmp (buf, "RichEdit20W"))
+        {
+          log_debug ("found class RichEdit20W");
+          return child;
+        }
       
       memset (buf, 0, sizeof (buf));
       GetWindowText (child, buf, sizeof (buf)-1);
@@ -126,14 +138,29 @@
   window = find_message_window (hwnd);
   if (window)
     {
+      const char *string, *s;
+
       log_debug ("%s:%s: window handle %p\n", __FILE__, __func__, window);
-      SetWindowText (window, msg->getDisplayText ());
+      string = msg->getDisplayText ();
+      
+      /* Decide whether we need to use the Unicode version. */
+      for (s=string; *s && !(*s & 0x80); s++)
+        ;
+      if (*s)
+        {
+          wchar_t *tmp = utf8_to_wchar (string);
+          SetWindowTextW (window, tmp);
+          xfree (tmp);
+        }
+      else
+        SetWindowTextA (window, string);
       log_debug ("%s:%s: window text is now `%s'",
-                 __FILE__, __func__, msg->getDisplayText ());
+                 __FILE__, __func__, string);
       return 0;
     }
   else if (exchange_cb && !opt.compat.no_oom_write)
     {
+      log_debug ("updating display using OOM");
       return put_outlook_property (exchange_cb, "Body",
                                    msg->getDisplayText ());
     }
@@ -156,7 +183,7 @@
   //  BOOL dummy_bool;
   const char *s;
   
-  /* Decide whether we ned to use the Unicode version. */
+  /* Decide whether we need to use the Unicode version. */
   for (s=string; *s && !(*s & 0x80); s++)
     ;
   if (*s)

Modified: trunk/src/gpgmsg.cpp
===================================================================
--- trunk/src/gpgmsg.cpp	2005-09-27 16:45:50 UTC (rev 107)
+++ trunk/src/gpgmsg.cpp	2005-09-28 19:20:00 UTC (rev 108)
@@ -1013,7 +1013,7 @@
       log_debug ("decrypt isHtml=%d\n", is_html);
 
       /* Do we really need to set the body?  update_display below
-         should be sufficient.  The problem witgh this is that we have
+         should be sufficient.  The problem with this is that we did
          changes in the MAPI and OL will later ask whether to save
          them.  The original reason for this kludge was to get the
          plaintext into the reply (by setting the property without
@@ -1233,19 +1233,16 @@
     }
 
   /* Gather the keys for the recipients. */
-      TRACEPOINT();
   recipients = getRecipients ();
-      TRACEPOINT();
   if ( op_lookup_keys (recipients, &keys, &unknown) )
     {
       log_debug ("%s.%s: leave (lookup keys failed)\n", __FILE__, __func__);
       return gpg_error (GPG_ERR_GENERAL);  
     }
-      TRACEPOINT();
   n_recp = count_strings (recipients);
   n_keys = count_keys (keys);
   n_unknown = count_strings (unknown);
-      TRACEPOINT();
+
   
   log_debug ("%s:%s: found %d recipients, need %d, unknown=%d\n",
              __FILE__, __func__, (int)n_keys, (int)n_recp, (int)n_unknown);

Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c	2005-09-27 16:45:50 UTC (rev 107)
+++ trunk/src/main.c	2005-09-28 19:20:00 UTC (rev 108)
@@ -328,6 +328,7 @@
   /* Note, that on purpose these flags are only Registry changeable.
      The format of the entry is a string of of "0" and "1" digits; see
      the switch below for a description. */
+  memset (&opt.compat, 0, sizeof opt.compat);
   load_extension_value ("compatFlags", &val);
   if (val)
     {

Modified: trunk/src/myexchext.h
===================================================================
--- trunk/src/myexchext.h	2005-09-27 16:45:50 UTC (rev 107)
+++ trunk/src/myexchext.h	2005-09-28 19:20:00 UTC (rev 108)
@@ -72,6 +72,13 @@
 #define EECMDID_ToolsOptions                   136
 
 
+/* Flag values for IExchExtAttachedFileEvents::OpenSzFile. */
+#define EEAFE_OPEN         (0x00000001)
+#define EEAFE_PRINT	   (0x00000002)
+#define EEAFE_QUICKVIEW	   (0x00000003)
+
+
+
 /* GUIDs */
 DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 
@@ -130,6 +137,9 @@
 typedef struct IOutlookExtCallback IOutlookExtCallback;
 typedef IOutlookExtCallback *LPOUTLOOKEXTCALLBACK;
 
+typedef struct IExchExtAttachedFileEvents IExchExtAttachedFileEvents;
+typedef IExchExtAttachedFileEvents *LPEXCHEXTATTACHEDFILEEVENTS;
+
 /* The next classes are not yet defined. but if so they should go here. */
 typedef struct IExchExtModeless IExchExtModeless; 
 typedef IExchExtModeless *LPEXCHEXTMODELESS;
@@ -330,22 +340,19 @@
   STDMETHOD(GetOfficeCharacter)(void **ppmsotfc);
 };
 
-// Flag values for IExchExtAttachedFileEvents::OpenSzFile
-#define EEAFE_OPEN         (0x00000001)
-#define EEAFE_PRINT	   (0x00000002)
-#define EEAFE_QUICKVIEW	   (0x00000003)
 
+
+EXTERN_C const IID IID_IExchExtAttachedFileEvents;
 #undef INTERFACE
-#define INTERFACE   IExchExtAttachedFileEvents
-
+#define INTERFACE  IExchExtAttachedFileEvents
 DECLARE_INTERFACE_(IExchExtAttachedFileEvents, IUnknown)
 {
-  // *** IUnknown methods ***
+  /*** IUnknown methods ***/
   STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * lppvObj) PURE;
   STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
   STDMETHOD_(ULONG,Release) (THIS) PURE;
   
-  // *** IExchExtAttachedFileEvents methods ***
+  /*** IExchExtAttachedFileEvents methods ***/
   STDMETHOD(OnReadPattFromSzFile)(THIS_ LPATTACH lpatt, LPTSTR lpszFile,
 				  ULONG ulFlags) PURE;
   STDMETHOD(OnWritePattToSzFile)(THIS_ LPATTACH lpatt, LPTSTR lpszFile,
@@ -354,9 +361,7 @@
   STDMETHOD(OnOpenPatt)(THIS_ LPATTACH lpatt) PURE;
   STDMETHOD(OnOpenSzFile)(THIS_ LPTSTR lpszFile, ULONG ulFlags) PURE;
 };
-typedef IExchExtAttachedFileEvents FAR * LPEXCHEXTATTACHEDFILEEVENTS;
 
-EXTERN_C const IID IID_IExchExtAttachedFileEvents;
 
 #ifdef __cplusplus
 }

Modified: trunk/src/olflange.cpp
===================================================================
--- trunk/src/olflange.cpp	2005-09-27 16:45:50 UTC (rev 107)
+++ trunk/src/olflange.cpp	2005-09-28 19:20:00 UTC (rev 108)
@@ -57,6 +57,9 @@
 
 bool g_initdll = FALSE;
 
+static HWND show_window_hierarchy (HWND parent, int level);
+
+
 /* Registers this module as an Exchange extension. This basically updates
    some Registry entries. */
 STDAPI 
@@ -484,8 +487,24 @@
 /*  Uninitializes the DLL in the session context. */
 CGPGExchExt::~CGPGExchExt (void) 
 {
-  log_debug ("%s:%s: cleaning up CGPGExchExt object\n", __FILE__, __func__);
-
+  log_debug ("%s:%s: cleaning up CGPGExchExt object; "
+             "context=0x%lx (%s)\n", __FILE__, __func__, 
+             m_lContext,
+             (m_lContext == EECONTEXT_SESSION?           "Session":
+              m_lContext == EECONTEXT_VIEWER?            "Viewer":
+              m_lContext == EECONTEXT_REMOTEVIEWER?      "RemoteViewer":
+              m_lContext == EECONTEXT_SEARCHVIEWER?      "SearchViewer":
+              m_lContext == EECONTEXT_ADDRBOOK?          "AddrBook" :
+              m_lContext == EECONTEXT_SENDNOTEMESSAGE?   "SendNoteMessage" :
+              m_lContext == EECONTEXT_READNOTEMESSAGE?   "ReadNoteMessage" :
+              m_lContext == EECONTEXT_SENDPOSTMESSAGE?   "SendPostMessage" :
+              m_lContext == EECONTEXT_READPOSTMESSAGE?   "ReadPostMessage" :
+              m_lContext == EECONTEXT_READREPORTMESSAGE? "ReadReportMessage" :
+              m_lContext == EECONTEXT_SENDRESENDMESSAGE? "SendResendMessage" :
+              m_lContext == EECONTEXT_PROPERTYSHEETS?    "PropertySheets" :
+              m_lContext == EECONTEXT_ADVANCEDCRITERIA?  "AdvancedCriteria" :
+              m_lContext == EECONTEXT_TASK?              "Task" : ""));
+  
   if (m_lContext == EECONTEXT_SESSION)
     {
       if (g_initdll)
@@ -497,6 +516,7 @@
           log_debug ("%s:%s: DLL closed down\n", __FILE__, __func__);
 	}	
     }
+
 }
 
 
@@ -656,6 +676,7 @@
   show_mapi_property (pMessage, PR_CONVERSATION_INDEX,"PR_CONVERSATION_INDEX");
   ul_release (pMessage);
   ul_release (pMDB);
+
   return S_FALSE;
 }
 
@@ -689,8 +710,18 @@
       ul_release (pMessage);
       ul_release (pMDB);
     }
-  
+#if 0
+  else
+    {
+      HWND hWnd = NULL;
 
+      if (FAILED (pEECB->GetWindow (&hWnd)))
+        hWnd = NULL;
+      else
+        show_window_hierarchy (hWnd, 0);
+    }
+#endif
+
   return S_FALSE;
 }
 
@@ -921,10 +952,19 @@
   while (child)
     {
       char buf[1024+1];
+      char name[200];
+      int nname;
+      char *pname;
       
       memset (buf, 0, sizeof (buf));
       GetWindowText (child, buf, sizeof (buf)-1);
-      log_debug ("XXX %*shwnd=%p `%s'", level*2, "", child, buf);
+      nname = GetClassName (child, name, sizeof (name)-1);
+      if (nname)
+        pname = name;
+      else
+        pname = NULL;
+      log_debug ("XXX %*shwnd=%p (%s) `%s'", level*2, "", child,
+                 pname? pname:"", buf);
       show_window_hierarchy (child, level+1);
       child = GetNextWindow (child, GW_HWNDNEXT);	
     }
@@ -977,7 +1017,7 @@
 
   /* Outlook 2003 sometimes displays the plaintext sometimes the
      orginal undecrypted text when doing a Reply.  This seems to
-     depend on the sieze of the message; my guess it that only short
+     depend on the size of the message; my guess it that only short
      messages are locally saved in the process and larger ones are
      fetyched again from the backend - or the other way around.
      Anyway, we can't rely on that and thus me make sure to update the
@@ -1232,6 +1272,63 @@
 {
   HRESULT hr;
 
+  log_debug ("%s:%s: commandID=%u (%#x)\n",
+             __FILE__, __func__, nCommandID, nCommandID);
+  if (nCommandID == SC_CLOSE && m_lContext == EECONTEXT_READNOTEMESSAGE)
+    {
+      /* This is the system close command. Replace it with our own to
+         avoid the "save changes" query, apparently induced by OL
+         internal syncronisation of our SetWindowText message with its
+         own OOM (in this case Body). */
+      LPDISPATCH pDisp;
+      DISPID dispid;
+      DISPPARAMS dispparams;
+      VARIANT aVariant;
+      
+      pDisp = find_outlook_property (pEECB, "Close", &dispid);
+      if (pDisp)
+        {
+          dispparams.rgvarg = &aVariant;
+          dispparams.rgvarg[0].vt = VT_INT;
+          dispparams.rgvarg[0].intVal = 1; /* olDiscard */
+          dispparams.cArgs = 1;
+          dispparams.cNamedArgs = 0;
+          hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
+                              DISPATCH_METHOD, &dispparams,
+                              NULL, NULL, NULL);
+          pDisp->Release();
+          pDisp = NULL;
+          if (hr == S_OK)
+            {
+              log_debug ("%s:%s: invoking Close succeeded", __FILE__,__func__);
+              return S_OK; /* We handled the close command. */
+            }
+
+          log_debug ("%s:%s: invoking Close failed: %#lx",
+                     __FILE__, __func__, hr);
+        }
+
+      /* We are not interested in the close command - pass it on. */
+      return S_FALSE; 
+    }
+  else if (nCommandID == 154)
+    {
+      log_debug ("%s:%s: command Reply called\n", __FILE__, __func__);
+      /* What we might want to do is to call Reply, then GetInspector
+         and then Activate - this allows us to get full control over
+         the quoted message and avoids the ugly msgcache. */
+    }
+  else if (nCommandID == 155)
+    {
+      log_debug ("%s:%s: command ReplyAll called\n", __FILE__, __func__);
+    }
+  else if (nCommandID == 156)
+    {
+      log_debug ("%s:%s: command Forward called\n", __FILE__, __func__);
+    }
+  
+
+
   if ((nCommandID != m_nCmdEncrypt) 
       && (nCommandID != m_nCmdSign))
     return S_FALSE; 
@@ -1244,6 +1341,9 @@
 
       if (FAILED (pEECB->GetWindow (&hWnd)))
         hWnd = NULL;
+//       else
+//         show_window_hierarchy (hWnd, 0);
+
       hr = pEECB->GetObject (&pMDB, (LPMAPIPROP *)&pMessage);
       if (SUCCEEDED (hr))
         {
@@ -1253,8 +1353,6 @@
               m->setExchangeCallback ((void*)pEECB);
               m->decrypt (hWnd);
               delete m;
-//               log_debug ("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
-//               show_window_hierarchy (hWnd, 0);
 	    }
 	}
       ul_release (pMessage);
@@ -1277,10 +1375,31 @@
   return S_OK; 
 }
 
-
+/* Called by Exchange when it receives a WM_INITMENU message, allowing
+   the extension object to enable, disable, or update its menu
+   commands before the user sees them. This method is called
+   frequently and should be written in a very efficient manner. */
 STDMETHODIMP_(VOID) 
 CGPGExchExtCommands::InitMenu(LPEXCHEXTCALLBACK pEECB) 
 {
+#if 0
+  log_debug ("%s:%s: context=0x%lx (%s)\n", __FILE__, __func__, 
+             m_lContext,
+             (m_lContext == EECONTEXT_SESSION?           "Session"          :
+              m_lContext == EECONTEXT_VIEWER?            "Viewer"           :
+              m_lContext == EECONTEXT_REMOTEVIEWER?      "RemoteViewer"     :
+              m_lContext == EECONTEXT_SEARCHVIEWER?      "SearchViewer"     :
+              m_lContext == EECONTEXT_ADDRBOOK?          "AddrBook"         :
+              m_lContext == EECONTEXT_SENDNOTEMESSAGE?   "SendNoteMessage"  :
+              m_lContext == EECONTEXT_READNOTEMESSAGE?   "ReadNoteMessage"  :
+              m_lContext == EECONTEXT_SENDPOSTMESSAGE?   "SendPostMessage"  :
+              m_lContext == EECONTEXT_READPOSTMESSAGE?   "ReadPostMessage"  :
+              m_lContext == EECONTEXT_READREPORTMESSAGE? "ReadReportMessage":
+              m_lContext == EECONTEXT_SENDRESENDMESSAGE? "SendResendMessage":
+              m_lContext == EECONTEXT_PROPERTYSHEETS?    "PropertySheets"   :
+              m_lContext == EECONTEXT_ADVANCEDCRITERIA?  "AdvancedCriteria" :
+              m_lContext == EECONTEXT_TASK?              "Task" : ""));
+#endif
 }
 
 

Modified: trunk/src/passphrase-dialog.c
===================================================================
--- trunk/src/passphrase-dialog.c	2005-09-27 16:45:50 UTC (rev 107)
+++ trunk/src/passphrase-dialog.c	2005-09-28 19:20:00 UTC (rev 108)
@@ -52,30 +52,37 @@
 
 
 static void
-set_key_hint (struct decrypt_key_s * dec, HWND dlg, int ctrlid)
+set_key_hint (struct decrypt_key_s *dec, HWND dlg, int ctrlid)
 {
-    const char *s = dec->user_id;
-    char *key_hint;
-    char stop_char=0;
-    size_t i=0;
+  const char *s = dec->user_id;
+  char *key_hint;
+  
+  if (s && dec->keyid) 
+    {
+      char stop_char;
+      size_t i = 0;
 
-    if (dec->user_id != NULL) {
-	key_hint = (char *)xmalloc (17 + strlen (dec->user_id) + 32);
-	if (strchr (s, '<') && strchr (s, '>'))
-	    stop_char = '<';
-	else if (strchr (s, '(') && strchr (s, ')'))
-	    stop_char = '(';
-	while (s && *s != stop_char)
-	    key_hint[i++] = *s++;
-	key_hint[i++] = ' ';
-	sprintf (key_hint+i, "(0x%s)", dec->keyid+8);
+      key_hint = xmalloc (17 + strlen (s) + strlen (dec->keyid) + 32);
+      if (strchr (s, '<') && strchr (s, '>'))
+        stop_char = '<';
+      else if (strchr (s, '(') && strchr (s, ')'))
+        stop_char = '(';
+      else
+        stop_char = 0;
+      while (*s != stop_char)
+        key_hint[i++] = *s++;
+      key_hint[i++] = ' ';
+      if (dec->keyid && strlen (dec->keyid) > 8)
+        sprintf (key_hint+i, "(0x%s)", dec->keyid+8);
+      else
+        key_hint[i] = 0;
     }
-    else
-	key_hint = xstrdup ("No key hint given.");
-    SendDlgItemMessage (dlg, ctrlid, CB_ADDSTRING, 0, 
-			(LPARAM)(const char *)key_hint);
-    SendDlgItemMessage (dlg, ctrlid, CB_SETCURSEL, 0, 0);
-    xfree (key_hint);
+  else
+    key_hint = xstrdup ("No key hint given.");
+  SendDlgItemMessage (dlg, ctrlid, CB_ADDSTRING, 0, 
+                      (LPARAM)(const char *)key_hint);
+  SendDlgItemMessage (dlg, ctrlid, CB_SETCURSEL, 0, 0);
+  xfree (key_hint);
 }
 
 /* Release the key array ARRAY as well as all COUNT keys. */
@@ -200,12 +207,10 @@
   gpgme_key_t *keyarray;
   size_t keyarray_size;
 
-  TRACEPOINT();
   err = gpgme_new (&ctx);
   if (err)
     return NULL;
 
-  TRACEPOINT();
   err = gpgme_op_keylist_start (ctx, NULL, 1);
   if (err)
     {
@@ -214,7 +219,6 @@
       return NULL;
     }
 
-  TRACEPOINT();
   keyarray_size = 20; 
   keyarray = xcalloc (keyarray_size+1, sizeof *keyarray);
   pos = 0;
@@ -224,7 +228,6 @@
       const char *name, *email, *keyid, *algo;
       char *p;
       
-  TRACEPOINT();
       if (key->revoked || key->expired || key->disabled || key->invalid)
         {
           gpgme_key_release (key);
@@ -259,16 +262,13 @@
 			  (LPARAM)(const char *) p);
       xfree (p);
 
-  TRACEPOINT();
       SendDlgItemMessage (dlg, ctlid, CB_SETITEMDATA, pos, (LPARAM)pos);
-  TRACEPOINT();
 
       if (pos >= keyarray_size)
         {
           gpgme_key_t *tmparr;
           size_t i;
 
-  TRACEPOINT();
           keyarray_size += 10;
           tmparr = xcalloc (keyarray_size, sizeof *tmparr);
           for (i=0; i < pos; i++)
@@ -277,13 +277,10 @@
           keyarray = tmparr;
         }
       keyarray[pos++] = key;
-  TRACEPOINT();
     }
 
-  TRACEPOINT();
   gpgme_op_keylist_end (ctx);
   gpgme_release (ctx);
-  TRACEPOINT();
   return keyarray;
 }
 
@@ -302,7 +299,6 @@
       context = (struct dialog_context_s *)lparam;
       context->hide_state = 1;
       dec = context->dec;
-      TRACEPOINT();
       if (dec && context->use_as_cb) 
         {
           dec->opts = 0;
@@ -315,10 +311,8 @@
                         (dec && dec->last_was_bad)?
                         _("Invalid passphrase; please try again..."):"");
 
-      TRACEPOINT();
       if (dec && !context->use_as_cb)
         context->keyarray = load_secbox (dlg, IDC_DEC_KEYLIST);
-      TRACEPOINT();
 
       CheckDlgButton (dlg, IDC_DEC_HIDE, BST_CHECKED);
       center_window (dlg, NULL);
@@ -534,16 +528,14 @@
   struct dialog_context_s context; 
   struct decrypt_key_s dec;
   
-  TRACEPOINT();
   memset (&context, 0, sizeof context);
   memset (&dec, 0, sizeof dec);
   dec.hide_pwd = 1;
   context.dec = &dec;
   
-  TRACEPOINT();
   DialogBoxParam (glob_hinst, (LPCTSTR)IDD_DEC, GetDesktopWindow (),
                   decrypt_key_dlg_proc, (LPARAM)&context);
-  TRACEPOINT();
+
   if (dec.signer) 
     {
       if (r_passwd)
@@ -558,16 +550,12 @@
       *r_key = dec.signer;
       dec.signer = NULL;
     }
-  TRACEPOINT();
   if (dec.pass)
     wipestring (dec.pass);
-  TRACEPOINT();
   xfree (dec.pass);
   if (dec.signer)
     gpgme_key_release (dec.signer);
-  TRACEPOINT();
   release_keyarray (context.keyarray);
-  TRACEPOINT();
   return (dec.opts & OPT_FLAG_CANCEL)? -1 : 0;
 }
 

Modified: trunk/src/pgpmime.c
===================================================================
--- trunk/src/pgpmime.c	2005-09-27 16:45:50 UTC (rev 107)
+++ trunk/src/pgpmime.c	2005-09-28 19:20:00 UTC (rev 108)
@@ -98,6 +98,7 @@
   int collect_attachment; /* True if we are collecting an attachment. */
   int is_qp_encoded;      /* Current part is QP encoded. */
   int is_base64_encoded;  /* Current part is base 64 encoded. */
+  int is_utf8;            /* Current part has charset utf-8. */
 
   int part_counter;       /* Counts the number of processed parts. */
   char *filename;         /* Current filename (malloced) or NULL. */
@@ -125,6 +126,41 @@
 typedef struct pgpmime_context *pgpmime_context_t;
 
 
+/* This function is a wrapper around gpgme_data_write to convert the
+   data to utf-8 first.  We assume Latin-1 here. */
+static int
+latin1_data_write (gpgme_data_t data, const char *line, size_t len)
+{
+  const char *s;
+  char *buffer, *p;
+  size_t i, n;
+  int rc;
+
+  for (s=line, i=0, n=0 ; i < len; s++, i++ ) 
+    {
+      n++;
+      if (*s & 0x80)
+        n++;
+    }
+  buffer = xmalloc (n + 1);
+  for (s=line, i=0, p=buffer; i < len; s++, i++ )
+    {
+      if (*s & 0x80)
+        {
+          *p++ = 0xc0 | ((*s >> 6) & 3);
+          *p++ = 0x80 | (*s & 0x3f);
+        }
+      else
+        *p++ = *s;
+    }
+  assert (p-buffer == n);
+  rc = gpgme_data_write (data, buffer, n);
+  xfree (buffer);
+  return rc;
+}
+
+
+
 /* Do in-place decoding of quoted-printable data of LENGTH in BUFFER.
    Returns the new length of the buffer. */
 static size_t
@@ -262,6 +298,7 @@
       char *p;
       int is_text = 0;
 
+      ctx->is_utf8 = 0;
       field = rfc822parse_parse_field (msg, "Content-Type", -1);
       if (field)
         {
@@ -291,7 +328,11 @@
                 }
 
             }
-          
+
+          s1 = rfc822parse_query_parameter (field, "charset", 0);
+          if (s1 && !strcmp (s1, "utf-8"))
+            ctx->is_utf8 = 1;
+
           rfc822parse_release_field (field);
         }
       else
@@ -474,7 +515,12 @@
                   else
                     len = pos;
                   if (len)
-                    gpgme_data_write (ctx->body, ctx->linebuf, len);
+                    {
+                      if (ctx->is_utf8)
+                        gpgme_data_write (ctx->body, ctx->linebuf, len);
+                      else
+                        latin1_data_write (ctx->body, ctx->linebuf, len);
+                    }
                   if (!ctx->is_base64_encoded)
                     gpgme_data_write (ctx->body, "\r\n", 2);
                 }

Modified: trunk/src/util.h
===================================================================
--- trunk/src/util.h	2005-09-27 16:45:50 UTC (rev 107)
+++ trunk/src/util.h	2005-09-28 19:20:00 UTC (rev 108)
@@ -56,8 +56,10 @@
 void out_of_core (void);
 
 char *wchar_to_utf8 (const wchar_t *string);
+char *wchar_to_utf8_2 (const wchar_t *string, size_t len);
 wchar_t *utf8_to_wchar (const char *string);
 wchar_t *utf8_to_wchar2 (const char *string, size_t len);
+char *latin1_to_utf8 (const char *string);
 
 char *trim_trailing_spaces (char *string);
 




More information about the Gnupg-commits mailing list