4c8a8e9133044caeaf77002285e6655880c8565a
[gpgme.git] / gpgme / edit.c
1 /* edit.c - Key edit function.
2    Copyright (C) 2002, 2003 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 General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (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    General Public License for more details.
15  
16    You should have received a copy of the GNU General Public License
17    along with GPGME; if not, write to the Free Software Foundation,
18    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdlib.h>
24
25 #include "gpgme.h"
26 #include "context.h"
27 #include "ops.h"
28
29 \f
30 typedef struct
31 {
32   /* The user callback function and its hook value.  */
33   GpgmeEditCb fnc;
34   void *fnc_value;
35 } *op_data_t;
36
37 \f
38 static GpgmeError
39 edit_status_handler (void *priv, GpgmeStatusCode status, char *args)
40 {
41   GpgmeCtx ctx = (GpgmeCtx) priv;
42   op_data_t opd;
43
44   return _gpgme_passphrase_status_handler (priv, status, args)
45     || _gpgme_progress_status_handler (priv, status, args)
46     || _gpgme_op_data_lookup (ctx, OPDATA_EDIT, (void **) &opd, -1, NULL)
47     || (*opd->fnc) (opd->fnc_value, status, args, NULL);
48 }
49
50
51 static GpgmeError
52 command_handler (void *priv, GpgmeStatusCode status, const char *args,
53                  const char **result)
54 {
55   GpgmeCtx ctx = (GpgmeCtx) priv;
56   GpgmeError err;
57   op_data_t opd;
58
59   *result = NULL;
60   if (ctx->passphrase_cb)
61     {
62       err = _gpgme_passphrase_command_handler (ctx, status, args, result);
63       if (err)
64         return err;
65     }
66
67   if (!*result)
68     {
69       err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, (void **) &opd, -1, NULL);
70       if (err)
71         return err;
72
73       return (*opd->fnc) (opd->fnc_value, status, args, result);
74     }
75   return 0;
76 }
77
78
79 static GpgmeError
80 edit_start (GpgmeCtx ctx, int synchronous, GpgmeKey key,
81             GpgmeEditCb fnc, void *fnc_value, GpgmeData out)
82 {
83   GpgmeError err;
84   op_data_t opd;
85
86   err = _gpgme_op_reset (ctx, synchronous);
87   if (err)
88     return err;
89
90   if (!fnc || !out)
91     return GPGME_Invalid_Value;
92
93   err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, (void **) &opd,
94                                sizeof (*opd), NULL);
95   if (err)
96     return err;
97
98   opd->fnc = fnc;
99   opd->fnc_value = fnc_value;
100
101   err = _gpgme_engine_set_command_handler (ctx->engine, command_handler,
102                                            ctx, out);
103   if (err)
104     return err;
105
106   _gpgme_engine_set_status_handler (ctx->engine, edit_status_handler, ctx);
107
108   return _gpgme_engine_op_edit (ctx->engine, key, out, ctx);
109 }
110
111
112 GpgmeError
113 gpgme_op_edit_start (GpgmeCtx ctx, GpgmeKey key,
114                      GpgmeEditCb fnc, void *fnc_value, GpgmeData out)
115 {
116   return edit_start (ctx, 0, key, fnc, fnc_value, out);
117 }
118
119
120 /* Edit the key KEY.  Send status and command requests to FNC and
121    output of edit commands to OUT.  */
122 GpgmeError
123 gpgme_op_edit (GpgmeCtx ctx, GpgmeKey key,
124                GpgmeEditCb fnc, void *fnc_value, GpgmeData out)
125 {
126   GpgmeError err = edit_start (ctx, 1, key, fnc, fnc_value, out);
127   if (!err)
128     err = _gpgme_wait_one (ctx);
129   return err;
130 }