diff options
-rw-r--r-- | loader/loader.c | 6 | ||||
-rw-r--r-- | loader/telnet.c | 80 | ||||
-rw-r--r-- | loader/telnet.h | 2 | ||||
-rw-r--r-- | loader/telnetd.c | 10 |
4 files changed, 89 insertions, 9 deletions
diff --git a/loader/loader.c b/loader/loader.c index 5e65504b7..ea01494fb 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -3019,8 +3019,10 @@ int main(int argc, char ** argv) { return 1; } - kickstartNetwork(&ksNetDevice, &netDev, NULL, flags); - writeNetInfo("/tmp/netinfo", &netDev, &kd); + if (!FL_TESTING(flags)) { + kickstartNetwork(&ksNetDevice, &netDev, NULL, flags); + writeNetInfo("/tmp/netinfo", &netDev, &kd); + } if (!beTelnet(flags)) flags |= LOADER_FLAGS_TEXT; } diff --git a/loader/telnet.c b/loader/telnet.c index bf53476aa..5e8f5a25f 100644 --- a/loader/telnet.c +++ b/loader/telnet.c @@ -20,6 +20,7 @@ /* Shamelessly stolen from ttywatch -- oot */ +#include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -36,6 +37,7 @@ #define SE "\xf0" #define ECHO "\x01" #define SUPPRESS_GO_AHEAD "\x03" +#define TERMINAL_TYPE "\x18" #define LINEMODE "\x22" #define NEWENVIRON "\x27" #define MODE "\x01" @@ -52,7 +54,12 @@ * too. */ void -telnet_negotiate(int socket) { +telnet_negotiate(int socket, char ** term_type_ptr) { + char ch; + int done = 0; + char * termType = NULL; + int termLength = 0, termAlloced = 0; + enum { ST_NONE, ST_TERMTYPE, ST_TERMSIZE } state; char request[]= IAC DONT ECHO IAC WILL ECHO @@ -60,17 +67,79 @@ telnet_negotiate(int socket) { IAC DO SUPPRESS_GO_AHEAD IAC DONT NEWENVIRON IAC WONT NEWENVIRON - IAC DO LINEMODE - IAC SB LINEMODE MODE "0" IAC SE + IAC WONT LINEMODE + IAC SB TERMINAL_TYPE "\x01" IAC SE ; + write(socket, request, sizeof(request)-1); + + /* Read from the terminal until we get the terminal type. This will + do bad things if the client doesn't send the terminal type, but + those clients have existed for aeons (right?) */ + + do { + read(socket, &ch, 1); + if (ch != '\xff') { + printf("got 0x%x\n", ch); + abort(); + } + + printf("got IAC\n"); + + read(socket, &ch, 1); /* command */ + + printf("command %d\n", (unsigned char) ch); + + if (ch != '\xfa') { + read(socket, &ch, 1); /* verb */ + printf("verb %d\n", (unsigned char) ch); + continue; + } + + read(socket, &ch, 1); /* suboption */ + printf("suboption %d\n", (unsigned char) ch); + if (ch == '\x18') { + state = ST_TERMTYPE; + read(socket, &ch, 1); /* should be 0x0! */ + done = 1; + } else { + state = ST_NONE;; + } + + read(socket, &ch, 1); /* data */ + while (ch != '\xff') { + printf("got %d '%c'\n", (unsigned char) ch, ch); + + if (state == ST_TERMTYPE) { + if (termAlloced == termLength) { + termAlloced += 10; + termType = realloc(termType, termAlloced + 1); + } + + termType[termLength++] = tolower(ch); + } + + read(socket, &ch, 1); /* data */ + } + + read(socket, &ch, 1); /* should be a SE */ + printf("ended on %d\n", (unsigned char) ch); + + printf("---\n"); + + termType[termLength] = '\0'; + + } while (!done); + + printf("term is %s\n", termType); + + if (term_type_ptr) *term_type_ptr = termType; } int telnet_process_input(telnet_state * ts, char *data, int len) { char *s, *d; /* source, destination */ -# define DEBUG_TELNET 0 # if DEBUG_TELNET printf("\nprinting packet:"); for (s=data; s<data+len; s++) { @@ -135,7 +204,7 @@ telnet_process_input(telnet_state * ts, char *data, int len) { *ts = TS_DATA; } else { # if DEBUG_TELNET - printf("IAC without SE in SB\n"); + printf("IAC without SE in SB (offset %d)\n", s-data-1); # endif /* DEBUG_TELNET */ *ts = TS_SB; } @@ -159,6 +228,7 @@ telnet_process_input(telnet_state * ts, char *data, int len) { } printf("\n"); #endif /* DEBUG_TELNET */ + return len; } diff --git a/loader/telnet.h b/loader/telnet.h index f43ed2b65..d1a7f990a 100644 --- a/loader/telnet.h +++ b/loader/telnet.h @@ -30,7 +30,7 @@ typedef enum { } telnet_state; void -telnet_negotiate(int socket); +telnet_negotiate(int socket, char ** term_type_ptr); int telnet_process_input(telnet_state * ts, char *data, int len); void diff --git a/loader/telnetd.c b/loader/telnetd.c index a496a2971..bd1f3a539 100644 --- a/loader/telnetd.c +++ b/loader/telnetd.c @@ -38,6 +38,7 @@ int beTelnet(int flags) { struct pollfd fds[3]; telnet_state ts = TS_DATA; struct termios orig, new; + char * termType; if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { logMessage("socket: %s", strerror(errno)); @@ -72,7 +73,12 @@ int beTelnet(int flags) { close(sock); - telnet_negotiate(conn); + telnet_negotiate(conn, &termType); + + printf("got term type %s\n", termType); + printf("term is currently %s\n", getenv("TERM")); + + sleep(3); masterFd = open("/dev/ptyp0", O_RDWR); if (masterFd < 0) { @@ -148,6 +154,8 @@ int beTelnet(int flags) { dup(0); /* brand new tty! */ + setenv("TERM", termType, 1); + startNewt(flags); return 0; |