2002-07-28 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / gpgme / encrypt.c
index 2f6abda..57ec978 100644 (file)
@@ -28,6 +28,7 @@
 #include "util.h"
 #include "context.h"
 #include "ops.h"
+#include "wait.h"
 
 #define SKIP_TOKEN_OR_RETURN(a) do { \
     while (*(a) && *(a) != ' ') (a)++; \
@@ -38,7 +39,8 @@
 
 struct encrypt_result_s
 {
-  int no_recipients;
+  int no_valid_recipients;
+  int invalid_recipients;
   GpgmeData xmlinfo;
 };
 
@@ -98,7 +100,7 @@ append_xml_encinfo (GpgmeData *rdh, char *args)
 
 
 void
-_gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
+_gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
 {
   if (ctx->error)
     return;
@@ -106,23 +108,26 @@ _gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
 
   switch (code)
     {
-    case STATUS_EOF:
+    case GPGME_STATUS_EOF:
       if (ctx->result.encrypt->xmlinfo)
        {
          append_xml_encinfo (&ctx->result.encrypt->xmlinfo, NULL);
          _gpgme_set_op_info (ctx, ctx->result.encrypt->xmlinfo);
          ctx->result.encrypt->xmlinfo = NULL;
         }
-      if (ctx->result.encrypt->no_recipients) 
+      if (ctx->result.encrypt->no_valid_recipients) 
        ctx->error = mk_error (No_Recipients);
+      else if (ctx->result.encrypt->invalid_recipients) 
+       ctx->error = mk_error (Invalid_Recipients);
       break;
 
-    case STATUS_INV_RECP:
+    case GPGME_STATUS_INV_RECP:
+      ctx->result.encrypt->invalid_recipients++;
       append_xml_encinfo (&ctx->result.encrypt->xmlinfo, args);
       break;
 
-    case STATUS_NO_RECP:
-      ctx->result.encrypt->no_recipients = 1; /* i.e. no usable ones */
+    case GPGME_STATUS_NO_RECP:
+      ctx->result.encrypt->no_valid_recipients = 1;
       break;
 
     default:
@@ -131,34 +136,44 @@ _gpgme_encrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
 }
 
 
-GpgmeError
-gpgme_op_encrypt_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData plain,
-                       GpgmeData ciph)
+void
+_gpgme_encrypt_sym_status_handler (GpgmeCtx ctx, GpgmeStatusCode code, char *args)
 {
-  int err = 0;
+  _gpgme_passphrase_status_handler (ctx, code, args);
+}
 
-  fail_on_pending_request (ctx);
-  ctx->pending = 1;
 
-  _gpgme_release_result (ctx);
+static GpgmeError
+_gpgme_op_encrypt_start (GpgmeCtx ctx, int synchronous,
+                        GpgmeRecipients recp, GpgmeData plain, GpgmeData ciph)
+{
+  GpgmeError err = 0;
+  int symmetric = 0;
 
   /* Do some checks.  */
-  if (!gpgme_recipients_count (recp))
+  if (!recp)
+    symmetric = 1;
+  else if (!gpgme_recipients_count (recp))
     {
-      /* Fixme: In this case we should do symmentric encryption.  */
       err = mk_error (No_Recipients);
       goto leave;
     }
 
-  /* Create an engine object.  */
-  _gpgme_engine_release (ctx->engine);
-  ctx->engine = NULL;
-  err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
-                          : GPGME_PROTOCOL_OpenPGP, &ctx->engine);
+  err = _gpgme_op_reset (ctx, synchronous);
   if (err)
     goto leave;
 
-  _gpgme_engine_set_status_handler (ctx->engine, _gpgme_encrypt_status_handler,
+  if (symmetric)
+    {
+      err = _gpgme_passphrase_start (ctx);
+      if (err)
+       goto leave;
+    }
+
+  _gpgme_engine_set_status_handler (ctx->engine,
+                                   symmetric
+                                   ? _gpgme_encrypt_sym_status_handler
+                                   : _gpgme_encrypt_status_handler,
                                    ctx);
   _gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
 
@@ -193,6 +208,14 @@ gpgme_op_encrypt_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData plain,
 }
 
 
+GpgmeError
+gpgme_op_encrypt_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData plain,
+                       GpgmeData ciph)
+{
+  return _gpgme_op_encrypt_start (ctx, 0, recp, plain, ciph);
+}
+
+
 /**
  * gpgme_op_encrypt:
  * @c: The context
@@ -210,10 +233,10 @@ GpgmeError
 gpgme_op_encrypt (GpgmeCtx ctx, GpgmeRecipients recp,
                  GpgmeData plain, GpgmeData cipher)
 {
-  int err = gpgme_op_encrypt_start (ctx, recp, plain, cipher);
+  int err = _gpgme_op_encrypt_start (ctx, 1, recp, plain, cipher);
   if (!err)
     {
-      gpgme_wait (ctx, &err, 1);
+      err = _gpgme_wait_one (ctx);
       /* Old gpg versions don't return status info for invalid
         recipients, so we simply check whether we got any output at
         all, and if not we assume that we don't have valid