diff --git a/ctrl.c b/ctrl.c index 6258f35..92a39b9 100644 --- a/ctrl.c +++ b/ctrl.c @@ -39,6 +39,7 @@ extern RD_BOOL g_seamless_rdp; extern uint8 g_static_rdesktop_salt_16[]; +extern char g_codepage[16]; static RD_BOOL _ctrl_is_slave; static int ctrlsock; @@ -442,10 +443,6 @@ ctrl_check_fds(fd_set * rfds, fd_set * wfds) } } -#if HAVE_ICONV -extern char g_codepage[16]; -#endif - int ctrl_send_command(const char *cmd, const char *arg) { diff --git a/rdesktop.c b/rdesktop.c index 98329a7..a6ec56d 100644 --- a/rdesktop.c +++ b/rdesktop.c @@ -36,11 +36,9 @@ #ifdef HAVE_LOCALE_H #include #endif -#ifdef HAVE_ICONV #ifdef HAVE_LANGINFO_H #include #endif -#endif #ifdef EGD_SOCKET #include @@ -142,9 +140,7 @@ RD_BOOL g_pending_resize = False; RD_BOOL g_rdpsnd = False; #endif -#ifdef HAVE_ICONV char g_codepage[16] = ""; -#endif char *g_sc_csp_name = NULL; /* Smartcard CSP name */ char *g_sc_reader_name = NULL; @@ -189,9 +185,7 @@ usage(char *program) #endif fprintf(stderr, " -f: full-screen mode\n"); fprintf(stderr, " -b: force bitmap updates\n"); -#ifdef HAVE_ICONV fprintf(stderr, " -L: local codepage\n"); -#endif fprintf(stderr, " -A: path to SeamlessRDP shell, this enables SeamlessRDP mode\n"); fprintf(stderr, " -B: use BackingStore of X-server (if available)\n"); fprintf(stderr, " -e: disable encryption (French TS)\n"); @@ -602,11 +596,7 @@ main(int argc, char *argv[]) break; case 'L': -#ifdef HAVE_ICONV STRNCPY(g_codepage, optarg, sizeof(g_codepage)); -#else - error("iconv support not available\n"); -#endif break; case 'd': @@ -1033,7 +1023,6 @@ main(int argc, char *argv[]) STRNCPY(g_username, pw->pw_name, pwlen); } -#ifdef HAVE_ICONV if (g_codepage[0] == 0) { if (setlocale(LC_CTYPE, "")) @@ -1045,7 +1034,6 @@ main(int argc, char *argv[]) STRNCPY(g_codepage, DEFAULT_CODEPAGE, sizeof(g_codepage)); } } -#endif if (g_hostname[0] == 0) { diff --git a/rdp.c b/rdp.c index a75fe0e..4eb70d1 100644 --- a/rdp.c +++ b/rdp.c @@ -3,7 +3,7 @@ Protocol services - RDP layer Copyright (C) Matthew Chapman 1999-2008 Copyright 2003-2011 Peter Astrand for Cendio AB - Copyright 2011-2014 Henrik Andersson for Cendio AB + Copyright 2011-2017 Henrik Andersson for Cendio AB 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 @@ -20,6 +20,8 @@ */ #include +#include + #ifndef _WIN32 #include #include @@ -27,15 +29,6 @@ #include "rdesktop.h" #include "ssl.h" -#ifdef HAVE_ICONV -#ifdef HAVE_ICONV_H -#include -#endif - -#ifndef ICONV_CONST -#define ICONV_CONST "" -#endif -#endif extern uint16 g_mcs_userid; extern char *g_username; @@ -90,10 +83,6 @@ extern uint8 g_client_random[SEC_RANDOM_SIZE]; static uint32 g_packetno; #endif -#ifdef HAVE_ICONV -static RD_BOOL g_iconv_works = True; -#endif - /* Receive an RDP packet */ static STREAM rdp_recv(uint8 * type) @@ -189,74 +178,42 @@ rdp_send_data(STREAM s, uint8 data_pdu_type) void rdp_out_unistr(STREAM s, char *string, int len) { + static iconv_t icv_local_to_utf16; + size_t ibl, obl; + char *pin, *pout; + + if (string == NULL || len == 0) return; -#ifdef HAVE_ICONV - size_t ibl = strlen(string), obl = len + 2; - static iconv_t iconv_h = (iconv_t) - 1; - char *pin = string, *pout = (char *) s->p; + // if not already open + if (!icv_local_to_utf16) + { + icv_local_to_utf16 = iconv_open(WINDOWS_CODEPAGE, g_codepage); + if (icv_local_to_utf16 == (iconv_t) - 1) + { + error("rdp_out_unistr: iconv_open[%s -> %s] fail %p\n", + g_codepage, WINDOWS_CODEPAGE, icv_local_to_utf16); + abort(); + } + } + + + ibl = strlen(string); + obl = len + 2; + pin = string; + pout = (char *) s->p; memset(pout, 0, len + 4); - if (g_iconv_works) + + if (iconv(icv_local_to_utf16, (char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) { - if (iconv_h == (iconv_t) - 1) - { - size_t i = 1, o = 4; - if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1) - { - warning("rdp_out_unistr: iconv_open[%s -> %s] fail %p\n", - g_codepage, WINDOWS_CODEPAGE, iconv_h); - - g_iconv_works = False; - rdp_out_unistr(s, string, len); - return; - } - if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) == - (size_t) - 1) - { - iconv_close(iconv_h); - iconv_h = (iconv_t) - 1; - warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno); - - g_iconv_works = False; - rdp_out_unistr(s, string, len); - return; - } - pin = string; - pout = (char *) s->p; - } - - if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) - { - iconv_close(iconv_h); - iconv_h = (iconv_t) - 1; - warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno); - - g_iconv_works = False; - rdp_out_unistr(s, string, len); - return; - } - - s->p += len + 2; - + error("rdp_out_unistr: iconv(2) fail, errno %d\n", errno); + abort(); } - else -#endif - { - int i = 0, j = 0; - len += 2; - - while (i < len) - { - s->p[i++] = string[j++]; - s->p[i++] = 0; - } - - s->p += len; - } + s->p += len + 2; } /* Input a string in Unicode @@ -266,78 +223,59 @@ rdp_out_unistr(STREAM s, char *string, int len) void rdp_in_unistr(STREAM s, int in_len, char **string, uint32 * str_size) { - /* Dynamic allocate of destination string if not provided */ - *string = xmalloc(in_len * 2); - *str_size = in_len * 2; + static iconv_t icv_utf16_to_local; + size_t ibl, obl; + char *pin, *pout; -#ifdef HAVE_ICONV - size_t ibl = in_len, obl = *str_size - 1; - char *pin = (char *) s->p, *pout = *string; - static iconv_t iconv_h = (iconv_t) - 1; - - if (g_iconv_works) + // if not already open + if (!icv_utf16_to_local) { - if (iconv_h == (iconv_t) - 1) + icv_utf16_to_local = iconv_open(g_codepage, WINDOWS_CODEPAGE); + if (icv_utf16_to_local == (iconv_t) - 1) { - if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1) - { - warning("rdp_in_unistr: iconv_open[%s -> %s] fail %p\n", - WINDOWS_CODEPAGE, g_codepage, iconv_h); - - g_iconv_works = False; - return rdp_in_unistr(s, in_len, string, str_size); - } + error("rdp_in_unistr: iconv_open[%s -> %s] fail %p\n", + WINDOWS_CODEPAGE, g_codepage, icv_utf16_to_local); + abort(); } - - if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) - { - if (errno == E2BIG) - { - warning("server sent an unexpectedly long string, truncating\n"); - } - else - { - warning("rdp_in_unistr: iconv fail, errno %d\n", errno); - - free(*string); - *string = NULL; - *str_size = 0; - } - } - - /* we must update the location of the current STREAM for future reads of s->p */ - s->p += in_len; - - *pout = 0; - - if (*string) - *str_size = pout - *string; } - else -#endif - { - int i = 0; - int rem = 0; - uint32 len = in_len / 2; - char *pstr = *string; - if (len > *str_size - 1) + /* Dynamic allocate of destination string if not provided */ + if (*string == NULL) + { + + *string = xmalloc(in_len * 2); + *str_size = in_len * 2; + } + + ibl = in_len; + obl = *str_size - 1; + pin = (char *) s->p; + pout = *string; + + if (iconv(icv_utf16_to_local, (char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) + { + if (errno == E2BIG) { warning("server sent an unexpectedly long string, truncating\n"); - len = *str_size - 1; - rem = in_len - 2 * len; } - - while (i < len) + else { - in_uint8a(s, &pstr[i++], 1); - in_uint8s(s, 1); - } + warning("rdp_in_unistr: iconv fail, errno %d\n", errno); - in_uint8s(s, rem); - pstr[len] = 0; - *str_size = len; + free(*string); + *string = NULL; + *str_size = 0; + } + abort(); } + + /* we must update the location of the current STREAM for future reads of s->p */ + s->p += in_len; + + *pout = 0; + + if (*string) + *str_size = pout - *string; } diff --git a/utils.c b/utils.c index cb42fd5..d73bf25 100644 --- a/utils.c +++ b/utils.c @@ -21,18 +21,11 @@ #include #include #include -#ifdef HAVE_ICONV_H #include -#endif #include "rdesktop.h" - -#ifdef HAVE_ICONV extern char g_codepage[16]; static RD_BOOL g_iconv_works = True; -#endif - - char * utils_string_escape(const char *str) @@ -177,7 +170,6 @@ utils_mkdir_p(const char *path, int mask) int utils_locale_to_utf8(const char *src, size_t is, char *dest, size_t os) { -#ifdef HAVE_ICONV static iconv_t *iconv_h = (iconv_t) - 1; if (strncmp(g_codepage, "UTF-8", strlen("UTF-8")) == 0) goto pass_trough_as_is; @@ -199,7 +191,7 @@ utils_locale_to_utf8(const char *src, size_t is, char *dest, size_t os) } /* convert string */ - if (iconv(iconv_h, (ICONV_CONST char **) &src, &is, &dest, &os) == (size_t) - 1) + if (iconv(iconv_h, (char **) &src, &is, &dest, &os) == (size_t) - 1) { iconv_close(iconv_h); iconv_h = (iconv_t) - 1; @@ -213,7 +205,6 @@ utils_locale_to_utf8(const char *src, size_t is, char *dest, size_t os) if (is != 0) return -1; -#endif pass_trough_as_is: /* can dest hold strcpy of src */ if (os < (strlen(src) + 1)) diff --git a/xclip.c b/xclip.c index 8a433bd..9798055 100644 --- a/xclip.c +++ b/xclip.c @@ -32,15 +32,11 @@ http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/dataexchange/clipboard/clipboardformats.asp */ -#ifdef HAVE_ICONV #ifdef HAVE_LANGINFO_H -#ifdef HAVE_ICONV_H #include #include #define USE_UNICODE_CLIPBOARD #endif -#endif -#endif #ifdef USE_UNICODE_CLIPBOARD #define RDP_CF_TEXT CF_UNICODETEXT @@ -357,7 +353,7 @@ xclip_send_data_with_convert(uint8 * source, size_t source_size, Atom target) unicode_buffer_remaining = unicode_buffer; data_remaining = (char *) source; data_size_remaining = source_size; - iconv(cd, (ICONV_CONST char **) &data_remaining, &data_size_remaining, + iconv(cd, (char **) &data_remaining, &data_size_remaining, &unicode_buffer_remaining, &unicode_buffer_size_remaining); iconv_close(cd); @@ -1005,7 +1001,7 @@ ui_clip_handle_data(uint8 * data, uint32 length) iconv_close(cd); return; } - iconv(cd, (ICONV_CONST char **) &data_remaining, &length_remaining, + iconv(cd, (char **) &data_remaining, &length_remaining, &utf8_data_remaining, &utf8_length_remaining); iconv_close(cd); free_data = True;