area/
build/testing/
log/
player/
player/backup/
/*
 * Telent.c For Lurking Fear
 */
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <glib.h>
#include <merc.h>
#include <telnet.h>

bool get_telnet_optns(unsigned char option)
{
	bool supported = FALSE;
	switch (option)
	{
		case TELOPT_ECHO:
			supported = TRUE;
			break;
		default:
			supported = FALSE;
			break;
	}
	return supported;
}

/*
 * Send back a standard reply to client
 */
void send_reply(DESCRIPTOR_DATA *d,unsigned char cmd, unsigned char option)
{
	char reply[3];
	reply[0] = IAC;
	reply[1] = cmd;
	reply[2] = option;
	write_to_descriptor(d->descriptor,(char *)reply,3); 
}
//
//Send all the options we want to support to the client
void init_telnet_optns(DESCRIPTOR_DATA *d)
{
	//send_reply(d,TC_DO,option);
}

//Client is asking for a option
void process_do(DESCRIPTOR_DATA *d, unsigned char option)
{
	if (get_telnet_optns(option))
	{
		if (d->telnet_option[option] != ACTIVE)
		{
			d->telnet_option[option] = ACTIVE;
			send_reply(d,TC_WILL,option);
		}
	}
	else
	{
		send_reply(d,TC_WONT,option);
	}
}

void process_dont(DESCRIPTOR_DATA *d, unsigned char option)
{
	if (d->telnet_option[option] != INACTIVE)
    {
        d->telnet_option[option] = INACTIVE;
        send_reply(d,TC_WONT,option);
    }
}

void process_will(DESCRIPTOR_DATA *d, unsigned char option)
{
}

void process_wont(DESCRIPTOR_DATA *d, unsigned char option)
{
}

int parse_telnetcommand(DESCRIPTOR_DATA *d)
{
	GString *intel;
	int i;
	int offset;
	unsigned char c;

	intel = g_string_new("");
	intel = g_string_assign(intel,d->inbuf);

	offset = 0;
	for (i = 0; i < intel->len; i++)
	{
		c = intel->str[i];
		switch (d->s_state)
		{
			case TOP_LEVEL:
				if (c == IAC)
					d->s_state = SEEN_IAC;
				break;
			case SEEN_SB:
				d->s_state = SUBNEGOT;
				break;
			case SUBNEGOT:
				if (c == TC_SE)
					d->s_state = TOP_LEVEL;
				break;
			case SEEN_SE:
				d->s_state = TOP_LEVEL;
				break;
			case SEEN_IAC:
				if (c == TC_DO)
					d->s_state = SEEN_DO;
				else if (c == TC_DONT)
					d->s_state = SEEN_DONT;
				else if (c == TC_WILL)
					d->s_state = SEEN_WILL;
				else if (c == TC_WONT)
					d->s_state = SEEN_WONT;
				else if (c == TC_SB)
					d->s_state = SEEN_SB;
				break;
			case SEEN_DO:
				process_do(d,c);
				d->s_state = TOP_LEVEL;
				offset = i;
				offset++;
				break;
			case SEEN_DONT:
				process_dont(d,c);
				d->s_state = TOP_LEVEL;
				offset = i;
				offset++;
				break;
			case SEEN_WILL:
				process_will(d,c);
				d->s_state = TOP_LEVEL;
				offset = i;
				offset++;
				break;
			case SEEN_WONT:
				process_wont(d,c);
				d->s_state = TOP_LEVEL;
				offset = i;
				offset++;
				break;
			default:
				break;
		}
	}
	g_string_free(intel,TRUE);
	return offset;
}