int telnet_main(int argc UNUSED_PARAM, 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 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(); xmove_fd(create_and_connect_stream_or_die(host, port), netfd); setsockopt(netfd, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); signal(SIGINT, record_signo); #ifdef USE_POLL ufds[0].fd = 0; ufds[1].fd = netfd; ufds[0].events = ufds[1].events = POLLIN; #else FD_ZERO(&readfds); FD_SET(STDIN_FILENO, &readfds); FD_SET(netfd, &readfds); maxfd = 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 (bb_got_signal) con_escape(); else sleep(1); break; default: #ifdef USE_POLL if (ufds[0].revents & POLLIN) #else if (FD_ISSET(STDIN_FILENO, &rfds)) #endif { len = safe_read(STDIN_FILENO, G.buf, DATABUFSIZE); if (len <= 0) doexit(EXIT_SUCCESS); TRACE(0, ("Read con: %d\n", len)); handle_net_output(len); } #ifdef USE_POLL if (ufds[1].revents & POLLIN) #else if (FD_ISSET(netfd, &rfds)) #endif { len = safe_read(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", netfd, len)); handle_net_input(len); } } } /* while (1) */ }
int telnet_main(int argc UNUSED_PARAM, char **argv) { char *host; int port; int len; struct pollfd ufds[2]; 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 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(); xmove_fd(create_and_connect_stream_or_die(host, port), netfd); setsockopt_keepalive(netfd); signal(SIGINT, record_signo); ufds[0].fd = STDIN_FILENO; ufds[0].events = POLLIN; ufds[1].fd = netfd; ufds[1].events = POLLIN; while (1) { if (poll(ufds, 2, -1) < 0) { /* error, ignore and/or log something, bay go to loop */ if (bb_got_signal) con_escape(); else sleep(1); continue; } // FIXME: reads can block. Need full bidirectional buffering. if (ufds[0].revents) { len = safe_read(STDIN_FILENO, G.buf, DATABUFSIZE); if (len <= 0) doexit(EXIT_SUCCESS); TRACE(0, ("Read con: %d\n", len)); handle_net_output(len); } if (ufds[1].revents) { len = safe_read(netfd, G.buf, DATABUFSIZE); if (len <= 0) { full_write1_str("Connection closed by foreign host\r\n"); doexit(EXIT_FAILURE); } TRACE(0, ("Read netfd (%d): %d\n", netfd, len)); handle_net_input(len); } } /* while (1) */ }