aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-04-26 07:20:47 +0000
committerEric Andersen <andersen@codepoet.org>2002-04-26 07:20:47 +0000
commit0e28e1fa0551487dd28a42f1dbeb5bf717817175 (patch)
treefa9fbece381defec1e511e0f468b342e0067bbbe
parent60e56f5292dfe525a28f321c2d7b9371ce639a86 (diff)
downloadbusybox-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.c88
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
50static const int DOTRACE = 1; 54static const int DOTRACE = 1;
51#endif 55#endif
@@ -140,6 +144,10 @@ static int one = 1;
140static char *ttype; 144static char *ttype;
141#endif 145#endif
142 146
147#ifdef CONFIG_FEATURE_AUTOWIDTH
148static int win_width, win_height;
149#endif
150
143static void doexit(int ev) 151static 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
374static 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
514static inline void to_naws()
515{
516 /* Tell server we will do NAWS */
517 putiac2(WILL, TELOPT_NAWS);
518 return;
519}
520#endif
521
469static void telopt(byte c) 522static 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
487static int subneg(byte c) 545static 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