updated docs
[rlserver.git] / telnet.c
blob6fd48ddeaaaedfad42d71de52b90270e02a11d4d
1 #include <stdint.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <sys/socket.h>
5 #include <pty.h>
6 #include "sessions.h"
7 #include "telnet.h"
10 int translate_telnet_input (char *cbuf, int len, session_info *sess)
12 uint8_t * const buf = (uint8_t*)cbuf;
15 int i = 0, j = 0;
16 while (i < len)
18 // CR
19 if (buf[i] == '\r')
21 // translate it to LF
22 buf[j++] = '\n';
24 if (++i >= len) break; // XXX
26 // CR LF and CR 0 are translated to LF
27 // translation is already done, so we only have to skip it here
28 if (buf[i] == '\n' || buf[i] == 0) i++;
30 continue;
33 // telnet command
34 if (buf[i] == TN_IAC)
36 if (++i >= len) break; // XXX
38 // it's just an escaped data octet
39 if (buf[i] == TN_IAC)
41 buf[j++] = buf[i++];
42 continue;
45 // some confirmation
46 if (buf[i] == TN_WILL || buf[i] == TN_DO)
48 i += 2; // XXX just skip it for now
51 // something is rejected
52 if (buf[i] == TN_WONT || buf[i] == TN_DONT)
54 i += 2; // XXX just skip it for now
57 // some subsection begins
58 if (buf[i] == TN_SB)
60 if (++i >= len) break; // XXX
62 // terminal window size
63 if (buf[i] == TN_NAWS)
65 struct winsize ws;
66 int n1, n2;
68 i++;
70 n1 = buf[i++];
71 if (n1 == TN_IAC) n1 = buf[i++];
72 n2 = buf[i++];
73 if (n2 == TN_IAC) n2 = buf[i++];
74 ws.ws_col = (n1 << 8) | n2;
76 n1 = buf[i++];
77 if (n1 == TN_IAC) n1 = buf[i++];
78 n2 = buf[i++];
79 if (n2 == TN_IAC) n2 = buf[i++];
80 ws.ws_row = (n1 << 8) | n2;
82 if (i + 2 > len) break; // XXX
84 // skip IAC SE
85 i += 2;
86 if (sess != NULL)
88 if (sess->pty_master >= 0)
90 ioctl (sess->pty_master, TIOCSWINSZ, &ws);
93 // do not lock mutex, it should be safe
94 sess->term_wid = ws.ws_col;
95 sess->term_hgt = ws.ws_row;
98 continue;
101 // XXX
104 continue;
107 // an ordinary octet, just copy it
108 buf[j++] = buf[i++];
111 return j;
116 void send_telnet_init (int sck)
118 uint8_t req[] =
120 TN_IAC, TN_WILL, TN_SUPPRESS_GA, // enable full-duplex mode (RFC 858)
121 TN_IAC, TN_DO, TN_NAWS, // request window size info (RFC 1073)
122 TN_IAC, TN_WILL, TN_ECHO // request to disable local echo (RFC 857)
124 send (sck, req, sizeof(req), 0);