diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index e309509d..2a7e61ed 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,96 @@ +2003-01-30 Marcus Brinkmann + + * 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 . + (_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 * types.h (EngineObject): Move typedef to ... diff --git a/gpgme/context.h b/gpgme/context.h index fa6a3dc0..26467cab 100644 --- a/gpgme/context.h +++ b/gpgme/context.h @@ -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 */ diff --git a/gpgme/decrypt.c b/gpgme/decrypt.c index e7f3914c..68555630 100644 --- a/gpgme/decrypt.c +++ b/gpgme/decrypt.c @@ -23,26 +23,18 @@ #endif #include -#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; } diff --git a/gpgme/delete.c b/gpgme/delete.c index 2fe33867..e711b30d 100644 --- a/gpgme/delete.c +++ b/gpgme/delete.c @@ -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; } diff --git a/gpgme/edit.c b/gpgme/edit.c index ec898dc9..b6245167 100644 --- a/gpgme/edit.c +++ b/gpgme/edit.c @@ -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; - goto leave; - } - ctx->result.edit->fnc = fnc; - ctx->result.edit->fnc_value = fnc_value; + err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, (void **) &result, + sizeof (*result), NULL); + if (err) + goto leave; + + result->fnc = fnc; + result->fnc_value = fnc_value; /* Check the supplied data. */ if (!out) diff --git a/gpgme/encrypt.c b/gpgme/encrypt.c index 3b36d76d..5f95151c 100644 --- a/gpgme/encrypt.c +++ b/gpgme/encrypt.c @@ -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 (result && result->no_valid_recipients) + return GPGME_No_Recipients; + if (result && result->invalid_recipients) + return GPGME_Invalid_Recipients; } - if (ctx->result.encrypt->no_valid_recipients) - return GPGME_No_Recipients; - else if (ctx->result.encrypt->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; } diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index 82d719a1..586bc2c8 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -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; } diff --git a/gpgme/export.c b/gpgme/export.c index 9fefee88..2cf9169b 100644 --- a/gpgme/export.c +++ b/gpgme/export.c @@ -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) diff --git a/gpgme/genkey.c b/gpgme/genkey.c index 427365ea..2636c0f1 100644 --- a/gpgme/genkey.c +++ b/gpgme/genkey.c @@ -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; } diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c index 134089b4..02bc9080 100644 --- a/gpgme/gpgme.c +++ b/gpgme/gpgme.c @@ -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); } diff --git a/gpgme/import.c b/gpgme/import.c index 46c696bc..ada3dd8b 100644 --- a/gpgme/import.c +++ b/gpgme/import.c @@ -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; - gpgme_data_release (result->xmlinfo); - free (result); + ImportResult result = (ImportResult) hook; + + if (result->xmlinfo) + gpgme_data_release (result->xmlinfo); } @@ -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); } - diff --git a/gpgme/keylist.c b/gpgme/keylist.c index c2b3c992..e6cc5cec 100644 --- a/gpgme/keylist.c +++ b/gpgme/keylist.c @@ -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; diff --git a/gpgme/op-support.c b/gpgme/op-support.c index 14fb6c80..909b75d1 100644 --- a/gpgme/op-support.c +++ b/gpgme/op-support.c @@ -20,11 +20,42 @@ #if HAVE_CONFIG_H #include #endif +#include #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. */ diff --git a/gpgme/ops.h b/gpgme/ops.h index b382ec2c..49e1afe3 100644 --- a/gpgme/ops.h +++ b/gpgme/ops.h @@ -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); diff --git a/gpgme/passphrase.c b/gpgme/passphrase.c index 43f2b7ba..67fb43ba 100644 --- a/gpgme/passphrase.c +++ b/gpgme/passphrase.c @@ -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; } diff --git a/gpgme/posix-io.c b/gpgme/posix-io.c index 49bca0f9..9c571b09 100644 --- a/gpgme/posix-io.c +++ b/gpgme/posix-io.c @@ -37,6 +37,7 @@ #include "io.h" #include "sema.h" #include "ath.h" +#include "debug.h" static struct { diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index 2b0e4d3d..2d5a1a7a 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -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" diff --git a/gpgme/sign.c b/gpgme/sign.c index d8431cb9..eeebe7ad 100644 --- a/gpgme/sign.c +++ b/gpgme/sign.c @@ -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 (!ctx->result.sign->okay) - return GPGME_No_Data; /* Hmmm: choose a better error? */ + 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; + } 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 diff --git a/gpgme/types.h b/gpgme/types.h index 90d71296..8a36c47e 100644 --- a/gpgme/types.h +++ b/gpgme/types.h @@ -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 */ diff --git a/gpgme/util.h b/gpgme/util.h index 8f697dee..a2805876 100644 --- a/gpgme/util.h +++ b/gpgme/util.h @@ -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 .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 diff --git a/gpgme/verify.c b/gpgme/verify.c index f678dc03..7817668d 100644 --- a/gpgme/verify.c +++ b/gpgme/verify.c @@ -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; - gpgme_data_release (result->notation); - free (result); - result = next_result; - } + VerifyResult result = (VerifyResult) hook; + + gpgme_data_release (result->notation); } + /* 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, " \n"); } if (code == GPGME_STATUS_NOTATION_DATA) { - if (!ctx->result.verify->notation_in_data) + if (!result->notation_in_data) _gpgme_data_append_string (dh, " "); - _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, "\n"); - ctx->result.verify->notation_in_data = 0; + result->notation_in_data = 0; } if (code == GPGME_STATUS_NOTATION_NAME) { _gpgme_data_append_string (dh, " "); - _gpgme_data_append_percentstring_for_xml (dh, data); + _gpgme_data_append_percentstring_for_xml (dh, notation); _gpgme_data_append_string (dh, "\n"); } else if (code == GPGME_STATUS_POLICY_URL) { _gpgme_data_append_string (dh, " "); - _gpgme_data_append_percentstring_for_xml (dh, data); + _gpgme_data_append_percentstring_for_xml (dh, notation); _gpgme_data_append_string (dh, "\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; - - /* FIXME: Put all notation data into one XML fragment. */ - if (ctx->result.verify->notation) + if (result) { - GpgmeData dh = ctx->result.verify->notation; + finish_sig (result); - if (ctx->result.verify->notation_in_data) + /* FIXME: Put all notation data into one XML fragment. */ + if (result->notation) { - _gpgme_data_append_string (dh, "\n"); - ctx->result.verify->notation_in_data = 0; + GpgmeData dh = result->notation; + + if (result->notation_in_data) + { + _gpgme_data_append_string (dh, "\n"); + result->notation_in_data = 0; + } + _gpgme_data_append_string (dh, "\n"); + ctx->notation = dh; + result->notation = NULL; } - _gpgme_data_append_string (dh, "\n"); - ctx->notation = dh; - ctx->result.verify->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: @@ -595,9 +631,9 @@ gpgme_get_sig_ulong_attr (GpgmeCtx c, int idx, GpgmeAttr what, int reserved) case GPGME_ATTR_EXPIRE: return result->exptimestamp; case GPGME_ATTR_VALIDITY: - return (unsigned long)result->validity; + return (unsigned long) result->validity; case GPGME_ATTR_SIG_STATUS: - return (unsigned long)result->status; + return (unsigned long) result->status; case GPGME_ATTR_SIG_SUMMARY: return calc_sig_summary (result); default: @@ -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); } diff --git a/gpgme/wait.c b/gpgme/wait.c index 6d5f2723..c70efa15 100644 --- a/gpgme/wait.c +++ b/gpgme/wait.c @@ -34,6 +34,7 @@ #include "sema.h" #include "io.h" #include "engine.h" +#include "debug.h" void