| @@ -101,6 +101,7 @@ static void iacflush(void) |
| |
| #define write_str(fd, str) write(fd, str, sizeof(str) - 1) |
| |
| + | static void doexit(int ev) ATTRIBUTE_NORETURN; |
| static void doexit(int ev) |
| { |
| cookmode(); |
| @@ -157,31 +158,29 @@ static void conescape(void) |
| |
| static void handlenetoutput(int len) |
| { |
| - | /* here we could do smart tricks how to handle 0xFF:s in output |
| - | * 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 |
| + | /* here we could do smart tricks how to handle 0xFF:s in output |
| + | * 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 |
| * |
| - | * 2002-mar-21, Przemyslaw Czerpak ([email protected]) |
| - | * 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. |
| + | * 2002-mar-21, Przemyslaw Czerpak ([email protected]) |
| + | * 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 too. |
| */ |
| |
| int i, j; |
| byte * p = (byte*)G.buf; |
| byte outbuf[4*DATABUFSIZE]; |
| |
| - | for (i = len, j = 0; i > 0; i--, p++) |
| - | { |
| - | if (*p == 0x1d) |
| - | { |
| + | for (i = len, j = 0; i > 0; i--, p++) { |
| + | if (*p == 0x1d) { |
| conescape(); |
| return; |
| } |
| @@ -200,68 +199,59 @@ static void handlenetinput(int len) |
| int i; |
| int cstart = 0; |
| |
| - | for (i = 0; i < len; i++) |
| - | { |
| + | for (i = 0; i < len; i++) { |
| byte c = G.buf[i]; |
| |
| - | if (G.telstate == 0) /* most of the time state == 0 */ |
| - | { |
| - | if (c == IAC) |
| - | { |
| + | if (G.telstate == 0) { /* most of the time state == 0 */ |
| + | if (c == IAC) { |
| cstart = i; |
| G.telstate = TS_IAC; |
| } |
| - | } |
| - | else |
| - | switch (G.telstate) |
| - | { |
| - | case TS_0: |
| - | if (c == IAC) |
| - | G.telstate = TS_IAC; |
| - | else |
| - | G.buf[cstart++] = c; |
| - | break; |
| - | |
| - | case TS_IAC: |
| - | if (c == IAC) /* IAC IAC -> 0xFF */ |
| - | { |
| - | G.buf[cstart++] = c; |
| - | G.telstate = TS_0; |
| - | break; |
| - | } |
| - | /* else */ |
| - | switch (c) |
| - | { |
| - | case SB: |
| - | G.telstate = TS_SUB1; |
| - | break; |
| - | case DO: |
| - | case DONT: |
| - | case WILL: |
| - | case WONT: |
| - | G.telwish = c; |
| - | G.telstate = TS_OPT; |
| - | break; |
| - | default: |
| - | G.telstate = TS_0; /* DATA MARK must be added later */ |
| - | } |
| - | break; |
| - | case TS_OPT: /* WILL, WONT, DO, DONT */ |
| - | telopt(c); |
| - | G.telstate = TS_0; |
| - | break; |
| - | case TS_SUB1: /* Subnegotiation */ |
| - | case TS_SUB2: /* Subnegotiation */ |
| - | if (subneg(c)) |
| - | G.telstate = TS_0; |
| - | break; |
| - | } |
| + | } else |
| + | switch (G.telstate) { |
| + | case TS_0: |
| + | if (c == IAC) |
| + | G.telstate = TS_IAC; |
| + | else |
| + | G.buf[cstart++] = c; |
| + | break; |
| + | |
| + | case TS_IAC: |
| + | if (c == IAC) { /* IAC IAC -> 0xFF */ |
| + | G.buf[cstart++] = c; |
| + | G.telstate = TS_0; |
| + | break; |
| + | } |
| + | /* else */ |
| + | switch (c) { |
| + | case SB: |
| + | G.telstate = TS_SUB1; |
| + | break; |
| + | case DO: |
| + | case DONT: |
| + | case WILL: |
| + | case WONT: |
| + | G.telwish = c; |
| + | G.telstate = TS_OPT; |
| + | break; |
| + | default: |
| + | G.telstate = TS_0; /* DATA MARK must be added later */ |
| + | } |
| + | break; |
| + | case TS_OPT: /* WILL, WONT, DO, DONT */ |
| + | telopt(c); |
| + | G.telstate = TS_0; |
| + | break; |
| + | case TS_SUB1: /* Subnegotiation */ |
| + | case TS_SUB2: /* Subnegotiation */ |
| + | if (subneg(c)) |
| + | G.telstate = TS_0; |
| + | break; |
| + | } |
| } |
| - | if (G.telstate) |
| - | { |
| - | if (G.iaclen) iacflush(); |
| + | if (G.telstate) { |
| + | if (G.iaclen) iacflush(); |
| if (G.telstate == TS_0) G.telstate = 0; |
| - | |
| len = cstart; |
| } |
| |
| @@ -440,7 +430,8 @@ static void to_sga(void) |
| } else if (G.telwish == WONT) |
| return; |
| |
| - | if ((G.telflags ^= UF_SGA) & UF_SGA) /* toggle */ |
| + | G.telflags ^= UF_SGA; /* toggle */ |
| + | if (G.telflags & UF_SGA) |
| putiac2(DO, TELOPT_SGA); |
| else |
| putiac2(DONT, TELOPT_SGA); |
| @@ -550,6 +541,9 @@ static void cookmode(void) |
| tcsetattr(0, TCSADRAIN, &G.termios_def); |
| } |
| |
| + | /* poll gives smaller (-70 bytes) code */ |
| + | #define USE_POLL 1 |
| + | |
| int telnet_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| int telnet_main(int argc, char **argv) |
| { |