w32: Remove all support for WindowsCE
[gpgme.git] / src / vfs-create.c
1 /* vfs-create.c - vfs create support in GPGME
2    Copyright (C) 2009 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
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 #include "util.h"
33
34 static gpgme_error_t
35 vfs_start (gpgme_ctx_t ctx, int synchronous,
36            const char *command,
37            gpgme_assuan_data_cb_t data_cb,
38            void *data_cb_value,
39            gpgme_assuan_inquire_cb_t inq_cb,
40            void *inq_cb_value,
41            gpgme_assuan_status_cb_t status_cb,
42            void *status_cb_value)
43 {
44   gpgme_error_t err;
45
46   if (!command || !*command)
47     return gpg_error (GPG_ERR_INV_VALUE);
48
49   /* The flag value 256 is used to suppress an engine reset.  This is
50      required to keep the connection running.  */
51   err = _gpgme_op_reset (ctx, ((synchronous & 255) | 256));
52   if (err)
53     return err;
54
55   return _gpgme_engine_op_assuan_transact (ctx->engine, command,
56                                            data_cb, data_cb_value,
57                                            inq_cb, inq_cb_value,
58                                            status_cb, status_cb_value);
59 }
60
61
62 #if 0
63 /* XXXX.  This is the asynchronous variant. */
64 static gpgme_error_t
65 gpgme_op_vfs_transact_start (gpgme_ctx_t ctx,
66                              const char *command,
67                              gpgme_assuan_data_cb_t data_cb,
68                              void *data_cb_value,
69                              gpgme_assuan_inquire_cb_t inq_cb,
70                              void *inq_cb_value,
71                              gpgme_assuan_status_cb_t status_cb,
72                              void *status_cb_value)
73 {
74   return vfs_start (ctx, 0, command, data_cb, data_cb_value,
75                     inq_cb, inq_cb_value, status_cb, status_cb_value);
76 }
77 #endif
78
79
80 /* XXXX.  This is the synchronous variant. */
81 static gpgme_error_t
82 gpgme_op_vfs_transact (gpgme_ctx_t ctx,
83                        const char *command,
84                        gpgme_assuan_data_cb_t data_cb,
85                        void *data_cb_value,
86                        gpgme_assuan_inquire_cb_t inq_cb,
87                        void *inq_cb_value,
88                        gpgme_assuan_status_cb_t status_cb,
89                        void *status_cb_value,
90                        gpgme_error_t *op_err)
91 {
92   gpgme_error_t err;
93
94   if (!ctx)
95     return gpg_error (GPG_ERR_INV_VALUE);
96
97   err = vfs_start (ctx, 1, command, data_cb, data_cb_value,
98                    inq_cb, inq_cb_value, status_cb, status_cb_value);
99   if (!err)
100     err = _gpgme_wait_one_ext (ctx, op_err);
101   return err;
102 }
103
104 \f
105 /* The actual exported interface follows.  */
106
107 /* The container is automatically uncreateed when the context is reset
108    or destroyed.  This is a synchronous convenience interface, which
109    automatically returns an operation error if there is no
110    transmission error.  */
111 static gpgme_error_t
112 _gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
113                       const char *container_file, unsigned int flags,
114                       gpgme_error_t *op_err)
115 {
116   gpg_error_t err;
117   char *cmd;
118   char *container_file_esc = NULL;
119   int i;
120
121   (void)flags;
122
123   /* We want to encourage people to check error values, so not getting
124      them is discouraged here.  Also makes our code easier.  */
125   if (! op_err)
126     return gpg_error (GPG_ERR_INV_VALUE);
127
128   err = _gpgme_encode_percent_string (container_file, &container_file_esc, 0);
129   if (err)
130     return err;
131
132   i = 0;
133   while (!err && recp[i])
134     {
135       if (!recp[i]->subkeys || !recp[i]->subkeys->fpr)
136         {
137           free (container_file_esc);
138           return gpg_error (GPG_ERR_UNUSABLE_PUBKEY);
139         }
140
141       if (gpgrt_asprintf (&cmd, "RECIPIENT %s", recp[i]->subkeys->fpr) < 0)
142         {
143           err = gpg_error_from_syserror ();
144           free (container_file_esc);
145           return err;
146         }
147
148       err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
149                                    NULL, NULL, op_err);
150       gpgrt_free (cmd);
151       if (err || *op_err)
152         {
153           free (container_file_esc);
154           return err;
155         }
156       recp++;
157     }
158
159   if (gpgrt_asprintf (&cmd, "CREATE -- %s", container_file_esc) < 0)
160     {
161       err = gpg_error_from_syserror ();
162       free (container_file_esc);
163       return err;
164     }
165   free (container_file_esc);
166
167   err = gpgme_op_vfs_transact (ctx, cmd, NULL, NULL, NULL, NULL,
168                                NULL, NULL, op_err);
169   gpgrt_free (cmd);
170
171   return err;
172 }
173
174
175 gpgme_error_t
176 gpgme_op_vfs_create (gpgme_ctx_t ctx, gpgme_key_t recp[],
177                       const char *container_file, unsigned int flags,
178                       gpgme_error_t *op_err)
179 {
180   gpg_error_t err;
181
182   TRACE_BEG3 (DEBUG_CTX, "gpgme_op_vfs_create", ctx,
183               "container_file=%s, flags=0x%x, op_err=%p",
184               container_file, flags, op_err);
185
186   if (!ctx)
187     return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
188
189   if (_gpgme_debug_trace () && recp)
190     {
191       int i = 0;
192
193       while (recp[i])
194         {
195           TRACE_LOG3 ("recipient[%i] = %p (%s)", i, recp[i],
196                       (recp[i]->subkeys && recp[i]->subkeys->fpr) ?
197                       recp[i]->subkeys->fpr : "invalid");
198           i++;
199         }
200     }
201
202   err = _gpgme_op_vfs_create (ctx, recp, container_file, flags, op_err);
203   return TRACE_ERR (err);
204 }
205