w32: Remove all support for WindowsCE
[gpgme.git] / src / delete.c
1 /* delete.c - Delete a key.
2    Copyright (C) 2001, 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 #include <errno.h>
26
27 #include "debug.h"
28 #include "gpgme.h"
29 #include "context.h"
30 #include "ops.h"
31
32 \f
33 static gpgme_error_t
34 delete_status_handler (void *priv, gpgme_status_code_t code, char *args)
35 {
36   (void)priv;
37
38   if (code == GPGME_STATUS_DELETE_PROBLEM)
39     {
40       enum delete_problem
41         {
42           DELETE_No_Problem = 0,
43           DELETE_No_Such_Key = 1,
44           DELETE_Must_Delete_Secret_Key = 2,
45           DELETE_Ambiguous_Specification = 3
46         };
47       long problem;
48       char *tail;
49
50       gpg_err_set_errno (0);
51       problem = strtol (args, &tail, 0);
52       if (errno || (*tail && *tail != ' '))
53         return trace_gpg_error (GPG_ERR_INV_ENGINE);
54
55       switch (problem)
56         {
57         case DELETE_No_Problem:
58           break;
59
60         case DELETE_No_Such_Key:
61           return gpg_error (GPG_ERR_NO_PUBKEY);
62
63         case DELETE_Must_Delete_Secret_Key:
64           return gpg_error (GPG_ERR_CONFLICT);
65
66         case DELETE_Ambiguous_Specification:
67           return gpg_error (GPG_ERR_AMBIGUOUS_NAME);
68
69         }
70
71       return gpg_error (GPG_ERR_GENERAL);
72     }
73   else if (code == GPGME_STATUS_ERROR)
74     {
75       /* Some error stati are informational, so we don't return an
76          error code if we are not ready to process this status.  */
77       gpgme_error_t err;
78       char *where = strchr (args, ' ');
79       char *which;
80
81       if (where)
82         {
83           *where = '\0';
84           which = where + 1;
85
86           where = strchr (which, ' ');
87           if (where)
88             *where = '\0';
89
90           where = args;
91         }
92       else
93         return trace_gpg_error (GPG_ERR_INV_ENGINE);
94
95       err = atoi (which);
96
97       if (!strcmp (where, "delete_key.secret")
98           && (gpg_err_code (err) == GPG_ERR_CANCELED
99               || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED))
100         {
101           /* This indicates a user cancellation on the confirmation dialog.  */
102           return gpg_error (gpg_err_code (err));
103         }
104     }
105   return 0;
106 }
107
108
109 static gpgme_error_t
110 delete_start (gpgme_ctx_t ctx, int synchronous, const gpgme_key_t key,
111               unsigned int flags)
112 {
113   gpgme_error_t err;
114
115   err = _gpgme_op_reset (ctx, synchronous);
116   if (err)
117     return err;
118
119   _gpgme_engine_set_status_handler (ctx->engine, delete_status_handler, ctx);
120
121   return _gpgme_engine_op_delete (ctx->engine, key, flags);
122 }
123
124
125 /* Delete KEY from the keyring.  If ALLOW_SECRET is non-zero, secret
126    keys are also deleted.  */
127 gpgme_error_t
128 gpgme_op_delete_start (gpgme_ctx_t ctx, const gpgme_key_t key,
129                        int allow_secret)
130 {
131   gpgme_error_t err;
132
133   TRACE_BEG3 (DEBUG_CTX, "gpgme_op_delete_start", ctx,
134               "key=%p (%s), allow_secret=%i", key,
135               (key->subkeys && key->subkeys->fpr) ?
136               key->subkeys->fpr : "invalid", allow_secret);
137
138   if (!ctx)
139     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
140
141   err = delete_start (ctx, 0, key,
142                       allow_secret ? GPGME_DELETE_ALLOW_SECRET : 0);
143   return TRACE_ERR (err);
144 }
145
146
147 /* Delete KEY from the keyring.  If ALLOW_SECRET is non-zero, secret
148    keys are also deleted.  */
149 gpgme_error_t
150 gpgme_op_delete (gpgme_ctx_t ctx, const gpgme_key_t key, int allow_secret)
151 {
152   gpgme_error_t err;
153
154   TRACE_BEG3 (DEBUG_CTX, "gpgme_op_delete", ctx,
155               "key=%p (%s), allow_secret=%i", key,
156               (key->subkeys && key->subkeys->fpr) ?
157               key->subkeys->fpr : "invalid", allow_secret);
158
159   if (!ctx)
160     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
161
162   err = delete_start (ctx, 1, key,
163                       allow_secret ? GPGME_DELETE_ALLOW_SECRET : 0);
164   if (!err)
165     err = _gpgme_wait_one (ctx);
166   return err;
167 }
168
169
170 /* Delete KEY from the keyring.  */
171 gpgme_error_t
172 gpgme_op_delete_ext_start (gpgme_ctx_t ctx, const gpgme_key_t key,
173                            unsigned int flags)
174 {
175   gpgme_error_t err;
176
177   TRACE_BEG3 (DEBUG_CTX, "gpgme_op_delete_ext_start", ctx,
178               "key=%p (%s), flags=0x%x", key,
179               (key->subkeys && key->subkeys->fpr) ?
180               key->subkeys->fpr : "invalid", flags);
181
182   if (!ctx)
183     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
184
185   err = delete_start (ctx, 0, key, flags);
186   return TRACE_ERR (err);
187 }
188
189
190 /* Delete KEY from the keyring.  */
191 gpgme_error_t
192 gpgme_op_delete_ext (gpgme_ctx_t ctx, const gpgme_key_t key,
193                      unsigned int flags)
194 {
195   gpgme_error_t err;
196
197   TRACE_BEG3 (DEBUG_CTX, "gpgme_op_delete_ext", ctx,
198               "key=%p (%s), flags=0x%x", key,
199               (key->subkeys && key->subkeys->fpr) ?
200               key->subkeys->fpr : "invalid", flags);
201
202   if (!ctx)
203     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
204
205   err = delete_start (ctx, 1, key, flags);
206   if (!err)
207     err = _gpgme_wait_one (ctx);
208   return err;
209 }