2003-09-14 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / tests / gpg / t-eventloop.c
1 /* t-eventloop.c  - regression test
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003 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 General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (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    General Public License for more details.
16  
17    You should have received a copy of the GNU General Public License
18    along with GPGME; if not, write to the Free Software Foundation,
19    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <assert.h>
25 #include <errno.h>
26 #include <sys/select.h>
27
28 #include <gpgme.h>
29
30 #include "t-support.h"
31
32 \f
33 /* Stripped down version of gpgme/wait.c.  */
34
35 struct op_result
36 {
37   int done;
38   gpgme_error_t err;
39 };
40
41 struct op_result op_result;
42
43 struct one_fd
44 {
45   int fd;
46   int dir;
47   gpgme_io_cb_t fnc;
48   void *fnc_data;
49 };
50
51 #define FDLIST_MAX 32
52 struct one_fd fdlist[FDLIST_MAX];
53
54 gpgme_error_t
55 add_io_cb (void *data, int fd, int dir, gpgme_io_cb_t fnc, void *fnc_data,
56            void **r_tag)
57 {
58   struct one_fd *fds = data;
59   int i;
60
61   for (i = 0; i < FDLIST_MAX; i++)
62     {
63       if (fds[i].fd == -1)
64         {
65           fds[i].fd = fd;
66           fds[i].dir = dir;
67           fds[i].fnc = fnc;
68           fds[i].fnc_data = fnc_data;
69           break;
70         }
71     }
72   if (i == FDLIST_MAX)
73     return gpg_err_make (GPG_ERR_SOURCE_USER_1, GPG_ERR_GENERAL);
74   *r_tag = &fds[i];
75   return 0;
76 }
77
78 void
79 remove_io_cb (void *tag)
80 {
81   struct one_fd *fd = tag;
82
83   fd->fd = -1;
84 }
85
86 void
87 io_event (void *data, gpgme_event_io_t type, void *type_data)
88 {
89   struct op_result *result = data;
90
91   if (type == GPGME_EVENT_DONE)
92     {
93       result->done = 1;
94       result->err = * (gpgme_error_t *) type_data;
95     }
96 }
97
98
99 int
100 do_select (void)
101 {
102   fd_set rfds;
103   fd_set wfds;
104   int i, n;
105   int any = 0;
106
107   FD_ZERO (&rfds);
108   FD_ZERO (&wfds);
109   for (i = 0; i < FDLIST_MAX; i++)
110     if (fdlist[i].fd != -1)
111       FD_SET (fdlist[i].fd, fdlist[i].dir ? &rfds : &wfds);
112
113   do
114     {
115       n = select (FD_SETSIZE, &rfds, &wfds, NULL, 0);
116     }
117   while (n < 0 && errno == EINTR);
118
119   if (n < 0)
120     return n;   /* Error or timeout.  */
121
122   for (i = 0; i < FDLIST_MAX && n; i++)
123     {
124       if (fdlist[i].fd != -1)
125         {
126           if (FD_ISSET (fdlist[i].fd, fdlist[i].dir ? &rfds : &wfds))
127             {
128               assert (n);
129               n--;
130               any = 1;
131               (*fdlist[i].fnc) (fdlist[i].fnc_data, fdlist[i].fd);
132             }
133         }
134     }
135   return any;
136 }
137
138 int
139 my_wait (void)
140 {
141   int n;
142
143   do
144     {
145       n = do_select ();
146     }
147   while (n >= 0 && !op_result.done);
148   return 0;
149 }
150
151
152 struct gpgme_io_cbs io_cbs =
153   {
154     add_io_cb,
155     fdlist,
156     remove_io_cb,
157     io_event,
158     &op_result
159   };
160
161
162 int 
163 main (int argc, char *argv[])
164 {
165   gpgme_ctx_t ctx;
166   gpgme_error_t err;
167   gpgme_data_t in, out;
168   gpgme_key_t key[3] = { NULL, NULL, NULL };
169   int i;
170
171   init_gpgme (GPGME_PROTOCOL_OpenPGP);
172
173   for (i = 0; i < FDLIST_MAX; i++)
174     fdlist[i].fd = -1;
175
176   err = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP);
177   fail_if_err (err);
178
179   err = gpgme_new (&ctx);
180   fail_if_err (err);
181   gpgme_set_armor (ctx, 1);
182   gpgme_set_io_cbs (ctx, &io_cbs);
183   op_result.done = 0;
184
185   err = gpgme_data_new_from_mem (&in, "Hallo Leute\n", 12, 0);
186   fail_if_err (err);
187
188   err = gpgme_data_new (&out);
189   fail_if_err (err);
190
191   err = gpgme_get_key (ctx, "A0FF4590BB6122EDEF6E3C542D727CC768697734",
192                        &key[0], 0);
193   fail_if_err (err);
194   err = gpgme_get_key (ctx, "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2",
195                        &key[1], 0);
196   fail_if_err (err);
197
198   err = gpgme_op_encrypt_start (ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, in, out);
199   fail_if_err (err);
200
201   my_wait ();
202   fail_if_err (op_result.err);
203   fail_if_err (err);
204
205   fflush (NULL);
206   fputs ("Begin Result:\n", stdout);
207   print_data (out);
208   fputs ("End Result.\n", stdout);
209    
210   gpgme_key_unref (key[0]);
211   gpgme_key_unref (key[1]);
212   gpgme_data_release (in);
213   gpgme_data_release (out);
214   gpgme_release (ctx);
215
216   return 0;
217 }