core: Fail loudly in case w32 spawner not found
[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   if (code == GPGME_STATUS_DELETE_PROBLEM)
37     {
38       enum delete_problem
39         {
40           DELETE_No_Problem = 0,
41           DELETE_No_Such_Key = 1,
42           DELETE_Must_Delete_Secret_Key = 2,
43           DELETE_Ambiguous_Specification = 3
44         };
45       long problem;
46       char *tail;
47
48       gpg_err_set_errno (0);
49       problem = strtol (args, &tail, 0);
50       if (errno || (*tail && *tail != ' '))
51         return trace_gpg_error (GPG_ERR_INV_ENGINE);
52
53       switch (problem)
54         {
55         case DELETE_No_Problem:
56           break;
57
58         case DELETE_No_Such_Key:
59           return gpg_error (GPG_ERR_NO_PUBKEY);
60
61         case DELETE_Must_Delete_Secret_Key:
62           return gpg_error (GPG_ERR_CONFLICT);
63
64         case DELETE_Ambiguous_Specification:
65           return gpg_error (GPG_ERR_AMBIGUOUS_NAME);
66
67         }
68
69       return gpg_error (GPG_ERR_GENERAL);
70     }
71   else if (code == GPGME_STATUS_ERROR)
72     {
73       /* Some error stati are informational, so we don't return an
74          error code if we are not ready to process this status.  */
75       gpgme_error_t err;
76       char *where = strchr (args, ' ');
77       char *which;
78
79       if (where)
80         {
81           *where = '\0';
82           which = where + 1;
83
84           where = strchr (which, ' ');
85           if (where)
86             *where = '\0';
87
88           where = args;
89         }
90       else
91         return trace_gpg_error (GPG_ERR_INV_ENGINE);
92
93       err = atoi (which);
94
95       if (!strcmp (where, "delete_key.secret")
96           && (gpg_err_code (err) == GPG_ERR_CANCELED
97               || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED))
98         {
99           /* This indicates a user cancellation on the confirmation dialog.  */
100           return gpg_error (gpg_err_code (err));
101         }
102     }
103   return 0;
104 }
105
106
107 static gpgme_error_t
108 delete_start (gpgme_ctx_t ctx, int synchronous, const gpgme_key_t key,
109               int allow_secret)
110 {
111   gpgme_error_t err;
112
113   err = _gpgme_op_reset (ctx, synchronous);
114   if (err)
115     return err;
116
117   _gpgme_engine_set_status_handler (ctx->engine, delete_status_handler, ctx);
118
119   return _gpgme_engine_op_delete (ctx->engine, key, allow_secret);
120 }
121
122
123 /* Delete KEY from the keyring.  If ALLOW_SECRET is non-zero, secret
124    keys are also deleted.  */
125 gpgme_error_t
126 gpgme_op_delete_start (gpgme_ctx_t ctx, const gpgme_key_t key,
127                        int allow_secret)
128 {
129   gpgme_error_t err;
130
131   TRACE_BEG3 (DEBUG_CTX, "gpgme_op_delete", ctx,
132               "key=%p (%s), allow_secret=%i", key,
133               (key->subkeys && key->subkeys->fpr) ?
134               key->subkeys->fpr : "invalid", allow_secret);
135
136   if (!ctx)
137     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
138
139   err = delete_start (ctx, 0, key, allow_secret);
140   return TRACE_ERR (err);
141 }
142
143
144 /* Delete KEY from the keyring.  If ALLOW_SECRET is non-zero, secret
145    keys are also deleted.  */
146 gpgme_error_t
147 gpgme_op_delete (gpgme_ctx_t ctx, const gpgme_key_t key, int allow_secret)
148 {
149   gpgme_error_t err;
150
151   TRACE_BEG3 (DEBUG_CTX, "gpgme_op_delete", ctx,
152               "key=%p (%s), allow_secret=%i", key,
153               (key->subkeys && key->subkeys->fpr) ?
154               key->subkeys->fpr : "invalid", allow_secret);
155
156   if (!ctx)
157     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
158
159   err = delete_start (ctx, 1, key, allow_secret);
160   if (!err)
161     err = _gpgme_wait_one (ctx);
162   return err;
163 }