/* * Read data from the Telnet session to the raw input queue. */ static void telnet_read(ndesc_t *nd, telnet_t *tp) { int cc; if (!nq_full(tp->t_rawq)) { if (tp->t_flags & TF_URGENT) { if (at_mark(nd_fd(nd))) { tp->t_flags &= ~TF_URGENT; nd_enable(nd, ND_X); } } cc = nq_recv(tp->t_rawq, nd_fd(nd), &tp->t_rblen); if (cc == -1) { switch (errno) { case EWOULDBLOCK: case EINTR: case EPROTO: break; default: telnet_disconnect(tp); return; } } if (cc == 0) { telnet_disconnect(tp); return; } if ((tp->t_flags & TF_FLOWC) == 0) nd_enable(nd, ND_C); telnet_enabr(tp); if (!nq_full(tp->t_rawq)) return; } tp->t_flags |= TF_ENABR; nd_disable(nd, ND_R); }
/* * Send the contents of the canonical queue to the interactive object. */ static void telnet_eol(telnet_t *tp) { char *cp; if (tp->t_flags & TF_SYNCH) return; if (nq_full(tp->t_canq)) { tp->t_flags &= ~TF_OVFLCANQ; cp = ""; } else { nq_putc(tp->t_canq, '\0'); cp = (char *)nq_rptr(tp->t_canq); } if (tp->t_flags & TF_ATTACH) interactive_input(tp->t_ip, cp); nq_init(tp->t_canq); tp->t_flags &= ~TF_GA; }
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); }
/* * Append a character to the option queue. */ static void telnet_optq_putc(telnet_t *tp, u_char c) { if (tp->t_flags & TF_OVFLOPTQ) return; if (!nq_full(tp->t_optq)) nq_putc(tp->t_optq, c); else tp->t_flags |= TF_OVFLOPTQ; }
/* * Send the contents of the canonical queue to the interactive object. */ static void telnet_eol(telnet_t *tp) { if (tp->t_flags & TF_SYNCH) return; if (nq_full(tp->t_canq)) { tp->t_flags &= ~TF_OVFLCANQ; } else { nq_putc(tp->t_canq, '\0'); } tp->t_flags |= TF_INPUT; }
/* * Append a character to the canonical queue. */ static void telnet_canq_putc(telnet_t *tp, u_char c) { if (tp->t_flags & (TF_OVFLCANQ | TF_SYNCH)) return; if (!nq_full(tp->t_canq)) { nq_putc(tp->t_canq, c); } else { tp->t_flags |= TF_OVFLCANQ; if (nq_avail(tp->t_outq) > 0) { nq_putc(tp->t_outq, BEL); telnet_enabw(tp); } } }