core: Make the status-fd monitor work for all gpgsm commands.
[gpgme.git] / src / passphrase.c
index c36b6ae..74d235c 100644 (file)
@@ -1,19 +1,19 @@
 /* passphrase.c - Passphrase callback.
    Copyright (C) 2000 Werner Koch (dd9jn)
    Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
+
    This file is part of GPGME.
+
    GPGME is free software; you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as
    published by the Free Software Foundation; either version 2.1 of
    the License, or (at your option) any later version.
-   
+
    GPGME is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.
-   
+
    You should have received a copy of the GNU Lesser General Public
    License along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
@@ -32,6 +32,7 @@
 #include "context.h"
 #include "ops.h"
 #include "util.h"
+#include "debug.h"
 
 \f
 typedef struct
@@ -40,6 +41,7 @@ typedef struct
   char *uid_hint;
   char *passphrase_info;
   int bad_passphrase;
+  char *maxlen;
 } *op_data_t;
 
 
@@ -52,6 +54,7 @@ release_op_data (void *hook)
     free (opd->passphrase_info);
   if (opd->uid_hint)
     free (opd->uid_hint);
+  free (opd->maxlen);
 }
 
 \f
@@ -72,11 +75,16 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code,
 
   switch (code)
     {
+    case GPGME_STATUS_INQUIRE_MAXLEN:
+      free (opd->maxlen);
+      if (!(opd->maxlen = strdup (args)))
+        return gpg_error_from_syserror ();
+      break;
     case GPGME_STATUS_USERID_HINT:
       if (opd->uid_hint)
        free (opd->uid_hint);
       if (!(opd->uid_hint = strdup (args)))
-      return gpg_error_from_errno (errno);
+        return gpg_error_from_syserror ();
       break;
 
     case GPGME_STATUS_BAD_PASSPHRASE:
@@ -96,7 +104,7 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code,
        free (opd->passphrase_info);
       opd->passphrase_info = strdup (args);
       if (!opd->passphrase_info)
-       return gpg_error_from_errno (errno);
+       return gpg_error_from_syserror ();
       break;
 
     case GPGME_STATUS_MISSING_PASSPHRASE:
@@ -108,6 +116,29 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code,
        return gpg_error (GPG_ERR_BAD_PASSPHRASE);
       break;
 
+    case GPGME_STATUS_ERROR:
+      /* We abuse this status handler to forward ERROR status codes to
+         the caller.  */
+      if (ctx->status_cb && !ctx->full_status)
+        {
+          err = ctx->status_cb (ctx->status_cb_value, "ERROR", args);
+          if (err)
+            return err;
+        }
+      break;
+
+    case GPGME_STATUS_FAILURE:
+      /* We abuse this status handler to forward FAILURE status codes
+         to the caller.  */
+      if (ctx->status_cb && !ctx->full_status)
+        {
+          err = ctx->status_cb (ctx->status_cb_value, "FAILURE", args);
+          if (err)
+            return err;
+        }
+      break;
+
+
     default:
       /* Ignore all other codes.  */
       break;
@@ -133,16 +164,22 @@ _gpgme_passphrase_command_handler (void *priv, gpgme_status_code_t code,
   if (err)
     return err;
 
-  if (code == GPGME_STATUS_GET_HIDDEN 
+  if (code == GPGME_STATUS_GET_HIDDEN
       && (!strcmp (key, "passphrase.enter")
           || !strcmp (key, "passphrase.pin.ask")))
     {
       if (processed)
        *processed = 1;
 
-      err = ctx->passphrase_cb (ctx->passphrase_cb_value,
-                               opd->uid_hint, opd->passphrase_info,
-                               opd->bad_passphrase, fd);
+      /* Fake a status line to to convey the MAXLEN info.  */
+      if (ctx->status_cb && opd->maxlen)
+        err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN",
+                              opd->maxlen);
+
+      if (!err)
+        err = ctx->passphrase_cb (ctx->passphrase_cb_value,
+                                  opd->uid_hint, opd->passphrase_info,
+                                  opd->bad_passphrase, fd);
 
       /* Reset bad passphrase flag, in case it is correct now.  */
       opd->bad_passphrase = 0;