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 :
31 :
32 : typedef struct
33 : {
34 : /* The user callback function and its hook value. */
35 : gpgme_edit_cb_t fnc;
36 : void *fnc_value;
37 : } *op_data_t;
38 :
39 :
40 : static gpgme_error_t
41 61 : edit_status_handler (void *priv, gpgme_status_code_t status, char *args)
42 : {
43 61 : gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
44 : gpgme_error_t err;
45 : void *hook;
46 : op_data_t opd;
47 :
48 61 : err = _gpgme_passphrase_status_handler (priv, status, args);
49 61 : if (err)
50 0 : return err;
51 :
52 61 : err = _gpgme_progress_status_handler (priv, status, args);
53 61 : if (err)
54 0 : return err;
55 :
56 61 : err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, -1, NULL);
57 61 : opd = hook;
58 61 : if (err)
59 0 : return err;
60 :
61 61 : return (*opd->fnc) (opd->fnc_value, status, args, -1);
62 : }
63 :
64 :
65 : static gpgme_error_t
66 26 : command_handler (void *priv, gpgme_status_code_t status, const char *args,
67 : int fd, int *processed_r)
68 : {
69 26 : gpgme_ctx_t ctx = (gpgme_ctx_t) priv;
70 : gpgme_error_t err;
71 26 : int processed = 0;
72 :
73 26 : if (ctx->passphrase_cb)
74 : {
75 15 : err = _gpgme_passphrase_command_handler (ctx, status, args,
76 : fd, &processed);
77 15 : if (err)
78 0 : return err;
79 : }
80 :
81 26 : if (!processed)
82 : {
83 : void *hook;
84 : op_data_t opd;
85 :
86 26 : err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, -1, NULL);
87 26 : opd = hook;
88 26 : if (err)
89 0 : return err;
90 :
91 : /* FIXME: We expect the user to handle _all_ status codes.
92 : Later, we may fix the callback interface to allow the user
93 : indicate if it processed the status code or not. */
94 26 : *processed_r = 1;
95 :
96 26 : return (*opd->fnc) (opd->fnc_value, status, args, fd);
97 : }
98 :
99 0 : *processed_r = processed;
100 0 : return 0;
101 : }
102 :
103 :
104 : static gpgme_error_t
105 7 : edit_start (gpgme_ctx_t ctx, int synchronous, int type, gpgme_key_t key,
106 : gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
107 : {
108 : gpgme_error_t err;
109 : void *hook;
110 : op_data_t opd;
111 :
112 7 : err = _gpgme_op_reset (ctx, synchronous);
113 7 : if (err)
114 0 : return err;
115 :
116 7 : if (!fnc || !out)
117 0 : return gpg_error (GPG_ERR_INV_VALUE);
118 :
119 7 : err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, sizeof (*opd), NULL);
120 7 : opd = hook;
121 7 : if (err)
122 0 : return err;
123 :
124 7 : opd->fnc = fnc;
125 7 : opd->fnc_value = fnc_value;
126 :
127 7 : err = _gpgme_engine_set_command_handler (ctx->engine, command_handler,
128 : ctx, out);
129 7 : if (err)
130 0 : return err;
131 :
132 7 : _gpgme_engine_set_status_handler (ctx->engine, edit_status_handler, ctx);
133 :
134 7 : return _gpgme_engine_op_edit (ctx->engine, type, key, out, ctx);
135 : }
136 :
137 :
138 : gpgme_error_t
139 0 : gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
140 : gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
141 : {
142 : gpgme_error_t err;
143 :
144 0 : TRACE_BEG5 (DEBUG_CTX, "gpgme_op_edit_start", ctx,
145 : "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key,
146 : (key && key->subkeys && key->subkeys->fpr) ?
147 : key->subkeys->fpr : "invalid", fnc, fnc_value, out);
148 :
149 0 : if (!ctx)
150 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
151 :
152 0 : err = edit_start (ctx, 0, 0, key, fnc, fnc_value, out);
153 0 : return err;
154 : }
155 :
156 :
157 : /* Edit the key KEY. Send status and command requests to FNC and
158 : output of edit commands to OUT. */
159 : gpgme_error_t
160 7 : gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key,
161 : gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
162 : {
163 : gpgme_error_t err;
164 :
165 7 : TRACE_BEG5 (DEBUG_CTX, "gpgme_op_edit", ctx,
166 : "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key,
167 : (key && key->subkeys && key->subkeys->fpr) ?
168 : key->subkeys->fpr : "invalid", fnc, fnc_value, out);
169 :
170 7 : if (!ctx)
171 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
172 :
173 7 : err = edit_start (ctx, 1, 0, key, fnc, fnc_value, out);
174 :
175 7 : if (!err)
176 7 : err = _gpgme_wait_one (ctx);
177 7 : return TRACE_ERR (err);
178 : }
179 :
180 :
181 : gpgme_error_t
182 0 : gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
183 : gpgme_edit_cb_t fnc, void *fnc_value,
184 : gpgme_data_t out)
185 : {
186 : gpgme_error_t err;
187 :
188 0 : TRACE_BEG5 (DEBUG_CTX, "gpgme_op_card_edit_start", ctx,
189 : "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key,
190 : (key && key->subkeys && key->subkeys->fpr) ?
191 : key->subkeys->fpr : "invalid", fnc, fnc_value, out);
192 :
193 0 : if (!ctx)
194 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
195 :
196 0 : err = edit_start (ctx, 0, 1, key, fnc, fnc_value, out);
197 0 : return err;
198 : }
199 :
200 :
201 : /* Edit the card for the key KEY. Send status and command requests to
202 : FNC and output of edit commands to OUT. */
203 : gpgme_error_t
204 0 : gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
205 : gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
206 : {
207 : gpgme_error_t err;
208 :
209 0 : TRACE_BEG5 (DEBUG_CTX, "gpgme_op_card_edit", ctx,
210 : "key=%p (%s), fnc=%p fnc_value=%p, out=%p", key,
211 : (key && key->subkeys && key->subkeys->fpr) ?
212 : key->subkeys->fpr : "invalid", fnc, fnc_value, out);
213 :
214 0 : if (!ctx)
215 0 : return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
216 :
217 0 : err = edit_start (ctx, 1, 1, key, fnc, fnc_value, out);
218 0 : if (!err)
219 0 : err = _gpgme_wait_one (ctx);
220 0 : return TRACE_ERR (err);
221 : }
|