Okay, it runs at least on Windows 95
This commit is contained in:
parent
b7a7d9b9cc
commit
874f12ea70
16
Makefile.am
16
Makefile.am
@ -1,6 +1,18 @@
|
||||
|
||||
EXTRA_DIST = README-alpha
|
||||
EXTRA_DIST = README-alpha build-w32
|
||||
|
||||
SUBDIRS = gpgme tests
|
||||
if BUILD_BONOBO
|
||||
bonobo = bonobo
|
||||
else
|
||||
bonobo =
|
||||
endif
|
||||
if BUILD_COMPLUS
|
||||
complus = complus
|
||||
else
|
||||
complus =
|
||||
endif
|
||||
|
||||
|
||||
SUBDIRS = jnlib gpgme tests ${bonobo} ${complus}
|
||||
|
||||
|
||||
|
@ -42,6 +42,15 @@
|
||||
/* path to the gpg binary */
|
||||
#undef GPG_PATH
|
||||
|
||||
/* stuff needed by lnlib/ */
|
||||
#undef HAVE_BYTE_TYPEDEF
|
||||
#undef HAVE_USHORT_TYPEDEF
|
||||
#undef HAVE_ULONG_TYPEDEF
|
||||
#undef HAVE_U16_TYPEDEF
|
||||
#undef HAVE_U32_TYPEDEF
|
||||
|
||||
|
||||
|
||||
@BOTTOM@
|
||||
|
||||
/* not yet needed #include "gpgme-defs.h"*/
|
||||
|
17
acinclude.m4
17
acinclude.m4
@ -21,6 +21,23 @@ AC_DEFUN(GNUPG_FIX_HDR_VERSION,
|
||||
fi
|
||||
])
|
||||
|
||||
dnl GNUPG_CHECK_TYPEDEF(TYPE, HAVE_NAME)
|
||||
dnl Check whether a typedef exists and create a #define $2 if it exists
|
||||
dnl
|
||||
AC_DEFUN(GNUPG_CHECK_TYPEDEF,
|
||||
[ AC_MSG_CHECKING(for $1 typedef)
|
||||
AC_CACHE_VAL(gnupg_cv_typedef_$1,
|
||||
[AC_TRY_COMPILE([#include <stdlib.h>
|
||||
#include <sys/types.h>], [
|
||||
#undef $1
|
||||
int a = sizeof($1);
|
||||
], gnupg_cv_typedef_$1=yes, gnupg_cv_typedef_$1=no )])
|
||||
AC_MSG_RESULT($gnupg_cv_typedef_$1)
|
||||
if test "$gnupg_cv_typedef_$1" = yes; then
|
||||
AC_DEFINE($2)
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
|
||||
|
||||
|
11
bonobo/Makefile.am
Normal file
11
bonobo/Makefile.am
Normal file
@ -0,0 +1,11 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
bin_PROGRAMS = gpgme
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/jnlib
|
||||
LDADD = -L ../jnlib -ljnlib
|
||||
|
||||
gpgme_SOURCES = main.c main.h
|
||||
|
||||
|
||||
|
20
bonobo/gpgme.c
Normal file
20
bonobo/gpgme.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* gpgme - Bonbobo component to access GnuPG
|
||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
||||
*
|
||||
* This file is part of GPGME.
|
||||
*
|
||||
* GPGME 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.
|
||||
*
|
||||
* GPGME 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
20
bonobo/main.c
Normal file
20
bonobo/main.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* main.c - Bonbobo component to access GnuPG
|
||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
||||
*
|
||||
* This file is part of GPGME.
|
||||
*
|
||||
* GPGME 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.
|
||||
*
|
||||
* GPGME 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
42
bonobo/main.h
Normal file
42
bonobo/main.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* main.h - GPGME Bonobo component
|
||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
||||
*
|
||||
* This file is part of GPGME.
|
||||
*
|
||||
* GPGME 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.
|
||||
*
|
||||
* GPGME 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
|
||||
struct {
|
||||
int verbose;
|
||||
int quiet;
|
||||
unsigned int debug;
|
||||
char *homedir;
|
||||
} opt;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* MAIN_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
12
complus/Makefile.am
Normal file
12
complus/Makefile.am
Normal file
@ -0,0 +1,12 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
# No need to install this becuase we are cross-compiling anyway.
|
||||
noinst_PROGRAMS = gpgme
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/jnlib
|
||||
LDADD = -L ../jnlib -ljnlib
|
||||
|
||||
gpgme_SOURCES = main.c main.h
|
||||
|
||||
|
||||
|
287
complus/main.c
Normal file
287
complus/main.c
Normal file
@ -0,0 +1,287 @@
|
||||
/* main.c - COM+ component to access GnuPG
|
||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
||||
*
|
||||
* This file is part of GPGME.
|
||||
*
|
||||
* GPGME 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.
|
||||
*
|
||||
* GPGME 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "argparse.h"
|
||||
|
||||
#include "main.h"
|
||||
|
||||
|
||||
static void register_server (void);
|
||||
static void unregister_server (void);
|
||||
static void enter_complus (void);
|
||||
|
||||
|
||||
enum cmd_and_opt_values { aNull = 0,
|
||||
oQuiet = 'q',
|
||||
oVerbose = 'v',
|
||||
|
||||
oNoVerbose = 500,
|
||||
oOptions,
|
||||
oDebug,
|
||||
oDebugAll,
|
||||
oNoGreeting,
|
||||
oNoOptions,
|
||||
oHomedir,
|
||||
oGPGBinary,
|
||||
oRegServer,
|
||||
oUnregServer,
|
||||
oEmbedding,
|
||||
aTest };
|
||||
|
||||
|
||||
static ARGPARSE_OPTS opts[] = {
|
||||
|
||||
{ 301, NULL, 0, N_("@Options:\n ") },
|
||||
|
||||
{ oVerbose, "verbose", 0, N_("verbose") },
|
||||
{ oQuiet, "quiet", 0, N_("be somewhat more quiet") },
|
||||
{ oOptions, "options" , 2, N_("read options from file")},
|
||||
{ oDebug, "debug" ,4|16, N_("set debugging flags")},
|
||||
{ oDebugAll, "debug-all" ,0, N_("enable full debugging")},
|
||||
{ oGPGBinary, "gpg-program", 2 , "@" },
|
||||
{ oRegServer, "RegServer" , 0, "@" },
|
||||
{ oUnregServer, "UnregServer" , 0, "@" },
|
||||
{ oEmbedding, "Embedding" , 0, "@" },
|
||||
{0} };
|
||||
|
||||
static const char *
|
||||
my_strusage( int level )
|
||||
{
|
||||
const char *p;
|
||||
switch( level ) {
|
||||
case 11: p = "gpgme";
|
||||
break;
|
||||
case 13: p = VERSION; break;
|
||||
/*case 17: p = PRINTABLE_OS_NAME; break;*/
|
||||
case 19: p =
|
||||
_("Please report bugs to <gpgme-bugs@gnupg.org>.\n");
|
||||
break;
|
||||
case 1:
|
||||
case 40: p =
|
||||
_("Usage: gpgme [options] (-h for help)");
|
||||
break;
|
||||
case 41: p =
|
||||
_("Syntax: gpgme [options]\n"
|
||||
"GnuPG COM+ component\n");
|
||||
break;
|
||||
|
||||
default: p = NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv )
|
||||
{
|
||||
ARGPARSE_ARGS pargs;
|
||||
int orig_argc;
|
||||
char **orig_argv;
|
||||
FILE *configfp = NULL;
|
||||
char *configname = NULL;
|
||||
unsigned configlineno;
|
||||
int parse_debug = 0;
|
||||
int default_config =1;
|
||||
int greeting = 0;
|
||||
int nogreeting = 0;
|
||||
int action = 0;
|
||||
|
||||
set_strusage( my_strusage );
|
||||
/*log_set_name ("gpa"); not yet implemented in logging.c */
|
||||
|
||||
opt.homedir = getenv("GNUPGHOME");
|
||||
if( !opt.homedir || !*opt.homedir ) {
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
opt.homedir = "c:/gnupg";
|
||||
#else
|
||||
opt.homedir = "~/.gnupg";
|
||||
#endif
|
||||
}
|
||||
|
||||
/* check whether we have a config file on the commandline */
|
||||
orig_argc = argc;
|
||||
orig_argv = argv;
|
||||
pargs.argc = &argc;
|
||||
pargs.argv = &argv;
|
||||
pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */
|
||||
while( arg_parse( &pargs, opts) ) {
|
||||
if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
|
||||
parse_debug++;
|
||||
else if( pargs.r_opt == oOptions ) {
|
||||
/* yes there is one, so we do not try the default one, but
|
||||
* read the option file when it is encountered at the commandline
|
||||
*/
|
||||
default_config = 0;
|
||||
}
|
||||
else if( pargs.r_opt == oNoOptions )
|
||||
default_config = 0; /* --no-options */
|
||||
else if( pargs.r_opt == oHomedir )
|
||||
opt.homedir = pargs.r.ret_str;
|
||||
}
|
||||
|
||||
if( default_config )
|
||||
configname = make_filename(opt.homedir, "gpgme.conf", NULL );
|
||||
|
||||
|
||||
argc = orig_argc;
|
||||
argv = orig_argv;
|
||||
pargs.argc = &argc;
|
||||
pargs.argv = &argv;
|
||||
pargs.flags= 1 | (1<<5); /* do not remove the args, allow one dash */
|
||||
next_pass:
|
||||
if( configname ) {
|
||||
configlineno = 0;
|
||||
configfp = fopen( configname, "r" );
|
||||
if( !configfp ) {
|
||||
if( default_config ) {
|
||||
if( parse_debug )
|
||||
log_info(_("NOTE: no default option file `%s'\n"),
|
||||
configname );
|
||||
}
|
||||
else {
|
||||
log_error(_("option file `%s': %s\n"),
|
||||
configname, strerror(errno) );
|
||||
exit(2);
|
||||
}
|
||||
free(configname); configname = NULL;
|
||||
}
|
||||
if( parse_debug && configname )
|
||||
log_info(_("reading options from `%s'\n"), configname );
|
||||
default_config = 0;
|
||||
}
|
||||
|
||||
while( optfile_parse( configfp, configname, &configlineno,
|
||||
&pargs, opts) ) {
|
||||
switch( pargs.r_opt ) {
|
||||
case oQuiet: opt.quiet = 1; break;
|
||||
case oVerbose: opt.verbose++; break;
|
||||
|
||||
case oDebug: opt.debug |= pargs.r.ret_ulong; break;
|
||||
case oDebugAll: opt.debug = ~0; break;
|
||||
|
||||
case oOptions:
|
||||
/* config files may not be nested (silently ignore them) */
|
||||
if( !configfp ) {
|
||||
free(configname);
|
||||
configname = xstrdup(pargs.r.ret_str);
|
||||
goto next_pass;
|
||||
}
|
||||
break;
|
||||
case oNoGreeting: nogreeting = 1; break;
|
||||
case oNoVerbose: opt.verbose = 0; break;
|
||||
case oNoOptions: break; /* no-options */
|
||||
case oHomedir: opt.homedir = pargs.r.ret_str; break;
|
||||
case oGPGBinary: break;
|
||||
|
||||
case oRegServer: action = 1; break;
|
||||
case oUnregServer: action = 2; break;
|
||||
case oEmbedding: action = 3; break;
|
||||
|
||||
default : pargs.err = configfp? 1:2; break;
|
||||
}
|
||||
}
|
||||
if( configfp ) {
|
||||
fclose( configfp );
|
||||
configfp = NULL;
|
||||
free(configname); configname = NULL;
|
||||
goto next_pass;
|
||||
}
|
||||
free( configname ); configname = NULL;
|
||||
if( log_get_errorcount(0) )
|
||||
exit(2);
|
||||
if( nogreeting )
|
||||
greeting = 0;
|
||||
|
||||
if( greeting ) {
|
||||
fprintf(stderr, "%s %s; %s\n",
|
||||
strusage(11), strusage(13), strusage(14) );
|
||||
fprintf(stderr, "%s\n", strusage(15) );
|
||||
}
|
||||
#ifdef IS_DEVELOPMENT_VERSION
|
||||
log_info("NOTE: this is a development version!\n");
|
||||
#endif
|
||||
|
||||
if ( action == 1 )
|
||||
register_server ();
|
||||
else if (action == 2 )
|
||||
unregister_server ();
|
||||
else if (action == 3 )
|
||||
enter_complus ();
|
||||
else {
|
||||
fprintf (stderr, "This is a COM+ component with no user interface.\n"
|
||||
"gpgme --help will give you a list of options\n" );
|
||||
exit (1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
register_server ()
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
unregister_server ()
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
enter_complus ()
|
||||
{
|
||||
HANDLE running;
|
||||
int reg;
|
||||
void *factory;
|
||||
|
||||
/* CoInitializeEx (NULL, COINIT_MULTITHREADED); */
|
||||
running = CreateEvent (NULL, FALSE, FALSE, NULL );
|
||||
|
||||
#if 0
|
||||
factory = create_class_factory ();
|
||||
CoRegisterClassObject (CLSID_gpgme, factory,
|
||||
CLSCTX_LOCAL_SERVER,
|
||||
REGCLS_SUSPENDED|REGCLASS_MULTIPLEUSE, ® );
|
||||
CoResumeClassObjects ();
|
||||
#endif
|
||||
|
||||
WaitForSingleObject ( running, INFINITE );
|
||||
CloseHandle (running);
|
||||
#if 0
|
||||
CoRevokeClassObject ( reg );
|
||||
factory->release ();
|
||||
CoUnitialize ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
50
complus/main.h
Normal file
50
complus/main.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* main.h - GPGME COM+ component
|
||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
||||
*
|
||||
* This file is part of GPGME.
|
||||
*
|
||||
* GPGME 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.
|
||||
*
|
||||
* GPGME 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#ifndef COMPLUS_MAIN_H
|
||||
#define COMPLUS_MAIN_H
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "stringhelp.h"
|
||||
#include "logging.h"
|
||||
|
||||
|
||||
#define _(a) (a)
|
||||
#define N_(a) (a)
|
||||
|
||||
|
||||
struct {
|
||||
int verbose;
|
||||
int quiet;
|
||||
unsigned int debug;
|
||||
char *homedir;
|
||||
} opt;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* COMPLUS_MAIN_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
46
configure.in
46
configure.in
@ -13,10 +13,10 @@ AM_MAINTAINER_MODE
|
||||
# AGE, set REVISION to 0.
|
||||
# 3. Interfaces removed (BAD, breaks upward compatibility): Increment
|
||||
# CURRENT, set AGE and REVISION to 0.
|
||||
AM_INIT_AUTOMAKE(gpgme,0.1.0)
|
||||
AM_INIT_AUTOMAKE(gpgme,0.1.1)
|
||||
LIBGPGME_LT_CURRENT=0
|
||||
LIBGPGME_LT_AGE=0
|
||||
LIBGPGME_LT_REVISION=2
|
||||
LIBGPGME_LT_REVISION=3
|
||||
##############################################
|
||||
|
||||
AC_SUBST(LIBGPGME_LT_CURRENT)
|
||||
@ -38,6 +38,7 @@ if test "$GCC" = yes; then
|
||||
fi
|
||||
|
||||
GPG=
|
||||
component_system=None
|
||||
case "${target}" in
|
||||
*-*-mingw32* | i?86-emx-os2 | i?86-*-os2*emx | i?86-*-msdosdjgpp* )
|
||||
# special stuff for Windoze NT
|
||||
@ -46,6 +47,7 @@ case "${target}" in
|
||||
AC_DEFINE(HAVE_DRIVE_LETTERS)
|
||||
AC_DEFINE(HAVE_DOSISH_SYSTEM)
|
||||
GPG='c:\\gnupg\\gpg.exe'
|
||||
component_system='COM+'
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
@ -63,9 +65,27 @@ dnl Checks for header files
|
||||
dnl
|
||||
|
||||
|
||||
|
||||
dnl
|
||||
dnl Checks for typedefs and structures
|
||||
dnl
|
||||
GNUPG_CHECK_TYPEDEF(byte, HAVE_BYTE_TYPEDEF)
|
||||
GNUPG_CHECK_TYPEDEF(ushort, HAVE_USHORT_TYPEDEF)
|
||||
GNUPG_CHECK_TYPEDEF(ulong, HAVE_ULONG_TYPEDEF)
|
||||
GNUPG_CHECK_TYPEDEF(u16, HAVE_U16_TYPEDEF)
|
||||
GNUPG_CHECK_TYPEDEF(u32, HAVE_U32_TYPEDEF)
|
||||
# We should not use them in this software;
|
||||
# However jnlib/types.h needs them - so we take the easy way.
|
||||
AC_CHECK_SIZEOF(unsigned short, 2)
|
||||
AC_CHECK_SIZEOF(unsigned int, 4)
|
||||
AC_CHECK_SIZEOF(unsigned long, 4)
|
||||
if test "$ac_cv_sizeof_unsigned_short" = "0" \
|
||||
|| test "$ac_cv_sizeof_unsigned_int" = "0" \
|
||||
|| test "$ac_cv_sizeof_unsigned_long" = "0"; then
|
||||
AC_MSG_WARN([Hmmm, something is wrong with the sizes - using defaults]);
|
||||
fi
|
||||
|
||||
|
||||
|
||||
dnl
|
||||
dnl Checks for compiler features
|
||||
@ -74,14 +94,15 @@ dnl
|
||||
dnl
|
||||
dnl Checks for library functions
|
||||
dnl
|
||||
AC_CHECK_FUNCS(stpcpy)
|
||||
dnl These are needed by libjnlib
|
||||
AC_CHECK_FUNCS(memicmp stpcpy strlwr strtoul memmove stricmp)
|
||||
|
||||
|
||||
dnl
|
||||
dnl Checks for system services
|
||||
dnl
|
||||
|
||||
if test -z "GPG"; then
|
||||
if test -z "$GPG"; then
|
||||
AC_PATH_PROG(GPG, gpg)
|
||||
if test -z "$GPG"; then
|
||||
AC_MSG_ERROR([[
|
||||
@ -95,11 +116,19 @@ fi
|
||||
AC_DEFINE_UNQUOTED(GPG_PATH, "$GPG")
|
||||
|
||||
|
||||
dnl
|
||||
dnl FIXME: check whether Bonobo is installed
|
||||
dnl
|
||||
|
||||
|
||||
dnl
|
||||
dnl Create config files
|
||||
dnl
|
||||
dnl
|
||||
|
||||
AM_CONDITIONAL(BUILD_COMPLUS, test "$component_system" = "COM+")
|
||||
AM_CONDITIONAL(BUILD_BONOBO, test "$component_system" = "Bonobo")
|
||||
|
||||
dnl Make the version number in gpgme/gpgme.h the same as the one here.
|
||||
dnl (this is easier than to have a *.in file just for one substitution)
|
||||
GNUPG_FIX_HDR_VERSION(gpgme/gpgme.h, GPGME_VERSION)
|
||||
@ -116,11 +145,20 @@ chmod +x gpgme/gpgme-config
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
jnlib/Makefile
|
||||
gpgme/Makefile
|
||||
gpgme/gpgme-config
|
||||
tests/Makefile
|
||||
bonobo/Makefile
|
||||
complus/Makefile
|
||||
])
|
||||
|
||||
echo "
|
||||
GPGME v${VERSION} has been configured as follows:
|
||||
|
||||
GPG path: $GPG
|
||||
Component: $component_system
|
||||
"
|
||||
|
||||
|
||||
|
||||
|
@ -56,9 +56,6 @@ struct gpgme_context_s {
|
||||
int use_armor;
|
||||
int use_textmode;
|
||||
|
||||
/* GpgmePassphraseCb passphrase_cb;*/
|
||||
/* void * passphrase_cb_value;*/
|
||||
|
||||
ResultType result_type;
|
||||
union {
|
||||
VerifyResult verify;
|
||||
@ -71,6 +68,8 @@ struct gpgme_context_s {
|
||||
GpgmeKey tmp_key; /* used by keylist.c */
|
||||
volatile int key_cond; /* something new is available */
|
||||
struct key_queue_item_s *key_queue;
|
||||
|
||||
char *prompt_1;
|
||||
};
|
||||
|
||||
|
||||
@ -79,6 +78,11 @@ struct gpgme_data_s {
|
||||
const char *data;
|
||||
GpgmeDataType type;
|
||||
GpgmeDataMode mode;
|
||||
|
||||
int (*read_cb)( void *, char *, size_t, size_t *);
|
||||
void *read_cb_value;
|
||||
int read_cb_eof;
|
||||
|
||||
size_t readpos;
|
||||
size_t writepos;
|
||||
size_t private_len;
|
||||
|
108
gpgme/data.c
108
gpgme/data.c
@ -113,6 +113,30 @@ gpgme_data_new_from_mem ( GpgmeData *r_dh,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
GpgmeError
|
||||
gpgme_data_new_with_read_cb ( GpgmeData *r_dh,
|
||||
int (*read_cb)(void*,char *,size_t,size_t*),
|
||||
void *read_cb_value )
|
||||
{
|
||||
GpgmeData dh;
|
||||
GpgmeError err;
|
||||
|
||||
if (!r_dh || !read_cb)
|
||||
return mk_error (Invalid_Value);
|
||||
*r_dh = NULL;
|
||||
err = gpgme_data_new ( &dh );
|
||||
if (err)
|
||||
return err;
|
||||
dh->type = GPGME_DATA_TYPE_CB;
|
||||
dh->mode = GPGME_DATA_MODE_OUT;
|
||||
dh->read_cb = read_cb;
|
||||
dh->read_cb_value = read_cb_value;
|
||||
|
||||
*r_dh = dh;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gpgme_data_new_from_file:
|
||||
* @r_dh: returns the new data object
|
||||
@ -279,7 +303,7 @@ gpgme_data_release_and_get_mem ( GpgmeData dh, size_t *r_len )
|
||||
GpgmeDataType
|
||||
gpgme_data_get_type ( GpgmeData dh )
|
||||
{
|
||||
if ( !dh || !dh->data )
|
||||
if ( !dh || (!dh->data && !dh->read_cb))
|
||||
return GPGME_DATA_TYPE_NONE;
|
||||
|
||||
return dh->type;
|
||||
@ -315,9 +339,18 @@ gpgme_data_rewind ( GpgmeData dh )
|
||||
{
|
||||
if ( !dh )
|
||||
return mk_error (Invalid_Value);
|
||||
/* Fixme: We should check whether rewinding does make sense for the
|
||||
* data type */
|
||||
dh->readpos = 0;
|
||||
|
||||
if (dh->type == GPGME_DATA_TYPE_MEM ) {
|
||||
dh->readpos = 0;
|
||||
}
|
||||
else if (dh->type == GPGME_DATA_TYPE_CB) {
|
||||
dh->len = dh->readpos = 0;
|
||||
dh->read_cb_eof = 0;
|
||||
/* FIXME: do a special call to the read function to trigger a rewind
|
||||
there */
|
||||
}
|
||||
else
|
||||
return mk_error (General_Error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -334,7 +367,7 @@ gpgme_data_rewind ( GpgmeData dh )
|
||||
* If there are no more bytes available %GPGME_EOF is returned and @nread
|
||||
* is set to 0.
|
||||
*
|
||||
* Return value: An errocodee or 0 on success, EOF is indcated by the
|
||||
* Return value: An errorcode or 0 on success, EOF is indcated by the
|
||||
* error code GPGME_EOF.
|
||||
**/
|
||||
GpgmeError
|
||||
@ -344,19 +377,66 @@ gpgme_data_read ( GpgmeData dh, char *buffer, size_t length, size_t *nread )
|
||||
|
||||
if ( !dh )
|
||||
return mk_error (Invalid_Value);
|
||||
nbytes = dh->len - dh->readpos;
|
||||
if ( !nbytes ) {
|
||||
*nread = 0;
|
||||
return mk_error(EOF);
|
||||
if (dh->type == GPGME_DATA_TYPE_MEM ) {
|
||||
nbytes = dh->len - dh->readpos;
|
||||
if ( !nbytes ) {
|
||||
*nread = 0;
|
||||
return mk_error(EOF);
|
||||
}
|
||||
if (nbytes > length)
|
||||
nbytes = length;
|
||||
memcpy ( buffer, dh->data + dh->readpos, nbytes );
|
||||
*nread = nbytes;
|
||||
dh->readpos += nbytes;
|
||||
}
|
||||
if (nbytes > length)
|
||||
nbytes = length;
|
||||
memcpy ( buffer, dh->data + dh->readpos, nbytes );
|
||||
*nread = nbytes;
|
||||
dh->readpos += nbytes;
|
||||
else if (dh->type == GPGME_DATA_TYPE_CB) {
|
||||
nbytes = dh->len - dh->readpos;
|
||||
if ( nbytes ) {
|
||||
/* we have unread data - return this */
|
||||
if (nbytes > length)
|
||||
nbytes = length;
|
||||
memcpy ( buffer, dh->data + dh->readpos, nbytes );
|
||||
*nread = nbytes;
|
||||
dh->readpos += nbytes;
|
||||
}
|
||||
else { /* get the data from the callback */
|
||||
if (!dh->read_cb || dh->read_cb_eof) {
|
||||
*nread = 0;
|
||||
return mk_error (EOF);
|
||||
}
|
||||
if (dh->read_cb (dh->read_cb_value, buffer, length, nread )) {
|
||||
*nread = 0;
|
||||
dh->read_cb_eof = 1;
|
||||
return mk_error (EOF);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return mk_error (General_Error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GpgmeError
|
||||
_gpgme_data_unread (GpgmeData dh, const char *buffer, size_t length )
|
||||
{
|
||||
if ( !dh )
|
||||
return mk_error (Invalid_Value);
|
||||
|
||||
if (dh->type == GPGME_DATA_TYPE_MEM ) {
|
||||
/* check that we don't unread more than we have yet read */
|
||||
if ( dh->readpos < length )
|
||||
return mk_error (Invalid_Value);
|
||||
/* No need to use the buffer for this data type */
|
||||
dh->readpos -= length;
|
||||
}
|
||||
else {
|
||||
return mk_error (General_Error);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function does make sense when we know that it contains no nil chars.
|
||||
*/
|
||||
|
@ -33,6 +33,7 @@ struct decrypt_result_s {
|
||||
int no_passphrase;
|
||||
int okay;
|
||||
int failed;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -43,6 +44,17 @@ _gpgme_release_decrypt_result ( DecryptResult res )
|
||||
}
|
||||
|
||||
|
||||
static GpgmeError
|
||||
create_result_struct ( GpgmeCtx ctx )
|
||||
{
|
||||
assert ( !ctx->result.decrypt );
|
||||
ctx->result.decrypt = xtrycalloc ( 1, sizeof *ctx->result.decrypt );
|
||||
if ( !ctx->result.decrypt ) {
|
||||
return mk_error (Out_Of_Core);
|
||||
}
|
||||
ctx->result_type = RESULT_TYPE_DECRYPT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
decrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
|
||||
@ -50,13 +62,10 @@ decrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
|
||||
if ( ctx->out_of_core )
|
||||
return;
|
||||
if ( ctx->result_type == RESULT_TYPE_NONE ) {
|
||||
assert ( !ctx->result.decrypt );
|
||||
ctx->result.decrypt = xtrycalloc ( 1, sizeof *ctx->result.decrypt );
|
||||
if ( !ctx->result.decrypt ) {
|
||||
if ( create_result_struct ( ctx ) ) {
|
||||
ctx->out_of_core = 1;
|
||||
return;
|
||||
}
|
||||
ctx->result_type = RESULT_TYPE_DECRYPT;
|
||||
}
|
||||
assert ( ctx->result_type == RESULT_TYPE_DECRYPT );
|
||||
|
||||
@ -66,7 +75,9 @@ decrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
|
||||
|
||||
case STATUS_NEED_PASSPHRASE:
|
||||
case STATUS_NEED_PASSPHRASE_SYM:
|
||||
fprintf (stderr, "Ooops: Need a passphrase - use the agent\n");
|
||||
fprintf (stderr, "need a passphrase ...\n" );
|
||||
_gpgme_set_prompt (ctx, 1, "Hey! We need your passphrase!");
|
||||
/* next thing gpg has to do is to read it from the passphrase-fd */
|
||||
break;
|
||||
|
||||
case STATUS_MISSING_PASSPHRASE:
|
||||
@ -91,9 +102,9 @@ decrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
|
||||
}
|
||||
|
||||
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData ciph, GpgmeData plain )
|
||||
gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData passphrase,
|
||||
GpgmeData ciph, GpgmeData plain )
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
@ -118,14 +129,19 @@ gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData ciph, GpgmeData plain )
|
||||
_gpgme_gpg_add_arg ( c->gpg, "--decrypt" );
|
||||
for ( i=0; i < c->verbosity; i++ )
|
||||
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
|
||||
|
||||
if (passphrase) {
|
||||
_gpgme_gpg_add_arg (c->gpg, "--passphrase-fd" );
|
||||
_gpgme_gpg_add_data (c->gpg, passphrase, -2 );
|
||||
}
|
||||
|
||||
|
||||
/* Check the supplied data */
|
||||
if ( !ciph || gpgme_data_get_type (ciph) == GPGME_DATA_TYPE_NONE ) {
|
||||
rc = mk_error (No_Data);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
_gpgme_data_set_mode (ciph, GPGME_DATA_MODE_OUT );
|
||||
|
||||
if ( gpgme_data_get_type (plain) != GPGME_DATA_TYPE_NONE ) {
|
||||
rc = mk_error (Invalid_Value);
|
||||
goto leave;
|
||||
@ -153,6 +169,7 @@ gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData ciph, GpgmeData plain )
|
||||
/**
|
||||
* gpgme_op_decrypt:
|
||||
* @c: The context
|
||||
* @passphrase: A data object with the passphrase or NULL.
|
||||
* @in: ciphertext input
|
||||
* @out: plaintext output
|
||||
*
|
||||
@ -163,9 +180,10 @@ gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData ciph, GpgmeData plain )
|
||||
* Return value: 0 on success or an errorcode.
|
||||
**/
|
||||
GpgmeError
|
||||
gpgme_op_decrypt ( GpgmeCtx c, GpgmeData in, GpgmeData out )
|
||||
gpgme_op_decrypt ( GpgmeCtx c, GpgmeData passphrase,
|
||||
GpgmeData in, GpgmeData out )
|
||||
{
|
||||
GpgmeError err = gpgme_op_decrypt_start ( c, in, out );
|
||||
GpgmeError err = gpgme_op_decrypt_start ( c, passphrase, in, out );
|
||||
if ( !err ) {
|
||||
gpgme_wait (c, 1);
|
||||
if ( c->result_type != RESULT_TYPE_DECRYPT )
|
||||
|
49
gpgme/errors.c
Normal file
49
gpgme/errors.c
Normal file
@ -0,0 +1,49 @@
|
||||
/* Generated automatically by mkerrors */
|
||||
/* Do not edit! */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "gpgme.h"
|
||||
|
||||
/**
|
||||
* gpgme_strerror:
|
||||
* @err: Error code
|
||||
*
|
||||
* This function returns a textual representaion of the given
|
||||
* errocode. If this is an unknown value, a string with the value
|
||||
* is returned (which is hold in a static buffer).
|
||||
*
|
||||
* Return value: String with the error description.
|
||||
**/
|
||||
const char *
|
||||
gpgme_strerror (GpgmeError err)
|
||||
{
|
||||
const char *s;
|
||||
static char buf[25];
|
||||
|
||||
switch (err) {
|
||||
case GPGME_No_Error: s="No Error"; break;
|
||||
case GPGME_General_Error: s="General Error"; break;
|
||||
case GPGME_Out_Of_Core: s="Out Of Core"; break;
|
||||
case GPGME_Invalid_Value: s="Invalid Value"; break;
|
||||
case GPGME_Busy: s="Busy"; break;
|
||||
case GPGME_No_Request: s="No Request"; break;
|
||||
case GPGME_Exec_Error: s="Exec Error"; break;
|
||||
case GPGME_Too_Many_Procs: s="Too Many Procs"; break;
|
||||
case GPGME_Pipe_Error: s="Pipe Error"; break;
|
||||
case GPGME_No_Recipients: s="No Recipients"; break;
|
||||
case GPGME_No_Data: s="No Data"; break;
|
||||
case GPGME_Conflict: s="Conflict"; break;
|
||||
case GPGME_Not_Implemented: s="Not Implemented"; break;
|
||||
case GPGME_Read_Error: s="Read Error"; break;
|
||||
case GPGME_Write_Error: s="Write Error"; break;
|
||||
case GPGME_Invalid_Type: s="Invalid Type"; break;
|
||||
case GPGME_Invalid_Mode: s="Invalid Mode"; break;
|
||||
case GPGME_File_Error: s="File Error"; break;
|
||||
case GPGME_Decryption_Failed: s="Decryption Failed"; break;
|
||||
case GPGME_No_Passphrase: s="No Passphrase"; break;
|
||||
default: sprintf (buf, "ec=%d", err ); s=buf; break;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "context.h"
|
||||
@ -69,7 +70,8 @@ gpgme_release ( GpgmeCtx c )
|
||||
_gpgme_key_release ( c->tmp_key );
|
||||
gpgme_data_release ( c->notation );
|
||||
/* fixme: release the key_queue */
|
||||
xfree ( c );
|
||||
xfree (c->prompt_1);
|
||||
xfree (c);
|
||||
}
|
||||
|
||||
|
||||
@ -145,16 +147,31 @@ gpgme_set_textmode ( GpgmeCtx c, int yes )
|
||||
c->use_textmode = yes;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* The only which currently allowed is 1
|
||||
*/
|
||||
void
|
||||
gpgme_set_passphrase_cb ( GpgmeCtx c, GpgmePassphraseCb fnc, void *fncval )
|
||||
_gpgme_set_prompt ( GpgmeCtx c, int which, const char *text )
|
||||
{
|
||||
if ( c ) {
|
||||
c->passphrase_cb = fnc;
|
||||
c->passphrase_cb_value = fncval;
|
||||
assert ( which == 1 );
|
||||
|
||||
xfree (c->prompt_1); c->prompt_1 = NULL;
|
||||
if (text) {
|
||||
c->prompt_1 = xtrystrdup (text);
|
||||
if ( !c->prompt_1 )
|
||||
c->out_of_core = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *
|
||||
gpgme_get_prompt ( GpgmeCtx c, int which )
|
||||
{
|
||||
if ( which != 1 )
|
||||
return NULL;
|
||||
return c->prompt_1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ extern "C" {
|
||||
* let autoconf (using the AM_PATH_GPGME macro) check that this
|
||||
* header matches the installed library.
|
||||
* Warning: Do not edit the next line. configure will do that for you! */
|
||||
#define GPGME_VERSION "0.1.0"
|
||||
#define GPGME_VERSION "0.1.1"
|
||||
|
||||
|
||||
|
||||
@ -79,7 +79,8 @@ typedef enum {
|
||||
GPGME_DATA_TYPE_NONE = 0,
|
||||
GPGME_DATA_TYPE_MEM = 1,
|
||||
GPGME_DATA_TYPE_FD = 2,
|
||||
GPGME_DATA_TYPE_FILE = 3
|
||||
GPGME_DATA_TYPE_FILE = 3,
|
||||
GPGME_DATA_TYPE_CB = 4
|
||||
} GpgmeDataType;
|
||||
|
||||
typedef enum {
|
||||
@ -91,8 +92,6 @@ typedef enum {
|
||||
GPGME_SIG_STAT_ERROR = 5
|
||||
} GpgmeSigStat;
|
||||
|
||||
/*typedef GpgmeData (*GpgmePassphraseCb)( void *opaque, const char *desc );*/
|
||||
|
||||
|
||||
/* Context management */
|
||||
GpgmeError gpgme_new (GpgmeCtx *r_ctx);
|
||||
@ -102,8 +101,7 @@ GpgmeCtx gpgme_wait ( GpgmeCtx c, int hang );
|
||||
char *gpgme_get_notation ( GpgmeCtx c );
|
||||
void gpgme_set_armor ( GpgmeCtx c, int yes );
|
||||
void gpgme_set_textmode ( GpgmeCtx c, int yes );
|
||||
/*void gpgme_set_passphrase_cb ( GpgmeCtx c,
|
||||
GpgmePassphraseCb fnc, void *fncval );*/
|
||||
|
||||
|
||||
|
||||
/* Functions to handle recipients */
|
||||
@ -118,6 +116,10 @@ GpgmeError gpgme_data_new ( GpgmeData *r_dh );
|
||||
GpgmeError gpgme_data_new_from_mem ( GpgmeData *r_dh,
|
||||
const char *buffer, size_t size,
|
||||
int copy );
|
||||
GpgmeError gpgme_data_new_with_read_cb ( GpgmeData *r_dh,
|
||||
int (*read_cb)(void*,char *,size_t,size_t*),
|
||||
void *read_cb_value );
|
||||
|
||||
GpgmeError gpgme_data_new_from_file ( GpgmeData *r_dh,
|
||||
const char *fname,
|
||||
int copy );
|
||||
@ -136,7 +138,7 @@ char *gpgme_key_get_as_xml ( GpgmeKey key );
|
||||
GpgmeError gpgme_op_encrypt_start ( GpgmeCtx c,
|
||||
GpgmeRecipients recp,
|
||||
GpgmeData in, GpgmeData out );
|
||||
GpgmeError gpgme_op_decrypt_start ( GpgmeCtx c,
|
||||
GpgmeError gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData passphrase,
|
||||
GpgmeData ciph, GpgmeData plain );
|
||||
GpgmeError gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out );
|
||||
GpgmeError gpgme_op_verify_start ( GpgmeCtx c,
|
||||
@ -152,7 +154,8 @@ GpgmeError gpgme_op_keylist_next ( GpgmeCtx c, GpgmeKey *r_key );
|
||||
/* Convenience functions for normal usage */
|
||||
GpgmeError gpgme_op_encrypt ( GpgmeCtx c, GpgmeRecipients recp,
|
||||
GpgmeData in, GpgmeData out );
|
||||
GpgmeError gpgme_op_decrypt ( GpgmeCtx c, GpgmeData in, GpgmeData out );
|
||||
GpgmeError gpgme_op_decrypt ( GpgmeCtx c, GpgmeData passphrase,
|
||||
GpgmeData in, GpgmeData out );
|
||||
GpgmeError gpgme_op_sign ( GpgmeCtx c, GpgmeData in, GpgmeData out );
|
||||
GpgmeError gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
|
||||
GpgmeSigStat *r_status );
|
||||
@ -161,6 +164,7 @@ GpgmeError gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
|
||||
/* miscellaneous functions */
|
||||
const char *gpgme_check_version ( const char *req_version );
|
||||
const char *gpgme_strerror (GpgmeError err);
|
||||
const char *gpgme_get_prompt ( GpgmeCtx c, int which );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -31,6 +31,7 @@ struct spawn_fd_item_s {
|
||||
|
||||
struct io_select_fd_s {
|
||||
int fd;
|
||||
int is_closed;
|
||||
int for_read;
|
||||
int for_write;
|
||||
int signaled;
|
||||
@ -42,7 +43,7 @@ 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_pipe ( int filedes[2], int inherit_idx );
|
||||
int _gpgme_io_close ( int fd );
|
||||
int _gpgme_io_set_nonblocking ( int fd );
|
||||
int _gpgme_io_spawn ( const char *path, char **argv,
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
/*-- gpgme.c --*/
|
||||
void _gpgme_release_result ( GpgmeCtx c );
|
||||
void _gpgme_set_prompt ( GpgmeCtx c, int which, const char *text );
|
||||
|
||||
/*-- wait.c --*/
|
||||
GpgmeCtx _gpgme_wait_on_condition ( GpgmeCtx c,
|
||||
@ -53,6 +54,9 @@ GpgmeError _gpgme_data_append_for_xml ( GpgmeData dh,
|
||||
GpgmeError _gpgme_data_append_percentstring_for_xml ( GpgmeData dh,
|
||||
const char *string );
|
||||
|
||||
GpgmeError _gpgme_data_unread (GpgmeData dh,
|
||||
const char *buffer, size_t length );
|
||||
|
||||
|
||||
/*-- key.c --*/
|
||||
GpgmeError _gpgme_key_new( GpgmeKey *r_key );
|
||||
|
@ -68,8 +68,9 @@ _gpgme_io_write ( int fd, const void *buffer, size_t count )
|
||||
}
|
||||
|
||||
int
|
||||
_gpgme_io_pipe ( int filedes[2] )
|
||||
_gpgme_io_pipe ( int filedes[2], int inherit_idx )
|
||||
{
|
||||
/* we don't need inherit_idx in this implementation */
|
||||
return pipe ( filedes );
|
||||
}
|
||||
|
||||
|
@ -40,12 +40,14 @@
|
||||
|
||||
#include "status-table.h"
|
||||
|
||||
|
||||
/* This type is used to build a list of gpg arguments and
|
||||
* data sources/sinks */
|
||||
struct arg_and_data_s {
|
||||
struct arg_and_data_s *next;
|
||||
GpgmeData data; /* If this is not NULL .. */
|
||||
int dup_to;
|
||||
int print_fd; /* print the fd number and not the special form of it */
|
||||
char arg[1]; /* .. this is used */
|
||||
};
|
||||
|
||||
@ -137,7 +139,7 @@ _gpgme_gpg_new ( GpgObject *r_gpg )
|
||||
}
|
||||
/* In any case we need a status pipe - create it right here and
|
||||
* don't handle it with our generic GpgmeData mechanism */
|
||||
if (_gpgme_io_pipe (gpg->status.fd) == -1) {
|
||||
if (_gpgme_io_pipe (gpg->status.fd, 1) == -1) {
|
||||
rc = mk_error (Pipe_Error);
|
||||
goto leave;
|
||||
}
|
||||
@ -151,6 +153,7 @@ _gpgme_gpg_new ( GpgObject *r_gpg )
|
||||
_gpgme_gpg_add_arg ( gpg, "--batch" );
|
||||
_gpgme_gpg_add_arg ( gpg, "--no-tty" );
|
||||
|
||||
|
||||
leave:
|
||||
if (rc) {
|
||||
_gpgme_gpg_release (gpg);
|
||||
@ -170,6 +173,11 @@ _gpgme_gpg_release ( GpgObject gpg )
|
||||
xfree (gpg->colon.buffer);
|
||||
if ( gpg->argv )
|
||||
free_argv (gpg->argv);
|
||||
#if 0
|
||||
/* fixme: We need a way to communicate back closed fds, so that we
|
||||
* don't do it a second time. One way to do it is by using a global
|
||||
* table of open fds associated with gpg objects - but this requires
|
||||
* additional locking. */
|
||||
if (gpg->status.fd[0] != -1 )
|
||||
_gpgme_io_close (gpg->status.fd[0]);
|
||||
if (gpg->status.fd[1] != -1 )
|
||||
@ -178,6 +186,7 @@ _gpgme_gpg_release ( GpgObject gpg )
|
||||
_gpgme_io_close (gpg->colon.fd[0]);
|
||||
if (gpg->colon.fd[1] != -1 )
|
||||
_gpgme_io_close (gpg->colon.fd[1]);
|
||||
#endif
|
||||
free_fd_data_map (gpg->fd_data_map);
|
||||
kill_gpg (gpg); /* fixme: should be done asyncronously */
|
||||
xfree (gpg);
|
||||
@ -237,7 +246,14 @@ _gpgme_gpg_add_data ( GpgObject gpg, GpgmeData data, int dup_to )
|
||||
}
|
||||
a->next = NULL;
|
||||
a->data = data;
|
||||
a->dup_to = dup_to;
|
||||
if ( dup_to == -2 ) {
|
||||
a->print_fd = 1;
|
||||
a->dup_to = -1;
|
||||
}
|
||||
else {
|
||||
a->print_fd = 0;
|
||||
a->dup_to = dup_to;
|
||||
}
|
||||
*gpg->argtail = a;
|
||||
gpg->argtail = &a->next;
|
||||
return 0;
|
||||
@ -268,7 +284,7 @@ _gpgme_gpg_set_colon_line_handler ( GpgObject gpg,
|
||||
if (!gpg->colon.buffer) {
|
||||
return mk_error (Out_Of_Core);
|
||||
}
|
||||
if (_gpgme_io_pipe (gpg->colon.fd) == -1) {
|
||||
if (_gpgme_io_pipe (gpg->colon.fd, 1) == -1) {
|
||||
xfree (gpg->colon.buffer); gpg->colon.buffer = NULL;
|
||||
return mk_error (Pipe_Error);
|
||||
}
|
||||
@ -294,11 +310,16 @@ free_fd_data_map ( struct fd_data_map_s *fd_data_map )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !fd_data_map )
|
||||
return;
|
||||
|
||||
for (i=0; fd_data_map[i].data; i++ ) {
|
||||
#if 0 /* fixme -> see gpg_release */
|
||||
if ( fd_data_map[i].fd != -1 )
|
||||
_gpgme_io_close (fd_data_map[i].fd);
|
||||
if ( fd_data_map[i].peer_fd != -1 )
|
||||
_gpgme_io_close (fd_data_map[i].peer_fd);
|
||||
#endif
|
||||
/* don't realease data because this is only a reference */
|
||||
}
|
||||
xfree (fd_data_map);
|
||||
@ -330,7 +351,7 @@ build_argv ( GpgObject gpg )
|
||||
if (a->data) {
|
||||
/*fprintf (stderr, "build_argv: data\n" );*/
|
||||
datac++;
|
||||
if ( a->dup_to == -1 )
|
||||
if ( a->dup_to == -1 && !a->print_fd )
|
||||
need_special = 1;
|
||||
}
|
||||
else {
|
||||
@ -403,6 +424,7 @@ build_argv ( GpgObject gpg )
|
||||
free_argv (argv);
|
||||
return mk_error (Invalid_Type);
|
||||
case GPGME_DATA_TYPE_MEM:
|
||||
case GPGME_DATA_TYPE_CB:
|
||||
break;
|
||||
case GPGME_DATA_TYPE_FD:
|
||||
case GPGME_DATA_TYPE_FILE:
|
||||
@ -415,7 +437,8 @@ build_argv ( GpgObject gpg )
|
||||
{
|
||||
int fds[2];
|
||||
|
||||
if (_gpgme_io_pipe (fds) == -1) {
|
||||
if (_gpgme_io_pipe (fds, fd_data_map[datac].inbound?1:0 )
|
||||
== -1) {
|
||||
xfree (fd_data_map);
|
||||
free_argv (argv);
|
||||
return mk_error (Pipe_Error);
|
||||
@ -439,7 +462,9 @@ build_argv ( GpgObject gpg )
|
||||
free_argv (argv);
|
||||
return mk_error (Out_Of_Core);
|
||||
}
|
||||
sprintf ( argv[argc], "-&%d", fd_data_map[datac].peer_fd );
|
||||
sprintf ( argv[argc],
|
||||
a->print_fd? "%d" : "-&%d",
|
||||
fd_data_map[datac].peer_fd );
|
||||
argc++;
|
||||
}
|
||||
datac++;
|
||||
@ -490,7 +515,7 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
|
||||
|
||||
/* build the fd list for the child */
|
||||
n=0;
|
||||
fd_child_list[n].fd = gpg->status.fd[0];
|
||||
fd_child_list[n].fd = gpg->status.fd[0];
|
||||
fd_child_list[n].dup_to = -1;
|
||||
n++;
|
||||
if ( gpg->colon.fnc ) {
|
||||
@ -538,7 +563,6 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
|
||||
fd_parent_list[n].dup_to = -1;
|
||||
|
||||
|
||||
fflush (stderr);
|
||||
pid = _gpgme_io_spawn (GPG_PATH, gpg->argv, fd_child_list, fd_parent_list);
|
||||
xfree (fd_child_list);
|
||||
if (pid == -1) {
|
||||
@ -604,7 +628,6 @@ gpg_inbound_handler ( void *opaque, int pid, int fd )
|
||||
assert ( _gpgme_data_get_mode (dh) == GPGME_DATA_MODE_IN );
|
||||
|
||||
nread = _gpgme_io_read (fd, buf, 200 );
|
||||
fprintf(stderr, "inbound on fd %d: nread=%d\n", fd, nread );
|
||||
if ( nread < 0 ) {
|
||||
fprintf (stderr, "read_mem_data: read failed on fd %d (n=%d): %s\n",
|
||||
fd, nread, strerror (errno) );
|
||||
@ -638,7 +661,6 @@ write_mem_data ( GpgmeData dh, int fd )
|
||||
|
||||
nbytes = dh->len - dh->readpos;
|
||||
if ( !nbytes ) {
|
||||
fprintf (stderr, "write_mem_data(%d): closing\n", fd );
|
||||
_gpgme_io_close (fd);
|
||||
return 1;
|
||||
}
|
||||
@ -650,11 +672,7 @@ write_mem_data ( GpgmeData dh, int fd )
|
||||
* To avoid that we have set the pipe to nonblocking.
|
||||
*/
|
||||
|
||||
|
||||
fprintf (stderr, "write_mem_data(%d): about to write %d bytes len=%d rpos=%d\n",
|
||||
fd, (int)nbytes, (int)dh->len, dh->readpos );
|
||||
nwritten = _gpgme_io_write ( fd, dh->data+dh->readpos, nbytes );
|
||||
fprintf (stderr, "write_mem_data(%d): wrote %d bytes\n", fd, nwritten );
|
||||
if (nwritten == -1 && errno == EAGAIN )
|
||||
return 0;
|
||||
if ( nwritten < 1 ) {
|
||||
@ -668,6 +686,40 @@ write_mem_data ( GpgmeData dh, int fd )
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
write_cb_data ( GpgmeData dh, int fd )
|
||||
{
|
||||
size_t nbytes;
|
||||
int err, nwritten;
|
||||
char buffer[512];
|
||||
|
||||
err = gpgme_data_read ( dh, buffer, DIM(buffer), &nbytes );
|
||||
if (err == GPGME_EOF) {
|
||||
_gpgme_io_close (fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nwritten = _gpgme_io_write ( fd, dh->data+dh->readpos, nbytes );
|
||||
if (nwritten == -1 && errno == EAGAIN )
|
||||
return 0;
|
||||
if ( nwritten < 1 ) {
|
||||
fprintf (stderr, "write_cb_data(%d): write failed (n=%d): %s\n",
|
||||
fd, nwritten, strerror (errno) );
|
||||
_gpgme_io_close (fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( nwritten < nbytes ) {
|
||||
if ( _gpgme_data_unread (dh, buffer + nwritten, nbytes - nwritten ) )
|
||||
fprintf (stderr, "wite_cb_data: unread of %d bytes failed\n",
|
||||
nbytes - nwritten );
|
||||
_gpgme_io_close (fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gpg_outbound_handler ( void *opaque, int pid, int fd )
|
||||
@ -680,11 +732,14 @@ gpg_outbound_handler ( void *opaque, int pid, int fd )
|
||||
if ( write_mem_data ( dh, fd ) )
|
||||
return 1; /* ready */
|
||||
break;
|
||||
case GPGME_DATA_TYPE_CB:
|
||||
if (write_cb_data (dh, fd))
|
||||
return 1; /* ready */
|
||||
break;
|
||||
default:
|
||||
assert (0);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
68
gpgme/status-table.h
Normal file
68
gpgme/status-table.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* Generated automatically by mkstatus */
|
||||
/* Do not edit! */
|
||||
|
||||
struct status_table_s {
|
||||
const char *name;
|
||||
GpgStatusCode code;
|
||||
};
|
||||
|
||||
static struct status_table_s status_table[] =
|
||||
{
|
||||
{ "ABORT", STATUS_ABORT },
|
||||
{ "BADARMOR", STATUS_BADARMOR },
|
||||
{ "BADMDC", STATUS_BADMDC },
|
||||
{ "BADSIG", STATUS_BADSIG },
|
||||
{ "BAD_PASSPHRASE", STATUS_BAD_PASSPHRASE },
|
||||
{ "BEGIN_DECRYPTION", STATUS_BEGIN_DECRYPTION },
|
||||
{ "BEGIN_ENCRYPTION", STATUS_BEGIN_ENCRYPTION },
|
||||
{ "DECRYPTION_FAILED", STATUS_DECRYPTION_FAILED },
|
||||
{ "DECRYPTION_OKAY", STATUS_DECRYPTION_OKAY },
|
||||
{ "DELETE_PROBLEM", STATUS_DELETE_PROBLEM },
|
||||
{ "ENC_TO", STATUS_ENC_TO },
|
||||
{ "END_DECRYPTION", STATUS_END_DECRYPTION },
|
||||
{ "END_ENCRYPTION", STATUS_END_ENCRYPTION },
|
||||
{ "ENTER", STATUS_ENTER },
|
||||
{ "ERRMDC", STATUS_ERRMDC },
|
||||
{ "ERRSIG", STATUS_ERRSIG },
|
||||
{ "FILE_DONE", STATUS_FILE_DONE },
|
||||
{ "FILE_ERROR", STATUS_FILE_ERROR },
|
||||
{ "FILE_START", STATUS_FILE_START },
|
||||
{ "GET_BOOL", STATUS_GET_BOOL },
|
||||
{ "GET_HIDDEN", STATUS_GET_HIDDEN },
|
||||
{ "GET_LINE", STATUS_GET_LINE },
|
||||
{ "GOODMDC", STATUS_GOODMDC },
|
||||
{ "GOODSIG", STATUS_GOODSIG },
|
||||
{ "GOOD_PASSPHRASE", STATUS_GOOD_PASSPHRASE },
|
||||
{ "GOT_IT", STATUS_GOT_IT },
|
||||
{ "IMPORTED", STATUS_IMPORTED },
|
||||
{ "IMPORT_RES", STATUS_IMPORT_RES },
|
||||
{ "KEYREVOKED", STATUS_KEYREVOKED },
|
||||
{ "LEAVE", STATUS_LEAVE },
|
||||
{ "MISSING_PASSPHRASE", STATUS_MISSING_PASSPHRASE },
|
||||
{ "NEED_PASSPHRASE", STATUS_NEED_PASSPHRASE },
|
||||
{ "NEED_PASSPHRASE_SYM,", STATUS_NEED_PASSPHRASE_SYM, },
|
||||
{ "NODATA", STATUS_NODATA },
|
||||
{ "NOTATION_DATA", STATUS_NOTATION_DATA },
|
||||
{ "NOTATION_NAME", STATUS_NOTATION_NAME },
|
||||
{ "NO_PUBKEY", STATUS_NO_PUBKEY },
|
||||
{ "NO_SECKEY", STATUS_NO_SECKEY },
|
||||
{ "POLICY_URL", STATUS_POLICY_URL },
|
||||
{ "PROGRESS", STATUS_PROGRESS },
|
||||
{ "RSA_OR_IDEA", STATUS_RSA_OR_IDEA },
|
||||
{ "SESSION_KEY", STATUS_SESSION_KEY },
|
||||
{ "SHM_GET", STATUS_SHM_GET },
|
||||
{ "SHM_GET_BOOL", STATUS_SHM_GET_BOOL },
|
||||
{ "SHM_GET_HIDDEN", STATUS_SHM_GET_HIDDEN },
|
||||
{ "SHM_INFO", STATUS_SHM_INFO },
|
||||
{ "SIGEXPIRED", STATUS_SIGEXPIRED },
|
||||
{ "SIG_CREATED", STATUS_SIG_CREATED },
|
||||
{ "SIG_ID", STATUS_SIG_ID },
|
||||
{ "TRUST_FULLY", STATUS_TRUST_FULLY },
|
||||
{ "TRUST_MARGINAL", STATUS_TRUST_MARGINAL },
|
||||
{ "TRUST_NEVER", STATUS_TRUST_NEVER },
|
||||
{ "TRUST_ULTIMATE", STATUS_TRUST_ULTIMATE },
|
||||
{ "TRUST_UNDEFINED", STATUS_TRUST_UNDEFINED },
|
||||
{ "VALIDSIG", STATUS_VALIDSIG },
|
||||
{NULL, 0}
|
||||
};
|
||||
|
@ -163,7 +163,6 @@ gpgme_op_verify_start ( GpgmeCtx c, GpgmeData sig, GpgmeData text )
|
||||
_gpgme_gpg_add_arg ( c->gpg, "--verify" );
|
||||
for ( i=0; i < c->verbosity; i++ )
|
||||
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
|
||||
|
||||
|
||||
/* Check the supplied data */
|
||||
if ( gpgme_data_get_type (sig) == GPGME_DATA_TYPE_NONE ) {
|
||||
@ -180,8 +179,10 @@ gpgme_op_verify_start ( GpgmeCtx c, GpgmeData sig, GpgmeData text )
|
||||
/* Tell the gpg object about the data */
|
||||
_gpgme_gpg_add_arg ( c->gpg, "--" );
|
||||
_gpgme_gpg_add_data ( c->gpg, sig, -1 );
|
||||
if (text)
|
||||
if (text) {
|
||||
_gpgme_gpg_add_arg ( c->gpg, "-" );
|
||||
_gpgme_gpg_add_data ( c->gpg, text, 0 );
|
||||
}
|
||||
|
||||
/* and kick off the process */
|
||||
rc = _gpgme_gpg_spawn ( c->gpg, c );
|
||||
|
104
gpgme/version.c
Normal file
104
gpgme/version.c
Normal file
@ -0,0 +1,104 @@
|
||||
/* version.c - version check
|
||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
||||
*
|
||||
* This file is part of GPGME.
|
||||
*
|
||||
* GPGME 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.
|
||||
*
|
||||
* GPGME 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "gpgme.h"
|
||||
|
||||
static const char*
|
||||
parse_version_number ( const char *s, int *number )
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
if ( *s == '0' && isdigit(s[1]) )
|
||||
return NULL; /* leading zeros are not allowed */
|
||||
for ( ; isdigit(*s); s++ ) {
|
||||
val *= 10;
|
||||
val += *s - '0';
|
||||
}
|
||||
*number = val;
|
||||
return val < 0? NULL : s;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
parse_version_string( const char *s, int *major, int *minor, int *micro )
|
||||
{
|
||||
s = parse_version_number ( s, major );
|
||||
if ( !s || *s != '.' )
|
||||
return NULL;
|
||||
s++;
|
||||
s = parse_version_number ( s, minor );
|
||||
if ( !s || *s != '.' )
|
||||
return NULL;
|
||||
s++;
|
||||
s = parse_version_number ( s, micro );
|
||||
if ( !s )
|
||||
return NULL;
|
||||
return s; /* patchlevel */
|
||||
}
|
||||
|
||||
/**
|
||||
* gpgme_check_version:
|
||||
* @req_version: A string with a version
|
||||
*
|
||||
* Check that the the version of the library is at minimum the requested one
|
||||
* and return the version string; return NULL if the condition is not
|
||||
* met. If a NULL is passed to this function, no check is done and
|
||||
* the version string is simply returned.
|
||||
*
|
||||
* Return value: The version string or NULL
|
||||
**/
|
||||
const char *
|
||||
gpgme_check_version ( const char *req_version )
|
||||
{
|
||||
const char *ver = VERSION;
|
||||
int my_major, my_minor, my_micro;
|
||||
int rq_major, rq_minor, rq_micro;
|
||||
const char *my_plvl, *rq_plvl;
|
||||
|
||||
if ( !req_version )
|
||||
return ver;
|
||||
|
||||
my_plvl = parse_version_string ( ver, &my_major, &my_minor, &my_micro );
|
||||
if ( !my_plvl )
|
||||
return NULL; /* very strange: our own version is bogus */
|
||||
rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
|
||||
&rq_micro );
|
||||
if ( !rq_plvl )
|
||||
return NULL; /* req version string is invalid */
|
||||
|
||||
if ( my_major > rq_major
|
||||
|| (my_major == rq_major && my_minor > rq_minor)
|
||||
|| (my_major == rq_major && my_minor == rq_minor
|
||||
&& my_micro > rq_micro)
|
||||
|| (my_major == rq_major && my_minor == rq_minor
|
||||
&& my_micro == rq_micro
|
||||
&& strcmp( my_plvl, rq_plvl ) >= 0) ) {
|
||||
return ver;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
361
gpgme/w32-io.c
361
gpgme/w32-io.c
@ -36,7 +36,7 @@
|
||||
#include "util.h"
|
||||
#include "io.h"
|
||||
|
||||
#define DEBUG_SELECT_ENABLED 1
|
||||
#define DEBUG_SELECT_ENABLED 0
|
||||
|
||||
#if DEBUG_SELECT_ENABLED
|
||||
# define DEBUG_SELECT(a) fprintf a
|
||||
@ -47,7 +47,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* We assume that a HANDLE can be represented by an int which should be true
|
||||
* 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
|
||||
* systems for which Windows is available.
|
||||
* Further we assume that -1 denotes an invalid handle.
|
||||
@ -65,10 +65,12 @@ _gpgme_io_read ( int fd, void *buffer, size_t count )
|
||||
int nread = 0;
|
||||
HANDLE h = fd_to_handle (fd);
|
||||
|
||||
DEBUG_SELECT ((stderr,"** fd %d: about to read %d bytes\n", fd, (int)count ));
|
||||
if ( !ReadFile ( h, buffer, count, &nread, NULL) ) {
|
||||
fprintf (stderr, "** ReadFile failed: ec=%d\n", (int)GetLastError ());
|
||||
return -1;
|
||||
}
|
||||
DEBUG_SELECT ((stderr,"** fd %d: got %d bytes\n", fd, nread ));
|
||||
|
||||
return nread;
|
||||
}
|
||||
@ -80,23 +82,62 @@ _gpgme_io_write ( int fd, const void *buffer, size_t count )
|
||||
int nwritten;
|
||||
HANDLE h = fd_to_handle (fd);
|
||||
|
||||
DEBUG_SELECT ((stderr,"** fd %d: about to write %d bytes\n", fd, (int)count ));
|
||||
if ( !WriteFile ( h, buffer, count, &nwritten, NULL) ) {
|
||||
fprintf (stderr, "** WriteFile failed: ec=%d\n", (int)GetLastError ());
|
||||
return -1;
|
||||
}
|
||||
DEBUG_SELECT ((stderr,"** fd %d: wrote %d bytes\n", fd, nwritten ));
|
||||
|
||||
return nwritten;
|
||||
}
|
||||
|
||||
int
|
||||
_gpgme_io_pipe ( int filedes[2] )
|
||||
_gpgme_io_pipe ( int filedes[2], int inherit_idx )
|
||||
{
|
||||
HANDLE r, w;
|
||||
SECURITY_ATTRIBUTES sec_attr;
|
||||
|
||||
memset (&sec_attr, 0, sizeof sec_attr );
|
||||
sec_attr.nLength = sizeof sec_attr;
|
||||
sec_attr.bInheritHandle = FALSE;
|
||||
|
||||
if (!CreatePipe ( &r, &w, NULL, 0))
|
||||
if (!CreatePipe ( &r, &w, &sec_attr, 0))
|
||||
return -1;
|
||||
/* make one end inheritable */
|
||||
if ( inherit_idx == 0 ) {
|
||||
HANDLE h;
|
||||
if (!DuplicateHandle( GetCurrentProcess(), r,
|
||||
GetCurrentProcess(), &h, 0,
|
||||
TRUE, DUPLICATE_SAME_ACCESS ) ) {
|
||||
fprintf (stderr, "** DuplicateHandle failed: ec=%d\n",
|
||||
(int)GetLastError());
|
||||
CloseHandle (r);
|
||||
CloseHandle (w);
|
||||
return -1;
|
||||
}
|
||||
CloseHandle (r);
|
||||
r = h;
|
||||
}
|
||||
else if ( inherit_idx == 1 ) {
|
||||
HANDLE h;
|
||||
if (!DuplicateHandle( GetCurrentProcess(), w,
|
||||
GetCurrentProcess(), &h, 0,
|
||||
TRUE, DUPLICATE_SAME_ACCESS ) ) {
|
||||
fprintf (stderr, "** DuplicateHandle failed: ec=%d\n",
|
||||
(int)GetLastError());
|
||||
CloseHandle (r);
|
||||
CloseHandle (w);
|
||||
return -1;
|
||||
}
|
||||
CloseHandle (w);
|
||||
w = h;
|
||||
}
|
||||
|
||||
filedes[0] = handle_to_fd (r);
|
||||
filedes[1] = handle_to_fd (w);
|
||||
DEBUG_SELECT ((stderr,"** create pipe %p %p %d %d inherit=%d\n", r, w,
|
||||
filedes[0], filedes[1], inherit_idx ));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -105,7 +146,15 @@ _gpgme_io_close ( int fd )
|
||||
{
|
||||
if ( fd == -1 )
|
||||
return -1;
|
||||
return CloseHandle (fd_to_handle(fd)) ? 0 : -1;
|
||||
|
||||
DEBUG_SELECT ((stderr,"** closing handle for fd %d\n", fd));
|
||||
if ( !CloseHandle (fd_to_handle (fd)) ) {
|
||||
fprintf (stderr, "** CloseHandle for fd %d failed: ec=%d\n",
|
||||
fd, (int)GetLastError ());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -126,12 +175,13 @@ build_commandline ( char **argv )
|
||||
* program parses the commandline and does some unquoting */
|
||||
for (i=0; argv[i]; i++)
|
||||
n += strlen (argv[i]) + 1;
|
||||
n += 5; /* "gpg " */
|
||||
buf = p = xtrymalloc (n);
|
||||
if ( !buf )
|
||||
return NULL;
|
||||
p = stpcpy (p, "gpg");
|
||||
for (i = 0; argv[i]; i++)
|
||||
*buf = 0;
|
||||
if ( argv[0] )
|
||||
p = stpcpy (p, argv[0]);
|
||||
for (i = 1; argv[i]; i++)
|
||||
p = stpcpy (stpcpy (p, " "), argv[i]);
|
||||
|
||||
return buf;
|
||||
@ -150,46 +200,84 @@ _gpgme_io_spawn ( const char *path, char **argv,
|
||||
0, /* returns pid */
|
||||
0 /* returns tid */
|
||||
};
|
||||
STARTUPINFO si = {
|
||||
0, NULL, NULL, NULL,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
STARTUPINFO si;
|
||||
char *envblock = NULL;
|
||||
int cr_flags = CREATE_DEFAULT_ERROR_MODE
|
||||
| GetPriorityClass (GetCurrentProcess ());
|
||||
int i, rc;
|
||||
int i;
|
||||
char *arg_string;
|
||||
HANDLE save_stdout;
|
||||
HANDLE outputfd[2], statusfd[2], inputfd[2];
|
||||
int duped_stdin = 0;
|
||||
int duped_stderr = 0;
|
||||
HANDLE hnul = INVALID_HANDLE_VALUE;
|
||||
|
||||
sec_attr.nLength = sizeof (sec_attr);
|
||||
memset (&sec_attr, 0, sizeof sec_attr );
|
||||
sec_attr.nLength = sizeof sec_attr;
|
||||
sec_attr.bInheritHandle = FALSE;
|
||||
sec_attr.lpSecurityDescriptor = NULL;
|
||||
|
||||
|
||||
arg_string = build_commandline ( argv );
|
||||
if (!arg_string )
|
||||
return -1;
|
||||
|
||||
memset (&si, 0, sizeof si);
|
||||
si.cb = sizeof (si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
|
||||
si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||
si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
|
||||
if (!SetHandleInformation (si.hStdOutput,
|
||||
HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
|
||||
fprintf (stderr, "** SHI 1 failed: ec=%d\n", (int) GetLastError ());
|
||||
}
|
||||
if (!SetHandleInformation (si.hStdError,
|
||||
HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
|
||||
fprintf (stderr, "** SHI 2 failed: ec=%d\n", (int) GetLastError ());
|
||||
}
|
||||
|
||||
|
||||
fputs ("** CreateProcess ...\n", stderr);
|
||||
fprintf (stderr, "** args=`%s'\n", arg_string);
|
||||
fflush (stderr);
|
||||
for (i=0; fd_child_list[i].fd != -1; i++ ) {
|
||||
if (fd_child_list[i].dup_to == 0 ) {
|
||||
si.hStdInput = fd_to_handle (fd_child_list[i].fd);
|
||||
DEBUG_SELECT ((stderr,"** using %d for stdin\n", fd_child_list[i].fd ));
|
||||
duped_stdin=1;
|
||||
}
|
||||
else if (fd_child_list[i].dup_to == 1 ) {
|
||||
si.hStdOutput = fd_to_handle (fd_child_list[i].fd);
|
||||
DEBUG_SELECT ((stderr,"** using %d for stdout\n", fd_child_list[i].fd ));
|
||||
}
|
||||
else if (fd_child_list[i].dup_to == 2 ) {
|
||||
si.hStdError = fd_to_handle (fd_child_list[i].fd);
|
||||
DEBUG_SELECT ((stderr,"** using %d for stderr\n", fd_child_list[i].fd ));
|
||||
duped_stderr = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if( !duped_stdin || !duped_stderr ) {
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
|
||||
memset (&sa, 0, sizeof sa );
|
||||
sa.nLength = sizeof sa;
|
||||
sa.bInheritHandle = TRUE;
|
||||
hnul = CreateFile ( "/dev/nul",
|
||||
GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
&sa,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL );
|
||||
if ( hnul == INVALID_HANDLE_VALUE ) {
|
||||
fprintf (stderr,"can't open `/dev/nul': ec=%d\n",
|
||||
(int)GetLastError () );
|
||||
xfree (arg_string);
|
||||
return -1;
|
||||
}
|
||||
/* Make sure that the process has a connected stdin */
|
||||
if ( !duped_stdin ) {
|
||||
si.hStdInput = hnul;
|
||||
DEBUG_SELECT ((stderr,"** using %d for stdin\n", (int)hnul ));
|
||||
}
|
||||
/* We normally don't want all the normal output */
|
||||
if ( !duped_stderr ) {
|
||||
if (!getenv ("GPGME_DEBUG") ) {
|
||||
si.hStdError = hnul;
|
||||
DEBUG_SELECT ((stderr,"** using %d for stderr\n", (int)hnul ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_SELECT ((stderr,"** CreateProcess ...\n"));
|
||||
DEBUG_SELECT ((stderr,"** args=`%s'\n", arg_string));
|
||||
cr_flags |= CREATE_SUSPENDED;
|
||||
if ( !CreateProcessA (GPG_PATH,
|
||||
arg_string,
|
||||
&sec_attr, /* process security attributes */
|
||||
@ -203,27 +291,47 @@ _gpgme_io_spawn ( const char *path, char **argv,
|
||||
) ) {
|
||||
fprintf (stderr, "** CreateProcess failed: ec=%d\n",
|
||||
(int) GetLastError ());
|
||||
fflush (stderr);
|
||||
xfree (arg_string);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* .dup_to is not used in the parent list */
|
||||
for (i=0; fd_parent_list[i].fd != -1; i++ ) {
|
||||
CloseHandle ( fd_to_handle (fd_parent_list[i].fd) );
|
||||
/* close the /dev/nul handle if used */
|
||||
if (hnul != INVALID_HANDLE_VALUE ) {
|
||||
if ( !CloseHandle ( hnul ) )
|
||||
fprintf (stderr, "** CloseHandle(hnul) failed: ec=%d\n",
|
||||
(int)GetLastError());
|
||||
}
|
||||
|
||||
fprintf (stderr, "** CreateProcess ready\n");
|
||||
fprintf (stderr, "** hProcess=%p hThread=%p\n",
|
||||
pi.hProcess, pi.hThread);
|
||||
fprintf (stderr, "** dwProcessID=%d dwThreadId=%d\n",
|
||||
(int) pi.dwProcessId, (int) pi.dwThreadId);
|
||||
fflush (stderr);
|
||||
/* Close the other ends of the pipes */
|
||||
for (i=0; fd_parent_list[i].fd != -1; i++ ) {
|
||||
DEBUG_SELECT ((stderr,"** Closing fd %d\n", fd_parent_list[i].fd ));
|
||||
if ( !CloseHandle ( fd_to_handle (fd_parent_list[i].fd) ) )
|
||||
fprintf (stderr, "** CloseHandle failed: ec=%d\n",
|
||||
(int)GetLastError());
|
||||
}
|
||||
|
||||
DEBUG_SELECT ((stderr,"** CreateProcess ready\n"
|
||||
"** hProcess=%p hThread=%p\n"
|
||||
"** dwProcessID=%d dwThreadId=%d\n",
|
||||
pi.hProcess, pi.hThread,
|
||||
(int) pi.dwProcessId, (int) pi.dwThreadId));
|
||||
|
||||
if ( ResumeThread ( pi.hThread ) < 0 ) {
|
||||
fprintf (stderr, "** ResumeThread failed: ec=%d\n",
|
||||
(int)GetLastError ());
|
||||
}
|
||||
|
||||
if ( !CloseHandle (pi.hThread) ) {
|
||||
fprintf (stderr, "** CloseHandle of thread failed: ec=%d\n",
|
||||
(int)GetLastError ());
|
||||
}
|
||||
|
||||
return handle_to_pid (pi.hProcess);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
_gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal )
|
||||
{
|
||||
@ -246,15 +354,15 @@ _gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal )
|
||||
*r_status = 4;
|
||||
}
|
||||
else {
|
||||
fprintf (stderr, "** GECP pid=%d exit code=%d\n",
|
||||
(int)pid, exc);
|
||||
DEBUG_SELECT ((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);
|
||||
DEBUG_SELECT ((stderr,"** WFSO pid=%d timed out\n", (int)pid));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -274,24 +382,28 @@ _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 )
|
||||
{
|
||||
#if 0 /* We can't use WFMO becaus a pipe handle is not a suitable object */
|
||||
HANDLE waitbuf[MAXIMUM_WAIT_OBJECTS];
|
||||
int code, nwait;
|
||||
int i, any, ret;
|
||||
int i, any, any_write;
|
||||
int count;
|
||||
|
||||
restart:
|
||||
DEBUG_SELECT ((stderr, "gpgme:select on [ "));
|
||||
any = 0;
|
||||
any = any_write = 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" ));
|
||||
DEBUG_SELECT ((stderr,stderr, "oops ]\n" ));
|
||||
fprintf (stderr, "** Too many objects for WFMO!\n" );
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
waitbuf[nwait++] = fd_to_handle (fds[i].fd);
|
||||
if ( fds[i].for_read )
|
||||
waitbuf[nwait++] = fd_to_handle (fds[i].fd);
|
||||
DEBUG_SELECT ((stderr, "%c%d ",
|
||||
fds[i].for_read? 'r':'w',fds[i].fd ));
|
||||
any = 1;
|
||||
@ -300,14 +412,73 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
|
||||
fds[i].signaled = 0;
|
||||
}
|
||||
DEBUG_SELECT ((stderr, "]\n" ));
|
||||
if (!any)
|
||||
if (!any)
|
||||
return 0;
|
||||
|
||||
ret = 0;
|
||||
code = WaitForMultipleObjects ( nwait, waitbuf, 0, 1000 );
|
||||
count = 0;
|
||||
for ( i=0; i < nfds; i++ ) {
|
||||
if ( fds[i].fd == -1 )
|
||||
continue;
|
||||
if ( fds[i].for_write ) {
|
||||
fds[i].signaled = 1;
|
||||
any_write =1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
code = WaitForMultipleObjects ( nwait, waitbuf, 0, any_write? 0:1000);
|
||||
if (code == WAIT_FAILED ) {
|
||||
fprintf (stderr, "** WFMO failed: %d\n", (int)GetLastError () );
|
||||
ret = -1;
|
||||
int le = (int)GetLastError ();
|
||||
if ( le == ERROR_INVALID_HANDLE || le == ERROR_INVALID_EVENT_COUNT ) {
|
||||
any = 0;
|
||||
for ( i=0; i < nfds; i++ ) {
|
||||
if ( fds[i].fd == -1 )
|
||||
continue;
|
||||
if ( fds[i].for_read /*|| fds[i].for_write*/ ) {
|
||||
int navail;
|
||||
if (PeekNamedPipe (fd_to_handle (fds[i].fd),
|
||||
NULL, 0, NULL,
|
||||
&navail, NULL) && navail ) {
|
||||
fds[i].signaled = 1;
|
||||
any = 1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (any)
|
||||
return count;
|
||||
/* find that handle and remove it from the list*/
|
||||
for (i=0; i < nwait; i++ ) {
|
||||
code = WaitForSingleObject ( waitbuf[i], NULL );
|
||||
if (!code) {
|
||||
int k, j = handle_to_fd (waitbuf[i]);
|
||||
|
||||
fprintf (stderr, "** handle meanwhile signaled %d\n", j);
|
||||
for (k=0 ; k < nfds; k++ ) {
|
||||
if ( fds[k].fd == j ) {
|
||||
fds[k].signaled = 1;
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
}
|
||||
fprintf (stderr, "** oops, or not???\n");
|
||||
}
|
||||
if ( GetLastError () == ERROR_INVALID_HANDLE) {
|
||||
int k, j = handle_to_fd (waitbuf[i]);
|
||||
|
||||
fprintf (stderr, "** WFMO invalid handle %d removed\n", j);
|
||||
for (k=0 ; k < nfds; i++ ) {
|
||||
if ( fds[k].fd == j ) {
|
||||
fds[k].for_read = fds[k].for_write = 0;
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
fprintf (stderr, "** oops, or not???\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf (stderr, "** WFMO failed: %d\n", le );
|
||||
count = -1;
|
||||
}
|
||||
else if ( code == WAIT_TIMEOUT ) {
|
||||
fprintf (stderr, "** WFMO timed out\n" );
|
||||
@ -326,22 +497,94 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
|
||||
if (WaitForSingleObject ( waitbuf[i], NULL ) == WAIT_OBJECT_0) {
|
||||
fds[i].signaled = 1;
|
||||
any = 1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (any)
|
||||
ret = 1;
|
||||
else {
|
||||
if (!any) {
|
||||
fprintf (stderr,
|
||||
"** Oops: No signaled objects found after WFMO\n");
|
||||
ret = -1;
|
||||
count = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf (stderr, "** WFMO returned %d\n", code );
|
||||
ret = -1;
|
||||
count = -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return count;
|
||||
#else /* This is the code we use */
|
||||
int i, any, count;
|
||||
int once_more = 0;
|
||||
|
||||
DEBUG_SELECT ((stderr, "gpgme:fakedselect on [ "));
|
||||
any = 0;
|
||||
for ( i=0; i < nfds; i++ ) {
|
||||
if ( fds[i].fd == -1 )
|
||||
continue;
|
||||
if ( fds[i].for_read || fds[i].for_write ) {
|
||||
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;
|
||||
|
||||
restart:
|
||||
count = 0;
|
||||
/* no way to see whether a handle is ready fro writing, signal all */
|
||||
for ( i=0; i < nfds; i++ ) {
|
||||
if ( fds[i].fd == -1 )
|
||||
continue;
|
||||
if ( fds[i].for_write ) {
|
||||
fds[i].signaled = 1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* now peek on all read handles */
|
||||
for ( i=0; i < nfds; i++ ) {
|
||||
if ( fds[i].fd == -1 )
|
||||
continue;
|
||||
if ( fds[i].for_read ) {
|
||||
int navail;
|
||||
|
||||
if ( !PeekNamedPipe (fd_to_handle (fds[i].fd),
|
||||
NULL, 0, NULL, &navail, NULL) ) {
|
||||
fprintf (stderr, "** select: PeekFile failed: ec=%d\n",
|
||||
(int)GetLastError ());
|
||||
}
|
||||
else if ( navail ) {
|
||||
fprintf (stderr, "** fd %d has %d bytes to read\n",
|
||||
fds[i].fd, navail );
|
||||
fds[i].signaled = 1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !once_more && !count ) {
|
||||
once_more = 1;
|
||||
Sleep (300);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if ( count ) {
|
||||
DEBUG_SELECT ((stderr, "gpgme: signaled [ "));
|
||||
for ( i=0; i < nfds; i++ ) {
|
||||
if ( fds[i].fd == -1 )
|
||||
continue;
|
||||
if ( (fds[i].for_read || fds[i].for_write) && fds[i].signaled ) {
|
||||
DEBUG_SELECT ((stderr, "%c%d ",
|
||||
fds[i].for_read? 'r':'w',fds[i].fd ));
|
||||
}
|
||||
}
|
||||
DEBUG_SELECT ((stderr, "]\n" ));
|
||||
}
|
||||
|
||||
return count;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /*HAVE_DOSISH_SYSTEM*/
|
||||
|
37
gpgme/wait.c
37
gpgme/wait.c
@ -111,6 +111,19 @@ count_active_fds ( int pid )
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_active_fds ( int pid )
|
||||
{
|
||||
struct wait_item_s *q;
|
||||
int i;
|
||||
|
||||
for (i=0; i < fd_table_size; i++ ) {
|
||||
if ( fd_table[i].fd != -1 && (q=fd_table[i].opaque)
|
||||
&& q->active && q->pid == pid )
|
||||
q->active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* remove the given process from the queue */
|
||||
static void
|
||||
@ -123,7 +136,11 @@ remove_process ( int pid )
|
||||
if (fd_table[i].fd != -1 && (q=fd_table[i].opaque) && q->pid == pid ) {
|
||||
xfree (q);
|
||||
fd_table[i].opaque = NULL;
|
||||
_gpgme_io_close (fd_table[i].fd);
|
||||
|
||||
if ( !fd_table[i].is_closed ) {
|
||||
_gpgme_io_close (fd_table[i].fd);
|
||||
fd_table[i].is_closed = 1;
|
||||
}
|
||||
fd_table[i].fd = -1;
|
||||
}
|
||||
}
|
||||
@ -168,8 +185,13 @@ _gpgme_wait_on_condition ( GpgmeCtx c, int hang, volatile int *cond )
|
||||
q = queue_item_from_context ( c );
|
||||
assert (q);
|
||||
|
||||
if (q->exited)
|
||||
;
|
||||
if (q->exited) {
|
||||
/* this is the second time we reached this and we got no
|
||||
* more data from the pipe (which may happen to to buffering).
|
||||
* Set all FDs inactive.
|
||||
*/
|
||||
clear_active_fds (q->pid);
|
||||
}
|
||||
else if ( _gpgme_io_waitpid (q->pid, 0,
|
||||
&q->exit_status, &q->exit_signal)){
|
||||
q->exited = 1;
|
||||
@ -207,26 +229,30 @@ do_select ( void )
|
||||
{
|
||||
struct wait_item_s *q;
|
||||
int i, n;
|
||||
int any=0;
|
||||
|
||||
n = _gpgme_io_select ( fd_table, fd_table_size );
|
||||
if ( n <= 0 )
|
||||
return 0; /* error or timeout */
|
||||
|
||||
for (i=0; i < fd_table_size && n; i++ ) {
|
||||
for (i=0; i < fd_table_size /*&& n*/; i++ ) {
|
||||
if ( fd_table[i].fd != -1 && fd_table[i].signaled ) {
|
||||
q = fd_table[i].opaque;
|
||||
assert (n);
|
||||
n--;
|
||||
if ( q->active )
|
||||
any = 1;
|
||||
if ( q->active && q->handler (q->handler_value,
|
||||
q->pid, fd_table[i].fd ) ) {
|
||||
q->active = 0;
|
||||
fd_table[i].for_read = 0;
|
||||
fd_table[i].for_write = 0;
|
||||
fd_table[i].is_closed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return any;
|
||||
}
|
||||
|
||||
|
||||
@ -262,6 +288,7 @@ _gpgme_register_pipe_handler( void *opaque,
|
||||
for (i=0; i < fd_table_size; i++ ) {
|
||||
if ( fd_table[i].fd == -1 ) {
|
||||
fd_table[i].fd = fd;
|
||||
fd_table[i].is_closed = 0;
|
||||
fd_table[i].for_read = inbound;
|
||||
fd_table[i].for_write = !inbound;
|
||||
fd_table[i].signaled = 0;
|
||||
|
@ -26,6 +26,12 @@
|
||||
|
||||
#include "../gpgme/gpgme.h"
|
||||
|
||||
struct passphrase_cb_info_s {
|
||||
GpgmeCtx c;
|
||||
int did_it;
|
||||
};
|
||||
|
||||
|
||||
#define fail_if_err(a) do { if(a) { int my_errno = errno; \
|
||||
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
|
||||
__FILE__, __LINE__, gpgme_strerror(a)); \
|
||||
@ -50,17 +56,31 @@ print_data ( GpgmeData dh )
|
||||
fail_if_err (err);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static GpgmeData
|
||||
passphrase_cb ( void *opaque, const char *description )
|
||||
{
|
||||
GpgmeData dh;
|
||||
|
||||
assert (NULL);
|
||||
gpgme_data_new_from_mem ( &dh, "abc", 3, 0 );
|
||||
return dh;
|
||||
static int
|
||||
passphrase_cb ( void *opaque, char *buffer, size_t length, size_t *nread )
|
||||
{
|
||||
struct passphrase_cb_info_s *info = opaque;
|
||||
const char *desc;
|
||||
|
||||
assert (info);
|
||||
assert (info->c);
|
||||
if ( !buffer || !length || !nread )
|
||||
return 0; /* those values are reserved for extensions */
|
||||
if ( info->did_it )
|
||||
return -1; /* eof */
|
||||
|
||||
desc = gpgme_get_prompt (info->c, 1);
|
||||
if (desc)
|
||||
fprintf (stderr, "Request passphrase for '%s'\n", desc );
|
||||
if ( length < 3 )
|
||||
return -1; /* FIXME - sending an EOF here is wrong */
|
||||
memcpy (buffer, "abc", 3 );
|
||||
*nread = 3;
|
||||
info->did_it = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static char *
|
||||
mk_fname ( const char *fname )
|
||||
@ -84,17 +104,18 @@ main (int argc, char **argv )
|
||||
{
|
||||
GpgmeCtx ctx;
|
||||
GpgmeError err;
|
||||
GpgmeData in, out;
|
||||
GpgmeData in, out, pwdata = NULL;
|
||||
struct passphrase_cb_info_s info;
|
||||
const char *cipher_1_asc = mk_fname ("cipher-1.asc");
|
||||
|
||||
do {
|
||||
err = gpgme_new (&ctx);
|
||||
fail_if_err (err);
|
||||
#if 0
|
||||
if ( !getenv("GPG_AGENT_INFO") {
|
||||
gpgme_set_passphrase_cb ( ctx, passphrase_cb, NULL );
|
||||
if ( 0 && !getenv("GPG_AGENT_INFO") ) {
|
||||
memset ( &info, 0, sizeof info );
|
||||
info.c = ctx;
|
||||
gpgme_data_new_with_read_cb ( &pwdata, passphrase_cb, &info );
|
||||
}
|
||||
#endif
|
||||
|
||||
err = gpgme_data_new_from_file ( &in, cipher_1_asc, 1 );
|
||||
fail_if_err (err);
|
||||
@ -102,7 +123,7 @@ main (int argc, char **argv )
|
||||
err = gpgme_data_new ( &out );
|
||||
fail_if_err (err);
|
||||
|
||||
err = gpgme_op_decrypt (ctx, in, out );
|
||||
err = gpgme_op_decrypt (ctx, pwdata, in, out );
|
||||
fail_if_err (err);
|
||||
|
||||
fflush (NULL);
|
||||
@ -112,6 +133,7 @@ main (int argc, char **argv )
|
||||
|
||||
gpgme_data_release (in);
|
||||
gpgme_data_release (out);
|
||||
gpgme_data_release (pwdata);
|
||||
gpgme_release (ctx);
|
||||
} while ( argc > 1 && !strcmp( argv[1], "--loop" ) );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user