This repository has been archived by the owner on Apr 19, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 95
/
ldisc.c
137 lines (127 loc) · 3.27 KB
/
ldisc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <windows.h>
#include <stdio.h>
#include <ctype.h>
#include "putty.h"
/*
* ldisc.c: PuTTY line disciplines
*/
static void c_write (char *buf, int len) {
while (len--) {
int new_head = (inbuf_head + 1) & INBUF_MASK;
if (new_head != inbuf_reap) {
inbuf[inbuf_head] = *buf++;
inbuf_head = new_head;
}
}
}
static char *term_buf = NULL;
static int term_buflen = 0, term_bufsiz = 0, term_quotenext = 0;
static int plen(unsigned char c) {
if ((c >= 32 && c <= 126) ||
(c >= 160))
return 1;
else if (c < 128)
return 2; /* ^x for some x */
else
return 4; /* <XY> for hex XY */
}
static void pwrite(unsigned char c) {
if ((c >= 32 && c <= 126) ||
(c >= 160)) {
char cc = (char)c;
c_write(&cc, 1);
} else if (c < 128) {
char cc[2];
cc[1] = (c == 127 ? '?' : c + 0x40);
cc[0] = '^';
c_write(cc, 2);
} else {
char cc[5];
sprintf(cc, "<%02X>", c);
c_write(cc, 4);
}
}
static void bsb(int n) {
while (n--)
c_write("\010 \010", 3);
}
static void term_send(char *buf, int len) {
while (len--) {
char c;
c = *buf++;
switch (term_quotenext ? ' ' : c) {
/*
* ^h/^?: delete one char and output one BSB
* ^w: delete, and output BSBs, to return to last space/nonspace
* boundary
* ^u: delete, and output BSBs, to return to BOL
* ^r: echo "^R\n" and redraw line
* ^v: quote next char
* ^d: if at BOL, end of file and close connection, else send line
* and reset to BOL
* ^m/^j: send line-plus-\r\n and reset to BOL
*/
case 8: case 127: /* backspace/delete */
if (term_buflen > 0) {
bsb(plen(term_buf[term_buflen-1]));
term_buflen--;
}
break;
case 23: /* ^W delete word */
while (term_buflen > 0) {
bsb(plen(term_buf[term_buflen-1]));
term_buflen--;
if (term_buflen > 0 &&
isspace(term_buf[term_buflen-1]) &&
!isspace(term_buf[term_buflen]))
break;
}
break;
case 21: /* ^U delete line */
while (term_buflen > 0) {
bsb(plen(term_buf[term_buflen-1]));
term_buflen--;
}
break;
case 18: /* ^R redraw line */
c_write("^R\r\n", 4);
{
int i;
for (i = 0; i < term_buflen; i++)
pwrite(term_buf[i]);
}
break;
case 22: /* ^V quote next char */
term_quotenext = TRUE;
break;
case 4: /* ^D logout or send */
if (term_buflen == 0) {
/* FIXME: eof */;
} else {
back->send(term_buf, term_buflen);
term_buflen = 0;
}
break;
case 13: case 10: /* ^M/^J send with newline */
back->send(term_buf, term_buflen);
back->send("\r\n", 2);
c_write("\r\n", 2);
term_buflen = 0;
break;
default: /* get to this label from ^V handler */
if (term_buflen >= term_bufsiz) {
term_bufsiz = term_buflen + 256;
term_buf = saferealloc(term_buf, term_bufsiz);
}
term_buf[term_buflen++] = c;
pwrite(c);
term_quotenext = FALSE;
break;
}
}
}
static void simple_send(char *buf, int len) {
back->send(buf, len);
}
Ldisc ldisc_term = { term_send };
Ldisc ldisc_simple = { simple_send };