2009-10-28 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / src / export.c
1 /* export.c - Export a key.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
4
5    This file is part of GPGME.
6  
7    GPGME is free software; you can redistribute it and/or modify it
8    under the terms of the GNU Lesser General Public License as
9    published by the Free Software Foundation; either version 2.1 of
10    the License, or (at your option) any later version.
11    
12    GPGME is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16    
17    You should have received a copy of the GNU Lesser General Public
18    License along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
21
22 #if HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "gpgme.h"
29 #include "debug.h"
30 #include "context.h"
31 #include "ops.h"
32
33 \f
34 static gpgme_error_t
35 export_status_handler (void *priv, gpgme_status_code_t code, char *args)
36 {
37   return 0;
38 }
39
40
41 static gpgme_error_t
42 export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,
43               gpgme_export_mode_t mode, gpgme_data_t keydata)
44 {
45   gpgme_error_t err;
46
47   if ((mode & ~(GPGME_EXPORT_MODE_EXTERN)))
48     return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE.  */
49
50   
51   if ((mode & GPGME_EXPORT_MODE_EXTERN))
52     {
53       if (keydata)
54         return gpg_error (GPG_ERR_INV_VALUE);
55     }
56   else
57     {
58       if (!keydata)
59         return gpg_error (GPG_ERR_INV_VALUE);
60     }
61
62   err = _gpgme_op_reset (ctx, synchronous);
63   if (err)
64     return err;
65
66   _gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx);
67
68   return _gpgme_engine_op_export (ctx->engine, pattern, mode, keydata,
69                                   ctx->use_armor);
70 }
71
72
73 /* Export the keys listed in PATTERN into KEYDATA.  */
74 gpgme_error_t
75 gpgme_op_export_start (gpgme_ctx_t ctx, const char *pattern,
76                        gpgme_export_mode_t mode, gpgme_data_t keydata)
77 {
78   TRACE_BEG3 (DEBUG_CTX, "gpgme_op_export_start", ctx,
79               "pattern=%s, mode=0x%x, keydata=%p", pattern, mode, keydata);
80   return TRACE_ERR (export_start (ctx, 0, pattern, mode, keydata));
81 }
82
83
84 /* Export the keys listed in PATTERN into KEYDATA.  */
85 gpgme_error_t
86 gpgme_op_export (gpgme_ctx_t ctx, const char *pattern,
87                  gpgme_export_mode_t mode, gpgme_data_t keydata)
88 {
89   gpgme_error_t err;
90
91   TRACE_BEG3 (DEBUG_CTX, "gpgme_op_export", ctx,
92               "pattern=%s, mode=0x%x, keydata=%p", pattern, mode, keydata);
93
94   err = export_start (ctx, 1, pattern, mode, keydata);
95   if (!err)
96     err = _gpgme_wait_one (ctx);
97   return err;
98 }
99
100 \f
101 static gpgme_error_t
102 export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[],
103                   gpgme_export_mode_t mode, gpgme_data_t keydata)
104 {
105   gpgme_error_t err;
106
107   if ((mode & ~(GPGME_EXPORT_MODE_EXTERN)))
108     return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE.  */
109
110   if ((mode & GPGME_EXPORT_MODE_EXTERN))
111     {
112       if (keydata)
113         return gpg_error (GPG_ERR_INV_VALUE);
114     }
115   else
116     {
117       if (!keydata)
118         return gpg_error (GPG_ERR_INV_VALUE);
119     }
120
121   err = _gpgme_op_reset (ctx, synchronous);
122   if (err)
123     return err;
124
125   _gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx);
126
127   return _gpgme_engine_op_export_ext (ctx->engine, pattern, mode, keydata,
128                                       ctx->use_armor);
129 }
130
131
132 /* Export the keys listed in PATTERN into KEYDATA.  */
133 gpgme_error_t
134 gpgme_op_export_ext_start (gpgme_ctx_t ctx, const char *pattern[],
135                            gpgme_export_mode_t mode, gpgme_data_t keydata)
136 {
137   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_export_ext_start", ctx,
138               "mode=0x%x, keydata=%p", mode, keydata);
139
140   if (_gpgme_debug_trace () && pattern)
141     {
142       int i = 0;
143
144       while (pattern[i])
145         {
146           TRACE_LOG2 ("pattern[%i] = %s", i, pattern[i]);
147           i++;
148         }
149     }
150
151   return TRACE_ERR (export_ext_start (ctx, 0, pattern, mode, keydata));
152 }
153
154
155 /* Export the keys listed in PATTERN into KEYDATA.  */
156 gpgme_error_t
157 gpgme_op_export_ext (gpgme_ctx_t ctx, const char *pattern[],
158                      gpgme_export_mode_t mode, gpgme_data_t keydata)
159 {
160   gpgme_error_t err;
161
162   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_export_ext_start", ctx,
163               "mode=0x%x, keydata=%p", mode, keydata);
164
165   if (_gpgme_debug_trace () && pattern)
166     {
167       int i = 0;
168
169       while (pattern[i])
170         {
171           TRACE_LOG2 ("pattern[%i] = %s", i, pattern[i]);
172           i++;
173         }
174     }
175
176   err = export_ext_start (ctx, 1, pattern, mode, keydata);
177   if (!err)
178     err = _gpgme_wait_one (ctx);
179   return TRACE_ERR (err);
180 }
181
182
183
184 \f
185
186 static gpgme_error_t
187 export_keys_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t keys[],
188                    gpgme_export_mode_t mode, gpgme_data_t keydata)
189 {
190   gpgme_error_t err;
191   int nkeys, idx;
192   char **pattern;
193
194   if (!keys)
195     return gpg_error (GPG_ERR_INV_VALUE);
196
197   /* Create a list of pattern from the keys.  */
198   for (idx=nkeys=0; keys[idx]; idx++)
199     if (keys[idx]->protocol == ctx->protocol)
200       nkeys++;
201   if (!nkeys)
202     return gpg_error (GPG_ERR_NO_DATA);
203   
204   pattern = calloc (nkeys+1, sizeof *pattern);
205   if (!pattern)
206     return gpg_error_from_syserror ();
207
208   for (idx=nkeys=0; keys[idx]; idx++)
209     if (keys[idx]->protocol == ctx->protocol
210         && keys[idx]->subkeys
211         && keys[idx]->subkeys->fpr
212         && *keys[idx]->subkeys->fpr)
213       {
214         pattern[nkeys] = strdup (keys[idx]->subkeys->fpr);
215         if (!pattern[nkeys])
216           {
217             err = gpg_error_from_syserror ();
218             goto leave;
219           }
220         nkeys++;
221       }
222
223
224   /* Pass on to the regular function.  */
225   err = export_ext_start (ctx, synchronous, (const char**)pattern,
226                           mode, keydata);
227
228  leave:
229   for (idx=0; pattern[idx]; idx++)
230     free (pattern[idx]);
231   free (pattern);
232
233   return err;
234 }
235
236
237 /* Export the keys from the array KEYS into KEYDATA.  Only keys of the
238    current protocol are exported and only those which have a
239    fingerprint set; that is keys received with some external search
240    methods are silently skipped.  */
241 gpgme_error_t
242 gpgme_op_export_keys_start (gpgme_ctx_t ctx,
243                             gpgme_key_t keys[],
244                             gpgme_export_mode_t mode,
245                             gpgme_data_t keydata)
246 {
247   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_export_keys_start", ctx,
248               "mode=0x%x, keydata=%p", mode, keydata);
249   
250   if (_gpgme_debug_trace () && keys)
251     {
252       int i = 0;
253
254       while (keys[i])
255         {
256           TRACE_LOG3 ("keys[%i] = %p (%s)", i, keys[i],
257                       (keys[i]->subkeys && keys[i]->subkeys->fpr) ? 
258                       keys[i]->subkeys->fpr : "invalid");
259           i++;
260         }
261     }
262
263   return TRACE_ERR (export_keys_start (ctx, 0, keys, mode, keydata));
264 }
265
266 gpgme_error_t
267 gpgme_op_export_keys (gpgme_ctx_t ctx,
268                       gpgme_key_t keys[],
269                       gpgme_export_mode_t mode,
270                       gpgme_data_t keydata)
271 {
272   gpgme_error_t err;
273
274   TRACE_BEG2 (DEBUG_CTX, "gpgme_op_export_keys", ctx,
275               "mode=0x%x, keydata=%p", mode, keydata);
276   
277   if (_gpgme_debug_trace () && keys)
278     {
279       int i = 0;
280
281       while (keys[i])
282         {
283           TRACE_LOG3 ("keys[%i] = %p (%s)", i, keys[i],
284                       (keys[i]->subkeys && keys[i]->subkeys->fpr) ? 
285                       keys[i]->subkeys->fpr : "invalid");
286           i++;
287         }
288     }
289
290   err = export_keys_start (ctx, 1, keys, mode, keydata);
291   if (!err)
292     err = _gpgme_wait_one (ctx);
293   return err;
294 }
295