+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.
@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
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 \
${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
DeleteResult delete;
GenKeyResult genkey;
KeylistResult keylist;
+ EditResult edit;
} result;
/* Last signature notation. */
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)
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);
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);
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;
static void
-delete_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
+delete_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
if (ctx->error)
return;
switch (code)
{
- case STATUS_EOF:
+ case GPGME_STATUS_EOF:
switch (ctx->result.delete->problem)
{
case DELETE_No_Problem:
}
break;
- case STATUS_DELETE_PROBLEM:
+ case GPGME_STATUS_DELETE_PROBLEM:
ctx->result.delete->problem = atoi (args);
break;
--- /dev/null
+/* 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;
+}
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);
}
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;
switch (code)
{
- case STATUS_EOF:
+ case GPGME_STATUS_EOF:
if (ctx->result.encrypt->xmlinfo)
{
append_xml_encinfo (&ctx->result.encrypt->xmlinfo, NULL);
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;
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);
}
}
/* 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,
&& line[0] == 'S' && line[1] == ' ')
{
char *rest;
- GpgStatusCode r;
+ GpgmeStatusCode r;
rest = strchr (line + 2, ' ');
if (!rest)
}
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;
}
}
-static GpgStatusCode
+static GpgmeStatusCode
parse_status (const char *name)
{
struct status_table_s t, *r;
}
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)
&& line[0] == 'S' && line[1] == ' ')
{
char *rest;
- GpgStatusCode r;
+ GpgmeStatusCode r;
rest = strchr (line + 2, ' ');
if (!rest)
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);
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;
}
+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)
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);
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);
static void
-export_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
+export_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
if (ctx->error)
return;
}
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);
switch (code)
{
- case STATUS_KEY_CREATED:
+ case GPGME_STATUS_KEY_CREATED:
if (args && *args)
{
if (*args == 'B' || *args == 'P')
}
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)
_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;
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
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. */
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 */
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]
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;
/* 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;
}
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++)
_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;
switch (code)
{
- case STATUS_EOF:
+ case GPGME_STATUS_EOF:
if (ctx->result.import->xmlinfo)
{
append_xml_impinfo (&ctx->result.import->xmlinfo, code, NULL);
/* 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;
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 */
static void
-keylist_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
+keylist_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
if (ctx->error)
return;
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");
struct status_table_s {
const char *name;
- GpgStatusCode code;
+ GpgmeStatusCode code;
};
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
};
EOF
-
-
-
-
-
-
-
-
-
/*-- 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,
/*-- 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 --*/
/*-- 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);
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;
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);
}
-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;
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;
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;
}
* >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);
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;
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);
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;
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;
*/
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;
+ assert (gpg);
+ if (gpg->pm.active)
+ return 0;
- err = gpgme_data_new_with_read_cb ( &tmp, command_cb, gpg );
- if (err)
- return err;
+ 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;
- return 0;
+ _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;
}
}
/* 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;
* 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;
-
- 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);
+ 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);
+ 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;
+ 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;
+ 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");
-
- _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;
+ 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");
+
+ /* 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
}
}
}
- /* 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;
}
}
+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)
#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);
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);
}
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);
switch (code)
{
- case STATUS_EOF:
+ case GPGME_STATUS_EOF:
if (ctx->result.sign->okay)
{
append_xml_siginfo (&ctx->result.sign->xmlinfo, NULL);
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;
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:
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 */
/* 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;
_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>");
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);
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;
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)
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));
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++)
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)
}
break;
- case STATUS_EOF:
+ case GPGME_STATUS_EOF:
finish_sig (ctx,1);
/* FIXME: Put all notation data into one XML fragment. */
* >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];
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
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)
{