2002-01-30 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / gpgme / delete.c
1 /* delete.c -  delete a key 
2  *      Copyright (C) 2001 g10 Code GmbH
3  *
4  * This file is part of GPGME.
5  *
6  * GPGME is free software; you can redistribute it and/or modify
7  * it 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,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <time.h>
26 #include <assert.h>
27
28 #include "util.h"
29 #include "context.h"
30 #include "ops.h"
31 #include "key.h"
32
33
34 enum delete_problem
35   {
36     DELETE_No_Problem = 0,
37     DELETE_No_Such_Key = 1,
38     DELETE_Must_Delete_Secret_Key = 2
39   };
40
41
42 struct delete_result_s
43 {
44   enum delete_problem problem;
45 };
46
47
48 void
49 _gpgme_release_delete_result (DeleteResult result)
50 {
51   if (!result)
52     return;
53   xfree (result);
54 }
55
56
57 static void
58 delete_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
59 {
60   if (ctx->out_of_core)
61     return;
62
63   if (!ctx->result.delete)
64     {
65       ctx->result.delete = xtrycalloc (1, sizeof *ctx->result.delete);
66       if (!ctx->result.delete)
67         {
68           ctx->out_of_core = 1;
69           return;
70         }
71     }
72
73   switch (code)
74     {
75     case STATUS_EOF:
76       break;
77
78     case STATUS_DELETE_PROBLEM:
79       ctx->result.delete->problem = atoi (args);
80       break;
81
82     default:
83       /* Ignore all other codes.  */
84       break;
85     }
86 }
87
88
89 GpgmeError
90 gpgme_op_delete_start (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
91 {
92   GpgmeError err = 0;
93
94   fail_on_pending_request (ctx);
95   ctx->pending = 1;
96
97   if (!key)
98     {
99       err = mk_error (Invalid_Value);
100       goto leave;
101     }
102
103   if (ctx->engine)
104     {
105       _gpgme_engine_release (ctx->engine); 
106       ctx->engine = NULL;
107     }
108     
109   err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
110                            : GPGME_PROTOCOL_OpenPGP, &ctx->engine);
111   if (err)
112     goto leave;
113
114   _gpgme_engine_set_status_handler (ctx->engine, delete_status_handler, ctx);
115   _gpgme_engine_set_verbosity (ctx->engine, ctx->verbosity);
116
117   err = _gpgme_engine_op_delete (ctx->engine, key, allow_secret);
118   if (!err)
119     err = _gpgme_engine_start (ctx->engine, ctx);
120
121  leave:
122   if (err)
123     {
124       ctx->pending = 0; 
125       _gpgme_engine_release (ctx->engine);
126       ctx->engine = NULL;
127     }
128   return err;
129 }
130
131
132 /**
133  * gpgme_op_delete:
134  * @c: Context 
135  * @key: A Key Object
136  * @allow_secret: Allow secret key delete
137  * 
138  * Delete the give @key from the key database.  To delete a secret
139  * along with the public key, @allow_secret must be true.
140  * 
141  * Return value: 0 on success or an error code.
142  **/
143 GpgmeError
144 gpgme_op_delete (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
145 {
146   GpgmeError err = gpgme_op_delete_start (ctx, key, allow_secret);
147   if (!err)
148     {
149       gpgme_wait (ctx, 1);
150       if (ctx->result.delete)
151         {
152           switch (ctx->result.delete->problem)
153             {
154             case DELETE_No_Problem:
155               break;
156             case DELETE_No_Such_Key:
157               err = mk_error(Invalid_Key);
158               break;
159             case DELETE_Must_Delete_Secret_Key:
160               err = mk_error(Conflict);
161               break;
162             default:
163               err = mk_error(General_Error);
164               break;
165             }
166         }
167     }
168   return err;
169 }