2003-01-30 Marcus Brinkmann <marcus@g10code.de>

* engine-gpgsm.c (status_handler): Do not close status fd at end
	of function.

	* ops.h (_gpgme_op_data_lookup): Add prototype.
	* op-support.c: Include <stdlib.h>.
	(_gpgme_op_data_lookup): New function.
	* decrypt.c (_gpgme_release_decrypt_result): Function removed.
	(struct decrypt_result_s): Rename to ...
	(struct decrypt_resul): ... this.
	(DecryptResult): New type.
	(_gpgme_decrypt_status_handler): Don't use
	test_and_allocate_result, but use _gpgme_op_data_lookup to
	retrieve result data object.
	* sign.c (_gpgme_release_sign_result): Function removed.
	(release_sign_result): New function.
	(struct sign_result_s): Rename to ...
	(struct sign_result): ... this.
	(SignResult): New type.
	(_gpgme_sign_status_handler): Don't use
	test_and_allocate_result, but use _gpgme_op_data_lookup to
	retrieve result data object.
	* encrypt.c (struct encrypt_result_s): Rename to ...
	(struct encrypt_result): ... this.
	(_gpgme_release_encrypt_result): Function removed.
	(release_encrypt_result): New function.
	(_gpgme_encrypt_status_handler): Don't use
	test_and_allocate_result, but use _gpgme_op_data_lookup to
	retrieve result data object.
	* verify.c (struct verify_result_s): Rename to ...
	(struct verify_result): ... this.  Remove member next.
	(VerifyResult): New type.
	(_gpgme_release_verify_result): Function removed.
	(release_verify_result): New function.
	(finish_sig): Change first argument to type VerifyResult.  Diddle
	the type of the op_data structure.
	(add_notation): Change first argument to type VerifyResult.
	(_gpgme_verify_status_handler): Don't use
	test_and_allocate_result, but use _gpgme_op_data_lookup to
	retrieve result data object.
	* passphrase.c (struct passphrase_result_s): Rename to ...
	(struct passphrase_result): ... this.  Remove member next.
	(PassphraseResult): New type.
	(_gpgme_release_passphrase_result): Function removed.
	(release_passphrase_result): New function.
	(_gpgme_passphrase_status_handler): Don't use
	test_and_allocate_result, but use _gpgme_op_data_lookup to
	retrieve result data object.
	(_gpgme_passphrase_command_handler): Likewise.
	* keylist.c (struct keylist_result_s): Rename to ...
	(struct keylist_result): ... this.  Remove member next.
	(KeylistResult): New type.
	(_gpgme_release_keylist_result): Function removed.
	(release_keylist_result): New function.
	(keylist_status_handler): Don't use
	test_and_allocate_result, but use _gpgme_op_data_lookup to
	retrieve result data object.
	* edit.c (struct edit_result_s): Rename to ...
	(struct edit_result): ... this.  Remove member next.
	(EditResult): New type.
	(_gpgme_release_edit_result): Function removed.
	(release_edit_result): New function.
	(edit_status_handler): Don't use
	test_and_allocate_result, but use _gpgme_op_data_lookup to
	retrieve result data object.
	(command_handler): Likewise.
	* types.h (DecryptResult, SignResult, EncryptResult,
	PassphraseResult, ImportResult, DeleteResult, GenKeyResult,
	KeylistResult, EditResult): Types removed.
	* ops.h: Don't include "types.h", but "gpgme.h" and "context.h".
	(test_and_allocate_result): Remove macro.
	(_gpgme_release_decrypt_result): Remove prototype.
	(_gpgme_decrypt_result): Remove prototype.
	(_gpgme_release_sign_result): Remove prototype.
	(_gpgme_release_encrypt_result): Remove prototype.
	(_gpgme_release_passphrase_result): Remove prototype.
	(_gpgme_release_import_result): Remove prototype.
	(_gpgme_release_delete_result): Remove prototype.
	(_gpgme_release_genkey_result): Remove prototype.
	(_gpgme_release_keylist_result): Remove prototype.
	(_gpgme_release_edit_result): Remove prototype.
	(_gpgme_release_verify_result): Remove prototype.
	* gpgme.c (_gpgme_release_result): Rewritten.
	* context.h (enum ctx_op_data_type): New enum.
	(struct ctx_op_data): New structure.
	(struct gpgme_context_s): Replace the member result with a member
	op_data.
	(fail_on_pending_request): Remove macro.
	* op-support.c (_gpgme_op_reset): Expand macro
	fail_on_pending_request.
	* util.h: Don't include "types.h" or "debug.h", but include "gpgme.h".
This commit is contained in:
Marcus Brinkmann 2003-01-30 22:40:05 +00:00
parent e0229fe1d6
commit 7618b28f1d
22 changed files with 604 additions and 444 deletions

View File

@ -1,3 +1,96 @@
2003-01-30 Marcus Brinkmann <marcus@g10code.de>
* engine-gpgsm.c (status_handler): Do not close status fd at end
of function.
* ops.h (_gpgme_op_data_lookup): Add prototype.
* op-support.c: Include <stdlib.h>.
(_gpgme_op_data_lookup): New function.
* decrypt.c (_gpgme_release_decrypt_result): Function removed.
(struct decrypt_result_s): Rename to ...
(struct decrypt_resul): ... this.
(DecryptResult): New type.
(_gpgme_decrypt_status_handler): Don't use
test_and_allocate_result, but use _gpgme_op_data_lookup to
retrieve result data object.
* sign.c (_gpgme_release_sign_result): Function removed.
(release_sign_result): New function.
(struct sign_result_s): Rename to ...
(struct sign_result): ... this.
(SignResult): New type.
(_gpgme_sign_status_handler): Don't use
test_and_allocate_result, but use _gpgme_op_data_lookup to
retrieve result data object.
* encrypt.c (struct encrypt_result_s): Rename to ...
(struct encrypt_result): ... this.
(_gpgme_release_encrypt_result): Function removed.
(release_encrypt_result): New function.
(_gpgme_encrypt_status_handler): Don't use
test_and_allocate_result, but use _gpgme_op_data_lookup to
retrieve result data object.
* verify.c (struct verify_result_s): Rename to ...
(struct verify_result): ... this. Remove member next.
(VerifyResult): New type.
(_gpgme_release_verify_result): Function removed.
(release_verify_result): New function.
(finish_sig): Change first argument to type VerifyResult. Diddle
the type of the op_data structure.
(add_notation): Change first argument to type VerifyResult.
(_gpgme_verify_status_handler): Don't use
test_and_allocate_result, but use _gpgme_op_data_lookup to
retrieve result data object.
* passphrase.c (struct passphrase_result_s): Rename to ...
(struct passphrase_result): ... this. Remove member next.
(PassphraseResult): New type.
(_gpgme_release_passphrase_result): Function removed.
(release_passphrase_result): New function.
(_gpgme_passphrase_status_handler): Don't use
test_and_allocate_result, but use _gpgme_op_data_lookup to
retrieve result data object.
(_gpgme_passphrase_command_handler): Likewise.
* keylist.c (struct keylist_result_s): Rename to ...
(struct keylist_result): ... this. Remove member next.
(KeylistResult): New type.
(_gpgme_release_keylist_result): Function removed.
(release_keylist_result): New function.
(keylist_status_handler): Don't use
test_and_allocate_result, but use _gpgme_op_data_lookup to
retrieve result data object.
* edit.c (struct edit_result_s): Rename to ...
(struct edit_result): ... this. Remove member next.
(EditResult): New type.
(_gpgme_release_edit_result): Function removed.
(release_edit_result): New function.
(edit_status_handler): Don't use
test_and_allocate_result, but use _gpgme_op_data_lookup to
retrieve result data object.
(command_handler): Likewise.
* types.h (DecryptResult, SignResult, EncryptResult,
PassphraseResult, ImportResult, DeleteResult, GenKeyResult,
KeylistResult, EditResult): Types removed.
* ops.h: Don't include "types.h", but "gpgme.h" and "context.h".
(test_and_allocate_result): Remove macro.
(_gpgme_release_decrypt_result): Remove prototype.
(_gpgme_decrypt_result): Remove prototype.
(_gpgme_release_sign_result): Remove prototype.
(_gpgme_release_encrypt_result): Remove prototype.
(_gpgme_release_passphrase_result): Remove prototype.
(_gpgme_release_import_result): Remove prototype.
(_gpgme_release_delete_result): Remove prototype.
(_gpgme_release_genkey_result): Remove prototype.
(_gpgme_release_keylist_result): Remove prototype.
(_gpgme_release_edit_result): Remove prototype.
(_gpgme_release_verify_result): Remove prototype.
* gpgme.c (_gpgme_release_result): Rewritten.
* context.h (enum ctx_op_data_type): New enum.
(struct ctx_op_data): New structure.
(struct gpgme_context_s): Replace the member result with a member
op_data.
(fail_on_pending_request): Remove macro.
* op-support.c (_gpgme_op_reset): Expand macro
fail_on_pending_request.
* util.h: Don't include "types.h" or "debug.h", but include "gpgme.h".
2003-01-30 Marcus Brinkmann <marcus@g10code.de>
* types.h (EngineObject): Move typedef to ...

View File

@ -26,12 +26,44 @@
#include "engine.h"
#include "wait.h"
/* Operations might require to remember arbitrary information and data
objects during invocations of the status handler. The
ctx_op_data structure provides a generic framework to hook in
such additional data. */
typedef enum
{
OPDATA_DECRYPT, OPDATA_SIGN, OPDATA_ENCRYPT, OPDATA_PASSPHRASE,
OPDATA_IMPORT, OPDATA_GENKEY, OPDATA_KEYLIST, OPDATA_EDIT,
OPDATA_VERIFY_COLLECTING, OPDATA_VERIFY
} ctx_op_data_type;
struct ctx_op_data
{
/* The next element in the linked list, or NULL if this is the last
element. */
struct ctx_op_data *next;
/* The type of the hook data, which can be used by a routine to
lookup the hook data. */
ctx_op_data_type type;
/* The function to release HOOK and all its associated resources.
Can be NULL if no special dealllocation routine is necessary. */
void (*cleanup) (void *hook);
/* The hook that points to the operation data. */
void *hook;
};
struct key_queue_item_s
{
struct key_queue_item_s *next;
GpgmeKey key;
};
struct trust_queue_item_s
{
struct trust_queue_item_s *next;
@ -68,19 +100,8 @@ struct gpgme_context_s
int signers_size;
GpgmeKey *signers;
struct
{
VerifyResult verify;
DecryptResult decrypt;
SignResult sign;
EncryptResult encrypt;
PassphraseResult passphrase;
ImportResult import;
DeleteResult delete;
GenKeyResult genkey;
KeylistResult keylist;
EditResult edit;
} result;
/* The operation data hooked into the context. */
struct ctx_op_data *op_data;
/* Last signature notation. */
GpgmeData notation;
@ -132,14 +153,8 @@ struct user_id_s
struct gpgme_recipients_s
{
struct user_id_s *list;
int checked; /* Wether the recipients are all valid. */
int checked; /* Whether the recipients are all valid. */
};
#define fail_on_pending_request(c) \
do { \
if (!(c)) return GPGME_Invalid_Value; \
if ((c)->pending) return GPGME_Busy; \
} while (0)
#endif /* CONTEXT_H */

View File

@ -23,26 +23,18 @@
#endif
#include <stdlib.h>
#include "util.h"
#include "context.h"
#include "ops.h"
struct decrypt_result_s
struct decrypt_result
{
int okay;
int failed;
};
typedef struct decrypt_result *DecryptResult;
void
_gpgme_release_decrypt_result (DecryptResult result)
{
if (!result)
return;
free (result);
}
/* Check whether STRING starts with TOKEN and return true in this
case. This is case insensitive. If NEXT is not NULL return the
number of bytes to be added to STRING to get to the next token; a
@ -87,30 +79,40 @@ skip_token (const char *string, size_t *next)
GpgmeError
_gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
GpgmeError err;
DecryptResult result;
GpgmeError err = 0;
size_t n;
err = _gpgme_passphrase_status_handler (ctx, code, args);
if (err)
return err;
test_and_allocate_result (ctx, decrypt);
switch (code)
{
case GPGME_STATUS_EOF:
if (ctx->result.decrypt->failed)
return GPGME_Decryption_Failed;
else if (!ctx->result.decrypt->okay)
return GPGME_No_Data;
err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, (void **) &result,
-1, NULL);
if (!err)
{
if (result && result->failed)
err = GPGME_Decryption_Failed;
else if (!result || !result->okay)
err = GPGME_No_Data;
}
break;
case GPGME_STATUS_DECRYPTION_OKAY:
ctx->result.decrypt->okay = 1;
err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, (void **) &result,
sizeof (*result), NULL);
if (!err)
result->okay = 1;
break;
case GPGME_STATUS_DECRYPTION_FAILED:
ctx->result.decrypt->failed = 1;
err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, (void **) &result,
sizeof (*result), NULL);
if (!err)
result->failed = 1;
break;
case GPGME_STATUS_ERROR:
@ -155,7 +157,7 @@ _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
break;
}
return 0;
return err;
}

View File

@ -37,53 +37,28 @@ enum delete_problem
};
struct delete_result_s
{
enum delete_problem problem;
};
void
_gpgme_release_delete_result (DeleteResult result)
{
if (!result)
return;
free (result);
}
static GpgmeError
delete_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
test_and_allocate_result (ctx, delete);
switch (code)
if (code == GPGME_STATUS_DELETE_PROBLEM)
{
case GPGME_STATUS_EOF:
switch (ctx->result.delete->problem)
enum delete_problem problem = atoi (args);
switch (problem)
{
case DELETE_No_Problem:
break;
case DELETE_No_Such_Key:
return GPGME_Invalid_Key;
break;
case DELETE_Must_Delete_Secret_Key:
return GPGME_Conflict;
break;
case DELETE_Ambiguous_Specification:
/* XXX Need better error value. Fall through. */
default:
return GPGME_General_Error;
break;
}
break;
case GPGME_STATUS_DELETE_PROBLEM:
ctx->result.delete->problem = atoi (args);
break;
default:
break;
}
return 0;
}

View File

@ -28,47 +28,52 @@
#include "ops.h"
struct edit_result_s
struct edit_result
{
GpgmeEditCb fnc;
void *fnc_value;
};
void
_gpgme_release_edit_result (EditResult result)
{
if (!result)
return;
free (result);
}
typedef struct edit_result *EditResult;
static GpgmeError
edit_status_handler (GpgmeCtx ctx, GpgmeStatusCode status, char *args)
{
EditResult result;
GpgmeError err = _gpgme_passphrase_status_handler (ctx, status, args);
if (err)
return err;
return (*ctx->result.edit->fnc) (ctx->result.edit->fnc_value, status,
args, NULL);
err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, (void **) &result,
-1, NULL);
if (err)
return err;
assert (result);
return (*result->fnc) (result->fnc_value, status, args, NULL);
}
static GpgmeError
command_handler (void *opaque, GpgmeStatusCode status, const char *args,
const char **result)
const char **result_r)
{
EditResult result;
GpgmeError err;
GpgmeCtx ctx = opaque;
err = _gpgme_passphrase_command_handler (ctx, status, args, result);
*result_r = NULL;
err = _gpgme_passphrase_command_handler (ctx, status, args, result_r);
if (err)
return err;
if (!result)
err = (*ctx->result.edit->fnc) (ctx->result.edit->fnc_value, status,
args, result);
err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, (void **) &result,
-1, NULL);
if (err)
return err;
assert (result);
if (!*result_r)
err = (*result->fnc) (result->fnc_value, status, args, result_r);
return err;
}
@ -80,6 +85,7 @@ _gpgme_op_edit_start (GpgmeCtx ctx, int synchronous,
GpgmeEditCb fnc, void *fnc_value,
GpgmeData out)
{
EditResult result;
GpgmeError err = 0;
if (!fnc)
@ -89,15 +95,13 @@ _gpgme_op_edit_start (GpgmeCtx ctx, int synchronous,
if (err)
goto leave;
assert (!ctx->result.edit);
ctx->result.edit = malloc (sizeof *ctx->result.edit);
if (!ctx->result.edit)
{
err = GPGME_Out_Of_Core;
err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, (void **) &result,
sizeof (*result), NULL);
if (err)
goto leave;
}
ctx->result.edit->fnc = fnc;
ctx->result.edit->fnc_value = fnc_value;
result->fnc = fnc;
result->fnc_value = fnc_value;
/* Check the supplied data. */
if (!out)

View File

@ -38,22 +38,23 @@
return; /* oops */ \
} while (0)
struct encrypt_result_s
struct encrypt_result
{
int no_valid_recipients;
int invalid_recipients;
GpgmeData xmlinfo;
};
typedef struct encrypt_result *EncryptResult;
void
_gpgme_release_encrypt_result (EncryptResult result)
static void
release_encrypt_result (void *hook)
{
if (!result)
return;
EncryptResult result = (EncryptResult) hook;
gpgme_data_release (result->xmlinfo);
free (result);
}
/* Parse the args and save the information in an XML structure. With
args of NULL the xml structure is closed. */
static void
@ -100,36 +101,50 @@ append_xml_encinfo (GpgmeData *rdh, char *args)
GpgmeError
_gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
test_and_allocate_result (ctx, encrypt);
GpgmeError err = 0;
EncryptResult result;
switch (code)
{
case GPGME_STATUS_EOF:
if (ctx->result.encrypt->xmlinfo)
err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, (void **) &result,
-1, NULL);
if (!err)
{
append_xml_encinfo (&ctx->result.encrypt->xmlinfo, NULL);
_gpgme_set_op_info (ctx, ctx->result.encrypt->xmlinfo);
ctx->result.encrypt->xmlinfo = NULL;
if (result && result->xmlinfo)
{
append_xml_encinfo (&result->xmlinfo, NULL);
_gpgme_set_op_info (ctx, result->xmlinfo);
result->xmlinfo = NULL;
}
if (ctx->result.encrypt->no_valid_recipients)
if (result && result->no_valid_recipients)
return GPGME_No_Recipients;
else if (ctx->result.encrypt->invalid_recipients)
if (result && result->invalid_recipients)
return GPGME_Invalid_Recipients;
}
break;
case GPGME_STATUS_INV_RECP:
ctx->result.encrypt->invalid_recipients++;
append_xml_encinfo (&ctx->result.encrypt->xmlinfo, args);
err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, (void **) &result,
sizeof (*result), release_encrypt_result);
if (!err)
{
result->invalid_recipients++;
append_xml_encinfo (&result->xmlinfo, args);
}
break;
case GPGME_STATUS_NO_RECP:
ctx->result.encrypt->no_valid_recipients = 1;
err = _gpgme_op_data_lookup (ctx, OPDATA_ENCRYPT, (void **) &result,
sizeof (*result), release_encrypt_result);
if (!err)
result->no_valid_recipients = 1;
break;
default:
break;
}
return 0;
return err;
}

View File

@ -806,7 +806,6 @@ status_handler (void *opaque, int fd)
}
while (!err && assuan_pending_line (gpgsm->assuan_ctx));
_gpgme_io_close (gpgsm->status_cb.fd);
return err;
}

View File

@ -26,7 +26,7 @@
#include "util.h"
#include "context.h"
#include "ops.h"
#include "debug.h"
static GpgmeError
export_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)

View File

@ -29,33 +29,36 @@
#include "ops.h"
struct genkey_result_s
struct genkey_result
{
int created_primary : 1;
int created_sub : 1;
char *fpr;
};
typedef struct genkey_result *GenKeyResult;
void
_gpgme_release_genkey_result (GenKeyResult result)
static void
release_genkey_result (void *hook)
{
if (!result)
return;
GenKeyResult result = (GenKeyResult) hook;
if (result->fpr)
free (result->fpr);
free (result);
}
static GpgmeError
genkey_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
GenKeyResult result;
GpgmeError err = _gpgme_progress_status_handler (ctx, code, args);
if (err)
return err;
test_and_allocate_result (ctx, genkey);
err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, (void **) &result,
sizeof (*result), release_genkey_result);
if (err)
return err;
switch (code)
{
@ -63,15 +66,15 @@ genkey_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
if (args && *args)
{
if (*args == 'B' || *args == 'P')
ctx->result.genkey->created_primary = 1;
result->created_primary = 1;
if (*args == 'B' || *args == 'S')
ctx->result.genkey->created_sub = 1;
result->created_sub = 1;
if (args[1] == ' ')
{
if (ctx->result.genkey->fpr)
free (ctx->result.genkey->fpr);
ctx->result.genkey->fpr = strdup (&args[2]);
if (!ctx->result.genkey->fpr)
if (result->fpr)
free (result->fpr);
result->fpr = strdup (&args[2]);
if (!result->fpr)
return GPGME_Out_Of_Core;
}
}
@ -79,8 +82,8 @@ genkey_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
case GPGME_STATUS_EOF:
/* FIXME: Should return some more useful error value. */
if (!ctx->result.genkey->created_primary
&& !ctx->result.genkey->created_sub)
if (!result->created_primary
&& !result->created_sub)
return GPGME_General_Error;
break;
@ -212,9 +215,16 @@ gpgme_op_genkey (GpgmeCtx ctx, const char *parms,
err = _gpgme_wait_one (ctx);
if (!err && fpr)
{
if (ctx->result.genkey->fpr)
GenKeyResult result;
err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, (void **) &result,
-1, NULL);
if (err)
return err;
if (result && result->fpr)
{
*fpr = strdup (ctx->result.genkey->fpr);
*fpr = strdup (result->fpr);
if (!*fpr)
return GPGME_Out_Of_Core;
}

View File

@ -87,17 +87,17 @@ gpgme_release (GpgmeCtx ctx)
void
_gpgme_release_result (GpgmeCtx ctx)
{
_gpgme_release_verify_result (ctx->result.verify);
_gpgme_release_decrypt_result (ctx->result.decrypt);
_gpgme_release_sign_result (ctx->result.sign);
_gpgme_release_encrypt_result (ctx->result.encrypt);
_gpgme_release_passphrase_result (ctx->result.passphrase);
_gpgme_release_import_result (ctx->result.import);
_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));
struct ctx_op_data *data = ctx->op_data;
while (data)
{
struct ctx_op_data *next_data = data->next;
if (data->cleanup)
(*data->cleanup) (data->hook);
free (data);
data = next_data;
}
ctx->op_data = NULL;
_gpgme_set_op_info (ctx, NULL);
}

View File

@ -28,22 +28,22 @@
#include "context.h"
#include "ops.h"
struct import_result_s
struct import_result
{
int nr_imported;
int nr_considered;
GpgmeData xmlinfo;
};
typedef struct import_result *ImportResult;
void
_gpgme_release_import_result (ImportResult result)
static void
release_import_result (void *hook)
{
if (!result)
return;
ImportResult result = (ImportResult) hook;
if (result->xmlinfo)
gpgme_data_release (result->xmlinfo);
free (result);
}
@ -143,28 +143,34 @@ append_xml_impinfo (GpgmeData *rdh, GpgmeStatusCode code, char *args)
static GpgmeError
import_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
test_and_allocate_result (ctx, import);
GpgmeError err;
ImportResult result;
err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, (void **) &result,
sizeof (*result), release_import_result);
if (err)
return err;
switch (code)
{
case GPGME_STATUS_EOF:
if (ctx->result.import->xmlinfo)
if (result->xmlinfo)
{
append_xml_impinfo (&ctx->result.import->xmlinfo, code, NULL);
_gpgme_set_op_info (ctx, ctx->result.import->xmlinfo);
ctx->result.import->xmlinfo = NULL;
append_xml_impinfo (&result->xmlinfo, code, NULL);
_gpgme_set_op_info (ctx, result->xmlinfo);
result->xmlinfo = NULL;
}
/* XXX Calculate error value. */
break;
case GPGME_STATUS_IMPORTED:
ctx->result.import->nr_imported++;
append_xml_impinfo (&ctx->result.import->xmlinfo, code, args);
result->nr_imported++;
append_xml_impinfo (&result->xmlinfo, code, args);
break;
case GPGME_STATUS_IMPORT_RES:
ctx->result.import->nr_considered = strtol (args, 0, 0);
append_xml_impinfo (&ctx->result.import->xmlinfo, code, args);
result->nr_considered = strtol (args, 0, 0);
append_xml_impinfo (&result->xmlinfo, code, args);
break;
default:
@ -230,8 +236,12 @@ gpgme_op_import_ext (GpgmeCtx ctx, GpgmeData keydata, int *nr)
err = _gpgme_wait_one (ctx);
if (!err && nr)
{
if (ctx->result.import)
*nr = ctx->result.import->nr_considered;
ImportResult result;
err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, (void **) &result,
-1, NULL);
if (result)
*nr = result->nr_considered;
else
*nr = 0;
}
@ -243,4 +253,3 @@ gpgme_op_import (GpgmeCtx ctx, GpgmeData keydata)
{
return gpgme_op_import_ext (ctx, keydata, 0);
}

View File

@ -32,21 +32,23 @@
#include "context.h"
#include "ops.h"
#include "key.h"
#include "debug.h"
struct keylist_result_s
struct keylist_result
{
int truncated;
GpgmeData xmlinfo;
};
typedef struct keylist_result *KeylistResult;
void
_gpgme_release_keylist_result (KeylistResult result)
static void
release_keylist_result (void *hook)
{
if (!result)
return;
free (result);
KeylistResult result = (KeylistResult) hook;
if (result->xmlinfo)
gpgme_data_release (result->xmlinfo);
}
@ -86,22 +88,28 @@ append_xml_keylistinfo (GpgmeData *rdh, char *args)
static GpgmeError
keylist_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
test_and_allocate_result (ctx, keylist);
GpgmeError err;
KeylistResult result;
err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, (void **) &result,
sizeof (*result), release_keylist_result);
if (err)
return err;
switch (code)
{
case GPGME_STATUS_TRUNCATED:
ctx->result.keylist->truncated = 1;
result->truncated = 1;
break;
case GPGME_STATUS_EOF:
if (ctx->result.keylist->truncated)
append_xml_keylistinfo (&ctx->result.keylist->xmlinfo, "1");
if (ctx->result.keylist->xmlinfo)
if (result->truncated)
append_xml_keylistinfo (&result->xmlinfo, "1");
if (result->xmlinfo)
{
append_xml_keylistinfo (&ctx->result.keylist->xmlinfo, NULL);
_gpgme_set_op_info (ctx, ctx->result.keylist->xmlinfo);
ctx->result.keylist->xmlinfo = NULL;
append_xml_keylistinfo (&result->xmlinfo, NULL);
_gpgme_set_op_info (ctx, result->xmlinfo);
result->xmlinfo = NULL;
}
break;

View File

@ -20,11 +20,42 @@
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include "gpgme.h"
#include "context.h"
#include "ops.h"
GpgmeError
_gpgme_op_data_lookup (GpgmeCtx ctx, ctx_op_data_type type, void **hook,
int size, void (*cleanup) (void *))
{
struct ctx_op_data *data = ctx->op_data;
while (data && data->type != type)
data = data->next;
if (!data)
{
if (size < 0)
{
*hook = NULL;
return 0;
}
data = calloc (1, sizeof (struct ctx_op_data) + size);
if (!data)
return GPGME_Out_Of_Core;
data->next = ctx->op_data;
data->type = type;
data->cleanup = cleanup;
data->hook = ((void *) data) + sizeof (struct ctx_op_data);
ctx->op_data = data;
}
*hook = data->hook;
return 0;
}
/* type is: 0: asynchronous operation (use global or user event loop).
1: synchronous operation (always use private event loop).
2: asynchronous private operation (use private or user
@ -35,7 +66,9 @@ _gpgme_op_reset (GpgmeCtx ctx, int type)
GpgmeError err = 0;
struct GpgmeIOCbs io_cbs;
fail_on_pending_request (ctx);
if (ctx->pending)
return GPGME_Busy;
_gpgme_release_result (ctx);
/* Create an engine object. */

View File

@ -21,21 +21,8 @@
#ifndef OPS_H
#define OPS_H
#include "types.h"
/* Support macros. */
#define test_and_allocate_result(ctx,field) \
do \
{ \
if (!ctx->result.field) \
{ \
ctx->result.field = calloc (1, sizeof *ctx->result.field); \
if (!ctx->result.field) \
return GPGME_Out_Of_Core; \
} \
} \
while (0)
#include "gpgme.h"
#include "context.h"
/*-- gpgme.c --*/
void _gpgme_release_result (GpgmeCtx ctx);
@ -77,34 +64,31 @@ GpgmeError _gpgme_key_new ( GpgmeKey *r_key );
GpgmeError _gpgme_key_new_secret ( GpgmeKey *r_key );
/*-- op-support.c --*/
GpgmeError _gpgme_op_data_lookup (GpgmeCtx ctx, ctx_op_data_type type,
void **hook, int size,
void (*cleanup) (void *));
GpgmeError _gpgme_op_reset (GpgmeCtx ctx, int synchronous);
/*-- verify.c --*/
void _gpgme_release_verify_result (VerifyResult result);
GpgmeError _gpgme_verify_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args);
/*-- decrypt.c --*/
void _gpgme_release_decrypt_result (DecryptResult result);
GpgmeError _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args);
GpgmeError _gpgme_decrypt_start (GpgmeCtx ctx, int synchronous,
GpgmeData ciph, GpgmeData plain,
void *status_handler);
GpgmeError _gpgme_decrypt_result (GpgmeCtx ctx);
/*-- sign.c --*/
void _gpgme_release_sign_result ( SignResult res );
GpgmeError _gpgme_sign_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args);
/*-- encrypt.c --*/
void _gpgme_release_encrypt_result ( EncryptResult res );
GpgmeError _gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args);
/*-- passphrase.c --*/
void _gpgme_release_passphrase_result (PassphraseResult result);
GpgmeError _gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args);
GpgmeError _gpgme_passphrase_command_handler (void *opaque,
@ -116,25 +100,12 @@ GpgmeError _gpgme_passphrase_start (GpgmeCtx ctx);
GpgmeError _gpgme_progress_status_handler (GpgmeCtx ctx, GpgmeStatusCode code,
char *args);
/*-- import.c --*/
void _gpgme_release_import_result (ImportResult res);
/*-- delete.c --*/
void _gpgme_release_delete_result (DeleteResult res);
/*-- genkey.c --*/
void _gpgme_release_genkey_result (GenKeyResult res);
/*-- keylist.c --*/
void _gpgme_release_keylist_result (KeylistResult res);
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

@ -29,9 +29,10 @@
#include "util.h"
#include "context.h"
#include "ops.h"
#include "debug.h"
struct passphrase_result_s
struct passphrase_result
{
int no_passphrase;
void *last_pw_handle;
@ -39,58 +40,63 @@ struct passphrase_result_s
char *passphrase_info;
int bad_passphrase;
};
typedef struct passphrase_result *PassphraseResult;
void
_gpgme_release_passphrase_result (PassphraseResult result)
static void
release_passphrase_result (void *hook)
{
if (!result)
return;
PassphraseResult result = (PassphraseResult) hook;
free (result->passphrase_info);
free (result->userid_hint);
free (result);
}
GpgmeError
_gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
test_and_allocate_result (ctx, passphrase);
GpgmeError err;
PassphraseResult result;
err = _gpgme_op_data_lookup (ctx, OPDATA_PASSPHRASE, (void **) &result,
sizeof (*result), release_passphrase_result);
if (err)
return err;
switch (code)
{
case GPGME_STATUS_USERID_HINT:
free (ctx->result.passphrase->userid_hint);
if (!(ctx->result.passphrase->userid_hint = strdup (args)))
free (result->userid_hint);
if (!(result->userid_hint = strdup (args)))
return GPGME_Out_Of_Core;
break;
case GPGME_STATUS_BAD_PASSPHRASE:
ctx->result.passphrase->bad_passphrase++;
ctx->result.passphrase->no_passphrase = 0;
result->bad_passphrase++;
result->no_passphrase = 0;
break;
case GPGME_STATUS_GOOD_PASSPHRASE:
ctx->result.passphrase->bad_passphrase = 0;
ctx->result.passphrase->no_passphrase = 0;
result->bad_passphrase = 0;
result->no_passphrase = 0;
break;
case GPGME_STATUS_NEED_PASSPHRASE:
case GPGME_STATUS_NEED_PASSPHRASE_SYM:
free (ctx->result.passphrase->passphrase_info);
ctx->result.passphrase->passphrase_info = strdup (args);
if (!ctx->result.passphrase->passphrase_info)
free (result->passphrase_info);
result->passphrase_info = strdup (args);
if (!result->passphrase_info)
return GPGME_Out_Of_Core;
break;
case GPGME_STATUS_MISSING_PASSPHRASE:
DEBUG0 ("missing passphrase - stop\n");;
ctx->result.passphrase->no_passphrase = 1;
result->no_passphrase = 1;
break;
case GPGME_STATUS_EOF:
if (ctx->result.passphrase->no_passphrase
|| ctx->result.passphrase->bad_passphrase)
if (result->no_passphrase
|| result->bad_passphrase)
return GPGME_No_Passphrase;
break;
@ -104,16 +110,16 @@ _gpgme_passphrase_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args
GpgmeError
_gpgme_passphrase_command_handler (void *opaque, GpgmeStatusCode code,
const char *key, const char **result)
const char *key, const char **result_r)
{
GpgmeCtx ctx = opaque;
GpgmeError err;
PassphraseResult result;
if (!ctx->result.passphrase)
{
ctx->result.passphrase = calloc (1, sizeof *ctx->result.passphrase);
if (!ctx->result.passphrase)
return GPGME_Out_Of_Core;
}
err = _gpgme_op_data_lookup (ctx, OPDATA_PASSPHRASE, (void **) &result,
sizeof (*result), release_passphrase_result);
if (err)
return err;
if (!code)
{
@ -122,26 +128,26 @@ _gpgme_passphrase_command_handler (void *opaque, GpgmeStatusCode code,
{
/* Fixme: Take the key in account. */
ctx->passphrase_cb (ctx->passphrase_cb_value, NULL,
&ctx->result.passphrase->last_pw_handle);
&result->last_pw_handle);
}
*result = NULL;
*result_r = NULL;
return 0;
}
if (!key || !ctx->passphrase_cb)
{
*result = NULL;
*result_r = NULL;
return 0;
}
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;
int bad_passphrase = ctx->result.passphrase->bad_passphrase;
const char *userid_hint = result->userid_hint;
const char *passphrase_info = result->passphrase_info;
int bad_passphrase = result->bad_passphrase;
char *buf;
ctx->result.passphrase->bad_passphrase = 0;
result->bad_passphrase = 0;
if (!userid_hint)
userid_hint = "[User ID hint missing]";
if (!passphrase_info)
@ -154,13 +160,13 @@ _gpgme_passphrase_command_handler (void *opaque, GpgmeStatusCode code,
bad_passphrase ? "TRY_AGAIN":"ENTER",
userid_hint, passphrase_info);
*result = ctx->passphrase_cb (ctx->passphrase_cb_value, buf,
&ctx->result.passphrase->last_pw_handle);
*result_r = ctx->passphrase_cb (ctx->passphrase_cb_value, buf,
&result->last_pw_handle);
free (buf);
return 0;
}
*result = NULL;
*result_r = NULL;
return 0;
}

View File

@ -37,6 +37,7 @@
#include "io.h"
#include "sema.h"
#include "ath.h"
#include "debug.h"
static struct
{

View File

@ -40,6 +40,7 @@
#include "context.h" /*temp hack until we have GpmeData methods to do I/O */
#include "io.h"
#include "sema.h"
#include "debug.h"
#include "status-table.h"
#include "engine-backend.h"

View File

@ -37,19 +37,20 @@
return; /* oops */ \
} while (0)
struct sign_result_s
struct sign_result
{
int okay;
GpgmeData xmlinfo;
};
typedef struct sign_result *SignResult;
void
_gpgme_release_sign_result (SignResult result)
static void
release_sign_result (void *hook)
{
if (!result)
return;
SignResult result = (SignResult) hook;
gpgme_data_release (result->xmlinfo);
free (result);
}
/* Parse the args and save the information
@ -139,35 +140,44 @@ append_xml_siginfo (GpgmeData *rdh, char *args)
GpgmeError
_gpgme_sign_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
GpgmeError err = _gpgme_passphrase_status_handler (ctx, code, args);
SignResult result;
GpgmeError err;
err = _gpgme_passphrase_status_handler (ctx, code, args);
if (err)
return err;
test_and_allocate_result (ctx, sign);
switch (code)
{
case GPGME_STATUS_EOF:
if (ctx->result.sign->okay)
err = _gpgme_op_data_lookup (ctx, OPDATA_SIGN, (void **) &result,
-1, NULL);
if (!err)
{
append_xml_siginfo (&ctx->result.sign->xmlinfo, NULL);
_gpgme_set_op_info (ctx, ctx->result.sign->xmlinfo);
ctx->result.sign->xmlinfo = NULL;
if (result && result->okay)
{
append_xml_siginfo (&result->xmlinfo, NULL);
_gpgme_set_op_info (ctx, result->xmlinfo);
result->xmlinfo = NULL;
}
else if (!result || !result->okay)
/* FIXME: choose a better error code? */
err = GPGME_No_Data;
}
if (!ctx->result.sign->okay)
return GPGME_No_Data; /* Hmmm: choose a better error? */
break;
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;
err = _gpgme_op_data_lookup (ctx, OPDATA_SIGN, (void **) &result,
sizeof (*result), release_sign_result);
append_xml_siginfo (&result->xmlinfo, args);
result->okay = 1;
break;
default:
break;
}
return 0;
return err;
}
static GpgmeError

View File

@ -32,44 +32,4 @@ typedef GpgmeError (*GpgmeCommandHandler) (void*, GpgmeStatusCode code,
const char *keyword, const char **result);
/*-- verify.c --*/
struct verify_result_s;
typedef struct verify_result_s *VerifyResult;
/*-- decrypt.c --*/
struct decrypt_result_s;
typedef struct decrypt_result_s *DecryptResult;
/*-- sign.c --*/
struct sign_result_s;
typedef struct sign_result_s *SignResult;
/*-- encrypt.c --*/
struct encrypt_result_s;
typedef struct encrypt_result_s *EncryptResult;
/*-- passphrase.c --*/
struct passphrase_result_s;
typedef struct passphrase_result_s *PassphraseResult;
/*-- import.c --*/
struct import_result_s;
typedef struct import_result_s *ImportResult;
/*-- delete.c --*/
struct delete_result_s;
typedef struct delete_result_s *DeleteResult;
/*-- genkey.c --*/
struct genkey_result_s;
typedef struct genkey_result_s *GenKeyResult;
/*-- keylist.c --*/
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

@ -21,17 +21,18 @@
#ifndef UTIL_H
#define UTIL_H
#include "types.h"
#include "debug.h"
#include "gpgme.h"
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
#define DIMof(type,member) DIM(((type *)0)->member)
/*-- {posix,w32}-util.c --*/
const char *_gpgme_get_gpg_path (void);
const char *_gpgme_get_gpgsm_path (void);
/*-- replacement functions in <funcname>.c --*/
#ifdef HAVE_CONFIG_H
#ifndef HAVE_STPCPY
@ -59,7 +60,7 @@ FILE *fopencookie (void *cookie, const char *opentype,
#endif /*!HAVE_FOPENCOOKIE*/
#endif /*HAVE_CONFIG_H*/
/*-- conversion.c --*/
/* Convert two hexadecimal digits from STR to the value they
represent. Returns -1 if one of the characters is not a

View File

@ -32,9 +32,8 @@
#include "key.h"
struct verify_result_s
struct verify_result
{
struct verify_result_s *next;
GpgmeSigStat status;
GpgmeSigStat expstatus; /* Only used by finish_sig. */
GpgmeData notation; /* We store an XML fragment here. */
@ -48,20 +47,18 @@ struct verify_result_s
int wrong_key_usage;
char trust_errtok[31]; /* Error token send with the trust status. */
};
typedef struct verify_result *VerifyResult;
void
_gpgme_release_verify_result (VerifyResult result)
static void
release_verify_result (void *hook)
{
while (result)
{
VerifyResult next_result = result->next;
VerifyResult result = (VerifyResult) hook;
gpgme_data_release (result->notation);
free (result);
result = next_result;
}
}
/* Check whether STRING starts with TOKEN and return true in this
case. This is case insensitive. If NEXT is not NULL return the
number of bytes to be added to STRING to get to the next token; a
@ -120,43 +117,43 @@ copy_token (const char *string, char *buffer, size_t length)
/* FIXME: Check that we are adding this to the correct signature. */
static GpgmeError
add_notation (GpgmeCtx ctx, GpgmeStatusCode code, const char *data)
add_notation (VerifyResult result, GpgmeStatusCode code, const char *notation)
{
GpgmeData dh = ctx->result.verify->notation;
GpgmeData dh = result->notation;
if (!dh)
{
if (gpgme_data_new (&dh))
return GPGME_Out_Of_Core;
ctx->result.verify->notation = dh;
result->notation = dh;
_gpgme_data_append_string (dh, " <notation>\n");
}
if (code == GPGME_STATUS_NOTATION_DATA)
{
if (!ctx->result.verify->notation_in_data)
if (!result->notation_in_data)
_gpgme_data_append_string (dh, " <data>");
_gpgme_data_append_percentstring_for_xml (dh, data);
ctx->result.verify->notation_in_data = 1;
_gpgme_data_append_percentstring_for_xml (dh, notation);
result->notation_in_data = 1;
return 0;
}
if (ctx->result.verify->notation_in_data)
if (result->notation_in_data)
{
_gpgme_data_append_string (dh, "</data>\n");
ctx->result.verify->notation_in_data = 0;
result->notation_in_data = 0;
}
if (code == GPGME_STATUS_NOTATION_NAME)
{
_gpgme_data_append_string (dh, " <name>");
_gpgme_data_append_percentstring_for_xml (dh, data);
_gpgme_data_append_percentstring_for_xml (dh, notation);
_gpgme_data_append_string (dh, "</name>\n");
}
else if (code == GPGME_STATUS_POLICY_URL)
{
_gpgme_data_append_string (dh, " <policy>");
_gpgme_data_append_percentstring_for_xml (dh, data);
_gpgme_data_append_percentstring_for_xml (dh, notation);
_gpgme_data_append_string (dh, "</policy>\n");
}
else
@ -165,53 +162,44 @@ add_notation (GpgmeCtx ctx, GpgmeStatusCode code, const char *data)
}
/* Finish a pending signature info collection and prepare for a new
signature info collection. */
static GpgmeError
finish_sig (GpgmeCtx ctx, int stop)
/* Finish a pending signature info collection. */
static void
finish_sig (VerifyResult result)
{
if (ctx->result.verify->status == GPGME_SIG_STAT_GOOD)
ctx->result.verify->status = ctx->result.verify->expstatus;
struct ctx_op_data *op_data;
if (stop)
return 0; /* nothing to do */
if (ctx->result.verify->collecting)
{
VerifyResult res2;
ctx->result.verify->collecting = 0;
/* Create a new result structure. */
res2 = calloc (1, sizeof *res2);
if (!res2)
return GPGME_Out_Of_Core;
res2->next = ctx->result.verify;
ctx->result.verify = res2;
}
ctx->result.verify->collecting = 1;
return 0;
/* We intimately know that gpgme_op_data_lookup appends the data to
the op_data structure. We can use this here to change the type
knowing only the hook value. */
op_data = (struct ctx_op_data *) ((void *) result
- sizeof (struct ctx_op_data));
op_data->type = OPDATA_VERIFY;
}
GpgmeError
_gpgme_verify_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
VerifyResult result;
GpgmeError err;
char *p;
size_t n;
int i;
test_and_allocate_result (ctx, verify);
err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY_COLLECTING, (void **) &result,
-1, NULL);
if (err)
return err;
if (code == GPGME_STATUS_GOODSIG
|| code == GPGME_STATUS_EXPSIG
|| code == GPGME_STATUS_EXPKEYSIG
|| code == GPGME_STATUS_BADSIG
if (code == GPGME_STATUS_GOODSIG || code == GPGME_STATUS_EXPSIG
|| code == GPGME_STATUS_EXPKEYSIG || code == GPGME_STATUS_BADSIG
|| code == GPGME_STATUS_ERRSIG)
{
err = finish_sig (ctx,0);
/* A new signature starts. */
if (result)
finish_sig (result);
err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY_COLLECTING, (void **) &result,
sizeof (*result), release_verify_result);
if (err)
return err;
}
@ -220,44 +208,56 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
{
case GPGME_STATUS_NODATA:
case GPGME_STATUS_UNEXPECTED:
ctx->result.verify->status = GPGME_SIG_STAT_NOSIG;
if (!result)
return GPGME_General_Error;
result->status = GPGME_SIG_STAT_NOSIG;
break;
case GPGME_STATUS_GOODSIG:
ctx->result.verify->expstatus = GPGME_SIG_STAT_GOOD;
if (!result)
return GPGME_General_Error;
result->expstatus = GPGME_SIG_STAT_GOOD;
break;
case GPGME_STATUS_EXPSIG:
ctx->result.verify->expstatus = GPGME_SIG_STAT_GOOD_EXP;
if (!result)
return GPGME_General_Error;
result->expstatus = GPGME_SIG_STAT_GOOD_EXP;
break;
case GPGME_STATUS_EXPKEYSIG:
ctx->result.verify->expstatus = GPGME_SIG_STAT_GOOD_EXPKEY;
if (!result)
return GPGME_General_Error;
result->expstatus = GPGME_SIG_STAT_GOOD_EXPKEY;
break;
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));
if (!result)
return GPGME_General_Error;
result->status = GPGME_SIG_STAT_GOOD;
i = copy_token (args, result->fpr, DIM (result->fpr));
/* Skip the formatted date. */
while (args[i] && args[i] == ' ')
i++;
while (args[i] && args[i] != ' ')
i++;
/* And get the timestamp. */
ctx->result.verify->timestamp = strtoul (args+i, &p, 10);
result->timestamp = strtoul (args + i, &p, 10);
if (args[i])
ctx->result.verify->exptimestamp = strtoul (p, NULL, 10);
result->exptimestamp = strtoul (p, NULL, 10);
break;
case GPGME_STATUS_BADSIG:
ctx->result.verify->status = GPGME_SIG_STAT_BAD;
if (!result)
return GPGME_General_Error;
result->status = GPGME_SIG_STAT_BAD;
/* Store the keyID in the fpr field. */
copy_token (args, ctx->result.verify->fpr,
DIM(ctx->result.verify->fpr));
copy_token (args, result->fpr, DIM (result->fpr));
break;
case GPGME_STATUS_ERRSIG:
if (!result)
return GPGME_General_Error;
/* 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++)
@ -268,85 +268,97 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
p++;
}
if (p && *(p++) == '9' && (*p == '\0' || *p == ' '))
ctx->result.verify->status = GPGME_SIG_STAT_NOKEY;
result->status = GPGME_SIG_STAT_NOKEY;
else
ctx->result.verify->status = GPGME_SIG_STAT_ERROR;
result->status = GPGME_SIG_STAT_ERROR;
/* Store the keyID in the fpr field. */
copy_token (args, ctx->result.verify->fpr,
DIM(ctx->result.verify->fpr));
copy_token (args, result->fpr, DIM (result->fpr));
break;
case GPGME_STATUS_NOTATION_NAME:
case GPGME_STATUS_NOTATION_DATA:
case GPGME_STATUS_POLICY_URL:
err = add_notation (ctx, code, args);
if (!result)
return GPGME_General_Error;
err = add_notation (result, code, args);
if (err)
return err;
break;
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));
if (!result)
return GPGME_General_Error;
result->validity = GPGME_VALIDITY_UNKNOWN;
copy_token (args, result->trust_errtok,
DIM(result->trust_errtok));
break;
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));
if (!result)
return GPGME_General_Error;
result->validity = GPGME_VALIDITY_NEVER;
copy_token (args, result->trust_errtok,
DIM(result->trust_errtok));
break;
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));
if (!result)
return GPGME_General_Error;
if (result->status == GPGME_SIG_STAT_GOOD)
result->validity = GPGME_VALIDITY_MARGINAL;
copy_token (args, result->trust_errtok,
DIM(result->trust_errtok));
break;
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;
if (!result)
return GPGME_General_Error;
if (result->status == GPGME_SIG_STAT_GOOD)
result->validity = GPGME_VALIDITY_FULL;
break;
case GPGME_STATUS_END_STREAM:
break;
case GPGME_STATUS_ERROR:
if (!result)
return GPGME_General_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)
{
args += n;
if (is_token (args, "No_Public_Key", NULL))
ctx->result.verify->status = GPGME_SIG_STAT_NOKEY;
result->status = GPGME_SIG_STAT_NOKEY;
else
ctx->result.verify->status = GPGME_SIG_STAT_ERROR;
result->status = GPGME_SIG_STAT_ERROR;
}
else if (skip_token (args, &n) && n)
{
args += n;
if (is_token (args, "Wrong_Key_Usage", NULL))
ctx->result.verify->wrong_key_usage = 1;
result->wrong_key_usage = 1;
}
break;
case GPGME_STATUS_EOF:
err = finish_sig (ctx,1);
if (err)
return err;
if (result)
{
finish_sig (result);
/* FIXME: Put all notation data into one XML fragment. */
if (ctx->result.verify->notation)
if (result->notation)
{
GpgmeData dh = ctx->result.verify->notation;
GpgmeData dh = result->notation;
if (ctx->result.verify->notation_in_data)
if (result->notation_in_data)
{
_gpgme_data_append_string (dh, "</data>\n");
ctx->result.verify->notation_in_data = 0;
result->notation_in_data = 0;
}
_gpgme_data_append_string (dh, "</notation>\n");
ctx->notation = dh;
ctx->result.verify->notation = NULL;
result->notation = NULL;
}
}
break;
@ -465,20 +477,28 @@ gpgme_op_verify (GpgmeCtx ctx, GpgmeData sig, GpgmeData signed_text,
* when there are no more signatures.
**/
const char *
gpgme_get_sig_status (GpgmeCtx c, int idx,
gpgme_get_sig_status (GpgmeCtx ctx, int idx,
GpgmeSigStat *r_stat, time_t *r_created)
{
struct ctx_op_data *op_data;
VerifyResult result;
if (!c || c->pending || !c->result.verify)
if (!ctx || ctx->pending)
return NULL; /* No results yet or verification error. */
for (result = c->result.verify;
result && idx > 0; result = result->next, idx--)
;
if (!result)
op_data = ctx->op_data;
while (op_data)
{
while (op_data && op_data->type != OPDATA_VERIFY)
op_data = op_data->next;
if (idx-- == 0)
break;
op_data = op_data->next;
}
if (!op_data)
return NULL; /* No more signatures. */
result = (VerifyResult) op_data->hook;
if (r_stat)
*r_stat = result->status;
if (r_created)
@ -545,19 +565,27 @@ calc_sig_summary (VerifyResult result)
const char *
gpgme_get_sig_string_attr (GpgmeCtx c, int idx, GpgmeAttr what, int whatidx)
gpgme_get_sig_string_attr (GpgmeCtx ctx, int idx, GpgmeAttr what, int whatidx)
{
struct ctx_op_data *op_data;
VerifyResult result;
if (!c || c->pending || !c->result.verify)
if (!ctx || ctx->pending)
return NULL; /* No results yet or verification error. */
for (result = c->result.verify;
result && idx > 0; result = result->next, idx--)
;
if (!result)
op_data = ctx->op_data;
while (op_data)
{
while (op_data && op_data->type != OPDATA_VERIFY)
op_data = op_data->next;
if (idx-- == 0)
break;
op_data = op_data->next;
}
if (!op_data)
return NULL; /* No more signatures. */
result = (VerifyResult) op_data->hook;
switch (what)
{
case GPGME_ATTR_FPR:
@ -575,19 +603,27 @@ gpgme_get_sig_string_attr (GpgmeCtx c, int idx, GpgmeAttr what, int whatidx)
unsigned long
gpgme_get_sig_ulong_attr (GpgmeCtx c, int idx, GpgmeAttr what, int reserved)
gpgme_get_sig_ulong_attr (GpgmeCtx ctx, int idx, GpgmeAttr what, int reserved)
{
struct ctx_op_data *op_data;
VerifyResult result;
if (!c || c->pending || !c->result.verify)
if (!ctx || ctx->pending)
return 0; /* No results yet or verification error. */
for (result = c->result.verify;
result && idx > 0; result = result->next, idx--)
;
if (!result)
op_data = ctx->op_data;
while (op_data)
{
while (op_data && op_data->type != OPDATA_VERIFY)
op_data = op_data->next;
if (idx-- == 0)
break;
op_data = op_data->next;
}
if (!op_data)
return 0; /* No more signatures. */
result = (VerifyResult) op_data->hook;
switch (what)
{
case GPGME_ATTR_CREATED:
@ -621,18 +657,28 @@ gpgme_get_sig_ulong_attr (GpgmeCtx c, int idx, GpgmeAttr what, int reserved)
GpgmeError
gpgme_get_sig_key (GpgmeCtx ctx, int idx, GpgmeKey *r_key)
{
struct ctx_op_data *op_data;
VerifyResult result;
if (!ctx || !r_key)
return GPGME_Invalid_Value;
if (ctx->pending || !ctx->result.verify)
if (ctx->pending)
return GPGME_Busy;
for (result = ctx->result.verify;
result && idx > 0; result = result->next, idx--)
;
if (!result)
op_data = ctx->op_data;
while (op_data)
{
while (op_data && op_data->type != OPDATA_VERIFY)
op_data = op_data->next;
if (idx-- == 0)
break;
op_data = op_data->next;
}
if (!op_data)
return GPGME_EOF;
result = (VerifyResult) op_data->hook;
return gpgme_get_key (ctx, result->fpr, r_key, 0, 0);
}

View File

@ -34,6 +34,7 @@
#include "sema.h"
#include "io.h"
#include "engine.h"
#include "debug.h"
void