[eterhack 3/4] winebrowser: Add attachment support (eterbug #6747).

Alexander Morozov amorozov на etersoft.ru
Пн Янв 17 21:22:27 MSK 2011


---
 programs/winebrowser/main.c |  104 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 102 insertions(+), 2 deletions(-)

diff --git a/programs/winebrowser/main.c b/programs/winebrowser/main.c
index 3d53419..29b4e48 100644
--- a/programs/winebrowser/main.c
+++ b/programs/winebrowser/main.c
@@ -32,7 +32,7 @@
  *  will be fed to a web browser. In the last case the argument is fed
  *  to a mail client. A mailto URL is composed as follows:
  *
- *   mailto:[E-MAIL]?subject=[TOPIC]&cc=[E-MAIL]&bcc=[E-MAIL]&body=[TEXT]
+ *   mailto:[E-MAIL]?subject=[TOPIC]&cc=[E-MAIL]&bcc=[E-MAIL]&body=[TEXT]&attachment=[PATH]
  */
 
 #define WIN32_LEAN_AND_MEAN
@@ -75,6 +75,106 @@ static WCHAR *strdupW( const WCHAR *src )
     return dst;
 }
 
+static WCHAR *strndupW( const WCHAR *src, INT n )
+{
+    WCHAR *dst;
+    int size = (n + 1) * sizeof(WCHAR);
+    if ((dst = HeapAlloc( GetProcessHeap(), 0, size )))
+    {
+        memcpy( dst, src, n * sizeof(WCHAR) );
+        dst[n] = 0;
+    }
+    return dst;
+}
+
+static char *strcat_unixcp( char *dest, const WCHAR *src, INT n, const char *add )
+{
+    char *ret;
+    int len = WideCharToMultiByte( CP_UNIXCP, 0, src, n, NULL, 0, NULL, NULL );
+    int size = len + (dest ? strlen( dest ) : 0) + (add ? strlen( add ) : 0) + 1;
+
+    if (dest)
+        ret = HeapReAlloc( GetProcessHeap(), 0, dest, size );
+    else
+        ret = HeapAlloc( GetProcessHeap(), 0, size );
+    if (ret)
+    {
+        dest = ret + (dest ? strlen( ret ) : 0);
+        WideCharToMultiByte( CP_UNIXCP, 0, src, n, dest, len, NULL, NULL );
+        dest[len] = 0;
+        if (add)
+            strcat( dest, add );
+    }
+    else if (dest)
+        HeapFree( GetProcessHeap(), 0, dest );
+    return ret;
+}
+
+static char *escape_str( char *str )
+{
+    char empty[] = "";
+    char *ret;
+    DWORD size = 1;
+
+    UrlEscapeA( str, empty, &size, URL_ESCAPE_SPACES_ONLY );
+    if ((ret = HeapAlloc( GetProcessHeap(), 0, size )))
+        UrlEscapeA( str, ret, &size, URL_ESCAPE_SPACES_ONLY );
+    HeapFree( GetProcessHeap(), 0, str );
+    return ret;
+}
+
+static char *convert_paths( const WCHAR *args )
+{
+    static const WCHAR attachmentW[] =
+        {'a','t','t','a','c','h','m','e','n','t','=',0};
+
+    const WCHAR *prev = args, *p, *ep;
+    WCHAR *dos_path = NULL;
+    char *buf = NULL, *unix_path = NULL;
+
+    if (!(p = strchrW( args, '?' )))
+        return strdup_unixcp( args );
+
+    for (;;)
+    {
+        ++p;
+        if (strlenW( p ) > strlenW( attachmentW ) &&
+            !memcmp( p, attachmentW, sizeof(attachmentW) - sizeof(WCHAR) ))
+        {
+            p += strlenW( attachmentW );
+            ep = strchrW( p, '&' );
+            /* mailto:name на example.com?attachment=c:\file1&attachment=c:\file2
+             * ^prev                              ^p      ^ep */
+            if (ep)
+            {
+                if (ep == p)
+                    continue;
+                dos_path = strndupW( p, ep - p );
+            }
+            else
+                dos_path = strdupW( p );
+            UrlUnescapeInPlaceW( dos_path, 0 );
+            if (!(unix_path = wine_get_unix_file_name( dos_path )) ||
+                !(unix_path = escape_str( unix_path )) ||
+                !(buf = strcat_unixcp( buf, prev, p - prev, unix_path )))
+                break;
+            HeapFree( GetProcessHeap(), 0, dos_path );
+            HeapFree( GetProcessHeap(), 0, unix_path );
+            if (!ep)
+                return buf;
+            prev = ep;
+            p = ep;
+        }
+        else
+            if (!(p = strchrW( p, '&' )))
+                return strcat_unixcp( buf, prev, -1, NULL );
+    }
+    HeapFree( GetProcessHeap(), 0, buf );
+    HeapFree( GetProcessHeap(), 0, dos_path );
+    HeapFree( GetProcessHeap(), 0, unix_path );
+    return NULL;
+}
+
 /* try to launch a unix app from a comma separated string of app names */
 static int launch_app( WCHAR *candidates, const WCHAR *argv1 )
 {
@@ -82,7 +182,7 @@ static int launch_app( WCHAR *candidates, const WCHAR *argv1 )
     const char *argv_new[3];
 
     if (!(applist = strdup_unixcp( candidates ))) return 1;
-    if (!(cmdline = strdup_unixcp( argv1 )))
+    if (!(cmdline = convert_paths( argv1 )))
     {
         HeapFree( GetProcessHeap(), 0, applist );
         return 1;
-- 
1.7.3.4


------------e8Ehp0EWD5AyIg6qya9bPo
Content-Disposition: attachment; filename=0002-winemapi-Address-can-contain-SMTP-eterbug-6747.txt
Content-Type: text/plain; name=0002-winemapi-Address-can-contain-SMTP-eterbug-6747.txt
Content-Transfer-Encoding: 7bit



Подробная информация о списке рассылки Wine-patches