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: 2016-11-29 15:07:43 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         103 : edit_status_handler (void *priv, gpgme_status_code_t status, char *args)
      45             : {
      46         103 :   gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
      47             :   gpgme_error_t err;
      48             :   void *hook;
      49             :   op_data_t opd;
      50             : 
      51         103 :   err = _gpgme_passphrase_status_handler (priv, status, args);
      52         103 :   if (err)
      53           0 :     return err;
      54             : 
      55         103 :   err = _gpgme_progress_status_handler (priv, status, args);
      56         103 :   if (err)
      57           0 :     return err;
      58             : 
      59         103 :   err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, -1, NULL);
      60         103 :   opd = hook;
      61         103 :   if (err)
      62           0 :     return err;
      63             : 
      64         103 :   if (opd->fnc_old)
      65          21 :     return (*opd->fnc_old) (opd->fnc_value, status, args, -1);
      66             : 
      67          82 :   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,
     143             :                                            ctx, out);
     144          11 :   if (err)
     145           0 :     return err;
     146             : 
     147          11 :   _gpgme_engine_set_status_handler (ctx->engine, edit_status_handler, ctx);
     148             : 
     149          11 :   return _gpgme_engine_op_edit (ctx->engine,
     150          11 :                                 (flags & GPGME_INTERACT_CARD)? 1: 0,
     151             :                                 key, out, ctx);
     152             : }
     153             : 
     154             : 
     155             : gpgme_error_t
     156           0 : gpgme_op_interact_start (gpgme_ctx_t ctx, gpgme_key_t key, unsigned int flags,
     157             :                          gpgme_interact_cb_t fnc, void *fnc_value,
     158             :                          gpgme_data_t out)
     159             : {
     160             :   gpgme_error_t err;
     161             : 
     162           0 :   TRACE_BEG5 (DEBUG_CTX, "gpgme_op_interact_start", ctx,
     163             :               "key=%p flags=0x%x fnc=%p fnc_value=%p, out=%p",
     164             :               key, flags,fnc, fnc_value, out);
     165             : 
     166           0 :   if (!ctx)
     167           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     168             : 
     169           0 :   err = interact_start (ctx, 0, key, flags, fnc, fnc_value, out);
     170           0 :   return err;
     171             : }
     172             : 
     173             : 
     174             : gpgme_error_t
     175          11 : gpgme_op_interact (gpgme_ctx_t ctx, gpgme_key_t key, unsigned int flags,
     176             :                    gpgme_interact_cb_t fnc, void *fnc_value,
     177             :                    gpgme_data_t out)
     178             : {
     179             :   gpgme_error_t err;
     180             : 
     181          11 :   TRACE_BEG5 (DEBUG_CTX, "gpgme_op_interact", ctx,
     182             :               "key=%p flags=0x%x fnc=%p fnc_value=%p, out=%p",
     183             :               key, flags,fnc, fnc_value, out);
     184             : 
     185          11 :   if (!ctx)
     186           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     187             : 
     188          11 :   err = interact_start (ctx, 1, key, flags, fnc, fnc_value, out);
     189          11 :   if (!err)
     190          11 :     err = _gpgme_wait_one (ctx);
     191          11 :   return err;
     192             : }
     193             : 
     194             : 
     195             : 
     196             : 
     197             : /* The deprectated interface.  */
     198             : static gpgme_error_t
     199           2 : edit_start (gpgme_ctx_t ctx, int synchronous, int type, gpgme_key_t key,
     200             :             gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
     201             : {
     202             :   gpgme_error_t err;
     203             :   void *hook;
     204             :   op_data_t opd;
     205             : 
     206           2 :   err = _gpgme_op_reset (ctx, synchronous);
     207           2 :   if (err)
     208           0 :     return err;
     209             : 
     210           2 :   if (!fnc || !out)
     211           0 :     return gpg_error (GPG_ERR_INV_VALUE);
     212             : 
     213           2 :   err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, sizeof (*opd), NULL);
     214           2 :   opd = hook;
     215           2 :   if (err)
     216           0 :     return err;
     217             : 
     218           2 :   opd->fnc = NULL;
     219           2 :   opd->fnc_old = fnc;
     220           2 :   opd->fnc_value = fnc_value;
     221             : 
     222           2 :   err = _gpgme_engine_set_command_handler (ctx->engine, command_handler,
     223             :                                            ctx, out);
     224           2 :   if (err)
     225           0 :     return err;
     226             : 
     227           2 :   _gpgme_engine_set_status_handler (ctx->engine, edit_status_handler, ctx);
     228             : 
     229           2 :   return _gpgme_engine_op_edit (ctx->engine, type, key, out, ctx);
     230             : }
     231             : 
     232             : 
     233             : gpgme_error_t
     234           0 : gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
     235             :                      gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
     236             : {
     237             :   gpgme_error_t err;
     238             : 
     239           0 :   TRACE_BEG5 (DEBUG_CTX, "gpgme_op_edit_start", ctx,
     240             :               "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key,
     241             :               (key && key->subkeys && key->subkeys->fpr) ?
     242             :               key->subkeys->fpr : "invalid", fnc, fnc_value, out);
     243             : 
     244           0 :   if (!ctx)
     245           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     246             : 
     247           0 :   err = edit_start (ctx, 0, 0, key, fnc, fnc_value, out);
     248           0 :   return err;
     249             : }
     250             : 
     251             : 
     252             : /* Edit the key KEY.  Send status and command requests to FNC and
     253             :    output of edit commands to OUT.  */
     254             : gpgme_error_t
     255           2 : gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key,
     256             :                gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
     257             : {
     258             :   gpgme_error_t err;
     259             : 
     260           2 :   TRACE_BEG5 (DEBUG_CTX, "gpgme_op_edit", ctx,
     261             :               "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key,
     262             :               (key && key->subkeys && key->subkeys->fpr) ?
     263             :               key->subkeys->fpr : "invalid", fnc, fnc_value, out);
     264             : 
     265           2 :   if (!ctx)
     266           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     267             : 
     268           2 :   err = edit_start (ctx, 1, 0, key, fnc, fnc_value, out);
     269             : 
     270           2 :   if (!err)
     271           2 :     err = _gpgme_wait_one (ctx);
     272           2 :   return TRACE_ERR (err);
     273             : }
     274             : 
     275             : 
     276             : gpgme_error_t
     277           0 : gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
     278             :                           gpgme_edit_cb_t fnc, void *fnc_value,
     279             :                           gpgme_data_t out)
     280             : {
     281             :   gpgme_error_t err;
     282             : 
     283           0 :   TRACE_BEG5 (DEBUG_CTX, "gpgme_op_card_edit_start", ctx,
     284             :               "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key,
     285             :               (key && key->subkeys && key->subkeys->fpr) ?
     286             :               key->subkeys->fpr : "invalid", fnc, fnc_value, out);
     287             : 
     288           0 :   if (!ctx)
     289           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     290             : 
     291           0 :   err = edit_start (ctx, 0, 1, key, fnc, fnc_value, out);
     292           0 :   return err;
     293             : }
     294             : 
     295             : 
     296             : /* Edit the card for the key KEY.  Send status and command requests to
     297             :    FNC and output of edit commands to OUT.  */
     298             : gpgme_error_t
     299           0 : gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
     300             :                     gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
     301             : {
     302             :   gpgme_error_t err;
     303             : 
     304           0 :   TRACE_BEG5 (DEBUG_CTX, "gpgme_op_card_edit", ctx,
     305             :               "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key,
     306             :               (key && key->subkeys && key->subkeys->fpr) ?
     307             :               key->subkeys->fpr : "invalid", fnc, fnc_value, out);
     308             : 
     309           0 :   if (!ctx)
     310           0 :     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
     311             : 
     312           0 :   err = edit_start (ctx, 1, 1, key, fnc, fnc_value, out);
     313           0 :   if (!err)
     314           0 :     err = _gpgme_wait_one (ctx);
     315           0 :   return TRACE_ERR (err);
     316             : }

Generated by: LCOV version 1.11