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 * * 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. */ int i, j; byte * p = G.buf; byte outbuf[4*DATABUFSIZE]; for (i = len, j = 0; i > 0; i--, p++) { if (*p == 0x1d) { conescape(); return; } outbuf[j++] = *p; if (*p == 0xff) outbuf[j++] = 0xff; else if (*p == 0x0d) outbuf[j++] = 0x00; } if (j > 0 ) write(G.netfd, outbuf, j); }
extern int telnet_main(int argc, char** argv) { int len; struct sockaddr_in s_in; #ifdef USE_POLL struct pollfd ufds[2]; #else fd_set readfds; int maxfd; #endif #ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN int opt; #endif #ifdef CONFIG_FEATURE_AUTOWIDTH get_terminal_width_height(0, &win_width, &win_height); #endif #ifdef CONFIG_FEATURE_TELNET_TTYPE ttype = getenv("TERM"); #endif memset(&G, 0, sizeof G); if (tcgetattr(0, &G.termios_def) < 0) exit(1); G.termios_raw = G.termios_def; cfmakeraw(&G.termios_raw); if (argc < 2) bb_show_usage(); #ifdef CONFIG_FEATURE_TELNET_AUTOLOGIN autologin = NULL; while ((opt = getopt(argc, argv, "al:")) != EOF) { switch (opt) { case 'l': autologin = optarg; break; case 'a': autologin = getenv("USER"); break; case '?': bb_show_usage(); break; } } if (optind < argc) { bb_lookup_host(&s_in, argv[optind++]); s_in.sin_port = bb_lookup_port((optind < argc) ? argv[optind++] : "telnet", "tcp", 23); if (optind < argc) bb_show_usage(); } else bb_show_usage(); #else bb_lookup_host(&s_in, argv[1]); s_in.sin_port = bb_lookup_port((argc == 3) ? argv[2] : "telnet", "tcp", 23); #endif G.netfd = xconnect(&s_in); setsockopt(G.netfd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof one); signal(SIGINT, fgotsig); #ifdef USE_POLL ufds[0].fd = 0; ufds[1].fd = G.netfd; ufds[0].events = ufds[1].events = POLLIN; #else FD_ZERO(&readfds); FD_SET(0, &readfds); FD_SET(G.netfd, &readfds); maxfd = G.netfd + 1; #endif while (1) { #ifndef USE_POLL fd_set rfds = readfds; switch (select(maxfd, &rfds, NULL, NULL, NULL)) #else switch (poll(ufds, 2, -1)) #endif { case 0: /* timeout */ case -1: /* error, ignore and/or log something, bay go to loop */ if (G.gotsig) conescape(); else sleep(1); break; default: #ifdef USE_POLL if (ufds[0].revents) /* well, should check POLLIN, but ... */ #else if (FD_ISSET(0, &rfds)) #endif { len = read(0, G.buf, DATABUFSIZE); if (len <= 0) doexit(0); TRACE(0, ("Read con: %d\n", len)); handlenetoutput(len); } #ifdef USE_POLL if (ufds[1].revents) /* well, should check POLLIN, but ... */ #else if (FD_ISSET(G.netfd, &rfds)) #endif { len = read(G.netfd, G.buf, DATABUFSIZE); if (len <= 0) { WriteCS(1, "Connection closed by foreign host.\r\n"); doexit(1); } TRACE(0, ("Read netfd (%d): %d\n", G.netfd, len)); handlenetinput(len); } } } }
int telnet_main(int argc, char **argv) { char *host; int port; int len; #ifdef USE_POLL struct pollfd ufds[2]; #else fd_set readfds; int maxfd; #endif INIT_G(); #if ENABLE_FEATURE_AUTOWIDTH get_terminal_width_height(0, &G.win_width, &G.win_height); #endif #if ENABLE_FEATURE_TELNET_TTYPE G.ttype = getenv("TERM"); #endif if (tcgetattr(0, &G.termios_def) >= 0) { G.do_termios = 1; G.termios_raw = G.termios_def; cfmakeraw(&G.termios_raw); } if (argc < 2) bb_show_usage(); #if ENABLE_FEATURE_TELNET_AUTOLOGIN if (1 & getopt32(argv, "al:", &G.autologin)) G.autologin = getenv("USER"); argv += optind; #else argv++; #endif if (!*argv) bb_show_usage(); host = *argv++; port = bb_lookup_port(*argv ? *argv++ : "telnet", "tcp", 23); if (*argv) /* extra params?? */ bb_show_usage(); G.netfd = create_and_connect_stream_or_die(host, port); setsockopt(G.netfd, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); signal(SIGINT, fgotsig); #ifdef USE_POLL ufds[0].fd = 0; ufds[1].fd = G.netfd; ufds[0].events = ufds[1].events = POLLIN; #else FD_ZERO(&readfds); FD_SET(STDIN_FILENO, &readfds); FD_SET(G.netfd, &readfds); maxfd = G.netfd + 1; #endif while (1) { #ifndef USE_POLL fd_set rfds = readfds; switch (select(maxfd, &rfds, NULL, NULL, NULL)) #else switch (poll(ufds, 2, -1)) #endif { case 0: /* timeout */ case -1: /* error, ignore and/or log something, bay go to loop */ if (G.gotsig) conescape(); else sleep(1); break; default: #ifdef USE_POLL if (ufds[0].revents) /* well, should check POLLIN, but ... */ #else if (FD_ISSET(STDIN_FILENO, &rfds)) #endif { len = read(STDIN_FILENO, G.buf, DATABUFSIZE); if (len <= 0) doexit(EXIT_SUCCESS); TRACE(0, ("Read con: %d\n", len)); handlenetoutput(len); } #ifdef USE_POLL if (ufds[1].revents) /* well, should check POLLIN, but ... */ #else if (FD_ISSET(G.netfd, &rfds)) #endif { len = read(G.netfd, G.buf, DATABUFSIZE); if (len <= 0) { write_str(1, "Connection closed by foreign host\r\n"); doexit(EXIT_FAILURE); } TRACE(0, ("Read netfd (%d): %d\n", G.netfd, len)); handlenetinput(len); } } } }
extern int telnet_main(int argc, char** argv) { struct in_addr host; int port; int len; #ifdef USE_POLL struct pollfd ufds[2]; #else fd_set readfds; int maxfd; #endif #ifdef BB_FEATURE_AUTOWIDTH struct winsize winp; if( ioctl(0, TIOCGWINSZ, &winp) == 0 ) { win_width = winp.ws_col; win_height = winp.ws_row; } #endif #ifdef BB_FEATURE_TELNET_TTYPE ttype = getenv("TERM"); #endif memset(&G, 0, sizeof G); if (tcgetattr(0, &G.termios_def) < 0) exit(1); G.termios_raw = G.termios_def; cfmakeraw(&G.termios_raw); if (argc < 2) show_usage(); port = (argc > 2)? getport(argv[2]): 23; host = getserver(argv[1]); G.netfd = remote_connect(host, port); signal(SIGINT, fgotsig); #ifdef USE_POLL ufds[0].fd = 0; ufds[1].fd = G.netfd; ufds[0].events = ufds[1].events = POLLIN; #else FD_ZERO(&readfds); FD_SET(0, &readfds); FD_SET(G.netfd, &readfds); maxfd = G.netfd + 1; #endif while (1) { #ifndef USE_POLL fd_set rfds = readfds; switch (select(maxfd, &rfds, NULL, NULL, NULL)) #else switch (poll(ufds, 2, -1)) #endif { case 0: /* timeout */ case -1: /* error, ignore and/or log something, bay go to loop */ if (G.gotsig) conescape(); else sleep(1); break; default: #ifdef USE_POLL if (ufds[0].revents) /* well, should check POLLIN, but ... */ #else if (FD_ISSET(0, &rfds)) #endif { len = read(0, G.buf, DATABUFSIZE); if (len <= 0) doexit(0); TRACE(0, ("Read con: %d\n", len)); handlenetoutput(len); } #ifdef USE_POLL if (ufds[1].revents) /* well, should check POLLIN, but ... */ #else if (FD_ISSET(G.netfd, &rfds)) #endif { len = read(G.netfd, G.buf, DATABUFSIZE); if (len <= 0) { WriteCS(1, "Connection closed by foreign host.\r\n"); doexit(1); } TRACE(0, ("Read netfd (%d): %d\n", G.netfd, len)); handlenetinput(len); } } } }