summaryrefslogtreecommitdiff
path: root/networking/telnet.c
diff options
context:
space:
mode:
authorEric Andersen2002-04-26 07:20:47 +0000
committerEric Andersen2002-04-26 07:20:47 +0000
commit0e28e1fa0551487dd28a42f1dbeb5bf717817175 (patch)
treefa9fbece381defec1e511e0f468b342e0067bbbe /networking/telnet.c
parent60e56f5292dfe525a28f321c2d7b9371ce639a86 (diff)
downloadbusybox-0e28e1fa0551487dd28a42f1dbeb5bf717817175.zip
busybox-0e28e1fa0551487dd28a42f1dbeb5bf717817175.tar.gz
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.
Diffstat (limited to 'networking/telnet.c')
-rw-r--r--networking/telnet.c88
1 files changed, 77 insertions, 11 deletions
diff --git a/networking/telnet.c b/networking/telnet.c
index d09a9d5..93eda56 100644
--- a/networking/telnet.c
+++ b/networking/telnet.c
@@ -46,6 +46,10 @@
#include <netdb.h>
#include "busybox.h"
+#ifdef CONFIG_FEATURE_AUTOWIDTH
+# include <sys/ioctl.h>
+#endif
+
#if 0
static const int DOTRACE = 1;
#endif
@@ -140,6 +144,10 @@ static int one = 1;
static char *ttype;
#endif
+#ifdef CONFIG_FEATURE_AUTOWIDTH
+static int win_width, win_height;
+#endif
+
static void doexit(int ev)
{
cookmode();
@@ -202,22 +210,38 @@ static void handlenetoutput(int len)
* stream like writing twice every sequence of FF:s (thus doing
* many write()s. But I think interactive telnet application does
* not need to be 100% 8-bit clean, so changing every 0xff:s to
- * 0x7f:s */
-
- int i;
+ * 0x7f:s
+ *
+ * 2002-mar-21, Przemyslaw Czerpak (druzus@polbox.com)
+ * I don't agree.
+ * first - I cannot use programs like sz/rz
+ * second - the 0x0D is sent as one character and if the next
+ * char is 0x0A then it's eaten by a server side.
+ * third - whay doy you have to make 'many write()s'?
+ * I don't understand.
+ * So I implemented it. It's realy useful for me. I hope that
+ * others people will find it interesting to.
+ */
+
+ int i, j;
byte * p = G.buf;
+ byte outbuf[4*DATABUFSIZE];
- for (i = len; i > 0; i--, p++)
+ for (i = len, j = 0; i > 0; i--, p++)
{
if (*p == 0x1d)
{
conescape();
return;
}
+ outbuf[j++] = *p;
if (*p == 0xff)
- *p = 0x7f;
+ outbuf[j++] = 0xff;
+ else if (*p == 0x0d)
+ outbuf[j++] = 0x00;
}
- write(G.netfd, G.buf, len);
+ if (j > 0 )
+ write(G.netfd, outbuf, j);
}
@@ -346,6 +370,26 @@ static void putiac_subopt(byte c, char *str)
}
#endif
+#ifdef CONFIG_FEATURE_AUTOWIDTH
+static void putiac_naws(byte c, int x, int y)
+{
+ if (G.iaclen + 9 > IACBUFSIZE)
+ iacflush();
+
+ putiac(IAC);
+ putiac(SB);
+ putiac(c);
+
+ putiac((x >> 8) & 0xff);
+ putiac(x & 0xff);
+ putiac((y >> 8) & 0xff);
+ putiac(y & 0xff);
+
+ putiac(IAC);
+ putiac(SE);
+}
+#endif
+
/* void putiacstring (subneg strings) */
/* ******************************* */
@@ -466,23 +510,37 @@ static inline void to_ttype(void)
}
#endif
+#ifdef CONFIG_FEATURE_AUTOWIDTH
+static inline void to_naws()
+{
+ /* Tell server we will do NAWS */
+ putiac2(WILL, TELOPT_NAWS);
+ return;
+}
+#endif
+
static void telopt(byte c)
{
switch (c)
{
- case TELOPT_ECHO: to_echo(); break;
- case TELOPT_SGA: to_sga(); break;
+ case TELOPT_ECHO: to_echo(c); break;
+ case TELOPT_SGA: to_sga(c); break;
#ifdef CONFIG_FEATURE_TELNET_TTYPE
- case TELOPT_TTYPE: to_ttype(); break;
+ case TELOPT_TTYPE: to_ttype(c);break;
#endif
- default: to_notsup(c); break;
+#ifdef CONFIG_FEATURE_AUTOWIDTH
+ case TELOPT_NAWS: to_naws(c);
+ putiac_naws(c, win_width, win_height);
+ break;
+#endif
+ default: to_notsup(c); break;
}
}
/* ******************************* */
-/* subnegotiation -- ignore all (except TTYPE) */
+/* subnegotiation -- ignore all (except TTYPE,NAWS) */
static int subneg(byte c)
{
@@ -536,6 +594,14 @@ extern int telnet_main(int argc, char** argv)
int maxfd;
#endif
+#ifdef CONFIG_FEATURE_AUTOWIDTH
+ struct winsize winp;
+ if( ioctl(0, TIOCGWINSZ, &winp) == 0 ) {
+ win_width = winp.ws_col;
+ win_height = winp.ws_row;
+ }
+#endif
+
#ifdef CONFIG_FEATURE_TELNET_TTYPE
ttype = getenv("TERM");
#endif