[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