doc: Fix documentation of struct data types
[gpgme.git] / src / op-support.c
index c3ba778..edd317d 100644 (file)
@@ -2,17 +2,17 @@
    Copyright (C) 2002, 2003, 2004, 2007 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, see <http://www.gnu.org/licenses/>.
  */
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
+#ifdef HAVE_LOCALE_H
 #include <locale.h>
+#endif
 
 #include "gpgme.h"
 #include "context.h"
 #include "ops.h"
+#include "util.h"
+#include "debug.h"
 
 \f
 gpgme_error_t
 _gpgme_op_data_lookup (gpgme_ctx_t ctx, ctx_op_data_id_t type, void **hook,
                       int size, void (*cleanup) (void *))
 {
-  struct ctx_op_data *data = ctx->op_data;
+  struct ctx_op_data *data;
+
+  if (!ctx)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  data = ctx->op_data;
   while (data && data->type != type)
     data = data->next;
   if (!data)
@@ -47,7 +56,7 @@ _gpgme_op_data_lookup (gpgme_ctx_t ctx, ctx_op_data_id_t type, void **hook,
 
       data = calloc (1, sizeof (struct ctx_op_data) + size);
       if (!data)
-       return gpg_error_from_errno (errno);
+       return gpg_error_from_syserror ();
       data->magic = CTX_OP_DATA_MAGIC;
       data->next = ctx->op_data;
       data->type = type;
@@ -64,7 +73,7 @@ _gpgme_op_data_lookup (gpgme_ctx_t ctx, ctx_op_data_id_t type, void **hook,
 /* 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
-            event loop).  
+            event loop).
             256: Modification flag to suppress the engine reset.
 */
 gpgme_error_t
@@ -114,7 +123,10 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
 
   if (!reuse_engine)
     {
+      err = 0;
+#ifdef LC_CTYPE
       err = _gpgme_engine_set_locale (ctx->engine, LC_CTYPE, ctx->lc_ctype);
+#endif
 #ifdef LC_MESSAGES
       if (!err)
         err = _gpgme_engine_set_locale (ctx->engine,
@@ -122,6 +134,15 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
 #endif
       if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
        err = 0;
+
+      if (!err)
+        {
+          err = _gpgme_engine_set_pinentry_mode (ctx->engine,
+                                                 ctx->pinentry_mode);
+          if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
+            err = 0;
+        }
+
       if (err)
         {
           _gpgme_engine_release (ctx->engine);
@@ -130,6 +151,13 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
         }
     }
 
+  if (ctx->sub_protocol != GPGME_PROTOCOL_DEFAULT)
+    {
+      err = _gpgme_engine_set_protocol (ctx->engine, ctx->sub_protocol);
+      if (err)
+       return err;
+    }
+
   if (type == 1 || (type == 2 && !ctx->io_cbs.add))
     {
       /* Use private event loop.  */
@@ -162,8 +190,8 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
 }
 
 \f
-/* Parse the INV_RECP status line in ARGS and return the result in
-   KEY.  */
+/* Parse the INV_RECP or INV-SNDR status line in ARGS and return the
+   result in KEY.  */
 gpgme_error_t
 _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
 {
@@ -173,15 +201,15 @@ _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
 
   inv_key = malloc (sizeof (*inv_key));
   if (!inv_key)
-    return gpg_error_from_errno (errno);
+    return gpg_error_from_syserror ();
   inv_key->next = NULL;
-  errno = 0;
+  gpg_err_set_errno (0);
   reason = strtol (args, &tail, 0);
-  if (errno || args == tail || *tail != ' ')
+  if (errno || args == tail || (*tail && *tail != ' '))
     {
       /* The crypto backend does not behave.  */
       free (inv_key);
-      return gpg_error (GPG_ERR_INV_ENGINE);
+      return trace_gpg_error (GPG_ERR_INV_ENGINE);
     }
 
   switch (reason)
@@ -234,18 +262,21 @@ _gpgme_parse_inv_recp (char *args, gpgme_invalid_key_t *key)
     case 11:
       inv_key->reason = gpg_error (GPG_ERR_MISSING_CERT);
       break;
+
+    case 12:
+      inv_key->reason = gpg_error (GPG_ERR_MISSING_ISSUER_CERT);
+      break;
     }
 
-  while (*tail == ' ')
+  while (*tail && *tail == ' ')
     tail++;
   if (*tail)
     {
       inv_key->fpr = strdup (tail);
       if (!inv_key->fpr)
        {
-         int saved_errno = errno;
          free (inv_key);
-         return gpg_error_from_errno (saved_errno);
+         return gpg_error_from_syserror ();
        }
     }
   else
@@ -292,7 +323,7 @@ _gpgme_parse_plaintext (char *args, char **filenamep)
     {
       char *filename = strdup (args);
       if (!filename)
-       return gpg_error_from_errno (errno);
+       return gpg_error_from_syserror ();
 
       *filenamep = filename;
     }