/[winpt]/trunk/Src/wptKeyEditCB.cpp
ViewVC logotype

Diff of /trunk/Src/wptKeyEditCB.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 23 by twoaday, Fri Sep 30 10:10:16 2005 UTC revision 220 by twoaday, Tue May 30 15:31:49 2006 UTC
# Line 1  Line 1 
1  /* wptKeyEditCB.cpp - Key edit callback handling  /* wptKeyEditCB.cpp - Key edit callback handling
2   *      Copyright (C) 2005 Timo Schulz   *      Copyright (C) 2005, 2006 Timo Schulz
3   *   *      Copyright (C) 2005 g10 Code GmbH
4   * This file is part of WinPT.   *
5   *   * This file is part of WinPT.
6   * WinPT is free software; you can redistribute it and/or   *
7   * modify it under the terms of the GNU General Public License   * WinPT is free software; you can redistribute it and/or
8   * as published by the Free Software Foundation; either version 2   * modify it under the terms of the GNU General Public License
9   * of the License, or (at your option) any later version.   * as published by the Free Software Foundation; either version 2
10   *     * of the License, or (at your option) any later version.
11   * WinPT is distributed in the hope that it will be useful,   *  
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * WinPT is distributed in the hope that it will be useful,
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * General Public License for more details.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   *   * General Public License for more details.
16   * You should have received a copy of the GNU General Public License   *
17   * along with WinPT; if not, write to the Free Software Foundation,   * You should have received a copy of the GNU General Public License
18   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   * along with WinPT; if not, write to the Free Software Foundation,
19   */   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  #include <stdio.h>   */
21  #include <string.h>  
22  #include <stdlib.h>  #ifdef HAVE_CONFIG_H
23  #include <assert.h>  #include <config.h>
24  #include <io.h>  #endif
25  #include <windows.h>  
26    #include <stdio.h>
27  #include "w32gpgme.h"  #include <string.h>
28  #include "wptCommonCtl.h"  #include <stdlib.h>
29  #include "wptContext.h"  #include <assert.h>
30  #include "wptKeyEdit.h"  #include <windows.h>
31    
32    #include "gpgme.h"
33  /* edit key callback for command 'keyserver' */  #include "wptCommonCtl.h"
34  static const char *  #include "wptContext.h"
35  cmd_keyserv_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)  #include "wptKeyEdit.h"
36  {  #include "wptErrors.h"
37      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {  
38          ctx->cmd_sent = 1;  /* Possible errors for the edit key operation. */
39          return "keyserver";  enum editkey_error_t {
40      }      EDITKEY_ERR_ALREADY_SIGNED = 1,
41      if (!strcmp (key, "keyedit.add_keyserver"))      EDITKEY_ERR_BAD_PASSPHRASE = 2
42          return ctx->url;  };
43      if ( !strcmp (key, "keyedit.confirm_keyserver"))  
44          return "Y";  typedef gpgme_status_code_t status_code_t;
45      if (!strcmp (key, "passphrase.enter"))  
46          return ctx->pass;  /* 'notation' command handler. */
47      if (!strcmp (key, "keyedit.prompt")) {  static const char*
48          ctx->cmd_sent = 0;  cmd_notation_handler (GpgKeyEdit *ctx, status_code_t code, const char *key)
49          return "save";  {
50      }      static char buf[32];
51    
52      return NULL;      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
53  }          int uid = ctx->getUseridIndex ();
54            ctx->cmd_sent = 1;
55            if (uid != -1) {
56  static const char*              sprintf (buf, "uid %d", ctx->getUseridIndex ());
57  cmd_sign_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)              return buf;
58  {          }
59      static char buf[32];      }
60        if (!strcmp (key, "keyedit.prompt") && ctx->cnt == 0) {
61      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {          ctx->cnt = 1;
62          ctx->cmd_sent = 1;          return "notation";
63          switch (ctx->type) {      }
64          case GPG_EDITKEY_SIGN: return "sign";      if (!strcmp (key, "keyedit.add_notation"))
65          case GPG_EDITKEY_TSIGN: return "tsign";          return ctx->notation;
66          case GPG_EDITKEY_LSIGN: return "lsign";      if (!strcmp (key, "passphrase.enter"))
67          case GPG_EDITKEY_NRSIGN: return"nrsign";          return ctx->pass;
68          case GPG_EDITKEY_NRLSIGN: return "nrlsign";  
69          }      return NULL;
70      }  }
71      if( !strcmp( key, "sign_uid.class" ) ) {      
72          sprintf( buf, "%d", ctx->sig_class );  
73          return buf;  /* 'keyserver' command handler. */
74      }  static const char*
75      if (!strcmp (key, "sign_uid.expire"))  cmd_keyserv_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
76          return "Y"; /* the sig expires when the key expires */  {
77      if (!strcmp (key, "siggen.valid"))      static char buf[32];
78          return ctx->exp_date;  
79      if (!strcmp (key, "trustsig_prompt.trust_value")) {      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
80          sprintf (buf, "%d", ctx->trust_id);          int uid = ctx->getUseridIndex ();
81          return buf;          ctx->cmd_sent = 1;
82      }          if (uid != -1) {
83      if (!strcmp (key, "trustsig_prompt.trust_depth"))              sprintf (buf, "uid %d", ctx->getUseridIndex ());
84          return ""; /* fixme */              return buf;
85      if (!strcmp (key, "trustsig_prompt.trust_regexp"))          }
86          return ""; /* fixme */      }
87      if( !strcmp (key, "sign_uid.local_promote_okay" ) )      if (!strcmp (key, "keyedit.prompt") && ctx->cnt == 0) {
88          return "Y";          ctx->cnt = 1;
89      if( !strcmp (key, "sign_uid.okay" ) )          return "keyserver";
90          return "Y";      }
91      if( !strcmp (key, "keyedit.sign_all.okay" ) )      if (!strcmp (key, "keyedit.add_keyserver"))
92          return "Y";          return ctx->url;
93      if( !strcmp ( key, "passphrase.enter" ) )      if (!strcmp (key, "keyedit.confirm_keyserver"))
94          return ctx->pass;          return "Y";
95      if( !strcmp (key, "keyedit.prompt" ) ) {      if (!strcmp (key, "passphrase.enter"))
96          ctx->cmd_sent = 0;          return ctx->pass;
97          return "save";      if (!strcmp (key, "keyedit.prompt") && ctx->cnt == 1) {
98      }          ctx->reset ();
99                return "save";
100      return NULL;      }
101  }  
102        return NULL;
103    }
104  static const char*  
105  cmd_trust_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)  
106  {  /* 'sign' command handler. */
107      static char buf[4];  static const char*
108    cmd_sign_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
109      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {  {
110          ctx->cmd_sent = 1;      static char buf[32];
111          return "trust";  
112      }      if (ctx->getUseridIndex () != -1 &&
113      if (!strcmp (key, "edit_ownertrust.set_ultimate.okay"))          ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
114          return "Y";          ctx->cnt++;
115      if (!strcmp (key, "edit_ownertrust.value" )) {          sprintf (buf, "uid %d", ctx->getUseridIndex ());
116          sprintf (buf, "%d", ctx->trust_id);          return buf;
117          return buf;      }
118      }  
119      if (!strcmp (key, "keyedit.prompt")) {      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
120          ctx->cmd_sent = 0;          ctx->cmd_sent = 1;
121          return "save";          switch (ctx->getType ()) {
122      }          case GPG_EDITKEY_SIGN:      return "sign";
123            case GPG_EDITKEY_TSIGN:     return "tsign";
124      return NULL;          case GPG_EDITKEY_LSIGN:     return "lsign";
125  }          case GPG_EDITKEY_NRSIGN:    return"nrsign";
126            case GPG_EDITKEY_NRLSIGN:   return "nrlsign";
127            }
128  static const char*      }
129  cmd_adduid_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)      if (!strcmp (key, "sign_uid.class")) {
130  {          sprintf (buf, "%d", ctx->sig_class);
131      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {          return buf;
132          ctx->cmd_sent = 1;      }
133          return "adduid";      if (!strcmp (key, "sign_uid.expire"))
134      }          return "Y"; /* the sig expires when the key expires */
135      if( !strcmp ( key, "keygen.name" ) )      if (!strcmp (key, "siggen.valid"))
136          return ctx->name;          return ctx->exp_date;
137      if( !strcmp (key, "keygen.email" ) )      if (!strcmp (key, "trustsig_prompt.trust_value")) {
138          return ctx->email;          sprintf (buf, "%d", ctx->trust_id);
139      if( !strcmp ( key, "keygen.comment" ) ) {          return buf;
140          if (ctx->cmt)      }
141              return ctx->cmt;      if (!strcmp (key, "trustsig_prompt.trust_depth"))
142          return "";          return ""; /* fixme */
143      }      if (!strcmp (key, "trustsig_prompt.trust_regexp"))
144      if( !strcmp (key, "passphrase.enter" ) )          return ""; /* fixme */
145          return ctx->pass;      if (!strcmp (key, "sign_uid.local_promote_okay" ) )
146      if( !strcmp (key, "keyedit.prompt" ) ) {          return "Y";
147          ctx->cmd_sent = 0;      if (!strcmp (key, "sign_uid.okay" ) )
148          return "save";          return "Y";
149      }      if (!strcmp (key, "keyedit.sign_all.okay"))
150            return "Y";
151      return NULL;      if (!strcmp ( key, "passphrase.enter"))
152  }          return ctx->pass;
153        if (!strcmp (key, "keyedit.prompt")) {
154            ctx->reset ();
155  static const char*          return "save";
156  cmd_deluid_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key,      }
157                      int *r_step)      
158  {      return NULL;
159      static char buf[64];  }
160      int step = *r_step;  
161    /* 'trust' command handler. */
162      if( step == 0 && !strcmp (key, "keyedit.prompt" ) ) {  static const char*
163          sprintf (buf, "uid %d", ctx->uid_index);  cmd_trust_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
164          *r_step = step = 1;  {
165          return buf;      static char buf[4];
166      }  
167      if( step == 1 && !strcmp( key, "keyedit.prompt" ) ) {      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
168          *r_step = step = 2;          ctx->cmd_sent = 1;
169          return "deluid";          return "trust";
170      }      }
171      if( step == 2 && !strcmp ( key, "keyedit.remove.uid.okay" ) ) {      if (!strcmp (key, "edit_ownertrust.set_ultimate.okay"))
172          *r_step = step = 3;          return "Y";
173          return "Y";      if (!strcmp (key, "edit_ownertrust.value" )) {
174      }          sprintf (buf, "%d", ctx->trust_id);
175      if( step == 3 && !strcmp ( key, "keyedit.prompt" ) ) {          return buf;
176          *r_step = step = 0;      }
177          return "save";      if (!strcmp (key, "keyedit.prompt")) {
178      }          ctx->reset ();
179                return "save";
180      return NULL;      }
181  }  
182        return NULL;
183    }
184  static const char *  
185  cmd_delsig_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char * key,  
186                      int * r_step)  /* 'adduid' command handler. */
187  {  static const char*
188      static char buf[64];  cmd_adduid_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
189      int step = *r_step;  {
190        if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
191      if (step == 0 && !strcmp (key, "keyedit.prompt")) {          ctx->cmd_sent = 1;
192          sprintf (buf, "uid %d", ctx->uid_index);          return "adduid";
193          *r_step = step = 1;      }
194          return buf;      if (!strcmp (key, "keygen.name"))
195      }          return ctx->name;
196      if (step == 1 && !strcmp (key, "keyedit.prompt")) {      if (!strcmp (key, "keygen.email"))
197          *r_step = step = 2;          return ctx->email;
198          return "delsig";      if (!strcmp (key, "keygen.comment"))
199      }          return ctx->cmt? ctx->cmt : "";
200      if (!strcmp (key, "keyedit.delsig.unknown") ||      if (!strcmp (key, "passphrase.enter"))
201          !strcmp (key, "keyedit.delsig.valid")) {          return ctx->pass;
202          if (++ctx->cnt == ctx->sig_index)      if( !strcmp (key, "keyedit.prompt")) {
203              return "Y";          ctx->reset ();
204          else          return "save";
205              return "N";      }
206      }  
207      if (ctx->sig_index == 0 &&      return NULL;
208          !strcmp (key, "keyedit.delsig.selfsig"))  }
209          return "Y";  
210      if (step == 2 && !strcmp (key, "keyedit.prompt")) {  
211          *r_step = step = 0;  static const char*
212          return "save";  cmd_deluid_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
213      }                      const char *key)
214      return NULL;  {
215  }      static char buf[64];
216    
217        if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
218  static const char*          sprintf (buf, "uid %d", ctx->getUseridIndex ());
219  cmd_delkey_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,          ctx->cnt = 1;
220                      const char *key, int *r_step )          return buf;
221  {      }
222      static char buf[64];      if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
223      int step = *r_step;          ctx->cnt = 2;
224            return "deluid";
225      if( step == 0 && !strcmp (key, "keyedit.prompt" ) ) {      }
226          sprintf( buf, "key %d", ctx->key_index);      if (ctx->cnt == 2 && !strcmp (key, "keyedit.remove.uid.okay")) {
227          *r_step = step = 1;          ctx->cnt = 3;
228          return buf;          return "Y";
229      }      }
230      if( step == 1 && !strcmp (key, "keyedit.prompt" ) ) {      if (ctx->cnt == 3 && !strcmp (key, "keyedit.prompt" )) {
231          *r_step = step = 2;          ctx->reset ();
232          return "delkey";          return "save";
233      }      }
234      if( step == 2 && !strcmp (key, "keyedit.remove.subkey.okay" ) ) {      
235          *r_step = step = 3;      return NULL;
236          return "Y";  }
237      }  
238      if( step == 3 && !strcmp (key, "keyedit.prompt" ) ) {  
239          *r_step = step = 0;  static const char*
240          return "save";  cmd_delsig_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
241      }  {
242            static char buf[64];
243      return NULL;      static int sig_cnt = 0;
244  }  
245        if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
246            sprintf (buf, "uid %d", ctx->getUseridIndex ());
247  static const char*          ctx->cnt = 1;
248  cmd_addkey_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)          return buf;
249  {      }
250      static char buf[64];      if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
251            ctx->cnt = 2;
252      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {          return "delsig";
253          ctx->cmd_sent = 1;      }
254          return "addkey";      if (!strcmp (key, "keyedit.delsig.unknown") ||
255      }          !strcmp (key, "keyedit.delsig.valid")) {
256            if (++sig_cnt == ctx->getSigIndex ())
257      if( !strcmp (key, "passphrase.enter" ) )              return "Y";
258          return ctx->pass;          else
259      if( !strcmp (key, "keygen.algo" ) ) {              return "N";
260          _snprintf( buf, sizeof buf-1, "%d", ctx->pubkey_algo);      }
261          return buf;      if (!strcmp (key, "keyedit.delsig.selfsig"))
262      }            return "Y";
263      if( !strcmp (key, "keygen.size" ) ) {      if (ctx->cnt == 2 && !strcmp (key, "keyedit.prompt")) {
264          _snprintf( buf, sizeof buf-1, "%d", ctx->pubkey_size);          sig_cnt = 0;
265          return buf;          ctx->reset ();
266      }          return "save";
267      if( !strcmp (key, "keygen.valid" ) ) {      }
268          _snprintf( buf, sizeof buf-1, "%d", ctx->valid);      return NULL;
269          return buf;          }
270      }  
271      if( !strcmp (key, "keyedit.prompt" ) ) {  
272          ctx->cmd_sent = 0;  /* 'delkey' command handler. */
273          return "save";  static const char*
274      }  cmd_delkey_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
275      return NULL;                      const char *key)
276  }  {
277        static char buf[64];
278    
279  static const char*      if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
280  cmd_passwd_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)          sprintf (buf, "key %d", ctx->getKeyIndex ());
281  {          ctx->cnt = 1;
282      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {          return buf;
283          ctx->cmd_sent = 1;      }
284          return "passwd";      if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
285      }          ctx->cnt = 2;
286      if( !strcmp (key, "passphrase.enter") && !ctx->cnt) {          return "delkey";
287          ctx->cnt = 1;      }
288          return ctx->pass;      if (ctx->cnt == 2 && !strcmp (key, "keyedit.remove.subkey.okay")) {
289      }          ctx->cnt = 3;
290      if( !strcmp (key, "passphrase.enter" ))          return "Y";
291          return ctx->new_pass;      }
292      if( !strcmp (key, "change_passwd.empty.okay" ))      if (ctx->cnt == 3 && !strcmp (key, "keyedit.prompt")) {
293          return ctx->flags?  "Y" : "N";          ctx->reset ();
294      if( !strcmp ( key, "keyedit.prompt" ) ) {          return "save";
295          ctx->cmd_sent = 0;      }
296          return "save";  
297      }      return NULL;
298      return NULL;  }
299  }  
300    
301    /* 'addkey' command handler. */
302  static const char *  static const char*
303  cmd_setpref_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char * key)  cmd_addkey_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
304  {  {
305      static char buf[128];      static char buf[64];
306    
307      /* XXX: check the code. */      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
308  #if 0          ctx->cmd_sent = 1;
309      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {          return "addkey";
310          ctx->cmd_sent = 1;      }
311          return "";  
312      }      if (!strcmp (key, "passphrase.enter"))
313      if (!strcmp ( key, "keyedit.prompt") && ctx->u.pref.id == 0) {          return ctx->pass;
314          ctx->u.pref.id++;      if (!strcmp (key, "keygen.algo")) {
315          _snprintf (buf, sizeof buf-1, "setpref %s", ctx->u.pref.new_prefs);          _snprintf (buf, sizeof (buf)-1, "%d", ctx->pubkey_algo);
316          return buf;          return buf;
317      }      }  
318      if (!strcmp ( key, "keyedit.prompt") && ctx->u.pref.id == 1) {      if (!strcmp (key, "keygen.size")) {
319          ctx->u.pref.id++;          _snprintf (buf, sizeof (buf)-1, "%d", ctx->pubkey_size);
320          return "updpref";          return buf;
321      }      }
322      if (!strcmp ( key, "keyedit.updpref.okay"))      if (!strcmp (key, "keygen.valid")) {
323          return "Y";          _snprintf (buf, sizeof (buf)-1, "%d", ctx->getValidDays ());
324      if (!strcmp (key, "passphrase.enter"))          return buf;        
325          return ctx->u.pref.passwd;      }
326      if (!strcmp (key, "keyedit.prompt") && ctx->u.pref.id == 2) {      if (!strcmp (key, "keyedit.prompt")) {
327          ctx->u.pref.id = 0;          ctx->reset ();
328          return "save";          return "save";
329      }      }
330  #endif      return NULL;
331      return NULL;  }
332  }  
333    
334    /* 'passwd' command handler. */
335  static const char*  static const char*
336  cmd_primary_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,  cmd_passwd_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
337                       const char *key, int *r_step )  {
338  {      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
339      static char buf[64];          ctx->cmd_sent = 1;
340      int step = *r_step;          return "passwd";
341        }
342      if( step == 0 && !strcmp (key, "keyedit.prompt" ) ) {      if (ctx->cnt == 0 && !strcmp (key, "passphrase.enter")) {
343          sprintf (buf, "uid %d", ctx->uid_index);          ctx->cnt = 1;
344          *r_step = step = 1;          /* it is possible that there is no old passphrase. */
345          return buf;          if (!ctx->pass && ctx->flags)
346      }              return "";
347      if( step == 1 && !strcmp ( key, "keyedit.prompt" ) ) {          return ctx->pass;
348          *r_step = step = 2;      }
349          return "primary";      if (!strcmp (key, "passphrase.enter" ))
350      }          return ctx->new_pass;
351      if( step == 2 && !strcmp ( key, "passphrase.enter" ) ) {      if (!strcmp (key, "change_passwd.empty.okay" ))
352          *r_step = step = 3;          return ctx->flags?  "Y" : "N";
353          return ctx->pass;      if (!strcmp (key, "keyedit.prompt")) {
354      }          ctx->reset ();
355      if( step == 3 && !strcmp (key, "keyedit.prompt" ) ) {          return "save";
356          *r_step = step = 0;      }
357          return "save";  
358      }      return NULL;
359      return NULL;  }
360  }  
361    
362    static const char*
363  static const char*  cmd_setpref_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char * key)
364  cmd_expire_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,  {
365                      const char *key, int *r_step )      static char buf[128] = {0};
366  {  
367      static char buf[64];      /* XXX: check the code. */
368      int step = *r_step;  #if 0
369        if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
370      if( step == 0 && !strcmp ( key, "keyedit.prompt" ) ) {          ctx->cmd_sent = 1;
371          sprintf(buf, "key %d", ctx->key_index);          return "";
372          *r_step = step = 1;      }
373          return buf;      if (!strcmp (key, "keyedit.prompt") && ctx->u.pref.id == 0) {
374      }          ctx->u.pref.id++;
375      if( step == 1 && !strcmp ( key, "keyedit.prompt" ) ) {          _snprintf (buf, sizeof buf-1, "setpref %s", ctx->u.pref.new_prefs);
376          *r_step = step = 2;          return buf;
377          return "expire";      }
378      }      if (!strcmp (key, "keyedit.prompt") && ctx->u.pref.id == 1) {
379      if( step == 2 && !strcmp ( key, "keygen.valid" ) ) {          ctx->u.pref.id++;
380          *r_step = step = 3;          return "updpref";
381          if (ctx->valid) {              }
382              sprintf (buf, "%d", ctx->valid);      if (!strcmp (key, "keyedit.updpref.okay"))
383              return buf;          return "Y";
384          }      if (!strcmp (key, "passphrase.enter"))
385          else          return ctx->u.pref.passwd;
386              return ctx->exp_date;      if (!strcmp (key, "keyedit.prompt") && ctx->u.pref.id == 2) {
387      }          ctx->u.pref.id = 0;
388      if( step == 3 && !strcmp (key, "passphrase.enter" ) ) {          ctx->reset ();
389          *r_step = step = 4;          return "save";
390          return ctx->pass;      }
391      }  #endif
392      if( step == 4 && !strcmp ( key, "keyedit.prompt" ) ) {      return buf;
393          *r_step = step = 0;  }
394          return "save";  
395      }  
396        /* 'primary' command handler. */
397      return NULL;  static const char*
398  }  cmd_primary_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
399                         const char *key)
400    {
401  const char*      static char buf[64];
402  cmd_revsig_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,  
403                      const char *key, int *r_step)      if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
404  {          sprintf (buf, "uid %d", ctx->getUseridIndex ());
405      static char buf[64];          ctx->cnt = 1;
406      int step = *r_step;          return buf;
407            }
408      if( step == 0 && !strcmp ( key, "keyedit.prompt" ) ) {      if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt" )) {
409          sprintf( buf, "uid %d", ctx->uid_index);          ctx->cnt = 2;
410          *r_step = step = 1;          return "primary";
411          return buf;      }
412      }      if (ctx->cnt == 2 && !strcmp (key, "passphrase.enter")) {
413      if( step == 1 && !strcmp ( key, "keyedit.prompt" ) ) {          ctx->cnt = 3;
414          *r_step = step = 2;          return ctx->pass;
415          return "revsig";      }
416      }      if (ctx->cnt == 3 && !strcmp (key, "keyedit.prompt")) {
417      if( step == 2 && !strcmp (key, "ask_revoke_sig.one" ) ) {          ctx->reset ();
418          *r_step = step = 3;          return "save";
419          return "Y";      }
420      }      return NULL;
421      if( step == 3 && !strcmp (key, "ask_revoke_sig.okay" ) ) {  }
422          *r_step = step = 4;  
423          return "Y";  
424      }  /* 'expire' command handler. */
425      if( step == 4 && !strcmp ( key, "ask_revocation_reason.code" ) ) {  static const char*
426          *r_step = step = 5;  cmd_expire_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
427          return "0";                      const char *key)
428      }  {
429      if( step == 5 && !strcmp ( key, "ask_revocation_reason.text" ) ) {      static char buf[64];
430          *r_step = step = 6;  
431          return "\n";      if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
432      }          sprintf (buf, "key %d", ctx->getKeyIndex ());
433      if( step == 6 && !strcmp (key, "ask_revocation_reason.okay" ) ) {          ctx->cnt = 1;
434          *r_step = step = 7;          return buf;
435          return "Y";      }
436      }      if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
437      if( step == 7 && !strcmp (key, "passphrase.enter" ) ) {          ctx->cnt = 2;
438          *r_step = step = 8;          return "expire";
439          return ctx->pass;      }
440      }      if (ctx->cnt == 2 && !strcmp (key, "keygen.valid" )) {
441      if( step == 8 && !strcmp ( key, "keyedit.prompt" ) ) {          ctx->cnt = 3;
442          *r_step = step = 0;          sprintf (buf, "%d", ctx->getValidDays ());
443          return "save";          return buf;
444      }      }
445            if (ctx->cnt == 3 && !strcmp (key, "passphrase.enter")) {
446      return NULL;          ctx->cnt = 4;
447  }          return ctx->pass;
448        }
449        if (ctx->cnt == 4 && !strcmp (key, "keyedit.prompt")) {
450  static const char *          ctx->reset ();
451  cmd_revkey_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,          return "save";
452                      const char * key, int *r_step)      }
453  {      
454      int step = *r_step;      return NULL;
455      static char buf[64];  }
456    
457      if( step == 0 && !strcmp ( key, "keyedit.prompt" ) ) {  
458          sprintf( buf, "key %d", ctx->key_index);  /* 'revuid' command handler. */
459          *r_step = step = 1;  const char*
460          return buf;  cmd_revuid_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
461      }                      const char *key)
462      if( step == 1 && !strcmp ( key, "keyedit.prompt" ) ) {  {
463          *r_step = step = 2;      static char buf[32];
464          return "revkey";      
465      }      if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
466      if( step == 2 && !strcmp (key, "keyedit.revoke.subkey.okay" ) ) {          ctx->cnt = 1;
467          *r_step = step = 3;          sprintf (buf, "uid %d", ctx->getUseridIndex ());
468          return "Y";          return buf;
469      }      }
470      if( step == 3 &&  !strcmp ( key, "ask_revocation_reason.code" ) ) {      else if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
471          sprintf( buf, "%d", ctx->reason);          ctx->cnt = 2;
472          *r_step = step = 4;          return "revuid";
473          return buf;      }
474      }      else if (ctx->cnt == 2 && !strcmp (key, "keyedit.revoke.uid.okay")) {
475      if( step == 4 && !strcmp ( key, "ask_revocation_reason.text" ) ) {          ctx->cnt = 3;
476          *r_step = step = 5;          return "Y";
477          return "";      }
478      }      else if (ctx->cnt == 3 && !strcmp (key, "ask_revocation_reason.code")) {
479      if( step == 5 && !strcmp (key, "ask_revocation_reason.okay" ) ) {          ctx->cnt = 4;
480          *r_step = step = 6;          return "4";
481          return "Y";      }
482      }      else if (ctx->cnt == 4 && !strcmp (key, "ask_revocation_reason.text")) {
483      if( step == 6 && !strcmp (key, "passphrase.enter" ) ) {          ctx->cnt = 5;
484          *r_step = step = 7;          return "";
485          return ctx->pass;      }
486      }      else if (ctx->cnt == 5 && !strcmp (key, "ask_revocation_reason.okay")) {
487      if( step == 7 && !strcmp ( key, "keyedit.prompt" ) ) {          ctx->cnt = 6;
488          *r_step = step = 0;          return "Y";
489          return "save";      }
490      }      else if (ctx->cnt == 6 && !strcmp (key, "passphrase.enter")) {
491      return NULL;          ctx->cnt = 7;
492  }          return ctx->pass;
493        }
494        else if (ctx->cnt == 7 && !strcmp (key, "keyedit.prompt")) {
495  static const char *          ctx->reset ();
496  cmd_addrev_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,          return "save";
497                      const char * key, int * r_step)      }
498  {      return NULL;
499      int step = *r_step;  }
500    
501      if ((step == 0 /*|| c->result.editk->already_signed*/)  
502          && !strcmp (key, "keyedit.add_revoker")) {  const char*
503          *r_step = step = 1;  cmd_revsig_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
504          /* XXX: handle already-signed. */                      const char *key)
505          return ctx->name;  {
506      }      static char buf[64];
507      if( step == 1 && !strcmp (key, "keyedit.add_revoker.okay" ) ) {      
508          *r_step = step = 2;      if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt" )) {
509          return "Y";          sprintf( buf, "uid %d", ctx->getUseridIndex ());
510      }          ctx->cnt = 1;
511      if( step == 2 && !strcmp (key, "passphrase.enter" ) ) {          return buf;
512          *r_step = step = 3;      }
513          return ctx->pass;      if (ctx->cnt == 1 && !strcmp ( key, "keyedit.prompt" ) ) {
514      }          ctx->cnt = 2;
515      if (step == 3 && !strcmp (key, "keyedit.prompt")) {          return "revsig";
516          *r_step = step = 0;      }
517          return "save";      if (ctx->cnt == 2 && !strcmp (key, "ask_revoke_sig.one" ) ) {
518      }          ctx->cnt = 3;
519      return NULL;          return "Y";
520  }      }
521        if (ctx->cnt == 3 && !strcmp (key, "ask_revoke_sig.okay" ) ) {
522            ctx->cnt = 4;
523  static const char*          return "Y";
524  cmd_addphoto_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key,      }
525                        int *r_step )      if (ctx->cnt == 4 && !strcmp ( key, "ask_revocation_reason.code" ) ) {
526  {          ctx->cnt = 5;
527      int step = *r_step;          return "0";
528        }
529      if (!strcmp (key, "photoid.jpeg.add"))      if (ctx->cnt == 5 && !strcmp ( key, "ask_revocation_reason.text" ) ) {
530          return ctx->url;          ctx->cnt = 6;
531      if (!strcmp (key, "photoid.jpeg.size"))          return "";
532          return "Y";      }
533      if (!strcmp (key, "passphrase.enter"))      if (ctx->cnt == 6 && !strcmp (key, "ask_revocation_reason.okay" ) ) {
534          return ctx->pass;          ctx->cnt = 7;
535      if (!strcmp (key, "keyedit.prompt")) {          return "Y";
536          *r_step = step = 0;      }
537          return "save";      if (ctx->cnt == 7 && !strcmp (key, "passphrase.enter" ) ) {
538      }          ctx->cnt = 8;
539      return NULL;          return ctx->pass;
540  }      }
541        if (ctx->cnt == 8 && !strcmp ( key, "keyedit.prompt" ) ) {
542            ctx->reset ();
543  static const char *          return "save";
544  cmd_enable_disable_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,      }
545                              const char * key, int mode)      
546  {      return NULL;
547      if (!strcmp (key, "keyedit.prompt") && !ctx->cmd_sent) {  }
548          ctx->cmd_sent = 1;  
549          if (mode)  
550              return "disable";  /* 'revoke' command handler. */
551          return "enable";  static const char *
552      }  cmd_revkey_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
553      if (!strcmp (key, "keyedit.prompt")) {                      const char *key)
554          ctx->cmd_sent = 0;  {
555          return "save";      static char buf[64];
556      }  
557      return NULL;      if (ctx->cnt == 0 && !strcmp ( key, "keyedit.prompt" ) ) {
558  }          sprintf( buf, "key %d", ctx->getKeyIndex ());
559            ctx->cnt = 1;
560            return buf;
561        }
562        if (ctx->cnt == 1 && !strcmp (key, "keyedit.prompt")) {
563  static gpgme_error_t                              ctx->cnt = 2;
564  editkey_command_handler (void *opaque, gpgme_status_code_t code, const char *key, int fd)          return "revkey";
565  {      }
566      static int step = 0;      if (ctx->cnt == 2 && !strcmp (key, "keyedit.revoke.subkey.okay")) {
567      const char *out = NULL;          ctx->cnt = 3;
568      GpgKeyEdit *ke = (GpgKeyEdit *)opaque;          return "Y";
569            }
570      if (!code || !ke)      if (ctx->cnt == 3 &&  !strcmp ( key, "ask_revocation_reason.code")) {
571          return gpg_error (GPG_ERR_INV_ARG);          sprintf( buf, "%d", ctx->reason);
572                ctx->cnt = 4;
573      switch (ke->type) {          return buf;
574      case GPG_EDITKEY_LSIGN:      }
575      case GPG_EDITKEY_SIGN:      if (ctx->cnt == 4 && !strcmp (key, "ask_revocation_reason.text")) {
576      case GPG_EDITKEY_NRSIGN:          ctx->cnt = 5;
577      case GPG_EDITKEY_TSIGN:          return "";
578      case GPG_EDITKEY_NRLSIGN:      }
579          out = cmd_sign_handler (ke, code, key);      if (ctx->cnt == 5 && !strcmp (key, "ask_revocation_reason.okay")) {
580          break;          ctx->cnt = 6;
581                    return "Y";
582      case GPG_EDITKEY_TRUST:      }
583          out =  cmd_trust_handler (ke, code, key);      if (ctx->cnt == 6 && !strcmp (key, "passphrase.enter")) {
584          break;          ctx->cnt = 7;
585                    return ctx->pass;
586      case GPG_EDITKEY_ADDUID:      }
587          out =  cmd_adduid_handler (ke, code, key);      if (ctx->cnt == 7 && !strcmp ( key, "keyedit.prompt")) {
588          break;          ctx->reset ();
589                    return "save";
590      case GPG_EDITKEY_DELUID:      }
591          out =  cmd_deluid_handler (ke, code, key, &step);      return NULL;
592          break;  }
593            
594      case GPG_EDITKEY_DELSIG:  
595          out =  cmd_delsig_handler (ke, code, key, &step);  /* 'addrevoker' command handler. */
596          break;  static const char *
597    cmd_addrev_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
598      case GPG_EDITKEY_DELKEY:                      const char *key)
599          out =  cmd_delkey_handler(ke, code, key, &step );  {
600          break;  
601                /* If the isuser already signed the key, send an empty
602      case GPG_EDITKEY_ADDKEY:             string and jump to quit. */
603          out =  cmd_addkey_handler (ke, code, key);      if (ctx->getResult () & EDITKEY_ERR_ALREADY_SIGNED
604          break;          && ctx->cnt != -1 && ctx->cnt != 4) {
605                    ctx->cnt = -1;
606      case GPG_EDITKEY_PASSWD:          return "";
607          out =  cmd_passwd_handler (ke, code, key);      }
608          break;      if (ctx->cnt == -1) {
609                    ctx->cnt = 4;
610      case GPG_EDITKEY_PRIMARY:          return ""; /* empty value to abort. */
611          out =  cmd_primary_handler (ke, code, key, &step);      }
612          break;      if (ctx->cnt == 0 && !strcmp (key, "keyedit.prompt")) {
613                    ctx->cnt = 1;
614      case GPG_EDITKEY_EXPIRE:          return "addrevoker";
615          out =  cmd_expire_handler (ke, code, key, &step);      }
616          break;      if (ctx->cnt == 1 && !strcmp (key, "keyedit.add_revoker")) {
617            ctx->cnt = 2;
618      case GPG_EDITKEY_REVSIG:          return ctx->name;
619          out =  cmd_revsig_handler (ke, code, key, &step);      }
620          break;      if (ctx->cnt == 2 && !strcmp (key, "keyedit.add_revoker.okay")) {
621            ctx->cnt = 3;
622      case GPG_EDITKEY_REVKEY:          return "Y";
623          out =  cmd_revkey_handler (ke, code, key, &step);      }
624          break;      if (ctx->cnt == 3 && !strcmp (key, "passphrase.enter")) {
625            ctx->cnt = 4;
626      case GPG_EDITKEY_ADDREV:          return ctx->pass;
627          out =  cmd_addrev_handler (ke, code, key, &step);      }
628          break;      if (ctx->cnt == 4 && !strcmp (key, "keyedit.prompt")) {
629            ctx->reset ();
630      case GPG_EDITKEY_ADDPHOTO:          return "save";
631          out =  cmd_addphoto_handler (ke, code, key, &step);      }
632          break;  
633        return NULL;
634      case GPG_EDITKEY_ENABLE:  }
635      case GPG_EDITKEY_DISABLE:  
636          out =  cmd_enable_disable_handler (ke, code, key,  
637                                             ke->type == GPG_EDITKEY_DISABLE? 1: 0);  /* 'addphoto' command handler. */
638          break;  static const char*
639    cmd_addphoto_handler (GpgKeyEdit *ctx, gpgme_status_code_t code, const char *key)
640      case GPG_EDITKEY_SETPREF:  {
641          out =  cmd_setpref_handler (ke, code, key);      if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
642          break;          ctx->cmd_sent = 1;
643            return "addphoto";
644      case GPG_EDITKEY_KEYSERV:      }
645          out =  cmd_keyserv_handler (ke, code, key);      if (!strcmp (key, "photoid.jpeg.add"))
646          break;          return ctx->url;
647      }      if (!strcmp (key, "photoid.jpeg.size"))
648      if (out != NULL) {          return "Y";
649          write (fd, out, strlen (out));        if (!strcmp (key, "passphrase.enter"))
650          write (fd, "\n", 1);          return ctx->pass;
651      }      if (!strcmp (key, "keyedit.prompt")) {      
652      return 0;          ctx->reset ();
653  }          return "save";
654        }
655        return NULL;
656    }
657  gpgme_error_t  
658  gpg_editkey (gpgme_ctx_t ctx, gpgme_key_t key, GpgKeyEdit *ek)  
659  {  static const char*
660      gpgme_error_t err;  cmd_minimize_handler (GpgKeyEdit *ctx, status_code_t code, const char *key)
661      {
662      err = gpgme_op_edit (ctx, key, editkey_command_handler, ek, NULL);      if (!strcmp (key, "keyedit.prompt") && !ctx->cmd_sent) {
663      return err;          ctx->cmd_sent = 1;
664  }          return "minimize";
665        }
666        if (!strcmp (key, "keyedit.prompt")) {
667            ctx->reset ();
668            return "save";
669        }
670    
671        return NULL;
672    }
673    
674    /* 'clean' command handler. */
675    static const char*
676    cmd_clean_handler (GpgKeyEdit *ctx, status_code_t code, const char *key)
677    {
678        if (!strcmp (key, "keyedit.prompt") && !ctx->cmd_sent) {
679            ctx->cmd_sent = 1;
680            return "clean";
681        }
682        if (!strcmp (key, "keyedit.prompt")) {
683            ctx->reset ();
684            return "save";
685        }
686        return NULL;
687    }
688    
689    
690    /* 'enable' and 'disable' command handler. */
691    static const char *
692    cmd_enable_disable_handler (GpgKeyEdit *ctx, gpgme_status_code_t code,
693                                const char * key, int mode)
694    {
695        if (!strcmp (key, "keyedit.prompt") && !ctx->cmd_sent) {
696            ctx->cmd_sent = 1;
697            return mode? "disable": "enable";
698        }
699        if (!strcmp (key, "keyedit.prompt")) {
700            ctx->reset ();
701            return "save";
702        }
703        return NULL;
704    }
705    
706    
707    /* edit key dispatch handler. */
708    static gpgme_error_t                    
709    editkey_command_handler (void *opaque, gpgme_status_code_t code,
710                             const char *key, int fd)
711    {
712        const char *out = NULL;
713        GpgKeyEdit *ke = (GpgKeyEdit *)opaque;
714        HANDLE hd = (HANDLE)fd;
715        DWORD n;
716        
717        if (!ke)
718            return gpg_error (GPG_ERR_INV_ARG);
719    
720        /*log_debug ("key=%s code=%d\r\n", key, code);*/
721        switch (code) {
722        case GPGME_STATUS_ALREADY_SIGNED:
723            ke->setResult (EDITKEY_ERR_ALREADY_SIGNED);
724            break;
725    
726        case GPGME_STATUS_BAD_PASSPHRASE:
727            log_debug ("editkey_command_handler: bad passphrase\n");
728            ke->setResult (EDITKEY_ERR_BAD_PASSPHRASE);
729            break;
730    
731        default:
732            break;
733        }
734    
735        if (ke->getResult () & EDITKEY_ERR_BAD_PASSPHRASE) {
736            /* If the entered passphrase is bad, we supply empty
737               passphrase to abort and send 'quit' as soon as possible. */
738            if (!strcmp (key, "passphrase.enter"))
739                WriteFile (hd, "\n", 1, &n, NULL);
740            if (!strcmp (key, "keyedit.prompt"))
741                WriteFile (hd, "quit\n", 5, &n, NULL);
742            ke->reset ();
743            return 0;
744        }
745        
746        switch (ke->getType ()) {
747        case GPG_EDITKEY_LSIGN:
748        case GPG_EDITKEY_SIGN:
749        case GPG_EDITKEY_NRSIGN:
750        case GPG_EDITKEY_TSIGN:
751        case GPG_EDITKEY_NRLSIGN:
752            out = cmd_sign_handler (ke, code, key);
753            break;
754            
755        case GPG_EDITKEY_TRUST:
756            out =  cmd_trust_handler (ke, code, key);
757            break;
758            
759        case GPG_EDITKEY_ADDUID:
760            out =  cmd_adduid_handler (ke, code, key);
761            break;
762            
763        case GPG_EDITKEY_DELUID:
764            out =  cmd_deluid_handler (ke, code, key);
765            break;
766            
767        case GPG_EDITKEY_DELSIG:
768            out =  cmd_delsig_handler (ke, code, key);
769            break;
770    
771        case GPG_EDITKEY_DELKEY:
772            out =  cmd_delkey_handler(ke, code, key);
773            break;
774            
775        case GPG_EDITKEY_ADDKEY:
776            out =  cmd_addkey_handler (ke, code, key);
777            break;
778            
779        case GPG_EDITKEY_PASSWD:
780            out =  cmd_passwd_handler (ke, code, key);
781            break;
782            
783        case GPG_EDITKEY_PRIMARY:
784            out =  cmd_primary_handler (ke, code, key);
785            break;
786            
787        case GPG_EDITKEY_EXPIRE:
788            out =  cmd_expire_handler (ke, code, key);
789            break;
790    
791        case GPG_EDITKEY_REVSIG:
792            out =  cmd_revsig_handler (ke, code, key);
793            break;
794    
795        case GPG_EDITKEY_REVKEY:
796            out =  cmd_revkey_handler (ke, code, key);
797            break;
798                
799        case GPG_EDITKEY_REVUID:
800            out = cmd_revuid_handler (ke, code, key);
801            break;
802    
803        case GPG_EDITKEY_ADDREV:
804            out =  cmd_addrev_handler (ke, code, key);
805            break;
806    
807        case GPG_EDITKEY_ADDPHOTO:
808            out =  cmd_addphoto_handler (ke, code, key);
809            break;
810    
811        case GPG_EDITKEY_NOTATION:
812            out = cmd_notation_handler (ke, code, key);
813            break;
814    
815        case GPG_EDITKEY_MINIMIZE:
816            out = cmd_minimize_handler (ke, code, key);
817            break;
818    
819        case GPG_EDITKEY_CLEAN:
820            out = cmd_clean_handler (ke, code, key);
821            break;
822    
823        case GPG_EDITKEY_ENABLE:
824        case GPG_EDITKEY_DISABLE:
825            n = ke->getType () == GPG_EDITKEY_DISABLE? 1: 0;
826            out = cmd_enable_disable_handler (ke, code, key, n);
827            break;
828    
829        case GPG_EDITKEY_SETPREF:
830            out =  cmd_setpref_handler (ke, code, key);
831            break;
832    
833        case GPG_EDITKEY_KEYSERV:
834            out =  cmd_keyserv_handler (ke, code, key);
835            break;
836        }
837    
838        if (out != NULL) {
839            WriteFile (hd, out, strlen (out), &n, NULL);
840            WriteFile (hd, "\n", 1, &n, NULL);
841        }
842        return 0;
843    }
844    
845    
846    /* Check if a GPG status code occured which marks the
847       current operation as failed.
848       Return value: gpg error constant. */
849    static gpgme_error_t
850    map_result (GpgKeyEdit *ke)
851    {
852        /* XXX Sometimes ALREADY_SIGNED indicates an failure. */
853        if (!ke->getResult ())
854            return gpg_error (GPG_ERR_NO_ERROR);
855        if (ke->getResult () & EDITKEY_ERR_BAD_PASSPHRASE)
856            return gpg_error (GPG_ERR_BAD_PASSPHRASE);
857        return 0;
858    }
859    
860    
861    /* Wrapper around the gpgme edit interface.
862       @ctx context to use.
863       @key key on which the operation should be performed.
864       @ek  key edit context.
865       Return value: 0 on success. */
866    gpgme_error_t
867    gpg_editkey (gpgme_ctx_t ctx, gpgme_key_t key, GpgKeyEdit *ek)
868    {
869        gpgme_error_t err;
870        gpgme_data_t out;
871      
872        err = gpgme_data_new (&out);
873        if (err)
874            return err;
875        err = gpgme_op_edit (ctx, key, editkey_command_handler, ek, out);
876        if (!err)
877            err = map_result (ek);
878    
879        gpgme_data_release (out);
880        return err;
881    }

Legend:
Removed from v.23  
changed lines
  Added in v.220

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26