Page MenuHome GnuPG

No OneTemporary

diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h
index 8a2dae7..e1cf50b 100644
--- a/src/gpgrt-int.h
+++ b/src/gpgrt-int.h
@@ -1,321 +1,365 @@
/* gpgrt-int.h - Internal definitions
* Copyright (C) 2014 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 <https://www.gnu.org/licenses/>.
*/
#ifndef _GPGRT_GPGRT_INT_H
#define _GPGRT_GPGRT_INT_H
#include "gpg-error.h"
#include "visibility.h"
/* Local error function prototypes. */
const char *_gpg_strerror (gpg_error_t err);
int _gpg_strerror_r (gpg_error_t err, char *buf, size_t buflen);
const char *_gpg_strsource (gpg_error_t err);
gpg_err_code_t _gpg_err_code_from_errno (int err);
int _gpg_err_code_to_errno (gpg_err_code_t code);
gpg_err_code_t _gpg_err_code_from_syserror (void);
void _gpg_err_set_errno (int err);
gpg_error_t _gpg_err_init (void);
void _gpg_err_deinit (int mode);
void _gpgrt_set_alloc_func (void *(*f)(void *a, size_t n));
void *_gpgrt_realloc (void *a, size_t n);
void *_gpgrt_malloc (size_t n);
void _gpgrt_free (void *a);
const char *_gpg_error_check_version (const char *req_version);
gpg_err_code_t _gpgrt_lock_init (gpgrt_lock_t *lockhd);
gpg_err_code_t _gpgrt_lock_lock (gpgrt_lock_t *lockhd);
gpg_err_code_t _gpgrt_lock_trylock (gpgrt_lock_t *lockhd);
gpg_err_code_t _gpgrt_lock_unlock (gpgrt_lock_t *lockhd);
gpg_err_code_t _gpgrt_lock_destroy (gpgrt_lock_t *lockhd);
gpg_err_code_t _gpgrt_yield (void);
+/* Trace support. */
+
+void _gpgrt_internal_trace_begin (const char *mod, const char *file, int line);
+void _gpgrt_internal_trace (const char *format,
+ ...) GPGRT_ATTR_PRINTF(1,2);
+void _gpgrt_internal_trace_errno (const char *format,
+ ...) GPGRT_ATTR_PRINTF(1,2);
+void _gpgrt_internal_trace_printf (const char *format,
+ ...) GPGRT_ATTR_PRINTF(1,2);
+void _gpgrt_internal_trace_end (void);
+
+#ifdef ENABLE_TRACING
+# define trace(X) do { \
+ _gpgrt_internal_trace_begin \
+ (ENABLE_TRACING, __func__, __LINE__); \
+ _gpgrt_internal_trace X; \
+ _gpgrt_internal_trace_end (); \
+ } while (0)
+# define trace_errno(X) do { \
+ _gpgrt_internal_trace_begin \
+ (ENABLE_TRACING, __func__, __LINE__); \
+ _gpgrt_internal_trace_errno X; \
+ _gpgrt_internal_trace_end (); \
+ } while (0)
+# define trace_start(X) do { \
+ _gpgrt_internal_trace_begin \
+ (ENABLE_TRACING, __func__, __LINE__); \
+ _gpgrt_internal_trace_printf X; \
+ } while (0)
+# define trace_append(X) do { \
+ _gpgrt_internal_trace_printf X; \
+ } while (0)
+# define trace_finish(X) do { \
+ _gpgrt_internal_trace_printf X; \
+ _gpgrt_internal_trace_end (); \
+ } while (0)
+#else
+# define trace(X) do { } while (0)
+# define trace_errno(X) do { } while (0)
+# define trace_start(X) do { } while (0)
+# define trace_append(X) do { } while (0)
+# define trace_finish(X) do { } while (0)
+#endif /*!ENABLE_TRACING*/
+
/* Local definitions for estream. */
#if HAVE_W32_SYSTEM
# ifndef O_NONBLOCK
# define O_NONBLOCK 0x40000000 /* FIXME: Is that safe? */
# endif
#endif
/*
* A private cookie function to implement an internal IOCTL service.
* and ist IOCTL numbers.
*/
typedef int (*cookie_ioctl_function_t) (void *cookie, int cmd,
void *ptr, size_t *len);
#define COOKIE_IOCTL_SNATCH_BUFFER 1
#define COOKIE_IOCTL_NONBLOCK 2
/* An internal variant of gpgrt_cookie_close_function_t with a slot
for the ioctl function. */
struct cookie_io_functions_s
{
struct _gpgrt_cookie_io_functions public;
cookie_ioctl_function_t func_ioctl;
};
typedef enum
{
BACKEND_MEM,
BACKEND_FD,
BACKEND_W32,
BACKEND_FP,
BACKEND_USER,
BACKEND_W32_POLLABLE
} gpgrt_stream_backend_kind_t;
/*
* A type to hold notification functions.
*/
struct notify_list_s
{
struct notify_list_s *next;
void (*fnc) (estream_t, void*); /* The notification function. */
void *fnc_value; /* The value to be passed to FNC. */
};
typedef struct notify_list_s *notify_list_t;
/*
* Buffer management layer.
*/
#define BUFFER_BLOCK_SIZE BUFSIZ
#define BUFFER_UNREAD_SIZE 16
/*
* The private object describing a stream.
*/
struct _gpgrt_stream_internal
{
unsigned char buffer[BUFFER_BLOCK_SIZE];
unsigned char unread_buffer[BUFFER_UNREAD_SIZE];
gpgrt_lock_t lock; /* Lock. Used by *_stream_lock(). */
gpgrt_stream_backend_kind_t kind;
void *cookie; /* Cookie. */
void *opaque; /* Opaque data. */
unsigned int modeflags; /* Flags for the backend. */
char *printable_fname; /* Malloced filename for es_fname_get. */
gpgrt_off_t offset;
gpgrt_cookie_read_function_t func_read;
gpgrt_cookie_write_function_t func_write;
gpgrt_cookie_seek_function_t func_seek;
gpgrt_cookie_close_function_t func_close;
cookie_ioctl_function_t func_ioctl;
int strategy;
es_syshd_t syshd; /* A copy of the system handle. */
struct
{
unsigned int err: 1;
unsigned int eof: 1;
unsigned int hup: 1;
} indicators;
unsigned int deallocate_buffer: 1;
unsigned int is_stdstream:1; /* This is a standard stream. */
unsigned int stdstream_fd:2; /* 0, 1 or 2 for a standard stream. */
unsigned int printable_fname_inuse: 1; /* es_fname_get has been used. */
unsigned int samethread: 1; /* The "samethread" mode keyword. */
size_t print_ntotal; /* Bytes written from in print_writer. */
notify_list_t onclose; /* On close notify function list. */
};
typedef struct _gpgrt_stream_internal *estream_internal_t;
/* Local prototypes for estream. */
int _gpgrt_estream_init (void);
void _gpgrt_set_syscall_clamp (void (*pre)(void), void (*post)(void));
void _gpgrt_get_syscall_clamp (void (**r_pre)(void), void (**r_post)(void));
gpgrt_stream_t _gpgrt_fopen (const char *_GPGRT__RESTRICT path,
const char *_GPGRT__RESTRICT mode);
gpgrt_stream_t _gpgrt_mopen (void *_GPGRT__RESTRICT data,
size_t data_n, size_t data_len,
unsigned int grow,
void *(*func_realloc) (void *mem, size_t size),
void (*func_free) (void *mem),
const char *_GPGRT__RESTRICT mode);
gpgrt_stream_t _gpgrt_fopenmem (size_t memlimit,
const char *_GPGRT__RESTRICT mode);
gpgrt_stream_t _gpgrt_fopenmem_init (size_t memlimit,
const char *_GPGRT__RESTRICT mode,
const void *data, size_t datalen);
gpgrt_stream_t _gpgrt_fdopen (int filedes, const char *mode);
gpgrt_stream_t _gpgrt_fdopen_nc (int filedes, const char *mode);
gpgrt_stream_t _gpgrt_sysopen (gpgrt_syshd_t *syshd, const char *mode);
gpgrt_stream_t _gpgrt_sysopen_nc (gpgrt_syshd_t *syshd, const char *mode);
gpgrt_stream_t _gpgrt_fpopen (FILE *fp, const char *mode);
gpgrt_stream_t _gpgrt_fpopen_nc (FILE *fp, const char *mode);
gpgrt_stream_t _gpgrt_freopen (const char *_GPGRT__RESTRICT path,
const char *_GPGRT__RESTRICT mode,
gpgrt_stream_t _GPGRT__RESTRICT stream);
gpgrt_stream_t _gpgrt_fopencookie (void *_GPGRT__RESTRICT cookie,
const char *_GPGRT__RESTRICT mode,
gpgrt_cookie_io_functions_t functions);
int _gpgrt_fclose (gpgrt_stream_t stream);
int _gpgrt_fclose_snatch (gpgrt_stream_t stream,
void **r_buffer, size_t *r_buflen);
int _gpgrt_onclose (gpgrt_stream_t stream, int mode,
void (*fnc) (gpgrt_stream_t, void*), void *fnc_value);
int _gpgrt_fileno (gpgrt_stream_t stream);
int _gpgrt_fileno_unlocked (gpgrt_stream_t stream);
int _gpgrt_syshd (gpgrt_stream_t stream, gpgrt_syshd_t *syshd);
int _gpgrt_syshd_unlocked (gpgrt_stream_t stream, gpgrt_syshd_t *syshd);
void _gpgrt__set_std_fd (int no, int fd);
gpgrt_stream_t _gpgrt__get_std_stream (int fd);
void _gpgrt_flockfile (gpgrt_stream_t stream);
int _gpgrt_ftrylockfile (gpgrt_stream_t stream);
void _gpgrt_funlockfile (gpgrt_stream_t stream);
int _gpgrt_feof (gpgrt_stream_t stream);
int _gpgrt_feof_unlocked (gpgrt_stream_t stream);
int _gpgrt_ferror (gpgrt_stream_t stream);
int _gpgrt_ferror_unlocked (gpgrt_stream_t stream);
void _gpgrt_clearerr (gpgrt_stream_t stream);
void _gpgrt_clearerr_unlocked (gpgrt_stream_t stream);
int _gpgrt__pending (gpgrt_stream_t stream);
int _gpgrt__pending_unlocked (gpgrt_stream_t stream);
int _gpgrt_fflush (gpgrt_stream_t stream);
int _gpgrt_fseek (gpgrt_stream_t stream, long int offset, int whence);
int _gpgrt_fseeko (gpgrt_stream_t stream, gpgrt_off_t offset, int whence);
long int _gpgrt_ftell (gpgrt_stream_t stream);
gpgrt_off_t _gpgrt_ftello (gpgrt_stream_t stream);
void _gpgrt_rewind (gpgrt_stream_t stream);
int _gpgrt_fgetc (gpgrt_stream_t stream);
int _gpgrt_fputc (int c, gpgrt_stream_t stream);
int _gpgrt__getc_underflow (gpgrt_stream_t stream);
int _gpgrt__putc_overflow (int c, gpgrt_stream_t stream);
/* Note: Keeps the next two macros in sync
with their counterparts in gpg-error.h. */
#define _gpgrt_getc_unlocked(stream) \
(((!(stream)->flags.writing) \
&& ((stream)->data_offset < (stream)->data_len) \
&& (! (stream)->unread_data_len)) \
? ((int) (stream)->buffer[((stream)->data_offset)++]) \
: _gpgrt__getc_underflow ((stream)))
#define _gpgrt_putc_unlocked(c, stream) \
(((stream)->flags.writing \
&& ((stream)->data_offset < (stream)->buffer_size) \
&& (c != '\n')) \
? ((int) ((stream)->buffer[((stream)->data_offset)++] = (c))) \
: _gpgrt__putc_overflow ((c), (stream)))
int _gpgrt_ungetc (int c, gpgrt_stream_t stream);
int _gpgrt_read (gpgrt_stream_t _GPGRT__RESTRICT stream,
void *_GPGRT__RESTRICT buffer, size_t bytes_to_read,
size_t *_GPGRT__RESTRICT bytes_read);
int _gpgrt_write (gpgrt_stream_t _GPGRT__RESTRICT stream,
const void *_GPGRT__RESTRICT buffer, size_t bytes_to_write,
size_t *_GPGRT__RESTRICT bytes_written);
int _gpgrt_write_sanitized (gpgrt_stream_t _GPGRT__RESTRICT stream,
const void *_GPGRT__RESTRICT buffer, size_t length,
const char *delimiters,
size_t *_GPGRT__RESTRICT bytes_written);
int _gpgrt_write_hexstring (gpgrt_stream_t _GPGRT__RESTRICT stream,
const void *_GPGRT__RESTRICT buffer, size_t length,
int reserved,
size_t *_GPGRT__RESTRICT bytes_written);
size_t _gpgrt_fread (void *_GPGRT__RESTRICT ptr, size_t size, size_t nitems,
gpgrt_stream_t _GPGRT__RESTRICT stream);
size_t _gpgrt_fwrite (const void *_GPGRT__RESTRICT ptr,
size_t size, size_t memb,
gpgrt_stream_t _GPGRT__RESTRICT stream);
char *_gpgrt_fgets (char *_GPGRT__RESTRICT s, int n,
gpgrt_stream_t _GPGRT__RESTRICT stream);
int _gpgrt_fputs (const char *_GPGRT__RESTRICT s,
gpgrt_stream_t _GPGRT__RESTRICT stream);
int _gpgrt_fputs_unlocked (const char *_GPGRT__RESTRICT s,
gpgrt_stream_t _GPGRT__RESTRICT stream);
gpgrt_ssize_t _gpgrt_getline (char *_GPGRT__RESTRICT *_GPGRT__RESTRICT lineptr,
size_t *_GPGRT__RESTRICT n,
gpgrt_stream_t stream);
gpgrt_ssize_t _gpgrt_read_line (gpgrt_stream_t stream,
char **addr_of_buffer, size_t *length_of_buffer,
size_t *max_length);
int _gpgrt_fprintf (gpgrt_stream_t _GPGRT__RESTRICT stream,
const char *_GPGRT__RESTRICT format, ...)
GPGRT_ATTR_PRINTF(2,3);
int _gpgrt_fprintf_unlocked (gpgrt_stream_t _GPGRT__RESTRICT stream,
const char *_GPGRT__RESTRICT format, ...)
GPGRT_ATTR_PRINTF(2,3);
int _gpgrt_vfprintf (gpgrt_stream_t _GPGRT__RESTRICT stream,
const char *_GPGRT__RESTRICT format, va_list ap)
GPGRT_ATTR_PRINTF(2,0);
int _gpgrt_vfprintf_unlocked (gpgrt_stream_t _GPGRT__RESTRICT stream,
const char *_GPGRT__RESTRICT format, va_list ap)
GPGRT_ATTR_PRINTF(2,0);
int _gpgrt_setvbuf (gpgrt_stream_t _GPGRT__RESTRICT stream,
char *_GPGRT__RESTRICT buf, int mode, size_t size);
void _gpgrt_set_binary (gpgrt_stream_t stream);
int _gpgrt_set_nonblock (gpgrt_stream_t stream, int onoff);
int _gpgrt_get_nonblock (gpgrt_stream_t stream);
int _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout);
gpgrt_stream_t _gpgrt_tmpfile (void);
void _gpgrt_opaque_set (gpgrt_stream_t _GPGRT__RESTRICT stream,
void *_GPGRT__RESTRICT opaque);
void *_gpgrt_opaque_get (gpgrt_stream_t stream);
void _gpgrt_fname_set (gpgrt_stream_t stream, const char *fname);
const char *_gpgrt_fname_get (gpgrt_stream_t stream);
#include "estream-printf.h"
#if _WIN32
/* Prototypes for w32-estream.c. */
struct cookie_io_functions_s _gpgrt_functions_w32_pollable;
int _gpgrt_w32_pollable_create (void *_GPGRT__RESTRICT *_GPGRT__RESTRICT cookie,
unsigned int modeflags,
struct cookie_io_functions_s next_functions,
void *next_cookie);
int _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout);
#endif
gpgrt_b64state_t _gpgrt_b64dec_start (const char *title);
gpg_error_t _gpgrt_b64dec_proc (gpgrt_b64state_t state, void *buffer,
size_t length, size_t *r_nbytes);
gpg_error_t _gpgrt_b64dec_finish (gpgrt_b64state_t state);
#endif /*_GPGRT_GPGRT_INT_H*/
diff --git a/src/init.c b/src/init.c
index f7207fe..e90bec5 100644
--- a/src/init.c
+++ b/src/init.c
@@ -1,427 +1,504 @@
/* 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 <https://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 "gpgrt-int.h"
#include "gettext.h"
#include "init.h"
#ifdef HAVE_W32CE_SYSTEM
# include "mkw32errmap.map.c" /* Generated map_w32codes () */
# ifndef TLS_OUT_OF_INDEXES
# define TLS_OUT_OF_INDEXES 0xFFFFFFFF
# endif
# ifndef __MINGW32CE__
# /* Replace the Mingw32CE provided abort function. */
# define abort() do { TerminateProcess (GetCurrentProcess(), 8); } while (0)
# endif
#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*/
/* The realloc function as set by gpgrt_set_alloc_func. */
static void *(*custom_realloc)(void *a, size_t n);
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
_gpgrt_estream_init ();
}
/* 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 ();
}
_gpg_w32__init_gettext_module ();
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
}
/* Register F as allocation function. This function is used for all
APIs which return an allocated buffer. F needs to have standard
realloc semantics. It should be called as early as possible and
not changed later. */
void
_gpgrt_set_alloc_func (void *(*f)(void *a, size_t n))
{
custom_realloc = f;
}
/* The realloc to be used for data returned by the public API. */
void *
_gpgrt_realloc (void *a, size_t n)
{
if (custom_realloc)
return custom_realloc (a, n);
if (!n)
{
free (a);
return NULL;
}
if (!a)
return malloc (n);
return realloc (a, n);
}
/* The malloc to be used for data returned by the public API. */
void *
_gpgrt_malloc (size_t n)
{
if (!n)
n++;
return _gpgrt_realloc (NULL, n);
}
/* The free to be used for data returned by the public API. */
void
_gpgrt_free (void *a)
{
_gpgrt_realloc (a, 0);
}
void
_gpg_err_set_errno (int err)
{
#ifdef HAVE_W32CE_SYSTEM
SetLastError (err);
#else /*!HAVE_W32CE_SYSTEM*/
errno = err;
#endif /*!HAVE_W32CE_SYSTEM*/
}
+
+/* Internal tracing functions. We use flockfile and funlockfile to
+ * protect their use. */
+static int trace_save_errno;
+static const char *trace_arg_module;
+static const char *trace_arg_file;
+static int trace_arg_line;
+
+void
+_gpgrt_internal_trace_begin (const char *module, const char *file, int line)
+{
+ int save_errno = errno;
+#ifdef HAVE_FLOCKFILE
+ flockfile (stderr);
+#endif
+ trace_save_errno = save_errno;
+ trace_arg_module = module;
+ trace_arg_file = file;
+ trace_arg_line = line;
+}
+
+
+static void
+do_internal_trace (const char *format, va_list arg_ptr, int with_errno)
+{
+ fprintf (stderr, "%s:%s:%d: ",
+ trace_arg_module, trace_arg_file, trace_arg_line);
+ vfprintf (stderr, format, arg_ptr);
+ if (with_errno)
+ fprintf (stderr, " errno=%s", strerror (trace_save_errno));
+ fputc ('\n', stderr);
+}
+
+void
+_gpgrt_internal_trace_printf (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format) ;
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+}
+
+
+void
+_gpgrt_internal_trace (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format) ;
+ do_internal_trace (format, arg_ptr, 0);
+ va_end (arg_ptr);
+}
+
+
+void
+_gpgrt_internal_trace_errno (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format) ;
+ do_internal_trace (format, arg_ptr, 1);
+ va_end (arg_ptr);
+}
+
+
+void
+_gpgrt_internal_trace_end (void)
+{
+ int save_errno = trace_save_errno;
+#ifdef HAVE_FLOCKFILE
+ funlockfile (stderr);
+#endif
+ errno = save_errno;
+}
+
+
#ifdef HAVE_W32_SYSTEM
/*****************************************
******** Below is only Windows code. ****
*****************************************/
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;
/* If we are installed below "bin" strip that part and
use the top directory instead.
Background: Under Windows we don't install GnuPG
below bin/ but in the top directory with only share/,
lib/, and etc/ below it. One of the reasons is to
keep the the length of the filenames at bay so not to
increase the limited length of the PATH envvar.
Another and more important reason, however, is that
the very first GPG versions on W32 were installed
into a flat directory structure and for best
compatibility with these versions we didn't changed
that later. For WindowsCE we can right away install
it under bin, though. The hack with detection of the
bin directory part allows us to eventually migrate to
such a directory layout under plain Windows without
the need to change libgpg-error. */
p = strrchr (result, '\\');
if (p && !strcmp (p+1, "bin"))
*p = 0;
/* Append the static part. */
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 ();
/* Note: On a German HTC Touch Pro2 device I also tried
LOCALE_USER_DEFAULT and LOCALE_SYSTEM_DEFAULT - both returned
English messages. */
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*/
/* 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;
(void)hinst;
switch (reason)
{
case DLL_PROCESS_ATTACH:
tls_index = TlsAlloc ();
if (tls_index == TLS_OUT_OF_INDEXES)
return FALSE;
#ifndef _GPG_ERR_HAVE_CONSTRUCTOR
/* If we have not constructors (e.g. MSC) we call it here. */
_gpg_w32__init_gettext_module ();
#endif
/* 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*/
#endif /*HAVE_W32_SYSTEM*/

File Metadata

Mime Type
text/x-diff
Expires
Thu, Feb 26, 6:32 PM (6 h, 26 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
51/b0/62fadc3e9ebb0a4d4165bea43559

Event Timeline