2003-01-30 Marcus Brinkmann <marcus@g10code.de>
authorMarcus Brinkmann <mb@g10code.com>
Thu, 30 Jan 2003 22:40:05 +0000 (22:40 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Thu, 30 Jan 2003 22:40:05 +0000 (22:40 +0000)
* 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".

22 files changed:
trunk/gpgme/ChangeLog
trunk/gpgme/context.h
trunk/gpgme/decrypt.c
trunk/gpgme/delete.c
trunk/gpgme/edit.c
trunk/gpgme/encrypt.c
trunk/gpgme/engine-gpgsm.c
trunk/gpgme/export.c
trunk/gpgme/genkey.c
trunk/gpgme/gpgme.c
trunk/gpgme/import.c
trunk/gpgme/keylist.c
trunk/gpgme/op-support.c
trunk/gpgme/ops.h
trunk/gpgme/passphrase.c
trunk/gpgme/posix-io.c
trunk/gpgme/rungpg.c
trunk/gpgme/sign.c
trunk/gpgme/types.h
trunk/gpgme/util.h
trunk/gpgme/verify.c
trunk/gpgme/wait.c

index e309509db7b8483331ff51a0b14d8cea21c2bb45..2a7e61edd515219db32ca4cae5aeb59f27f1e36f 100644 (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 ...
index fa6a3dc06540ed7f930d6d1a70add8879ac56059..26467cab6256ab26eca7e4ac2e2992c1b4128796 100644 (file)
 #include "engine.h"
 #include "wait.h"
 
+\f
+/* 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;
+};
+
+\f
 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 */
index e7f3914c1298afc2adb37308b7f2377e647597a7..685556300ed635be118200aefdca894851d208d4 100644 (file)
 #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;
 }
 
 
index 2fe33867a5748662e107f143fc392cb93ce30903..e711b30d1670d60803fd96bc086a9dcb650eed29 100644 (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;
 }
index ec898dc905990be9da126b579922cd5d7b0082d5..b6245167b544dca7a52f4b1fefcc9e481e7941be 100644 (file)
 #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;
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, (void **) &result,
+                              -1, NULL);
   if (err)
     return err;
+  assert (result);
 
-  if (!result)
-    err = (*ctx->result.edit->fnc) (ctx->result.edit->fnc_value, status,
-                                   args, 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)
index 3b36d76d544ca4f21e0ad9de9d7244ffa68d72f1..5f95151cacfb1858be28ac1c56d850239872e140 100644 (file)
         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;
 }
 
 
index 82d719a1c13163a30bc26649a285c7323f179551..586bc2c8f3603103b3128cfbe77a21100f1664e9 100644 (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;
 }
 
index 9fefee8845af9f0059e8c5076c79cf1a6f5dab22..2cf9169b3a9265d03fdbd40b0ec2e94d03b65520 100644 (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)
index 427365ea7268771bcfb3e05e056a46091ec3f042..2636c0f1be89e7135e62843c72bb9e53e2cdcc9d 100644 (file)
 #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;
        }
index 134089b492c7968cf59f79b0bbf9dcefc862bf50..02bc9080c5f6921a259d0beb38cc8fc800fca9ea 100644 (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);
 }
 
index 46c696bc646ce02634788ca52d6ed98aa473e5be..ada3dd8bb0863d66ba87c4082c78423954b640b9 100644 (file)
 #include "context.h"
 #include "ops.h"
 
-
-struct import_result_s
+\f
+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);
 }
-
index c2b3c992c9c0d0e0fff47da8de79b0201b80985d..e6cc5cec15105602f28e6a36d0019d4288aaf18e 100644 (file)
 #include "context.h"
 #include "ops.h"
 #include "key.h"
+#include "debug.h"
 
 \f
-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;
 
index 14fb6c8018b89f06bf0b67f9da08b60fdcef567a..909b75d1eb252ae4a75863dedd3d20f829841039 100644 (file)
 #if HAVE_CONFIG_H
 #include <config.h>
 #endif
+#include <stdlib.h>
 
 #include "gpgme.h"
 #include "context.h"
 #include "ops.h"
 
+\f
+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.  */
index b382ec2cc585467c33244d74d5587cd48699a73b..49e1afe3772ab9e880c985361c1341af96649f70 100644 (file)
 #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);
index 43f2b7ba3fb467eb87b669319af21c74008b2b1d..67fb43ba1e630831a4617d665a91fd5f3f7340dd 100644 (file)
 #include "util.h"
 #include "context.h"
 #include "ops.h"
+#include "debug.h"
 
-
-struct passphrase_result_s
+\f
+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);
 }
 
-
+\f
 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;
 }
 
index 49bca0f95590536e2137249e222ce6e413f5263e..9c571b090c4796c3199ee48f2bac04bc131472cb 100644 (file)
@@ -37,6 +37,7 @@
 #include "io.h"
 #include "sema.h"
 #include "ath.h"
+#include "debug.h"
 
 static struct
 {
index 2b0e4d3dfd13c10b2319872232518943b0e2692e..2d5a1a7a583835b53a8166aaccd1d7c79e9bbaa6 100644 (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"
index d8431cb9bb59c7ab6083ae3f590d8375472db89a..eeebe7ade5262beb0bd4662df2c4d2e0ad973671 100644 (file)
         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
index 90d712966fdd37bea6a0a4a82a45192adec19525..8a36c47ea4c7f332cc002778975181511f9391b1 100644 (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 */
index 8f697dee24ba92762056d6c81875b0d55900f100..a2805876f29b777a0ad2ed66581047cc6b5eeabf 100644 (file)
 #ifndef UTIL_H
 #define UTIL_H
 
-#include "types.h"
-#include "debug.h"
-
+#include "gpgme.h"
 
+\f
 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
 #define DIMof(type,member)   DIM(((type *)0)->member)
 
+\f
 /*-- {posix,w32}-util.c --*/
 const char *_gpgme_get_gpg_path (void);
 const char *_gpgme_get_gpgsm_path (void);
 
+\f
 /*-- 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*/
 
-
+\f
 /*-- conversion.c --*/
 /* Convert two hexadecimal digits from STR to the value they
    represent.  Returns -1 if one of the characters is not a
index f678dc03b6dbebb5eb1b9c1e1691f28a116f94e9..7817668d6c0c1d87402cbf8eb6b858c40dd840b9 100644 (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;
-      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, "  <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;
-
-  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;
+  struct ctx_op_data *op_data;
+
+  /* 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, "</data>\n");
-             ctx->result.verify->notation_in_data = 0;
+             GpgmeData dh = result->notation;
+             
+             if (result->notation_in_data)
+               {
+                 _gpgme_data_append_string (dh, "</data>\n");
+                 result->notation_in_data = 0;
+               }
+             _gpgme_data_append_string (dh, "</notation>\n");
+             ctx->notation = dh;
+             result->notation = NULL;
            }
-         _gpgme_data_append_string (dh, "</notation>\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);
 }
index 6d5f27230925e30b4e2b561e3053ac0ac91041b2..c70efa1557672ad79bd8fcb8553ca40d9e189a77 100644 (file)
@@ -34,6 +34,7 @@
 #include "sema.h"
 #include "io.h"
 #include "engine.h"
+#include "debug.h"
 
 \f
 void