- Add Windows UTF8 to classic UTF8 conversion through a lexer
authorJulien Kerihuel <j.kerihuel@openchange.org>
Thu, 31 May 2007 02:56:35 +0000 (02:56 +0000)
committerJulien Kerihuel <j.kerihuel@openchange.org>
Thu, 31 May 2007 02:56:35 +0000 (02:56 +0000)
- openchangeclient --mailbox option changed to use it
- flex and bison support added to configure.ac
- windows_to_utf8 function added: wrapper over yyparse_utf8 routine

Makefile.in
configure.ac
libmapi/utf8_convert.l [new file with mode: 0644]
libmapi/utils.c
utils/openchangeclient.c

index 4d79b98bd1c334b65fb41a216b1f9599e61fdd55..687ee87eaa8015b18d653f7c4552cca5f37bc40c 100644 (file)
@@ -2,6 +2,7 @@
 # Written by Jelmer Vernooij <jelmer@samba.org>, 2005.
 
 CC=@CC@
+LEX=@LEX@
 CFLAGS=@CFLAGS@ -I. -Wall -Wmissing-prototypes -Wstrict-prototypes -g3
 PIDL=@PIDL@
 PERL=@PERL@
@@ -33,7 +34,8 @@ LIBS+=@SAMBA_LIBS@
 CFLAGS+=@LDB_CFLAGS@ @TALLOC_CFLAGS@
 LIBS+=@LDB_LIBS@ @TALLOC_LIBS@
 
-all:   gen_ndr gen_ndr/ndr_exchange.h proto.h                  \
+all:   libmapi/utf8_convert.yy.c                               \
+       gen_ndr gen_ndr/ndr_exchange.h proto.h                  \
        torture_proto.h providers_proto.h dcesrv_proto.h        \
        libmapi.$(SHLIBEXT)                                     \
        bin/schemaIDGUID                                        \
@@ -128,6 +130,10 @@ torture/openchange.$(SHLIBEXT):    torture/testjoin_exchange.o     \
        @echo "Compiling $<"
        @$(CC) -o $@ $(DSOOPT) $^ -L. $(LIBS) -lmapi
 
+libmapi/utf8_convert.yy.c:     libmapi/utf8_convert.l
+       @echo "Generating $@"
+       @$(LEX) -t $< > $@
+
 server/dcesrv_exchange.$(SHLIBEXT): providers/emsabp.o server/dcesrv_exchange.o
        @echo "Compiling $<"
        @$(CC) -o $@ $(DSOOPT) $^ -L. -lmapi $(LIBS)
@@ -207,6 +213,7 @@ realdistclean: distclean
 clean:
        rm -f libmapi/generated/*
        rm -f libmapi/*.o
+       rm -f libmapi/utf8_convert.yy.c
        rm -f libmapi/tests/*.o
        rm -f libmapi/util/*.o
        rm -f tests/*.o
@@ -330,7 +337,8 @@ libmapi.$(SHLIBEXT):        libmapi/IABContainer.o                          \
                        gen_ndr/ndr_exchange.o                          \
                        gen_ndr/ndr_exchange_c.o                        \
                        libmapi/socket/interface.o                      \
-                       libmapi/socket/netif.o                          
+                       libmapi/socket/netif.o                          \
+                       libmapi/utf8_convert.yy.c
        @echo "Compiling $<"
        @$(CC) $(DSOOPT) -o $@ $^ $(LIBS)
 
index b994ef1c7295d3a49e9ef30252ced0bd80a4e16a..6ac2282915d0d8f03e480db70bcfa6af28ad119f 100644 (file)
@@ -7,6 +7,8 @@ AC_CONFIG_HEADER([config.h])
 AC_DEFINE(_GNU_SOURCE, 1, [Use GNU extensions])
 
 AC_PROG_CC
+AC_PROG_LEX
+AC_PROG_YACC
 
 dnl ***********************
 dnl Check for PERL
diff --git a/libmapi/utf8_convert.l b/libmapi/utf8_convert.l
new file mode 100644 (file)
index 0000000..8595815
--- /dev/null
@@ -0,0 +1,356 @@
+%{
+/*
+ *  OpenChange MAPI implementation.
+ *
+ *  Copyright (C) Julien Kerihuel 2007.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+int yylex(void);
+
+char *newbuf;
+int  newbuf_idx;
+
+#define        U00A1   "\xc2\xa1"      /* ¡ */
+#define        U00A2   "\xc2\xa2"      /* ¢ */
+#define        U00A3   "\xc2\xa3"      /* £ */
+#define        U00A4   "\xc2\xa4"      /* ¤ */
+#define        U00A5   "\xc2\xa5"      /* ¥ */
+#define        U00A6   "\xc2\xa6"      /* ¦ */
+#define        U00A7   "\xc2\xa7"      /* § */
+#define        U00A8   "\xc2\xa8"      /* ¨ */
+#define        U00A9   "\xc2\xa9"      /* © */
+#define        U00AA   "\xc2\xaa"      /* ª */
+#define        U00AB   "\xc2\xab"      /* « */
+#define        U00AC   "\xc2\xac"      /* ¬ */
+#define U00AD  "\xc2\xad"      /* ­ */
+#define U00AE  "\xc2\xae"      /* ® */
+#define U00AF  "\xc2\xaf"      /* ¯ */
+#define U00B0  "\xc2\xb0"      /* ° */
+#define U00B1  "\xc2\xb1"      /* ± */
+#define U00B2  "\xc2\xb2"      /* ² */
+#define U00B3  "\xc2\xb3"      /* ³ */
+#define U00B4  "\xc2\xb4"      /* ´ */
+#define U00B5  "\xc2\xb5"      /* µ */
+#define U00B6  "\xc2\xb6"      /* ¶ */
+#define U00B7  "\xc2\xb7"      /* · */
+#define U00B8  "\xc2\xb8"      /* ¸ */
+#define U00B9  "\xc2\xb9"      /* ¹ */
+#define U00BA  "\xc2\xba"      /* º */
+#define U00BB  "\xc2\xbb"      /* » */
+#define U00BC  "\xc2\xbc"      /* ¼ */
+#define U00BD  "\xc2\xbd"      /* ½ */
+#define U00BE  "\xc2\xbe"      /* ¾ */
+#define U00BF  "\xc2\xbf"      /* ¿ */
+#define U00C0  "\xc3\x80"      /* À */
+#define U00C1  "\xc3\x81"      /* Á */
+#define U00C2  "\xc3\x82"      /* Â */
+#define U00C3  "\xc3\x83"      /* Ã */
+#define U00C4  "\xc3\x84"      /* Ä */
+#define U00C5  "\xc3\x85"      /* Å */
+#define U00C6  "\xc3\x86"      /* Æ */
+#define U00C7  "\xc3\x87"      /* Ç */
+#define U00C8  "\xc3\x88"      /* È */
+#define        U00C9   "\xc3\x89"      /* É */
+#define        U00CA   "\xc3\x8a"      /* Ê */
+#define        U00CB   "\xc3\x8b"      /* Ë */
+#define        U00CC   "\xc3\x8c"      /* Ì */
+#define        U00CD   "\xc3\x8d"      /* Í */
+#define        U00CE   "\xc3\x8e"      /* Î */
+#define        U00CF   "\xc3\x8f"      /* Ï */
+#define        U00D0   "\xc3\x90"      /* Ð */
+#define        U00D1   "\xc3\x91"      /* Ñ */
+#define        U00D2   "\xc3\x92"      /* Ò */
+#define        U00D3   "\xc3\x93"      /* Ó */
+#define        U00D4   "\xc3\x94"      /* Ô */
+#define        U00D5   "\xc3\x95"      /* Õ */
+#define        U00D6   "\xc3\x96"      /* Ö */
+#define        U00D7   "\xc3\x97"      /* × */
+#define        U00D8   "\xc3\x98"      /* Ø */
+#define        U00D9   "\xc3\x99"      /* Ù */
+#define        U00DA   "\xc3\x9a"      /* Ú */
+#define        U00DB   "\xc3\x9b"      /* Û */
+#define        U00DC   "\xc3\x9c"      /* Ü */
+#define        U00DD   "\xc3\x9d"      /* Ý */
+#define        U00DE   "\xc3\x9e"      /* Þ */
+#define        U00DF   "\xc3\x9f"      /* ß */
+#define        U00E0   "\xc3\xa0"      /* à */
+#define        U00E1   "\xc3\xa1"      /* á */
+#define        U00E2   "\xc3\xa2"      /* â */
+#define        U00E3   "\xc3\xa3"      /* ã */
+#define        U00E4   "\xc3\xa4"      /* ä */
+#define        U00E5   "\xc3\xa5"      /* å */
+#define        U00E6   "\xc3\xa6"      /* æ */
+#define        U00E7   "\xc3\xa7"      /* ç */
+#define        U00E8   "\xc3\xa8"      /* è */
+#define        U00E9   "\xc3\xa9"      /* é */
+#define        U00EA   "\xc3\xaa"      /* ê */
+#define        U00EB   "\xc3\xab"      /* ë */
+#define        U00EC   "\xc3\xac"      /* ì */
+#define        U00ED   "\xc3\xad"      /* í */
+#define        U00EE   "\xc3\xae"      /* î */
+#define        U00EF   "\xc3\xaf"      /* ï */
+#define        U00F0   "\xc3\xb0"      /* ð */
+#define        U00F1   "\xc3\xb1"      /* ñ */
+#define        U00F2   "\xc3\xb2"      /* ò */
+#define        U00F3   "\xc3\xb3"      /* ó */
+#define        U00F4   "\xc3\xb4"      /* ô */
+#define        U00F5   "\xc3\xb5"      /* õ */
+#define        U00F6   "\xc3\xb6"      /* ö */
+#define        U00F7   "\xc3\xb7"      /* ÷ */
+#define        U00F8   "\xc3\xb8"      /* ø */
+#define        U00F9   "\xc3\xb9"      /* ù */
+#define        U00FA   "\xc3\xba"      /* ú */
+#define        U00FB   "\xc3\xbb"      /* û */
+#define        U00FC   "\xc3\xbc"      /* ü */
+#define        U00FD   "\xc3\xbd"      /* ý */
+#define        U00FE   "\xc3\xbe"      /* þ */
+#define        U00FF   "\xc3\xbf"      /* ÿ */
+
+%}
+
+chars [A-za-z\_\'\.\"]
+numbers ([0-9])+
+delim [" "\n\t]
+whitespace {delim}+
+words {chars}+
+
+WIN_U00A1      "\xc3\xad"
+WIN_U00A2      "\xc3\xb3"
+WIN_U00A3      "\xc3\xba"
+WIN_U00A4      "\xc3\xb1"
+WIN_U00A5      "\xc3\x91"
+WIN_U00A6      "\xc2\xaa"
+WIN_U00A7      "\xc2\xba"
+WIN_U00A8      "\xc2\xbf"
+WIN_U00A9      "\xc2\xae"
+WIN_U00AA      "\xc2\xac"
+WIN_U00AB      "\xc2\xbd"
+WIN_U00AC      "\xc2\xbc"
+WIN_U00AD      "\xc2\xa1"
+WIN_U00AE      "\xc2\xab"
+WIN_U00AF      "\xc2\xbb"
+WIN_U00B0      "\xe2\x96\x91"
+WIN_U00B1      "\xe2\x96\x92"
+WIN_U00B2      "\xe2\x96\x93"
+WIN_U00B3      "\xe2\x94\x82"
+WIN_U00B4      "\xe2\x94\xa4"
+WIN_U00B5      "\xc3\x81"
+WIN_U00B6      "\xc3\x82"
+WIN_U00B7      "\xc3\x80"
+WIN_U00B8      "\xc2\xa9"
+WIN_U00B9      "\xe2\x95\xa3"
+WIN_U00BA      "\xe2\x95\x91"
+WIN_U00BB      "\xe2\x95\x97"
+WIN_U00BC      "\xe2\x95\x9d"
+WIN_U00BD      "\xc2\xa2"
+WIN_U00BE      "\xc2\xa5"
+WIN_U00BF      "\xe2\x94\x90"
+WIN_U00C0      "\xe2\x94\x94"
+WIN_U00C1      "\xe2\x94\xb4"
+WIN_U00C2      "\xe2\x94\xac"
+WIN_U00C3      "\xe2\x94\x9c"
+WIN_U00C4      "\xe2\x94\x80"
+WIN_U00C5      "\xe2\x94\xbc"
+WIN_U00C6      "\xc3\xa3"
+WIN_U00C7      "\xc3\x83"
+WIN_U00C8      "\xe2\x95\x9a"
+WIN_U00C9      "\xe2\x95\x94"
+WIN_U00CA      "\xe2\x95\xa9"
+WIN_U00CB      "\xe2\x95\xa6"
+WIN_U00CC      "\xe2\x95\xa0"
+WIN_U00CD      "\xe2\x95\x90"
+WIN_U00CE      "\xe2\x95\xac"
+WIN_U00CF      "\xc2\xa4"
+WIN_U00D0      "\xc3\xb0"
+WIN_U00D1      "\xc3\x90"
+WIN_U00D2      "\xc3\x8a"
+WIN_U00D3      "\xc3\x8b"
+WIN_U00D4      "\xc3\x88"
+WIN_U00D5      "\xc4\xb1"
+WIN_U00D6      "\xc3\x8d"
+WIN_U00D7      "\xc3\x8e"
+WIN_U00D8      "\xc3\x8f"
+WIN_U00D9      "\xe2\x94\x98"
+WIN_U00DA      "\xe2\x94\x8c"
+WIN_U00DB      "\xe2\x96\x88"
+WIN_U00DC      "\xe2\x96\x84"
+WIN_U00DD      "\xc2\xa6"
+WIN_U00DE      "\xc3\x8c"
+WIN_U00DF      "\xe2\x96\x80"
+WIN_U00E0      "\xc3\x93"
+WIN_U00E1      "\xc3\x9f"
+WIN_U00E2      "\xc3\x94"
+WIN_U00E3      "\xc3\x92"
+WIN_U00E4      "\xc3\xb5"
+WIN_U00E5      "\xc3\x95"
+WIN_U00E6      "\xc2\xb5"
+WIN_U00E7      "\xc3\xbe"
+WIN_U00E8      "\xc3\x9e"
+WIN_U00E9      "\xc3\x9a"
+WIN_U00EA      "\xc3\x9b"
+WIN_U00EB      "\xc3\x99"
+WIN_U00EC      "\xc3\xbd"
+WIN_U00ED      "\xc3\x9d"
+WIN_U00EE      "\xc2\xaf"
+WIN_U00EF      "\xc2\xb4"
+WIN_U00F0      "\xc2\xad"
+WIN_U00F1      "\xc2\xb1"
+WIN_U00F2      "\xe2\x80\x97"
+WIN_U00F3      "\xc2\xbe"
+WIN_U00F4      "\xc2\xb6"
+WIN_U00F5      "\xc2\xa7"
+WIN_U00F6      "\xc3\xb7"
+WIN_U00F7      "\xc2\xb8"
+WIN_U00F8      "\xc2\xb0"
+WIN_U00F9      "\xc2\xa8"
+WIN_U00FA      "\xc2\xb7"
+WIN_U00FB      "\xc2\xb9"
+WIN_U00FC      "\xc2\xb3"
+WIN_U00FD      "\xc2\xb2"
+WIN_U00FE      "\xe2\x96\xa0"
+WIN_U00FF      "\xc2\xa0"
+
+
+%%
+{words} { yyreplace_utf8(yytext); }
+{delim} { yyreplace_utf8(yytext); }
+{whitespace} { yyreplace_utf8(yytext); }
+{WIN_U00A1} { yyreplace_utf8(U00A1);}
+{WIN_U00A2} { yyreplace_utf8(U00A2);}
+{WIN_U00A3} { yyreplace_utf8(U00A3);}
+{WIN_U00A4} { yyreplace_utf8(U00A4);}
+{WIN_U00A5} { yyreplace_utf8(U00A5);}
+{WIN_U00A6} { yyreplace_utf8(U00A6);}
+{WIN_U00A7} { yyreplace_utf8(U00A7);}
+{WIN_U00A8} { yyreplace_utf8(U00A8);}
+{WIN_U00A9} { yyreplace_utf8(U00A9);}
+{WIN_U00AA} { yyreplace_utf8(U00AA);}
+{WIN_U00AB} { yyreplace_utf8(U00AB);}
+{WIN_U00AC} { yyreplace_utf8(U00AC);}
+{WIN_U00AD} { yyreplace_utf8(U00AD);}
+{WIN_U00AE} { yyreplace_utf8(U00AE);}
+{WIN_U00AF} { yyreplace_utf8(U00AF);}
+{WIN_U00B0} { yyreplace_utf8(U00B0);}
+{WIN_U00B1} { yyreplace_utf8(U00B1);}
+{WIN_U00B2} { yyreplace_utf8(U00B2);}
+{WIN_U00B3} { yyreplace_utf8(U00B3);}
+{WIN_U00B4} { yyreplace_utf8(U00B4);}
+{WIN_U00B5} { yyreplace_utf8(U00B5);}
+{WIN_U00B6} { yyreplace_utf8(U00B6);}
+{WIN_U00B7} { yyreplace_utf8(U00B7);}
+{WIN_U00B8} { yyreplace_utf8(U00B8);}
+{WIN_U00B9} { yyreplace_utf8(U00B9);}
+{WIN_U00BA} { yyreplace_utf8(U00BA);}
+{WIN_U00BB} { yyreplace_utf8(U00BB);}
+{WIN_U00BC} { yyreplace_utf8(U00BC);}
+{WIN_U00BD} { yyreplace_utf8(U00BD);}
+{WIN_U00BE} { yyreplace_utf8(U00BE);}
+{WIN_U00BF} { yyreplace_utf8(U00BF);}
+{WIN_U00C0} { yyreplace_utf8(U00C0);}
+{WIN_U00C1} { yyreplace_utf8(U00C1);}
+{WIN_U00C2} { yyreplace_utf8(U00C2);}
+{WIN_U00C3} { yyreplace_utf8(U00C3);}
+{WIN_U00C4} { yyreplace_utf8(U00C4);}
+{WIN_U00C5} { yyreplace_utf8(U00C5);}
+{WIN_U00C6} { yyreplace_utf8(U00C6);}
+{WIN_U00C7} { yyreplace_utf8(U00C7);}
+{WIN_U00C8} { yyreplace_utf8(U00C8);}
+{WIN_U00C9} { yyreplace_utf8(U00C9);}
+{WIN_U00CA} { yyreplace_utf8(U00CA);}
+{WIN_U00CB} { yyreplace_utf8(U00CB);}
+{WIN_U00CC} { yyreplace_utf8(U00CC);}
+{WIN_U00CD} { yyreplace_utf8(U00CD);}
+{WIN_U00CE} { yyreplace_utf8(U00CE);}
+{WIN_U00CF} { yyreplace_utf8(U00CF);}
+{WIN_U00D0} { yyreplace_utf8(U00D0);}
+{WIN_U00D1} { yyreplace_utf8(U00D1);}
+{WIN_U00D2} { yyreplace_utf8(U00D2);}
+{WIN_U00D3} { yyreplace_utf8(U00D3);}
+{WIN_U00D4} { yyreplace_utf8(U00D4);}
+{WIN_U00D5} { yyreplace_utf8(U00D5);}
+{WIN_U00D6} { yyreplace_utf8(U00D6);}
+{WIN_U00D7} { yyreplace_utf8(U00D7);}
+{WIN_U00D8} { yyreplace_utf8(U00D8);}
+{WIN_U00D9} { yyreplace_utf8(U00D9);}
+{WIN_U00DA} { yyreplace_utf8(U00DA);}
+{WIN_U00DB} { yyreplace_utf8(U00DB);}
+{WIN_U00DC} { yyreplace_utf8(U00DC);}
+{WIN_U00DD} { yyreplace_utf8(U00DD);}
+{WIN_U00DE} { yyreplace_utf8(U00DE);}
+{WIN_U00DF} { yyreplace_utf8(U00DF);}
+{WIN_U00E0} { yyreplace_utf8(U00E0);}
+{WIN_U00E1} { yyreplace_utf8(U00E1);}
+{WIN_U00E2} { yyreplace_utf8(U00E2);}
+{WIN_U00E3} { yyreplace_utf8(U00E3);}
+{WIN_U00E4} { yyreplace_utf8(U00E4);}
+{WIN_U00E5} { yyreplace_utf8(U00E5);}
+{WIN_U00E6} { yyreplace_utf8(U00E6);}
+{WIN_U00E7} { yyreplace_utf8(U00E7);}
+{WIN_U00E8} { yyreplace_utf8(U00E8);}
+{WIN_U00E9} { yyreplace_utf8(U00E9);}
+{WIN_U00EA} { yyreplace_utf8(U00EA);}
+{WIN_U00EB} { yyreplace_utf8(U00EB);}
+{WIN_U00EC} { yyreplace_utf8(U00EC);}
+{WIN_U00ED} { yyreplace_utf8(U00ED);}
+{WIN_U00EE} { yyreplace_utf8(U00EE);}
+{WIN_U00EF} { yyreplace_utf8(U00EF);}
+{WIN_U00F0} { yyreplace_utf8(U00F0);}
+{WIN_U00F1} { yyreplace_utf8(U00F1);}
+{WIN_U00F2} { yyreplace_utf8(U00F2);}
+{WIN_U00F3} { yyreplace_utf8(U00F3);}
+{WIN_U00F4} { yyreplace_utf8(U00F4);}
+{WIN_U00F5} { yyreplace_utf8(U00F5);}
+{WIN_U00F6} { yyreplace_utf8(U00F6);}
+{WIN_U00F7} { yyreplace_utf8(U00F7);}
+{WIN_U00F8} { yyreplace_utf8(U00F8);}
+{WIN_U00F9} { yyreplace_utf8(U00F9);}
+{WIN_U00FA} { yyreplace_utf8(U00FA);}
+{WIN_U00FB} { yyreplace_utf8(U00FB);}
+{WIN_U00FC} { yyreplace_utf8(U00FC);}
+{WIN_U00FD} { yyreplace_utf8(U00FD);}
+{WIN_U00FE} { yyreplace_utf8(U00FE);}
+{WIN_U00FF} { yyreplace_utf8(U00FF);}
+
+%%
+
+#ifndef yywrap
+int 
+yywrap(void) 
+{
+       return 1;
+}
+#endif
+
+int
+yyreplace_utf8(char *str)
+{
+       memcpy(&newbuf[newbuf_idx], str, strlen(str));
+       newbuf_idx += strlen(str);
+}
+
+int
+yyparse_utf8(char *mybuf, char *str)
+{
+       newbuf = mybuf;
+       newbuf_idx = 0;
+       yy_scan_string(str);
+       yylex();
+       newbuf[newbuf_idx] = 0;
+}
index c53b3f4694195c5ddd7de3651ff6a68d63b4e0ca..189102da9458775c968b1c9549bc041ac5524da7 100644 (file)
@@ -96,3 +96,21 @@ _PUBLIC_ struct SBinary *generate_recipient_entryid(TALLOC_CTX *mem_ctx, const c
        return entryid;
 }
 
+/**
+ * convert utf8 windows string into classic utf8
+ * NOTE: windows utf8 encoding is equal or larger to classic utf8
+ *       we should anyway find a better way to allocate the output buf
+ */
+
+int yyparse_utf8(char *, const char *);
+
+_PUBLIC_ char *windows_to_utf8(TALLOC_CTX *mem_ctx, const char *input)
+{
+       char    *output;
+
+       if (!input) return NULL;
+
+       output = talloc_size(mem_ctx, strlen(input) + 1);
+       yyparse_utf8(output, input);
+       return output;
+}
index aadc0b75184c014908bf88f7f54ac33e84b26e9f..d049aa5e1e39768c0362a8e3922f46fdee4d60eb 100644 (file)
@@ -988,6 +988,14 @@ static const char *get_container_class(TALLOC_CTX *mem_ctx, mapi_object_t *paren
        return lpProps[0].value.lpszA;
 }
 
+static char *utf8tolinux(TALLOC_CTX *mem_ctx, const char *wstring)
+{
+       char            *newstr;
+
+       newstr = windows_to_utf8(mem_ctx, wstring);
+       return newstr;
+}
+
 static BOOL get_child_folders(TALLOC_CTX *mem_ctx, mapi_object_t *parent, mapi_id_t folder_id, int count)
 {
        enum MAPISTATUS         retval;
@@ -997,6 +1005,7 @@ static BOOL get_child_folders(TALLOC_CTX *mem_ctx, mapi_object_t *parent, mapi_i
        struct SPropTagArray    *SPropTagArray;
        struct SRowSet          rowset;
        const char              *name;
+       char                    *newname;
        const char              *comment;
        uint32_t                *total;
        uint32_t                *unread;
@@ -1036,8 +1045,10 @@ static BOOL get_child_folders(TALLOC_CTX *mem_ctx, mapi_object_t *parent, mapi_i
                        for (i = 0; i < count; i++) {
                                printf("|   ");
                        }
-                       printf("|---+ %-15s : %-20s (Total: %d / Unread: %d - Container class: %s)\n", name, comment, *total, *unread,
+                       newname = utf8tolinux(mem_ctx, name);
+                       printf("|---+ %-15s : %-20s (Total: %d / Unread: %d - Container class: %s)\n", newname, comment, *total, *unread,
                               get_container_class(mem_ctx, parent, *fid));
+                       MAPIFreeBuffer(newname);
                        if (*child) {
                                ret = get_child_folders(mem_ctx, &obj_folder, *fid, count + 1);
                                if (ret == False) return ret;
@@ -1056,6 +1067,7 @@ static BOOL openchangeclient_mailbox(TALLOC_CTX *mem_ctx, struct mapi_session *s
        struct SPropValue               *lpProps;
        uint32_t                        cValues;
        const char                      *mailbox_name;
+       char                            *utf8_mailbox_name;
 
        /* Retrieve the mailbox folder name */
        SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_DISPLAY_NAME);
@@ -1073,7 +1085,9 @@ static BOOL openchangeclient_mailbox(TALLOC_CTX *mem_ctx, struct mapi_session *s
        retval = GetDefaultFolder(obj_store, &id_mailbox, olFolderTopInformationStore);
        if (retval != MAPI_E_SUCCESS) return False;
 
-       printf("+ %s\n", mailbox_name);
+       utf8_mailbox_name = utf8tolinux(mem_ctx, mailbox_name);
+       printf("+ %s\n", utf8_mailbox_name);
+       MAPIFreeBuffer(utf8_mailbox_name);
        return get_child_folders(mem_ctx, obj_store, id_mailbox, 0);
 }