diff --git a/acconfig.h b/acconfig.h index 724fd6ff..5b1dd4c6 100644 --- a/acconfig.h +++ b/acconfig.h @@ -31,17 +31,12 @@ @TOP@ - - -#undef HAVE_DRIVE_LETTERS /* defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2) * with special properties like no file modes */ #undef HAVE_DOSISH_SYSTEM -/* because the Unix gettext has to much overhead on MingW32 systems - * and these systems lack Posix functions, we use a simplified version - * of gettext */ -#undef USE_SIMPLE_GETTEXT -/* Some systems have mkdir that takes a single argument. */ +/* defined if the filesystem uses driver letters */ +#undef HAVE_DRIVE_LETTERS +/* Some systems have a mkdir that takes a single argument. */ #undef MKDIR_TAKES_ONE_ARG /* path to the gpg binary */ diff --git a/acinclude.m4 b/acinclude.m4 index 296639b5..4b870edb 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1,5 +1,6 @@ dnl Macros to configure gpgme + dnl GNUPG_FIX_HDR_VERSION(FILE, NAME) dnl (wk 2000-11-17) AC_DEFUN(GNUPG_FIX_HDR_VERSION, @@ -21,3 +22,6 @@ AC_DEFUN(GNUPG_FIX_HDR_VERSION, ]) + + + diff --git a/build-w32 b/build-w32 new file mode 100755 index 00000000..bb72045c --- /dev/null +++ b/build-w32 @@ -0,0 +1,11 @@ +#!/bin/sh + +target=i386--mingw32 +host=`./config.guess` + +CC="${target}-gcc" +CPP="${target}-gcc -E" +RANLIB="${target}-ranlib" + +export CC CPP RANLIB +./configure --host=${host} --target=${target} $* diff --git a/configure.in b/configure.in index 7363d790..c1fde710 100644 --- a/configure.in +++ b/configure.in @@ -23,6 +23,7 @@ AC_SUBST(LIBGPGME_LT_CURRENT) AC_SUBST(LIBGPGME_LT_AGE) AC_SUBST(LIBGPGME_LT_REVISION) + dnl dnl Checks for programs dnl @@ -36,6 +37,22 @@ if test "$GCC" = yes; then CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" fi +GPG= +case "${target}" in + *-*-mingw32* | i?86-emx-os2 | i?86-*-os2*emx | i?86-*-msdosdjgpp* ) + # special stuff for Windoze NT + # OS/2 with the EMX environment + # DOS with the DJGPP environment + AC_DEFINE(HAVE_DRIVE_LETTERS) + AC_DEFINE(HAVE_DOSISH_SYSTEM) + GPG='c:\\gnupg\\gpg.exe' + ;; + *) + ;; +esac + + + dnl dnl Checks for libraries @@ -64,14 +81,16 @@ dnl dnl Checks for system services dnl -AC_PATH_PROG(GPG, gpg) -if test -z "$GPG"; then - AC_MSG_ERROR([[ +if test -z "GPG"; then + AC_PATH_PROG(GPG, gpg) + if test -z "$GPG"; then + AC_MSG_ERROR([[ *** *** GnuPG not found. Please install GnuPG first. *** See http://www.gnupg.org/download.html *** -]]) + ]]) + fi fi AC_DEFINE_UNQUOTED(GPG_PATH, "$GPG") diff --git a/gpgme/data.c b/gpgme/data.c index 62bd830a..dc6117fa 100644 --- a/gpgme/data.c +++ b/gpgme/data.c @@ -27,6 +27,7 @@ #include #include + #include "util.h" #include "context.h" #include "ops.h" diff --git a/gpgme/io.h b/gpgme/io.h index 5afac591..41ea160f 100644 --- a/gpgme/io.h +++ b/gpgme/io.h @@ -43,11 +43,12 @@ struct io_select_fd_s { int _gpgme_io_read ( int fd, void *buffer, size_t count ); int _gpgme_io_write ( int fd, const void *buffer, size_t count ); int _gpgme_io_pipe ( int filedes[2] ); +int _gpgme_io_close ( int fd ); int _gpgme_io_set_nonblocking ( int fd ); -pid_t _gpgme_io_spawn ( const char *path, char **argv, - struct spawn_fd_item_s *fd_child_list, - struct spawn_fd_item_s *fd_parent_list ); -int _gpgme_io_waitpid ( pid_t pid, int hang, int *r_status, int *r_signal ); +int _gpgme_io_spawn ( const char *path, char **argv, + struct spawn_fd_item_s *fd_child_list, + struct spawn_fd_item_s *fd_parent_list ); +int _gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal ); int _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds); diff --git a/gpgme/posix-io.c b/gpgme/posix-io.c index f2de6cdd..098a83e5 100644 --- a/gpgme/posix-io.c +++ b/gpgme/posix-io.c @@ -73,6 +73,13 @@ _gpgme_io_pipe ( int filedes[2] ) return pipe ( filedes ); } +int +_gpgme_io_close ( int fd ) +{ + if ( fd == -1 ) + return -1; + return close (fd); +} int _gpgme_io_set_nonblocking ( int fd ) @@ -87,7 +94,7 @@ _gpgme_io_set_nonblocking ( int fd ) } -pid_t +int _gpgme_io_spawn ( const char *path, char **argv, struct spawn_fd_item_s *fd_child_list, struct spawn_fd_item_s *fd_parent_list ) @@ -165,12 +172,12 @@ _gpgme_io_spawn ( const char *path, char **argv, close (fd_parent_list[i].fd); } - return pid; + return (int)pid; } int -_gpgme_io_waitpid ( pid_t pid, int hang, int *r_status, int *r_signal ) +_gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal ) { int status; diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index 316f78b5..b7a3943c 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -88,7 +87,7 @@ struct gpg_object_s { char **argv; struct fd_data_map_s *fd_data_map; - pid_t pid; + int pid; /* we can't use pid_t because we don't use it in Windoze */ int running; int exit_status; @@ -99,13 +98,13 @@ static void kill_gpg ( GpgObject gpg ); static void free_argv ( char **argv ); static void free_fd_data_map ( struct fd_data_map_s *fd_data_map ); -static int gpg_inbound_handler ( void *opaque, pid_t pid, int fd ); -static int gpg_outbound_handler ( void *opaque, pid_t pid, int fd ); +static int gpg_inbound_handler ( void *opaque, int pid, int fd ); +static int gpg_outbound_handler ( void *opaque, int pid, int fd ); -static int gpg_status_handler ( void *opaque, pid_t pid, int fd ); +static int gpg_status_handler ( void *opaque, int pid, int fd ); static GpgmeError read_status ( GpgObject gpg ); -static int gpg_colon_line_handler ( void *opaque, pid_t pid, int fd ); +static int gpg_colon_line_handler ( void *opaque, int pid, int fd ); static GpgmeError read_colon_line ( GpgObject gpg ); @@ -172,13 +171,13 @@ _gpgme_gpg_release ( GpgObject gpg ) if ( gpg->argv ) free_argv (gpg->argv); if (gpg->status.fd[0] != -1 ) - close (gpg->status.fd[0]); + _gpgme_io_close (gpg->status.fd[0]); if (gpg->status.fd[1] != -1 ) - close (gpg->status.fd[1]); + _gpgme_io_close (gpg->status.fd[1]); if (gpg->colon.fd[0] != -1 ) - close (gpg->colon.fd[0]); + _gpgme_io_close (gpg->colon.fd[0]); if (gpg->colon.fd[1] != -1 ) - close (gpg->colon.fd[1]); + _gpgme_io_close (gpg->colon.fd[1]); free_fd_data_map (gpg->fd_data_map); kill_gpg (gpg); /* fixme: should be done asyncronously */ xfree (gpg); @@ -297,9 +296,9 @@ free_fd_data_map ( struct fd_data_map_s *fd_data_map ) for (i=0; fd_data_map[i].data; i++ ) { if ( fd_data_map[i].fd != -1 ) - close (fd_data_map[i].fd); + _gpgme_io_close (fd_data_map[i].fd); if ( fd_data_map[i].peer_fd != -1 ) - close (fd_data_map[i].peer_fd); + _gpgme_io_close (fd_data_map[i].peer_fd); /* don't realease data because this is only a reference */ } xfree (fd_data_map); @@ -466,7 +465,7 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque ) { int rc; int i, n; - pid_t pid; + int pid; struct spawn_fd_item_s *fd_child_list, *fd_parent_list; if ( !gpg ) @@ -595,7 +594,7 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque ) static int -gpg_inbound_handler ( void *opaque, pid_t pid, int fd ) +gpg_inbound_handler ( void *opaque, int pid, int fd ) { GpgmeData dh = opaque; GpgmeError err; @@ -640,7 +639,7 @@ write_mem_data ( GpgmeData dh, int fd ) nbytes = dh->len - dh->readpos; if ( !nbytes ) { fprintf (stderr, "write_mem_data(%d): closing\n", fd ); - close (fd); + _gpgme_io_close (fd); return 1; } @@ -661,7 +660,7 @@ write_mem_data ( GpgmeData dh, int fd ) if ( nwritten < 1 ) { fprintf (stderr, "write_mem_data(%d): write failed (n=%d): %s\n", fd, nwritten, strerror (errno) ); - close (fd); + _gpgme_io_close (fd); return 1; } @@ -671,7 +670,7 @@ write_mem_data ( GpgmeData dh, int fd ) static int -gpg_outbound_handler ( void *opaque, pid_t pid, int fd ) +gpg_outbound_handler ( void *opaque, int pid, int fd ) { GpgmeData dh = opaque; @@ -692,7 +691,7 @@ gpg_outbound_handler ( void *opaque, pid_t pid, int fd ) static int -gpg_status_handler ( void *opaque, pid_t pid, int fd ) +gpg_status_handler ( void *opaque, int pid, int fd ) { GpgObject gpg = opaque; int rc = 0; @@ -817,7 +816,7 @@ read_status ( GpgObject gpg ) * For now we use this thing here becuase it is easier to implement. */ static int -gpg_colon_line_handler ( void *opaque, pid_t pid, int fd ) +gpg_colon_line_handler ( void *opaque, int pid, int fd ) { GpgObject gpg = opaque; GpgmeError rc = 0; diff --git a/gpgme/w32-io.c b/gpgme/w32-io.c index 36bbe2a6..39e50826 100644 --- a/gpgme/w32-io.c +++ b/gpgme/w32-io.c @@ -33,8 +33,19 @@ #include #include +#include "util.h" #include "io.h" +#define DEBUG_SELECT_ENABLED 1 + +#if DEBUG_SELECT_ENABLED +# define DEBUG_SELECT(a) fprintf a +#else +# define DEBUG_SELECT(a) do { } while(0) +#endif + + + /* * We assume that a HANDLE can be represented by an int which should be true * for all i386 systems (HANDLE is defined as void *) and these are the only @@ -45,7 +56,7 @@ #define fd_to_handle(a) ((HANDLE)(a)) #define handle_to_fd(a) ((int)(a)) #define pid_to_handle(a) ((HANDLE)(a)) -#define handle_to_pid(a) ((pid_t)(a)) +#define handle_to_pid(a) ((int)(a)) int @@ -86,9 +97,18 @@ _gpgme_io_pipe ( int filedes[2] ) return -1; filedes[0] = handle_to_fd (r); filedes[1] = handle_to_fd (w); - return 0 + return 0; } +int +_gpgme_io_close ( int fd ) +{ + if ( fd == -1 ) + return -1; + return CloseHandle (fd_to_handle(fd)) ? 0 : -1; +} + + int _gpgme_io_set_nonblocking ( int fd ) { @@ -97,7 +117,7 @@ _gpgme_io_set_nonblocking ( int fd ) static char * -build_commandline ( char **argv ); +build_commandline ( char **argv ) { int i, n = 0; char *buf, *p; @@ -118,7 +138,7 @@ build_commandline ( char **argv ); } -pid_t +int _gpgme_io_spawn ( const char *path, char **argv, struct spawn_fd_item_s *fd_child_list, struct spawn_fd_item_s *fd_parent_list ) @@ -138,7 +158,8 @@ _gpgme_io_spawn ( const char *path, char **argv, char *envblock = NULL; int cr_flags = CREATE_DEFAULT_ERROR_MODE | GetPriorityClass (GetCurrentProcess ()); - int rc; + int i, rc; + char *arg_string; HANDLE save_stdout; HANDLE outputfd[2], statusfd[2], inputfd[2]; @@ -204,9 +225,43 @@ _gpgme_io_spawn ( const char *path, char **argv, int -_gpgme_io_waitpid ( pid_t pid, int hang, int *r_status, int *r_signal ) +_gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal ) { - return 0; + HANDLE proc = fd_to_handle (pid); + int code, exc, ret = 0; + + *r_status = 0; + *r_signal = 0; + code = WaitForSingleObject ( proc, hang? INFINITE : NULL ); + switch (code) { + case WAIT_FAILED: + fprintf (stderr, "** WFSO pid=%d failed: %d\n", + (int)pid, (int)GetLastError () ); + break; + + case WAIT_OBJECT_0: + if (!GetExitCodeProcess (proc, &exc)) { + fprintf (stderr, "** GECP pid=%d failed: ec=%d\n", + (int)pid, (int)GetLastError () ); + *r_status = 4; + } + else { + fprintf (stderr, "** GECP pid=%d exit code=%d\n", + (int)pid, exc); + *r_status = exc; + } + ret = 1; + break; + + case WAIT_TIMEOUT: + fprintf (stderr, "** WFSO pid=%d timed out\n", (int)pid); + break; + + default: + fprintf (stderr, "** WFSO pid=%d returned %d\n", (int)pid, code ); + break; + } + return ret; } @@ -219,14 +274,76 @@ _gpgme_io_waitpid ( pid_t pid, int hang, int *r_status, int *r_signal ) int _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds ) { - return -1; + HANDLE waitbuf[MAXIMUM_WAIT_OBJECTS]; + int code, nwait; + int i, any, ret; + + DEBUG_SELECT ((stderr, "gpgme:select on [ ")); + any = 0; + nwait = 0; + for ( i=0; i < nfds; i++ ) { + if ( fds[i].fd == -1 ) + continue; + if ( fds[i].for_read || fds[i].for_write ) { + if ( nwait >= DIM (waitbuf) ) { + DEBUG_SELECT ((stderr, "oops ]\n" )); + fprintf (stderr, "** Too many objects for WFMO!\n" ); + return -1; + } + else { + waitbuf[nwait++] = fd_to_handle (fds[i].fd); + DEBUG_SELECT ((stderr, "%c%d ", + fds[i].for_read? 'r':'w',fds[i].fd )); + any = 1; + } + } + fds[i].signaled = 0; + } + DEBUG_SELECT ((stderr, "]\n" )); + if (!any) + return 0; + + ret = 0; + code = WaitForMultipleObjects ( nwait, waitbuf, 0, 1000 ); + if (code == WAIT_FAILED ) { + fprintf (stderr, "** WFMO failed: %d\n", (int)GetLastError () ); + ret = -1; + } + else if ( code == WAIT_TIMEOUT ) { + fprintf (stderr, "** WFMO timed out\n" ); + } + else if ( code >= WAIT_OBJECT_0 && code < WAIT_OBJECT_0 + nwait ) { + /* This WFMO is a really silly function: It does return either + * the index of the signaled object or if 2 objects have been + * signalled at the same time, the index of the object with the + * lowest object is returned - so and how do we find out + * how many objects have been signaled???. + * The only solution I can imagine is to test each object starting + * with the returned index individually - how dull. + */ + any = 0; + for (i=code - WAIT_OBJECT_0; i < nwait; i++ ) { + if (WaitForSingleObject ( waitbuf[i], NULL ) == WAIT_OBJECT_0) { + fds[i].signaled = 1; + any = 1; + } + } + if (any) + ret = 1; + else { + fprintf (stderr, + "** Oops: No signaled objects found after WFMO\n"); + ret = -1; + } + } + else { + fprintf (stderr, "** WFMO returned %d\n", code ); + ret = -1; + } + + return ret; } - - - - - #endif /*HAVE_DOSISH_SYSTEM*/ diff --git a/gpgme/wait.c b/gpgme/wait.c index d08c021a..080858e0 100644 --- a/gpgme/wait.c +++ b/gpgme/wait.c @@ -27,7 +27,6 @@ #include #include #include -#include #include "util.h" #include "context.h" @@ -51,9 +50,9 @@ struct wait_item_s { volatile int active; - int (*handler)(void*,pid_t,int); + int (*handler)(void*,int,int); void *handler_value; - pid_t pid; + int pid; int inbound; /* this is an inbound data handler fd */ int exited; int exit_status; @@ -99,7 +98,7 @@ propagate_term_results ( const struct wait_item_s *first_q ) } static int -count_active_fds ( pid_t pid ) +count_active_fds ( int pid ) { struct wait_item_s *q; int i, count = 0; @@ -115,7 +114,7 @@ count_active_fds ( pid_t pid ) /* remove the given process from the queue */ static void -remove_process ( pid_t pid ) +remove_process ( int pid ) { struct wait_item_s *q; int i; @@ -124,7 +123,7 @@ remove_process ( pid_t pid ) if (fd_table[i].fd != -1 && (q=fd_table[i].opaque) && q->pid == pid ) { xfree (q); fd_table[i].opaque = NULL; - close (fd_table[i].fd); + _gpgme_io_close (fd_table[i].fd); fd_table[i].fd = -1; } } @@ -237,9 +236,9 @@ do_select ( void ) */ GpgmeError _gpgme_register_pipe_handler( void *opaque, - int (*handler)(void*,pid_t,int), + int (*handler)(void*,int,int), void *handler_value, - pid_t pid, int fd, int inbound ) + int pid, int fd, int inbound ) { GpgmeCtx ctx = opaque; struct wait_item_s *q; diff --git a/gpgme/wait.h b/gpgme/wait.h index f6374149..775be1d4 100644 --- a/gpgme/wait.h +++ b/gpgme/wait.h @@ -28,9 +28,9 @@ GpgmeError _gpgme_register_pipe_handler( void *opaque, - int (*handler)(void*,pid_t,int), + int (*handler)(void*,int,int), void *handler_value, - pid_t pid, int fd, int inbound ); + int pid, int fd, int inbound );