Detect and bailo out on double plaintext messages.
[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, 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 /* We need to include config.h so that we know whether we are building
23    with large file system (LFS) support. */
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <assert.h>
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <sys/select.h>
35
36 #include <gpgme.h>
37
38 #include "t-support.h"
39
40 \f
41 /* Stripped down version of gpgme/wait.c.  */
42
43 struct op_result
44 {
45   int done;
46   gpgme_error_t err;
47 };
48
49 struct op_result op_result;
50
51 struct one_fd
52 {
53   int fd;
54   int dir;
55   gpgme_io_cb_t fnc;
56   void *fnc_data;
57 };
58
59 #define FDLIST_MAX 32
60 struct one_fd fdlist[FDLIST_MAX];
61
62 gpgme_error_t
63 add_io_cb (void *data, int fd, int dir, gpgme_io_cb_t fnc, void *fnc_data,
64            void **r_tag)
65 {
66   struct one_fd *fds = data;
67   int i;
68
69   for (i = 0; i < FDLIST_MAX; i++)
70     {
71       if (fds[i].fd == -1)
72         {
73           fds[i].fd = fd;
74           fds[i].dir = dir;
75           fds[i].fnc = fnc;
76           fds[i].fnc_data = fnc_data;
77           break;
78         }
79     }
80   if (i == FDLIST_MAX)
81     return gpg_err_make (GPG_ERR_SOURCE_USER_1, GPG_ERR_GENERAL);
82   *r_tag = &fds[i];
83   return 0;
84 }
85
86 void
87 remove_io_cb (void *tag)
88 {
89   struct one_fd *fd = tag;
90
91   fd->fd = -1;
92 }
93
94 void
95 io_event (void *data, gpgme_event_io_t type, void *type_data)
96 {
97   struct op_result *result = data;
98
99   if (type == GPGME_EVENT_DONE)
100     {
101       result->done = 1;
102       result->err = * (gpgme_error_t *) type_data;
103     }
104 }
105
106
107 int
108 do_select (void)
109 {
110   fd_set rfds;
111   fd_set wfds;
112   int i, n;
113   int any = 0;
114
115   FD_ZERO (&rfds);
116   FD_ZERO (&wfds);
117   for (i = 0; i < FDLIST_MAX; i++)
118     if (fdlist[i].fd != -1)
119       FD_SET (fdlist[i].fd, fdlist[i].dir ? &rfds : &wfds);
120
121   do
122     {
123       n = select (FD_SETSIZE, &rfds, &wfds, NULL, 0);
124     }
125   while (n < 0 && errno == EINTR);
126
127   if (n < 0)
128     return n;   /* Error or timeout.  */
129
130   for (i = 0; i < FDLIST_MAX && n; i++)
131     {
132       if (fdlist[i].fd != -1)
133         {
134           if (FD_ISSET (fdlist[i].fd, fdlist[i].dir ? &rfds : &wfds))
135             {
136               assert (n);
137               n--;
138               any = 1;
139               (*fdlist[i].fnc) (fdlist[i].fnc_data, fdlist[i].fd);
140             }
141         }
142     }
143   return any;
144 }
145
146 int
147 my_wait (void)
148 {
149   int n;
150
151   do
152     {
153       n = do_select ();
154     }
155   while (n >= 0 && !op_result.done);
156   return 0;
157 }
158
159
160 struct gpgme_io_cbs io_cbs =
161   {
162     add_io_cb,
163     fdlist,
164     remove_io_cb,
165     io_event,
166     &op_result
167   };
168
169
170 int 
171 main (int argc, char *argv[])
172 {
173   gpgme_ctx_t ctx;
174   gpgme_error_t err;
175   gpgme_data_t in, out;
176   gpgme_key_t key[3] = { NULL, NULL, NULL };
177   int i;
178
179   init_gpgme (GPGME_PROTOCOL_OpenPGP);
180
181   for (i = 0; i < FDLIST_MAX; i++)
182     fdlist[i].fd = -1;
183
184   err = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP);
185   fail_if_err (err);
186
187   err = gpgme_new (&ctx);
188   fail_if_err (err);
189   gpgme_set_armor (ctx, 1);
190   gpgme_set_io_cbs (ctx, &io_cbs);
191   op_result.done = 0;
192
193   err = gpgme_data_new_from_mem (&in, "Hallo Leute\n", 12, 0);
194   fail_if_err (err);
195
196   err = gpgme_data_new (&out);
197   fail_if_err (err);
198
199   err = gpgme_get_key (ctx, "A0FF4590BB6122EDEF6E3C542D727CC768697734",
200                        &key[0], 0);
201   fail_if_err (err);
202   err = gpgme_get_key (ctx, "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2",
203                        &key[1], 0);
204   fail_if_err (err);
205
206   err = gpgme_op_encrypt_start (ctx, key, GPGME_ENCRYPT_ALWAYS_TRUST, in, out);
207   fail_if_err (err);
208
209   my_wait ();
210   fail_if_err (op_result.err);
211   fail_if_err (err);
212
213   fflush (NULL);
214   fputs ("Begin Result:\n", stdout);
215   print_data (out);
216   fputs ("End Result.\n", stdout);
217    
218   gpgme_key_unref (key[0]);
219   gpgme_key_unref (key[1]);
220   gpgme_data_release (in);
221   gpgme_data_release (out);
222   gpgme_release (ctx);
223
224   return 0;
225 }