projects
/
u
/
mdw
/
putty
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
SCO ACS part 2 (ESC[12m) apparently puts the top half of CP437 into
[u/mdw/putty]
/
telnet.c
diff --git
a/telnet.c
b/telnet.c
index
f20488e
..
9d82509
100644
(file)
--- a/
telnet.c
+++ b/
telnet.c
@@
-86,7
+86,9
@@
#define LF 10
#define NUL 0
#define LF 10
#define NUL 0
-#define iswritable(x) ( (x) != IAC && (x) != CR )
+#define iswritable(x) \
+ ( (x) != IAC && \
+ (telnet->opt_states[o_we_bin.index] == ACTIVE || (x) != CR))
static char *telopt(int opt)
{
static char *telopt(int opt)
{
@@
-157,6
+159,8
@@
enum {
OPTINDEX_ECHO,
OPTINDEX_WE_SGA,
OPTINDEX_THEY_SGA,
OPTINDEX_ECHO,
OPTINDEX_WE_SGA,
OPTINDEX_THEY_SGA,
+ OPTINDEX_WE_BIN,
+ OPTINDEX_THEY_BIN,
NUM_OPTS
};
NUM_OPTS
};
@@
-178,10
+182,14
@@
static const struct Opt o_we_sga =
{ WILL, WONT, DO, DONT, TELOPT_SGA, OPTINDEX_WE_SGA, REQUESTED };
static const struct Opt o_they_sga =
{ DO, DONT, WILL, WONT, TELOPT_SGA, OPTINDEX_THEY_SGA, REQUESTED };
{ WILL, WONT, DO, DONT, TELOPT_SGA, OPTINDEX_WE_SGA, REQUESTED };
static const struct Opt o_they_sga =
{ DO, DONT, WILL, WONT, TELOPT_SGA, OPTINDEX_THEY_SGA, REQUESTED };
+static const struct Opt o_we_bin =
+ { WILL, WONT, DO, DONT, TELOPT_BINARY, OPTINDEX_WE_BIN, INACTIVE };
+static const struct Opt o_they_bin =
+ { DO, DONT, WILL, WONT, TELOPT_BINARY, OPTINDEX_THEY_BIN, INACTIVE };
static const struct Opt *const opts[] = {
&o_naws, &o_tspeed, &o_ttype, &o_oenv, &o_nenv, &o_echo,
static const struct Opt *const opts[] = {
&o_naws, &o_tspeed, &o_ttype, &o_oenv, &o_nenv, &o_echo,
- &o_we_sga, &o_they_sga, NULL
+ &o_we_sga, &o_they_sga,
&o_we_bin, &o_they_bin,
NULL
};
typedef struct telnet_tag {
};
typedef struct telnet_tag {
@@
-225,17
+233,18
@@
static void c_write1(Telnet telnet, int c)
static void log_option(Telnet telnet, char *sender, int cmd, int option)
{
static void log_option(Telnet telnet, char *sender, int cmd, int option)
{
- char
buf[50]
;
+ char
*buf
;
/*
* The strange-looking "<?""?>" below is there to avoid a
* trigraph - a double question mark followed by > maps to a
* closing brace character!
*/
/*
* The strange-looking "<?""?>" below is there to avoid a
* trigraph - a double question mark followed by > maps to a
* closing brace character!
*/
-
sprintf(buf,
"%s:\t%s %s", sender,
- (cmd == WILL ? "WILL" : cmd == WONT ? "WONT" :
- cmd == DO ? "DO" : cmd == DONT ? "DONT" : "<?""?>"),
- telopt(option));
+
buf = dupprintf(
"%s:\t%s %s", sender,
+
(cmd == WILL ? "WILL" : cmd == WONT ? "WONT" :
+
cmd == DO ? "DO" : cmd == DONT ? "DONT" : "<?""?>"),
+
telopt(option));
logevent(telnet->frontend, buf);
logevent(telnet->frontend, buf);
+ sfree(buf);
}
static void send_opt(Telnet telnet, int cmd, int option)
}
static void send_opt(Telnet telnet, int cmd, int option)
@@
-372,7
+381,7
@@
static void process_subneg(Telnet telnet)
switch (telnet->sb_opt) {
case TELOPT_TSPEED:
if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) {
switch (telnet->sb_opt) {
case TELOPT_TSPEED:
if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) {
- char
logbuf[sizeof(cfg.termspeed) + 80]
;
+ char
*logbuf
;
b[0] = IAC;
b[1] = SB;
b[2] = TELOPT_TSPEED;
b[0] = IAC;
b[1] = SB;
b[2] = TELOPT_TSPEED;
@@
-383,14
+392,15
@@
static void process_subneg(Telnet telnet)
b[n + 1] = SE;
telnet->bufsize = sk_write(telnet->s, b, n + 2);
logevent(telnet->frontend, "server:\tSB TSPEED SEND");
b[n + 1] = SE;
telnet->bufsize = sk_write(telnet->s, b, n + 2);
logevent(telnet->frontend, "server:\tSB TSPEED SEND");
-
sprintf(logbuf,
"client:\tSB TSPEED IS %s", cfg.termspeed);
+
logbuf = dupprintf(
"client:\tSB TSPEED IS %s", cfg.termspeed);
logevent(telnet->frontend, logbuf);
logevent(telnet->frontend, logbuf);
+ sfree(logbuf);
} else
logevent(telnet->frontend, "server:\tSB TSPEED <something weird>");
break;
case TELOPT_TTYPE:
if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) {
} else
logevent(telnet->frontend, "server:\tSB TSPEED <something weird>");
break;
case TELOPT_TTYPE:
if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) {
- char
logbuf[sizeof(cfg.termtype) + 80]
;
+ char
*logbuf
;
b[0] = IAC;
b[1] = SB;
b[2] = TELOPT_TTYPE;
b[0] = IAC;
b[1] = SB;
b[2] = TELOPT_TTYPE;
@@
-405,8
+415,9
@@
static void process_subneg(Telnet telnet)
telnet->bufsize = sk_write(telnet->s, b, n + 6);
b[n + 4] = 0;
logevent(telnet->frontend, "server:\tSB TTYPE SEND");
telnet->bufsize = sk_write(telnet->s, b, n + 6);
b[n + 4] = 0;
logevent(telnet->frontend, "server:\tSB TTYPE SEND");
-
sprintf(logbuf,
"client:\tSB TTYPE IS %s", b + 4);
+
logbuf = dupprintf(
"client:\tSB TTYPE IS %s", b + 4);
logevent(telnet->frontend, logbuf);
logevent(telnet->frontend, logbuf);
+ sfree(logbuf);
} else
logevent(telnet->frontend, "server:\tSB TTYPE <something weird>\r\n");
break;
} else
logevent(telnet->frontend, "server:\tSB TTYPE <something weird>\r\n");
break;
@@
-415,10
+426,11
@@
static void process_subneg(Telnet telnet)
p = telnet->sb_buf;
q = p + telnet->sb_len;
if (p < q && *p == TELQUAL_SEND) {
p = telnet->sb_buf;
q = p + telnet->sb_len;
if (p < q && *p == TELQUAL_SEND) {
- char
logbuf[50]
;
+ char
*logbuf
;
p++;
p++;
-
sprintf(logbuf,
"server:\tSB %s SEND", telopt(telnet->sb_opt));
+
logbuf = dupprintf(
"server:\tSB %s SEND", telopt(telnet->sb_opt));
logevent(telnet->frontend, logbuf);
logevent(telnet->frontend, logbuf);
+ sfree(logbuf);
if (telnet->sb_opt == TELOPT_OLD_ENVIRON) {
if (cfg.rfc_environ) {
value = RFC_VALUE;
if (telnet->sb_opt == TELOPT_OLD_ENVIRON) {
if (cfg.rfc_environ) {
value = RFC_VALUE;
@@
-479,9
+491,10
@@
static void process_subneg(Telnet telnet)
b[n++] = IAC;
b[n++] = SE;
telnet->bufsize = sk_write(telnet->s, b, n);
b[n++] = IAC;
b[n++] = SE;
telnet->bufsize = sk_write(telnet->s, b, n);
-
sprintf(logbuf,
"client:\tSB %s IS %s", telopt(telnet->sb_opt),
- n == 6 ? "<nothing>" : "<stuff>");
+
logbuf = dupprintf(
"client:\tSB %s IS %s", telopt(telnet->sb_opt),
+
n == 6 ? "<nothing>" : "<stuff>");
logevent(telnet->frontend, logbuf);
logevent(telnet->frontend, logbuf);
+ sfree(logbuf);
}
break;
}
}
break;
}
@@
-516,7
+529,7
@@
static void do_telnet_read(Telnet telnet, char *buf, int len)
else if (c == DM)
telnet->in_synch = 0;
#endif
else if (c == DM)
telnet->in_synch = 0;
#endif
- if (c == CR)
+ if (c == CR
&& telnet->opt_states[o_they_bin.index] != ACTIVE
)
telnet->state = SEENCR;
else
telnet->state = TOP_LEVEL;
telnet->state = SEENCR;
else
telnet->state = TOP_LEVEL;
@@
-668,11
+681,12
@@
static char *telnet_init(void *frontend_handle, void **backend_handle,
* Try to find host.
*/
{
* Try to find host.
*/
{
- char
buf[200]
;
-
sprintf(buf, "Looking up host \"%.170
s\"", host);
+ char
*buf
;
+
buf = dupprintf("Looking up host \"%
s\"", host);
logevent(telnet->frontend, buf);
logevent(telnet->frontend, buf);
+ sfree(buf);
}
}
- addr =
sk_namelookup(hos
t, realhost);
+ addr =
name_lookup(host, por
t, realhost);
if ((err = sk_addr_error(addr)))
return err;
if ((err = sk_addr_error(addr)))
return err;
@@
-683,10
+697,11
@@
static char *telnet_init(void *frontend_handle, void **backend_handle,
* Open socket.
*/
{
* Open socket.
*/
{
- char
buf[200]
, addrbuf[100];
+ char
*buf
, addrbuf[100];
sk_getaddr(addr, addrbuf, 100);
sk_getaddr(addr, addrbuf, 100);
-
sprintf(buf, "Connecting to %.100
s port %d", addrbuf, port);
+
buf = dupprintf("Connecting to %
s port %d", addrbuf, port);
logevent(telnet->frontend, buf);
logevent(telnet->frontend, buf);
+ sfree(buf);
}
telnet->s = new_connection(addr, *realhost, port, 0, 1,
nodelay, (Plug) telnet);
}
telnet->s = new_connection(addr, *realhost, port, 0, 1,
nodelay, (Plug) telnet);
@@
-742,7
+757,7
@@
static int telnet_send(void *handle, char *buf, int len)
while (p < buf + len) {
char *q = p;
while (p < buf + len) {
char *q = p;
- while (
iswritable((unsigned char) *p) && p < buf + len
)
+ while (
p < buf + len && iswritable((unsigned char) *p)
)
p++;
telnet->bufsize = sk_write(telnet->s, q, p - q);
p++;
telnet->bufsize = sk_write(telnet->s, q, p - q);
@@
-772,7
+787,7
@@
static void telnet_size(void *handle, int width, int height)
{
Telnet telnet = (Telnet) handle;
unsigned char b[16];
{
Telnet telnet = (Telnet) handle;
unsigned char b[16];
- char
logbuf[50]
;
+ char
*logbuf
;
telnet->term_width = width;
telnet->term_height = height;
telnet->term_width = width;
telnet->term_height = height;
@@
-789,10
+804,11
@@
static void telnet_size(void *handle, int width, int height)
b[7] = IAC;
b[8] = SE;
telnet->bufsize = sk_write(telnet->s, b, 9);
b[7] = IAC;
b[8] = SE;
telnet->bufsize = sk_write(telnet->s, b, 9);
-
sprintf(logbuf,
"client:\tSB NAWS %d,%d",
- ((unsigned char) b[3] << 8) + (unsigned char) b[4],
- ((unsigned char) b[5] << 8) + (unsigned char) b[6]);
+
logbuf = dupprintf(
"client:\tSB NAWS %d,%d",
+
((unsigned char) b[3] << 8) + (unsigned char) b[4],
+
((unsigned char) b[5] << 8) + (unsigned char) b[6]);
logevent(telnet->frontend, logbuf);
logevent(telnet->frontend, logbuf);
+ sfree(logbuf);
}
/*
}
/*
@@
-857,7
+873,11
@@
static void telnet_special(void *handle, Telnet_Special code)
telnet->bufsize = sk_write(telnet->s, b, 2);
break;
case TS_EOL:
telnet->bufsize = sk_write(telnet->s, b, 2);
break;
case TS_EOL:
- telnet->bufsize = sk_write(telnet->s, "\r\n", 2);
+ /* In BINARY mode, CR-LF becomes just CR. */
+ if (telnet->opt_states[o_we_bin.index] == ACTIVE)
+ telnet->bufsize = sk_write(telnet->s, "\r", 2);
+ else
+ telnet->bufsize = sk_write(telnet->s, "\r\n", 2);
break;
case TS_SYNCH:
b[1] = DM;
break;
case TS_SYNCH:
b[1] = DM;