Various bug/warning fixes from Jacob
[u/mdw/putty] / rlogin.c
1 #include <windows.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <ctype.h>
5
6 #include "putty.h"
7
8 #ifndef FALSE
9 #define FALSE 0
10 #endif
11 #ifndef TRUE
12 #define TRUE 1
13 #endif
14
15 static Socket s = NULL;
16
17 static void rlogin_size(void);
18
19 static int sb_opt, sb_len;
20 static char *sb_buf = NULL;
21 static int sb_size = 0;
22 #define SB_DELTA 1024
23
24 static void c_write (char *buf, int len) {
25 from_backend(0, buf, len);
26 }
27
28 static int rlogin_receive (Socket skt, int urgent, char *data, int len) {
29 if (urgent==3) {
30 /* A socket error has occurred. */
31 sk_close(s);
32 s = NULL;
33 connection_fatal(data);
34 return 0;
35 } else if (!len) {
36 /* Connection has closed. */
37 sk_close(s);
38 s = NULL;
39 return 0;
40 }
41 if (urgent == 2) {
42 char c;
43
44 c = *data++; len--;
45 if (c == '\x80')
46 rlogin_size();
47 /*
48 * We should flush everything (aka Telnet SYNCH) if we see
49 * 0x02, and we should turn off and on _local_ flow control
50 * on 0x10 and 0x20 respectively. I'm not convinced it's
51 * worth it...
52 */
53 } else {
54 /*
55 * Main rlogin protocol. This is really simple: the first
56 * byte is expected to be NULL and is ignored, and the rest
57 * is printed.
58 */
59 static int firstbyte = 1;
60 if (firstbyte) {
61 if (data[0] == '\0') {
62 data++;
63 len--;
64 }
65 firstbyte = 0;
66 }
67 c_write(data, len);
68 }
69 return 1;
70 }
71
72 /*
73 * Called to set up the rlogin connection.
74 *
75 * Returns an error message, or NULL on success.
76 *
77 * Also places the canonical host name into `realhost'.
78 */
79 static char *rlogin_init (char *host, int port, char **realhost) {
80 SockAddr addr;
81 char *err;
82
83 /*
84 * Try to find host.
85 */
86 addr = sk_namelookup(host, realhost);
87 if ( (err = sk_addr_error(addr)) )
88 return err;
89
90 if (port < 0)
91 port = 513; /* default rlogin port */
92
93 /*
94 * Open socket.
95 */
96 s = sk_new(addr, port, 1, 0, rlogin_receive);
97 if ( (err = sk_socket_error(s)) )
98 return err;
99
100 sk_addr_free(addr);
101
102 /*
103 * Send local username, remote username, terminal/speed
104 */
105
106 {
107 char z = 0;
108 char *p;
109 sk_write(s, &z, 1);
110 sk_write(s, cfg.localusername, strlen(cfg.localusername));
111 sk_write(s, &z, 1);
112 sk_write(s, cfg.username, strlen(cfg.username));
113 sk_write(s, &z, 1);
114 sk_write(s, cfg.termtype, strlen(cfg.termtype));
115 sk_write(s, "/", 1);
116 for(p = cfg.termspeed; isdigit(*p); p++);
117 sk_write(s, cfg.termspeed, p - cfg.termspeed);
118 sk_write(s, &z, 1);
119 }
120
121 return NULL;
122 }
123
124 /*
125 * Called to send data down the rlogin connection.
126 */
127 static void rlogin_send (char *buf, int len) {
128
129 if (s == NULL)
130 return;
131
132 sk_write(s, buf, len);
133 }
134
135 /*
136 * Called to set the size of the window
137 */
138 static void rlogin_size(void) {
139 char b[12] = { '\xFF', '\xFF', 0x73, 0x73, 0, 0, 0, 0, 0, 0, 0, 0 };
140
141 b[6] = cols >> 8; b[7] = cols & 0xFF;
142 b[4] = rows >> 8; b[5] = rows & 0xFF;
143 sk_write(s, b, 12);
144 return;
145 }
146
147 /*
148 * Send rlogin special codes.
149 */
150 static void rlogin_special (Telnet_Special code) {
151 /* Do nothing! */
152 return;
153 }
154
155 static Socket rlogin_socket(void) { return s; }
156
157 static int rlogin_sendok(void) { return 1; }
158
159 static int rlogin_ldisc(int option) {
160 return 0;
161 }
162
163 Backend rlogin_backend = {
164 rlogin_init,
165 rlogin_send,
166 rlogin_size,
167 rlogin_special,
168 rlogin_socket,
169 rlogin_sendok,
170 rlogin_ldisc,
171 1
172 };