telnet: someone tried to do data optimization before me. Complete it. text data bss dec hex filename 2558 0 404 2962 b92 busybox.t2/networking/telnet.o 2542 0 0 2542 9ee busybox.t3/networking/telnet.o
No binary (build failed)
—
(log yok)
| @@ -32,10 +32,10 @@ | |
| #define TRACE(x, y) | |
| #endif | |
| - | #define DATABUFSIZE 128 |
| - | #define IACBUFSIZE 128 |
| - | |
| enum { | |
| + | DATABUFSIZE = 128, |
| + | IACBUFSIZE = 128, |
| + | |
| CHM_TRY = 0, | |
| CHM_ON = 1, | |
| CHM_OFF = 2, | |
| @@ -50,40 +50,36 @@ enum { | |
| TS_SUB2 = 5, | |
| }; | |
| - | #define WriteCS(fd, str) write(fd, str, sizeof str -1) |
| - | |
| typedef unsigned char byte; | |
| - | /* use globals to reduce size ??? */ /* test this hypothesis later */ |
| - | static struct Globalvars { |
| - | int netfd; /* console fd:s are 0 and 1 (and 2) */ |
| - | /* same buffer used both for network and console read/write */ |
| - | char buf[DATABUFSIZE]; /* allocating so static size is smaller */ |
| + | |
| + | struct globals { |
| + | int netfd; /* console fd:s are 0 and 1 (and 2) */ |
| + | short iaclen; /* could even use byte */ |
| byte telstate; /* telnet negotiation state from network input */ | |
| byte telwish; /* DO, DONT, WILL, WONT */ | |
| byte charmode; | |
| byte telflags; | |
| byte gotsig; | |
| byte do_termios; | |
| - | /* buffer to handle telnet negotiations */ |
| + | #if ENABLE_FEATURE_TELNET_TTYPE |
| + | char *ttype; |
| + | #endif |
| + | #if ENABLE_FEATURE_TELNET_AUTOLOGIN |
| + | const char *autologin; |
| + | #endif |
| + | #if ENABLE_FEATURE_AUTOWIDTH |
| + | int win_width, win_height; |
| + | #endif |
| + | /* same buffer used both for network and console read/write */ |
| + | char buf[DATABUFSIZE]; /* allocating so static size is smaller */ |
| char iacbuf[IACBUFSIZE]; | |
| - | short iaclen; /* could even use byte */ |
| struct termios termios_def; | |
| struct termios termios_raw; | |
| - | } G; |
| - | |
| - | #define xUSE_GLOBALVAR_PTR /* xUSE... -> don't use :D (makes smaller code) */ |
| + | }; |
| - | #ifdef USE_GLOBALVAR_PTR |
| - | struct Globalvars * Gptr; |
| - | #define G (*Gptr) |
| - | #endif |
| + | #define G (*(struct globals*)bb_common_bufsiz1) |
| - | static void iacflush(void) |
| - | { |
| - | write(G.netfd, G.iacbuf, G.iaclen); |
| - | G.iaclen = 0; |
| - | } |
| /* Function prototypes */ | |
| static void rawmode(void); | |
| @@ -93,20 +89,16 @@ static void will_charmode(void); | |
| static void telopt(byte c); | |
| static int subneg(byte c); | |
| - | /* Some globals */ |
| - | #ifdef CONFIG_FEATURE_TELNET_TTYPE |
| - | static char *ttype; |
| - | #endif |
| - | |
| - | #ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN |
| - | static const char *autologin; |
| - | #endif |
| + | static void iacflush(void) |
| + | { |
| + | write(G.netfd, G.iacbuf, G.iaclen); |
| + | G.iaclen = 0; |
| + | } |
| - | #ifdef CONFIG_FEATURE_AUTOWIDTH |
| - | static int win_width, win_height; |
| - | #endif |
| + | #define write_str(fd, str) write(fd, str, sizeof(str) - 1) |
| - | static void doexit(int ev) |
| + | static void /* buffer to handle telnet negotiations */ |
| + | doexit(int ev) |
| { | |
| cookmode(); | |
| exit(ev); | |
| @@ -119,7 +111,7 @@ static void conescape(void) | |
| if (G.gotsig) /* came from line mode... go raw */ | |
| rawmode(); | |
| - | WriteCS(1, "\r\nConsole escape. Commands are:\r\n\n" |
| + | write_str(1, "\r\nConsole escape. Commands are:\r\n\n" |
| " l go to line mode\r\n" | |
| " c go to character mode\r\n" | |
| " z suspend telnet\r\n" | |
| @@ -128,18 +120,15 @@ static void conescape(void) | |
| if (read(0, &b, 1) <= 0) | |
| doexit(1); | |
| - | switch (b) |
| - | { |
| + | switch (b) { |
| case 'l': | |
| - | if (!G.gotsig) |
| - | { |
| + | if (!G.gotsig) { |
| do_linemode(); | |
| goto rrturn; | |
| } | |
| break; | |
| case 'c': | |
| - | if (G.gotsig) |
| - | { |
| + | if (G.gotsig) { |
| will_charmode(); | |
| goto rrturn; | |
| } | |
| @@ -153,7 +142,7 @@ static void conescape(void) | |
| doexit(0); | |
| } | |
| - | WriteCS(1, "continuing...\r\n"); |
| + | write_str(1, "continuing...\r\n"); |
| if (G.gotsig) | |
| cookmode(); | |
| @@ -296,7 +285,7 @@ static void putiac2(byte wwdd, byte c) | |
| putiac(c); | |
| } | |
| - | #ifdef CONFIG_FEATURE_TELNET_TTYPE |
| + | #if ENABLE_FEATURE_TELNET_TTYPE |
| static void putiac_subopt(byte c, char *str) | |
| { | |
| int len = strlen(str) + 6; // ( 2 + 1 + 1 + strlen + 2 ) | |
| @@ -317,10 +306,10 @@ static void putiac_subopt(byte c, char *str) | |
| } | |
| #endif | |
| - | #ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN |
| + | #if ENABLE_FEATURE_TELNET_AUTOLOGIN |
| static void putiac_subopt_autologin(void) | |
| { | |
| - | int len = strlen(autologin) + 6; // (2 + 1 + 1 + strlen + 2) |
| + | int len = strlen(G.autologin) + 6; // (2 + 1 + 1 + strlen + 2) |
| const char *user = "USER"; | |
| if (G.iaclen + len > IACBUFSIZE) | |
| @@ -337,15 +326,15 @@ static void putiac_subopt_autologin(void) | |
| putiac(NEW_ENV_VALUE); | |
| - | while (*autologin) |
| - | putiac(*autologin++); |
| + | while (*G.autologin) |
| + | putiac(*G.autologin++); |
| putiac(IAC); | |
| putiac(SE); | |
| } | |
| #endif | |
| - | #ifdef CONFIG_FEATURE_AUTOWIDTH |
| + | #if ENABLE_FEATURE_AUTOWIDTH |
| static void putiac_naws(byte c, int x, int y) | |
| { | |
| if (G.iaclen + 9 > IACBUFSIZE) | |
| @@ -419,24 +408,27 @@ static void do_linemode(void) | |
| static void to_notsup(char c) | |
| { | |
| - | if (G.telwish == WILL) putiac2(DONT, c); |
| - | else if (G.telwish == DO) putiac2(WONT, c); |
| + | if (G.telwish == WILL) |
| + | putiac2(DONT, c); |
| + | else if (G.telwish == DO) |
| + | putiac2(WONT, c); |
| } | |
| static void to_echo(void) | |
| { | |
| /* if server requests ECHO, don't agree */ | |
| - | if (G.telwish == DO) { putiac2(WONT, TELOPT_ECHO); return; } |
| - | else if (G.telwish == DONT) return; |
| + | if (G.telwish == DO) { |
| + | putiac2(WONT, TELOPT_ECHO); |
| + | return; |
| + | } |
| + | if (G.telwish == DONT) |
| + | return; |
| - | if (G.telflags & UF_ECHO) |
| - | { |
| + | if (G.telflags & UF_ECHO) { |
| if (G.telwish == WILL) | |
| return; | |
| - | } |
| - | else |
| - | if (G.telwish == WONT) |
| - | return; |
| + | } else if (G.telwish == WONT) |
| + | return; |
| if (G.charmode != CHM_OFF) | |
| G.telflags ^= UF_ECHO; | |
| @@ -447,21 +439,18 @@ static void to_echo(void) | |
| putiac2(DONT, TELOPT_ECHO); | |
| setConMode(); | |
| - | WriteCS(1, "\r\n"); /* sudden modec */ |
| + | write_str(1, "\r\n"); /* sudden modec */ |
| } | |
| static void to_sga(void) | |
| { | |
| /* daemon always sends will/wont, client do/dont */ | |
| - | if (G.telflags & UF_SGA) |
| - | { |
| + | if (G.telflags & UF_SGA) { |
| if (G.telwish == WILL) | |
| return; | |
| - | } |
| - | else |
| - | if (G.telwish == WONT) |
| - | return; |
| + | } else if (G.telwish == WONT) |
| + | return; |
| if ((G.telflags ^= UF_SGA) & UF_SGA) /* toggle */ | |
| putiac2(DO, TELOPT_SGA); | |
| @@ -469,31 +458,31 @@ static void to_sga(void) | |
| putiac2(DONT, TELOPT_SGA); | |
| } | |
| - | #ifdef CONFIG_FEATURE_TELNET_TTYPE |
| + | #if ENABLE_FEATURE_TELNET_TTYPE |
| static void to_ttype(void) | |
| { | |
| /* Tell server we will (or won't) do TTYPE */ | |
| - | if(ttype) |
| + | if (G.ttype) |
| putiac2(WILL, TELOPT_TTYPE); | |
| else | |
| putiac2(WONT, TELOPT_TTYPE); | |
| } | |
| #endif | |
| - | #ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN |
| + | #if ENABLE_FEATURE_TELNET_AUTOLOGIN |
| static void to_new_environ(void) | |
| { | |
| /* Tell server we will (or will not) do AUTOLOGIN */ | |
| - | if (autologin) |
| + | if (G.autologin) |
| putiac2(WILL, TELOPT_NEW_ENVIRON); | |
| else | |
| putiac2(WONT, TELOPT_NEW_ENVIRON); | |
| } | |
| #endif | |
| - | #ifdef CONFIG_FEATURE_AUTOWIDTH |
| + | #if ENABLE_FEATURE_AUTOWIDTH |
| static void to_naws(void) | |
| { | |
| /* Tell server we will do NAWS */ | |
| @@ -508,18 +497,18 @@ static void telopt(byte c) | |
| to_echo(); break; | |
| case TELOPT_SGA: | |
| to_sga(); break; | |
| - | #ifdef CONFIG_FEATURE_TELNET_TTYPE |
| + | #if ENABLE_FEATURE_TELNET_TTYPE |
| case TELOPT_TTYPE: | |
| to_ttype(); break; | |
| #endif | |
| - | #ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN |
| + | #if ENABLE_FEATURE_TELNET_AUTOLOGIN |
| case TELOPT_NEW_ENVIRON: | |
| to_new_environ(); break; | |
| #endif | |
| - | #ifdef CONFIG_FEATURE_AUTOWIDTH |
| + | #if ENABLE_FEATURE_AUTOWIDTH |
| case TELOPT_NAWS: | |
| to_naws(); | |
| - | putiac_naws(c, win_width, win_height); |
| + | putiac_naws(c, G.win_width, G.win_height); |
| break; | |
| #endif | |
| default: | |
| @@ -535,17 +524,16 @@ static void telopt(byte c) | |
| static int subneg(byte c) | |
| { | |
| - | switch (G.telstate) |
| - | { |
| + | switch (G.telstate) { |
| case TS_SUB1: | |
| if (c == IAC) | |
| G.telstate = TS_SUB2; | |
| - | #ifdef CONFIG_FEATURE_TELNET_TTYPE |
| + | #if ENABLE_FEATURE_TELNET_TTYPE |
| else | |
| if (c == TELOPT_TTYPE) | |
| - | putiac_subopt(TELOPT_TTYPE,ttype); |
| + | putiac_subopt(TELOPT_TTYPE, G.ttype); |
| #endif | |
| - | #ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN |
| + | #if ENABLE_FEATURE_TELNET_AUTOLOGIN |
| else | |
| if (c == TELOPT_NEW_ENVIRON) | |
| putiac_subopt_autologin(); | |
| @@ -578,6 +566,8 @@ static void cookmode(void) | |
| if (G.do_termios) tcsetattr(0, TCSADRAIN, &G.termios_def); | |
| } | |
| + | void BUG_telnet_globals_too_big(void); |
| + | |
| int telnet_main(int argc, char** argv); | |
| int telnet_main(int argc, char** argv) | |
| { | |
| @@ -591,15 +581,17 @@ int telnet_main(int argc, char** argv) | |
| int maxfd; | |
| #endif | |
| - | #ifdef CONFIG_FEATURE_AUTOWIDTH |
| - | get_terminal_width_height(0, &win_width, &win_height); |
| - | #endif |
| + | if (sizeof(G) > sizeof(bb_common_bufsiz1)) |
| + | BUG_telnet_globals_too_big(); |
| + | /* memset(&G, 0, sizeof G); - already is */ |
| - | #ifdef CONFIG_FEATURE_TELNET_TTYPE |
| - | ttype = getenv("TERM"); |
| + | #if ENABLE_FEATURE_AUTOWIDTH |
| + | get_terminal_width_height(0, &G.win_width, &G.win_height); |
| #endif | |
| - | /* memset(&G, 0, sizeof G); - already is */ |
| + | #if ENABLE_FEATURE_TELNET_TTYPE |
| + | G.ttype = getenv("TERM"); |
| + | #endif |
| if (tcgetattr(0, &G.termios_def) >= 0) { | |
| G.do_termios = 1; | |
| @@ -610,9 +602,9 @@ int telnet_main(int argc, char** argv) | |
| if (argc < 2) | |
| bb_show_usage(); | |
| - | #ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN |
| - | if (1 & getopt32(argc, argv, "al:", &autologin)) |
| - | autologin = getenv("USER"); |
| + | #if ENABLE_FEATURE_TELNET_AUTOLOGIN |
| + | if (1 & getopt32(argc, argv, "al:", &G.autologin)) |
| + | G.autologin = getenv("USER"); |
| argv += optind; | |
| #else | |
| argv++; | |
| @@ -667,12 +659,9 @@ int telnet_main(int argc, char** argv) | |
| #endif | |
| { | |
| len = read(0, G.buf, DATABUFSIZE); | |
| - | |
| if (len <= 0) | |
| doexit(0); | |
| - | |
| TRACE(0, ("Read con: %d\n", len)); | |
| - | |
| handlenetoutput(len); | |
| } | |
| @@ -683,13 +672,11 @@ int telnet_main(int argc, char** argv) | |
| #endif | |
| { | |
| len = read(G.netfd, G.buf, DATABUFSIZE); | |
| - | |
| if (len <= 0) { | |
| - | WriteCS(1, "Connection closed by foreign host.\r\n"); |
| + | write_str(1, "Connection closed by foreign host\r\n"); |
| doexit(1); | |
| } | |
| TRACE(0, ("Read netfd (%d): %d\n", G.netfd, len)); | |
| - | |
| handlenetinput(len); | |
| } | |
| } | |