Merge pull request #115 from hfmanson/master
[tlspool] / tool / runterminal-libev.c
1 /* runterminal.c -- shared testing code loop for message loop */
2
3 /* runterminal-libev.c is a variant that uses libev instead of poll() */
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdint.h>
9
10 #include <unistd.h>
11 #include <poll.h>
12 #include <errno.h>
13 #include <signal.h>
14
15 #include <sys/socket.h>
16 #include <netinet/in.h>
17
18 #include <tlspool/starttls.h>
19
20 #include <ev.h>
21
22
23 int           chanio_global = -1;
24 starttls_t  *tlsdata_global = NULL;
25 uint32_t  startflags_global = 0;
26 const char  *localid_global = "";
27 const char *remoteid_global = "";
28
29
30 static void keys_cb (EV_P_ ev_io *evt, int revents) {
31         ssize_t sz;
32         char buf [512];
33         if (revents & EV_ERROR) {
34                 ev_break (EV_A_ EVBREAK_ALL);
35         }
36         sz = read (0, buf, sizeof (buf));
37         printf ("Read %ld bytes\n", sz);
38         if (sz == -1) {
39                 ev_break (EV_A_ EVBREAK_ALL);
40         } else if (sz == 0) {
41                 errno = 0;
42                 ev_break (EV_A_ EVBREAK_ALL);
43         } else if (send (chanio_global, buf, sz, MSG_DONTWAIT) != sz) {
44                 ev_break (EV_A_ EVBREAK_ALL);
45         } else {
46                 printf ("Sent %ld bytes\n", sz);
47         }
48 }
49
50
51 static void chan_cb (EV_P_ ev_io *evt, int revents) {
52         ssize_t sz;
53         char buf [512];
54         if (revents & EV_ERROR) {
55                 ev_break (EV_A_ EVBREAK_ALL);
56         }
57         sz = recv (chanio_global, buf, sizeof (buf), MSG_DONTWAIT);
58         printf ("Received %ld bytes\n", sz);
59         if (sz == -1) {
60                 ev_break (EV_A_ EVBREAK_ALL);
61         } else if (sz == 0) {
62                 errno = 0;
63                 ev_break (EV_A_ EVBREAK_ALL);
64         } else if (write (1, buf, sz) != sz) {
65                 ev_break (EV_A_ EVBREAK_ALL);
66         } else {
67                 printf ("Printed %ld bytes\n", sz);
68         }
69 }
70
71
72 static void cont_cb (EV_P_ ev_signal *sig, int revents) {
73         if (revents & EV_ERROR) {
74                 ev_break (EV_A_ EVBREAK_ALL);
75         }
76         printf ("Received SIGCONT, will now initiate TLS handshake renegotiation\n");
77         tlsdata_global->flags = startflags_global;
78         if (localid_global)
79                 strcpy (tlsdata_global->localid, localid_global);
80         if (remoteid_global)
81                 strcpy (tlsdata_global->remoteid, remoteid_global);
82         if (-1 == tlspool_starttls (-1, tlsdata_global, NULL, NULL)) {
83                 printf ("TLS handshake renegotiation failed, terminating\n");
84                 ev_break (EV_A_ EVBREAK_ALL);
85         }
86         printf ("TLS handshake renegotiation completed successfully\n");
87 }
88
89
90 void runterminal (int chanio, int *sigcont, starttls_t *tlsdata,
91                   uint32_t startflags, const char *localid, const char *remoteid) {
92         struct ev_loop *loop = EV_DEFAULT;
93         ev_io     keys;
94         ev_io     chan;
95         ev_signal cont;
96         //
97         // Make parameters tlsdata globally known (imperfect solution)
98         chanio_global     = chanio;
99         tlsdata_global    = tlsdata;
100         startflags_global = startflags;
101         localid_global    = localid;
102         remoteid_global   = remoteid;
103         //
104         // Initialise event handler structures
105         ev_io_init     (&keys, keys_cb, 0,      EV_READ);
106         ev_io_init     (&chan, chan_cb, chanio, EV_READ);
107         ev_signal_init (&cont, cont_cb, SIGCONT);
108         //
109         // Start event handlers
110         ev_io_start     (loop, &keys);
111         ev_io_start     (loop, &chan);
112         ev_signal_start (loop, &cont);
113         //
114         // Run the event loop
115         ev_run (loop, 0);
116 }