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 */
|
/* path to the gpg binary */
|
||||||
#undef GPG_PATH
|
#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@
|
@BOTTOM@
|
||||||
|
|
||||||
/* not yet needed #include "gpgme-defs.h"*/
|
/* not yet needed #include "gpgme-defs.h"*/
|
||||||
|
17
acinclude.m4
17
acinclude.m4
@ -21,6 +21,23 @@ AC_DEFUN(GNUPG_FIX_HDR_VERSION,
|
|||||||
fi
|
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.
|
# AGE, set REVISION to 0.
|
||||||
# 3. Interfaces removed (BAD, breaks upward compatibility): Increment
|
# 3. Interfaces removed (BAD, breaks upward compatibility): Increment
|
||||||
# CURRENT, set AGE and REVISION to 0.
|
# 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_CURRENT=0
|
||||||
LIBGPGME_LT_AGE=0
|
LIBGPGME_LT_AGE=0
|
||||||
LIBGPGME_LT_REVISION=2
|
LIBGPGME_LT_REVISION=3
|
||||||
##############################################
|
##############################################
|
||||||
|
|
||||||
AC_SUBST(LIBGPGME_LT_CURRENT)
|
AC_SUBST(LIBGPGME_LT_CURRENT)
|
||||||
@ -38,6 +38,7 @@ if test "$GCC" = yes; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
GPG=
|
GPG=
|
||||||
|
component_system=None
|
||||||
case "${target}" in
|
case "${target}" in
|
||||||
*-*-mingw32* | i?86-emx-os2 | i?86-*-os2*emx | i?86-*-msdosdjgpp* )
|
*-*-mingw32* | i?86-emx-os2 | i?86-*-os2*emx | i?86-*-msdosdjgpp* )
|
||||||
# special stuff for Windoze NT
|
# special stuff for Windoze NT
|
||||||
@ -46,6 +47,7 @@ case "${target}" in
|
|||||||
AC_DEFINE(HAVE_DRIVE_LETTERS)
|
AC_DEFINE(HAVE_DRIVE_LETTERS)
|
||||||
AC_DEFINE(HAVE_DOSISH_SYSTEM)
|
AC_DEFINE(HAVE_DOSISH_SYSTEM)
|
||||||
GPG='c:\\gnupg\\gpg.exe'
|
GPG='c:\\gnupg\\gpg.exe'
|
||||||
|
component_system='COM+'
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
;;
|
;;
|
||||||
@ -63,9 +65,27 @@ dnl Checks for header files
|
|||||||
dnl
|
dnl
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl Checks for typedefs and structures
|
dnl Checks for typedefs and structures
|
||||||
dnl
|
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
|
||||||
dnl Checks for compiler features
|
dnl Checks for compiler features
|
||||||
@ -74,14 +94,15 @@ dnl
|
|||||||
dnl
|
dnl
|
||||||
dnl Checks for library functions
|
dnl Checks for library functions
|
||||||
dnl
|
dnl
|
||||||
AC_CHECK_FUNCS(stpcpy)
|
dnl These are needed by libjnlib
|
||||||
|
AC_CHECK_FUNCS(memicmp stpcpy strlwr strtoul memmove stricmp)
|
||||||
|
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl Checks for system services
|
dnl Checks for system services
|
||||||
dnl
|
dnl
|
||||||
|
|
||||||
if test -z "GPG"; then
|
if test -z "$GPG"; then
|
||||||
AC_PATH_PROG(GPG, gpg)
|
AC_PATH_PROG(GPG, gpg)
|
||||||
if test -z "$GPG"; then
|
if test -z "$GPG"; then
|
||||||
AC_MSG_ERROR([[
|
AC_MSG_ERROR([[
|
||||||
@ -95,11 +116,19 @@ fi
|
|||||||
AC_DEFINE_UNQUOTED(GPG_PATH, "$GPG")
|
AC_DEFINE_UNQUOTED(GPG_PATH, "$GPG")
|
||||||
|
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl FIXME: check whether Bonobo is installed
|
||||||
|
dnl
|
||||||
|
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl Create config files
|
dnl Create config files
|
||||||
dnl
|
dnl
|
||||||
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 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)
|
dnl (this is easier than to have a *.in file just for one substitution)
|
||||||
GNUPG_FIX_HDR_VERSION(gpgme/gpgme.h, GPGME_VERSION)
|
GNUPG_FIX_HDR_VERSION(gpgme/gpgme.h, GPGME_VERSION)
|
||||||
@ -116,11 +145,20 @@ chmod +x gpgme/gpgme-config
|
|||||||
|
|
||||||
AC_OUTPUT([
|
AC_OUTPUT([
|
||||||
Makefile
|
Makefile
|
||||||
|
jnlib/Makefile
|
||||||
gpgme/Makefile
|
gpgme/Makefile
|
||||||
gpgme/gpgme-config
|
gpgme/gpgme-config
|
||||||
tests/Makefile
|
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_armor;
|
||||||
int use_textmode;
|
int use_textmode;
|
||||||
|
|
||||||
/* GpgmePassphraseCb passphrase_cb;*/
|
|
||||||
/* void * passphrase_cb_value;*/
|
|
||||||
|
|
||||||
ResultType result_type;
|
ResultType result_type;
|
||||||
union {
|
union {
|
||||||
VerifyResult verify;
|
VerifyResult verify;
|
||||||
@ -71,6 +68,8 @@ struct gpgme_context_s {
|
|||||||
GpgmeKey tmp_key; /* used by keylist.c */
|
GpgmeKey tmp_key; /* used by keylist.c */
|
||||||
volatile int key_cond; /* something new is available */
|
volatile int key_cond; /* something new is available */
|
||||||
struct key_queue_item_s *key_queue;
|
struct key_queue_item_s *key_queue;
|
||||||
|
|
||||||
|
char *prompt_1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -79,6 +78,11 @@ struct gpgme_data_s {
|
|||||||
const char *data;
|
const char *data;
|
||||||
GpgmeDataType type;
|
GpgmeDataType type;
|
||||||
GpgmeDataMode mode;
|
GpgmeDataMode mode;
|
||||||
|
|
||||||
|
int (*read_cb)( void *, char *, size_t, size_t *);
|
||||||
|
void *read_cb_value;
|
||||||
|
int read_cb_eof;
|
||||||
|
|
||||||
size_t readpos;
|
size_t readpos;
|
||||||
size_t writepos;
|
size_t writepos;
|
||||||
size_t private_len;
|
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;
|
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:
|
* gpgme_data_new_from_file:
|
||||||
* @r_dh: returns the new data object
|
* @r_dh: returns the new data object
|
||||||
@ -279,7 +303,7 @@ gpgme_data_release_and_get_mem ( GpgmeData dh, size_t *r_len )
|
|||||||
GpgmeDataType
|
GpgmeDataType
|
||||||
gpgme_data_get_type ( GpgmeData dh )
|
gpgme_data_get_type ( GpgmeData dh )
|
||||||
{
|
{
|
||||||
if ( !dh || !dh->data )
|
if ( !dh || (!dh->data && !dh->read_cb))
|
||||||
return GPGME_DATA_TYPE_NONE;
|
return GPGME_DATA_TYPE_NONE;
|
||||||
|
|
||||||
return dh->type;
|
return dh->type;
|
||||||
@ -315,9 +339,18 @@ gpgme_data_rewind ( GpgmeData dh )
|
|||||||
{
|
{
|
||||||
if ( !dh )
|
if ( !dh )
|
||||||
return mk_error (Invalid_Value);
|
return mk_error (Invalid_Value);
|
||||||
/* Fixme: We should check whether rewinding does make sense for the
|
|
||||||
* data type */
|
if (dh->type == GPGME_DATA_TYPE_MEM ) {
|
||||||
dh->readpos = 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +367,7 @@ gpgme_data_rewind ( GpgmeData dh )
|
|||||||
* If there are no more bytes available %GPGME_EOF is returned and @nread
|
* If there are no more bytes available %GPGME_EOF is returned and @nread
|
||||||
* is set to 0.
|
* 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.
|
* error code GPGME_EOF.
|
||||||
**/
|
**/
|
||||||
GpgmeError
|
GpgmeError
|
||||||
@ -344,19 +377,66 @@ gpgme_data_read ( GpgmeData dh, char *buffer, size_t length, size_t *nread )
|
|||||||
|
|
||||||
if ( !dh )
|
if ( !dh )
|
||||||
return mk_error (Invalid_Value);
|
return mk_error (Invalid_Value);
|
||||||
nbytes = dh->len - dh->readpos;
|
if (dh->type == GPGME_DATA_TYPE_MEM ) {
|
||||||
if ( !nbytes ) {
|
nbytes = dh->len - dh->readpos;
|
||||||
*nread = 0;
|
if ( !nbytes ) {
|
||||||
return mk_error(EOF);
|
*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)
|
else if (dh->type == GPGME_DATA_TYPE_CB) {
|
||||||
nbytes = length;
|
nbytes = dh->len - dh->readpos;
|
||||||
memcpy ( buffer, dh->data + dh->readpos, nbytes );
|
if ( nbytes ) {
|
||||||
*nread = nbytes;
|
/* we have unread data - return this */
|
||||||
dh->readpos += nbytes;
|
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;
|
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.
|
* 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 no_passphrase;
|
||||||
int okay;
|
int okay;
|
||||||
int failed;
|
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
|
static void
|
||||||
decrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
|
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 )
|
if ( ctx->out_of_core )
|
||||||
return;
|
return;
|
||||||
if ( ctx->result_type == RESULT_TYPE_NONE ) {
|
if ( ctx->result_type == RESULT_TYPE_NONE ) {
|
||||||
assert ( !ctx->result.decrypt );
|
if ( create_result_struct ( ctx ) ) {
|
||||||
ctx->result.decrypt = xtrycalloc ( 1, sizeof *ctx->result.decrypt );
|
|
||||||
if ( !ctx->result.decrypt ) {
|
|
||||||
ctx->out_of_core = 1;
|
ctx->out_of_core = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctx->result_type = RESULT_TYPE_DECRYPT;
|
|
||||||
}
|
}
|
||||||
assert ( 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:
|
||||||
case STATUS_NEED_PASSPHRASE_SYM:
|
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;
|
break;
|
||||||
|
|
||||||
case STATUS_MISSING_PASSPHRASE:
|
case STATUS_MISSING_PASSPHRASE:
|
||||||
@ -91,9 +102,9 @@ decrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GpgmeError
|
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 rc = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -118,14 +129,19 @@ gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData ciph, GpgmeData plain )
|
|||||||
_gpgme_gpg_add_arg ( c->gpg, "--decrypt" );
|
_gpgme_gpg_add_arg ( c->gpg, "--decrypt" );
|
||||||
for ( i=0; i < c->verbosity; i++ )
|
for ( i=0; i < c->verbosity; i++ )
|
||||||
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
|
_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 */
|
/* Check the supplied data */
|
||||||
if ( !ciph || gpgme_data_get_type (ciph) == GPGME_DATA_TYPE_NONE ) {
|
if ( !ciph || gpgme_data_get_type (ciph) == GPGME_DATA_TYPE_NONE ) {
|
||||||
rc = mk_error (No_Data);
|
rc = mk_error (No_Data);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
_gpgme_data_set_mode (ciph, GPGME_DATA_MODE_OUT );
|
_gpgme_data_set_mode (ciph, GPGME_DATA_MODE_OUT );
|
||||||
|
|
||||||
if ( gpgme_data_get_type (plain) != GPGME_DATA_TYPE_NONE ) {
|
if ( gpgme_data_get_type (plain) != GPGME_DATA_TYPE_NONE ) {
|
||||||
rc = mk_error (Invalid_Value);
|
rc = mk_error (Invalid_Value);
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -153,6 +169,7 @@ gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData ciph, GpgmeData plain )
|
|||||||
/**
|
/**
|
||||||
* gpgme_op_decrypt:
|
* gpgme_op_decrypt:
|
||||||
* @c: The context
|
* @c: The context
|
||||||
|
* @passphrase: A data object with the passphrase or NULL.
|
||||||
* @in: ciphertext input
|
* @in: ciphertext input
|
||||||
* @out: plaintext output
|
* @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.
|
* Return value: 0 on success or an errorcode.
|
||||||
**/
|
**/
|
||||||
GpgmeError
|
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 ) {
|
if ( !err ) {
|
||||||
gpgme_wait (c, 1);
|
gpgme_wait (c, 1);
|
||||||
if ( c->result_type != RESULT_TYPE_DECRYPT )
|
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 <config.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
@ -69,7 +70,8 @@ gpgme_release ( GpgmeCtx c )
|
|||||||
_gpgme_key_release ( c->tmp_key );
|
_gpgme_key_release ( c->tmp_key );
|
||||||
gpgme_data_release ( c->notation );
|
gpgme_data_release ( c->notation );
|
||||||
/* fixme: release the key_queue */
|
/* 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;
|
c->use_textmode = yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
/*
|
||||||
|
* The only which currently allowed is 1
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
gpgme_set_passphrase_cb ( GpgmeCtx c, GpgmePassphraseCb fnc, void *fncval )
|
_gpgme_set_prompt ( GpgmeCtx c, int which, const char *text )
|
||||||
{
|
{
|
||||||
if ( c ) {
|
assert ( which == 1 );
|
||||||
c->passphrase_cb = fnc;
|
|
||||||
c->passphrase_cb_value = fncval;
|
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
|
* let autoconf (using the AM_PATH_GPGME macro) check that this
|
||||||
* header matches the installed library.
|
* header matches the installed library.
|
||||||
* Warning: Do not edit the next line. configure will do that for you! */
|
* 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_NONE = 0,
|
||||||
GPGME_DATA_TYPE_MEM = 1,
|
GPGME_DATA_TYPE_MEM = 1,
|
||||||
GPGME_DATA_TYPE_FD = 2,
|
GPGME_DATA_TYPE_FD = 2,
|
||||||
GPGME_DATA_TYPE_FILE = 3
|
GPGME_DATA_TYPE_FILE = 3,
|
||||||
|
GPGME_DATA_TYPE_CB = 4
|
||||||
} GpgmeDataType;
|
} GpgmeDataType;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -91,8 +92,6 @@ typedef enum {
|
|||||||
GPGME_SIG_STAT_ERROR = 5
|
GPGME_SIG_STAT_ERROR = 5
|
||||||
} GpgmeSigStat;
|
} GpgmeSigStat;
|
||||||
|
|
||||||
/*typedef GpgmeData (*GpgmePassphraseCb)( void *opaque, const char *desc );*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Context management */
|
/* Context management */
|
||||||
GpgmeError gpgme_new (GpgmeCtx *r_ctx);
|
GpgmeError gpgme_new (GpgmeCtx *r_ctx);
|
||||||
@ -102,8 +101,7 @@ GpgmeCtx gpgme_wait ( GpgmeCtx c, int hang );
|
|||||||
char *gpgme_get_notation ( GpgmeCtx c );
|
char *gpgme_get_notation ( GpgmeCtx c );
|
||||||
void gpgme_set_armor ( GpgmeCtx c, int yes );
|
void gpgme_set_armor ( GpgmeCtx c, int yes );
|
||||||
void gpgme_set_textmode ( 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 */
|
/* Functions to handle recipients */
|
||||||
@ -118,6 +116,10 @@ GpgmeError gpgme_data_new ( GpgmeData *r_dh );
|
|||||||
GpgmeError gpgme_data_new_from_mem ( GpgmeData *r_dh,
|
GpgmeError gpgme_data_new_from_mem ( GpgmeData *r_dh,
|
||||||
const char *buffer, size_t size,
|
const char *buffer, size_t size,
|
||||||
int copy );
|
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,
|
GpgmeError gpgme_data_new_from_file ( GpgmeData *r_dh,
|
||||||
const char *fname,
|
const char *fname,
|
||||||
int copy );
|
int copy );
|
||||||
@ -136,7 +138,7 @@ char *gpgme_key_get_as_xml ( GpgmeKey key );
|
|||||||
GpgmeError gpgme_op_encrypt_start ( GpgmeCtx c,
|
GpgmeError gpgme_op_encrypt_start ( GpgmeCtx c,
|
||||||
GpgmeRecipients recp,
|
GpgmeRecipients recp,
|
||||||
GpgmeData in, GpgmeData out );
|
GpgmeData in, GpgmeData out );
|
||||||
GpgmeError gpgme_op_decrypt_start ( GpgmeCtx c,
|
GpgmeError gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData passphrase,
|
||||||
GpgmeData ciph, GpgmeData plain );
|
GpgmeData ciph, GpgmeData plain );
|
||||||
GpgmeError gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out );
|
GpgmeError gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out );
|
||||||
GpgmeError gpgme_op_verify_start ( GpgmeCtx c,
|
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 */
|
/* Convenience functions for normal usage */
|
||||||
GpgmeError gpgme_op_encrypt ( GpgmeCtx c, GpgmeRecipients recp,
|
GpgmeError gpgme_op_encrypt ( GpgmeCtx c, GpgmeRecipients recp,
|
||||||
GpgmeData in, GpgmeData out );
|
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_sign ( GpgmeCtx c, GpgmeData in, GpgmeData out );
|
||||||
GpgmeError gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
|
GpgmeError gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
|
||||||
GpgmeSigStat *r_status );
|
GpgmeSigStat *r_status );
|
||||||
@ -161,6 +164,7 @@ GpgmeError gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
|
|||||||
/* miscellaneous functions */
|
/* miscellaneous functions */
|
||||||
const char *gpgme_check_version ( const char *req_version );
|
const char *gpgme_check_version ( const char *req_version );
|
||||||
const char *gpgme_strerror (GpgmeError err);
|
const char *gpgme_strerror (GpgmeError err);
|
||||||
|
const char *gpgme_get_prompt ( GpgmeCtx c, int which );
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -31,6 +31,7 @@ struct spawn_fd_item_s {
|
|||||||
|
|
||||||
struct io_select_fd_s {
|
struct io_select_fd_s {
|
||||||
int fd;
|
int fd;
|
||||||
|
int is_closed;
|
||||||
int for_read;
|
int for_read;
|
||||||
int for_write;
|
int for_write;
|
||||||
int signaled;
|
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_read ( int fd, void *buffer, size_t count );
|
||||||
int _gpgme_io_write ( int fd, const 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_close ( int fd );
|
||||||
int _gpgme_io_set_nonblocking ( int fd );
|
int _gpgme_io_set_nonblocking ( int fd );
|
||||||
int _gpgme_io_spawn ( const char *path, char **argv,
|
int _gpgme_io_spawn ( const char *path, char **argv,
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
/*-- gpgme.c --*/
|
/*-- gpgme.c --*/
|
||||||
void _gpgme_release_result ( GpgmeCtx c );
|
void _gpgme_release_result ( GpgmeCtx c );
|
||||||
|
void _gpgme_set_prompt ( GpgmeCtx c, int which, const char *text );
|
||||||
|
|
||||||
/*-- wait.c --*/
|
/*-- wait.c --*/
|
||||||
GpgmeCtx _gpgme_wait_on_condition ( GpgmeCtx 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,
|
GpgmeError _gpgme_data_append_percentstring_for_xml ( GpgmeData dh,
|
||||||
const char *string );
|
const char *string );
|
||||||
|
|
||||||
|
GpgmeError _gpgme_data_unread (GpgmeData dh,
|
||||||
|
const char *buffer, size_t length );
|
||||||
|
|
||||||
|
|
||||||
/*-- key.c --*/
|
/*-- key.c --*/
|
||||||
GpgmeError _gpgme_key_new( GpgmeKey *r_key );
|
GpgmeError _gpgme_key_new( GpgmeKey *r_key );
|
||||||
|
@ -68,8 +68,9 @@ _gpgme_io_write ( int fd, const void *buffer, size_t count )
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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 );
|
return pipe ( filedes );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,12 +40,14 @@
|
|||||||
|
|
||||||
#include "status-table.h"
|
#include "status-table.h"
|
||||||
|
|
||||||
|
|
||||||
/* This type is used to build a list of gpg arguments and
|
/* This type is used to build a list of gpg arguments and
|
||||||
* data sources/sinks */
|
* data sources/sinks */
|
||||||
struct arg_and_data_s {
|
struct arg_and_data_s {
|
||||||
struct arg_and_data_s *next;
|
struct arg_and_data_s *next;
|
||||||
GpgmeData data; /* If this is not NULL .. */
|
GpgmeData data; /* If this is not NULL .. */
|
||||||
int dup_to;
|
int dup_to;
|
||||||
|
int print_fd; /* print the fd number and not the special form of it */
|
||||||
char arg[1]; /* .. this is used */
|
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
|
/* In any case we need a status pipe - create it right here and
|
||||||
* don't handle it with our generic GpgmeData mechanism */
|
* 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);
|
rc = mk_error (Pipe_Error);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -151,6 +153,7 @@ _gpgme_gpg_new ( GpgObject *r_gpg )
|
|||||||
_gpgme_gpg_add_arg ( gpg, "--batch" );
|
_gpgme_gpg_add_arg ( gpg, "--batch" );
|
||||||
_gpgme_gpg_add_arg ( gpg, "--no-tty" );
|
_gpgme_gpg_add_arg ( gpg, "--no-tty" );
|
||||||
|
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
if (rc) {
|
if (rc) {
|
||||||
_gpgme_gpg_release (gpg);
|
_gpgme_gpg_release (gpg);
|
||||||
@ -170,6 +173,11 @@ _gpgme_gpg_release ( GpgObject gpg )
|
|||||||
xfree (gpg->colon.buffer);
|
xfree (gpg->colon.buffer);
|
||||||
if ( gpg->argv )
|
if ( gpg->argv )
|
||||||
free_argv (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 )
|
if (gpg->status.fd[0] != -1 )
|
||||||
_gpgme_io_close (gpg->status.fd[0]);
|
_gpgme_io_close (gpg->status.fd[0]);
|
||||||
if (gpg->status.fd[1] != -1 )
|
if (gpg->status.fd[1] != -1 )
|
||||||
@ -178,6 +186,7 @@ _gpgme_gpg_release ( GpgObject gpg )
|
|||||||
_gpgme_io_close (gpg->colon.fd[0]);
|
_gpgme_io_close (gpg->colon.fd[0]);
|
||||||
if (gpg->colon.fd[1] != -1 )
|
if (gpg->colon.fd[1] != -1 )
|
||||||
_gpgme_io_close (gpg->colon.fd[1]);
|
_gpgme_io_close (gpg->colon.fd[1]);
|
||||||
|
#endif
|
||||||
free_fd_data_map (gpg->fd_data_map);
|
free_fd_data_map (gpg->fd_data_map);
|
||||||
kill_gpg (gpg); /* fixme: should be done asyncronously */
|
kill_gpg (gpg); /* fixme: should be done asyncronously */
|
||||||
xfree (gpg);
|
xfree (gpg);
|
||||||
@ -237,7 +246,14 @@ _gpgme_gpg_add_data ( GpgObject gpg, GpgmeData data, int dup_to )
|
|||||||
}
|
}
|
||||||
a->next = NULL;
|
a->next = NULL;
|
||||||
a->data = data;
|
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;
|
||||||
gpg->argtail = &a->next;
|
gpg->argtail = &a->next;
|
||||||
return 0;
|
return 0;
|
||||||
@ -268,7 +284,7 @@ _gpgme_gpg_set_colon_line_handler ( GpgObject gpg,
|
|||||||
if (!gpg->colon.buffer) {
|
if (!gpg->colon.buffer) {
|
||||||
return mk_error (Out_Of_Core);
|
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;
|
xfree (gpg->colon.buffer); gpg->colon.buffer = NULL;
|
||||||
return mk_error (Pipe_Error);
|
return mk_error (Pipe_Error);
|
||||||
}
|
}
|
||||||
@ -294,11 +310,16 @@ free_fd_data_map ( struct fd_data_map_s *fd_data_map )
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if ( !fd_data_map )
|
||||||
|
return;
|
||||||
|
|
||||||
for (i=0; fd_data_map[i].data; i++ ) {
|
for (i=0; fd_data_map[i].data; i++ ) {
|
||||||
|
#if 0 /* fixme -> see gpg_release */
|
||||||
if ( fd_data_map[i].fd != -1 )
|
if ( fd_data_map[i].fd != -1 )
|
||||||
_gpgme_io_close (fd_data_map[i].fd);
|
_gpgme_io_close (fd_data_map[i].fd);
|
||||||
if ( fd_data_map[i].peer_fd != -1 )
|
if ( fd_data_map[i].peer_fd != -1 )
|
||||||
_gpgme_io_close (fd_data_map[i].peer_fd);
|
_gpgme_io_close (fd_data_map[i].peer_fd);
|
||||||
|
#endif
|
||||||
/* don't realease data because this is only a reference */
|
/* don't realease data because this is only a reference */
|
||||||
}
|
}
|
||||||
xfree (fd_data_map);
|
xfree (fd_data_map);
|
||||||
@ -330,7 +351,7 @@ build_argv ( GpgObject gpg )
|
|||||||
if (a->data) {
|
if (a->data) {
|
||||||
/*fprintf (stderr, "build_argv: data\n" );*/
|
/*fprintf (stderr, "build_argv: data\n" );*/
|
||||||
datac++;
|
datac++;
|
||||||
if ( a->dup_to == -1 )
|
if ( a->dup_to == -1 && !a->print_fd )
|
||||||
need_special = 1;
|
need_special = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -403,6 +424,7 @@ build_argv ( GpgObject gpg )
|
|||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Invalid_Type);
|
return mk_error (Invalid_Type);
|
||||||
case GPGME_DATA_TYPE_MEM:
|
case GPGME_DATA_TYPE_MEM:
|
||||||
|
case GPGME_DATA_TYPE_CB:
|
||||||
break;
|
break;
|
||||||
case GPGME_DATA_TYPE_FD:
|
case GPGME_DATA_TYPE_FD:
|
||||||
case GPGME_DATA_TYPE_FILE:
|
case GPGME_DATA_TYPE_FILE:
|
||||||
@ -415,7 +437,8 @@ build_argv ( GpgObject gpg )
|
|||||||
{
|
{
|
||||||
int fds[2];
|
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);
|
xfree (fd_data_map);
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Pipe_Error);
|
return mk_error (Pipe_Error);
|
||||||
@ -439,7 +462,9 @@ build_argv ( GpgObject gpg )
|
|||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Out_Of_Core);
|
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++;
|
argc++;
|
||||||
}
|
}
|
||||||
datac++;
|
datac++;
|
||||||
@ -490,7 +515,7 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
|
|||||||
|
|
||||||
/* build the fd list for the child */
|
/* build the fd list for the child */
|
||||||
n=0;
|
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;
|
fd_child_list[n].dup_to = -1;
|
||||||
n++;
|
n++;
|
||||||
if ( gpg->colon.fnc ) {
|
if ( gpg->colon.fnc ) {
|
||||||
@ -538,7 +563,6 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
|
|||||||
fd_parent_list[n].dup_to = -1;
|
fd_parent_list[n].dup_to = -1;
|
||||||
|
|
||||||
|
|
||||||
fflush (stderr);
|
|
||||||
pid = _gpgme_io_spawn (GPG_PATH, gpg->argv, fd_child_list, fd_parent_list);
|
pid = _gpgme_io_spawn (GPG_PATH, gpg->argv, fd_child_list, fd_parent_list);
|
||||||
xfree (fd_child_list);
|
xfree (fd_child_list);
|
||||||
if (pid == -1) {
|
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 );
|
assert ( _gpgme_data_get_mode (dh) == GPGME_DATA_MODE_IN );
|
||||||
|
|
||||||
nread = _gpgme_io_read (fd, buf, 200 );
|
nread = _gpgme_io_read (fd, buf, 200 );
|
||||||
fprintf(stderr, "inbound on fd %d: nread=%d\n", fd, nread );
|
|
||||||
if ( nread < 0 ) {
|
if ( nread < 0 ) {
|
||||||
fprintf (stderr, "read_mem_data: read failed on fd %d (n=%d): %s\n",
|
fprintf (stderr, "read_mem_data: read failed on fd %d (n=%d): %s\n",
|
||||||
fd, nread, strerror (errno) );
|
fd, nread, strerror (errno) );
|
||||||
@ -638,7 +661,6 @@ write_mem_data ( GpgmeData dh, int fd )
|
|||||||
|
|
||||||
nbytes = dh->len - dh->readpos;
|
nbytes = dh->len - dh->readpos;
|
||||||
if ( !nbytes ) {
|
if ( !nbytes ) {
|
||||||
fprintf (stderr, "write_mem_data(%d): closing\n", fd );
|
|
||||||
_gpgme_io_close (fd);
|
_gpgme_io_close (fd);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -650,11 +672,7 @@ write_mem_data ( GpgmeData dh, int fd )
|
|||||||
* To avoid that we have set the pipe to nonblocking.
|
* 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 );
|
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 )
|
if (nwritten == -1 && errno == EAGAIN )
|
||||||
return 0;
|
return 0;
|
||||||
if ( nwritten < 1 ) {
|
if ( nwritten < 1 ) {
|
||||||
@ -668,6 +686,40 @@ write_mem_data ( GpgmeData dh, int fd )
|
|||||||
return 0;
|
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
|
static int
|
||||||
gpg_outbound_handler ( void *opaque, int pid, int fd )
|
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 ) )
|
if ( write_mem_data ( dh, fd ) )
|
||||||
return 1; /* ready */
|
return 1; /* ready */
|
||||||
break;
|
break;
|
||||||
|
case GPGME_DATA_TYPE_CB:
|
||||||
|
if (write_cb_data (dh, fd))
|
||||||
|
return 1; /* ready */
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert (0);
|
assert (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 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" );
|
_gpgme_gpg_add_arg ( c->gpg, "--verify" );
|
||||||
for ( i=0; i < c->verbosity; i++ )
|
for ( i=0; i < c->verbosity; i++ )
|
||||||
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
|
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
|
||||||
|
|
||||||
|
|
||||||
/* Check the supplied data */
|
/* Check the supplied data */
|
||||||
if ( gpgme_data_get_type (sig) == GPGME_DATA_TYPE_NONE ) {
|
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 */
|
/* Tell the gpg object about the data */
|
||||||
_gpgme_gpg_add_arg ( c->gpg, "--" );
|
_gpgme_gpg_add_arg ( c->gpg, "--" );
|
||||||
_gpgme_gpg_add_data ( c->gpg, sig, -1 );
|
_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 );
|
_gpgme_gpg_add_data ( c->gpg, text, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
/* and kick off the process */
|
/* and kick off the process */
|
||||||
rc = _gpgme_gpg_spawn ( c->gpg, c );
|
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 "util.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
#define DEBUG_SELECT_ENABLED 1
|
#define DEBUG_SELECT_ENABLED 0
|
||||||
|
|
||||||
#if DEBUG_SELECT_ENABLED
|
#if DEBUG_SELECT_ENABLED
|
||||||
# define DEBUG_SELECT(a) fprintf a
|
# 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
|
* for all i386 systems (HANDLE is defined as void *) and these are the only
|
||||||
* systems for which Windows is available.
|
* systems for which Windows is available.
|
||||||
* Further we assume that -1 denotes an invalid handle.
|
* 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;
|
int nread = 0;
|
||||||
HANDLE h = fd_to_handle (fd);
|
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) ) {
|
if ( !ReadFile ( h, buffer, count, &nread, NULL) ) {
|
||||||
fprintf (stderr, "** ReadFile failed: ec=%d\n", (int)GetLastError ());
|
fprintf (stderr, "** ReadFile failed: ec=%d\n", (int)GetLastError ());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
DEBUG_SELECT ((stderr,"** fd %d: got %d bytes\n", fd, nread ));
|
||||||
|
|
||||||
return nread;
|
return nread;
|
||||||
}
|
}
|
||||||
@ -80,23 +82,62 @@ _gpgme_io_write ( int fd, const void *buffer, size_t count )
|
|||||||
int nwritten;
|
int nwritten;
|
||||||
HANDLE h = fd_to_handle (fd);
|
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) ) {
|
if ( !WriteFile ( h, buffer, count, &nwritten, NULL) ) {
|
||||||
fprintf (stderr, "** WriteFile failed: ec=%d\n", (int)GetLastError ());
|
fprintf (stderr, "** WriteFile failed: ec=%d\n", (int)GetLastError ());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
DEBUG_SELECT ((stderr,"** fd %d: wrote %d bytes\n", fd, nwritten ));
|
||||||
|
|
||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_gpgme_io_pipe ( int filedes[2] )
|
_gpgme_io_pipe ( int filedes[2], int inherit_idx )
|
||||||
{
|
{
|
||||||
HANDLE r, w;
|
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;
|
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[0] = handle_to_fd (r);
|
||||||
filedes[1] = handle_to_fd (w);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +146,15 @@ _gpgme_io_close ( int fd )
|
|||||||
{
|
{
|
||||||
if ( fd == -1 )
|
if ( fd == -1 )
|
||||||
return -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 */
|
* program parses the commandline and does some unquoting */
|
||||||
for (i=0; argv[i]; i++)
|
for (i=0; argv[i]; i++)
|
||||||
n += strlen (argv[i]) + 1;
|
n += strlen (argv[i]) + 1;
|
||||||
n += 5; /* "gpg " */
|
|
||||||
buf = p = xtrymalloc (n);
|
buf = p = xtrymalloc (n);
|
||||||
if ( !buf )
|
if ( !buf )
|
||||||
return NULL;
|
return NULL;
|
||||||
p = stpcpy (p, "gpg");
|
*buf = 0;
|
||||||
for (i = 0; argv[i]; i++)
|
if ( argv[0] )
|
||||||
|
p = stpcpy (p, argv[0]);
|
||||||
|
for (i = 1; argv[i]; i++)
|
||||||
p = stpcpy (stpcpy (p, " "), argv[i]);
|
p = stpcpy (stpcpy (p, " "), argv[i]);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
@ -150,46 +200,84 @@ _gpgme_io_spawn ( const char *path, char **argv,
|
|||||||
0, /* returns pid */
|
0, /* returns pid */
|
||||||
0 /* returns tid */
|
0 /* returns tid */
|
||||||
};
|
};
|
||||||
STARTUPINFO si = {
|
STARTUPINFO si;
|
||||||
0, NULL, NULL, NULL,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
NULL, NULL, NULL, NULL
|
|
||||||
};
|
|
||||||
char *envblock = NULL;
|
char *envblock = NULL;
|
||||||
int cr_flags = CREATE_DEFAULT_ERROR_MODE
|
int cr_flags = CREATE_DEFAULT_ERROR_MODE
|
||||||
| GetPriorityClass (GetCurrentProcess ());
|
| GetPriorityClass (GetCurrentProcess ());
|
||||||
int i, rc;
|
int i;
|
||||||
char *arg_string;
|
char *arg_string;
|
||||||
HANDLE save_stdout;
|
int duped_stdin = 0;
|
||||||
HANDLE outputfd[2], statusfd[2], inputfd[2];
|
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.bInheritHandle = FALSE;
|
||||||
sec_attr.lpSecurityDescriptor = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
arg_string = build_commandline ( argv );
|
arg_string = build_commandline ( argv );
|
||||||
if (!arg_string )
|
if (!arg_string )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
memset (&si, 0, sizeof si);
|
||||||
si.cb = sizeof (si);
|
si.cb = sizeof (si);
|
||||||
si.dwFlags = STARTF_USESTDHANDLES;
|
si.dwFlags = STARTF_USESTDHANDLES;
|
||||||
si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
|
si.hStdInput = GetStdHandle (STD_INPUT_HANDLE);
|
||||||
si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
|
si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||||
si.hStdError = GetStdHandle (STD_ERROR_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);
|
for (i=0; fd_child_list[i].fd != -1; i++ ) {
|
||||||
fprintf (stderr, "** args=`%s'\n", arg_string);
|
if (fd_child_list[i].dup_to == 0 ) {
|
||||||
fflush (stderr);
|
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,
|
if ( !CreateProcessA (GPG_PATH,
|
||||||
arg_string,
|
arg_string,
|
||||||
&sec_attr, /* process security attributes */
|
&sec_attr, /* process security attributes */
|
||||||
@ -203,27 +291,47 @@ _gpgme_io_spawn ( const char *path, char **argv,
|
|||||||
) ) {
|
) ) {
|
||||||
fprintf (stderr, "** CreateProcess failed: ec=%d\n",
|
fprintf (stderr, "** CreateProcess failed: ec=%d\n",
|
||||||
(int) GetLastError ());
|
(int) GetLastError ());
|
||||||
fflush (stderr);
|
|
||||||
xfree (arg_string);
|
xfree (arg_string);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .dup_to is not used in the parent list */
|
/* close the /dev/nul handle if used */
|
||||||
for (i=0; fd_parent_list[i].fd != -1; i++ ) {
|
if (hnul != INVALID_HANDLE_VALUE ) {
|
||||||
CloseHandle ( fd_to_handle (fd_parent_list[i].fd) );
|
if ( !CloseHandle ( hnul ) )
|
||||||
|
fprintf (stderr, "** CloseHandle(hnul) failed: ec=%d\n",
|
||||||
|
(int)GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (stderr, "** CreateProcess ready\n");
|
/* Close the other ends of the pipes */
|
||||||
fprintf (stderr, "** hProcess=%p hThread=%p\n",
|
for (i=0; fd_parent_list[i].fd != -1; i++ ) {
|
||||||
pi.hProcess, pi.hThread);
|
DEBUG_SELECT ((stderr,"** Closing fd %d\n", fd_parent_list[i].fd ));
|
||||||
fprintf (stderr, "** dwProcessID=%d dwThreadId=%d\n",
|
if ( !CloseHandle ( fd_to_handle (fd_parent_list[i].fd) ) )
|
||||||
(int) pi.dwProcessId, (int) pi.dwThreadId);
|
fprintf (stderr, "** CloseHandle failed: ec=%d\n",
|
||||||
fflush (stderr);
|
(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);
|
return handle_to_pid (pi.hProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal )
|
_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;
|
*r_status = 4;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf (stderr, "** GECP pid=%d exit code=%d\n",
|
DEBUG_SELECT ((stderr,"** GECP pid=%d exit code=%d\n",
|
||||||
(int)pid, exc);
|
(int)pid, exc));
|
||||||
*r_status = exc;
|
*r_status = exc;
|
||||||
}
|
}
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WAIT_TIMEOUT:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -274,24 +382,28 @@ _gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal )
|
|||||||
int
|
int
|
||||||
_gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
|
_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];
|
HANDLE waitbuf[MAXIMUM_WAIT_OBJECTS];
|
||||||
int code, nwait;
|
int code, nwait;
|
||||||
int i, any, ret;
|
int i, any, any_write;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
restart:
|
||||||
DEBUG_SELECT ((stderr, "gpgme:select on [ "));
|
DEBUG_SELECT ((stderr, "gpgme:select on [ "));
|
||||||
any = 0;
|
any = any_write = 0;
|
||||||
nwait = 0;
|
nwait = 0;
|
||||||
for ( i=0; i < nfds; i++ ) {
|
for ( i=0; i < nfds; i++ ) {
|
||||||
if ( fds[i].fd == -1 )
|
if ( fds[i].fd == -1 )
|
||||||
continue;
|
continue;
|
||||||
if ( fds[i].for_read || fds[i].for_write ) {
|
if ( fds[i].for_read || fds[i].for_write ) {
|
||||||
if ( nwait >= DIM (waitbuf) ) {
|
if ( nwait >= DIM (waitbuf) ) {
|
||||||
DEBUG_SELECT ((stderr, "oops ]\n" ));
|
DEBUG_SELECT ((stderr,stderr, "oops ]\n" ));
|
||||||
fprintf (stderr, "** Too many objects for WFMO!\n" );
|
fprintf (stderr, "** Too many objects for WFMO!\n" );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else {
|
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 ",
|
DEBUG_SELECT ((stderr, "%c%d ",
|
||||||
fds[i].for_read? 'r':'w',fds[i].fd ));
|
fds[i].for_read? 'r':'w',fds[i].fd ));
|
||||||
any = 1;
|
any = 1;
|
||||||
@ -300,14 +412,73 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
|
|||||||
fds[i].signaled = 0;
|
fds[i].signaled = 0;
|
||||||
}
|
}
|
||||||
DEBUG_SELECT ((stderr, "]\n" ));
|
DEBUG_SELECT ((stderr, "]\n" ));
|
||||||
if (!any)
|
if (!any)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = 0;
|
count = 0;
|
||||||
code = WaitForMultipleObjects ( nwait, waitbuf, 0, 1000 );
|
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 ) {
|
if (code == WAIT_FAILED ) {
|
||||||
fprintf (stderr, "** WFMO failed: %d\n", (int)GetLastError () );
|
int le = (int)GetLastError ();
|
||||||
ret = -1;
|
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 ) {
|
else if ( code == WAIT_TIMEOUT ) {
|
||||||
fprintf (stderr, "** WFMO timed out\n" );
|
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) {
|
if (WaitForSingleObject ( waitbuf[i], NULL ) == WAIT_OBJECT_0) {
|
||||||
fds[i].signaled = 1;
|
fds[i].signaled = 1;
|
||||||
any = 1;
|
any = 1;
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (any)
|
if (!any) {
|
||||||
ret = 1;
|
|
||||||
else {
|
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"** Oops: No signaled objects found after WFMO\n");
|
"** Oops: No signaled objects found after WFMO\n");
|
||||||
ret = -1;
|
count = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf (stderr, "** WFMO returned %d\n", code );
|
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*/
|
#endif /*HAVE_DOSISH_SYSTEM*/
|
||||||
|
37
gpgme/wait.c
37
gpgme/wait.c
@ -111,6 +111,19 @@ count_active_fds ( int pid )
|
|||||||
return count;
|
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 */
|
/* remove the given process from the queue */
|
||||||
static void
|
static void
|
||||||
@ -123,7 +136,11 @@ remove_process ( int pid )
|
|||||||
if (fd_table[i].fd != -1 && (q=fd_table[i].opaque) && q->pid == pid ) {
|
if (fd_table[i].fd != -1 && (q=fd_table[i].opaque) && q->pid == pid ) {
|
||||||
xfree (q);
|
xfree (q);
|
||||||
fd_table[i].opaque = NULL;
|
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;
|
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 );
|
q = queue_item_from_context ( c );
|
||||||
assert (q);
|
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,
|
else if ( _gpgme_io_waitpid (q->pid, 0,
|
||||||
&q->exit_status, &q->exit_signal)){
|
&q->exit_status, &q->exit_signal)){
|
||||||
q->exited = 1;
|
q->exited = 1;
|
||||||
@ -207,26 +229,30 @@ do_select ( void )
|
|||||||
{
|
{
|
||||||
struct wait_item_s *q;
|
struct wait_item_s *q;
|
||||||
int i, n;
|
int i, n;
|
||||||
|
int any=0;
|
||||||
|
|
||||||
n = _gpgme_io_select ( fd_table, fd_table_size );
|
n = _gpgme_io_select ( fd_table, fd_table_size );
|
||||||
if ( n <= 0 )
|
if ( n <= 0 )
|
||||||
return 0; /* error or timeout */
|
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 ) {
|
if ( fd_table[i].fd != -1 && fd_table[i].signaled ) {
|
||||||
q = fd_table[i].opaque;
|
q = fd_table[i].opaque;
|
||||||
assert (n);
|
assert (n);
|
||||||
n--;
|
n--;
|
||||||
|
if ( q->active )
|
||||||
|
any = 1;
|
||||||
if ( q->active && q->handler (q->handler_value,
|
if ( q->active && q->handler (q->handler_value,
|
||||||
q->pid, fd_table[i].fd ) ) {
|
q->pid, fd_table[i].fd ) ) {
|
||||||
q->active = 0;
|
q->active = 0;
|
||||||
fd_table[i].for_read = 0;
|
fd_table[i].for_read = 0;
|
||||||
fd_table[i].for_write = 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++ ) {
|
for (i=0; i < fd_table_size; i++ ) {
|
||||||
if ( fd_table[i].fd == -1 ) {
|
if ( fd_table[i].fd == -1 ) {
|
||||||
fd_table[i].fd = fd;
|
fd_table[i].fd = fd;
|
||||||
|
fd_table[i].is_closed = 0;
|
||||||
fd_table[i].for_read = inbound;
|
fd_table[i].for_read = inbound;
|
||||||
fd_table[i].for_write = !inbound;
|
fd_table[i].for_write = !inbound;
|
||||||
fd_table[i].signaled = 0;
|
fd_table[i].signaled = 0;
|
||||||
|
@ -26,6 +26,12 @@
|
|||||||
|
|
||||||
#include "../gpgme/gpgme.h"
|
#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; \
|
#define fail_if_err(a) do { if(a) { int my_errno = errno; \
|
||||||
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
|
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
|
||||||
__FILE__, __LINE__, gpgme_strerror(a)); \
|
__FILE__, __LINE__, gpgme_strerror(a)); \
|
||||||
@ -50,17 +56,31 @@ print_data ( GpgmeData dh )
|
|||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static GpgmeData
|
|
||||||
passphrase_cb ( void *opaque, const char *description )
|
|
||||||
{
|
|
||||||
GpgmeData dh;
|
|
||||||
|
|
||||||
assert (NULL);
|
static int
|
||||||
gpgme_data_new_from_mem ( &dh, "abc", 3, 0 );
|
passphrase_cb ( void *opaque, char *buffer, size_t length, size_t *nread )
|
||||||
return dh;
|
{
|
||||||
|
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 *
|
static char *
|
||||||
mk_fname ( const char *fname )
|
mk_fname ( const char *fname )
|
||||||
@ -84,17 +104,18 @@ main (int argc, char **argv )
|
|||||||
{
|
{
|
||||||
GpgmeCtx ctx;
|
GpgmeCtx ctx;
|
||||||
GpgmeError err;
|
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");
|
const char *cipher_1_asc = mk_fname ("cipher-1.asc");
|
||||||
|
|
||||||
do {
|
do {
|
||||||
err = gpgme_new (&ctx);
|
err = gpgme_new (&ctx);
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
#if 0
|
if ( 0 && !getenv("GPG_AGENT_INFO") ) {
|
||||||
if ( !getenv("GPG_AGENT_INFO") {
|
memset ( &info, 0, sizeof info );
|
||||||
gpgme_set_passphrase_cb ( ctx, passphrase_cb, NULL );
|
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 );
|
err = gpgme_data_new_from_file ( &in, cipher_1_asc, 1 );
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
@ -102,7 +123,7 @@ main (int argc, char **argv )
|
|||||||
err = gpgme_data_new ( &out );
|
err = gpgme_data_new ( &out );
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
|
||||||
err = gpgme_op_decrypt (ctx, in, out );
|
err = gpgme_op_decrypt (ctx, pwdata, in, out );
|
||||||
fail_if_err (err);
|
fail_if_err (err);
|
||||||
|
|
||||||
fflush (NULL);
|
fflush (NULL);
|
||||||
@ -112,6 +133,7 @@ main (int argc, char **argv )
|
|||||||
|
|
||||||
gpgme_data_release (in);
|
gpgme_data_release (in);
|
||||||
gpgme_data_release (out);
|
gpgme_data_release (out);
|
||||||
|
gpgme_data_release (pwdata);
|
||||||
gpgme_release (ctx);
|
gpgme_release (ctx);
|
||||||
} while ( argc > 1 && !strcmp( argv[1], "--loop" ) );
|
} while ( argc > 1 && !strcmp( argv[1], "--loop" ) );
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user