diff options
author | Eric Andersen <andersen@codepoet.org> | 2002-04-26 07:20:47 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2002-04-26 07:20:47 +0000 |
commit | 0e28e1fa0551487dd28a42f1dbeb5bf717817175 (patch) | |
tree | fa9fbece381defec1e511e0f468b342e0067bbbe | |
parent | 60e56f5292dfe525a28f321c2d7b9371ce639a86 (diff) | |
download | busybox-w32-0e28e1fa0551487dd28a42f1dbeb5bf717817175.tar.gz busybox-w32-0e28e1fa0551487dd28a42f1dbeb5bf717817175.tar.bz2 busybox-w32-0e28e1fa0551487dd28a42f1dbeb5bf717817175.zip |
Forward port patch from Przemyslaw Czerpak <druzus@polbox.com>:
1. busybox-telnet dosn't inform server about the size of terminal screen.
In the world of xterminals and frame buffers it's rather horrible
to use fixed 80x24 region in upper-left corner of screen/window.
2. If client sends character 0x0d to the server then sends character 0x0a
the server eat the second byte (0x0a) - it's described in telnet RFC.
Client should send two bytes ( 0x0d + 0x0a or 0x0d + 0x00 ) insted of
one 0x0d byte.
3. busybox telnet implementation wasn't 8bit clean (look at 0xff byte).
I need it because I have to use binray transfer like rz/sz. So when
I resloved the problem (2) I corrected this one two.
This also contains a small cleanup patch from vodz, and some minor editing
by me.
-rw-r--r-- | networking/telnet.c | 88 |
1 files changed, 77 insertions, 11 deletions
diff --git a/networking/telnet.c b/networking/telnet.c index d09a9d558..93eda56e1 100644 --- a/networking/telnet.c +++ b/networking/telnet.c | |||
@@ -46,6 +46,10 @@ | |||
46 | #include <netdb.h> | 46 | #include <netdb.h> |
47 | #include "busybox.h" | 47 | #include "busybox.h" |
48 | 48 | ||
49 | #ifdef CONFIG_FEATURE_AUTOWIDTH | ||
50 | # include <sys/ioctl.h> | ||
51 | #endif | ||
52 | |||
49 | #if 0 | 53 | #if 0 |
50 | static const int DOTRACE = 1; | 54 | static const int DOTRACE = 1; |
51 | #endif | 55 | #endif |
@@ -140,6 +144,10 @@ static int one = 1; | |||
140 | static char *ttype; | 144 | static char *ttype; |
141 | #endif | 145 | #endif |
142 | 146 | ||
147 | #ifdef CONFIG_FEATURE_AUTOWIDTH | ||
148 | static int win_width, win_height; | ||
149 | #endif | ||
150 | |||
143 | static void doexit(int ev) | 151 | static void doexit(int ev) |
144 | { | 152 | { |
145 | cookmode(); | 153 | cookmode(); |
@@ -202,22 +210,38 @@ static void handlenetoutput(int len) | |||
202 | * stream like writing twice every sequence of FF:s (thus doing | 210 | * stream like writing twice every sequence of FF:s (thus doing |
203 | * many write()s. But I think interactive telnet application does | 211 | * many write()s. But I think interactive telnet application does |
204 | * not need to be 100% 8-bit clean, so changing every 0xff:s to | 212 | * not need to be 100% 8-bit clean, so changing every 0xff:s to |
205 | * 0x7f:s */ | 213 | * 0x7f:s |
206 | 214 | * | |
207 | int i; | 215 | * 2002-mar-21, Przemyslaw Czerpak (druzus@polbox.com) |
216 | * I don't agree. | ||
217 | * first - I cannot use programs like sz/rz | ||
218 | * second - the 0x0D is sent as one character and if the next | ||
219 | * char is 0x0A then it's eaten by a server side. | ||
220 | * third - whay doy you have to make 'many write()s'? | ||
221 | * I don't understand. | ||
222 | * So I implemented it. It's realy useful for me. I hope that | ||
223 | * others people will find it interesting to. | ||
224 | */ | ||
225 | |||
226 | int i, j; | ||
208 | byte * p = G.buf; | 227 | byte * p = G.buf; |
228 | byte outbuf[4*DATABUFSIZE]; | ||
209 | 229 | ||
210 | for (i = len; i > 0; i--, p++) | 230 | for (i = len, j = 0; i > 0; i--, p++) |
211 | { | 231 | { |
212 | if (*p == 0x1d) | 232 | if (*p == 0x1d) |
213 | { | 233 | { |
214 | conescape(); | 234 | conescape(); |
215 | return; | 235 | return; |
216 | } | 236 | } |
237 | outbuf[j++] = *p; | ||
217 | if (*p == 0xff) | 238 | if (*p == 0xff) |
218 | *p = 0x7f; | 239 | outbuf[j++] = 0xff; |
240 | else if (*p == 0x0d) | ||
241 | outbuf[j++] = 0x00; | ||
219 | } | 242 | } |
220 | write(G.netfd, G.buf, len); | 243 | if (j > 0 ) |
244 | write(G.netfd, outbuf, j); | ||
221 | } | 245 | } |
222 | 246 | ||
223 | 247 | ||
@@ -346,6 +370,26 @@ static void putiac_subopt(byte c, char *str) | |||
346 | } | 370 | } |
347 | #endif | 371 | #endif |
348 | 372 | ||
373 | #ifdef CONFIG_FEATURE_AUTOWIDTH | ||
374 | static void putiac_naws(byte c, int x, int y) | ||
375 | { | ||
376 | if (G.iaclen + 9 > IACBUFSIZE) | ||
377 | iacflush(); | ||
378 | |||
379 | putiac(IAC); | ||
380 | putiac(SB); | ||
381 | putiac(c); | ||
382 | |||
383 | putiac((x >> 8) & 0xff); | ||
384 | putiac(x & 0xff); | ||
385 | putiac((y >> 8) & 0xff); | ||
386 | putiac(y & 0xff); | ||
387 | |||
388 | putiac(IAC); | ||
389 | putiac(SE); | ||
390 | } | ||
391 | #endif | ||
392 | |||
349 | /* void putiacstring (subneg strings) */ | 393 | /* void putiacstring (subneg strings) */ |
350 | 394 | ||
351 | /* ******************************* */ | 395 | /* ******************************* */ |
@@ -466,23 +510,37 @@ static inline void to_ttype(void) | |||
466 | } | 510 | } |
467 | #endif | 511 | #endif |
468 | 512 | ||
513 | #ifdef CONFIG_FEATURE_AUTOWIDTH | ||
514 | static inline void to_naws() | ||
515 | { | ||
516 | /* Tell server we will do NAWS */ | ||
517 | putiac2(WILL, TELOPT_NAWS); | ||
518 | return; | ||
519 | } | ||
520 | #endif | ||
521 | |||
469 | static void telopt(byte c) | 522 | static void telopt(byte c) |
470 | { | 523 | { |
471 | switch (c) | 524 | switch (c) |
472 | { | 525 | { |
473 | case TELOPT_ECHO: to_echo(); break; | 526 | case TELOPT_ECHO: to_echo(c); break; |
474 | case TELOPT_SGA: to_sga(); break; | 527 | case TELOPT_SGA: to_sga(c); break; |
475 | #ifdef CONFIG_FEATURE_TELNET_TTYPE | 528 | #ifdef CONFIG_FEATURE_TELNET_TTYPE |
476 | case TELOPT_TTYPE: to_ttype(); break; | 529 | case TELOPT_TTYPE: to_ttype(c);break; |
477 | #endif | 530 | #endif |
478 | default: to_notsup(c); break; | 531 | #ifdef CONFIG_FEATURE_AUTOWIDTH |
532 | case TELOPT_NAWS: to_naws(c); | ||
533 | putiac_naws(c, win_width, win_height); | ||
534 | break; | ||
535 | #endif | ||
536 | default: to_notsup(c); break; | ||
479 | } | 537 | } |
480 | } | 538 | } |
481 | 539 | ||
482 | 540 | ||
483 | /* ******************************* */ | 541 | /* ******************************* */ |
484 | 542 | ||
485 | /* subnegotiation -- ignore all (except TTYPE) */ | 543 | /* subnegotiation -- ignore all (except TTYPE,NAWS) */ |
486 | 544 | ||
487 | static int subneg(byte c) | 545 | static int subneg(byte c) |
488 | { | 546 | { |
@@ -536,6 +594,14 @@ extern int telnet_main(int argc, char** argv) | |||
536 | int maxfd; | 594 | int maxfd; |
537 | #endif | 595 | #endif |
538 | 596 | ||
597 | #ifdef CONFIG_FEATURE_AUTOWIDTH | ||
598 | struct winsize winp; | ||
599 | if( ioctl(0, TIOCGWINSZ, &winp) == 0 ) { | ||
600 | win_width = winp.ws_col; | ||
601 | win_height = winp.ws_row; | ||
602 | } | ||
603 | #endif | ||
604 | |||
539 | #ifdef CONFIG_FEATURE_TELNET_TTYPE | 605 | #ifdef CONFIG_FEATURE_TELNET_TTYPE |
540 | ttype = getenv("TERM"); | 606 | ttype = getenv("TERM"); |
541 | #endif | 607 | #endif |