]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - raw.c
Major destabilisation, phase 2. This time it's the backends' turn:
[PuTTY.git] / 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 };