LCOV - code coverage report
Current view: top level - src - edit.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 73 115 63.5 %
Date: 2018-11-14 16:53:58 Functions: 6 10 60.0 %

          Line data    Source code
       1             : /* edit.c - Key edit function.
       2             :    Copyright (C) 2002, 2003, 2004 g10 Code GmbH
       3             : 
       4             :    This file is part of GPGME.
       5             : 
       6             :    GPGME is free software; you can redistribute it and/or modify it
       7             :    under the terms of the GNU Lesser General Public License as
       8             :    published by the Free Software Foundation; either version 2.1 of
       9             :    the License, or (at your option) any later version.
      10             : 
      11             :    GPGME is distributed in the hope that it will be useful, but
      12             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :    Lesser General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU Lesser General Public
      17             :    License along with this program; if not, write to the Free Software
      18             :    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
      19             :    02111-1307, USA.  */
      20             : 
      21             : #if HAVE_CONFIG_H
      22             : #include <config.h>
      23             : #endif
      24             : #include <stdlib.h>
      25             : 
      26             : #include "gpgme.h"
      27             : #include "debug.h"
      28             : #include "context.h"
      29             : #include "ops.h"
      30             : #include "util.h"
      31             : 
      32             : 
      33             : 
      34             : typedef struct
      35             : {
      36             :   /* The user callback function and its hook value.  */
      37             :   gpgme_interact_cb_t fnc;
      38             :   gpgme_edit_cb_t fnc_old;
      39             :   void *fnc_value;
      40             : } *op_data_t;
      41             : 
      42             : 
      43             : static gpgme_error_t
      44          76 : edit_status_handler (void *priv, gpgme_status_code_t status, char *args)
      45             : {
      46          76 :   gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
      47             :   gpgme_error_t err;
      48             :   void *hook;
      49             :   op_data_t opd;
      50             : 
      51          76 :   err = _gpgme_passphrase_status_handler (priv, status, args);
      52          76 :   if (err)
      53           0 :     return err;
      54             : 
      55          76 :   err = _gpgme_progress_status_handler (priv, status, args);
      56          76 :   if (err)
      57           0 :     return err;
      58             : 
      59          76 :   err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, -1, NULL);
      60          76 :   opd = hook;
      61          76 :   if (err)
      62           0 :     return err;
      63             : 
      64          76 :   if (opd->fnc_old)
      65          11 :     return (*opd->fnc_old) (opd->fnc_value, status, args, -1);
      66             : 
      67          65 :   return (*opd->fnc) (opd->fnc_value, _gpgme_status_to_string (status),
      68             :                       args, -1);
      69             : }
      70             : 
      71             : 
      72             : static gpgme_error_t
      73          52 : command_handler (void *priv, gpgme_status_code_t status, const char *args,
      74             :                  int fd, int *processed_r)
      75             : {
      76          52 :   gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
      77             :   gpgme_error_t err;
      78          52 :   int processed = 0;
      79             : 
      80          52 :   if (ctx->passphrase_cb)
      81             :     {
      82          37 :       err = _gpgme_passphrase_command_handler (ctx, status, args,
      83             :                                                fd, &processed);
      84          37 :       if (err)
      85           0 :         return err;
      86             :     }
      87             :   else
      88          15 :     err = 0;
      89             : 
      90          52 :   if (!processed)
      91             :     {
      92             :       void *hook;
      93             :       op_data_t opd;
      94             : 
      95          52 :       err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, -1, NULL);
      96          52 :       opd = hook;
      97          52 :       if (err)
      98           0 :         return err;
      99             : 
     100          52 :       if (opd->fnc_old)
     101           7 :         err = (*opd->fnc_old) (opd->fnc_value, status, args, fd);
     102             :       else
     103          45 :         err = (*opd->fnc) (opd->fnc_value, _gpgme_status_to_string (status),
     104             :                            args, fd);
     105             : 
     106          52 :       if (gpg_err_code (err) == GPG_ERR_FALSE)
     107           0 :         err = 0;
     108             :       else
     109          52 :         processed = 1;
     110             :     }
     111             : 
     112          52 :   *processed_r = processed;
     113          52 :   return err;
     114             : }
     115             : 
     116             : 
     117             : static gpgme_error_t
     118          11 : interact_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t key,
     119             :                 unsigned int flags,
     120             :                 gpgme_interact_cb_t fnc, void *fnc_value, gpgme_data_t out)
     121             : {
     122             :   gpgme_error_t err;
     123             :   void *hook;
     124             :   op_data_t opd;
     125             : 
     126          11 :   err = _gpgme_op_reset (ctx, synchronous);
     127          11 :   if (err)
     128           0 :     return err;
     129             : 
     130          11 :   if (!fnc || !out)
     131           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     132             : 
     133          11 :   err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, sizeof (*opd), NULL);
     134          11 :   opd = hook;
     135          11 :   if (err)
     136           0 :     return err;
     137             : 
     138          11 :   opd->fnc = fnc;
     139          11 :   opd->fnc_old = NULL;
     140          11 :   opd->fnc_value = fnc_value;
     141             : 
     142          11 :   err = _gpgme_engine_set_command_handler (ctx->engine, command_handler, ctx);
     143          11 :   if (err)
     144           0 :     return err;
     145             : 
     146          11 :   _gpgme_engine_set_status_handler (ctx->engine, edit_status_handler, ctx);
     147             : 
     148          11 :   return _gpgme_engine_op_edit (ctx->engine,
     149          11 :                                 (flags & GPGME_INTERACT_CARD)? 1: 0,
     150             :                                 key, out, ctx);
     151             : }
     152             : 
     153             : 
     154             : gpgme_error_t
     155           0 : gpgme_op_interact_start (gpgme_ctx_t ctx, gpgme_key_t key, unsigned int flags,
     156             :                          gpgme_interact_cb_t fnc, void *fnc_value,
     157             :                          gpgme_data_t out)
     158             : {
     159             :   gpgme_error_t err;
     160             : 
     161           0 :   TRACE_BEG5 (DEBUG_CTX, "gpgme_op_interact_start", ctx,
     162             :               "key=%p flags=0x%x fnc=%p fnc_value=%p, out=%p",
     163             :               key, flags,fnc, fnc_value, out);
     164             : 
     165           0 :   if (!ctx)
     166           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     167             : 
     168           0 :   err = interact_start (ctx, 0, key, flags, fnc, fnc_value, out);
     169           0 :   return err;
     170             : }
     171             : 
     172             : 
     173             : gpgme_error_t
     174          11 : gpgme_op_interact (gpgme_ctx_t ctx, gpgme_key_t key, unsigned int flags,
     175             :                    gpgme_interact_cb_t fnc, void *fnc_value,
     176             :                    gpgme_data_t out)
     177             : {
     178             :   gpgme_error_t err;
     179             : 
     180          11 :   TRACE_BEG5 (DEBUG_CTX, "gpgme_op_interact", ctx,
     181             :               "key=%p flags=0x%x fnc=%p fnc_value=%p, out=%p",
     182             :               key, flags,fnc, fnc_value, out);
     183             : 
     184          11 :   if (!ctx)
     185           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     186             : 
     187          11 :   err = interact_start (ctx, 1, key, flags, fnc, fnc_value, out);
     188          11 :   if (!err)
     189          11 :     err = _gpgme_wait_one (ctx);
     190          11 :   return err;
     191             : }
     192             : 
     193             : 
     194             : 
     195             : 
     196             : /* The deprecated interface.  */
     197             : static gpgme_error_t
     198           2 : edit_start (gpgme_ctx_t ctx, int synchronous, int type, gpgme_key_t key,
     199             :             gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
     200             : {
     201             :   gpgme_error_t err;
     202             :   void *hook;
     203             :   op_data_t opd;
     204             : 
     205           2 :   err = _gpgme_op_reset (ctx, synchronous);
     206           2 :   if (err)
     207           0 :     return err;
     208             : 
     209           2 :   if (!fnc || !out)
     210           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     211             : 
     212           2 :   err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, sizeof (*opd), NULL);
     213           2 :   opd = hook;
     214           2 :   if (err)
     215           0 :     return err;
     216             : 
     217           2 :   opd->fnc = NULL;
     218           2 :   opd->fnc_old = fnc;
     219           2 :   opd->fnc_value = fnc_value;
     220             : 
     221           2 :   err = _gpgme_engine_set_command_handler (ctx->engine, command_handler, ctx);
     222           2 :   if (err)
     223           0 :     return err;
     224             : 
     225           2 :   _gpgme_engine_set_status_handler (ctx->engine, edit_status_handler, ctx);
     226             : 
     227           2 :   return _gpgme_engine_op_edit (ctx->engine, type, key, out, ctx);
     228             : }
     229             : 
     230             : 
     231             : gpgme_error_t
     232           0 : gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
     233             :                      gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
     234             : {
     235             :   gpgme_error_t err;
     236             : 
     237           0 :   TRACE_BEG5 (DEBUG_CTX, "gpgme_op_edit_start", ctx,
     238             :               "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key,
     239             :               (key && key->subkeys && key->subkeys->fpr) ?
     240             :               key->subkeys->fpr : "invalid", fnc, fnc_value, out);
     241             : 
     242           0 :   if (!ctx)
     243           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     244             : 
     245           0 :   err = edit_start (ctx, 0, 0, key, fnc, fnc_value, out);
     246           0 :   return err;
     247             : }
     248             : 
     249             : 
     250             : /* Edit the key KEY.  Send status and command requests to FNC and
     251             :    output of edit commands to OUT.  */
     252             : gpgme_error_t
     253           2 : gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key,
     254             :                gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
     255             : {
     256             :   gpgme_error_t err;
     257             : 
     258           2 :   TRACE_BEG5 (DEBUG_CTX, "gpgme_op_edit", ctx,
     259             :               "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key,
     260             :               (key && key->subkeys && key->subkeys->fpr) ?
     261             :               key->subkeys->fpr : "invalid", fnc, fnc_value, out);
     262             : 
     263           2 :   if (!ctx)
     264           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     265             : 
     266           2 :   err = edit_start (ctx, 1, 0, key, fnc, fnc_value, out);
     267             : 
     268           2 :   if (!err)
     269           2 :     err = _gpgme_wait_one (ctx);
     270           2 :   return TRACE_ERR (err);
     271             : }
     272             : 
     273             : 
     274             : gpgme_error_t
     275           0 : gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
     276             :                           gpgme_edit_cb_t fnc, void *fnc_value,
     277             :                           gpgme_data_t out)
     278             : {
     279             :   gpgme_error_t err;
     280             : 
     281           0 :   TRACE_BEG5 (DEBUG_CTX, "gpgme_op_card_edit_start", ctx,
     282             :               "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key,
     283             :               (key && key->subkeys && key->subkeys->fpr) ?
     284             :               key->subkeys->fpr : "invalid", fnc, fnc_value, out);
     285             : 
     286           0 :   if (!ctx)
     287           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     288             : 
     289           0 :   err = edit_start (ctx, 0, 1, key, fnc, fnc_value, out);
     290           0 :   return err;
     291             : }
     292             : 
     293             : 
     294             : /* Edit the card for the key KEY.  Send status and command requests to
     295             :    FNC and output of edit commands to OUT.  */
     296             : gpgme_error_t
     297           0 : gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
     298             :                     gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
     299             : {
     300             :   gpgme_error_t err;
     301             : 
     302           0 :   TRACE_BEG5 (DEBUG_CTX, "gpgme_op_card_edit", ctx,
     303             :               "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key,
     304             :               (key && key->subkeys && key->subkeys->fpr) ?
     305             :               key->subkeys->fpr : "invalid", fnc, fnc_value, out);
     306             : 
     307           0 :   if (!ctx)
     308           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     309             : 
     310           0 :   err = edit_start (ctx, 1, 1, key, fnc, fnc_value, out);
     311           0 :   if (!err)
     312           0 :     err = _gpgme_wait_one (ctx);
     313           0 :   return TRACE_ERR (err);
     314             : }

Generated by: LCOV version 1.13