First take on the low-level assuan interface.
[gpgme.git] / src / opassuan.c
1 /* opassuan.c - Low-level Assuan operations.
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, see <http://www.gnu.org/licenses/>.
18  */
19
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include "gpgme.h"
25 #include "context.h"
26 #include "ops.h"
27 #include "util.h"
28
29 typedef struct
30 {
31   /* The result of the assuan command with 0 for OK and an error value
32      for ERR.  */
33   gpgme_error_t result;
34 } *op_data_t;
35
36
37
38 \f
39 /* This callback is used to return the status of the assuan command
40    back.  Note that this is different from the error code returned
41    from gpgme_op_assuan_transact because the later only reflects error
42    with the connection.  */
43 static gpgme_error_t
44 result_cb (void *priv, gpgme_error_t result)
45 {
46   gpgme_ctx_t ctx = (gpgme_ctx_t)priv;
47   gpgme_error_t err;
48   void *hook;
49   op_data_t opd;
50
51   err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL);
52   opd = hook;
53   if (err)
54     return err;
55   if (!opd)
56     return gpg_error (GPG_ERR_INTERNAL);
57
58   opd->result = result;
59   return 0;
60 }
61
62
63 gpgme_error_t
64 gpgme_op_assuan_result (gpgme_ctx_t ctx)
65 {
66   gpgme_error_t err;
67   void *hook;
68   op_data_t opd;
69
70   err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL);
71   opd = hook;
72   if (err)
73     return err;
74   if (!opd)
75     return gpg_error (GPG_ERR_INTERNAL);
76
77   return opd->result;
78 }
79
80
81 static gpgme_error_t
82 opassuan_start (gpgme_ctx_t ctx, int synchronous,
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 {
91   gpgme_error_t err;
92   void *hook;
93   op_data_t opd;
94
95   if (!command || !*command)
96     return gpg_error (GPG_ERR_INV_VALUE);
97
98   /* The flag value 256 is used to suppress an engine reset.  This is
99      required to keep the connection running.  */
100   err = _gpgme_op_reset (ctx, ((synchronous&255) | 256));
101   if (err)
102     return err;
103
104   err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, sizeof (*opd), NULL);
105   opd = hook;
106   if (err)
107     return err;
108   opd->result = gpg_error (GPG_ERR_UNFINISHED);
109
110   return _gpgme_engine_op_assuan_transact (ctx->engine, command,
111                                            result_cb, ctx,
112                                            data_cb, data_cb_value,
113                                            inq_cb, inq_cb_value,
114                                            status_cb, status_cb_value);
115 }
116
117
118
119 /* XXXX.  This is the asynchronous variant. */
120 gpgme_error_t
121 gpgme_op_assuan_transact_start (gpgme_ctx_t ctx, 
122                                 const char *command,
123                                 gpgme_assuan_data_cb_t data_cb,
124                                 void *data_cb_value,
125                                 gpgme_assuan_inquire_cb_t inq_cb,
126                                 void *inq_cb_value,
127                                 gpgme_assuan_status_cb_t status_cb,
128                                 void *status_cb_value)
129 {
130   return opassuan_start (ctx, 0, command, 
131                          data_cb, data_cb_value,
132                          inq_cb, inq_cb_value,
133                          status_cb, status_cb_value);
134 }
135
136
137 /* XXXX.  This is the synchronous variant. */
138 gpgme_error_t
139 gpgme_op_assuan_transact (gpgme_ctx_t ctx,
140                           const char *command,
141                           gpgme_assuan_data_cb_t data_cb,
142                           void *data_cb_value,
143                           gpgme_assuan_inquire_cb_t inq_cb,
144                           void *inq_cb_value,
145                           gpgme_assuan_status_cb_t status_cb,
146                           void *status_cb_value)
147 {
148   gpgme_error_t err;
149
150   err = opassuan_start (ctx, 1, command, 
151                         data_cb, data_cb_value,
152                         inq_cb, inq_cb_value,
153                         status_cb, status_cb_value);
154   if (!err)
155     err = _gpgme_wait_one (ctx);
156   return err;
157 }
158