--- libbtctl-0.11.1/src/Makefile.am.unicode 2014-11-11 18:43:29.000000000 -0800 +++ libbtctl-0.11.1/src/Makefile.am 2014-11-11 19:00:55.000000000 -0800 @@ -70,7 +70,7 @@ obex-server-source.c obex-server-source.h \ obex-server-source-private.h \ btobex.c btobex.h obexsdp.h obexsdp.c \ - obex-client-source.c obex-client-source.h \ + obex-client-source.c obex-client-source.h unicode.c unicode.h common.h \ btobex-client.c btobex-client.h \ btctl-types.h btctl-types.c --- libbtctl-0.11.1/src/btobex.c.unicode 2007-07-24 07:53:51.000000000 -0700 +++ libbtctl-0.11.1/src/btobex.c 2014-11-11 18:56:25.000000000 -0800 @@ -29,6 +29,7 @@ #include "btctl-types.h" #include "btctl-marshal.h" #include "obexsdp.h" +#include "unicode.h" static gpointer parent_class = NULL; @@ -310,7 +311,7 @@ if ((namebuf = g_new0 (gchar, hlen/2))) { /* FIXME: figure out which encoding of unicode is * being used and handle it properly */ - OBEX_UnicodeToChar (namebuf, hv.bs, hlen); + UnicodeToChar (namebuf, hv.bs, hlen); name = namebuf; } break; --- libbtctl-0.11.1/src/obex-client-source.c.unicode 2007-03-05 15:07:19.000000000 -0800 +++ libbtctl-0.11.1/src/obex-client-source.c 2014-11-11 18:57:30.000000000 -0800 @@ -34,6 +34,7 @@ #include "obex-client-source.h" #include "obex-server-source-private.h" +#include "unicode.h" #define OBEX_STREAM_CHUNK 4096 @@ -327,7 +328,7 @@ bfname = g_path_get_basename (fname); uname_size = (strlen (bfname)+1)*2; uname = g_malloc (uname_size); - OBEX_CharToUnicode (uname, bfname, uname_size); + CharToUnicode (uname, bfname, uname_size); hd.bs = uname; OBEX_ObjectAddHeader (bc->handle, object, --- /dev/null 2014-11-11 18:16:49.229711166 -0800 +++ libbtctl-0.11.1/src/unicode.h 2013-03-05 12:43:50.000000000 -0800 @@ -0,0 +1,39 @@ +/** + \file obexftp/unicode.h + Unicode charset and encoding conversions. + ObexFTP library - language bindings for OBEX file transfer. + + Copyright (c) 2007 Christian W. Zuckschwerdt + + ObexFTP is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with ObexFTP. If not, see . + */ + +#ifndef OBEXFTP_UNICODE_H +#define OBEXFTP_UNICODE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int CharToUnicode(uint8_t *uc, const uint8_t *c, int size); +int UnicodeToChar(uint8_t *c, const uint8_t *uc, int size); +int Utf8ToChar(uint8_t *c, const uint8_t *uc, int size); + +#ifdef __cplusplus +} +#endif + +#endif /* OBEXFTP_UNICODE_H */ --- /dev/null 2014-11-11 18:16:49.229711166 -0800 +++ libbtctl-0.11.1/src/unicode.c 2013-03-05 12:43:50.000000000 -0800 @@ -0,0 +1,294 @@ +/** + \file obexftp/unicode.c + Unicode charset and encoding conversions. + ObexFTP library - language bindings for OBEX file transfer. + + Copyright (c) 2007 Christian W. Zuckschwerdt + + ObexFTP is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with ObexFTP. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#ifdef _WIN32 /* no need for iconv */ +#include /* pulls in Winnls.h */ +#else +#ifdef HAVE_ICONV +#include +#include +#ifndef ICONV_CONST +#define ICONV_CONST +#endif +#ifdef HAVE_LANGINFO_H +#include +#define locale_charset nl_langinfo(CODESET) +#else +#define locale_charset "" +#endif /* HAVE_LANGINFO_H */ +#endif /* HAVE_ICONV */ +#endif /* _WIN32 */ + +#include "unicode.h" + +#include + + +/** + Convert a string to UTF-16BE, tries to guess charset and encoding. + + As a lib we can't be sure what the input charset and encoding is. + Try to read the input as UTF-8, this will also work for plain ASCII (7bit). + On errors fall back to the environment locale, which again could be UTF-8. + As last resort try to copy verbatim, i.e. as ISO-8859-1. + + \note This is a quick hack until OpenOBEX is iconv-ready. + */ +int CharToUnicode(uint8_t *uc, const uint8_t *c, int size) +{ +#ifdef _WIN32 /* no need for iconv */ + int ret, i; + char tmp; + + return_val_if_fail(uc != NULL, -1); + return_val_if_fail(c != NULL, -1); + + /* ANSI to UTF-16LE */ + ret = MultiByteToWideChar(CP_ACP, 0, c, -1, (LPWSTR)uc, size); + /* turn the eggs the right way around now */ + for (i=0; i < ret; i++) { + tmp = uc[2*i]; + uc[2*i] = uc[2*i+1]; + uc[2*i+1] = tmp; + } + return ret * 2; /* 0 on error */ +#else /* _WIN32 */ + +#ifdef HAVE_ICONV + iconv_t utf16; + size_t ni, no, nrc; + /* avoid type-punned dereferecing (breaks strict aliasing) */ + ICONV_CONST char *cc = (ICONV_CONST char *)c; + char *ucc = (char *)uc; + + return_val_if_fail(uc != NULL, -1); + return_val_if_fail(c != NULL, -1); + + /* try UTF-8 to UTF-16BE */ + ni = strlen(cc) + 1; + no = size; + utf16 = iconv_open("UTF-16BE", "UTF-8"); + nrc = iconv(utf16, &cc, &ni, &ucc, &no); + (void)iconv_close(utf16); + if (nrc == (size_t)(-1)) { + DEBUG(3, "Iconv from UTF-8 conversion error: '%s'\n", cc); + } else { + return size-no; + } + + /* try current locale charset to UTF-16BE */ + setlocale(LC_CTYPE, ""); + DEBUG(2, "Iconv from locale \"%s\"\n", locale_charset); + cc = (ICONV_CONST char *)c; + ucc = (char *)uc; + ni = strlen(cc) + 1; + no = size; + utf16 = iconv_open("UTF-16BE", locale_charset); + nrc = iconv(utf16, &cc, &ni, &ucc, &no); + (void)iconv_close(utf16); + if (nrc == (size_t)(-1)) { + DEBUG(3, "Iconv from locale conversion error: '%s'\n", cc); + } else { + return size-no; + } + + /* fallback to ISO-8859-1 to UTF-16BE (every byte is valid here) */ + cc = (ICONV_CONST char *)c; + ucc = (char *)uc; + ni = strlen(cc) + 1; + no = size; + utf16 = iconv_open("UTF-16BE", "ISO-8859-1"); + nrc = iconv(utf16, &cc, &ni, &ucc, &no); + (void)iconv_close(utf16); + if (nrc == (size_t)(-1)) { + DEBUG(2, "Iconv internal conversion error: '%s'\n", cc); + return -1; + } + + return size-no; +#else /* HAVE_ICONV */ + int len, n; + + if (uc == NULL || c == NULL) + return -1; + + len = n = strlen((char *) c); + if (n*2+2 > size) + return -1; + + uc[n*2+1] = 0; + uc[n*2] = 0; + + while (n--) { + uc[n*2+1] = c[n]; + uc[n*2] = 0; + } + + return (len * 2) + 2; +#endif /* HAVE_ICONV */ + +#endif /* _WIN32 */ +} + + +/** + Convert a string from UTF-16BE to locale charset. + + Plain ASCII (7bit) and basic ISO-8859-1 will always work. + This conversion supports UTF-8 and single byte locales. + + \note This is a quick hack until OpenOBEX is iconv-ready. + */ +int UnicodeToChar(uint8_t *c, const uint8_t *uc, int size) +{ +#ifdef _WIN32 /* no need for iconv */ + int ret, n, i; + uint8_t *le; + + return_val_if_fail(uc != NULL, -1); + return_val_if_fail(c != NULL, -1); + + /* turn the eggs around, pointy side up */ + for (n=0; uc[2*n] != 0 || uc[2*n+1] != 0; n++); + le = malloc(2*n+2); + for (i=0; i <= n; i++) { + le[2*i] = uc[2*i+1]; + le[2*i+1] = uc[2*i]; + } + /* UTF-16LE to ANSI */ + ret = WideCharToMultiByte(CP_ACP, 0, le, -1, c, size, NULL, NULL); + free(le); + return ret; /* 0 on error */ +#else /* _WIN32 */ + +#ifdef HAVE_ICONV + iconv_t utf16; + size_t ni, no, nrc; + /* avoid type-punned dereferecing (breaks strict aliasing) */ + char *cc = (char *)c; + ICONV_CONST char *ucc = (ICONV_CONST char *)uc; + + return_val_if_fail(uc != NULL, -1); + return_val_if_fail(c != NULL, -1); + + /* UTF-16BE to current locale charset */ + setlocale(LC_CTYPE, ""); + DEBUG(3, "Iconv to locale \"%s\"\n", locale_charset); + for (ni=0; ucc[2*ni] != 0 || ucc[2*ni+1] != 0; ni++); + ni = 2*ni+2; + no = size; + utf16 = iconv_open(locale_charset, "UTF-16BE"); + nrc = iconv(utf16, &ucc, &ni, &cc, &no); + (void)iconv_close(utf16); + if (nrc == (size_t)(-1)) { + DEBUG(2, "Iconv from locale conversion error: '%s'\n", cc); + } + return size-no; +#else /* HAVE_ICONV */ + int n; + + if (uc == NULL || c == NULL) + return -1; + + /* Make sure buffer is big enough! */ + for (n = 0; uc[n*2+1] != 0; n++); + + if (n >= size) + return -1; + + for (n = 0; uc[n*2+1] != 0; n++) + c[n] = uc[n*2+1]; + c[n] = 0; + + return 0; +#endif /* HAVE_ICONV */ + +#endif /* _WIN32 */ +} + + +/** + Convert a (xml) string from UTF-8 to locale charset. + + Plain ASCII (7bit) and basic ISO-8859-1 will always work. + This conversion supports UTF-8 and single byte locales. + + \note This is a quick hack until OpenOBEX is iconv-ready. + */ +int Utf8ToChar(uint8_t *c, const uint8_t *uc, int size) +{ +#ifdef _WIN32 /* no need for iconv */ + int ret, n, i; + uint8_t *le; + + return_val_if_fail(uc != NULL, -1); + return_val_if_fail(c != NULL, -1); + + n = strlen(uc)*2+2; + le = malloc(n); + /* UTF-8 to UTF-16LE */ + ret = MultiByteToWideChar(CP_UTF8, 0, uc, -1, (LPWSTR)le, n); + + /* UTF-16LE to ANSI */ + ret = WideCharToMultiByte(CP_ACP, 0, le, -1, c, size, NULL, NULL); + free(le); + return ret; /* 0 on error */ +#else /* _WIN32 */ + +#ifdef HAVE_ICONV + iconv_t utf8; + size_t ni, no, nrc; + /* avoid type-punned dereferecing (breaks strict aliasing) */ + char *cc = (char *)c; + ICONV_CONST char *ucc = (ICONV_CONST char *)uc; + + return_val_if_fail(uc != NULL, -1); + return_val_if_fail(c != NULL, -1); + + setlocale(LC_CTYPE, ""); + DEBUG(2, "Iconv to \"%s\"\n", locale_charset); + ni = strlen(ucc); + no = size; + utf8 = iconv_open(locale_charset, "UTF-8"); + nrc = iconv(utf8, &ucc, &ni, &cc, &no); + (void)iconv_close(utf8); + if (nrc != (size_t)(-1)) { + DEBUG(2, "Iconv from locale conversion error: '%s'\n", cc); + } + return size-no; +#else /* HAVE_ICONV */ + int n, i; + n = strlen(uc); + strncpy(c, uc, size); + c[size] = '\0'; + return n; +#endif /* HAVE_ICONV */ + +#endif /* _WIN32 */ +} --- /dev/null 2014-11-11 18:16:49.229711166 -0800 +++ libbtctl-0.11.1/src/common.h 2013-03-05 12:43:50.000000000 -0800 @@ -0,0 +1,73 @@ +/** + \file includes/common.h + ObexFTP common macros and debugging. + ObexFTP library - language bindings for OBEX file transfer. + */ + +#ifndef _OBEXFTP_COMMON_H +#define _OBEXFTP_COMMON_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include + +#ifdef UNUSED +#elif defined(__GNUC__) +# define UNUSED(x) UNUSED_ ## x __attribute__((unused)) +#elif defined(__LCLINT__) +# define UNUSED(x) /*@unused@*/ x +#else +# define UNUSED(x) x +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +/* these are not asserts! dont define to nothing */ +#define return_if_fail(expr) do { if (!(expr)) return; } while(0); +#define return_val_if_fail(expr,val) do { if (!(expr)) return val; } while(0); + +#ifdef _WIN32 +#define snprintf _snprintf +#endif /* _WIN32 */ + +/* use 0 for production, 1 for verification, >2 for debug */ +#ifndef OBEXFTP_DEBUG +#define OBEXFTP_DEBUG 0 +#endif + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define DEBUG(n, ...) if (OBEXFTP_DEBUG >= (n)) fprintf(stderr, __VA_ARGS__) +#elif defined (__GNUC__) +#define DEBUG(n, format...) if (OBEXFTP_DEBUG >= (n)) fprintf (stderr, format) +#else /* !__GNUC__ */ +static void +DEBUG (int n, const char *format, ...) +{ + va_list args; + if (OBEXFTP_DEBUG >= (n)) { + va_start (args, format); + fprintf (stderr, format, args); + va_end (args); + } +} +#endif /* !__GNUC__ */ + +#if OBEXFTP_DEBUG > 4 +#define DEBUGBUFFER(b,l) do { \ + int i; \ + for (i=0; i < (l); i++) \ + fprintf (stderr, "%02x ", ((uint8_t *)(b))[i]); \ + fprintf (stderr, "\n"); \ +} while (0) +#else +#define DEBUGBUFFER(b,l) do { } while (0) +#endif + +#endif /* _OBEXFTP_COMMON_H */