static void telnet_interactive(void *vp) { telnet_t *tp = vp; char *cp; if (!(tp->t_flags & TF_ATTACH)) { tp->task = NULL; telnet_shutdown(tp->t_nd, tp); return; } if (tp->t_flags & TF_DISCONNECT) { tp->t_flags &= ~TF_DISCONNECT; if (tp->t_ip) remove_interactive(tp->t_ip, 1); } if (!(tp->t_flags & TF_ATTACH)) { tp->task = NULL; telnet_shutdown(tp->t_nd, tp); return; } if (tp->t_flags & TF_OVFLOUTQ) { tp->task = NULL; return; } if (tp->t_flags & TF_INPUT) { tp->t_flags &= ~TF_INPUT; if (nq_full(tp->t_canq)) cp = ""; else cp = (char *)nq_rptr(tp->t_canq); interactive_input(tp->t_ip, cp); nq_init(tp->t_canq); } if (!(tp->t_flags & TF_ATTACH)) { tp->task = NULL; telnet_shutdown(tp->t_nd, tp); return; } tp->t_flags &= ~TF_GA; telnet_readbytes(tp->t_nd, tp); telnet_input(tp); if (!(tp->t_flags & TF_ATTACH)) { tp->task = NULL; telnet_shutdown(tp->t_nd, tp); return; } if (tp->t_flags & (TF_INPUT|TF_DISCONNECT)) { reschedule_task(tp->task); return; } tp->task = NULL; nd_enable(tp->t_nd, ND_R); }
/* * Telnet session cleanup processing. */ static void telnet_cleanup(ndesc_t *nd, telnet_t *tp) { if ((tp->t_flags & TF_ATTACH) == 0) { telnet_shutdown(nd, tp); } else { telnet_input(nd, tp); } }
/* * Accept a new Telnet connection. */ static void telnet_accept(void *vp) { ndesc_t *nd = vp; int addrlen, s; struct sockaddr_in addr; telnet_t *tp; void *ip; nd_enable(nd, ND_R); addrlen = sizeof (addr); s = accept(nd_fd(nd), (struct sockaddr *)&addr, &addrlen); if (s == -1) { switch (errno) { default: warning("telnet_accept: accept() errno = %d. ip: %s\n", errno, inet_ntoa(addr.sin_addr)); case EWOULDBLOCK: case EINTR: case EPROTO: return; } } enable_nbio(s); enable_oobinline(s); enable_nodelay(s); enable_lowdelay(s); enable_keepalive(s); set_rcvsize(s, TELNET_RCVBUF_SIZE); set_sndsize(s, TELNET_SNDBUF_SIZE); tp = telnet_alloc(); tp->t_nd = nd_attach(s, telnet_read, telnet_write, telnet_exception, NULL, telnet_shutdown, tp); ip = (void *)new_player(tp, &addr, addrlen); if (ip == NULL) { telnet_shutdown(tp->t_nd, tp); } else { telnet_attach(tp, ip); nd_enable(tp->t_nd, ND_R | ND_X); } }