From a7fe86bc02f5b33cfc3c48a4d2e15d3ff94ffa16 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 26 Jun 2007 13:48:44 +0000 Subject: [PATCH] More W32 related changes --- ChangeLog | 5 + TODO | 2 +- agent/ChangeLog | 4 + agent/gpg-agent.c | 12 ++- common/ChangeLog | 17 +++ common/Makefile.am | 5 +- common/gpgrlhelp.c | 4 +- common/homedir.c | 65 +++++++++--- common/init.h | 28 +++++ common/iobuf.c | 244 +++++++++++++++++++++++++------------------ common/sysutils.h | 2 +- common/ttyio.c | 2 +- common/util.h | 6 +- g10/ChangeLog | 9 +- g10/gpg.c | 1 + g10/gpgv.c | 1 + g10/openfile.c | 56 +++++----- gl/mkdtemp.c | 7 +- kbx/ChangeLog | 4 + kbx/kbxutil.c | 4 +- sm/ChangeLog | 5 + sm/Makefile.am | 4 +- sm/gpgsm.c | 1 + tools/ChangeLog | 11 ++ tools/gpgconf-comp.c | 74 ++++++++++--- 25 files changed, 392 insertions(+), 181 deletions(-) create mode 100644 common/init.h diff --git a/ChangeLog b/ChangeLog index fa9811cf9..b375edf43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-06-25 Werner Koch + + * gl/mkdtemp.c (gen_tempname) [MKDIR_TAKES_ONE_ARG]: Avoid + compiler warning by using the proper config macro. + 2007-06-15 Werner Koch * configure.ac: Call AM_PO_SUBDIRS. diff --git a/TODO b/TODO index 649dbf2fd..1d34988d4 100644 --- a/TODO +++ b/TODO @@ -109,7 +109,7 @@ ** GCRY_MD_USER Remove these definitions. ** MY_GCRY_PK_ECDSA - Removed this. + Remove this. * Extend selinux support to other modules diff --git a/agent/ChangeLog b/agent/ChangeLog index 653bcd032..607a02282 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,7 @@ +2007-06-26 Werner Koch + + * gpg-agent.c (create_directories) [W32]: Made it work. + 2007-06-21 Werner Koch * agent.h (ctrl_t): Remove. It is now declared in ../common/util.h. diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 360870f27..b69142825 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1351,10 +1351,7 @@ static void create_directories (void) { struct stat statbuf; -#ifdef HAVE_W32_SYSTEM -#warning change it so that it works like in gpg. -#endif - const char *defhome = GNUPG_DEFAULT_HOMEDIR; + const char *defhome = standard_homedir (); char *home; home = make_filename (opt.homedir, NULL); @@ -1362,11 +1359,16 @@ create_directories (void) { if (errno == ENOENT) { - if ( (*defhome == '~' + if ( +#ifdef HAVE_W32_SYSTEM + ( !compare_filenames (home, defhome) ) +#else + (*defhome == '~' && (strlen (home) >= strlen (defhome+1) && !strcmp (home + strlen(home) - strlen (defhome+1), defhome+1))) || (*defhome != '~' && !strcmp (home, defhome) ) +#endif ) { #ifdef HAVE_W32_SYSTEM diff --git a/common/ChangeLog b/common/ChangeLog index c5fc79d92..f6ef06e80 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,5 +1,22 @@ +2007-06-26 Werner Koch + + * Makefile.am ($(PROGRAMS)): New. + + * util.h (init_common_subsystems): Moved to .. + * init.h: .. New. + * util.h: Include init.h. + + * homedir.c (standard_homedir): New. + (default_homedir) [W32]: Reimplemented in terms of + standard_homedir. Fixed memory leak. + 2007-06-25 Werner Koch + * iobuf.c: Add more documentation and slighly restructured macro + defintion for better readability. + (FILEP_OR_FD): Rename to fp_or_fd_t. + (CLOSE_CACHE): Rename to close_cache_t. + * sysutils.c (translate_sys2libc_fd): New using the code from iobuf.c. * iobuf.c: Include sysutils.h. (iobuf_translate_file_handle): Remove. diff --git a/common/Makefile.am b/common/Makefile.am index 51682306d..73951c463 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -37,7 +37,7 @@ common_sources = \ openpgpdefs.h \ keyserver.h \ sexp-parse.h \ - init.c \ + init.c init.h \ sexputil.c \ sysutils.c sysutils.h \ homedir.c \ @@ -91,3 +91,6 @@ t_common_ldadd = ../jnlib/libjnlib.a $(libcommon) ../gl/libgnu.a \ t_convert_DEPENDENCIES = convert.c libcommon.a t_convert_LDADD = $(t_common_ldadd) + +$(PROGRAMS): ../jnlib/libjnlib.a $(libcommon) ../gl/libgnu.a + diff --git a/common/gpgrlhelp.c b/common/gpgrlhelp.c index ec72c98c8..4f8e65295 100644 --- a/common/gpgrlhelp.c +++ b/common/gpgrlhelp.c @@ -21,8 +21,8 @@ /* This module may by used by applications to initializes readline support. It is required so that we can have hooks in other parts - of libcommon without actually requing to link against - libreadline. It works along ttyio.c which a proper part of + of libcommon without actually requiring to link against + libreadline. It works along with ttyio.c which is a proper part of libcommon. */ #include diff --git a/common/homedir.c b/common/homedir.c index e0c511cc9..772bd30d6 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -1,5 +1,5 @@ /* homedir.c - Setup the home directory. - * Copyright (C) 2004, 2006 Free Software Foundation, Inc. + * Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -83,18 +83,17 @@ w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e) #endif /*HAVE_W32_SYSTEM*/ -/* Set up the default home directory. The usual --homedir option - should be parsed later. */ +/* Get the standard home directory. In general this function should + not be used as it does not consider a registry value (under W32) or + the GNUPGHOME encironment variable. It is better to use + default_homedir(). */ const char * -default_homedir (void) +standard_homedir (void) { - const char *dir; - - dir = getenv("GNUPGHOME"); #ifdef HAVE_W32_SYSTEM - if (!dir || !*dir) - dir = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG", "HomeDir"); - if (!dir || !*dir) + static const char *dir; + + if (!dir) { char path[MAX_PATH]; @@ -112,11 +111,53 @@ default_homedir (void) strcpy (stpcpy (tmp, path), "\\gnupg"); dir = tmp; - /* Try to create the directory if it does not yet - exists. */ + /* Try to create the directory if it does not yet exists. */ if (access (dir, F_OK)) CreateDirectory (dir, NULL); } + else + dir = GNUPG_DEFAULT_HOMEDIR; + } + return dir; +#else/*!HAVE_W32_SYSTEM*/ + return GNUPG_DEFAULT_HOMEDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + +/* Set up the default home directory. The usual --homedir option + should be parsed later. */ +const char * +default_homedir (void) +{ + const char *dir; + + dir = getenv ("GNUPGHOME"); +#ifdef HAVE_W32_SYSTEM + if (!dir || !*dir) + { + static const char *saved_dir; + + if (!saved_dir) + { + if (!dir || !*dir) + { + char *tmp; + + tmp = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG", + "HomeDir"); + if (tmp && *tmp) + { + xfree (tmp); + tmp = NULL; + } + if (tmp) + saved_dir = tmp; + } + + if (!saved_dir) + saved_dir = standard_homedir (); + } + dir = saved_dir; } #endif /*HAVE_W32_SYSTEM*/ if (!dir || !*dir) diff --git a/common/init.h b/common/init.h new file mode 100644 index 000000000..83e6c6b2c --- /dev/null +++ b/common/init.h @@ -0,0 +1,28 @@ +/* init.h - Definitions for init fucntions. + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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. + * + * GnuPG 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifndef GNUPG_COMMON_INIT_H +#define GNUPG_COMMON_INIT_H + +void init_common_subsystems (void); + + +#endif /*GNUPG_COMMON_INIT_H*/ diff --git a/common/iobuf.c b/common/iobuf.c index f395405f6..bf5bf8b23 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -1,6 +1,6 @@ -/* iobuf.c - file handling - * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004, 2006 Free Software Foundation, Inc. +/* iobuf.c - File Handling for OpenPGP. + * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, + * 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -31,95 +31,129 @@ #include #include #include -#ifdef HAVE_DOSISH_SYSTEM -#include +#ifdef HAVE_W32_SYSTEM +# include #endif #ifdef __riscos__ -#include -#include +# include +# include #endif /* __riscos__ */ #include "util.h" #include "sysutils.h" #include "iobuf.h" +/*-- Begin configurable part. --*/ + /* The size of the internal buffers. NOTE: If you change this value you MUST also adjust the regression test "armored_key_8192" in armor.test! */ #define IOBUF_BUFFER_SIZE 8192 +/* We don't want to use the STDIO based backend. */ #undef FILE_FILTER_USES_STDIO -#ifdef HAVE_DOSISH_SYSTEM -#define USE_SETMODE 1 -#endif +/*-- End configurable part. --*/ + +/* Under W32 the default is to use the setmode call. Define a macro + which allows us to enable this call. */ +#ifdef HAVE_W32_SYSTEM +# define USE_SETMODE 1 +#endif /*HAVE_W32_SYSTEM*/ + + +/* Definition of constants and macros used by our file filter + implementation. What we define here are 3 macros to make the + appropriate calls: + + my_fileno + Is expanded to fileno(a) if using a stdion backend and to a if we + are using the low-level backend. + + my_fopen + Is defined to fopen for the stdio backend and to direct_open if + we are using the low-evel backend. + + my_fopen_ro + Is defined to fopen for the stdio backend and to fd_cache_open if + we are using the low-evel backend. + + fp_or_fd_t + Is the type we use for the backend stream or fiel descriptor. + + INVALID_FP, FILEP_OR_FD_FOR_STDIN, FILEP_OR_FD_FOR_STDOUT + Are macros defined depending on the used backend. + +*/ #ifdef FILE_FILTER_USES_STDIO -#define my_fileno(a) fileno ((a)) -#define my_fopen_ro(a,b) fopen ((a),(b)) -#define my_fopen(a,b) fopen ((a),(b)) -typedef FILE *FILEP_OR_FD; -#define INVALID_FP NULL -#define FILEP_OR_FD_FOR_STDIN (stdin) -#define FILEP_OR_FD_FOR_STDOUT (stdout) +# define my_fileno(a) fileno ((a)) +# define my_fopen_ro(a,b) fopen ((a),(b)) +# define my_fopen(a,b) fopen ((a),(b)) + typedef FILE *fp_or_fd_t; +# define INVALID_FP NULL +# define FILEP_OR_FD_FOR_STDIN (stdin) +# define FILEP_OR_FD_FOR_STDOUT (stdout) +#else /*!FILE_FILTER_USES_STDIO*/ +# define my_fopen_ro(a,b) fd_cache_open ((a),(b)) +# define my_fopen(a,b) direct_open ((a),(b)) +# ifdef HAVE_W32_SYSTEM + /* (We assume that a HANDLE first into an int.) */ +# define my_fileno(a) ((int)(a)) + typedef HANDLE fp_or_fd_t; +# define INVALID_FP ((HANDLE)-1) +# define FILEP_OR_FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE)) +# define FILEP_OR_FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE)) +# undef USE_SETMODE +# else /*!HAVE_W32_SYSTEM*/ +# define my_fileno(a) (a) + typedef int fp_or_fd_t; +# define INVALID_FP (-1) +# define FILEP_OR_FD_FOR_STDIN (0) +# define FILEP_OR_FD_FOR_STDOUT (1) +# endif /*!HAVE_W32_SYSTEM*/ +#endif /*!FILE_FILTER_USES_STDIO*/ + +/* The context used by the file filter. */ typedef struct { - FILE *fp; /* open file handle */ - int keep_open; - int no_cache; - int print_only_name; /* flags indicating that fname is not a real file */ - char fname[1]; /* name of the file */ -} -file_filter_ctx_t; -#else -#define my_fileno(a) (a) -#define my_fopen_ro(a,b) fd_cache_open ((a),(b)) -#define my_fopen(a,b) direct_open ((a),(b)) -#ifdef HAVE_DOSISH_SYSTEM -typedef HANDLE FILEP_OR_FD; -#define INVALID_FP ((HANDLE)-1) -#define FILEP_OR_FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE)) -#define FILEP_OR_FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE)) -#undef USE_SETMODE -#else -typedef int FILEP_OR_FD; -#define INVALID_FP (-1) -#define FILEP_OR_FD_FOR_STDIN (0) -#define FILEP_OR_FD_FOR_STDOUT (1) -#endif -typedef struct -{ - FILEP_OR_FD fp; /* open file handle */ - int keep_open; + fp_or_fd_t fp; /* Open file pointer or handle. */ + int keep_open; int no_cache; int eof_seen; - int print_only_name; /* flags indicating that fname is not a real file */ - char fname[1]; /* name of the file */ + int print_only_name; /* Flags indicating that fname is not a real file. */ + char fname[1]; /* Name of the file. */ } file_filter_ctx_t; + +/* If we are not using stdio as the backend we make use of a "close + cache". */ +#ifndef FILE_FILTER_USES_STDIO struct close_cache_s { struct close_cache_s *next; - FILEP_OR_FD fp; + fp_or_fd_t fp; char fname[1]; }; -typedef struct close_cache_s *CLOSE_CACHE; -static CLOSE_CACHE close_cache; -#endif +typedef struct close_cache_s *close_cache_t; +static close_cache_t close_cache; +#endif /*!FILE_FILTER_USES_STDIO*/ -#ifdef _WIN32 + + +#ifdef HAVE_W32_SYSTEM typedef struct { int sock; int keep_open; int no_cache; int eof_seen; - int print_only_name; /* flags indicating that fname is not a real file */ - char fname[1]; /* name of the file */ + int print_only_name; /* Flag indicating that fname is not a real file. */ + char fname[1]; /* Name of the file */ } sock_filter_ctx_t; -#endif /*_WIN32*/ +#endif /*HAVE_W32_SYSTEM*/ /* The first partial length header block must be of size 512 * to make it easier (and efficienter) we use a min. block size of 512 @@ -127,33 +161,41 @@ sock_filter_ctx_t; #define OP_MIN_PARTIAL_CHUNK 512 #define OP_MIN_PARTIAL_CHUNK_2POW 9 +/* The context we use for the block filter (used to handle OpenPGP + length information header). */ typedef struct { int use; size_t size; size_t count; - int partial; /* 1 = partial header, 2 in last partial packet */ - char *buffer; /* used for partial header */ - size_t buflen; /* used size of buffer */ - int first_c; /* of partial header (which is > 0) */ + int partial; /* 1 = partial header, 2 in last partial packet. */ + char *buffer; /* Used for partial header. */ + size_t buflen; /* Used size of buffer. */ + int first_c; /* First character of a partial header (which is > 0). */ int eof; } block_filter_ctx_t; + +/* Global flag to tell whether special file names are enabled. See + gpg.c for an explanation of these file names. FIXME: it does not + belong into the iobuf subsystem. */ static int special_names_enabled; +/* Local prototypes. */ static int underflow (iobuf_t a); static int translate_file_handle (int fd, int for_write); -#ifndef FILE_FILTER_USES_STDIO + +#ifndef FILE_FILTER_USES_STDIO /* * Invalidate (i.e. close) a cached iobuf */ static void fd_cache_invalidate (const char *fname) { - CLOSE_CACHE cc; + close_cache_t cc; assert (fname); if (DBG_IOBUF) @@ -165,7 +207,7 @@ fd_cache_invalidate (const char *fname) { if (DBG_IOBUF) log_debug (" did (%s)\n", cc->fname); -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM CloseHandle (cc->fp); #else close (cc->fp); @@ -176,11 +218,10 @@ fd_cache_invalidate (const char *fname) } - -static FILEP_OR_FD +static fp_or_fd_t direct_open (const char *fname, const char *mode) { -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM unsigned long da, cd, sm; HANDLE hfile; @@ -213,7 +254,7 @@ direct_open (const char *fname, const char *mode) hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL); return hfile; -#else +#else /*!HAVE_W32_SYSTEM*/ int oflag; int cflag = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; @@ -236,6 +277,7 @@ direct_open (const char *fname, const char *mode) if (strchr (mode, 'b')) oflag |= O_BINARY; #endif + /* No we need to distinguish between POSIX and RISC OS. */ #ifndef __riscos__ return open (fname, oflag, cflag); #else @@ -250,7 +292,7 @@ direct_open (const char *fname, const char *mode) return open (fname, oflag, cflag); } #endif -#endif +#endif /*!HAVE_W32_SYSTEM*/ } @@ -259,14 +301,14 @@ direct_open (const char *fname, const char *mode) * Note that this caching strategy only works if the process does not chdir. */ static void -fd_cache_close (const char *fname, FILEP_OR_FD fp) +fd_cache_close (const char *fname, fp_or_fd_t fp) { - CLOSE_CACHE cc; + close_cache_t cc; assert (fp); if (!fname || !*fname) { -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM CloseHandle (fp); #else close (fp); @@ -299,21 +341,21 @@ fd_cache_close (const char *fname, FILEP_OR_FD fp) /* * Do an direct_open on FNAME but first try to reuse one from the fd_cache */ -static FILEP_OR_FD +static fp_or_fd_t fd_cache_open (const char *fname, const char *mode) { - CLOSE_CACHE cc; + close_cache_t cc; assert (fname); for (cc = close_cache; cc; cc = cc->next) { if (cc->fp != INVALID_FP && !strcmp (cc->fname, fname)) { - FILEP_OR_FD fp = cc->fp; + fp_or_fd_t fp = cc->fp; cc->fp = INVALID_FP; if (DBG_IOBUF) log_debug ("fd_cache_open (%s) using cached fp\n", fname); -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff) { log_error ("rewind file failed on handle %p: ec=%d\n", @@ -335,7 +377,6 @@ fd_cache_open (const char *fname, const char *mode) return direct_open (fname, mode); } - #endif /*FILE_FILTER_USES_STDIO */ @@ -368,7 +409,7 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, size_t * ret_len) { file_filter_ctx_t *a = opaque; - FILEP_OR_FD f = a->fp; + fp_or_fd_t f = a->fp; size_t size = *ret_len; size_t nbytes = 0; int rc = 0; @@ -444,7 +485,7 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, } else { -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM unsigned long nread; nbytes = 0; @@ -503,7 +544,7 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, { if (size) { -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM byte *p = buf; unsigned long n; @@ -563,7 +604,7 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, } else if (control == IOBUFCTRL_FREE) { -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM if (f != FILEP_OR_FD_FOR_STDIN && f != FILEP_OR_FD_FOR_STDOUT) { if (DBG_IOBUF) @@ -587,9 +628,10 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, return rc; } -#ifdef _WIN32 -/* Becuase sockets are an special object under Lose32 we have to - * use a special filter */ + +#ifdef HAVE_W32_SYSTEM +/* Because network sockets are special objects under Lose32 we have to + use a dedicated filter for them. */ static int sock_filter (void *opaque, int control, iobuf_t chain, byte * buf, size_t * ret_len) @@ -674,7 +716,7 @@ sock_filter (void *opaque, int control, iobuf_t chain, byte * buf, } return rc; } -#endif /*_WIN32*/ +#endif /*HAVE_W32_SYSTEM*/ /**************** * This is used to implement the block write mode. @@ -1050,7 +1092,7 @@ iobuf_cancel (iobuf_t a) const char *s; iobuf_t a2; int rc; -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) +#if defined(HAVE_W32_SYSTEM) || defined(__riscos__) char *remove_name = NULL; #endif @@ -1059,7 +1101,7 @@ iobuf_cancel (iobuf_t a) s = iobuf_get_real_fname (a); if (s && *s) { -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) +#if defined(HAVE_W32_SYSTEM) || defined(__riscos__) remove_name = xstrdup (s); #else remove (s); @@ -1076,7 +1118,7 @@ iobuf_cancel (iobuf_t a) } rc = iobuf_close (a); -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) +#if defined(HAVE_W32_SYSTEM) || defined(__riscos__) if (remove_name) { /* Argg, MSDOS does not allow to remove open files. So @@ -1161,7 +1203,7 @@ iobuf_t iobuf_open (const char *fname) { iobuf_t a; - FILEP_OR_FD fp; + fp_or_fd_t fp; file_filter_ctx_t *fcx; size_t len; int print_only = 0; @@ -1206,7 +1248,7 @@ iobuf_t iobuf_fdopen (int fd, const char *mode) { iobuf_t a; - FILEP_OR_FD fp; + fp_or_fd_t fp; file_filter_ctx_t *fcx; size_t len; @@ -1214,7 +1256,7 @@ iobuf_fdopen (int fd, const char *mode) if (!(fp = fdopen (fd, mode))) return NULL; #else - fp = (FILEP_OR_FD) fd; + fp = (fp_or_fd_t) fd; #endif a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, 8192); fcx = xmalloc (sizeof *fcx + 20); @@ -1236,7 +1278,7 @@ iobuf_t iobuf_sockopen (int fd, const char *mode) { iobuf_t a; -#ifdef _WIN32 +#ifdef HAVE_W32_SYSTEM sock_filter_ctx_t *scx; size_t len; @@ -1265,7 +1307,7 @@ iobuf_t iobuf_create (const char *fname) { iobuf_t a; - FILEP_OR_FD fp; + fp_or_fd_t fp; file_filter_ctx_t *fcx; size_t len; int print_only = 0; @@ -1339,7 +1381,7 @@ iobuf_t iobuf_openrw (const char *fname) { iobuf_t a; - FILEP_OR_FD fp; + fp_or_fd_t fp; file_filter_ctx_t *fcx; size_t len; @@ -1379,7 +1421,7 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval) b->keep_open = intval; return 0; } -#ifdef _WIN32 +#ifdef HAVE_W32_SYSTEM else if (!a->chain && a->filter == sock_filter) { sock_filter_ctx_t *b = a->filter_ov; @@ -1414,7 +1456,7 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval) b->no_cache = intval; return 0; } -#ifdef _WIN32 +#ifdef HAVE_W32_SYSTEM else if (!a->chain && a->filter == sock_filter) { sock_filter_ctx_t *b = a->filter_ov; @@ -2027,9 +2069,9 @@ iobuf_get_filelength (iobuf_t a, int *overflow) if ( !a->chain && a->filter == file_filter ) { file_filter_ctx_t *b = a->filter_ov; - FILEP_OR_FD fp = b->fp; + fp_or_fd_t fp = b->fp; -#if defined(HAVE_DOSISH_SYSTEM) && !defined(FILE_FILTER_USES_STDIO) +#if defined(HAVE_W32_SYSTEM) && !defined(FILE_FILTER_USES_STDIO) ulong size; static int (* __stdcall get_file_size_ex) (void *handle, LARGE_INTEGER *r_size); @@ -2096,7 +2138,7 @@ iobuf_get_fd (iobuf_t a) if (!a->chain && a->filter == file_filter) { file_filter_ctx_t *b = a->filter_ov; - FILEP_OR_FD fp = b->fp; + fp_or_fd_t fp = b->fp; return my_fileno (fp); } @@ -2184,7 +2226,7 @@ iobuf_seek (iobuf_t a, off_t newpos) return -1; } #else -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff) { log_error ("SetFilePointer failed on handle %p: ec=%d\n", @@ -2354,10 +2396,10 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, static int translate_file_handle (int fd, int for_write) { -#ifdef _WIN32 -#ifdef FILE_FILTER_USES_STDIO +#ifdef HAVE_W32_SYSTEM +# ifdef FILE_FILTER_USES_STDIO fd = translate_sys2libc_fd (fd, for_write); -#else +# else { int x; @@ -2376,7 +2418,7 @@ translate_file_handle (int fd, int for_write) fd = x; } -#endif +# endif #endif return fd; } diff --git a/common/sysutils.h b/common/sysutils.h index 3ed702aa7..b59f345dd 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -26,7 +26,7 @@ void trap_unaligned (void); int disable_core_dumps (void); int enable_core_dumps (void); const unsigned char *get_session_marker (size_t *rlen); -int check_permissions (const char *path,int extension,int checkonly); +/*int check_permissions (const char *path,int extension,int checkonly);*/ void gnupg_sleep (unsigned int seconds); int translate_sys2libc_fd (int fd, int for_write); diff --git a/common/ttyio.c b/common/ttyio.c index 98a4614fe..5b10915d3 100644 --- a/common/ttyio.c +++ b/common/ttyio.c @@ -632,7 +632,7 @@ tty_get_answer_is_yes( const char *prompt ) } -/* Called by gnupg_rl_initialize to setup the reradline support. */ +/* Called by gnupg_rl_initialize to setup the readline support. */ void tty_private_set_rl_hooks (void (*init_stream) (FILE *), void (*set_completer) (rl_completion_func_t*), diff --git a/common/util.h b/common/util.h index 39858216f..11595127a 100644 --- a/common/util.h +++ b/common/util.h @@ -40,12 +40,15 @@ #include "../jnlib/utf8conv.h" #include "../jnlib/dynload.h" +#include "init.h" + /* Redefine asprintf by our estream version which uses our own memory allocator.. */ #include "estream-printf.h" #define asprintf estream_asprintf #define vasprintf estream_vasprintf + /* GCC attributes. */ #if __GNUC__ >= 4 # define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a))) @@ -119,8 +122,6 @@ gnupg_copy_time (gnupg_isotime_t d, const gnupg_isotime_t s) strcpy (d, s); } -/*-- init.c --*/ -void init_common_subsystems (void); /*-- signal.c --*/ void gnupg_init_signals (int mode, void (*fast_cleanup)(void)); @@ -170,6 +171,7 @@ char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf); /*-- homedir.c --*/ +const char *standard_homedir (void); const char *default_homedir (void); const char *gnupg_sysconfdir (void); const char *gnupg_bindir (void); diff --git a/g10/ChangeLog b/g10/ChangeLog index 2958c9fff..477815825 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,8 +1,13 @@ +2007-06-26 Werner Koch + + * openfile.c (try_make_homedir): Support W32; use standard_homedir. + 2007-06-25 Werner Koch - * gpg.c (main): Replace iobuf_translate_file_handle by + * gpg.c, gpgv.c: Include sysutils.h. + (main): Replace iobuf_translate_file_handle by translate_sys2libc_fd. - * gpgv.c (main): Ditto. + 2007-06-21 Werner Koch diff --git a/g10/gpg.c b/g10/gpg.c index d1d79ea19..0eb21f079 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -53,6 +53,7 @@ #include "filter.h" #include "ttyio.h" #include "i18n.h" +#include "sysutils.h" #include "status.h" #include "keyserver-internal.h" #include "exec.h" diff --git a/g10/gpgv.c b/g10/gpgv.c index f7cac3457..72ee53c4b 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -48,6 +48,7 @@ #include "filter.h" #include "ttyio.h" #include "i18n.h" +#include "sysutils.h" #include "status.h" #include "call-agent.h" diff --git a/g10/openfile.c b/g10/openfile.c index 095aad9f4..949299ae7 100644 --- a/g10/openfile.c +++ b/g10/openfile.c @@ -404,37 +404,35 @@ copy_options_file( const char *destdir ) void -try_make_homedir( const char *fname ) +try_make_homedir (const char *fname) { - const char *defhome = GNUPG_DEFAULT_HOMEDIR; + const char *defhome = standard_homedir (); + + /* Create the directory only if the supplied directory name is the + same as the default one. This way we avoid to create arbitrary + directories when a non-default home directory is used. To cope + with HOME, we do compare only the suffix if we see that the + default homedir does start with a tilde. */ + if ( opt.dry_run || opt.no_homedir_creation ) + return; + + if ( #ifdef HAVE_W32_SYSTEM -#warning use a function and not a constant + ( !compare_filenames (fname, defhome) ) +#else + ( *defhome == '~' + && (strlen(fname) >= strlen (defhome+1) + && !strcmp(fname+strlen(fname)-strlen(defhome+1), defhome+1 ) )) + || (*defhome != '~' && !compare_filenames( fname, defhome ) ) #endif - - /* Create the directory only if the supplied directory name - * is the same as the default one. This way we avoid to create - * arbitrary directories when a non-default homedirectory is used. - * To cope with HOME, we do compare only the suffix if we see that - * the default homedir does start with a tilde. - */ - if( opt.dry_run || opt.no_homedir_creation ) - return; - - if ( ( *defhome == '~' - && ( strlen(fname) >= strlen (defhome+1) - && !strcmp(fname+strlen(fname)-strlen(defhome+1), - defhome+1 ) )) - || ( *defhome != '~' - && !compare_filenames( fname, defhome ) ) - ) { - if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) ) - log_fatal( _("can't create directory `%s': %s\n"), - fname, strerror(errno) ); - else if( !opt.quiet ) - log_info( _("directory `%s' created\n"), fname ); - copy_options_file( fname ); -/* log_info(_("you have to start GnuPG again, " */ -/* "so it can read the new configuration file\n") ); */ -/* g10_exit(1); */ + ) + { + if ( mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR) ) + log_fatal ( _("can't create directory `%s': %s\n"), + fname, strerror(errno) ); + else if (!opt.quiet ) + log_info ( _("directory `%s' created\n"), fname ); + copy_options_file( fname ); + } } diff --git a/gl/mkdtemp.c b/gl/mkdtemp.c index 60bbd0aa4..c3460782a 100644 --- a/gl/mkdtemp.c +++ b/gl/mkdtemp.c @@ -74,9 +74,6 @@ #ifdef __MINGW32__ # include -/* mingw's _mkdir() function has 1 argument, but we pass 2 arguments. - Therefore we have to disable the argument count checking. */ -# define mkdir ((int (*)()) _mkdir) #endif #if !_LIBC @@ -177,7 +174,11 @@ gen_tempname (char *tmpl) v /= 62; XXXXXX[5] = letters[v % 62]; +#ifdef MKDIR_TAKES_ONE_ARG + fd = mkdir (tmpl); +#else fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); +#endif if (fd >= 0) { diff --git a/kbx/ChangeLog b/kbx/ChangeLog index e7c7b9afd..b36746d0b 100644 --- a/kbx/ChangeLog +++ b/kbx/ChangeLog @@ -1,3 +1,7 @@ +2007-06-26 Werner Koch + + * kbxutil.c: Include init.h + 2007-06-15 Werner Koch * Makefile.am (kbxutil_LDADD): Add W32SOCKLIBS. diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index 3919684e5..e231a82d4 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -34,12 +34,12 @@ #include "../jnlib/argparse.h" #include "../jnlib/stringhelp.h" #include "../jnlib/utf8conv.h" -#include "../common/i18n.h" +#include "i18n.h" +#include "init.h" #include "keybox-defs.h" #include - enum cmd_and_opt_values { aNull = 0, oArmor = 'a', diff --git a/sm/ChangeLog b/sm/ChangeLog index a57af3cfb..ab9b89977 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,8 @@ +2007-06-26 Werner Koch + + * gpgsm.c (main): Call gnupg_rl_initialize. + * Makefile.am (gpgsm_LDADD): Add LIBREADLINE and libgpgrl.a. + 2007-06-25 Werner Koch * gpgsm.c (check_special_filename): Use translate_sys2libc_fd and diff --git a/sm/Makefile.am b/sm/Makefile.am index e56064812..8171af54b 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -57,9 +57,9 @@ gpgsm_SOURCES = \ common_libs = ../jnlib/libjnlib.a ../kbx/libkeybox.a \ $(libcommon) ../gl/libgnu.a -gpgsm_LDADD = $(common_libs) \ +gpgsm_LDADD = $(common_libs) ../common/libgpgrl.a \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) \ - $(GPG_ERROR_LIBS) $(LIBINTL) $(ZLIBS) $(LIBICONV) + $(GPG_ERROR_LIBS) $(LIBREADLINE) $(LIBINTL) $(ZLIBS) $(LIBICONV) # Make sure that all libs are build before we use them. This is # important for things like make -j2. diff --git a/sm/gpgsm.c b/sm/gpgsm.c index d3be015c7..08f08049b 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -736,6 +736,7 @@ main ( int argc, char **argv) /*mtrace();*/ /* trap_unaligned ();*/ + gnupg_rl_initialize (); set_strusage (my_strusage); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); /* We don't need any locking in libgcrypt unless we use any kind of diff --git a/tools/ChangeLog b/tools/ChangeLog index f36c33a40..72298daf0 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,14 @@ +2007-06-26 Werner Koch + + * gpgconf-comp.c (key_matches_user_or_group) [W32]: Implement user + name matching. + (GPGNAME): New. Use it instead of "gpg". + (gc_component) [W32]: Disable dirmngr for now. + (gc_component_retrieve_options): Ignore components without options. + (gc_component_change_options): Ditto. + (gc_component_list_options): Ditto. + (gc_component_find, gc_component_list_components): Ditto. + 2007-06-19 Werner Koch * gpgconf-comp.c (percent_escape): Rename to my_percent_escape. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index caf09d342..4a83adb9e 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -33,9 +33,12 @@ #include #include #include -#ifndef HAVE_W32_SYSTEM -#include -#include +#ifdef HAVE_W32_SYSTEM +# define WIN32_LEAN_AND_MEAN 1 +# include +#else +# include +# include #endif /* For log_logv(), asctimestamp(), gnupg_get_time (). */ @@ -46,6 +49,16 @@ #include "gpgconf.h" +/* There is a problem with gpg 1.4 under Windows: --gpgconf-list + returns a plain filename without escaping. As long as we have not + fixed that we need to use gpg2 - it might actually be better to use + gpg2 in any case. */ +#ifdef HAVE_W32_SYSTEM +#define GPGNAME "gpg2" +#else +#define GPGNAME "gpg" +#endif + /* TODO: Components: Add more components and their options. @@ -156,7 +169,7 @@ static struct } gc_backend[GC_BACKEND_NR] = { { NULL }, /* GC_BACKEND_ANY dummy entry. */ - { "GnuPG", "gpg", NULL, "gpgconf-gpg.conf" }, + { "GnuPG", GPGNAME, NULL, "gpgconf-gpg.conf" }, { "GPGSM", "gpgsm", NULL, "gpgconf-gpgsm.conf" }, { "GPG Agent", "gpg-agent", gpg_agent_runtime_change, "gpgconf-gpg-agent.conf" }, @@ -901,7 +914,9 @@ static struct { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent }, { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon }, { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm }, +#ifndef HAVE_W32_SYSTEM { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr } +#endif }; @@ -1081,10 +1096,13 @@ gc_component_list_components (FILE *out) for (idx = 0; idx < GC_COMPONENT_NR; idx++) { - const char *desc = gc_component[idx].desc; - desc = my_dgettext (gc_component[idx].desc_domain, desc); - fprintf (out, "%s:%s\n", - gc_component[idx].name, my_percent_escape (desc)); + if (gc_component[idx].options) + { + const char *desc = gc_component[idx].desc; + desc = my_dgettext (gc_component[idx].desc_domain, desc); + fprintf (out, "%s:%s\n", + gc_component[idx].name, my_percent_escape (desc)); + } } } @@ -1098,7 +1116,8 @@ gc_component_find (const char *name) for (idx = 0; idx < GC_COMPONENT_NR; idx++) { - if (!strcmp (name, gc_component[idx].name)) + if (gc_component[idx].options + && !strcmp (name, gc_component[idx].name)) return idx; } return -1; @@ -1222,7 +1241,7 @@ gc_component_list_options (int component, FILE *out) const gc_option_t *option = gc_component[component].options; const gc_option_t *group_option = NULL; - while (option->name) + while (option && option->name) { /* Do not output unknown or internal options. */ if (!(option->flags & GC_OPT_FLAG_GROUP) @@ -1595,7 +1614,7 @@ gc_component_retrieve_options (int component) { option = gc_component[component].options; - while (option->name) + while (option && option->name) { if (!(option->flags & GC_OPT_FLAG_GROUP)) { @@ -2507,7 +2526,7 @@ gc_component_change_options (int component, FILE *in) write them out to new configuration files, verify them externally, and then commit them. */ option = gc_component[component].options; - while (option->name) + while (option && option->name) { /* Go on if we have already seen this backend, or if there is nothing to do. */ @@ -2649,11 +2668,7 @@ gc_component_change_options (int component, FILE *in) static int key_matches_user_or_group (char *user) { -#ifdef HAVE_W32_SYSTEM -# warning We need a real user and group lookup. -#else char *group; - int n; if (*user == '*' && user[1] == 0) return 1; /* A single asterisk matches all users. */ @@ -2662,6 +2677,30 @@ key_matches_user_or_group (char *user) if (group) *group++ = 0; +#ifdef HAVE_W32_SYSTEM + /* Under Windows we don't support groups. */ + if (group && *group) + gc_error (0, 0, _("Note that group specifications are ignored\n")); + if (*user) + { + static char *my_name; + + if (!my_name) + { + char tmp[1]; + DWORD size = 1; + + GetUserNameA (tmp, &size); + my_name = xmalloc (size); + if (!GetUserNameA (my_name, &size)) + gc_error (1,0, "error getting current user name: %s", + w32_strerror (-1)); + } + + if (!strcmp (user, my_name)) + return 1; /* Found. */ + } +#else /*!HAVE_W32_SYSTEM*/ /* First check whether the user matches. */ if (*user) { @@ -2683,6 +2722,7 @@ key_matches_user_or_group (char *user) { static char *my_group; static char **my_supgroups; + int n; if (!my_group) { @@ -2719,7 +2759,7 @@ key_matches_user_or_group (char *user) if (!strcmp (group, my_supgroups[n])) return 1; /* Found. */ } -#endif +#endif /*!HAVE_W32_SYSTEM*/ return 0; /* No match. */ }