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