- addr.sin_family = host->h_addrtype;
- memcpy(&addr.sin_addr, host->h_addr, sizeof(addr.sin_addr));
- addr.sin_port = htons(port);
-
- printf("Trying %s...\n", inet_ntoa(addr.sin_addr));
-
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) PERROR("socket");
- if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
- PERROR("connect");
- printf("Connected to %s\n", hostname);
- printf("Escape character is ^]\n");
-
- signal(SIGINT, sighandler);
- signal(SIGQUIT, sighandler);
- signal(SIGPIPE, sighandler);
- signal(SIGWINCH, sighandler);
-
- /* make inputs nonblocking */
- c = 1;
- ioctl(s, FIONBIO, &c);
- ioctl(STDIN, FIONBIO, &c);
-
- if (port == TELNETPORT) telnet_setoptions(s);
-
- /* shuttle data back and forth between tty and socket */
- while (1) {
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
-
- FD_SET(s, &rfds);
- /* FD_SET(s, &wfds); */
- FD_SET(STDIN, &rfds);
- /* FD_SET(STDOUT, &wfds); */
-
- if ((c = select(s+1, &rfds, &wfds, 0, 0))) {
- if (c == -1) {
- /* handle errors */
- PERROR("select");
- }
- if (FD_ISSET(s, &rfds)) {
- /* input from network */
- FD_CLR(s, &rfds);
- c = telnet_recv(s, STDOUT);
- if (c == 0) break;
- if (c < 0) PERROR("telnet_recv");
- }
- if (FD_ISSET(STDIN, &rfds)) {
- /* input from tty */
- FD_CLR(STDIN, &rfds);
- c = telnet_send(STDIN, s);
- if (c == 0) break;
- if (c < 0) PERROR("telnet_send");
- }
+ if (G.telwish == DONT)
+ return;
+
+ if (G.telflags & UF_ECHO) {
+ if (G.telwish == WILL)
+ return;
+ } else if (G.telwish == WONT)
+ return;
+
+ if (G.charmode != CHM_OFF)
+ G.telflags ^= UF_ECHO;
+
+ if (G.telflags & UF_ECHO)
+ put_iac2(DO, TELOPT_ECHO);
+ else
+ put_iac2(DONT, TELOPT_ECHO);
+
+ setConMode();
+ full_write1_str("\r\n"); /* sudden modec */
+}
+
+static void to_sga(void)
+{
+ /* daemon always sends will/wont, client do/dont */
+
+ if (G.telflags & UF_SGA) {
+ if (G.telwish == WILL)
+ return;
+ } else if (G.telwish == WONT)
+ return;
+
+ G.telflags ^= UF_SGA; /* toggle */
+ if (G.telflags & UF_SGA)
+ put_iac2(DO, TELOPT_SGA);
+ else
+ put_iac2(DONT, TELOPT_SGA);
+}
+
+#if ENABLE_FEATURE_TELNET_TTYPE
+static void to_ttype(void)
+{
+ /* Tell server we will (or won't) do TTYPE */
+ if (G.ttype)
+ put_iac2(WILL, TELOPT_TTYPE);
+ else
+ put_iac2(WONT, TELOPT_TTYPE);
+}
+#endif
+
+#if ENABLE_FEATURE_TELNET_AUTOLOGIN
+static void to_new_environ(void)
+{
+ /* Tell server we will (or will not) do AUTOLOGIN */
+ if (G.autologin)
+ put_iac2(WILL, TELOPT_NEW_ENVIRON);
+ else
+ put_iac2(WONT, TELOPT_NEW_ENVIRON);
+}
+#endif
+
+#if ENABLE_FEATURE_TELNET_WIDTH
+static void to_naws(void)
+{
+ /* Tell server we will do NAWS */
+ put_iac2(WILL, TELOPT_NAWS);
+}
+#endif
+
+static void telopt(byte c)
+{
+ switch (c) {
+ case TELOPT_ECHO:
+ to_echo(); break;
+ case TELOPT_SGA:
+ to_sga(); break;
+#if ENABLE_FEATURE_TELNET_TTYPE
+ case TELOPT_TTYPE:
+ to_ttype(); break;
+#endif
+#if ENABLE_FEATURE_TELNET_AUTOLOGIN
+ case TELOPT_NEW_ENVIRON:
+ to_new_environ(); break;
+#endif
+#if ENABLE_FEATURE_TELNET_WIDTH
+ case TELOPT_NAWS:
+ to_naws();
+ put_iac_naws(c, G.win_width, G.win_height);
+ break;
+#endif
+ default:
+ to_notsup(c);
+ break;
+ }
+}
+
+/* subnegotiation -- ignore all (except TTYPE,NAWS) */
+static void subneg(byte c)
+{
+ switch (G.telstate) {
+ case TS_SUB1:
+ if (c == IAC)
+ G.telstate = TS_SUB2;
+#if ENABLE_FEATURE_TELNET_TTYPE
+ else
+ if (c == TELOPT_TTYPE && G.ttype)
+ put_iac_subopt(TELOPT_TTYPE, G.ttype);
+#endif
+#if ENABLE_FEATURE_TELNET_AUTOLOGIN
+ else
+ if (c == TELOPT_NEW_ENVIRON && G.autologin)
+ put_iac_subopt_autologin();
+#endif
+ break;
+ case TS_SUB2:
+ if (c == SE) {
+ G.telstate = TS_COPY;
+ return;