filter_telnet.c
author viric@mandarina
Thu, 21 Aug 2008 23:21:22 +0200
changeset 93 7d9b7a6da507
parent 53 07500c5c53cb
permissions -rw-r--r--
Removing direct references to /usr in the Makefile, for nix.

/*
    Terminal Mixer - multi-point multi-user access to terminal applications
    Copyright (C) 2007  LluĂ­s Batlle i Rossell

    Please find the license in the provided COPYING file.
*/
#include <stdlib.h>
#include "main.h"
#include "filter.h"

enum TState
{
    NOTHING,
    RECEIVED_IAC,
    RECEIVED_OPT,
    SUBNEGOTIATED
};

enum Chars
{
    IAC = 255,
    SB = 250,
    SE = 240
};

struct FTelnet
{
    struct FFilter base;
    enum TState state;
};

static void ftelnet_reset(struct FFilter *ff)
{
    struct FTelnet *ft = (struct FTelnet *) ff;
    ft->state = NOTHING;
}

static int ftelnet_function(struct FFilter *ff, unsigned char c)
{
    struct FTelnet *ft = (struct FTelnet *) ff;

    switch (ft->state)
    {
        case NOTHING:
            if (c == IAC)
            {
                ft->state = RECEIVED_IAC;
                ft->base.matched++;
            }
            break;
        case RECEIVED_IAC:
            if (c == SB)
            {
                ft->state = SUBNEGOTIATED;
                ft->base.matched++;
            } else /* Received the control char */
            {
                ft->state = RECEIVED_OPT;
                ft->base.matched++;
            }
            break;
        case RECEIVED_OPT:
            ft->base.matched++;
            return 1;
            break;
        case SUBNEGOTIATED:
            ft->base.matched++;
            if (c == SE)
            {
                return 1;
            }
            break;
    }
    return 0;
}

struct FFilter *new_ftelnet()
{
    struct FTelnet *ft;
    ft = (struct FTelnet *) malloc(sizeof(*ft));

    ft->state = NOTHING;
    ft->base.matched = 0;
    ft->base.function = ftelnet_function;
    ft->base.reset = ftelnet_reset;
    ft->base.callback = 0;

    return (struct FFilter *) ft;
}