diff options
Diffstat (limited to 'plugins/MirOTR/Libgpg-error/init.c')
-rw-r--r-- | plugins/MirOTR/Libgpg-error/init.c | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/plugins/MirOTR/Libgpg-error/init.c b/plugins/MirOTR/Libgpg-error/init.c new file mode 100644 index 0000000000..d30435a2ce --- /dev/null +++ b/plugins/MirOTR/Libgpg-error/init.c @@ -0,0 +1,399 @@ +/* init.c - Initialize the GnuPG error library. + Copyright (C) 2005, 2010 g10 Code GmbH + + This file is part of libgpg-error. + + libgpg-error 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.1 of + the License, or (at your option) any later version. + + libgpg-error 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 this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include <gpg-error.h> + +#include "gettext.h" +#include "init.h" + +#ifdef HAVE_W32CE_SYSTEM +# include "mkw32errmap.map.c" /* Generated map_w32codes () */ +#endif + + +/* Locale directory support. */ + +#if HAVE_W32_SYSTEM + +#include <windows.h> + +static int tls_index = TLS_OUT_OF_INDEXES; /* Index for the TLS functions. */ + +static char *get_locale_dir (void); +static void drop_locale_dir (char *locale_dir); + +#else /*!HAVE_W32_SYSTEM*/ + +#define get_locale_dir() LOCALEDIR +#define drop_locale_dir(dir) + +#endif /*!HAVE_W32_SYSTEM*/ + + +static void +real_init (void) +{ +#ifdef ENABLE_NLS + char *locale_dir; + + /* We only have to bind our locale directory to our text domain. */ + locale_dir = get_locale_dir (); + if (locale_dir) + { + bindtextdomain (PACKAGE, locale_dir); + drop_locale_dir (locale_dir); + } +#endif +} + +/* Initialize the library. This function should be run early. */ +gpg_error_t +gpg_err_init (void) +{ +#ifdef HAVE_W32_SYSTEM +# ifdef DLL_EXPORT + /* We always have a constructor and thus this function is called + automatically. Due to the way the C init code of mingw works, + the constructors are called before our DllMain function is + called. The problem with that is that the TLS has not been setup + and w32-gettext.c requires TLS. To solve this we do nothing here + but call the actual init code from our DllMain. */ +# else /*!DLL_EXPORT*/ + /* Note that if the TLS is actually used, we can't release the TLS + as there is no way to know when a thread terminates (i.e. no + thread-specific-atexit). You are really better off to use the + DLL! */ + if (tls_index == TLS_OUT_OF_INDEXES) + { + tls_index = TlsAlloc (); + if (tls_index == TLS_OUT_OF_INDEXES) + { + /* No way to continue - commit suicide. */ + abort (); + } + real_init (); + } +# endif /*!DLL_EXPORT*/ +#else + real_init (); +#endif + return 0; +} + + +/* Deinitialize libgpg-error. This function is only used in special + circumstances. No gpg-error function should be used after this + function has been called. A value of 0 passed for MODE + deinitializes the entire libgpg-error, a value of 1 releases + resources allocated for the current thread and only that thread may + not anymore access libgpg-error after such a call. Under Windows + this function may be called from the DllMain function of a DLL + which statically links to libgpg-error. */ +void +gpg_err_deinit (int mode) +{ +#if defined (HAVE_W32_SYSTEM) && !defined(DLL_EXPORT) + struct tls_space_s *tls; + + tls = TlsGetValue (tls_index); + if (tls) + { + TlsSetValue (tls_index, NULL); + LocalFree (tls); + } + + if (mode == 0) + { + TlsFree (tls_index); + tls_index = TLS_OUT_OF_INDEXES; + } +#else + (void)mode; +#endif +} + + + +#ifdef HAVE_W32_SYSTEM + +/* Return a malloced string encoded in UTF-8 from the wide char input + string STRING. Caller must free this value. Returns NULL on + failure. Caller may use GetLastError to get the actual error + number. The result of calling this function with STRING set to + NULL is not defined. */ +static char * +wchar_to_utf8 (const wchar_t *string) +{ + int n; + char *result; + + /* Note, that CP_UTF8 is not defined in Windows versions earlier + than NT. */ + n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL); + if (n < 0) + return NULL; + + result = malloc (n+1); + if (result) + { + n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL); + if (n < 0) + { + free (result); + result = NULL; + } + } + return result; +} + + +/* Return a malloced wide char string from an UTF-8 encoded input + string STRING. Caller must free this value. Returns NULL on + failure. Caller may use GetLastError to get the actual error + number. The result of calling this function with STRING set to + NULL is not defined. */ +static wchar_t * +utf8_to_wchar (const char *string) +{ + int n; + wchar_t *result; + + n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0); + if (n < 0) + return NULL; + + result = malloc ((n+1) * sizeof *result); + if (result) + { + n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n); + if (n < 0) + { + free (result); + result = NULL; + } + return NULL; + } + return result; +} + + +static char * +get_locale_dir (void) +{ + static wchar_t moddir[MAX_PATH+5]; + char *result, *p; + int nbytes; + + if (!GetModuleFileNameW (NULL, moddir, MAX_PATH)) + *moddir = 0; + +#define SLDIR "\\share\\locale" + if (*moddir) + { + nbytes = WideCharToMultiByte (CP_UTF8, 0, moddir, -1, NULL, 0, NULL, NULL); + if (nbytes < 0) + return NULL; + + result = malloc (nbytes + strlen (SLDIR) + 1); + if (result) + { + nbytes = WideCharToMultiByte (CP_UTF8, 0, moddir, -1, + result, nbytes, NULL, NULL); + if (nbytes < 0) + { + free (result); + result = NULL; + } + else + { + p = strrchr (result, '\\'); + if (p) + *p = 0; + strcat (result, SLDIR); + } + } + } + else /* Use the old default value. */ + { + result = malloc (10 + strlen (SLDIR) + 1); + if (result) + { + strcpy (result, "c:\\gnupg"); + strcat (result, SLDIR); + } + } +#undef SLDIR + return result; +} + + +static void +drop_locale_dir (char *locale_dir) +{ + free (locale_dir); +} + + +/* Return the tls object. This function is guaranteed to return a + valid non-NULL object. */ +struct tls_space_s * +get_tls (void) +{ + struct tls_space_s *tls; + + tls = TlsGetValue (tls_index); + if (!tls) + { + /* Called by a thread which existed before this DLL was loaded. + Allocate the space. */ + tls = LocalAlloc (LPTR, sizeof *tls); + if (!tls) + { + /* No way to continue - commit suicide. */ + abort (); + } + tls->gt_use_utf8 = 0; + TlsSetValue (tls_index, tls); + } + + return tls; +} + + +/* Return the value of the ERRNO variable. This needs to be a + function so that we can have a per-thread ERRNO. This is used only + on WindowsCE because that OS misses an errno. */ +#ifdef HAVE_W32CE_SYSTEM +int +_gpg_w32ce_get_errno (void) +{ + return map_w32codes ( GetLastError () ); +} +#endif /*HAVE_W32CE_SYSTEM*/ + + +/* Replacement strerror function for WindowsCE. */ +#ifdef HAVE_W32CE_SYSTEM +char * +_gpg_w32ce_strerror (int err) +{ + struct tls_space_s *tls = get_tls (); + wchar_t tmpbuf[STRBUFFER_SIZE]; + int n; + + if (err == -1) + err = _gpg_w32ce_get_errno (); + if (FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + tmpbuf, STRBUFFER_SIZE -1, + NULL)) + { + n = WideCharToMultiByte (CP_UTF8, 0, tmpbuf, -1, + tls->strerror_buffer, + sizeof tls->strerror_buffer -1, + NULL, NULL); + } + else + n = -1; + + if (n < 0) + snprintf (tls->strerror_buffer, sizeof tls->strerror_buffer -1, + "[w32err=%d]", err); + return tls->strerror_buffer; +} +#endif /*HAVE_W32CE_SYSTEM*/ + + +void +gpg_err_set_errno (int err) +{ +#ifdef HAVE_W32CE_SYSTEM + SetLastError (err); +#else /*!HAVE_W32CE_SYSTEM*/ + errno = err; +#endif /*!HAVE_W32CE_SYSTEM*/ +} + + +/* Entry point called by the DLL loader. */ +#ifdef DLL_EXPORT +int WINAPI +DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved) +{ + struct tls_space_s *tls; + (void)reserved; + + switch (reason) + { + case DLL_PROCESS_ATTACH: + tls_index = TlsAlloc (); + if (tls_index == TLS_OUT_OF_INDEXES) + return FALSE; + /* falltru. */ + case DLL_THREAD_ATTACH: + tls = LocalAlloc (LPTR, sizeof *tls); + if (!tls) + return FALSE; + tls->gt_use_utf8 = 0; + TlsSetValue (tls_index, tls); + if (reason == DLL_PROCESS_ATTACH) + { + real_init (); + } + break; + + case DLL_THREAD_DETACH: + tls = TlsGetValue (tls_index); + if (tls) + LocalFree (tls); + break; + + case DLL_PROCESS_DETACH: + tls = TlsGetValue (tls_index); + if (tls) + LocalFree (tls); + TlsFree (tls_index); + break; + + default: + break; + } + + return TRUE; +} +#endif /*DLL_EXPORT*/ + +#else /*!HAVE_W32_SYSTEM*/ + +void +gpg_err_set_errno (int err) +{ + errno = err; +} + +#endif /*!HAVE_W32_SYSTEM*/ |