1e2943914a7d19ec53f0a2eebdb36ad7936e9ce1
[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 "context.h"
30 #include "ops.h"
31
32 \f
33 static gpgme_error_t
34 export_status_handler (void *priv, gpgme_status_code_t code, char *args)
35 {
36   return 0;
37 }
38
39
40 static gpgme_error_t
41 export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,
42               gpgme_export_mode_t mode, gpgme_data_t keydata)
43 {
44   gpgme_error_t err;
45
46   if ((mode & ~(GPGME_EXPORT_MODE_EXTERN)))
47     return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE.  */
48
49   
50   if ((mode & GPGME_EXPORT_MODE_EXTERN))
51     {
52       if (keydata)
53         return gpg_error (GPG_ERR_INV_VALUE);
54     }
55   else
56     {
57       if (!keydata)
58         return gpg_error (GPG_ERR_INV_VALUE);
59     }
60
61   err = _gpgme_op_reset (ctx, synchronous);
62   if (err)
63     return err;
64
65   _gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx);
66
67   return _gpgme_engine_op_export (ctx->engine, pattern, mode, keydata,
68                                   ctx->use_armor);
69 }
70
71
72 /* Export the keys listed in PATTERN into KEYDATA.  */
73 gpgme_error_t
74 gpgme_op_export_start (gpgme_ctx_t ctx, const char *pattern,
75                        gpgme_export_mode_t mode, gpgme_data_t keydata)
76 {
77   return export_start (ctx, 0, pattern, mode, keydata);
78 }
79
80
81 /* Export the keys listed in PATTERN into KEYDATA.  */
82 gpgme_error_t
83 gpgme_op_export (gpgme_ctx_t ctx, const char *pattern,
84                  gpgme_export_mode_t mode, gpgme_data_t keydata)
85 {
86   gpgme_error_t err = export_start (ctx, 1, pattern, mode, keydata);
87   if (!err)
88     err = _gpgme_wait_one (ctx);
89   return err;
90 }
91
92 \f
93 static gpgme_error_t
94 export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[],
95                   gpgme_export_mode_t mode, gpgme_data_t keydata)
96 {
97   gpgme_error_t err;
98
99   if ((mode & ~(GPGME_EXPORT_MODE_EXTERN)))
100     return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE.  */
101
102   if ((mode & GPGME_EXPORT_MODE_EXTERN))
103     {
104       if (keydata)
105         return gpg_error (GPG_ERR_INV_VALUE);
106     }
107   else
108     {
109       if (!keydata)
110         return gpg_error (GPG_ERR_INV_VALUE);
111     }
112
113   err = _gpgme_op_reset (ctx, synchronous);
114   if (err)
115     return err;
116
117   _gpgme_engine_set_status_handler (ctx->engine, export_status_handler, ctx);
118
119   return _gpgme_engine_op_export_ext (ctx->engine, pattern, mode, keydata,
120                                       ctx->use_armor);
121 }
122
123
124 /* Export the keys listed in PATTERN into KEYDATA.  */
125 gpgme_error_t
126 gpgme_op_export_ext_start (gpgme_ctx_t ctx, const char *pattern[],
127                            gpgme_export_mode_t mode, gpgme_data_t keydata)
128 {
129   return export_ext_start (ctx, 0, pattern, mode, keydata);
130 }
131
132
133 /* Export the keys listed in PATTERN into KEYDATA.  */
134 gpgme_error_t
135 gpgme_op_export_ext (gpgme_ctx_t ctx, const char *pattern[],
136                      gpgme_export_mode_t mode, gpgme_data_t keydata)
137 {
138   gpgme_error_t err = export_ext_start (ctx, 1, pattern, mode, keydata);
139   if (!err)
140     err = _gpgme_wait_one (ctx);
141   return err;
142 }
143
144
145
146 \f
147
148 static gpgme_error_t
149 export_keys_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t keys[],
150                    gpgme_export_mode_t mode, gpgme_data_t keydata)
151 {
152   gpgme_error_t err;
153   int nkeys, idx;
154   char **pattern;
155
156   if (!keys)
157     return gpg_error (GPG_ERR_INV_VALUE);
158
159   /* Create a list of pattern from the keys.  */
160   for (idx=nkeys=0; keys[idx]; idx++)
161     if (keys[idx]->protocol == ctx->protocol)
162       nkeys++;
163   if (!nkeys)
164     return gpg_error (GPG_ERR_NO_DATA);
165   
166   pattern = calloc (nkeys+1, sizeof *pattern);
167   if (!pattern)
168     return gpg_error_from_syserror ();
169
170   for (idx=nkeys=0; keys[idx]; idx++)
171     if (keys[idx]->protocol == ctx->protocol
172         && keys[idx]->subkeys
173         && keys[idx]->subkeys->fpr
174         && *keys[idx]->subkeys->fpr)
175       {
176         pattern[nkeys] = strdup (keys[idx]->subkeys->fpr);
177         if (!pattern[nkeys])
178           {
179             err = gpg_error_from_syserror ();
180             goto leave;
181           }
182         nkeys++;
183       }
184
185
186   /* Pass on to the regular function.  */
187   err = export_ext_start (ctx, synchronous, (const char**)pattern,
188                           mode, keydata);
189
190  leave:
191   for (idx=0; pattern[idx]; idx++)
192     free (pattern[idx]);
193   free (pattern);
194
195   return err;
196 }
197
198
199 /* Export the keys from the array KEYS into KEYDATA.  Only keys of the
200    current protocol are exported and only those which have a
201    fingerprint set; that is keys received with some external search
202    methods are silently skipped.  */
203 gpgme_error_t
204 gpgme_op_export_keys_start (gpgme_ctx_t ctx,
205                             gpgme_key_t keys[],
206                             gpgme_export_mode_t mode,
207                             gpgme_data_t keydata)
208 {
209   return export_keys_start (ctx, 0, keys, mode, keydata);
210 }
211
212 gpgme_error_t
213 gpgme_op_export_keys (gpgme_ctx_t ctx,
214                       gpgme_key_t keys[],
215                       gpgme_export_mode_t mode,
216                       gpgme_data_t keydata)
217 {
218   gpgme_error_t err = export_keys_start (ctx, 1, keys, mode, keydata);
219   if (!err)
220     err = _gpgme_wait_one (ctx);
221   return err;
222 }
223