Ejemplo n.º 1
0
/*
 * Process an Urgent Data indication.
 */
static void
telnet_exception(ndesc_t *nd, telnet_t *tp)
{
    tp->t_flags |= TF_SYNCH | TF_URGENT;
    nq_init(tp->t_canq);
    nd_disable(nd, ND_X);
}
Ejemplo n.º 2
0
/*
 * 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;
}
Ejemplo n.º 3
0
/*
 * Process an Erase Line.
 */
static void
telnet_el(telnet_t *tp)
{
    if (tp->t_flags & (TF_OVFLCANQ | TF_SYNCH))
	return;

    nq_init(tp->t_canq);
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
/*
 * 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);
}
Ejemplo n.º 6
0
/*
 * 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;
	    if (tp->t_flags & (TF_INPUT|TF_DISCONNECT) &&
		!tp->task) /* Reenable command processing */
		tp->task = create_task(telnet_interactive, tp);
	}
    }

    if (!nq_empty(tp->t_outq))
	return;

    nq_init(tp->t_outq);

    nd_disable(nd, ND_W);
}
Ejemplo n.º 7
0
/*
 * Process a Subnegotiate End.
 */
static void
telnet_se(telnet_t *tp)
{
    tp->t_flags &= ~TF_OVFLOPTQ;
    nq_init(tp->t_optq);
}
Ejemplo n.º 8
0
/*
 * Perform Telnet protocol processing, copying the contents of the raw input
 * queue to the canonical queue.
 */
static void
telnet_input(telnet_t *tp)
{
    u_char c;
    while (!nq_empty(tp->t_rawq))
    {
        c = nq_getc(tp->t_rawq);

	switch (tp->t_state)
	{
	case TS_DATA:
            switch (c)
            {
	    case NUL:
		break;

            case BS:
		telnet_ec(tp);
                break;

	    case LF:
		telnet_eol(tp);
                return;
                
            case CR:
                tp->t_state = TS_CR;
                break;

            case DEL:
		telnet_ec(tp);
                break;

            case IAC:
                tp->t_state = TS_IAC;
                break;

            default:
		telnet_canq_putc(tp, c);
                break;
            }
	    break;

	case TS_CR:
	    telnet_eol(tp);
            tp->t_state = TS_DATA;
            return;

	case TS_IAC:
            tp->t_state = TS_DATA;
            switch (c)
            {
            case DM:
		telnet_dm(tp);
                break;

	    case AYT:
		telnet_ayt(tp);
		break;

	    case EC:
		telnet_ec(tp);
		break;

	    case EL:
		telnet_el(tp);
		break;

            case SB:
                tp->t_state = TS_IAC_SB;
                break;

            case WILL:
                tp->t_state = TS_IAC_WILL;
                break;

            case WONT:
                tp->t_state = TS_IAC_WONT;
                break;

            case DO:
                tp->t_state = TS_IAC_DO;
                break;

            case DONT:
                tp->t_state = TS_IAC_DONT;
                break;

            case IAC:
		telnet_canq_putc(tp, c);
		break;
            }
	    break;

	case TS_IAC_SB:
	    telnet_sb(tp, c);
            tp->t_state = TS_IAC_SB_DATA;
	    break;

	case TS_IAC_SB_DATA:
            switch (c)
            {
            case IAC:
                tp->t_state = TS_IAC_SB_IAC;
                break;

            default:
		telnet_optq_putc(tp, c);
                break;
            }
	    break;

	case TS_IAC_SB_IAC:
	    tp->t_state = TS_IAC_SB_DATA;
            switch (c)
            {
            case SE:
                telnet_se(tp);
                tp->t_state = TS_DATA;
                break;

            case IAC:
		telnet_optq_putc(tp, c);
                break;
            }
	    break;

	case TS_IAC_WILL:
            telnet_will(tp, c);
	    tp->t_state = TS_DATA;
	    break;

	case TS_IAC_WONT:
            telnet_wont(tp, c);
            tp->t_state = TS_DATA;
	    break;

	case TS_IAC_DO:
	    telnet_do(tp, c);
            tp->t_state = TS_DATA;
	    break;

	case TS_IAC_DONT:
            telnet_dont(tp, c);
            tp->t_state = TS_DATA;
	    break;
        }
    }

    if ((tp->t_flags & (TF_SGA | TF_GA)) == 0)
    {
	if (nq_avail(tp->t_outq) >= 2)
	{
	    tp->t_flags |= TF_GA;
	    telnet_send_ga(tp);
	}
    }

    nq_init(tp->t_rawq);
}