Major destabilisation, phase 2. This time it's the backends' turn:
[u/mdw/putty] / raw.c
1 #include <windows.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 #include "putty.h"
6
7 #ifndef FALSE
8 #define FALSE 0
9 #endif
10 #ifndef TRUE
11 #define TRUE 1
12 #endif
13
14 #define RAW_MAX_BACKLOG 4096
15
16 typedef struct raw_backend_data {
17 const struct plug_function_table *fn;
18 /* the above field _must_ be first in the structure */
19
20 Socket s;
21 int bufsize;
22 void *frontend;
23 } *Raw;
24
25 static void raw_size(void *handle, int width, int height);
26
27 static void c_write(Raw raw, char *buf, int len)
28 {
29 int backlog = from_backend(raw->frontend, 0, buf, len);
30 sk_set_frozen(raw->s, backlog > RAW_MAX_BACKLOG);
31 }
32
33 static int raw_closing(Plug plug, char *error_msg, int error_code,
34 int calling_back)
35 {
36 Raw raw = (Raw) plug;
37
38 if (raw->s) {
39 sk_close(raw->s);
40 raw->s = NULL;
41 }
42 if (error_msg) {
43 /* A socket error has occurred. */
44 logevent(error_msg);
45 connection_fatal("%s", error_msg);
46 } /* Otherwise, the remote side closed the connection normally. */
47 return 0;
48 }
49
50 static int raw_receive(Plug plug, int urgent, char *data, int len)
51 {
52 Raw raw = (Raw) plug;
53 c_write(raw, data, len);
54 return 1;
55 }
56
57 static void raw_sent(Plug plug, int bufsize)
58 {
59 Raw raw = (Raw) plug;
60 raw->bufsize = bufsize;
61 }
62
63 /*
64 * Called to set up the raw connection.
65 *
66 * Returns an error message, or NULL on success.
67 *
68 * Also places the canonical host name into `realhost'. It must be
69 * freed by the caller.
70 */
71 static char *raw_init(void *frontend_handle, void **backend_handle,
72 char *host, int port, char **realhost, int nodelay)
73 {
74 static const struct plug_function_table fn_table = {
75 raw_closing,
76 raw_receive,
77 raw_sent
78 };
79 SockAddr addr;
80 char *err;
81 Raw raw;
82
83 raw = smalloc(sizeof(*raw));
84 raw->fn = &fn_table;
85 raw->s = NULL;
86 *backend_handle = raw;
87
88 raw->frontend = frontend_handle;
89
90 /*
91 * Try to find host.
92 */
93 {
94 char buf[200];
95 sprintf(buf, "Looking up host \"%.170s\"", host);
96 logevent(buf);
97 }
98 addr = sk_namelookup(host, realhost);
99 if ((err = sk_addr_error(addr)))
100 return err;
101
102 if (port < 0)
103 port = 23; /* default telnet port */
104
105 /*
106 * Open socket.
107 */
108 {
109 char buf[200], addrbuf[100];
110 sk_getaddr(addr, addrbuf, 100);
111 sprintf(buf, "Connecting to %.100s port %d", addrbuf, port);
112 logevent(buf);
113 }
114 raw->s = new_connection(addr, *realhost, port, 0, 1, nodelay, (Plug) raw);
115 if ((err = sk_socket_error(raw->s)))
116 return err;
117
118 sk_addr_free(addr);
119
120 return NULL;
121 }
122
123 /*
124 * Called to send data down the raw connection.
125 */
126 static int raw_send(void *handle, char *buf, int len)
127 {
128 Raw raw = (Raw) handle;
129
130 if (raw->s == NULL)
131 return 0;
132
133 raw->bufsize = sk_write(raw->s, buf, len);
134
135 return raw->bufsize;
136 }
137
138 /*
139 * Called to query the current socket sendability status.
140 */
141 static int raw_sendbuffer(void *handle)
142 {
143 Raw raw = (Raw) handle;
144 return raw->bufsize;
145 }
146
147 /*
148 * Called to set the size of the window
149 */
150 static void raw_size(void *handle, int width, int height)
151 {
152 /* Do nothing! */
153 return;
154 }
155
156 /*
157 * Send raw special codes.
158 */
159 static void raw_special(void *handle, Telnet_Special code)
160 {
161 /* Do nothing! */
162 return;
163 }
164
165 static Socket raw_socket(void *handle)
166 {
167 Raw raw = (Raw) handle;
168 return raw->s;
169 }
170
171 static int raw_sendok(void *handle)
172 {
173 return 1;
174 }
175
176 static void raw_unthrottle(void *handle, int backlog)
177 {
178 Raw raw = (Raw) handle;
179 sk_set_frozen(raw->s, backlog > RAW_MAX_BACKLOG);
180 }
181
182 static int raw_ldisc(void *handle, int option)
183 {
184 if (option == LD_EDIT || option == LD_ECHO)
185 return 1;
186 return 0;
187 }
188
189 static int raw_exitcode(void *handle)
190 {
191 /* Exit codes are a meaningless concept in the Raw protocol */
192 return 0;
193 }
194
195 Backend raw_backend = {
196 raw_init,
197 raw_send,
198 raw_sendbuffer,
199 raw_size,
200 raw_special,
201 raw_socket,
202 raw_exitcode,
203 raw_sendok,
204 raw_ldisc,
205 raw_unthrottle,
206 1
207 };