From: Marcus Brinkmann Date: Sat, 12 Oct 2002 00:33:05 +0000 (+0000) Subject: 2002-10-10 Marcus Brinkmann X-Git-Tag: gpgme-0-4-0~31 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=3a6381133afaadf4af08fa2f64d04b5ba95f6949;p=gpgme.git 2002-10-10 Marcus Brinkmann * rungpg.h, engine-gpgsm.h: File removed. * engine-backend.h: New file. * Makefile.am (gpgsm_components): New variable, set depending on automake conditional HAVE_GPGSM. (libgpgme_la_SOURCES): Add engine-backend.h, remove rungpg.h and engine-gpgsm.h. Replace engine-gpgsm.c with ${gpgsm_components}. (status-table.h): Depend on gpgme.h, not rungpg.h. * conversion.c: Include . * engine-gpgsm.c: Do not set ENABLE_GPGSM here. Include "engine-backend.h" instead "engine-gpgsm.h". Reorder some functions and remove all function prototypes. (_gpgme_gpgsm_get_version): Make static and rename to ... (gpgsm_get_version): ... this. (_gpgme_gpgsm_check_version): Make static and rename to ... (gpgsm_check_version): ... this. (_gpgme_gpgsm_new): Make static. Change argument type from GpgsmObject * to void **. Call gpgsm_release instead _gpgme_gpgsm_release. (_gpgme_gpgsm_op_decrypt): Make static and rename to ... (gpgsm_check_decrypt): ... this. (_gpgme_gpgsm_op_delete): Make static and rename to ... (gpgsm_check_delete): ... this. (_gpgme_gpgsm_set_recipients): Make static and rename to ... (gpgsm_check_set_recipients): ... this. (_gpgme_gpgsm_op_encrypt): Make static and rename to ... (gpgsm_encrypt): ... this. (_gpgme_gpgsm_op_export): Make static and rename to ... (gpgsm_export): ... this. (_gpgme_gpgsm_op_genkey): Make static and rename to ... (gpgsm_genkey): ... this. (_gpgme_gpgsm_op_import): Make static and rename to ... (gpgsm_import): ... this. (_gpgme_gpgsm_op_keylist): Make static and rename to ... (gpgsm_keylist): ... this. (_gpgme_gpgsm_op_keylist_ext): Make static and rename to ... (gpgsm_keylist_ext): ... this. (_gpgme_gpgsm_op_sign): Make static and rename to ... (gpgsm_sign): ... this. (_gpgme_gpgsm_op_trustlist): Make static and rename to ... (gpgsm_trustlist): ... this. (_gpgme_gpgsm_op_verify): Make static and rename to ... (gpgsm_verify): ... this. (gpgsm_status_handler): Rename to ... (status_handler): ... this. (_gpgme_gpgsm_set_status_handler): Make static and rename to ... (gpgsm_set_status_handler): ... this. (_gpgme_gpgsm_set_colon_line_handler): Make static and rename to ... (gpgsm_set_colon_line_handler): ... this. (_gpgme_gpgsm_add_io_cb): Rename to ... (add_io_cb): ... this. (_gpgme_gpgsm_start): Make static and rename to ... (gpgsm_start): ... this. (_gpgme_gpgsm_set_io_cb): Make static and rename to ... (gpgsm_set_io_cb): ... this. (_gpgme_gpgsm_io_event): Make static and rename to ... (gpgsm_io_event): ... this. (struct _gpgme_engine_ops_gpgsm): New variable. [!ENABLE_GPGSM]: Removed. * engine.c: Do not include , , , , "io.h", "rungpg.h" and "engine-gpgsm.h". Include and "engine-backend.h". (struct engine_object_s): Rewritten. (engine_ops): New variable. * engine.c (_gpgme_engine_get_path, _gpgme_engine_get_version, _gpgme_engine_check_version, _gpgme_engine_new, _gpgme_engine_release, _gpgme_engine_set_verbosity, _gpgme_engine_set_status_handler, _gpgme_engine_set_command_handler, _gpgme_engine_set_colon_line_handler, _gpgme_engine_op_decrypt, _gpgme_engine_op_delete, _gpgme_engine_op_edit, _gpgme_engine_op_encrypt, _gpgme_engine_op_encrypt_sign, _gpgme_engine_op_export, _gpgme_engine_op_genkey, _gpgme_engine_op_import, _gpgme_engine_op_keylist, _gpgme_engine_op_keylist_ext, _gpgme_engine_op_sign, _gpgme_engine_op_trustlist, _gpgme_engine_op_verify, _gpgme_engine_start, _gpgme_engine_set_io_cbs, _gpgme_engine_io_event): Reimplement. * engine.h: Fix a few comments and a variable name in a prototype. * ops.h: Do not include "rungpg.h". * passphrase.c: Include config.h only if [HAVE_CONFIG_H]. Do not include "rungpg.h". * recipient.c: Likewise. * signers.c: Likewise. * version.c: Likewise. * rungpg.c: Likewise. Include "engine-backend.h". Reorder functions and remove prototypes. (_gpgme_gpg_get_version): Make static and rename to ... (gpg_get_version): ... this. (_gpgme_gpg_check_version): Make static and rename to ... (gpg_check_version): ... this. (_gpgme_gpg_new): Make static. Change argument type from GpgObject * to void **. Call gpg_release instead _gpgme_gpg_release. (_gpgme_gpg_op_decrypt): Make static and rename to ... (gpg_check_decrypt): ... this. (_gpgme_gpg_op_delete): Make static and rename to ... (gpg_check_delete): ... this. (_gpgme_gpg_set_recipients): Make static and rename to ... (gpg_check_set_recipients): ... this. (_gpgme_gpg_op_encrypt): Make static and rename to ... (gpg_encrypt): ... this. (_gpgme_gpg_op_export): Make static and rename to ... (gpg_export): ... this. (_gpgme_gpg_op_genkey): Make static and rename to ... (gpg_genkey): ... this. (_gpgme_gpg_op_import): Make static and rename to ... (gpg_import): ... this. (_gpgme_gpg_op_keylist): Make static and rename to ... (gpg_keylist): ... this. (_gpgme_gpg_op_keylist_ext): Make static and rename to ... (gpg_keylist_ext): ... this. (_gpgme_gpg_op_sign): Make static and rename to ... (gpg_sign): ... this. (_gpgme_gpg_op_trustlist): Make static and rename to ... (gpg_trustlist): ... this. (_gpgme_gpg_op_verify): Make static and rename to ... (gpg_verify): ... this. (gpg_status_handler): Rename to ... (status_handler): ... this. (_gpgme_gpg_set_status_handler): Make static and rename to ... (gpg_set_status_handler): ... this. (_gpgme_gpg_set_colon_line_handler): Make static and rename to ... (gpg_set_colon_line_handler): ... this. (gpgme_gpg_add_io_cb): Rename to ... (add_io_cb): ... this. (_gpgme_gpg_start): Make static and rename to ... (gpg_start): ... this. (_gpgme_gpg_set_io_cb): Make static and rename to ... (gpg_set_io_cb): ... this. (_gpgme_gpg_io_event): Make static and rename to ... (gpg_io_event): ... this. (struct _gpgme_engine_ops_gpg): New variable. --- diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 053c82f..da977ea 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,138 @@ +2002-10-10 Marcus Brinkmann + + * rungpg.h, engine-gpgsm.h: File removed. + * engine-backend.h: New file. + * Makefile.am (gpgsm_components): New variable, set depending on + automake conditional HAVE_GPGSM. + (libgpgme_la_SOURCES): Add engine-backend.h, remove rungpg.h and + engine-gpgsm.h. Replace engine-gpgsm.c with ${gpgsm_components}. + (status-table.h): Depend on gpgme.h, not rungpg.h. + * conversion.c: Include . + * engine-gpgsm.c: Do not set ENABLE_GPGSM here. Include + "engine-backend.h" instead "engine-gpgsm.h". Reorder some + functions and remove all function prototypes. + (_gpgme_gpgsm_get_version): Make static and rename to ... + (gpgsm_get_version): ... this. + (_gpgme_gpgsm_check_version): Make static and rename to ... + (gpgsm_check_version): ... this. + (_gpgme_gpgsm_new): Make static. Change argument type from + GpgsmObject * to void **. Call gpgsm_release instead + _gpgme_gpgsm_release. + (_gpgme_gpgsm_op_decrypt): Make static and rename to ... + (gpgsm_check_decrypt): ... this. + (_gpgme_gpgsm_op_delete): Make static and rename to ... + (gpgsm_check_delete): ... this. + (_gpgme_gpgsm_set_recipients): Make static and rename to ... + (gpgsm_check_set_recipients): ... this. + (_gpgme_gpgsm_op_encrypt): Make static and rename to ... + (gpgsm_encrypt): ... this. + (_gpgme_gpgsm_op_export): Make static and rename to ... + (gpgsm_export): ... this. + (_gpgme_gpgsm_op_genkey): Make static and rename to ... + (gpgsm_genkey): ... this. + (_gpgme_gpgsm_op_import): Make static and rename to ... + (gpgsm_import): ... this. + (_gpgme_gpgsm_op_keylist): Make static and rename to ... + (gpgsm_keylist): ... this. + (_gpgme_gpgsm_op_keylist_ext): Make static and rename to ... + (gpgsm_keylist_ext): ... this. + (_gpgme_gpgsm_op_sign): Make static and rename to ... + (gpgsm_sign): ... this. + (_gpgme_gpgsm_op_trustlist): Make static and rename to ... + (gpgsm_trustlist): ... this. + (_gpgme_gpgsm_op_verify): Make static and rename to ... + (gpgsm_verify): ... this. + (gpgsm_status_handler): Rename to ... + (status_handler): ... this. + (_gpgme_gpgsm_set_status_handler): Make static and rename to ... + (gpgsm_set_status_handler): ... this. + (_gpgme_gpgsm_set_colon_line_handler): Make static and rename to ... + (gpgsm_set_colon_line_handler): ... this. + (_gpgme_gpgsm_add_io_cb): Rename to ... + (add_io_cb): ... this. + (_gpgme_gpgsm_start): Make static and rename to ... + (gpgsm_start): ... this. + (_gpgme_gpgsm_set_io_cb): Make static and rename to ... + (gpgsm_set_io_cb): ... this. + (_gpgme_gpgsm_io_event): Make static and rename to ... + (gpgsm_io_event): ... this. + (struct _gpgme_engine_ops_gpgsm): New variable. + [!ENABLE_GPGSM]: Removed. + * engine.c: Do not include , , , + , "io.h", "rungpg.h" and "engine-gpgsm.h". Include + and "engine-backend.h". + (struct engine_object_s): Rewritten. + (engine_ops): New variable. + * engine.c (_gpgme_engine_get_path, _gpgme_engine_get_version, + _gpgme_engine_check_version, _gpgme_engine_new, + _gpgme_engine_release, _gpgme_engine_set_verbosity, + _gpgme_engine_set_status_handler, + _gpgme_engine_set_command_handler, + _gpgme_engine_set_colon_line_handler, _gpgme_engine_op_decrypt, + _gpgme_engine_op_delete, _gpgme_engine_op_edit, + _gpgme_engine_op_encrypt, _gpgme_engine_op_encrypt_sign, + _gpgme_engine_op_export, _gpgme_engine_op_genkey, + _gpgme_engine_op_import, _gpgme_engine_op_keylist, + _gpgme_engine_op_keylist_ext, _gpgme_engine_op_sign, + _gpgme_engine_op_trustlist, _gpgme_engine_op_verify, + _gpgme_engine_start, _gpgme_engine_set_io_cbs, + _gpgme_engine_io_event): Reimplement. + * engine.h: Fix a few comments and a variable name in a prototype. + * ops.h: Do not include "rungpg.h". + * passphrase.c: Include config.h only if [HAVE_CONFIG_H]. Do not + include "rungpg.h". + * recipient.c: Likewise. + * signers.c: Likewise. + * version.c: Likewise. + * rungpg.c: Likewise. Include "engine-backend.h". Reorder + functions and remove prototypes. + (_gpgme_gpg_get_version): Make static and rename to ... + (gpg_get_version): ... this. + (_gpgme_gpg_check_version): Make static and rename to ... + (gpg_check_version): ... this. + (_gpgme_gpg_new): Make static. Change argument type from + GpgObject * to void **. Call gpg_release instead + _gpgme_gpg_release. + (_gpgme_gpg_op_decrypt): Make static and rename to ... + (gpg_check_decrypt): ... this. + (_gpgme_gpg_op_delete): Make static and rename to ... + (gpg_check_delete): ... this. + (_gpgme_gpg_set_recipients): Make static and rename to ... + (gpg_check_set_recipients): ... this. + (_gpgme_gpg_op_encrypt): Make static and rename to ... + (gpg_encrypt): ... this. + (_gpgme_gpg_op_export): Make static and rename to ... + (gpg_export): ... this. + (_gpgme_gpg_op_genkey): Make static and rename to ... + (gpg_genkey): ... this. + (_gpgme_gpg_op_import): Make static and rename to ... + (gpg_import): ... this. + (_gpgme_gpg_op_keylist): Make static and rename to ... + (gpg_keylist): ... this. + (_gpgme_gpg_op_keylist_ext): Make static and rename to ... + (gpg_keylist_ext): ... this. + (_gpgme_gpg_op_sign): Make static and rename to ... + (gpg_sign): ... this. + (_gpgme_gpg_op_trustlist): Make static and rename to ... + (gpg_trustlist): ... this. + (_gpgme_gpg_op_verify): Make static and rename to ... + (gpg_verify): ... this. + (gpg_status_handler): Rename to ... + (status_handler): ... this. + (_gpgme_gpg_set_status_handler): Make static and rename to ... + (gpg_set_status_handler): ... this. + (_gpgme_gpg_set_colon_line_handler): Make static and rename to ... + (gpg_set_colon_line_handler): ... this. + (gpgme_gpg_add_io_cb): Rename to ... + (add_io_cb): ... this. + (_gpgme_gpg_start): Make static and rename to ... + (gpg_start): ... this. + (_gpgme_gpg_set_io_cb): Make static and rename to ... + (gpg_set_io_cb): ... this. + (_gpgme_gpg_io_event): Make static and rename to ... + (gpg_io_event): ... this. + (struct _gpgme_engine_ops_gpg): New variable. + 2002-10-10 Marcus Brinkmann * engine-gpgsm.c (_gpgme_gpgsm_op_verify) [!ENABLE_GPGSM]: Add diff --git a/gpgme/Makefile.am b/gpgme/Makefile.am index 523b283..8c8440b 100644 --- a/gpgme/Makefile.am +++ b/gpgme/Makefile.am @@ -55,6 +55,12 @@ else system_components = ${ath_components} posix-util.c posix-sema.c posix-io.c endif +if HAVE_GPGSM +gpgsm_components = engine-gpgsm.c +else +gpgsm_components = +endif + libgpgme_la_SOURCES = \ gpgme.h types.h util.h conversion.c context.h ops.h \ data.h data.c data-fd.c data-stream.c data-mem.c data-user.c \ @@ -64,15 +70,14 @@ libgpgme_la_SOURCES = \ sign.c passphrase.c progress.c \ key.h key.c keylist.c trustlist.c \ import.c export.c genkey.c delete.c edit.c \ - engine.h engine.c rungpg.h rungpg.c status-table.h \ - engine-gpgsm.c engine-gpgsm.h \ - sema.h io.h ${system_components} \ + engine.h engine-backend.h engine.c rungpg.c status-table.h \ + ${gpgsm_components} sema.h io.h ${system_components} \ debug.c debug.h gpgme.c version.c errors.c libgpgme_la_LIBADD = ${assuan_libobjs} @LTLIBOBJS@ errors.c : gpgme.h $(srcdir)/mkerrors < $(srcdir)/gpgme.h > errors.c -status-table.h : rungpg.h +status-table.h : gpgme.h $(srcdir)/mkstatus < $(srcdir)/gpgme.h > status-table.h diff --git a/gpgme/conversion.c b/gpgme/conversion.c index 36b11fd..e0344ec 100644 --- a/gpgme/conversion.c +++ b/gpgme/conversion.c @@ -1,23 +1,22 @@ /* conversion.c - String conversion helper functions. - * Copyright (C) 2000 Werner Koch (dd9jn) - * Copyright (C) 2001, 2002 g10 Code GmbH - * - * 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 - */ + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002 g10 Code GmbH + + 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 GPGME; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if HAVE_CONFIG_H #include @@ -27,6 +26,7 @@ #include #include #include +#include #include "gpgme.h" #include "util.h" diff --git a/gpgme/engine-backend.h b/gpgme/engine-backend.h new file mode 100644 index 0000000..70c2c03 --- /dev/null +++ b/gpgme/engine-backend.h @@ -0,0 +1,88 @@ +/* engine-backend.h - A crypto backend for the engine interface. + Copyright (C) 2002 g10 Code GmbH + + 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 GPGME; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef ENGINE_BACKEND_H +#define ENGINE_BACKEND_H + +#include "types.h" + + +/* FIXME: Correct check? */ +#ifdef GPGSM_PATH +#define ENABLE_GPGSM 1 +#endif + + +struct engine_ops +{ + /* Static functions. */ + const char *(*get_path) (void); + const char *(*get_version) (void); + GpgmeError (*check_version) (void); + GpgmeError (*new) (void **r_engine); + + /* Member functions. */ + void (*release) (void *engine); + void (*set_status_handler) (void *engine, GpgmeStatusHandler fnc, + void *fnc_value); + GpgmeError (*set_command_handler) (void *engine, GpgmeCommandHandler fnc, + void *fnc_value, GpgmeData data); + GpgmeError (*set_colon_line_handler) (void *engine, + GpgmeColonLineHandler fnc, + void *fnc_value); + GpgmeError (*set_verbosity) (void *engine, int verbosity); + GpgmeError (*decrypt) (void *engine, GpgmeData ciph, GpgmeData plain); + GpgmeError (*delete) (void *engine, GpgmeKey key, int allow_secret); + GpgmeError (*edit) (void *engine, GpgmeKey key, GpgmeData out, + GpgmeCtx ctx /* FIXME */); + GpgmeError (*encrypt) (void *engine, GpgmeRecipients recp, + GpgmeData plain, GpgmeData ciph, int use_armor); + GpgmeError (*encrypt_sign) (void *engine, GpgmeRecipients recp, + GpgmeData plain, GpgmeData ciph, + int use_armor, GpgmeCtx ctx /* FIXME */); + GpgmeError (*export) (void *engine, GpgmeRecipients recp, + GpgmeData keydata, int use_armor); + GpgmeError (*genkey) (void *engine, GpgmeData help_data, int use_armor, + GpgmeData pubkey, GpgmeData seckey); + GpgmeError (*import) (void *engine, GpgmeData keydata); + GpgmeError (*keylist) (void *engine, const char *pattern, + int secret_only, int keylist_mode); + GpgmeError (*keylist_ext) (void *engine, const char *pattern[], + int secret_only, int reserved, + int keylist_mode); + GpgmeError (*sign) (void *engine, GpgmeData in, GpgmeData out, + GpgmeSigMode mode, int use_armor, int use_textmode, + int include_certs, GpgmeCtx ctx /* FIXME */); + GpgmeError (*trustlist) (void *engine, const char *pattern); + GpgmeError (*verify) (void *engine, GpgmeData sig, GpgmeData signed_text, + GpgmeData plaintext); + GpgmeError (*start) (void *engine, void *opaque); + + void (*set_io_cbs) (void *engine, struct GpgmeIOCbs *io_cbs); + void (*io_event) (void *engine, GpgmeEventIO type, void *type_data); +}; + + +extern struct engine_ops _gpgme_engine_ops_gpg; /* OpenPGP. */ +#ifdef ENABLE_GPGSM +extern struct engine_ops _gpgme_engine_ops_gpgsm; /* CMS. */ +#endif + +#endif /* ENGINE_BACKEND_H */ + diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index 0955c95..87bbb34 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -22,13 +22,6 @@ #include #endif -/* FIXME: Correct check? */ -#ifdef GPGSM_PATH -#define ENABLE_GPGSM 1 -#endif - -#ifdef ENABLE_GPGSM - #include #include #include @@ -46,18 +39,17 @@ #include "key.h" #include "sema.h" +#include "assuan.h" #include "status-table.h" -#include "engine-gpgsm.h" +#include "engine-backend.h" -#include "assuan.h" #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) - typedef struct { int fd; /* FD we talk about. */ @@ -66,6 +58,7 @@ typedef struct void *tag; /* ID from the user for gpgme_remove_io_callback. */ } iocb_data_t; + struct gpgsm_object_s { ASSUAN_CONTEXT assuan_ctx; @@ -107,8 +100,8 @@ struct gpgsm_object_s }; -const char * -_gpgme_gpgsm_get_version (void) +static const char * +gpgsm_get_version (void) { static const char *gpgsm_version; DEFINE_STATIC_LOCK (gpgsm_version_lock); @@ -122,11 +115,10 @@ _gpgme_gpgsm_get_version (void) } -GpgmeError -_gpgme_gpgsm_check_version (void) +static GpgmeError +gpgsm_check_version (void) { - return _gpgme_compare_versions (_gpgme_gpgsm_get_version (), - NEED_GPGSM_VERSION) + return _gpgme_compare_versions (gpgsm_get_version (), NEED_GPGSM_VERSION) ? 0 : mk_error (Invalid_Engine); } @@ -282,8 +274,33 @@ map_assuan_error (AssuanError err) } -GpgmeError -_gpgme_gpgsm_new (GpgsmObject *r_gpgsm) +static void +gpgsm_release (void *engine) +{ + GpgsmObject gpgsm = engine; + + if (!gpgsm) + return; + + if (gpgsm->status_cb.fd != -1) + _gpgme_io_close (gpgsm->status_cb.fd); + if (gpgsm->input_cb.fd != -1) + _gpgme_io_close (gpgsm->input_cb.fd); + if (gpgsm->output_cb.fd != -1) + _gpgme_io_close (gpgsm->output_cb.fd); + if (gpgsm->message_cb.fd != -1) + _gpgme_io_close (gpgsm->message_cb.fd); + + assuan_disconnect (gpgsm->assuan_ctx); + + free (gpgsm->colon.attic.line); + free (gpgsm->command); + free (gpgsm); +} + + +static GpgmeError +gpgsm_new (void **engine) { GpgmeError err = 0; GpgsmObject gpgsm; @@ -299,7 +316,6 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm) int fdlist[5]; int nfds; - *r_gpgsm = NULL; gpgsm = calloc (1, sizeof *gpgsm); if (!gpgsm) { @@ -505,7 +521,7 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm) leave: /* Close the server ends of the pipes. Our ends are closed in - _gpgme_gpgsm_release. */ + gpgsm_release(). */ if (gpgsm->input_fd_server != -1) _gpgme_io_close (gpgsm->input_fd_server); if (gpgsm->output_fd_server != -1) @@ -514,36 +530,14 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm) _gpgme_io_close (gpgsm->message_fd_server); if (err) - _gpgme_gpgsm_release (gpgsm); + gpgsm_release (gpgsm); else - *r_gpgsm = gpgsm; + *engine = gpgsm; return err; } -void -_gpgme_gpgsm_release (GpgsmObject gpgsm) -{ - if (!gpgsm) - return; - - if (gpgsm->status_cb.fd != -1) - _gpgme_io_close (gpgsm->status_cb.fd); - if (gpgsm->input_cb.fd != -1) - _gpgme_io_close (gpgsm->input_cb.fd); - if (gpgsm->output_cb.fd != -1) - _gpgme_io_close (gpgsm->output_cb.fd); - if (gpgsm->message_cb.fd != -1) - _gpgme_io_close (gpgsm->message_cb.fd); - - assuan_disconnect (gpgsm->assuan_ctx); - - free (gpgsm->colon.attic.line); - free (gpgsm->command); - free (gpgsm); -} - /* Forward declaration. */ static GpgmeStatusCode parse_status (const char *name); @@ -639,9 +633,10 @@ map_input_enc (GpgmeData d) } -GpgmeError -_gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph, GpgmeData plain) +static GpgmeError +gpgsm_decrypt (void *engine, GpgmeData ciph, GpgmeData plain) { + GpgsmObject gpgsm = engine; GpgmeError err; if (!gpgsm) @@ -666,9 +661,10 @@ _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph, GpgmeData plain) } -GpgmeError -_gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key, int allow_secret) +static GpgmeError +gpgsm_delete (void *engine, GpgmeKey key, int allow_secret) { + GpgsmObject gpgsm = engine; char *fpr = (char *) gpgme_key_get_string_attr (key, GPGME_ATTR_FPR, NULL, 0); char *linep = fpr; char *line; @@ -730,7 +726,7 @@ _gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key, int allow_secret) static GpgmeError -gpgsm_set_recipients (GpgsmObject gpgsm, GpgmeRecipients recp) +set_recipients (GpgsmObject gpgsm, GpgmeRecipients recp) { GpgmeError err; ASSUAN_CONTEXT ctx = gpgsm->assuan_ctx; @@ -777,10 +773,11 @@ gpgsm_set_recipients (GpgsmObject gpgsm, GpgmeRecipients recp) } -GpgmeError -_gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp, - GpgmeData plain, GpgmeData ciph, int use_armor) +static GpgmeError +gpgsm_encrypt (void *engine, GpgmeRecipients recp, GpgmeData plain, + GpgmeData ciph, int use_armor) { + GpgsmObject gpgsm = engine; GpgmeError err; if (!gpgsm) @@ -804,7 +801,7 @@ _gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp, return err; _gpgme_io_close (gpgsm->message_cb.fd); - err = gpgsm_set_recipients (gpgsm, recp); + err = set_recipients (gpgsm, recp); if (err) return err; @@ -812,10 +809,11 @@ _gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp, } -GpgmeError -_gpgme_gpgsm_op_export (GpgsmObject gpgsm, GpgmeRecipients recp, - GpgmeData keydata, int use_armor) +static GpgmeError +gpgsm_export (void *engine, GpgmeRecipients recp, GpgmeData keydata, + int use_armor) { + GpgsmObject gpgsm = engine; GpgmeError err = 0; char *cmd = NULL; int cmdi; @@ -875,10 +873,11 @@ _gpgme_gpgsm_op_export (GpgsmObject gpgsm, GpgmeRecipients recp, } -GpgmeError -_gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data, int use_armor, - GpgmeData pubkey, GpgmeData seckey) +static GpgmeError +gpgsm_genkey (void *engine, GpgmeData help_data, int use_armor, + GpgmeData pubkey, GpgmeData seckey) { + GpgsmObject gpgsm = engine; GpgmeError err; if (!gpgsm || !pubkey || seckey) @@ -904,9 +903,10 @@ _gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data, int use_armor, } -GpgmeError -_gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata) +static GpgmeError +gpgsm_import (void *engine, GpgmeData keydata) { + GpgsmObject gpgsm = engine; GpgmeError err; if (!gpgsm) @@ -928,10 +928,11 @@ _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata) } -GpgmeError -_gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern, - int secret_only, int keylist_mode) +static GpgmeError +gpgsm_keylist (void *engine, const char *pattern, int secret_only, + int keylist_mode) { + GpgsmObject gpgsm = engine; char *line; GpgmeError err; @@ -969,10 +970,11 @@ _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern, } -GpgmeError -_gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm, const char *pattern[], - int secret_only, int reserved, int keylist_mode) +static GpgmeError +gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only, + int reserved, int keylist_mode) { + GpgsmObject gpgsm = engine; char *line; GpgmeError err; /* Length is "LISTSECRETKEYS " + p + '\0'. */ @@ -1068,12 +1070,12 @@ _gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm, const char *pattern[], } -GpgmeError -_gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out, - GpgmeSigMode mode, int use_armor, - int use_textmode, int include_certs, - GpgmeCtx ctx /* FIXME */) +static GpgmeError +gpgsm_sign (void *engine, GpgmeData in, GpgmeData out, GpgmeSigMode mode, + int use_armor, int use_textmode, int include_certs, + GpgmeCtx ctx /* FIXME */) { + GpgsmObject gpgsm = engine; GpgmeError err; char *assuan_cmd; int i; @@ -1135,18 +1137,19 @@ _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out, } -GpgmeError -_gpgme_gpgsm_op_trustlist (GpgsmObject gpgsm, const char *pattern) +static GpgmeError +gpgsm_trustlist (void *engine, const char *pattern) { /* FIXME */ return mk_error (Not_Implemented); } -GpgmeError -_gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData signed_text, - GpgmeData plaintext) +static GpgmeError +gpgsm_verify (void *engine, GpgmeData sig, GpgmeData signed_text, + GpgmeData plaintext) { + GpgsmObject gpgsm = engine; GpgmeError err; if (!gpgsm) @@ -1206,7 +1209,7 @@ parse_status (const char *name) static void -gpgsm_status_handler (void *opaque, int fd) +status_handler (void *opaque, int fd) { AssuanError err; GpgsmObject gpgsm = opaque; @@ -1358,32 +1361,32 @@ gpgsm_status_handler (void *opaque, int fd) } -void -_gpgme_gpgsm_set_status_handler (GpgsmObject gpgsm, - GpgmeStatusHandler fnc, void *fnc_value) +static void +gpgsm_set_status_handler (void *engine, GpgmeStatusHandler fnc, + void *fnc_value) { - assert (gpgsm); + GpgsmObject gpgsm = engine; gpgsm->status.fnc = fnc; gpgsm->status.fnc_value = fnc_value; } -void -_gpgme_gpgsm_set_colon_line_handler (GpgsmObject gpgsm, - GpgmeColonLineHandler fnc, void *fnc_value) +static GpgmeError +gpgsm_set_colon_line_handler (void *engine, GpgmeColonLineHandler fnc, + void *fnc_value) { - assert (gpgsm); + GpgsmObject gpgsm = engine; gpgsm->colon.fnc = fnc; gpgsm->colon.fnc_value = fnc_value; gpgsm->colon.any = 0; + return 0; } static GpgmeError -_gpgme_gpgsm_add_io_cb (GpgsmObject gpgsm, iocb_data_t *iocbd, - GpgmeIOCb handler) +add_io_cb (GpgsmObject gpgsm, iocb_data_t *iocbd, GpgmeIOCb handler) { GpgmeError err; @@ -1398,9 +1401,11 @@ _gpgme_gpgsm_add_io_cb (GpgsmObject gpgsm, iocb_data_t *iocbd, return err; } -GpgmeError -_gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque) + +static GpgmeError +gpgsm_start (void *engine, void *opaque) { + GpgsmObject gpgsm = engine; GpgmeError err = 0; pid_t pid; @@ -1409,17 +1414,13 @@ _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque) pid = assuan_get_pid (gpgsm->assuan_ctx); - err = _gpgme_gpgsm_add_io_cb (gpgsm, &gpgsm->status_cb, - gpgsm_status_handler); + err = add_io_cb (gpgsm, &gpgsm->status_cb, status_handler); if (gpgsm->input_cb.fd != -1) - err = _gpgme_gpgsm_add_io_cb (gpgsm, &gpgsm->input_cb, - _gpgme_data_outbound_handler); + err = add_io_cb (gpgsm, &gpgsm->input_cb, _gpgme_data_outbound_handler); if (!err && gpgsm->output_cb.fd != -1) - err = _gpgme_gpgsm_add_io_cb (gpgsm, &gpgsm->output_cb, - _gpgme_data_inbound_handler); + err = add_io_cb (gpgsm, &gpgsm->output_cb, _gpgme_data_inbound_handler); if (!err && gpgsm->message_cb.fd != -1) - err = _gpgme_gpgsm_add_io_cb (gpgsm, &gpgsm->message_cb, - _gpgme_data_outbound_handler); + err = add_io_cb (gpgsm, &gpgsm->message_cb, _gpgme_data_outbound_handler); if (!err) err = assuan_write_line (gpgsm->assuan_ctx, gpgsm->command); @@ -1427,170 +1428,53 @@ _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque) return err; } -void -_gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs) -{ - gpgsm->io_cbs = *io_cbs; -} - -void -_gpgme_gpgsm_io_event (GpgsmObject gpgsm, GpgmeEventIO type, void *type_data) -{ - if (gpgsm->io_cbs.event) - (*gpgsm->io_cbs.event) (gpgsm->io_cbs.event_priv, type, type_data); -} - -#else /* ENABLE_GPGSM */ - -#include -#include "util.h" - -#include "engine-gpgsm.h" - - -const char * -_gpgme_gpgsm_get_version (void) -{ - return NULL; -} - - -GpgmeError -_gpgme_gpgsm_check_version (void) -{ - return mk_error (Invalid_Engine); -} - - -GpgmeError -_gpgme_gpgsm_new (GpgsmObject *r_gpgsm) -{ - return mk_error (Invalid_Engine); -} - - -void -_gpgme_gpgsm_release (GpgsmObject gpgsm) -{ - return; -} - - -void -_gpgme_gpgsm_set_status_handler (GpgsmObject gpgsm, - GpgmeStatusHandler fnc, void *fnc_value) -{ - return; -} - - -GpgmeError -_gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph, GpgmeData plain) -{ - return mk_error (Invalid_Engine); -} - - -GpgmeError -_gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key, int allow_secret) -{ - return mk_error (Invalid_Engine); -} - - -GpgmeError -_gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp, - GpgmeData plain, GpgmeData ciph, int use_armor) -{ - return mk_error (Invalid_Engine); -} - - -GpgmeError -_gpgme_gpgsm_op_export (GpgsmObject gpgsm, GpgmeRecipients recp, - GpgmeData keydata, int use_armor) -{ - return mk_error (Invalid_Engine); -} - - -GpgmeError -_gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data, int use_armor, - GpgmeData pubkey, GpgmeData seckey) -{ - return mk_error (Invalid_Engine); -} - - -GpgmeError -_gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata) -{ - return mk_error (Invalid_Engine); -} - - -GpgmeError -_gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern, - int secret_only, int keylist_mode) -{ - return mk_error (Invalid_Engine); -} - - -GpgmeError -_gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm, const char *pattern[], - int secret_only, int reserved, int keylist_mode) -{ - return mk_error (Invalid_Engine); -} - -GpgmeError -_gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out, - GpgmeSigMode mode, int use_armor, - int use_textmode, int include_certs, - GpgmeCtx ctx /* FIXME */) -{ - return mk_error (Invalid_Engine); -} - - -GpgmeError -_gpgme_gpgsm_op_trustlist (GpgsmObject gpgsm, const char *pattern) -{ - return mk_error (Invalid_Engine); -} - - -GpgmeError -_gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData signed_text, - GpgmeData plaintest) -{ - return mk_error (Invalid_Engine); -} - - -void -_gpgme_gpgsm_set_colon_line_handler (GpgsmObject gpgsm, - GpgmeColonLineHandler fnc, void *fnc_value) +static void +gpgsm_set_io_cbs (void *engine, struct GpgmeIOCbs *io_cbs) { + GpgsmObject gpgsm = engine; + gpgsm->io_cbs = *io_cbs; } -GpgmeError -_gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque) +static void +gpgsm_io_event (void *engine, GpgmeEventIO type, void *type_data) { - return mk_error (Invalid_Engine); -} + GpgsmObject gpgsm = engine; -void -_gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs) -{ + if (gpgsm->io_cbs.event) + (*gpgsm->io_cbs.event) (gpgsm->io_cbs.event_priv, type, type_data); } -void -_gpgme_gpgsm_io_event (GpgsmObject gpgsm, GpgmeEventIO type, void *type_data) -{ -} -#endif /* ! ENABLE_GPGSM */ +struct engine_ops _gpgme_engine_ops_gpgsm = + { + /* Static functions. */ + _gpgme_get_gpgsm_path, + gpgsm_get_version, + gpgsm_check_version, + gpgsm_new, + + /* Member functions. */ + gpgsm_release, + gpgsm_set_status_handler, + NULL, /* set_command_handler */ + gpgsm_set_colon_line_handler, + NULL, /* set_verbosity */ + gpgsm_decrypt, + gpgsm_delete, + NULL, /* edit */ + gpgsm_encrypt, + NULL, + gpgsm_export, + gpgsm_genkey, + gpgsm_import, + gpgsm_keylist, + gpgsm_keylist_ext, + gpgsm_sign, + gpgsm_trustlist, + gpgsm_verify, + gpgsm_start, + gpgsm_set_io_cbs, + gpgsm_io_event + }; diff --git a/gpgme/engine-gpgsm.h b/gpgme/engine-gpgsm.h deleted file mode 100644 index 9b6cf92..0000000 --- a/gpgme/engine-gpgsm.h +++ /dev/null @@ -1,67 +0,0 @@ -/* engine-gpgsm.h - GPGME GpgSM engine calling functions - Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002 g10 Code GmbH - - 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 GPGME; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef ENGINE_GPGSM_H -#define ENGINE_GPGSM_H - -#include "types.h" - -const char *_gpgme_gpgsm_get_version (void); -GpgmeError _gpgme_gpgsm_check_version (void); - -GpgmeError _gpgme_gpgsm_new (GpgsmObject *r_gpg); -void _gpgme_gpgsm_release (GpgsmObject gpg); - -void _gpgme_gpgsm_set_status_handler (GpgsmObject gpgsm, - GpgmeStatusHandler fnc, void *fnc_value); -void _gpgme_gpgsm_set_colon_line_handler (GpgsmObject gpgsm, - GpgmeColonLineHandler fnc, void *fnc_value) ; -GpgmeError _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph, - GpgmeData plain); -GpgmeError _gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key, - int allow_secret); -GpgmeError _gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp, - GpgmeData plain, GpgmeData ciph, - int use_armor); -GpgmeError _gpgme_gpgsm_op_export (GpgsmObject gpgsm, GpgmeRecipients recp, - GpgmeData keydata, int use_armor); -GpgmeError _gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data, - int use_armor, GpgmeData pubkey, - GpgmeData seckey); -GpgmeError _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata); -GpgmeError _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern, - int secret_only, int keylist_mode); -GpgmeError _gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm, - const char *pattern[], - int secret_only, int reserved, - int keylist_mode); -GpgmeError _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, - GpgmeData out, - GpgmeSigMode mode, int use_armor, - int use_textmode, int include_certs, - GpgmeCtx ctx /* FIXME */); -GpgmeError _gpgme_gpgsm_op_trustlist (GpgsmObject gpgsm, const char *pattern); -GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, - GpgmeData signed_text, GpgmeData plaintext); -GpgmeError _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque); -void _gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs); -void _gpgme_gpgsm_io_event (GpgsmObject gpgsm, GpgmeEventIO type, void *type_data); - -#endif /* ENGINE_GPGSM_H */ diff --git a/gpgme/engine.c b/gpgme/engine.c index c5323ad..66a492d 100644 --- a/gpgme/engine.c +++ b/gpgme/engine.c @@ -1,4 +1,4 @@ -/* engine.c +/* engine.c - GPGME engine support. Copyright (C) 2000 Werner Koch (dd9jn) Copyright (C) 2001, 2002 g10 Code GmbH @@ -21,49 +21,45 @@ #ifdef HAVE_CONFIG_H #include #endif -#include -#include -#include -#include +#include #include "gpgme.h" #include "util.h" #include "sema.h" -#include "io.h" #include "engine.h" -#include "rungpg.h" -#include "engine-gpgsm.h" +#include "engine-backend.h" struct engine_object_s - { - GpgmeProtocol protocol; +{ + struct engine_ops *ops; + void *engine; +}; - const char *path; - const char *version; - union - { - GpgObject gpg; - GpgsmObject gpgsm; - } engine; -}; +static struct engine_ops *engine_ops[] = + { + &_gpgme_engine_ops_gpg, /* OpenPGP. */ +#ifdef ENABLE_GPGSM + &_gpgme_engine_ops_gpgsm /* CMS. */ +#else + NULL +#endif + }; /* Get the path of the engine for PROTOCOL. */ const char * _gpgme_engine_get_path (GpgmeProtocol proto) { - switch (proto) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_get_gpg_path (); - case GPGME_PROTOCOL_CMS: - return _gpgme_get_gpgsm_path (); - default: - return NULL; - } + if (proto > sizeof (engine_ops) / sizeof (engine_ops[0])) + return NULL; + + if (engine_ops[proto] && engine_ops[proto]->get_path) + return (*engine_ops[proto]->get_path) (); + else + return NULL; } @@ -71,30 +67,30 @@ _gpgme_engine_get_path (GpgmeProtocol proto) const char * _gpgme_engine_get_version (GpgmeProtocol proto) { - switch (proto) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_get_version (); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_get_version (); - default: - return NULL; - } + if (proto > sizeof (engine_ops) / sizeof (engine_ops[0])) + return NULL; + + if (engine_ops[proto] && engine_ops[proto]->get_version) + return (*engine_ops[proto]->get_version) (); + else + return NULL; } +/* Verify the version requirement for the engine for PROTOCOL. */ GpgmeError gpgme_engine_check_version (GpgmeProtocol proto) { - switch (proto) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_check_version (); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_check_version (); - default: - return mk_error (Invalid_Value); - } + if (proto > sizeof (engine_ops) / sizeof (engine_ops[0])) + return mk_error (Invalid_Value); + + if (!engine_ops[proto]) + return mk_error (Invalid_Engine); + + if (engine_ops[proto]->check_version) + return (*engine_ops[proto]->check_version) (); + else + return 0; } @@ -141,48 +137,40 @@ GpgmeError _gpgme_engine_new (GpgmeProtocol proto, EngineObject *r_engine) { EngineObject engine; - GpgmeError err = 0; + + const char *path; + const char *version; + + if (proto > sizeof (engine_ops) / sizeof (engine_ops[0])) + return mk_error (Invalid_Value); + + if (!engine_ops[proto]) + return mk_error (Invalid_Engine); + + path = _gpgme_engine_get_path (proto); + version = _gpgme_engine_get_version (proto); + if (!path || !version) + return mk_error (Invalid_Engine); engine = calloc (1, sizeof *engine); if (!engine) - { - err = mk_error (Out_Of_Core); - goto leave; - } + return mk_error (Out_Of_Core); - engine->protocol = proto; - switch (proto) + engine->ops = engine_ops[proto]; + if (engine_ops[proto]->new) { - case GPGME_PROTOCOL_OpenPGP: - err =_gpgme_gpg_new (&engine->engine.gpg); - break; - case GPGME_PROTOCOL_CMS: - err = _gpgme_gpgsm_new (&engine->engine.gpgsm); + GpgmeError err = (*engine_ops[proto]->new) (&engine->engine); if (err) - goto leave; - break; - default: - err = mk_error (Invalid_Value); - } - if (err) - goto leave; - - engine->path = _gpgme_engine_get_path (proto); - engine->version = _gpgme_engine_get_version (proto); - - if (!engine->path || !engine->version) - { - err = mk_error (Invalid_Engine); - goto leave; + { + free (engine); + return err; + } } - - leave: - if (err) - _gpgme_engine_release (engine); else - *r_engine = engine; - - return err; + engine->engine = NULL; + + *r_engine = engine; + return 0; } @@ -192,17 +180,8 @@ _gpgme_engine_release (EngineObject engine) if (!engine) return; - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - _gpgme_gpg_release (engine->engine.gpg); - break; - case GPGME_PROTOCOL_CMS: - _gpgme_gpgsm_release (engine->engine.gpgsm); - break; - default: - break; - } + if (engine->ops->release) + (*engine->ops->release) (engine->engine); free (engine); } @@ -213,19 +192,11 @@ _gpgme_engine_set_verbosity (EngineObject engine, int verbosity) if (!engine) return; - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - _gpgme_gpg_set_verbosity (engine->engine.gpg, verbosity); - break; - case GPGME_PROTOCOL_CMS: - /* FIXME */ - break; - default: - break; - } + if (engine->ops->set_verbosity) + (*engine->ops->set_verbosity) (engine->engine, verbosity); } + void _gpgme_engine_set_status_handler (EngineObject engine, GpgmeStatusHandler fnc, void *fnc_value) @@ -233,19 +204,11 @@ _gpgme_engine_set_status_handler (EngineObject engine, if (!engine) return; - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - _gpgme_gpg_set_status_handler (engine->engine.gpg, fnc, fnc_value); - break; - case GPGME_PROTOCOL_CMS: - _gpgme_gpgsm_set_status_handler (engine->engine.gpgsm, fnc, fnc_value); - break; - default: - break; - } + if (engine->ops->set_status_handler) + (*engine->ops->set_status_handler) (engine->engine, fnc, fnc_value); } + GpgmeError _gpgme_engine_set_command_handler (EngineObject engine, GpgmeCommandHandler fnc, void *fnc_value, @@ -254,18 +217,11 @@ _gpgme_engine_set_command_handler (EngineObject engine, if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_set_command_handler (engine->engine.gpg, - fnc, fnc_value, linked_data); - case GPGME_PROTOCOL_CMS: - /* FIXME */ - break; - default: - break; - } - return 0; + if (!engine->ops->set_command_handler) + return mk_error (Not_Implemented); + + return (*engine->ops->set_command_handler) (engine->engine, + fnc, fnc_value, linked_data); } GpgmeError _gpgme_engine_set_colon_line_handler (EngineObject engine, @@ -275,20 +231,11 @@ GpgmeError _gpgme_engine_set_colon_line_handler (EngineObject engine, if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_set_colon_line_handler (engine->engine.gpg, - fnc, fnc_value); - case GPGME_PROTOCOL_CMS: - _gpgme_gpgsm_set_colon_line_handler (engine->engine.gpgsm, - fnc, fnc_value); - break; - - default: - break; - } - return 0; + if (!engine->ops->set_colon_line_handler) + return mk_error (Not_Implemented); + + return (*engine->ops->set_colon_line_handler) (engine->engine, + fnc, fnc_value); } GpgmeError @@ -297,16 +244,10 @@ _gpgme_engine_op_decrypt (EngineObject engine, GpgmeData ciph, GpgmeData plain) if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_decrypt (engine->engine.gpg, ciph, plain); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_op_decrypt (engine->engine.gpgsm, ciph, plain); - default: - break; - } - return 0; + if (!engine->ops->decrypt) + return mk_error (Not_Implemented); + + return (*engine->ops->decrypt) (engine->engine, ciph, plain); } GpgmeError @@ -315,16 +256,10 @@ _gpgme_engine_op_delete (EngineObject engine, GpgmeKey key, int allow_secret) if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_delete (engine->engine.gpg, key, allow_secret); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_op_delete (engine->engine.gpgsm, key, allow_secret); - default: - break; - } - return 0; + if (!engine->ops->delete) + return mk_error (Not_Implemented); + + return (*engine->ops->delete) (engine->engine, key, allow_secret); } @@ -335,19 +270,13 @@ _gpgme_engine_op_edit (EngineObject engine, GpgmeKey key, GpgmeData out, if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_edit (engine->engine.gpg, key, out, ctx); - case GPGME_PROTOCOL_CMS: - /* FIXME */ - return mk_error (Not_Implemented); - default: - break; - } - return 0; + if (!engine->ops->edit) + return mk_error (Not_Implemented); + + return (*engine->ops->edit) (engine->engine, key, out, ctx); } + GpgmeError _gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp, GpgmeData plain, GpgmeData ciph, int use_armor) @@ -355,18 +284,11 @@ _gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp, if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_encrypt (engine->engine.gpg, recp, plain, ciph, - use_armor); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_op_encrypt (engine->engine.gpgsm, recp, plain, ciph, - use_armor); - default: - break; - } - return 0; + if (!engine->ops->encrypt) + return mk_error (Not_Implemented); + + return (*engine->ops->encrypt) (engine->engine, recp, plain, ciph, + use_armor); } @@ -378,17 +300,11 @@ _gpgme_engine_op_encrypt_sign (EngineObject engine, GpgmeRecipients recp, if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_encrypt_sign (engine->engine.gpg, recp, plain, ciph, - use_armor, ctx); - case GPGME_PROTOCOL_CMS: - return mk_error (Not_Implemented); - default: - break; - } - return 0; + if (!engine->ops->encrypt_sign) + return mk_error (Not_Implemented); + + return (*engine->ops->encrypt_sign) (engine->engine, recp, plain, ciph, + use_armor, ctx); } @@ -399,20 +315,14 @@ _gpgme_engine_op_export (EngineObject engine, GpgmeRecipients recp, if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_export (engine->engine.gpg, recp, keydata, - use_armor); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_op_export (engine->engine.gpgsm, recp, keydata, - use_armor); - default: - break; - } - return 0; + if (!engine->ops->export) + return mk_error (Not_Implemented); + + return (*engine->ops->export) (engine->engine, recp, keydata, + use_armor); } + GpgmeError _gpgme_engine_op_genkey (EngineObject engine, GpgmeData help_data, int use_armor, GpgmeData pubkey, GpgmeData seckey) @@ -420,36 +330,24 @@ _gpgme_engine_op_genkey (EngineObject engine, GpgmeData help_data, if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_genkey (engine->engine.gpg, help_data, use_armor, - pubkey, seckey); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_op_genkey (engine->engine.gpgsm, help_data, use_armor, - pubkey, seckey); - default: - break; - } - return 0; + if (!engine->ops->genkey) + return mk_error (Not_Implemented); + + return (*engine->ops->genkey) (engine->engine, help_data, use_armor, + pubkey, seckey); } + GpgmeError _gpgme_engine_op_import (EngineObject engine, GpgmeData keydata) { if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_import (engine->engine.gpg, keydata); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_op_import (engine->engine.gpgsm, keydata); - default: - break; - } - return 0; + if (!engine->ops->import) + return mk_error (Not_Implemented); + + return (*engine->ops->import) (engine->engine, keydata); } @@ -460,18 +358,11 @@ _gpgme_engine_op_keylist (EngineObject engine, const char *pattern, if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_keylist (engine->engine.gpg, pattern, secret_only, - keylist_mode); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_op_keylist (engine->engine.gpgsm, pattern, secret_only, - keylist_mode); - default: - break; - } - return 0; + if (!engine->ops->keylist) + return mk_error (Not_Implemented); + + return (*engine->ops->keylist) (engine->engine, pattern, secret_only, + keylist_mode); } @@ -482,18 +373,11 @@ _gpgme_engine_op_keylist_ext (EngineObject engine, const char *pattern[], if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_keylist_ext (engine->engine.gpg, pattern, - secret_only, reserved, keylist_mode); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_op_keylist_ext (engine->engine.gpgsm, pattern, - secret_only, reserved, keylist_mode); - default: - break; - } - return 0; + if (!engine->ops->keylist_ext) + return mk_error (Not_Implemented); + + return (*engine->ops->keylist_ext) (engine->engine, pattern, secret_only, + reserved, keylist_mode); } @@ -506,39 +390,27 @@ _gpgme_engine_op_sign (EngineObject engine, GpgmeData in, GpgmeData out, if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_sign (engine->engine.gpg, in, out, mode, use_armor, - use_textmode, ctx); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_op_sign (engine->engine.gpgsm, in, out, mode, - use_armor, use_textmode, include_certs, ctx); - break; - default: - break; - } - return 0; + if (!engine->ops->sign) + return mk_error (Not_Implemented); + + return (*engine->ops->sign) (engine->engine, in, out, mode, use_armor, + use_textmode, include_certs, ctx); } + GpgmeError _gpgme_engine_op_trustlist (EngineObject engine, const char *pattern) { if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_trustlist (engine->engine.gpg, pattern); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_op_trustlist (engine->engine.gpgsm, pattern); - default: - break; - } - return 0; + if (!engine->ops->trustlist) + return mk_error (Not_Implemented); + + return (*engine->ops->trustlist) (engine->engine, pattern); } + GpgmeError _gpgme_engine_op_verify (EngineObject engine, GpgmeData sig, GpgmeData signed_text, GpgmeData plaintext) @@ -546,38 +418,26 @@ _gpgme_engine_op_verify (EngineObject engine, GpgmeData sig, if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_op_verify (engine->engine.gpg, sig, - signed_text, plaintext); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_op_verify (engine->engine.gpgsm, sig, - signed_text, plaintext); - default: - break; - } - return 0; + if (!engine->ops->verify) + return mk_error (Not_Implemented); + + return (*engine->ops->verify) (engine->engine, sig, signed_text, plaintext); } + GpgmeError _gpgme_engine_start (EngineObject engine, void *opaque) { if (!engine) return mk_error (Invalid_Value); - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - return _gpgme_gpg_spawn (engine->engine.gpg, opaque); - case GPGME_PROTOCOL_CMS: - return _gpgme_gpgsm_start (engine->engine.gpgsm, opaque); - default: - break; - } - return 0; + if (!engine->ops->start) + return mk_error (Not_Implemented); + + return (*engine->ops->start) (engine->engine, opaque); } + void _gpgme_engine_set_io_cbs (EngineObject engine, struct GpgmeIOCbs *io_cbs) @@ -585,17 +445,7 @@ _gpgme_engine_set_io_cbs (EngineObject engine, if (!engine) return; - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - _gpgme_gpg_set_io_cbs (engine->engine.gpg, io_cbs); - break; - case GPGME_PROTOCOL_CMS: - _gpgme_gpgsm_set_io_cbs (engine->engine.gpgsm, io_cbs); - break; - default: - break; - } + (*engine->ops->set_io_cbs) (engine->engine, io_cbs); } void @@ -605,15 +455,5 @@ _gpgme_engine_io_event (EngineObject engine, if (!engine) return; - switch (engine->protocol) - { - case GPGME_PROTOCOL_OpenPGP: - _gpgme_gpg_io_event (engine->engine.gpg, type, type_data); - break; - case GPGME_PROTOCOL_CMS: - _gpgme_gpgsm_io_event (engine->engine.gpgsm, type, type_data); - break; - default: - break; - } + (*engine->ops->io_event) (engine->engine, type, type_data); } diff --git a/gpgme/engine.h b/gpgme/engine.h index c2da9c8..27fc5ac 100644 --- a/gpgme/engine.h +++ b/gpgme/engine.h @@ -1,32 +1,37 @@ -/* engine.h - GPGME engine calling functions - * Copyright (C) 2000 Werner Koch (dd9jn) - * Copyright (C) 2001, 2002 g10 Code GmbH - * - * 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 - */ +/* engine.h - GPGME engine interface. + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002 g10 Code GmbH + + 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 GPGME; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef ENGINE_H #define ENGINE_H #include "types.h" +/* Get the path of the engine for PROTOCOL. */ const char *_gpgme_engine_get_path (GpgmeProtocol proto); + +/* Get the version number of the engine for PROTOCOL. */ const char *_gpgme_engine_get_version (GpgmeProtocol proto); -const char * _gpgme_engine_get_info (GpgmeProtocol proto); + +/* Verify the version requirement for the engine for PROTOCOL. */ +const char *_gpgme_engine_get_info (GpgmeProtocol proto); + GpgmeError _gpgme_engine_new (GpgmeProtocol proto, EngineObject *r_engine); void _gpgme_engine_release (EngineObject engine); void _gpgme_engine_set_status_handler (EngineObject engine, @@ -35,7 +40,7 @@ GpgmeError _gpgme_engine_set_command_handler (EngineObject engine, GpgmeCommandHandler fnc, void *fnc_value, GpgmeData data); -GpgmeError _gpgme_engine_set_colon_line_handler (EngineObject gpg, +GpgmeError _gpgme_engine_set_colon_line_handler (EngineObject engine, GpgmeColonLineHandler fnc, void *fnc_value); void _gpgme_engine_set_verbosity (EngineObject engine, int verbosity); diff --git a/gpgme/ops.h b/gpgme/ops.h index 500792d..4398de5 100644 --- a/gpgme/ops.h +++ b/gpgme/ops.h @@ -1,29 +1,27 @@ /* ops.h - internal operations stuff - * Copyright (C) 2000 Werner Koch (dd9jn) - * Copyright (C) 2001, 2002 g10 Code GmbH - * - * 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 - */ + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002 g10 Code GmbH + + 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 GPGME; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef OPS_H #define OPS_H #include "types.h" -#include "rungpg.h" /* Support macros. */ diff --git a/gpgme/passphrase.c b/gpgme/passphrase.c index 36e2dc8..a8900a7 100644 --- a/gpgme/passphrase.c +++ b/gpgme/passphrase.c @@ -1,25 +1,26 @@ /* passphrase.c - passphrase functions - * Copyright (C) 2000 Werner Koch (dd9jn) - * Copyright (C) 2001, 2002 g10 Code GmbH - * - * 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 - */ - + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002 g10 Code GmbH + + 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 GPGME; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#if HAVE_CONFIG_H #include +#endif #include #include #include @@ -172,7 +173,8 @@ _gpgme_passphrase_start (GpgmeCtx ctx) GpgmeError err = 0; if (ctx->passphrase_cb) - err = _gpgme_engine_set_command_handler (ctx->engine, _gpgme_passphrase_command_handler, + err = _gpgme_engine_set_command_handler (ctx->engine, + _gpgme_passphrase_command_handler, ctx, NULL); return err; } diff --git a/gpgme/recipient.c b/gpgme/recipient.c index df1fe5c..31712c6 100644 --- a/gpgme/recipient.c +++ b/gpgme/recipient.c @@ -1,25 +1,26 @@ /* recipient.c - mainatin recipient sets - * Copyright (C) 2000 Werner Koch (dd9jn) - * Copyright (C) 2001 g10 Code GmbH - * - * 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 - */ - + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002 g10 Code GmbH + + 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 GPGME; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#if HAVE_CONFIG_H #include +#endif #include #include #include @@ -27,7 +28,6 @@ #include "util.h" #include "context.h" -#include "rungpg.h" /** * gpgme_recipients_new: diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index b6bc45d..19ca74d 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -1,25 +1,26 @@ -/* rungpg.c - * Copyright (C) 2000 Werner Koch (dd9jn) - * Copyright (C) 2001, 2002 g10 Code GmbH - * - * 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 - */ - +/* rungpg.c - Gpg Engine. + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002 g10 Code GmbH + + 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 GPGME; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#if HAVE_CONFIG_H #include +#endif #include #include #include @@ -36,12 +37,12 @@ #include "util.h" #include "ops.h" #include "wait.h" -#include "rungpg.h" #include "context.h" /*temp hack until we have GpmeData methods to do I/O */ #include "io.h" #include "sema.h" #include "status-table.h" +#include "engine-backend.h" /* This type is used to build a list of gpg arguments and data @@ -56,6 +57,7 @@ struct arg_and_data_s char arg[1]; /* Used if data above is not used. */ }; + struct fd_data_map_s { GpgmeData data; @@ -85,7 +87,7 @@ struct gpg_object_s void *tag; } status; - /* This is a kludge - see the comment at gpg_colon_line_handler. */ + /* This is a kludge - see the comment at colon_line_handler. */ struct { int fd[2]; @@ -121,17 +123,16 @@ struct gpg_object_s struct GpgmeIOCbs io_cbs; }; -static void free_argv (char **argv); -static void free_fd_data_map (struct fd_data_map_s *fd_data_map); -static void gpg_status_handler (void *opaque, int fd); -static GpgmeError read_status (GpgObject gpg); +static void +gpg_io_event (void *engine, GpgmeEventIO type, void *type_data) +{ + GpgObject gpg = engine; -static void gpg_colon_line_handler (void *opaque, int fd); -static GpgmeError read_colon_line (GpgObject gpg); + if (gpg->io_cbs.event) + (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, type, type_data); +} -static int command_cb (void *opaque, char *buffer, size_t length, - size_t *nread); static void close_notify_handler (int fd, void *opaque) @@ -204,7 +205,7 @@ close_notify_handler (int fd, void *opaque) } } if (!not_done) - _gpgme_gpg_io_event (gpg, GPGME_EVENT_DONE, NULL); + gpg_io_event (gpg, GPGME_EVENT_DONE, NULL); } static GpgmeError @@ -263,8 +264,8 @@ add_data (GpgObject gpg, GpgmeData data, int dup_to, int inbound) } -const char * -_gpgme_gpg_get_version (void) +static const char * +gpg_get_version (void) { static const char *gpg_version; DEFINE_STATIC_LOCK (gpg_version_lock); @@ -276,16 +277,86 @@ _gpgme_gpg_get_version (void) return gpg_version; } -GpgmeError -_gpgme_gpg_check_version (void) + +static GpgmeError +gpg_check_version (void) { - return _gpgme_compare_versions (_gpgme_gpg_get_version (), - NEED_GPG_VERSION) + return _gpgme_compare_versions (gpg_get_version (), NEED_GPG_VERSION) ? 0 : mk_error (Invalid_Engine); } -GpgmeError -_gpgme_gpg_new (GpgObject *r_gpg) + +static void +free_argv (char **argv) +{ + int i; + + for (i = 0; argv[i]; i++) + free (argv[i]); + free (argv); +} + + +static void +free_fd_data_map (struct fd_data_map_s *fd_data_map) +{ + int i; + + if (!fd_data_map) + return; + + for (i = 0; fd_data_map[i].data; i++) + { + if (fd_data_map[i].fd != -1) + _gpgme_io_close (fd_data_map[i].fd); + if (fd_data_map[i].peer_fd != -1) + _gpgme_io_close (fd_data_map[i].peer_fd); + /* Don't release data because this is only a reference. */ + } + free (fd_data_map); +} + + +static void +gpg_release (void *engine) +{ + GpgObject gpg = engine; + + if (!gpg) + return; + + while (gpg->arglist) + { + struct arg_and_data_s *next = gpg->arglist->next; + + free (gpg->arglist); + gpg->arglist = next; + } + + free (gpg->status.buffer); + free (gpg->colon.buffer); + if (gpg->argv) + free_argv (gpg->argv); + gpgme_data_release (gpg->cmd.cb_data); + free (gpg->cmd.keyword); + + if (gpg->status.fd[0] != -1) + _gpgme_io_close (gpg->status.fd[0]); + if (gpg->status.fd[1] != -1) + _gpgme_io_close (gpg->status.fd[1]); + if (gpg->colon.fd[0] != -1) + _gpgme_io_close (gpg->colon.fd[0]); + if (gpg->colon.fd[1] != -1) + _gpgme_io_close (gpg->colon.fd[1]); + free_fd_data_map (gpg->fd_data_map); + if (gpg->cmd.fd != -1) + _gpgme_io_close (gpg->cmd.fd); + free (gpg); +} + + +static GpgmeError +gpg_new (void **engine) { GpgObject gpg; int rc = 0; @@ -344,55 +415,18 @@ _gpgme_gpg_new (GpgObject *r_gpg) leave: if (rc) - { - _gpgme_gpg_release (gpg); - *r_gpg = NULL; - } + gpg_release (gpg); else - *r_gpg = gpg; + *engine = gpg; return rc; } -void -_gpgme_gpg_release (GpgObject gpg) +static GpgmeError +gpg_set_verbosity (void *engine, int verbosity) { - if (!gpg) - return; - - while (gpg->arglist) - { - struct arg_and_data_s *next = gpg->arglist->next; - - free (gpg->arglist); - gpg->arglist = next; - } - - free (gpg->status.buffer); - free (gpg->colon.buffer); - if (gpg->argv) - free_argv (gpg->argv); - gpgme_data_release (gpg->cmd.cb_data); - free (gpg->cmd.keyword); - - if (gpg->status.fd[0] != -1) - _gpgme_io_close (gpg->status.fd[0]); - if (gpg->status.fd[1] != -1) - _gpgme_io_close (gpg->status.fd[1]); - if (gpg->colon.fd[0] != -1) - _gpgme_io_close (gpg->colon.fd[0]); - if (gpg->colon.fd[1] != -1) - _gpgme_io_close (gpg->colon.fd[1]); - free_fd_data_map (gpg->fd_data_map); - if (gpg->cmd.fd != -1) - _gpgme_io_close (gpg->cmd.fd); - free (gpg); -} + GpgObject gpg = engine; - -GpgmeError -_gpgme_gpg_set_verbosity (GpgObject gpg, int verbosity) -{ GpgmeError err = 0; while (!err && verbosity-- > 0) err = add_arg (gpg, "--verbose"); @@ -401,22 +435,21 @@ _gpgme_gpg_set_verbosity (GpgObject gpg, int verbosity) /* Note, that the status_handler is allowed to modifiy the args value. */ -void -_gpgme_gpg_set_status_handler (GpgObject gpg, - GpgmeStatusHandler fnc, void *fnc_value) +static void +gpg_set_status_handler (void *engine, GpgmeStatusHandler fnc, void *fnc_value) { - assert (gpg); + GpgObject gpg = engine; gpg->status.fnc = fnc; gpg->status.fnc_value = fnc_value; } /* Kludge to process --with-colon output. */ -GpgmeError -_gpgme_gpg_set_colon_line_handler (GpgObject gpg, - GpgmeColonLineHandler fnc, void *fnc_value) +static GpgmeError +gpg_set_colon_line_handler (void *engine, GpgmeColonLineHandler fnc, + void *fnc_value) { - assert (gpg); + GpgObject gpg = engine; gpg->colon.bufsize = 1024; gpg->colon.readpos = 0; @@ -441,21 +474,80 @@ _gpgme_gpg_set_colon_line_handler (GpgObject gpg, } +/* Here we handle --command-fd. This works closely together with the + status handler. */ +static int +command_cb (void *opaque, char *buffer, size_t length, size_t *nread) +{ + GpgObject gpg = opaque; + const char *value; + int value_len; + + DEBUG0 ("command_cb: enter\n"); + assert (gpg->cmd.used); + if (!buffer || !length || !nread) + return 0; /* These values are reserved for extensions. */ + *nread = 0; + if (!gpg->cmd.code) + { + DEBUG0 ("command_cb: no code\n"); + return -1; + } + + if (!gpg->cmd.fnc) + { + DEBUG0 ("command_cb: no user cb\n"); + return -1; + } + + value = gpg->cmd.fnc (gpg->cmd.fnc_value, + gpg->cmd.code, gpg->cmd.keyword); + if (!value) + { + DEBUG0 ("command_cb: no data from user cb\n"); + gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value); + return -1; + } + + value_len = strlen (value); + if (value_len + 1 > length) + { + DEBUG0 ("command_cb: too much data from user cb\n"); + gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value); + return -1; + } + + memcpy (buffer, value, value_len); + if (!value_len || (value_len && value[value_len-1] != '\n')) + buffer[value_len++] = '\n'; + *nread = value_len; + + gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value); + gpg->cmd.code = 0; + /* And sleep again until read_status will wake us up again. */ + /* XXX We must check if there are any more fds active after removing + this one. */ + (*gpg->io_cbs.remove) (gpg->fd_data_map[gpg->cmd.idx].tag); + gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd; + gpg->fd_data_map[gpg->cmd.idx].fd = -1; + + return 0; +} + + /* The Fnc will be called to get a value for one of the commands with a key KEY. If the Code pssed to FNC is 0, the function may release resources associated with the returned value from another call. To match such a second call to a first call, the returned value from the first call is passed as keyword. */ -GpgmeError -_gpgme_gpg_set_command_handler (GpgObject gpg, - GpgmeCommandHandler fnc, void *fnc_value, - GpgmeData linked_data) +static GpgmeError +gpg_set_command_handler (void *engine, GpgmeCommandHandler fnc, + void *fnc_value, GpgmeData linked_data) { + GpgObject gpg = engine; GpgmeData tmp; GpgmeError err; - assert (gpg); - err = gpgme_data_new_with_read_cb (&tmp, command_cb, gpg); if (err) return err; @@ -471,37 +563,6 @@ _gpgme_gpg_set_command_handler (GpgObject gpg, } -static void -free_argv (char **argv) -{ - int i; - - for (i = 0; argv[i]; i++) - free (argv[i]); - free (argv); -} - - -static void -free_fd_data_map (struct fd_data_map_s *fd_data_map) -{ - int i; - - if (!fd_data_map) - return; - - for (i = 0; fd_data_map[i].data; i++) - { - if (fd_data_map[i].fd != -1) - _gpgme_io_close (fd_data_map[i].fd); - if (fd_data_map[i].peer_fd != -1) - _gpgme_io_close (fd_data_map[i].peer_fd); - /* Don't release data because this is only a reference. */ - } - free (fd_data_map); -} - - static GpgmeError build_argv (GpgObject gpg) { @@ -712,9 +773,10 @@ build_argv (GpgObject gpg) return 0; } + static GpgmeError -_gpgme_gpg_add_io_cb (GpgObject gpg, int fd, int dir, - GpgmeIOCb handler, void *data, void **tag) +add_io_cb (GpgObject gpg, int fd, int dir, GpgmeIOCb handler, void *data, + void **tag) { GpgmeError err; @@ -727,197 +789,42 @@ _gpgme_gpg_add_io_cb (GpgObject gpg, int fd, int dir, return err; } -GpgmeError -_gpgme_gpg_spawn (GpgObject gpg, void *opaque) -{ - GpgmeError rc; - int i, n; - int status; - struct spawn_fd_item_s *fd_child_list, *fd_parent_list; - if (!gpg) - return mk_error (Invalid_Value); +static int +status_cmp (const void *ap, const void *bp) +{ + const struct status_table_s *a = ap; + const struct status_table_s *b = bp; - if (! _gpgme_get_gpg_path ()) - return mk_error (Invalid_Engine); + return strcmp (a->name, b->name); +} - /* Kludge, so that we don't need to check the return code of all the - add_arg (). We bail out here instead. */ - if (gpg->arg_error) - return mk_error (Out_Of_Core); - rc = build_argv (gpg); - if (rc) - return rc; +/* Handle the status output of GnuPG. This function does read entire + lines and passes them as C strings to the callback function (we can + use C Strings because the status output is always UTF-8 encoded). + Of course we have to buffer the lines to cope with long lines + e.g. with a large user ID. Note: We can optimize this to only cope + with status line code we know about and skip all other stuff + without buffering (i.e. without extending the buffer). */ +static GpgmeError +read_status (GpgObject gpg) +{ + char *p; + int nread; + size_t bufsize = gpg->status.bufsize; + char *buffer = gpg->status.buffer; + size_t readpos = gpg->status.readpos; - n = 3; /* status_fd, colon_fd and end of list */ - for (i = 0; gpg->fd_data_map[i].data; i++) - n++; - fd_child_list = calloc (n + n, sizeof *fd_child_list); - if (!fd_child_list) - return mk_error (Out_Of_Core); - fd_parent_list = fd_child_list + n; - - /* build the fd list for the child */ - n = 0; - if (gpg->colon.fnc) - { - fd_child_list[n].fd = gpg->colon.fd[1]; - fd_child_list[n].dup_to = 1; /* dup to stdout */ - n++; - } - for (i = 0; gpg->fd_data_map[i].data; i++) - { - if (gpg->fd_data_map[i].dup_to != -1) - { - fd_child_list[n].fd = gpg->fd_data_map[i].peer_fd; - fd_child_list[n].dup_to = gpg->fd_data_map[i].dup_to; - n++; - } - } - fd_child_list[n].fd = -1; - fd_child_list[n].dup_to = -1; - - /* Build the fd list for the parent. */ - n = 0; - if (gpg->status.fd[1] != -1) - { - fd_parent_list[n].fd = gpg->status.fd[1]; - fd_parent_list[n].dup_to = -1; - n++; - gpg->status.fd[1] = -1; - } - if (gpg->colon.fd[1] != -1) - { - fd_parent_list[n].fd = gpg->colon.fd[1]; - fd_parent_list[n].dup_to = -1; - n++; - gpg->colon.fd[1] = -1; - } - for (i = 0; gpg->fd_data_map[i].data; i++) - { - fd_parent_list[n].fd = gpg->fd_data_map[i].peer_fd; - fd_parent_list[n].dup_to = -1; - n++; - gpg->fd_data_map[i].peer_fd = -1; - } - fd_parent_list[n].fd = -1; - fd_parent_list[n].dup_to = -1; - - status = _gpgme_io_spawn (_gpgme_get_gpg_path (), - gpg->argv, fd_child_list, fd_parent_list); - free (fd_child_list); - if (status == -1) - return mk_error (Exec_Error); - - /*_gpgme_register_term_handler ( closure, closure_value, pid );*/ - - rc = _gpgme_gpg_add_io_cb (gpg, gpg->status.fd[0], 1, - gpg_status_handler, gpg, &gpg->status.tag); - if (rc) - /* FIXME: kill the child */ - return rc; - - if (gpg->colon.fnc) - { - assert (gpg->colon.fd[0] != -1); - rc = _gpgme_gpg_add_io_cb (gpg, gpg->colon.fd[0], 1, - gpg_colon_line_handler, gpg, - &gpg->colon.tag); - if (rc) - /* FIXME: kill the child */ - return rc; - } - - for (i = 0; gpg->fd_data_map[i].data; i++) - { - if (gpg->cmd.used && i == gpg->cmd.idx) - { - /* Park the cmd fd. */ - gpg->cmd.fd = gpg->fd_data_map[i].fd; - gpg->fd_data_map[i].fd = -1; - } - else - { - rc = _gpgme_gpg_add_io_cb (gpg, gpg->fd_data_map[i].fd, - gpg->fd_data_map[i].inbound, - gpg->fd_data_map[i].inbound - ? _gpgme_data_inbound_handler - : _gpgme_data_outbound_handler, - gpg->fd_data_map[i].data, - &gpg->fd_data_map[i].tag); - - if (rc) - /* FIXME: kill the child */ - return rc; - } - } - - /* fixme: check what data we can release here */ - return 0; -} - - -static void -gpg_status_handler (void *opaque, int fd) -{ - GpgObject gpg = opaque; - int err; - - assert (fd == gpg->status.fd[0]); - err = read_status (gpg); - if (err) - { - /* XXX Horrible kludge. We really must not make use of - fnc_value. */ - GpgmeCtx ctx = (GpgmeCtx) gpg->status.fnc_value; - ctx->error = err; - DEBUG1 ("gpg_handler: read_status problem %d\n - stop", err); - _gpgme_io_close (fd); - return; - } - if (gpg->status.eof) - _gpgme_io_close (fd); -} - - -static int -status_cmp (const void *ap, const void *bp) -{ - const struct status_table_s *a = ap; - const struct status_table_s *b = bp; - - return strcmp (a->name, b->name); -} - - - -/* - * Handle the status output of GnuPG. This function does read entire - * lines and passes them as C strings to the callback function (we can - * use C Strings because the status output is always UTF-8 encoded). - * Of course we have to buffer the lines to cope with long lines - * e.g. with a large user ID. Note: We can optimize this to only cope - * with status line code we know about and skip all other stuff - * without buffering (i.e. without extending the buffer). */ -static GpgmeError -read_status (GpgObject gpg) -{ - char *p; - int nread; - size_t bufsize = gpg->status.bufsize; - char *buffer = gpg->status.buffer; - size_t readpos = gpg->status.readpos; - - assert (buffer); - if (bufsize - readpos < 256) - { - /* Need more room for the read. */ - bufsize += 1024; - buffer = realloc (buffer, bufsize); - if (!buffer) - return mk_error (Out_Of_Core); - } + assert (buffer); + if (bufsize - readpos < 256) + { + /* Need more room for the read. */ + bufsize += 1024; + buffer = realloc (buffer, bufsize); + if (!buffer) + return mk_error (Out_Of_Core); + } nread = _gpgme_io_read (gpg->status.fd[0], buffer + readpos, bufsize-readpos); @@ -997,11 +904,10 @@ read_status (GpgObject gpg) while (fds.signaled); } - _gpgme_gpg_add_io_cb - (gpg, gpg->cmd.fd, - 0, _gpgme_data_outbound_handler, - gpg->fd_data_map[gpg->cmd.idx].data, - &gpg->fd_data_map[gpg->cmd.idx].tag); + add_io_cb (gpg, gpg->cmd.fd, 0, + _gpgme_data_outbound_handler, + gpg->fd_data_map[gpg->cmd.idx].data, + &gpg->fd_data_map[gpg->cmd.idx].tag); gpg->fd_data_map[gpg->cmd.idx].fd = gpg->cmd.fd; gpg->cmd.fd = -1; } @@ -1051,12 +957,109 @@ read_status (GpgObject gpg) } +static void +status_handler (void *opaque, int fd) +{ + GpgObject gpg = opaque; + int err; + + assert (fd == gpg->status.fd[0]); + err = read_status (gpg); + if (err) + { + /* XXX Horrible kludge. We really must not make use of + fnc_value. */ + GpgmeCtx ctx = (GpgmeCtx) gpg->status.fnc_value; + ctx->error = err; + DEBUG1 ("gpg_handler: read_status problem %d\n - stop", err); + _gpgme_io_close (fd); + return; + } + if (gpg->status.eof) + _gpgme_io_close (fd); +} + + +static GpgmeError +read_colon_line (GpgObject gpg) +{ + char *p; + int nread; + size_t bufsize = gpg->colon.bufsize; + char *buffer = gpg->colon.buffer; + size_t readpos = gpg->colon.readpos; + + assert (buffer); + if (bufsize - readpos < 256) + { + /* Need more room for the read. */ + bufsize += 1024; + buffer = realloc (buffer, bufsize); + if (!buffer) + return mk_error (Out_Of_Core); + } + + nread = _gpgme_io_read (gpg->colon.fd[0], buffer+readpos, bufsize-readpos); + if (nread == -1) + return mk_error (Read_Error); + + if (!nread) + { + gpg->colon.eof = 1; + assert (gpg->colon.fnc); + gpg->colon.fnc (gpg->colon.fnc_value, NULL); + return 0; + } + + while (nread > 0) + { + for (p = buffer + readpos; nread; nread--, p++) + { + if ( *p == '\n' ) + { + /* (we require that the last line is terminated by a LF) + and we skip empty lines. Note: we use UTF8 encoding + and escaping of special characters We require at + least one colon to cope with some other printed + information. */ + *p = 0; + if (*buffer && strchr (buffer, ':')) + { + assert (gpg->colon.fnc); + gpg->colon.fnc (gpg->colon.fnc_value, buffer); + } + + /* To reuse the buffer for the next line we have to + shift the remaining data to the buffer start and + restart the loop Hmmm: We can optimize this function + by looking forward in the buffer to see whether a + second complete line is available and in this case + avoid the memmove for this line. */ + nread--; p++; + if (nread) + memmove (buffer, p, nread); + readpos = 0; + break; /* The for loop. */ + } + else + readpos++; + } + } + + /* Update the gpg object. */ + gpg->colon.bufsize = bufsize; + gpg->colon.buffer = buffer; + gpg->colon.readpos = readpos; + return 0; +} + + /* This colonline handler thing is not the clean way to do it. It might be better to enhance the GpgmeData object to act as a wrapper for a callback. Same goes for the status thing. For now we use this thing here because it is easier to implement. */ static void -gpg_colon_line_handler (void *opaque, int fd) +colon_line_handler (void *opaque, int fd) { GpgObject gpg = opaque; GpgmeError rc = 0; @@ -1074,143 +1077,141 @@ gpg_colon_line_handler (void *opaque, int fd) _gpgme_io_close (fd); } + static GpgmeError -read_colon_line ( GpgObject gpg ) +gpg_start (void *engine, void *opaque) { - char *p; - int nread; - size_t bufsize = gpg->colon.bufsize; - char *buffer = gpg->colon.buffer; - size_t readpos = gpg->colon.readpos; - - assert (buffer); - if (bufsize - readpos < 256) { - /* need more room for the read */ - bufsize += 1024; - buffer = realloc (buffer, bufsize); - if ( !buffer ) - return mk_error (Out_Of_Core); - } - + GpgObject gpg = engine; + GpgmeError rc; + int i, n; + int status; + struct spawn_fd_item_s *fd_child_list, *fd_parent_list; - nread = _gpgme_io_read ( gpg->colon.fd[0], - buffer+readpos, bufsize-readpos ); - if (nread == -1) - return mk_error(Read_Error); + if (!gpg) + return mk_error (Invalid_Value); - if (!nread) { - gpg->colon.eof = 1; - assert (gpg->colon.fnc); - gpg->colon.fnc ( gpg->colon.fnc_value, NULL ); - return 0; - } + if (! _gpgme_get_gpg_path ()) + return mk_error (Invalid_Engine); - while (nread > 0) { - for (p = buffer + readpos; nread; nread--, p++) { - if ( *p == '\n' ) { - /* (we require that the last line is terminated by a - * LF) and we skip empty lines. Note: we use UTF8 - * encoding and escaping of special characters - * We require at least one colon to cope with - * some other printed information. - */ - *p = 0; - if (*buffer && strchr (buffer, ':')) - { - assert (gpg->colon.fnc); - gpg->colon.fnc (gpg->colon.fnc_value, buffer); - } - - /* To reuse the buffer for the next line we have to - * shift the remaining data to the buffer start and - * restart the loop Hmmm: We can optimize this - * function by looking forward in the buffer to see - * whether a second complete line is available and in - * this case avoid the memmove for this line. */ - nread--; p++; - if (nread) - memmove (buffer, p, nread); - readpos = 0; - break; /* the for loop */ - } - else - readpos++; - } - } - - /* Update the gpg object. */ - gpg->colon.bufsize = bufsize; - gpg->colon.buffer = buffer; - gpg->colon.readpos = readpos; - return 0; -} + /* Kludge, so that we don't need to check the return code of all the + add_arg (). We bail out here instead. */ + if (gpg->arg_error) + return mk_error (Out_Of_Core); -/* - * Here we handle --command-fd. This works closely together with - * the status handler. - */ + rc = build_argv (gpg); + if (rc) + return rc; -static int -command_cb (void *opaque, char *buffer, size_t length, size_t *nread) -{ - GpgObject gpg = opaque; - const char *value; - int value_len; + n = 3; /* status_fd, colon_fd and end of list */ + for (i = 0; gpg->fd_data_map[i].data; i++) + n++; + fd_child_list = calloc (n + n, sizeof *fd_child_list); + if (!fd_child_list) + return mk_error (Out_Of_Core); + fd_parent_list = fd_child_list + n; - DEBUG0 ("command_cb: enter\n"); - assert (gpg->cmd.used); - if (!buffer || !length || !nread) - return 0; /* These values are reserved for extensions. */ - *nread = 0; - if (!gpg->cmd.code) + /* build the fd list for the child */ + n = 0; + if (gpg->colon.fnc) { - DEBUG0 ("command_cb: no code\n"); - return -1; + fd_child_list[n].fd = gpg->colon.fd[1]; + fd_child_list[n].dup_to = 1; /* dup to stdout */ + n++; } - - if (!gpg->cmd.fnc) + for (i = 0; gpg->fd_data_map[i].data; i++) { - DEBUG0 ("command_cb: no user cb\n"); - return -1; + if (gpg->fd_data_map[i].dup_to != -1) + { + fd_child_list[n].fd = gpg->fd_data_map[i].peer_fd; + fd_child_list[n].dup_to = gpg->fd_data_map[i].dup_to; + n++; + } } + fd_child_list[n].fd = -1; + fd_child_list[n].dup_to = -1; - value = gpg->cmd.fnc (gpg->cmd.fnc_value, - gpg->cmd.code, gpg->cmd.keyword); - if (!value) + /* Build the fd list for the parent. */ + n = 0; + if (gpg->status.fd[1] != -1) { - DEBUG0 ("command_cb: no data from user cb\n"); - gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value); - return -1; + fd_parent_list[n].fd = gpg->status.fd[1]; + fd_parent_list[n].dup_to = -1; + n++; + gpg->status.fd[1] = -1; } - - value_len = strlen (value); - if (value_len + 1 > length) + if (gpg->colon.fd[1] != -1) { - DEBUG0 ("command_cb: too much data from user cb\n"); - gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value); - return -1; + fd_parent_list[n].fd = gpg->colon.fd[1]; + fd_parent_list[n].dup_to = -1; + n++; + gpg->colon.fd[1] = -1; } + for (i = 0; gpg->fd_data_map[i].data; i++) + { + fd_parent_list[n].fd = gpg->fd_data_map[i].peer_fd; + fd_parent_list[n].dup_to = -1; + n++; + gpg->fd_data_map[i].peer_fd = -1; + } + fd_parent_list[n].fd = -1; + fd_parent_list[n].dup_to = -1; - memcpy (buffer, value, value_len); - if (!value_len || (value_len && value[value_len-1] != '\n')) - buffer[value_len++] = '\n'; - *nread = value_len; - - gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value); - gpg->cmd.code = 0; - /* And sleep again until read_status will wake us up again. */ - /* XXX We must check if there are any more fds active after removing - this one. */ - (*gpg->io_cbs.remove) (gpg->fd_data_map[gpg->cmd.idx].tag); - gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd; - gpg->fd_data_map[gpg->cmd.idx].fd = -1; + status = _gpgme_io_spawn (_gpgme_get_gpg_path (), + gpg->argv, fd_child_list, fd_parent_list); + free (fd_child_list); + if (status == -1) + return mk_error (Exec_Error); + + /*_gpgme_register_term_handler ( closure, closure_value, pid );*/ + + rc = add_io_cb (gpg, gpg->status.fd[0], 1, status_handler, gpg, + &gpg->status.tag); + if (rc) + /* FIXME: kill the child */ + return rc; + + if (gpg->colon.fnc) + { + assert (gpg->colon.fd[0] != -1); + rc = add_io_cb (gpg, gpg->colon.fd[0], 1, colon_line_handler, gpg, + &gpg->colon.tag); + if (rc) + /* FIXME: kill the child */ + return rc; + } + for (i = 0; gpg->fd_data_map[i].data; i++) + { + if (gpg->cmd.used && i == gpg->cmd.idx) + { + /* Park the cmd fd. */ + gpg->cmd.fd = gpg->fd_data_map[i].fd; + gpg->fd_data_map[i].fd = -1; + } + else + { + rc = add_io_cb (gpg, gpg->fd_data_map[i].fd, + gpg->fd_data_map[i].inbound, + gpg->fd_data_map[i].inbound + ? _gpgme_data_inbound_handler + : _gpgme_data_outbound_handler, + gpg->fd_data_map[i].data, &gpg->fd_data_map[i].tag); + + if (rc) + /* FIXME: kill the child */ + return rc; + } + } + + /* fixme: check what data we can release here */ return 0; } -GpgmeError -_gpgme_gpg_op_decrypt (GpgObject gpg, GpgmeData ciph, GpgmeData plain) + +static GpgmeError +gpg_decrypt (void *engine, GpgmeData ciph, GpgmeData plain) { + GpgObject gpg = engine; GpgmeError err; err = add_arg (gpg, "--decrypt"); @@ -1228,9 +1229,10 @@ _gpgme_gpg_op_decrypt (GpgObject gpg, GpgmeData ciph, GpgmeData plain) return err; } -GpgmeError -_gpgme_gpg_op_delete (GpgObject gpg, GpgmeKey key, int allow_secret) +static GpgmeError +gpg_delete (void *engine, GpgmeKey key, int allow_secret) { + GpgObject gpg = engine; GpgmeError err; err = add_arg (gpg, allow_secret ? "--delete-secret-and-public-key" @@ -1251,8 +1253,7 @@ _gpgme_gpg_op_delete (GpgObject gpg, GpgmeKey key, int allow_secret) static GpgmeError -_gpgme_append_gpg_args_from_signers (GpgObject gpg, - GpgmeCtx ctx /* FIXME */) +append_args_from_signers (GpgObject gpg, GpgmeCtx ctx /* FIXME */) { GpgmeError err = 0; int i; @@ -1276,15 +1277,15 @@ _gpgme_append_gpg_args_from_signers (GpgObject gpg, } -GpgmeError -_gpgme_gpg_op_edit (GpgObject gpg, GpgmeKey key, GpgmeData out, - GpgmeCtx ctx /* FIXME */) +static GpgmeError +gpg_edit (void *engine, GpgmeKey key, GpgmeData out, GpgmeCtx ctx /* FIXME */) { + GpgObject gpg = engine; GpgmeError err; err = add_arg (gpg, "--with-colons"); if (!err) - err = _gpgme_append_gpg_args_from_signers (gpg, ctx); + err = append_args_from_signers (gpg, ctx); if (!err) err = add_arg (gpg, "--edit-key"); if (!err) @@ -1305,8 +1306,7 @@ _gpgme_gpg_op_edit (GpgObject gpg, GpgmeKey key, GpgmeData out, static GpgmeError -_gpgme_append_gpg_args_from_recipients (GpgObject gpg, - const GpgmeRecipients rset) +append_args_from_recipients (GpgObject gpg, const GpgmeRecipients rset) { GpgmeError err = 0; struct user_id_s *r; @@ -1324,10 +1324,11 @@ _gpgme_append_gpg_args_from_recipients (GpgObject gpg, } -GpgmeError -_gpgme_gpg_op_encrypt (GpgObject gpg, GpgmeRecipients recp, - GpgmeData plain, GpgmeData ciph, int use_armor) +static GpgmeError +gpg_encrypt (void *engine, GpgmeRecipients recp, GpgmeData plain, + GpgmeData ciph, int use_armor) { + GpgObject gpg = engine; GpgmeError err; int symmetric = !recp; @@ -1344,7 +1345,7 @@ _gpgme_gpg_op_encrypt (GpgObject gpg, GpgmeRecipients recp, err = add_arg (gpg, "--always-trust"); if (!err) - err = _gpgme_append_gpg_args_from_recipients (gpg, recp); + err = append_args_from_recipients (gpg, recp); } /* Tell the gpg object about the data. */ @@ -1362,11 +1363,11 @@ _gpgme_gpg_op_encrypt (GpgObject gpg, GpgmeRecipients recp, return err; } -GpgmeError -_gpgme_gpg_op_encrypt_sign (GpgObject gpg, GpgmeRecipients recp, - GpgmeData plain, GpgmeData ciph, int use_armor, - GpgmeCtx ctx /* FIXME */) +static GpgmeError +gpg_encrypt_sign (void *engine, GpgmeRecipients recp, GpgmeData plain, + GpgmeData ciph, int use_armor, GpgmeCtx ctx /* FIXME */) { + GpgObject gpg = engine; GpgmeError err; err = add_arg (gpg, "--encrypt"); @@ -1381,10 +1382,10 @@ _gpgme_gpg_op_encrypt_sign (GpgObject gpg, GpgmeRecipients recp, err = add_arg (gpg, "--always-trust"); if (!err) - err = _gpgme_append_gpg_args_from_recipients (gpg, recp); + err = append_args_from_recipients (gpg, recp); if (!err) - err = _gpgme_append_gpg_args_from_signers (gpg, ctx); + err = append_args_from_signers (gpg, ctx); /* Tell the gpg object about the data. */ if (!err) @@ -1401,10 +1402,11 @@ _gpgme_gpg_op_encrypt_sign (GpgObject gpg, GpgmeRecipients recp, return err; } -GpgmeError -_gpgme_gpg_op_export (GpgObject gpg, GpgmeRecipients recp, - GpgmeData keydata, int use_armor) +static GpgmeError +gpg_export (void *engine, GpgmeRecipients recp, GpgmeData keydata, + int use_armor) { + GpgObject gpg = engine; GpgmeError err; err = add_arg (gpg, "--export"); @@ -1430,19 +1432,21 @@ _gpgme_gpg_op_export (GpgObject gpg, GpgmeRecipients recp, return err; } -GpgmeError -_gpgme_gpg_op_genkey (GpgObject gpg, GpgmeData help_data, int use_armor, - GpgmeData pubkey, GpgmeData seckey) + +static GpgmeError +gpg_genkey (void *engine, GpgmeData help_data, int use_armor, + GpgmeData pubkey, GpgmeData seckey) { + GpgObject gpg = engine; GpgmeError err; if (!gpg) return mk_error (Invalid_Value); - /* We need a special mechanism to get the fd of a pipe here, so - * that we can use this for the %pubring and %secring parameters. - * We don't have this yet, so we implement only the adding to the - * standard keyrings */ + /* We need a special mechanism to get the fd of a pipe here, so that + we can use this for the %pubring and %secring parameters. We + don't have this yet, so we implement only the adding to the + standard keyrings. */ if (pubkey || seckey) return err = mk_error (Not_Implemented); @@ -1455,9 +1459,11 @@ _gpgme_gpg_op_genkey (GpgObject gpg, GpgmeData help_data, int use_armor, return err; } -GpgmeError -_gpgme_gpg_op_import (GpgObject gpg, GpgmeData keydata) + +static GpgmeError +gpg_import (void *engine, GpgmeData keydata) { + GpgObject gpg = engine; GpgmeError err; err = add_arg (gpg, "--import"); @@ -1468,10 +1474,11 @@ _gpgme_gpg_op_import (GpgObject gpg, GpgmeData keydata) } -GpgmeError -_gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, int secret_only, - int keylist_mode) +static GpgmeError +gpg_keylist (void *engine, const char *pattern, int secret_only, + int keylist_mode) { + GpgObject gpg = engine; GpgmeError err; err = add_arg (gpg, "--with-colons"); @@ -1495,10 +1502,11 @@ _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, int secret_only, } -GpgmeError -_gpgme_gpg_op_keylist_ext (GpgObject gpg, const char *pattern[], - int secret_only, int reserved, int keylist_mode) +static GpgmeError +gpg_keylist_ext (void *engine, const char *pattern[], int secret_only, + int reserved, int keylist_mode) { + GpgObject gpg = engine; GpgmeError err; if (reserved) @@ -1525,11 +1533,12 @@ _gpgme_gpg_op_keylist_ext (GpgObject gpg, const char *pattern[], } -GpgmeError -_gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out, - GpgmeSigMode mode, int use_armor, - int use_textmode, GpgmeCtx ctx /* FIXME */) +static GpgmeError +gpg_sign (void *engine, GpgmeData in, GpgmeData out, GpgmeSigMode mode, + int use_armor, int use_textmode, int include_certs, + GpgmeCtx ctx /* FIXME */) { + GpgObject gpg = engine; GpgmeError err; if (mode == GPGME_SIG_MODE_CLEAR) @@ -1546,7 +1555,7 @@ _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out, } if (!err) - err = _gpgme_append_gpg_args_from_signers (gpg, ctx); + err = append_args_from_signers (gpg, ctx); /* Tell the gpg object about the data. */ if (!err) @@ -1557,9 +1566,10 @@ _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out, return err; } -GpgmeError -_gpgme_gpg_op_trustlist (GpgObject gpg, const char *pattern) +static GpgmeError +gpg_trustlist (void *engine, const char *pattern) { + GpgObject gpg = engine; GpgmeError err; err = add_arg (gpg, "--with-colons"); @@ -1575,10 +1585,12 @@ _gpgme_gpg_op_trustlist (GpgObject gpg, const char *pattern) return err; } -GpgmeError -_gpgme_gpg_op_verify (GpgObject gpg, GpgmeData sig, GpgmeData signed_text, - GpgmeData plaintext) + +static GpgmeError +gpg_verify (void *engine, GpgmeData sig, GpgmeData signed_text, + GpgmeData plaintext) { + GpgObject gpg = engine; GpgmeError err = 0; if (plaintext) @@ -1614,16 +1626,43 @@ _gpgme_gpg_op_verify (GpgObject gpg, GpgmeData sig, GpgmeData signed_text, } -void -_gpgme_gpg_set_io_cbs (GpgObject gpg, struct GpgmeIOCbs *io_cbs) +static void +gpg_set_io_cbs (void *engine, struct GpgmeIOCbs *io_cbs) { + GpgObject gpg = engine; + gpg->io_cbs = *io_cbs; } - -void -_gpgme_gpg_io_event (GpgObject gpg, GpgmeEventIO type, void *type_data) -{ - if (gpg->io_cbs.event) - (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, type, type_data); -} + +struct engine_ops _gpgme_engine_ops_gpg = + { + /* Static functions. */ + _gpgme_get_gpg_path, + gpg_get_version, + gpg_check_version, + gpg_new, + + /* Member functions. */ + gpg_release, + gpg_set_status_handler, + gpg_set_command_handler, + gpg_set_colon_line_handler, + gpg_set_verbosity, + gpg_decrypt, + gpg_delete, + gpg_edit, + gpg_encrypt, + gpg_encrypt_sign, + gpg_export, + gpg_genkey, + gpg_import, + gpg_keylist, + gpg_keylist_ext, + gpg_sign, + gpg_trustlist, + gpg_verify, + gpg_start, + gpg_set_io_cbs, + gpg_io_event + }; diff --git a/gpgme/rungpg.h b/gpgme/rungpg.h deleted file mode 100644 index b2e8f07..0000000 --- a/gpgme/rungpg.h +++ /dev/null @@ -1,75 +0,0 @@ -/* rungpg.h - GPGME GnuPG engine calling functions. - Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002 g10 Code GmbH - - 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 GPGME; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef RUNGPG_H -#define RUNGPG_H - -#include "types.h" - -const char *_gpgme_gpg_get_version (void); -GpgmeError _gpgme_gpg_check_version (void); - -GpgmeError _gpgme_gpg_new (GpgObject *r_gpg); -void _gpgme_gpg_release (GpgObject gpg); -GpgmeError _gpgme_gpg_set_verbosity (GpgObject gpg, int verbosity); -void _gpgme_gpg_set_status_handler (GpgObject gpg, GpgmeStatusHandler fnc, - void *fnc_value); -GpgmeError _gpgme_gpg_set_colon_line_handler (GpgObject gpg, - GpgmeColonLineHandler fnc, - void *fnc_value); -GpgmeError _gpgme_gpg_set_command_handler (GpgObject gpg, - GpgmeCommandHandler fnc, - void *fnc_value, - GpgmeData linked_data); - -GpgmeError _gpgme_gpg_op_decrypt (GpgObject gpg, GpgmeData ciph, - GpgmeData plain); -GpgmeError _gpgme_gpg_op_delete (GpgObject gpg, GpgmeKey key, int allow_secret); -GpgmeError _gpgme_gpg_op_edit (GpgObject gpg, GpgmeKey key, GpgmeData out, - GpgmeCtx ctx /* FIXME */); -GpgmeError _gpgme_gpg_op_encrypt (GpgObject gpg, GpgmeRecipients recp, - GpgmeData plain, GpgmeData ciph, - int use_armor); -GpgmeError _gpgme_gpg_op_encrypt_sign (GpgObject gpg, GpgmeRecipients recp, - GpgmeData plain, GpgmeData ciph, - int use_armor, GpgmeCtx ctx); -GpgmeError _gpgme_gpg_op_export (GpgObject gpg, GpgmeRecipients recp, - GpgmeData keydata, int use_armor); -GpgmeError _gpgme_gpg_op_genkey (GpgObject gpg, GpgmeData help_data, - int use_armor, GpgmeData pubkey, - GpgmeData seckey); -GpgmeError _gpgme_gpg_op_import (GpgObject gpg, GpgmeData keydata); -GpgmeError _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, - int secret_only, int keylist_mode); -GpgmeError _gpgme_gpg_op_keylist_ext (GpgObject gpg, const char *pattern[], - int secret_only, int reserved, - int keylist_mode); -GpgmeError _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out, - GpgmeSigMode mode, int use_armor, - int use_textmode, GpgmeCtx ctx /* FIXME */); -GpgmeError _gpgme_gpg_op_trustlist (GpgObject gpg, const char *pattern); -GpgmeError _gpgme_gpg_op_verify (GpgObject gpg, GpgmeData sig, - GpgmeData signed_text, - GpgmeData plaintext); -GpgmeError _gpgme_gpg_spawn (GpgObject gpg, void *opaque); -void _gpgme_gpg_set_io_cbs (GpgObject gpg, struct GpgmeIOCbs *io_cbs); -void _gpgme_gpg_io_event (GpgObject gpg, GpgmeEventIO type, void *type_data); - -#endif /* RUNGPG_H */ diff --git a/gpgme/signers.c b/gpgme/signers.c index 9881473..fa8a9e3 100644 --- a/gpgme/signers.c +++ b/gpgme/signers.c @@ -1,36 +1,36 @@ /* signers.c - maintain signer sets - * Copyright (C) 2001 Werner Koch (dd9jn) - * Copyright (C) 2001, 2002 g10 Code GmbH - * - * 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 - */ + Copyright (C) 2001 Werner Koch (dd9jn) + Copyright (C) 2001, 2002 g10 Code GmbH + + 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 GPGME; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#if HAVE_CONFIG_H #include +#endif + #include #include #include #include "util.h" #include "context.h" -#include "rungpg.h" -/* The signers are directly stored in the context. - * So this is quite different to a recipient set. - */ +/* The signers are directly stored in the context. So this is quite + different to a recipient set. */ /** diff --git a/gpgme/version.c b/gpgme/version.c index c562684..03cdb32 100644 --- a/gpgme/version.c +++ b/gpgme/version.c @@ -1,25 +1,26 @@ /* version.c - version check - * Copyright (C) 2000 Werner Koch (dd9jn) - * Copyright (C) 2001 g10 Code GmbH - * - * 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 - */ + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002 g10 Code GmbH + + 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 GPGME; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#if HAVE_CONFIG_H #include +#endif #include #include #include @@ -27,7 +28,6 @@ #include "gpgme.h" #include "context.h" -#include "rungpg.h" #include "sema.h" #include "util.h" #include "key.h" /* for key_cache_init */