2002-07-28 Marcus Brinkmann <marcus@g10code.de>

* data.c (gpgme_data_read): For GPGME_DATA_TYPE_NONE, return EOF
	instead an error.

	The following changes make it possible to flush an inbound data
	pipe before invoking a command handler:

	* posix-io.c (_gpgme_io_select): Accept new argument NONBLOCK to
	_gpgme_io_select.  Set timeout of 0 if this is set.
	* w32-io.c (_gpgme_io_select): Likewise.
	* io.h: Add new argument NONBLOCK to _gpgme_io_select prototype.
	* wait.c (do_select): Add new argument to _gpgme_io_select
	invocation.
	* rungpg.h (_gpgme_gpg_set_command_handler): Add new argument
	linked_data to prototype.
	* engine.h (_gpgme_engine_set_command_handler): Likewise.
	* engine.c (_gpgme_engine_set_command_handler): Likewise.
	* passphrase.c (_gpgme_passphrase_start): Pass NULL as linked_data
	argument to _gpgme_engine_set_command_handler.
	* rungpg.c (struct gpg_object_s): New members linked_data and
	linked_idx in CMD.
	(_gpgme_gpg_new): Initialize those new members.
	(_gpgme_gpg_set_command_handler): Accept new argument linked_data.
	(build_argv): Handle linked_data in the same hack as cb_data.
	(read_status): If linked_data is in use, flush the pipe before
	activating the command handler.
	* gpgme.h: Add prototypes for gpgme_op_edit_start and
	gpgme_op_edit.

	The next changes export the status codes to the user:

	* decrypt.c (_gpgme_decrypt_status_handler): Likewise, also prefix
	all STATUS_ with GPGME_.
	* delete.c (delete_status_handler): Likewise.
	* decrypt-verify.c (decrypt_verify_status_handler): Likewise.
	* encrypt.c (_gpgme_encrypt_status_handler): Likewise.
	(_gpgme_encrypt_sym_status_handler): Likewise.
	* encrypt-sign.c (encrypt_sign_status_handler): Likewise.
	* engine-gpgsm.c (parse_status): Likewise.
	(gpgsm_status_handler): Likewise.
	(gpgsm_set_recipients): Likewise.
	* export.c (export_status_handler): Likewise.
	* genkey.c (genkey_status_handler): Likewise.
	* import.c (append_xml_impinfo): Likewise.
	(import_status_handler): Likewise.
	* keylist.c (keylist_status_handler): Likewise.
	* passphrase.c (_gpgme_passphrase_status_handler): Likewise.
	(command_handler): Likewise.
	* progress.c (_gpgme_progress_status_handler): Likewise.
	* sign.c (_gpgme_sign_status_handler): Likewise.
	* trustlist.c (trustlist_status_handler): Likewise.
	* verify.c (_gpgme_verify_status_handler): Likewise.
	* gpgme.h (GpgmeEditCb): New type.
	* rungpg.h (GpgStatusCode): Rename and move to ...
	* gpgme.h (GpgmeStatusCode): ... this and here.
	* Makefile.am (status-table.h): Run mkstatus on gpgme.h, not rungpg.h.
	* mkstatus: Prefix STATUS with GPGME_.
	* rungpg.h (GpgStatusHandler, GpgCommandHandler): Change type
	accordingly.
	* ops.h (_gpgme_verify_status_handler,
	_gpgme_decrypt_status_handler, _gpgme_sign_status_handler,
	_gpgme_encrypt_status_handler, _gpgme_passphrase_status_handler,
	_gpgme_progress_status_handler): Likewise.
	* rungpg.c (struct gpg_object_s): Likewise for CMD.code.

	These changes add an edit operation to GPGME:

	* context.h (struct gpgme_context_s): New member RESULT.edit.  *
	ops.h: Add prototype for _gpgme_release_edit_result and
	_gpgme_passphrase_command_handler.
	* passphrase.c (command_handler): Make non-static and rename to ...
	(_gpgme_passphrase_command_handler): ... this.
	(_gpgme_passphrase_start): Use new name for command handler.
	* types.h: Add EditResult type.
	* gpgme.c (_gpgme_release_result): Release EDIT result.
	* edit.c: New file.
	* Makefile.am (libgpgme_la_SOURCES): Add edit.c.
	(libgpgme_la_LDADD): Rename to libgpgme_la_LIBADD, and include
	assuan_libobjs.
	(assuan_libobjs): New variable, set this instead
	libgpgme_la_LIBADD.
	* engine.h (_gpgme_engine_op_edit): New prototype.
	* engine.c (_gpgme_engine_op_edit): New function.
	* rungpg.h (_gpgme_gpg_op_edit): New prototype.
	* rungpg.c (_gpgme_gpg_op_edit): New function.
This commit is contained in:
Marcus Brinkmann 2002-07-28 18:41:02 +00:00
parent a1f15581e9
commit f12433c1e4
33 changed files with 687 additions and 321 deletions

View File

@ -1,3 +1,90 @@
2002-07-28 Marcus Brinkmann <marcus@g10code.de>
* data.c (gpgme_data_read): For GPGME_DATA_TYPE_NONE, return EOF
instead an error.
The following changes make it possible to flush an inbound data
pipe before invoking a command handler:
* posix-io.c (_gpgme_io_select): Accept new argument NONBLOCK to
_gpgme_io_select. Set timeout of 0 if this is set.
* w32-io.c (_gpgme_io_select): Likewise.
* io.h: Add new argument NONBLOCK to _gpgme_io_select prototype.
* wait.c (do_select): Add new argument to _gpgme_io_select
invocation.
* rungpg.h (_gpgme_gpg_set_command_handler): Add new argument
linked_data to prototype.
* engine.h (_gpgme_engine_set_command_handler): Likewise.
* engine.c (_gpgme_engine_set_command_handler): Likewise.
* passphrase.c (_gpgme_passphrase_start): Pass NULL as linked_data
argument to _gpgme_engine_set_command_handler.
* rungpg.c (struct gpg_object_s): New members linked_data and
linked_idx in CMD.
(_gpgme_gpg_new): Initialize those new members.
(_gpgme_gpg_set_command_handler): Accept new argument linked_data.
(build_argv): Handle linked_data in the same hack as cb_data.
(read_status): If linked_data is in use, flush the pipe before
activating the command handler.
* gpgme.h: Add prototypes for gpgme_op_edit_start and
gpgme_op_edit.
The next changes export the status codes to the user:
* decrypt.c (_gpgme_decrypt_status_handler): Likewise, also prefix
all STATUS_ with GPGME_.
* delete.c (delete_status_handler): Likewise.
* decrypt-verify.c (decrypt_verify_status_handler): Likewise.
* encrypt.c (_gpgme_encrypt_status_handler): Likewise.
(_gpgme_encrypt_sym_status_handler): Likewise.
* encrypt-sign.c (encrypt_sign_status_handler): Likewise.
* engine-gpgsm.c (parse_status): Likewise.
(gpgsm_status_handler): Likewise.
(gpgsm_set_recipients): Likewise.
* export.c (export_status_handler): Likewise.
* genkey.c (genkey_status_handler): Likewise.
* import.c (append_xml_impinfo): Likewise.
(import_status_handler): Likewise.
* keylist.c (keylist_status_handler): Likewise.
* passphrase.c (_gpgme_passphrase_status_handler): Likewise.
(command_handler): Likewise.
* progress.c (_gpgme_progress_status_handler): Likewise.
* sign.c (_gpgme_sign_status_handler): Likewise.
* trustlist.c (trustlist_status_handler): Likewise.
* verify.c (_gpgme_verify_status_handler): Likewise.
* gpgme.h (GpgmeEditCb): New type.
* rungpg.h (GpgStatusCode): Rename and move to ...
* gpgme.h (GpgmeStatusCode): ... this and here.
* Makefile.am (status-table.h): Run mkstatus on gpgme.h, not rungpg.h.
* mkstatus: Prefix STATUS with GPGME_.
* rungpg.h (GpgStatusHandler, GpgCommandHandler): Change type
accordingly.
* ops.h (_gpgme_verify_status_handler,
_gpgme_decrypt_status_handler, _gpgme_sign_status_handler,
_gpgme_encrypt_status_handler, _gpgme_passphrase_status_handler,
_gpgme_progress_status_handler): Likewise.
* rungpg.c (struct gpg_object_s): Likewise for CMD.code.
These changes add an edit operation to GPGME:
* context.h (struct gpgme_context_s): New member RESULT.edit. *
ops.h: Add prototype for _gpgme_release_edit_result and
_gpgme_passphrase_command_handler.
* passphrase.c (command_handler): Make non-static and rename to ...
(_gpgme_passphrase_command_handler): ... this.
(_gpgme_passphrase_start): Use new name for command handler.
* types.h: Add EditResult type.
* gpgme.c (_gpgme_release_result): Release EDIT result.
* edit.c: New file.
* Makefile.am (libgpgme_la_SOURCES): Add edit.c.
(libgpgme_la_LDADD): Rename to libgpgme_la_LIBADD, and include
assuan_libobjs.
(assuan_libobjs): New variable, set this instead
libgpgme_la_LIBADD.
* engine.h (_gpgme_engine_op_edit): New prototype.
* engine.c (_gpgme_engine_op_edit): New function.
* rungpg.h (_gpgme_gpg_op_edit): New prototype.
* rungpg.c (_gpgme_gpg_op_edit): New function.
2002-07-27 Marcus Brinkmann <marcus@g10code.de>
* delete.c (delete_problem): New case ambigious specification.

View File

@ -32,7 +32,9 @@ libgpgme_la_LDFLAGS = -version-info \
@LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@
if BUILD_ASSUAN
AM_CPPFLAGS = -I$(top_srcdir)/assuan
libgpgme_la_LIBADD = ../assuan/libassuan.la ../jnlib/libjnlib.la
assuan_libobjs = ../assuan/libassuan.la ../jnlib/libjnlib.la @LIBOBJS@
else
assuan_libobjs =
endif
if HAVE_PTHREAD
@ -75,6 +77,7 @@ libgpgme_la_SOURCES = \
export.c \
genkey.c \
delete.c \
edit.c \
rungpg.c rungpg.h status-table.h \
engine-gpgsm.c engine-gpgsm.h \
engine.c engine.h \
@ -82,11 +85,11 @@ libgpgme_la_SOURCES = \
${system_components} \
debug.c debug.h \
gpgme.c version.c errors.c
libgpgme_la_LDADD = @LIBOBJS@
libgpgme_la_LIBADD = ${assuan_libobjs} @LIBOBJS@
errors.c : gpgme.h
$(srcdir)/mkerrors < $(srcdir)/gpgme.h > errors.c
status-table.h : rungpg.h
$(srcdir)/mkstatus < $(srcdir)/rungpg.h > status-table.h
$(srcdir)/mkstatus < $(srcdir)/gpgme.h > status-table.h

View File

@ -83,6 +83,7 @@ struct gpgme_context_s
DeleteResult delete;
GenKeyResult genkey;
KeylistResult keylist;
EditResult edit;
} result;
/* Last signature notation. */

View File

@ -566,6 +566,11 @@ gpgme_data_read (GpgmeData dh, void *buffer, size_t length, size_t *nread)
switch (dh->type)
{
case GPGME_DATA_TYPE_NONE:
*nread = 0;
return mk_error(EOF);
break;
case GPGME_DATA_TYPE_MEM:
nbytes = dh->len - dh->readpos;
if (!nbytes)

View File

@ -31,7 +31,7 @@
static void
decrypt_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
decrypt_verify_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
_gpgme_decrypt_status_handler (ctx, code, args);
_gpgme_verify_status_handler (ctx, code, args);

View File

@ -47,7 +47,7 @@ _gpgme_release_decrypt_result (DecryptResult result)
void
_gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
_gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
_gpgme_passphrase_status_handler (ctx, code, args);
@ -57,18 +57,18 @@ _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
switch (code)
{
case STATUS_EOF:
case GPGME_STATUS_EOF:
if (ctx->result.decrypt->failed)
ctx->error = mk_error (Decryption_Failed);
else if (!ctx->result.decrypt->okay)
ctx->error = mk_error (No_Data);
break;
case STATUS_DECRYPTION_OKAY:
case GPGME_STATUS_DECRYPTION_OKAY:
ctx->result.decrypt->okay = 1;
break;
case STATUS_DECRYPTION_FAILED:
case GPGME_STATUS_DECRYPTION_FAILED:
ctx->result.decrypt->failed = 1;
break;

View File

@ -56,7 +56,7 @@ _gpgme_release_delete_result (DeleteResult result)
static void
delete_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
delete_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
if (ctx->error)
return;
@ -64,7 +64,7 @@ delete_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
switch (code)
{
case STATUS_EOF:
case GPGME_STATUS_EOF:
switch (ctx->result.delete->problem)
{
case DELETE_No_Problem:
@ -83,7 +83,7 @@ delete_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
}
break;
case STATUS_DELETE_PROBLEM:
case GPGME_STATUS_DELETE_PROBLEM:
ctx->result.delete->problem = atoi (args);
break;

158
gpgme/edit.c Normal file
View File

@ -0,0 +1,158 @@
/* edit.c - key edit functions
* 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
struct edit_result_s
{
GpgmeEditCb fnc;
void *fnc_value;
};
void
_gpgme_release_edit_result (EditResult result)
{
if (!result)
return;
xfree (result);
}
void
_gpgme_edit_status_handler (GpgmeCtx ctx, GpgmeStatusCode status, char *args)
{
_gpgme_passphrase_status_handler (ctx, status, args);
if (ctx->error)
return;
ctx->error = (*ctx->result.edit->fnc) (ctx->result.edit->fnc_value, status, args, NULL);
}
static const char *
command_handler (void *opaque, GpgmeStatusCode status, const char *args)
{
GpgmeCtx ctx = opaque;
const char *result;
result = _gpgme_passphrase_command_handler (ctx, status, args);
if (!result)
ctx->error = (*ctx->result.edit->fnc) (ctx->result.edit->fnc_value, status, args, &result);
return result;
}
static GpgmeError
_gpgme_op_edit_start (GpgmeCtx ctx, int synchronous,
GpgmeKey key,
GpgmeEditCb fnc, void *fnc_value,
GpgmeData out)
{
GpgmeError err = 0;
if (!fnc)
return mk_error (Invalid_Value);
err = _gpgme_op_reset (ctx, synchronous);
if (err)
goto leave;
assert (!ctx->result.edit);
ctx->result.edit = xtrymalloc (sizeof *ctx->result.edit);
if (!ctx->result.edit)
{
err = mk_error (Out_Of_Core);
goto leave;
}
ctx->result.edit->fnc = fnc;
ctx->result.edit->fnc_value = fnc_value;
/* Check the supplied data. */
if (!out || gpgme_data_get_type (out) != GPGME_DATA_TYPE_NONE)
{
err = mk_error (Invalid_Value);
goto leave;
}
_gpgme_data_set_mode (out, GPGME_DATA_MODE_IN);
err = _gpgme_engine_set_command_handler (ctx->engine, command_handler,
ctx, out);
if (err)
goto leave;
_gpgme_engine_set_status_handler (ctx->engine, _gpgme_edit_status_handler,
ctx);
_gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
_gpgme_engine_op_edit (ctx->engine, key, out);
/* And kick off the process. */
err = _gpgme_engine_start (ctx->engine, ctx);
leave:
if (err)
{
ctx->pending = 0;
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
return err;
}
GpgmeError
gpgme_op_edit_start (GpgmeCtx ctx,
GpgmeKey key,
GpgmeEditCb fnc, void *fnc_value,
GpgmeData out)
{
return _gpgme_op_edit_start (ctx, 0, key, fnc, fnc_value, out);
}
/**
* gpgme_op_edit:
* @ctx: The context
* @key: The key to be edited.
* @fnc: An edit callback handler.
* @fnc_value: To be passed to @fnc as first arg.
* @out: The output.
*
* Return value: 0 on success or an error code.
**/
GpgmeError
gpgme_op_edit (GpgmeCtx ctx,
GpgmeKey key,
GpgmeEditCb fnc, void *fnc_value,
GpgmeData out)
{
GpgmeError err = _gpgme_op_edit_start (ctx, 1, key, fnc, fnc_value, out);
if (!err)
err = _gpgme_wait_one (ctx);
return err;
}

View File

@ -34,21 +34,21 @@
static void
encrypt_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
encrypt_sign_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
char *encrypt_info = 0;
size_t encrypt_info_len;
_gpgme_encrypt_status_handler (ctx, code, args);
if (code == STATUS_EOF)
if (code == GPGME_STATUS_EOF)
{
encrypt_info = gpgme_data_release_and_get_mem (ctx->op_info,
&encrypt_info_len);
ctx->op_info = NULL;
}
_gpgme_sign_status_handler (ctx, code, args);
if (code == STATUS_EOF && encrypt_info)
if (code == GPGME_STATUS_EOF && encrypt_info)
_gpgme_data_append (ctx->op_info, encrypt_info, encrypt_info_len);
}

View File

@ -100,7 +100,7 @@ append_xml_encinfo (GpgmeData *rdh, char *args)
void
_gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
_gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
if (ctx->error)
return;
@ -108,7 +108,7 @@ _gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
switch (code)
{
case STATUS_EOF:
case GPGME_STATUS_EOF:
if (ctx->result.encrypt->xmlinfo)
{
append_xml_encinfo (&ctx->result.encrypt->xmlinfo, NULL);
@ -121,12 +121,12 @@ _gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
ctx->error = mk_error (Invalid_Recipients);
break;
case STATUS_INV_RECP:
case GPGME_STATUS_INV_RECP:
ctx->result.encrypt->invalid_recipients++;
append_xml_encinfo (&ctx->result.encrypt->xmlinfo, args);
break;
case STATUS_NO_RECP:
case GPGME_STATUS_NO_RECP:
ctx->result.encrypt->no_valid_recipients = 1;
break;
@ -137,7 +137,7 @@ _gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
void
_gpgme_encrypt_sym_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
_gpgme_encrypt_sym_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
_gpgme_passphrase_status_handler (ctx, code, args);
}

View File

@ -545,7 +545,7 @@ _gpgme_gpgsm_release (GpgsmObject gpgsm)
}
/* Forward declaration. */
static GpgStatusCode parse_status (const char *name);
static GpgmeStatusCode parse_status (const char *name);
static GpgmeError
gpgsm_assuan_simple_command (ASSUAN_CONTEXT ctx, char *cmd, GpgStatusHandler status_fnc,
@ -580,7 +580,7 @@ gpgsm_assuan_simple_command (ASSUAN_CONTEXT ctx, char *cmd, GpgStatusHandler sta
&& line[0] == 'S' && line[1] == ' ')
{
char *rest;
GpgStatusCode r;
GpgmeStatusCode r;
rest = strchr (line + 2, ' ');
if (!rest)
@ -772,7 +772,7 @@ gpgsm_set_recipients (GpgsmObject gpgsm, GpgmeRecipients recp)
}
xfree (line);
if (!valid_recipients && gpgsm->status.fnc)
gpgsm->status.fnc (gpgsm->status.fnc_value, STATUS_NO_RECP, "");
gpgsm->status.fnc (gpgsm->status.fnc_value, GPGME_STATUS_NO_RECP, "");
return 0;
}
@ -1166,7 +1166,7 @@ status_cmp (const void *ap, const void *bp)
}
static GpgStatusCode
static GpgmeStatusCode
parse_status (const char *name)
{
struct status_table_s t, *r;
@ -1216,7 +1216,7 @@ gpgsm_status_handler (void *opaque, int fd)
}
if (gpgsm->status.fnc)
gpgsm->status.fnc (gpgsm->status.fnc_value, STATUS_EOF, "");
gpgsm->status.fnc (gpgsm->status.fnc_value, GPGME_STATUS_EOF, "");
/* XXX: Try our best to terminate the connection. */
if (err)
@ -1296,7 +1296,7 @@ gpgsm_status_handler (void *opaque, int fd)
&& line[0] == 'S' && line[1] == ' ')
{
char *rest;
GpgStatusCode r;
GpgmeStatusCode r;
rest = strchr (line + 2, ' ');
if (!rest)

View File

@ -262,7 +262,8 @@ _gpgme_engine_set_status_handler (EngineObject engine,
GpgmeError
_gpgme_engine_set_command_handler (EngineObject engine,
GpgCommandHandler fnc, void *fnc_value)
GpgCommandHandler fnc, void *fnc_value,
GpgmeData linked_data)
{
if (!engine)
return mk_error (Invalid_Value);
@ -270,7 +271,8 @@ _gpgme_engine_set_command_handler (EngineObject engine,
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
return _gpgme_gpg_set_command_handler (engine->engine.gpg, fnc, fnc_value);
return _gpgme_gpg_set_command_handler (engine->engine.gpg,
fnc, fnc_value, linked_data);
case GPGME_PROTOCOL_CMS:
/* FIXME */
break;
@ -340,6 +342,25 @@ _gpgme_engine_op_delete (EngineObject engine, GpgmeKey key, int allow_secret)
}
GpgmeError
_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);
case GPGME_PROTOCOL_CMS:
/* FIXME */
return mk_error (Not_Implemented);
default:
break;
}
return 0;
}
GpgmeError
_gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp,
GpgmeData plain, GpgmeData ciph, int use_armor)

View File

@ -34,7 +34,8 @@ void _gpgme_engine_set_status_handler (EngineObject engine,
GpgStatusHandler fnc, void *fnc_value);
GpgmeError _gpgme_engine_set_command_handler (EngineObject engine,
GpgCommandHandler fnc,
void *fnc_value);
void *fnc_value,
GpgmeData data);
GpgmeError _gpgme_engine_set_colon_line_handler (EngineObject gpg,
GpgColonLineHandler fnc,
void *fnc_value);
@ -43,6 +44,8 @@ GpgmeError _gpgme_engine_op_decrypt (EngineObject engine, GpgmeData ciph,
GpgmeData plain);
GpgmeError _gpgme_engine_op_delete (EngineObject engine, GpgmeKey key,
int allow_secret);
GpgmeError _gpgme_engine_op_edit (EngineObject engine, GpgmeKey key,
GpgmeData out);
GpgmeError _gpgme_engine_op_encrypt (EngineObject engine, GpgmeRecipients recp,
GpgmeData plain, GpgmeData ciph,
int use_armor);

View File

@ -31,7 +31,7 @@
static void
export_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
export_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
if (ctx->error)
return;

View File

@ -46,7 +46,7 @@ _gpgme_release_genkey_result (GenKeyResult result)
}
static void
genkey_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
genkey_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
_gpgme_progress_status_handler (ctx, code, args);
@ -56,7 +56,7 @@ genkey_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
switch (code)
{
case STATUS_KEY_CREATED:
case GPGME_STATUS_KEY_CREATED:
if (args && *args)
{
if (*args == 'B' || *args == 'P')
@ -66,7 +66,7 @@ genkey_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
}
break;
case STATUS_EOF:
case GPGME_STATUS_EOF:
/* FIXME: Should return some more useful error value. */
if (!ctx->result.genkey->created_primary
&& !ctx->result.genkey->created_sub)

View File

@ -95,6 +95,7 @@ _gpgme_release_result (GpgmeCtx ctx)
_gpgme_release_delete_result (ctx->result.delete);
_gpgme_release_genkey_result (ctx->result.genkey);
_gpgme_release_keylist_result (ctx->result.keylist);
_gpgme_release_edit_result (ctx->result.edit);
memset (&ctx->result, 0, sizeof (ctx->result));
_gpgme_set_op_info (ctx, NULL);
ctx->error = 0;

View File

@ -222,6 +222,90 @@ typedef enum
GpgmeProtocol;
/* The possible stati for the edit operation. */
typedef enum {
GPGME_STATUS_EOF,
/* mkstatus starts here */
GPGME_STATUS_ENTER ,
GPGME_STATUS_LEAVE ,
GPGME_STATUS_ABORT ,
GPGME_STATUS_GOODSIG ,
GPGME_STATUS_BADSIG ,
GPGME_STATUS_ERRSIG ,
GPGME_STATUS_BADARMOR ,
GPGME_STATUS_RSA_OR_IDEA ,
GPGME_STATUS_KEYEXPIRED ,
GPGME_STATUS_KEYREVOKED ,
GPGME_STATUS_TRUST_UNDEFINED ,
GPGME_STATUS_TRUST_NEVER ,
GPGME_STATUS_TRUST_MARGINAL ,
GPGME_STATUS_TRUST_FULLY ,
GPGME_STATUS_TRUST_ULTIMATE ,
GPGME_STATUS_SHM_INFO ,
GPGME_STATUS_SHM_GET ,
GPGME_STATUS_SHM_GET_BOOL ,
GPGME_STATUS_SHM_GET_HIDDEN ,
GPGME_STATUS_NEED_PASSPHRASE ,
GPGME_STATUS_VALIDSIG ,
GPGME_STATUS_SIG_ID ,
GPGME_STATUS_ENC_TO ,
GPGME_STATUS_NODATA ,
GPGME_STATUS_BAD_PASSPHRASE ,
GPGME_STATUS_NO_PUBKEY ,
GPGME_STATUS_NO_SECKEY ,
GPGME_STATUS_NEED_PASSPHRASE_SYM,
GPGME_STATUS_DECRYPTION_FAILED ,
GPGME_STATUS_DECRYPTION_OKAY ,
GPGME_STATUS_MISSING_PASSPHRASE ,
GPGME_STATUS_GOOD_PASSPHRASE ,
GPGME_STATUS_GOODMDC ,
GPGME_STATUS_BADMDC ,
GPGME_STATUS_ERRMDC ,
GPGME_STATUS_IMPORTED ,
GPGME_STATUS_IMPORT_RES ,
GPGME_STATUS_FILE_START ,
GPGME_STATUS_FILE_DONE ,
GPGME_STATUS_FILE_ERROR ,
GPGME_STATUS_BEGIN_DECRYPTION ,
GPGME_STATUS_END_DECRYPTION ,
GPGME_STATUS_BEGIN_ENCRYPTION ,
GPGME_STATUS_END_ENCRYPTION ,
GPGME_STATUS_DELETE_PROBLEM ,
GPGME_STATUS_GET_BOOL ,
GPGME_STATUS_GET_LINE ,
GPGME_STATUS_GET_HIDDEN ,
GPGME_STATUS_GOT_IT ,
GPGME_STATUS_PROGRESS ,
GPGME_STATUS_SIG_CREATED ,
GPGME_STATUS_SESSION_KEY ,
GPGME_STATUS_NOTATION_NAME ,
GPGME_STATUS_NOTATION_DATA ,
GPGME_STATUS_POLICY_URL ,
GPGME_STATUS_BEGIN_STREAM ,
GPGME_STATUS_END_STREAM ,
GPGME_STATUS_KEY_CREATED ,
GPGME_STATUS_USERID_HINT ,
GPGME_STATUS_UNEXPECTED ,
GPGME_STATUS_INV_RECP ,
GPGME_STATUS_NO_RECP ,
GPGME_STATUS_ALREADY_SIGNED ,
GPGME_STATUS_SIGEXPIRED ,
GPGME_STATUS_EXPSIG ,
GPGME_STATUS_EXPKEYSIG ,
GPGME_STATUS_TRUNCATED ,
GPGME_STATUS_ERROR ,
} GpgmeStatusCode;
/* The available keylist mode flags. */
#define GPGME_KEYLIST_MODE_LOCAL 1
#define GPGME_KEYLIST_MODE_EXTERN 2
@ -237,6 +321,9 @@ typedef const char *(*GpgmePassphraseCb) (void *hook, const char *desc,
typedef void (*GpgmeProgressCb) (void *opaque, const char *what,
int type, int current, int total);
/* Interact with the user about an edit operation. */
typedef GpgmeError (*GpgmeEditCb) (void *opaque, GpgmeStatusCode status,
const char *args, const char **reply);
/* Context management functions. */
@ -598,6 +685,14 @@ GpgmeError gpgme_op_delete_start (GpgmeCtx ctx, const GpgmeKey key,
GpgmeError gpgme_op_delete (GpgmeCtx ctx, const GpgmeKey key,
int allow_secret);
/* Edit the key KEY. Send status and command requests to FNC and
output of edit commands to OUT. */
GpgmeError gpgme_op_edit_start (GpgmeCtx ctx, GpgmeKey key,
GpgmeEditCb fnc, void *fnc_value,
GpgmeData out);
GpgmeError gpgme_op_edit (GpgmeCtx ctx, GpgmeKey key,
GpgmeEditCb fnc, void *fnc_value,
GpgmeData out);
/* Key management functions */

View File

@ -51,7 +51,7 @@ _gpgme_release_import_result (ImportResult result)
the data buffer. With args of NULL the xml structure is
closed. */
static void
append_xml_impinfo (GpgmeData *rdh, GpgStatusCode code, char *args)
append_xml_impinfo (GpgmeData *rdh, GpgmeStatusCode code, char *args)
{
#define MAX_IMPORTED_FIELDS 14
static const char *const imported_fields[MAX_IMPORTED_FIELDS]
@ -68,14 +68,14 @@ append_xml_impinfo (GpgmeData *rdh, GpgStatusCode code, char *args)
int i;
/* Verify that we can use the args. */
if (code != STATUS_EOF)
if (code != GPGME_STATUS_EOF)
{
if (!args)
return;
if (code == STATUS_IMPORTED)
if (code == GPGME_STATUS_IMPORTED)
field_name = imported_fields;
else if (code == STATUS_IMPORT_RES)
else if (code == GPGME_STATUS_IMPORT_RES)
field_name = import_res_fields;
else
return;
@ -94,7 +94,7 @@ append_xml_impinfo (GpgmeData *rdh, GpgStatusCode code, char *args)
/* gpgsm does not print a useful user ID and uses a fingerprint
instead of the key ID. */
if (code == STATUS_IMPORTED && field[0] && strlen (field[0]) > 16)
if (code == GPGME_STATUS_IMPORTED && field[0] && strlen (field[0]) > 16)
field_name = imported_fields_x509;
}
@ -109,16 +109,16 @@ append_xml_impinfo (GpgmeData *rdh, GpgStatusCode code, char *args)
else
dh = *rdh;
if (code == STATUS_EOF)
if (code == GPGME_STATUS_EOF)
{
/* Just close the XML containter. */
_gpgme_data_append_string (dh, "</GnupgOperationInfo>\n");
}
else
{
if (code == STATUS_IMPORTED)
if (code == GPGME_STATUS_IMPORTED)
_gpgme_data_append_string (dh, " <import>\n");
else if (code == STATUS_IMPORT_RES)
else if (code == GPGME_STATUS_IMPORT_RES)
_gpgme_data_append_string (dh, " <importResult>\n");
for (i = 0; field_name[i]; i++)
@ -132,16 +132,16 @@ append_xml_impinfo (GpgmeData *rdh, GpgStatusCode code, char *args)
_gpgme_data_append_string (dh, ">\n");
}
if (code == STATUS_IMPORTED)
if (code == GPGME_STATUS_IMPORTED)
_gpgme_data_append_string (dh, " </import>\n");
else if (code == STATUS_IMPORT_RES)
else if (code == GPGME_STATUS_IMPORT_RES)
_gpgme_data_append_string (dh, " </importResult>\n");
}
}
static void
import_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
import_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
if (ctx->error)
return;
@ -149,7 +149,7 @@ import_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
switch (code)
{
case STATUS_EOF:
case GPGME_STATUS_EOF:
if (ctx->result.import->xmlinfo)
{
append_xml_impinfo (&ctx->result.import->xmlinfo, code, NULL);
@ -159,9 +159,9 @@ import_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
/* XXX Calculate error value. */
break;
case STATUS_IMPORTED:
case GPGME_STATUS_IMPORTED:
ctx->result.import->any_imported = 1;
case STATUS_IMPORT_RES:
case GPGME_STATUS_IMPORT_RES:
append_xml_impinfo (&ctx->result.import->xmlinfo, code, args);
break;

View File

@ -59,7 +59,7 @@ int _gpgme_io_spawn (const char *path, char **argv,
struct spawn_fd_item_s *fd_parent_list);
int _gpgme_io_waitpid (int pid, int hang, int *r_status, int *r_signal);
int _gpgme_io_kill (int pid, int hard);
int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds);
int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock);
#endif /* IO_H */

View File

@ -88,7 +88,7 @@ append_xml_keylistinfo (GpgmeData *rdh, char *args)
static void
keylist_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
keylist_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
if (ctx->error)
return;
@ -96,11 +96,11 @@ keylist_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
switch (code)
{
case STATUS_TRUNCATED:
case GPGME_STATUS_TRUNCATED:
ctx->result.keylist->truncated = 1;
break;
case STATUS_EOF:
case GPGME_STATUS_EOF:
finish_key (ctx);
if (ctx->result.keylist->truncated)
append_xml_keylistinfo (&ctx->result.keylist->xmlinfo, "1");

View File

@ -31,7 +31,7 @@ cat <<EOF
struct status_table_s {
const char *name;
GpgStatusCode code;
GpgmeStatusCode code;
};
static struct status_table_s status_table[] =
@ -39,10 +39,10 @@ static struct status_table_s status_table[] =
EOF
awk '
/STATUS_ENTER/ { okay=1 }
/GPGME_STATUS_ENTER/ { okay=1 }
!okay {next}
/}/ { exit 0 }
/STATUS_[A-Za-z_]*/ { printf " { \"%s\", %s },\n", substr($1,8), $1 }
/GPGME_STATUS_[A-Za-z_]*/ { printf " { \"%s\", %s },\n", substr($1,14), $1 }
' | sort
cat <<EOF
@ -50,12 +50,3 @@ cat <<EOF
};
EOF

View File

@ -89,12 +89,12 @@ GpgmeError _gpgme_op_reset (GpgmeCtx ctx, int synchronous);
/*-- verify.c --*/
void _gpgme_release_verify_result (VerifyResult result);
GpgmeSigStat _gpgme_intersect_stati (VerifyResult result);
void _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code,
void _gpgme_verify_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args);
/*-- decrypt.c --*/
void _gpgme_release_decrypt_result (DecryptResult result);
void _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code,
void _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args);
GpgmeError _gpgme_decrypt_start (GpgmeCtx ctx, int synchronous,
GpgmeData ciph, GpgmeData plain,
@ -103,22 +103,25 @@ GpgmeError _gpgme_decrypt_result (GpgmeCtx ctx);
/*-- sign.c --*/
void _gpgme_release_sign_result ( SignResult res );
void _gpgme_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code,
void _gpgme_sign_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args);
/*-- encrypt.c --*/
void _gpgme_release_encrypt_result ( EncryptResult res );
void _gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code,
void _gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args);
/*-- passphrase.c --*/
void _gpgme_release_passphrase_result (PassphraseResult result);
void _gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgStatusCode code,
void _gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args);
const char * _gpgme_passphrase_command_handler (void *opaque,
GpgmeStatusCode code,
const char *key);
GpgmeError _gpgme_passphrase_start (GpgmeCtx ctx);
/*-- progress.c --*/
void _gpgme_progress_status_handler (GpgmeCtx ctx, GpgStatusCode code,
void _gpgme_progress_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args);
/*-- import.c --*/
@ -137,6 +140,9 @@ void _gpgme_op_keylist_event_cb (void *data, GpgmeEventIO type, void *type_data)
/*-- trustlist.c --*/
void _gpgme_op_trustlist_event_cb (void *data, GpgmeEventIO type, void *type_data);
/*-- edit.c --*/
void _gpgme_release_edit_result (EditResult res);
/*-- version.c --*/
const char *_gpgme_compare_versions (const char *my_version,
const char *req_version);

View File

@ -52,7 +52,7 @@ _gpgme_release_passphrase_result (PassphraseResult result)
void
_gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
_gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
if (ctx->error)
return;
@ -60,34 +60,34 @@ _gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
switch (code)
{
case STATUS_USERID_HINT:
case GPGME_STATUS_USERID_HINT:
xfree (ctx->result.passphrase->userid_hint);
if (!(ctx->result.passphrase->userid_hint = xtrystrdup (args)))
ctx->error = mk_error (Out_Of_Core);
break;
case STATUS_BAD_PASSPHRASE:
case GPGME_STATUS_BAD_PASSPHRASE:
ctx->result.passphrase->bad_passphrase++;
break;
case STATUS_GOOD_PASSPHRASE:
case GPGME_STATUS_GOOD_PASSPHRASE:
ctx->result.passphrase->bad_passphrase = 0;
break;
case STATUS_NEED_PASSPHRASE:
case STATUS_NEED_PASSPHRASE_SYM:
case GPGME_STATUS_NEED_PASSPHRASE:
case GPGME_STATUS_NEED_PASSPHRASE_SYM:
xfree (ctx->result.passphrase->passphrase_info);
ctx->result.passphrase->passphrase_info = xtrystrdup (args);
if (!ctx->result.passphrase->passphrase_info)
ctx->error = mk_error (Out_Of_Core);
break;
case STATUS_MISSING_PASSPHRASE:
case GPGME_STATUS_MISSING_PASSPHRASE:
DEBUG0 ("missing passphrase - stop\n");;
ctx->result.passphrase->no_passphrase = 1;
break;
case STATUS_EOF:
case GPGME_STATUS_EOF:
if (ctx->result.passphrase->no_passphrase
|| ctx->result.passphrase->bad_passphrase)
ctx->error = mk_error (No_Passphrase);
@ -100,8 +100,8 @@ _gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
}
static const char *
command_handler (void *opaque, GpgStatusCode code, const char *key)
const char *
_gpgme_passphrase_command_handler (void *opaque, GpgmeStatusCode code, const char *key)
{
GpgmeCtx ctx = opaque;
@ -130,7 +130,7 @@ command_handler (void *opaque, GpgStatusCode code, const char *key)
if (!key || !ctx->passphrase_cb)
return NULL;
if (code == STATUS_GET_HIDDEN && !strcmp (key, "passphrase.enter"))
if (code == GPGME_STATUS_GET_HIDDEN && !strcmp (key, "passphrase.enter"))
{
const char *userid_hint = ctx->result.passphrase->userid_hint;
const char *passphrase_info = ctx->result.passphrase->passphrase_info;
@ -170,6 +170,7 @@ _gpgme_passphrase_start (GpgmeCtx ctx)
GpgmeError err = 0;
if (ctx->passphrase_cb)
err = _gpgme_engine_set_command_handler (ctx->engine, command_handler, ctx);
err = _gpgme_engine_set_command_handler (ctx->engine, _gpgme_passphrase_command_handler,
ctx, NULL);
return err;
}

View File

@ -287,12 +287,12 @@ _gpgme_io_kill (int pid, int hard)
* >0 = number of signaled fds
*/
int
_gpgme_io_select (struct io_select_fd_s *fds, size_t nfds)
_gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
{
fd_set readfds;
fd_set writefds;
int any, i, max_fd, n, count;
struct timeval timeout = { 1, 0 }; /* Use a 1s timeout. */
struct timeval timeout = { nonblock ? 0 : 1, 0 }; /* Use a 1s timeout. */
void *dbg_help = NULL;
FD_ZERO (&readfds);

View File

@ -30,7 +30,7 @@
void
_gpgme_progress_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
_gpgme_progress_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
char *p;
char *args_cpy;
@ -38,7 +38,7 @@ _gpgme_progress_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
int current = 0;
int total = 0;
if (code != STATUS_PROGRESS || !*args || !ctx->progress_cb)
if (code != GPGME_STATUS_PROGRESS || !*args || !ctx->progress_cb)
return;
args_cpy = xtrystrdup (args);

View File

@ -119,10 +119,14 @@ struct gpg_object_s
int fd;
int idx; /* Index in fd_data_map */
GpgmeData cb_data; /* hack to get init the above idx later */
GpgStatusCode code; /* last code */
GpgmeStatusCode code; /* last code */
char *keyword; /* what has been requested (malloced) */
GpgCommandHandler fnc;
void *fnc_value;
/* The kludges never end. This is used to couple command handlers
with output data in edit key mode. */
GpgmeData linked_data;
int linked_idx;
} cmd;
struct GpgmeIOCbs io_cbs;
@ -257,6 +261,8 @@ _gpgme_gpg_new (GpgObject *r_gpg)
gpg->colon.fd[1] = -1;
gpg->cmd.fd = -1;
gpg->cmd.idx = -1;
gpg->cmd.linked_data = NULL;
gpg->cmd.linked_idx = -1;
gpg->pid = -1;
@ -518,27 +524,29 @@ _gpgme_gpg_set_simple_line_handler ( GpgObject gpg,
*/
GpgmeError
_gpgme_gpg_set_command_handler ( GpgObject gpg,
GpgCommandHandler fnc, void *fnc_value )
_gpgme_gpg_set_command_handler (GpgObject gpg,
GpgCommandHandler fnc, void *fnc_value,
GpgmeData linked_data)
{
GpgmeData tmp;
GpgmeError err;
GpgmeData tmp;
GpgmeError err;
assert (gpg);
if (gpg->pm.active)
return 0;
err = gpgme_data_new_with_read_cb ( &tmp, command_cb, gpg );
if (err)
return err;
_gpgme_gpg_add_arg ( gpg, "--command-fd" );
_gpgme_gpg_add_data (gpg, tmp, -2);
gpg->cmd.cb_data = tmp;
gpg->cmd.fnc = fnc;
gpg->cmd.fnc_value = fnc_value;
gpg->cmd.used = 1;
assert (gpg);
if (gpg->pm.active)
return 0;
err = gpgme_data_new_with_read_cb (&tmp, command_cb, gpg);
if (err)
return err;
_gpgme_gpg_add_arg ( gpg, "--command-fd" );
_gpgme_gpg_add_data (gpg, tmp, -2);
gpg->cmd.cb_data = tmp;
gpg->cmd.fnc = fnc;
gpg->cmd.fnc_value = fnc_value;
gpg->cmd.linked_data = linked_data;
gpg->cmd.used = 1;
return 0;
}
@ -763,10 +771,18 @@ build_argv (GpgObject gpg)
}
/* Hack to get hands on the fd later. */
if (gpg->cmd.used && gpg->cmd.cb_data == a->data)
if (gpg->cmd.used)
{
assert (gpg->cmd.idx == -1);
gpg->cmd.idx = datac;
if (gpg->cmd.cb_data == a->data)
{
assert (gpg->cmd.idx == -1);
gpg->cmd.idx = datac;
}
else if (gpg->cmd.linked_data == a->data)
{
assert (gpg->cmd.linked_idx == -1);
gpg->cmd.linked_idx = datac;
}
}
fd_data_map[datac].data = a->data;
@ -1001,86 +1017,118 @@ status_cmp (const void *ap, const void *bp)
* 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 )
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;
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 = xtryrealloc (buffer, bufsize);
if ( !buffer )
return mk_error (Out_Of_Core);
}
nread = _gpgme_io_read ( gpg->status.fd[0],
buffer+readpos, bufsize-readpos );
if (nread == -1)
return mk_error(Read_Error);
if (!nread) {
gpg->status.eof = 1;
if (gpg->status.fnc)
gpg->status.fnc ( gpg->status.fnc_value, STATUS_EOF, "" );
return 0;
assert (buffer);
if (bufsize - readpos < 256)
{
/* Need more room for the read. */
bufsize += 1024;
buffer = xtryrealloc (buffer, bufsize);
if (!buffer)
return mk_error (Out_Of_Core);
}
while (nread > 0) {
for (p = buffer + readpos; nread; nread--, p++) {
if ( *p == '\n' ) {
/* (we require that the last line is terminated by a LF) */
*p = 0;
if (!strncmp (buffer, "[GNUPG:] ", 9 )
&& buffer[9] >= 'A' && buffer[9] <= 'Z' ) {
struct status_table_s t, *r;
char *rest;
nread = _gpgme_io_read (gpg->status.fd[0],
buffer + readpos, bufsize-readpos);
if (nread == -1)
return mk_error(Read_Error);
rest = strchr (buffer+9, ' ');
if ( !rest )
rest = p; /* set to an empty string */
else
*rest++ = 0;
if (!nread)
{
gpg->status.eof = 1;
if (gpg->status.fnc)
gpg->status.fnc (gpg->status.fnc_value, GPGME_STATUS_EOF, "");
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) */
*p = 0;
if (!strncmp (buffer, "[GNUPG:] ", 9)
&& buffer[9] >= 'A' && buffer[9] <= 'Z')
{
struct status_table_s t, *r;
char *rest;
rest = strchr (buffer + 9, ' ');
if (!rest)
rest = p; /* Set to an empty string. */
else
*rest++ = 0;
t.name = buffer+9;
/* (the status table as one extra element) */
r = bsearch ( &t, status_table, DIM(status_table)-1,
sizeof t, status_cmp );
if ( r ) {
if ( gpg->cmd.used
&& ( r->code == STATUS_GET_BOOL
|| r->code == STATUS_GET_LINE
|| r->code == STATUS_GET_HIDDEN )) {
gpg->cmd.code = r->code;
xfree (gpg->cmd.keyword);
gpg->cmd.keyword = xtrystrdup (rest);
if ( !gpg->cmd.keyword )
return mk_error (Out_Of_Core);
/* this should be the last thing we have received
* and the next thing will be that the command
* handler does its action */
if ( nread > 1 )
DEBUG0 ("ERROR, unexpected data in read_status");
t.name = buffer+9;
/* (the status table has one extra element) */
r = bsearch (&t, status_table, DIM(status_table) - 1,
sizeof t, status_cmp);
if (r)
{
if (gpg->cmd.used
&& (r->code == GPGME_STATUS_GET_BOOL
|| r->code == GPGME_STATUS_GET_LINE
|| r->code == GPGME_STATUS_GET_HIDDEN))
{
gpg->cmd.code = r->code;
xfree (gpg->cmd.keyword);
gpg->cmd.keyword = xtrystrdup (rest);
if (!gpg->cmd.keyword)
return mk_error (Out_Of_Core);
/* This should be the last thing we have
received and the next thing will be that
the command handler does its action. */
if (nread > 1)
DEBUG0 ("ERROR, unexpected data in read_status");
_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);
gpg->fd_data_map[gpg->cmd.idx].fd = gpg->cmd.fd;
gpg->cmd.fd = -1;
/* Before we can actually add the command
fd, we might have to flush the linked
output data pipe. */
if (gpg->cmd.linked_idx != -1
&& gpg->fd_data_map[gpg->cmd.linked_idx].fd != -1)
{
struct io_select_fd_s fds;
fds.fd = gpg->fd_data_map[gpg->cmd.linked_idx].fd;
fds.for_read = 1;
fds.for_write = 0;
fds.frozen = 0;
fds.opaque = NULL;
do
{
fds.signaled = 0;
_gpgme_io_select (&fds, 1, 1);
if (fds.signaled)
_gpgme_data_inbound_handler
(gpg->cmd.linked_data, fds.fd);
}
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);
gpg->fd_data_map[gpg->cmd.idx].fd = gpg->cmd.fd;
gpg->cmd.fd = -1;
}
else if ( gpg->status.fnc ) {
gpg->status.fnc ( gpg->status.fnc_value,
r->code, rest);
else if (gpg->status.fnc)
{
gpg->status.fnc (gpg->status.fnc_value,
r->code, rest);
}
if ( r->code == STATUS_END_STREAM ) {
if (r->code == GPGME_STATUS_END_STREAM)
{
if (gpg->cmd.used)
{
/* XXX We must check if there are any
@ -1094,28 +1142,28 @@ read_status ( GpgObject gpg )
}
}
}
/* 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 */
/* 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++;
else
readpos++;
}
}
/* Update the gpg object. */
gpg->status.bufsize = bufsize;
gpg->status.buffer = buffer;
gpg->status.readpos = readpos;
return 0;
/* Update the gpg object. */
gpg->status.bufsize = bufsize;
gpg->status.buffer = buffer;
gpg->status.readpos = readpos;
return 0;
}
@ -1399,6 +1447,29 @@ _gpgme_gpg_op_delete (GpgObject gpg, GpgmeKey key, int allow_secret)
}
GpgmeError
_gpgme_gpg_op_edit (GpgObject gpg, GpgmeKey key, GpgmeData out)
{
GpgmeError err;
err = _gpgme_gpg_add_arg (gpg, "--edit-key");
if (!err)
err = _gpgme_gpg_add_data (gpg, out, 1);
if (!err)
err = _gpgme_gpg_add_arg (gpg, "--");
if (!err)
{
const char *s = gpgme_key_get_string_attr (key, GPGME_ATTR_FPR, NULL, 0);
if (!s)
err = mk_error (Invalid_Key);
else
err = _gpgme_gpg_add_arg (gpg, s);
}
return err;
}
static GpgmeError
_gpgme_append_gpg_args_from_recipients (GpgObject gpg,
const GpgmeRecipients rset)

View File

@ -24,92 +24,9 @@
#include "types.h"
typedef enum {
STATUS_EOF ,
/* mkstatus starts here */
STATUS_ENTER ,
STATUS_LEAVE ,
STATUS_ABORT ,
STATUS_GOODSIG ,
STATUS_BADSIG ,
STATUS_ERRSIG ,
STATUS_BADARMOR ,
STATUS_RSA_OR_IDEA ,
STATUS_KEYEXPIRED ,
STATUS_KEYREVOKED ,
STATUS_TRUST_UNDEFINED ,
STATUS_TRUST_NEVER ,
STATUS_TRUST_MARGINAL ,
STATUS_TRUST_FULLY ,
STATUS_TRUST_ULTIMATE ,
STATUS_SHM_INFO ,
STATUS_SHM_GET ,
STATUS_SHM_GET_BOOL ,
STATUS_SHM_GET_HIDDEN ,
STATUS_NEED_PASSPHRASE ,
STATUS_VALIDSIG ,
STATUS_SIG_ID ,
STATUS_ENC_TO ,
STATUS_NODATA ,
STATUS_BAD_PASSPHRASE ,
STATUS_NO_PUBKEY ,
STATUS_NO_SECKEY ,
STATUS_NEED_PASSPHRASE_SYM,
STATUS_DECRYPTION_FAILED ,
STATUS_DECRYPTION_OKAY ,
STATUS_MISSING_PASSPHRASE ,
STATUS_GOOD_PASSPHRASE ,
STATUS_GOODMDC ,
STATUS_BADMDC ,
STATUS_ERRMDC ,
STATUS_IMPORTED ,
STATUS_IMPORT_RES ,
STATUS_FILE_START ,
STATUS_FILE_DONE ,
STATUS_FILE_ERROR ,
STATUS_BEGIN_DECRYPTION ,
STATUS_END_DECRYPTION ,
STATUS_BEGIN_ENCRYPTION ,
STATUS_END_ENCRYPTION ,
STATUS_DELETE_PROBLEM ,
STATUS_GET_BOOL ,
STATUS_GET_LINE ,
STATUS_GET_HIDDEN ,
STATUS_GOT_IT ,
STATUS_PROGRESS ,
STATUS_SIG_CREATED ,
STATUS_SESSION_KEY ,
STATUS_NOTATION_NAME ,
STATUS_NOTATION_DATA ,
STATUS_POLICY_URL ,
STATUS_BEGIN_STREAM ,
STATUS_END_STREAM ,
STATUS_KEY_CREATED ,
STATUS_USERID_HINT ,
STATUS_UNEXPECTED ,
STATUS_INV_RECP ,
STATUS_NO_RECP ,
STATUS_ALREADY_SIGNED ,
STATUS_SIGEXPIRED ,
STATUS_EXPSIG ,
STATUS_EXPKEYSIG ,
STATUS_TRUNCATED ,
STATUS_ERROR ,
} GpgStatusCode;
typedef void (*GpgStatusHandler)( GpgmeCtx, GpgStatusCode code, char *args );
typedef void (*GpgStatusHandler)( GpgmeCtx, GpgmeStatusCode code, char *args );
typedef void (*GpgColonLineHandler)( GpgmeCtx, char *line );
typedef const char *(*GpgCommandHandler)(void*, GpgStatusCode code,
typedef const char *(*GpgCommandHandler)(void*, GpgmeStatusCode code,
const char *keyword);
const char *_gpgme_gpg_get_version (void);
@ -122,22 +39,24 @@ void _gpgme_gpg_enable_pipemode ( GpgObject gpg );
GpgmeError _gpgme_gpg_add_arg ( GpgObject gpg, const char *arg );
GpgmeError _gpgme_gpg_add_data ( GpgObject gpg, GpgmeData data, int dup_to );
GpgmeError _gpgme_gpg_add_pm_data ( GpgObject gpg, GpgmeData data, int what );
void _gpgme_gpg_set_status_handler ( GpgObject gpg,
GpgStatusHandler fnc,
void *fnc_value );
void _gpgme_gpg_set_status_handler (GpgObject gpg,
GpgStatusHandler fnc,
void *fnc_value);
GpgmeError _gpgme_gpg_set_colon_line_handler ( GpgObject gpg,
GpgColonLineHandler fnc,
void *fnc_value );
GpgmeError _gpgme_gpg_set_simple_line_handler ( GpgObject gpg,
GpgColonLineHandler fnc,
void *fnc_value );
GpgmeError _gpgme_gpg_set_command_handler ( GpgObject gpg,
GpgCommandHandler fnc,
void *fnc_value );
GpgmeError _gpgme_gpg_set_command_handler (GpgObject gpg,
GpgCommandHandler 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);
GpgmeError _gpgme_gpg_op_encrypt (GpgObject gpg, GpgmeRecipients recp,
GpgmeData plain, GpgmeData ciph,
int use_armor);

View File

@ -136,7 +136,7 @@ append_xml_siginfo (GpgmeData *rdh, char *args)
}
void
_gpgme_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
_gpgme_sign_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
_gpgme_passphrase_status_handler (ctx, code, args);
@ -146,7 +146,7 @@ _gpgme_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
switch (code)
{
case STATUS_EOF:
case GPGME_STATUS_EOF:
if (ctx->result.sign->okay)
{
append_xml_siginfo (&ctx->result.sign->xmlinfo, NULL);
@ -157,7 +157,7 @@ _gpgme_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
ctx->error = mk_error (No_Data); /* Hmmm: choose a better error? */
break;
case STATUS_SIG_CREATED:
case GPGME_STATUS_SIG_CREATED:
/* FIXME: We have no error return for multiple signatures. */
append_xml_siginfo (&ctx->result.sign->xmlinfo, args);
ctx->result.sign->okay = 1;

View File

@ -52,14 +52,14 @@ trust_item_new (void)
static void
trustlist_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
trustlist_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
if (ctx->error)
return;
switch (code)
{
case STATUS_EOF:
case GPGME_STATUS_EOF:
break;
default:

View File

@ -92,5 +92,9 @@ typedef struct genkey_result_s *GenKeyResult;
struct keylist_result_s;
typedef struct keylist_result_s *KeylistResult;
/*-- edit.c --*/
struct edit_result_s;
typedef struct edit_result_s *EditResult;
#endif /* TYPES_H */

View File

@ -119,7 +119,7 @@ copy_token (const char *string, char *buffer, size_t length)
/* FIXME: Check that we are adding this to the correct signature. */
static void
add_notation (GpgmeCtx ctx, GpgStatusCode code, const char *data)
add_notation (GpgmeCtx ctx, GpgmeStatusCode code, const char *data)
{
GpgmeData dh = ctx->result.verify->notation;
@ -134,7 +134,7 @@ add_notation (GpgmeCtx ctx, GpgStatusCode code, const char *data)
_gpgme_data_append_string (dh, " <notation>\n");
}
if (code == STATUS_NOTATION_DATA)
if (code == GPGME_STATUS_NOTATION_DATA)
{
if (!ctx->result.verify->notation_in_data)
_gpgme_data_append_string (dh, " <data>");
@ -149,13 +149,13 @@ add_notation (GpgmeCtx ctx, GpgStatusCode code, const char *data)
ctx->result.verify->notation_in_data = 0;
}
if (code == STATUS_NOTATION_NAME)
if (code == GPGME_STATUS_NOTATION_NAME)
{
_gpgme_data_append_string (dh, " <name>");
_gpgme_data_append_percentstring_for_xml (dh, data);
_gpgme_data_append_string (dh, "</name>\n");
}
else if (code == STATUS_POLICY_URL)
else if (code == GPGME_STATUS_POLICY_URL)
{
_gpgme_data_append_string (dh, " <policy>");
_gpgme_data_append_percentstring_for_xml (dh, data);
@ -201,7 +201,7 @@ finish_sig (GpgmeCtx ctx, int stop)
void
_gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
_gpgme_verify_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
char *p;
size_t n;
@ -211,11 +211,11 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
return;
test_and_allocate_result (ctx, verify);
if (code == STATUS_GOODSIG
|| code == STATUS_EXPSIG
|| code == STATUS_EXPKEYSIG
|| code == STATUS_BADSIG
|| code == STATUS_ERRSIG)
if (code == GPGME_STATUS_GOODSIG
|| code == GPGME_STATUS_EXPSIG
|| code == GPGME_STATUS_EXPKEYSIG
|| code == GPGME_STATUS_BADSIG
|| code == GPGME_STATUS_ERRSIG)
{
finish_sig (ctx,0);
if (ctx->error)
@ -224,23 +224,23 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
switch (code)
{
case STATUS_NODATA:
case GPGME_STATUS_NODATA:
ctx->result.verify->status = GPGME_SIG_STAT_NOSIG;
break;
case STATUS_GOODSIG:
case GPGME_STATUS_GOODSIG:
ctx->result.verify->expstatus = GPGME_SIG_STAT_GOOD;
break;
case STATUS_EXPSIG:
case GPGME_STATUS_EXPSIG:
ctx->result.verify->expstatus = GPGME_SIG_STAT_GOOD_EXP;
break;
case STATUS_EXPKEYSIG:
case GPGME_STATUS_EXPKEYSIG:
ctx->result.verify->expstatus = GPGME_SIG_STAT_GOOD_EXPKEY;
break;
case STATUS_VALIDSIG:
case GPGME_STATUS_VALIDSIG:
ctx->result.verify->status = GPGME_SIG_STAT_GOOD;
i = copy_token (args, ctx->result.verify->fpr,
DIM(ctx->result.verify->fpr));
@ -255,14 +255,14 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
ctx->result.verify->exptimestamp = strtoul (p, NULL, 10);
break;
case STATUS_BADSIG:
case GPGME_STATUS_BADSIG:
ctx->result.verify->status = GPGME_SIG_STAT_BAD;
/* Store the keyID in the fpr field. */
copy_token (args, ctx->result.verify->fpr,
DIM(ctx->result.verify->fpr));
break;
case STATUS_ERRSIG:
case GPGME_STATUS_ERRSIG:
/* The return code is the 6th argument, if it is 9, the problem
is a missing key. Note that this is not emitted by gpgsm */
for (p = args, i = 0; p && *p && i < 5; i++)
@ -281,38 +281,38 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
DIM(ctx->result.verify->fpr));
break;
case STATUS_NOTATION_NAME:
case STATUS_NOTATION_DATA:
case STATUS_POLICY_URL:
case GPGME_STATUS_NOTATION_NAME:
case GPGME_STATUS_NOTATION_DATA:
case GPGME_STATUS_POLICY_URL:
add_notation (ctx, code, args);
break;
case STATUS_TRUST_UNDEFINED:
case GPGME_STATUS_TRUST_UNDEFINED:
ctx->result.verify->validity = GPGME_VALIDITY_UNKNOWN;
copy_token (args, ctx->result.verify->trust_errtok,
DIM(ctx->result.verify->trust_errtok));
break;
case STATUS_TRUST_NEVER:
case GPGME_STATUS_TRUST_NEVER:
ctx->result.verify->validity = GPGME_VALIDITY_NEVER;
copy_token (args, ctx->result.verify->trust_errtok,
DIM(ctx->result.verify->trust_errtok));
break;
case STATUS_TRUST_MARGINAL:
case GPGME_STATUS_TRUST_MARGINAL:
if (ctx->result.verify->status == GPGME_SIG_STAT_GOOD)
ctx->result.verify->validity = GPGME_VALIDITY_MARGINAL;
copy_token (args, ctx->result.verify->trust_errtok,
DIM(ctx->result.verify->trust_errtok));
break;
case STATUS_TRUST_FULLY:
case STATUS_TRUST_ULTIMATE:
case GPGME_STATUS_TRUST_FULLY:
case GPGME_STATUS_TRUST_ULTIMATE:
if (ctx->result.verify->status == GPGME_SIG_STAT_GOOD)
ctx->result.verify->validity = GPGME_VALIDITY_FULL;
break;
case STATUS_END_STREAM:
case GPGME_STATUS_END_STREAM:
break;
case STATUS_ERROR:
case GPGME_STATUS_ERROR:
/* Generic error, we need this for gpgsm (and maybe for gpg in future)
to get error descriptions. */
if (is_token (args, "verify.findkey", &n) && n)
@ -332,7 +332,7 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
}
break;
case STATUS_EOF:
case GPGME_STATUS_EOF:
finish_sig (ctx,1);
/* FIXME: Put all notation data into one XML fragment. */

View File

@ -985,7 +985,7 @@ _gpgme_io_kill ( int pid, int hard )
* >0 = number of signaled fds
*/
int
_gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
_gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds, int nonblock )
{
HANDLE waitbuf[MAXIMUM_WAIT_OBJECTS];
int waitidx[MAXIMUM_WAIT_OBJECTS];
@ -1056,7 +1056,7 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
if (!any)
return 0;
code = WaitForMultipleObjects ( nwait, waitbuf, 0, 1000);
code = WaitForMultipleObjects ( nwait, waitbuf, 0, nonblock ? 0 : 1000);
if ( code >= WAIT_OBJECT_0 && code < WAIT_OBJECT_0 + nwait ) {
/* This WFMO is a really silly function: It does return either
* the index of the signaled object or if 2 objects have been

View File

@ -152,7 +152,7 @@ do_select (fd_table_t fdt)
int any = 0;
LOCK (fdt->lock);
n = _gpgme_io_select (fdt->fds, fdt->size);
n = _gpgme_io_select (fdt->fds, fdt->size, 0);
if (n <= 0)
{