/* * Append a character string to the output queue, encapsulating it * appropriately. * Returns 1 in case the message is truncated. */ int telnet_output(telnet_t *tp, u_char *cp) { int len; u_char c, *bp, buf[TELNET_OUTQ_SIZE + 3]; if (tp->t_flags & TF_OVFLOUTQ) return 1; bp = buf; while (bp < &buf[TELNET_OUTQ_SIZE] && *cp != '\0') { c = *cp++; switch (c) { case LF: *bp++ = CR; break; case IAC: *bp++ = IAC; break; } *bp++ = c; } *bp = '\0'; len = bp - buf; if (len == 0) return 0; if (nq_len(tp->t_outq) + len >= TELNET_OUTQ_HIWAT) { telnet_flush(tp); if (nq_len(tp->t_outq) + len >= TELNET_OUTQ_HIWAT) { tp->t_flags |= TF_OVFLOUTQ; buf[TELNET_OUTQ_HIWAT - nq_len(tp->t_outq)] = '\0'; nq_puts(tp->t_outq, buf); nq_puts(tp->t_outq, (u_char *)"*** Truncated. ***\r\n"); telnet_enabw(tp); return 1; } } nq_puts(tp->t_outq, buf); telnet_enabw(tp); return 0; }
/* * Process an Are You There. */ static void telnet_ayt(telnet_t *tp) { u_char version[13]; sprintf(version, "[%6.6s%02d]\r\n", GAME_VERSION, PATCH_LEVEL); nq_puts(tp->t_outq, version); telnet_enabw(tp); }
/* * Write data from the output queue to the Telnet session. */ static void telnet_write(ndesc_t *nd, telnet_t *tp) { if (!nq_empty(tp->t_outq)) { if (nq_send(tp->t_outq, nd_fd(nd), &tp->t_sblen) == -1) { switch (errno) { case EWOULDBLOCK: case EINTR: case EPROTO: break; default: telnet_disconnect(tp); return; } } } if (tp->t_flags & TF_OVFLOUTQ) { if (nq_len(tp->t_outq) < TELNET_OUTQ_LOWAT) { tp->t_flags &= ~TF_OVFLOUTQ; nq_puts(tp->t_outq, (u_char *)"*** Truncated. ***\r\n"); } } if (tp->t_flags & TF_FLOWC) { if (nq_len(tp->t_outq) < TELNET_OUTQ_HIWAT) { tp->t_flags &= ~TF_FLOWC; nd_enable(nd, ND_C); } } if (!nq_empty(tp->t_outq)) return; nq_init(tp->t_outq); tp->t_flags |= TF_ENABW; nd_disable(nd, ND_W); }