diff options
| author | Werner Koch <[email protected]> | 2005-08-26 12:38:57 +0000 | 
|---|---|---|
| committer | Werner Koch <[email protected]> | 2005-08-26 12:38:57 +0000 | 
| commit | 82a0c97250995ef82144422a48cc066018790020 (patch) | |
| tree | 5913647abab3f668ff2fddcd77d5d1e09381eb20 | |
| parent | Added missing files and fixed stuff from the recent merged. I did only (diff) | |
| download | gpgme-82a0c97250995ef82144422a48cc066018790020.tar.gz gpgme-82a0c97250995ef82144422a48cc066018790020.zip | |
* configure.ac (SEPCONSTANTS): New to define DIRSEP_C et al.
* w32-util.c (read_w32_registry_string): Updated from code used by
GnuPG.  This allows for expanding strings and features the
implicit fallback key.
(w32_shgetfolderpath, find_program_at_standard_place): New.
(_gpgme_get_gpg_path, _gpgme_get_gpgsm_path): With no registry
entry, locate the programs at the standard place.
(dlopen, dlsym, dlclose): New, so that we can keep on using what
we are accustomed to.
* debug.c (debug_init): Use PATHSEP_C so that under W32 a
semicolon is used which allows us to create files with drive
letters.
* w32-io.c (_gpgme_io_read, _gpgme_io_write): Print content in
debug mode too.
Diffstat (limited to '')
| -rw-r--r-- | ChangeLog | 4 | ||||
| -rw-r--r-- | NEWS | 4 | ||||
| -rw-r--r-- | configure.ac | 23 | ||||
| -rw-r--r-- | gpgme/ChangeLog | 18 | ||||
| -rw-r--r-- | gpgme/debug.c | 4 | ||||
| -rw-r--r-- | gpgme/w32-io.c | 6 | ||||
| -rw-r--r-- | gpgme/w32-util.c | 213 | 
7 files changed, 237 insertions, 35 deletions
| @@ -1,3 +1,7 @@ +2005-08-26  Werner Koch  <[email protected]> + +	* configure.ac (SEPCONSTANTS): New to define DIRSEP_C et al. +  2005-08-19  Werner Koch  <[email protected]>  	* configure.ac [W32]: Create values for versioninfo.rc and list @@ -3,6 +3,10 @@ Noteworthy changes in version 1.1.0 (unreleased)   * "./autogen.sh --build-w32" does now build gpgme.dll. + * [W32] The environment variable GPGME_DEBUG now uses a semicolon as +   delimiter.  The standard install directory is used when locating +   gpg or gpgsm before finally falling back to the hardwired name. +   * You can now configure the backend engine file name and home     directory to be used, as default and per context. diff --git a/configure.ac b/configure.ac index 801a4c43..de35e787 100644 --- a/configure.ac +++ b/configure.ac @@ -458,6 +458,29 @@ fi  AC_SUBST(BUILD_TIMESTAMP)  AC_SUBST(BUILD_FILEVERSION) +# Add a few constants to help porting to W32 +AH_VERBATIM([SEPCONSTANTS], +[ +/* Separators as used in file names and $PATH. Please note that the +   string version must not contain more than one character because +   the using code assumes strlen()==1 */ +#ifdef HAVE_DOSISH_SYSTEM +#define DIRSEP_C '\\\\' +#define EXTSEP_C '.' +#define DIRSEP_S "\\\\" +#define EXTSEP_S "." +#define PATHSEP_C ';' +#define PATHSEP_S ";" +#else +#define DIRSEP_C '/' +#define EXTSEP_C '.' +#define DIRSEP_S "/" +#define EXTSEP_S "." +#define PATHSEP_C ':' +#define PATHSEP_S ":" +#endif +]) +  # Substitution used for gpgme-config   GPGME_CONFIG_LIBS="-lgpgme" diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 0a50a9fd..72a7eab7 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,21 @@ +2005-08-26  Werner Koch  <[email protected]> + +	* w32-util.c (read_w32_registry_string): Updated from code used by +	GnuPG.  This allows for expanding strings and features the +	implicit fallback key. +	(w32_shgetfolderpath, find_program_at_standard_place): New. +	(_gpgme_get_gpg_path, _gpgme_get_gpgsm_path): With no registry +	entry, locate the programs at the standard place. +	(dlopen, dlsym, dlclose): New, so that we can keep on using what +	we are accustomed to. + +	* debug.c (debug_init): Use PATHSEP_C so that under W32 a +	semicolon is used which allows us to create files with drive +	letters. + +	* w32-io.c (_gpgme_io_read, _gpgme_io_write): Print content in +	debug mode too. +  2005-08-19  Werner Koch  <[email protected]>  	* gpgme.def: New. diff --git a/gpgme/debug.c b/gpgme/debug.c index 34a794d6..c51f05ac 100644 --- a/gpgme/debug.c +++ b/gpgme/debug.c @@ -101,7 +101,7 @@ debug_init (void)        if (e)  	{  	  debug_level = atoi (e); -	  s1 = strchr (e, ':'); +	  s1 = strchr (e, PATHSEP_C);  	  if (s1)  	    {  #ifndef HAVE_DOSISH_SYSTEM @@ -112,7 +112,7 @@ debug_init (void)  		  FILE *fp;  		  s1++; -		  if (!(s2 = strchr (s1, ':'))) +		  if (!(s2 = strchr (s1, PATHSEP_C)))  		    s2 = s1 + strlen (s1);  		  p = malloc (s2 - s1 + 1);  		  if (p) diff --git a/gpgme/w32-io.c b/gpgme/w32-io.c index 431acbe9..94f0a06a 100644 --- a/gpgme/w32-io.c +++ b/gpgme/w32-io.c @@ -395,12 +395,11 @@ _gpgme_io_read ( int fd, void *buffer, size_t count )      UNLOCK (c->mutex);      DEBUG2 ("fd %d: got %d bytes\n", fd, nread ); +    if (nread > 0) +      _gpgme_debug (2, "fd %d: got `%.*s'\n", fd, nread, buffer);      return nread;  } - - -  /*   * The writer does use a simple buffering strategy so that we are   * informed about write errors as soon as possible (i.e. with the the @@ -600,6 +599,7 @@ _gpgme_io_write ( int fd, const void *buffer, size_t count )      struct writer_context_s *c = find_writer (fd,1);      DEBUG2 ("fd %d: about to write %d bytes\n", fd, (int)count ); +    _gpgme_debug (2, "fd %d: write `%.*s'\n", fd, (int) count, buffer);      if ( !c ) {          DEBUG0 ( "no writer thread\n");          return -1; diff --git a/gpgme/w32-util.c b/gpgme/w32-util.c index e4fac8e2..fa1a6d7a 100644 --- a/gpgme/w32-util.c +++ b/gpgme/w32-util.c @@ -33,6 +33,7 @@  #include <signal.h>  #include <fcntl.h>  #include <windows.h> +#include <shlobj.h>  #include <io.h>  #include "util.h" @@ -41,62 +42,187 @@  DEFINE_STATIC_LOCK (get_path_lock); -/* Return a string from the Win32 Registry or NULL in case of error. -  Caller must release the return value.  A NULL for root is an alias -  for HKEY_CURRENT_USER.  */ + +#define RTLD_LAZY 0 + +static __inline__ void * +dlopen (const char * name, int flag) +{ +  void * hd = LoadLibrary (name); +  return hd; +} + +static __inline__ void * +dlsym (void * hd, const char * sym) +{ +  if (hd && sym) +    { +      void * fnc = GetProcAddress (hd, sym); +      if (!fnc) +        return NULL; +      return fnc; +    } +  return NULL; +} + +static __inline__ int +dlclose (void * hd) +{ +  if (hd) +    { +      FreeLibrary (hd); +      return 0; +    } +  return -1; +}   + + +/* Return a string from the W32 Registry or NULL in case of error. +   Caller must release the return value.  A NULL for root is an alias +   for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn. */  static char *  read_w32_registry_string (const char *root, const char *dir, const char *name)  {    HKEY root_key, key_handle; -  DWORD n1, nbytes; +  DWORD n1, nbytes, type;    char *result = NULL; - -#ifdef HAVE_W32_SYSTEM -#warning Check that this code matches the one used by gnupg -#endif - -  if (!root) +	 +  if ( !root )      root_key = HKEY_CURRENT_USER; -  else if (!strcmp (root, "HKEY_CLASSES_ROOT")) +  else if ( !strcmp( root, "HKEY_CLASSES_ROOT" ) )      root_key = HKEY_CLASSES_ROOT; -  else if (!strcmp (root, "HKEY_CURRENT_USER")) +  else if ( !strcmp( root, "HKEY_CURRENT_USER" ) )      root_key = HKEY_CURRENT_USER; -  else if (!strcmp (root, "HKEY_LOCAL_MACHINE")) +  else if ( !strcmp( root, "HKEY_LOCAL_MACHINE" ) )      root_key = HKEY_LOCAL_MACHINE; -  else if (!strcmp (root, "HKEY_USERS")) +  else if ( !strcmp( root, "HKEY_USERS" ) )      root_key = HKEY_USERS; -  else if (!strcmp (root, "HKEY_PERFORMANCE_DATA")) +  else if ( !strcmp( root, "HKEY_PERFORMANCE_DATA" ) )      root_key = HKEY_PERFORMANCE_DATA; -  else if (!strcmp (root, "HKEY_CURRENT_CONFIG")) +  else if ( !strcmp( root, "HKEY_CURRENT_CONFIG" ) )      root_key = HKEY_CURRENT_CONFIG;    else      return NULL; - -  if (RegOpenKeyEx (root_key, dir, 0, KEY_READ, &key_handle)) -    return NULL;	/* No need for a RegClose, so return directly.  */ +	 +  if ( RegOpenKeyEx ( root_key, dir, 0, KEY_READ, &key_handle ) ) +    { +      if (root) +        return NULL; /* no need for a RegClose, so return direct */ +      /* It seems to be common practise to fall back to HKLM. */ +      if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) ) +        return NULL; /* still no need for a RegClose, so return direct */ +    }    nbytes = 1; -  if (RegQueryValueEx (key_handle, name, 0, NULL, NULL, &nbytes)) -    goto leave; -  n1 = nbytes + 1; -  result = malloc (n1); -  if (!result) +  if ( RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes ) ) +    { +      if (root) +        goto leave; +      /* Try to fallback to HKLM also vor a missing value.  */ +      RegCloseKey (key_handle); +      if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) ) +        return NULL; /* Nope.  */ +      if (RegQueryValueEx ( key_handle, name, 0, NULL, NULL, &nbytes)) +        goto leave; +    } +  result = malloc ( (n1=nbytes+1) ); +  if ( !result )      goto leave; -  if (RegQueryValueEx (key_handle, name, 0, NULL, result, &n1)) +  if ( RegQueryValueEx ( key_handle, name, 0, &type, result, &n1 ) )      { -      free (result); -      result = NULL; +      free(result); result = NULL;        goto leave;      } -  result[nbytes] = 0;	/* Make sure it is really a string.  */ +  result[nbytes] = 0; /* Make sure it is really a string.  */ +  if (type == REG_EXPAND_SZ && strchr (result, '%'))  +    { +      char *tmp; +         +      n1 += 1000; +      tmp = malloc (n1+1); +      if (!tmp) +        goto leave; +      nbytes = ExpandEnvironmentStrings (result, tmp, n1); +      if (nbytes && nbytes > n1) +        { +          free (tmp); +          n1 = nbytes; +          tmp = malloc (n1 + 1); +          if (!tmp) +            goto leave; +          nbytes = ExpandEnvironmentStrings (result, tmp, n1); +          if (nbytes && nbytes > n1) { +            free (tmp); /* Oops - truncated, better don't expand at all. */ +            goto leave; +          } +          tmp[nbytes] = 0; +          free (result); +          result = tmp; +        } +      else if (nbytes)  /* Okay, reduce the length. */ +        { +          tmp[nbytes] = 0; +          free (result); +          result = malloc (strlen (tmp)+1); +          if (!result) +            result = tmp; +          else  +            { +              strcpy (result, tmp); +              free (tmp); +            } +        } +      else  /* Error - don't expand. */ +        { +          free (tmp); +        } +    }   leave: -  RegCloseKey (key_handle); +  RegCloseKey( key_handle );    return result;  } -static const char * +/* This is a helper function to load and run a Windows function from +   either of one DLLs. */ +static HRESULT +w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e) +{ +  static int initialized; +  static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR); + +  if (!initialized) +    { +      static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL }; +      void *handle; +      int i; + +      initialized = 1; + +      for (i=0, handle = NULL; !handle && dllnames[i]; i++) +        { +          handle = dlopen (dllnames[i], RTLD_LAZY); +          if (handle) +            { +              func = dlsym (handle, "SHGetFolderPathA"); +              if (!func) +                { +                  dlclose (handle); +                  handle = NULL; +                } +            } +        } +    } + +  if (func) +    return func (a,b,c,d,e); +  else +    return -1; +} + + +static char *  find_program_in_registry (const char *name)  {    char *program = NULL; @@ -117,6 +243,29 @@ find_program_in_registry (const char *name)  } +static char * +find_program_at_standard_place (const char *name) +{ +  char path[MAX_PATH]; +  char *result = NULL; +       +  if (w32_shgetfolderpath (NULL, CSIDL_PROGRAM_FILES, NULL, 0, path) >= 0)  +    { +      result = malloc (strlen (path) + 1 + strlen (name) + 1); +      if (result) +        { +          strcpy (stpcpy (stpcpy (result, path), "\\"), name); +          if (access (result, F_OK)) +            { +              free (result); +              result = NULL; +            } +        } +    } +  return result; +} + +  const char *  _gpgme_get_gpg_path (void)  { @@ -125,6 +274,8 @@ _gpgme_get_gpg_path (void)    LOCK (get_path_lock);    if (!gpg_program)      gpg_program = find_program_in_registry ("gpgProgram"); +  if (!gpg_program) +    gpg_program = find_program_at_standard_place ("GNU\\GnuPG\\gpg.exe");  #ifdef GPG_PATH    if (!gpg_program)      gpg_program = GPG_PATH; @@ -141,6 +292,8 @@ _gpgme_get_gpgsm_path (void)    LOCK (get_path_lock);    if (!gpgsm_program)      gpgsm_program = find_program_in_registry ("gpgsmProgram"); +  if (!gpgsm_program) +    gpgsm_program = find_program_at_standard_place ("GNU\\GnuPG\\gpgsm.exe");  #ifdef GPGSM_PATH    if (!gpgsm_program)      gpgsm_program = GPGSM_PATH; | 
