doc/
[gpgme.git] / gpgme / edit.c
1 /* edit.c - Key edit functions.
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 #include <assert.h>
25
26 #include "util.h"
27 #include "context.h"
28 #include "ops.h"
29
30
31 struct edit_result_s
32 {
33   GpgmeEditCb fnc;
34   void *fnc_value;
35 };
36
37 void
38 _gpgme_release_edit_result (EditResult result)
39 {
40   if (!result)
41     return;
42   free (result);
43 }
44
45
46 static GpgmeError
47 edit_status_handler (GpgmeCtx ctx, GpgmeStatusCode status, char *args)
48 {
49   GpgmeError err = _gpgme_passphrase_status_handler (ctx, status, args);
50   if (err)
51     return err;
52
53   return (*ctx->result.edit->fnc) (ctx->result.edit->fnc_value, status,
54                                    args, NULL);
55 }
56
57
58 static GpgmeError
59 command_handler (void *opaque, GpgmeStatusCode status, const char *args,
60                  const char **result)
61 {
62   GpgmeError err;
63   GpgmeCtx ctx = opaque;
64
65   err = _gpgme_passphrase_command_handler (ctx, status, args, result);
66   if (err)
67     return err;
68
69   if (!result)
70     err = (*ctx->result.edit->fnc) (ctx->result.edit->fnc_value, status,
71                                     args, result);
72
73   return err;
74 }
75
76
77 static GpgmeError
78 _gpgme_op_edit_start (GpgmeCtx ctx, int synchronous,
79                       GpgmeKey key,
80                       GpgmeEditCb fnc, void *fnc_value,
81                       GpgmeData out)
82 {
83   GpgmeError err = 0;
84
85   if (!fnc)
86     return GPGME_Invalid_Value;
87
88   err = _gpgme_op_reset (ctx, synchronous);
89   if (err)
90     goto leave;
91
92   assert (!ctx->result.edit);
93   ctx->result.edit = malloc (sizeof *ctx->result.edit);
94   if (!ctx->result.edit)
95     {
96       err = GPGME_Out_Of_Core;
97       goto leave;
98     }
99   ctx->result.edit->fnc = fnc;
100   ctx->result.edit->fnc_value = fnc_value;
101
102   /* Check the supplied data.  */
103   if (!out)
104     {
105       err = GPGME_Invalid_Value;
106       goto leave;
107     }
108
109   err = _gpgme_engine_set_command_handler (ctx->engine, command_handler,
110                                            ctx, out);
111   if (err)
112     goto leave;
113
114   _gpgme_engine_set_status_handler (ctx->engine, edit_status_handler, ctx);
115
116   _gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
117
118   err = _gpgme_engine_op_edit (ctx->engine, key, out, ctx);
119
120  leave:
121   if (err)
122     {
123       ctx->pending = 0; 
124       _gpgme_engine_release (ctx->engine);
125       ctx->engine = NULL;
126     }
127   return err;
128 }
129
130 GpgmeError
131 gpgme_op_edit_start (GpgmeCtx ctx,
132                      GpgmeKey key,
133                      GpgmeEditCb fnc, void *fnc_value,
134                      GpgmeData out)
135 {
136   return _gpgme_op_edit_start (ctx, 0, key, fnc, fnc_value, out);
137 }
138
139 /**
140  * gpgme_op_edit:
141  * @ctx: The context
142  * @key: The key to be edited.
143  * @fnc: An edit callback handler.
144  * @fnc_value: To be passed to @fnc as first arg.
145  * @out: The output.
146  * 
147  * Return value: 0 on success or an error code.
148  **/
149 GpgmeError
150 gpgme_op_edit (GpgmeCtx ctx,
151                GpgmeKey key,
152                GpgmeEditCb fnc, void *fnc_value,
153                GpgmeData out)
154 {
155   GpgmeError err = _gpgme_op_edit_start (ctx, 1, key, fnc, fnc_value, out);
156   if (!err)
157     err = _gpgme_wait_one (ctx);
158   return err;
159 }