/*
 * Sean Middleditch
 * sean@sourcemud.org
 *
 * The author or authors of this code dedicate any and all copyright interest
 * in this code to the public domain. We make this dedication for the benefit
 * of the public at large and to the detriment of our heirs and successors. We
 * intend this dedication to be an overt act of relinquishment in perpetuity of
 * all present and future rights to this code under copyright law. 
 */

#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>

#ifdef HAVE_ZLIB
#include "zlib.h"
#endif

#include "libtelnet.h"

/* RFC1143 state names */
#define RFC1143_NO 0x00
#define RFC1143_YES 0x01

#define RFC1143_WANT 0x02
#define RFC1143_OP 0x04

#define RFC1143_WANTNO (RFC1143_WANT|RFC1143_YES)
#define RFC1143_WANTYES (RFC1143_WANT|RFC1143_NO)
#define RFC1143_WANTNO_OP (RFC1143_WANTNO|RFC1143_OP)
#define RFC1143_WANTYES_OP (RFC1143_WANTYES|RFC1143_OP)

/* buffer sizes */
static const unsigned int _buffer_sizes[] = {
	0,
	512,
	2048,
	8192,
	16384,
};
static const unsigned int _buffer_sizes_count = sizeof(_buffer_sizes) /
		sizeof(_buffer_sizes[0]);

/* event dispatch helper; return value is value of the accept field of the
 * event struct after dispatch; used for the funky REQUEST event */
static int _event(libtelnet_t *telnet, libtelnet_event_type_t type,
		unsigned char command, unsigned char telopt, unsigned char *buffer,
		unsigned int size) {
	libtelnet_event_t ev;
	ev.buffer = buffer;
	ev.size = size;
	ev.type = type;
	ev.command = command;
	ev.telopt = telopt;
	ev.accept = 0;

	telnet->eh(telnet, &ev, telnet->ud);

	return ev.accept;
}

/* error generation function */
static libtelnet_error_t _error(libtelnet_t *telnet, unsigned line,
		const char* func, libtelnet_error_t err, int fatal, const char *fmt,
		...) {
	char buffer[512];
	va_list va;

	/* format error intro */
	snprintf(buffer, sizeof(buffer), "%s:%u in %s: ", __FILE__, line, func);

	va_start(va, fmt);
	vsnprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer),
			fmt, va);
	va_end(va);

	_event(telnet, fatal ? LIBTELNET_EV_ERROR : LIBTELNET_EV_WARNING, err,
			0, (unsigned char *)buffer, strlen(buffer));
	
	return err;
}

/* initialize the zlib box for a telnet box; if deflate is non-zero, it
 * initializes zlib for delating (compression), otherwise for inflating
 * (decompression).  returns LIBTELNET_EOK on success, something else on
 * failure.
 */
libtelnet_error_t _init_zlib(libtelnet_t *telnet, int deflate, int err_fatal) {
	z_stream *z;
	int rs;

	/* if compression is already enabled, fail loudly */
	if (telnet->z != 0)
		return _error(telnet, __LINE__, __func__, LIBTELNET_EBADVAL,
				err_fatal, "cannot initialize compression twice");

	/* allocate zstream box */
	if ((z= (z_stream *)calloc(1, sizeof(z_stream))) == 0)
		return _error(telnet, __LINE__, __func__, LIBTELNET_ENOMEM, err_fatal,
				"malloc() failed: %s", strerror(errno));

	/* initialize */
	if (deflate) {
		if ((rs = deflateInit(z, Z_DEFAULT_COMPRESSION)) != Z_OK) {
			free(z);
			return _error(telnet, __LINE__, __func__, LIBTELNET_ECOMPRESS,
					err_fatal, "deflateInit() failed: %s", zError(rs));
		}
		telnet->flags |= LIBTELNET_PFLAG_DEFLATE;
	} else {
		if ((rs = inflateInit(z)) != Z_OK) {
			free(z);
			return _error(telnet, __LINE__, __func__, LIBTELNET_ECOMPRESS,
					err_fatal, "inflateInit() failed: %s", zError(rs));
		}
		telnet->flags &= ~LIBTELNET_PFLAG_DEFLATE;
	}

	telnet->z = z;

	return LIBTELNET_EOK;
}

/* push bytes out, compressing them first if need be */
static void _send(libtelnet_t *telnet, unsigned char *buffer,
		unsigned int size) {
#ifdef HAVE_ZLIB
	/* if we have a deflate (compression) zlib box, use it */
	if (telnet->z != 0 && telnet->flags & LIBTELNET_PFLAG_DEFLATE) {
		unsigned char deflate_buffer[1024];
		int rs;

		/* initialize z state */
		telnet->z->next_in = buffer;
		telnet->z->avail_in = size;
		telnet->z->next_out = deflate_buffer;
		telnet->z->avail_out = sizeof(deflate_buffer);

		/* deflate until buffer exhausted and all output is produced */
		while (telnet->z->avail_in > 0 || telnet->z->avail_out == 0) {
			/* compress */
			if ((rs = deflate(telnet->z, Z_SYNC_FLUSH)) != Z_OK) {
				_error(telnet, __LINE__, __func__, LIBTELNET_ECOMPRESS, 1,
						"deflate() failed: %s", zError(rs));
				deflateEnd(telnet->z);
				free(telnet->z);
				telnet->z = 0;
				break;
			}

			_event(telnet, LIBTELNET_EV_SEND, 0, 0, deflate_buffer,
					sizeof(deflate_buffer) - telnet->z->avail_out);

			/* prepare output buffer for next run */
			telnet->z->next_out = deflate_buffer;
			telnet->z->avail_out = sizeof(deflate_buffer);
		}

	/* COMPRESS2 is not negotiated, just send */
	} else
#endif /* HAVE_ZLIB */
		_event(telnet, LIBTELNET_EV_SEND, 0, 0, buffer, size);
}

/* retrieve RFC1143 option state */
libtelnet_rfc1143_t _get_rfc1143(libtelnet_t *telnet, unsigned char telopt) {
	static const libtelnet_rfc1143_t empty = { 0, 0, 0};
	int i;

	/* search for entry */
	for (i = 0; i != telnet->q_size; ++i)
		if (telnet->q[i].telopt == telopt)
			return telnet->q[i];

	/* not found, return empty value */
	return empty;
}

/* save RFC1143 option state */
void _set_rfc1143(libtelnet_t *telnet, libtelnet_rfc1143_t q) {
	libtelnet_rfc1143_t *qtmp;
	int i;

	/* search for entry */
	for (i = 0; i != telnet->q_size; ++i) {
		if (telnet->q[i].telopt == q.telopt) {
			telnet->q[i] = q;
			return;
		}
	}

	/* we're going to need to track state for it, so grow the queue
	 * and put the telopt into it; bail on allocation error
	 */
	if ((qtmp = (libtelnet_rfc1143_t *)malloc(sizeof(
			libtelnet_rfc1143_t) * (telnet->q_size + 1))) == 0) {
		_error(telnet, __LINE__, __func__, LIBTELNET_ENOMEM, 0,
				"malloc() failed: %s", strerror(errno));
		return;
	}
	telnet->q = qtmp;
	telnet->q[telnet->q_size++] = q;
}

/* send a negotiation without going through the RFC1143 checks */
static void _send_negotiate(libtelnet_t *telnet, unsigned char cmd,
		unsigned char opt) {
	unsigned char bytes[3] = { LIBTELNET_IAC, cmd, opt };
	_send(telnet, bytes, 3);
}

/* negotiation handling magic for RFC1143 */
static void _negotiate(libtelnet_t *telnet, unsigned char cmd,
		unsigned char telopt) {
	libtelnet_rfc1143_t q;

	/* in PROXY mode, just pass it thru and do nothing */
	if (telnet->flags & LIBTELNET_FLAG_PROXY) {
		switch (cmd) {
		case LIBTELNET_WILL:
			_event(telnet, LIBTELNET_EV_WILL, 0, telopt, 0, 0);
			break;
		case LIBTELNET_WONT:
			_event(telnet, LIBTELNET_EV_WONT, 0, telopt, 0, 0);
			break;
		case LIBTELNET_DO:
			_event(telnet, LIBTELNET_EV_DO, 0, telopt, 0, 0);
			break;
		case LIBTELNET_DONT:
			_event(telnet, LIBTELNET_EV_DONT, 0, telopt, 0, 0);
			break;
		}
		return;
	}

	/* lookup the current state of the option */
	q = _get_rfc1143(telnet, telopt);

	/* start processing... */
	switch (cmd) {
	/* request to enable option on remote end or confirm DO */
	case LIBTELNET_WILL:
		switch (q.him) {
		case RFC1143_NO:
			if (_event(telnet, LIBTELNET_EV_WILL, cmd, telopt, 0, 0) == 1) {
				q.him = RFC1143_YES;
				_set_rfc1143(telnet, q);
				_send_negotiate(telnet, LIBTELNET_DO, telopt);
			} else
				_send_negotiate(telnet, LIBTELNET_DONT, telopt);
			break;
		case RFC1143_YES:
			break;
		case RFC1143_WANTNO:
			q.him = RFC1143_NO;
			_set_rfc1143(telnet, q);
			_error(telnet, __LINE__, __func__, LIBTELNET_EPROTOCOL, 0,
					"DONT answered by WILL");
			break;
		case RFC1143_WANTNO_OP:
			q.him = RFC1143_YES;
			_set_rfc1143(telnet, q);
			_error(telnet, __LINE__, __func__, LIBTELNET_EPROTOCOL, 0,
					"DONT answered by WILL");
			break;
		case RFC1143_WANTYES:
			q.him = RFC1143_YES;
			_set_rfc1143(telnet, q);
			break;
		case RFC1143_WANTYES_OP:
			q.him = RFC1143_WANTNO;
			_set_rfc1143(telnet, q);
			_send_negotiate(telnet, LIBTELNET_DONT, telopt);
			break;
		}
		break;

	/* request to disable option on remote end, confirm DONT, reject DO */
	case LIBTELNET_WONT:
		switch (q.him) {
		case RFC1143_NO:
			break;
		case RFC1143_YES:
			q.him = RFC1143_NO;
			_set_rfc1143(telnet, q);
			_send_negotiate(telnet, LIBTELNET_DONT, telopt);
			_event(telnet, LIBTELNET_EV_WONT, 0, telopt,
					0, 0);
			break;
		case RFC1143_WANTNO:
			q.him = RFC1143_NO;
			_set_rfc1143(telnet, q);
			_event(telnet, LIBTELNET_EV_WONT, 0, telopt,
					0, 0);
			break;
		case RFC1143_WANTNO_OP:
			q.him = RFC1143_WANTYES;
			_set_rfc1143(telnet, q);
			_event(telnet, LIBTELNET_EV_DO, 0, telopt,
					0, 0);
			break;
		case RFC1143_WANTYES:
		case RFC1143_WANTYES_OP:
			q.him = RFC1143_NO;
			_set_rfc1143(telnet, q);
			break;
		}
		break;

	/* request to enable option on local end or confirm WILL */
	case LIBTELNET_DO:
		switch (q.us) {
		case RFC1143_NO:
			if (_event(telnet, LIBTELNET_EV_DO, cmd, telopt, 0, 0) == 1) {
				q.us = RFC1143_YES;
				_set_rfc1143(telnet, q);
				_send_negotiate(telnet, LIBTELNET_WILL, telopt);
			} else
				_send_negotiate(telnet, LIBTELNET_WONT, telopt);
			break;
		case RFC1143_YES:
			break;
		case RFC1143_WANTNO:
			q.us = RFC1143_NO;
			_set_rfc1143(telnet, q);
			_error(telnet, __LINE__, __func__, LIBTELNET_EPROTOCOL, 0,
					"WONT answered by DO");
			break;
		case RFC1143_WANTNO_OP:
			q.us = RFC1143_YES;
			_set_rfc1143(telnet, q);
			_error(telnet, __LINE__, __func__, LIBTELNET_EPROTOCOL, 0,
					"WONT answered by DO");
			break;
		case RFC1143_WANTYES:
			q.us = RFC1143_YES;
			_set_rfc1143(telnet, q);
			break;
		case RFC1143_WANTYES_OP:
			q.us = RFC1143_WANTNO;
			_set_rfc1143(telnet, q);
			_send_negotiate(telnet, LIBTELNET_WONT, telopt);
			break;
		}
		break;

	/* request to disable option on local end, confirm WONT, reject WILL */
	case LIBTELNET_DONT:
		switch (q.us) {
		case RFC1143_NO:
			break;
		case RFC1143_YES:
			q.us = RFC1143_NO;
			_set_rfc1143(telnet, q);
			_send_negotiate(telnet, LIBTELNET_WONT, telopt);
			_event(telnet, LIBTELNET_EV_DONT, 0, telopt, 0, 0);
			break;
		case RFC1143_WANTNO:
			q.us = RFC1143_NO;
			_set_rfc1143(telnet, q);
			_event(telnet, LIBTELNET_EV_WONT, 0, telopt, 0, 0);
			break;
		case RFC1143_WANTNO_OP:
			q.us = RFC1143_WANTYES;
			_set_rfc1143(telnet, q);
			_event(telnet, LIBTELNET_EV_WILL, 0, telopt, 0, 0);
			break;
		case RFC1143_WANTYES:
		case RFC1143_WANTYES_OP:
			q.us = RFC1143_NO;
			_set_rfc1143(telnet, q);
			break;
		}
		break;
	}
}

/* initialize a telnet state tracker */
void libtelnet_init(libtelnet_t *telnet, libtelnet_event_handler_t eh,
		unsigned char flags, void *user_data) {
	memset(telnet, 0, sizeof(libtelnet_t));
	telnet->ud = user_data;
	telnet->eh = eh;
	telnet->flags = flags;
}

/* free up any memory allocated by a state tracker */
void libtelnet_free(libtelnet_t *telnet) {
	/* free sub-request buffer */
	if (telnet->buffer != 0) {
		free(telnet->buffer);
		telnet->buffer = 0;
		telnet->buffer_size = 0;
		telnet->buffer_pos = 0;
	}

	/* free zlib box */
	if (telnet->z != 0) {
		if (telnet->flags & LIBTELNET_PFLAG_DEFLATE)
			deflateEnd(telnet->z);
		else
			inflateEnd(telnet->z);
		free(telnet->z);
		telnet->z = 0;
	}

	/* free RFC1143 queue */
	if (telnet->q) {
		free(telnet->q);
		telnet->q = 0;
		telnet->q_size = 0;
	}
}

/* push a byte into the telnet buffer */
static libtelnet_error_t _buffer_byte(libtelnet_t *telnet,
		unsigned char byte) {
	unsigned char *new_buffer;
	int i;

	/* check if we're out of room */
	if (telnet->buffer_pos == telnet->buffer_size) {
		/* find the next buffer size */
		for (i = 0; i != _buffer_sizes_count; ++i) {
			if (_buffer_sizes[i] == telnet->buffer_size)
				break;
		}

		/* overflow -- can't grow any more */
		if (i >= _buffer_sizes_count - 1) {
			_error(telnet, __LINE__, __func__, LIBTELNET_EOVERFLOW, 0,
					"subnegotiation buffer size limit reached");
			libtelnet_free(telnet);
			return LIBTELNET_EOVERFLOW;
		}

		/* (re)allocate buffer */
		new_buffer = (unsigned char *)realloc(telnet->buffer,
				_buffer_sizes[i + 1]);
		if (new_buffer == 0) {
			_error(telnet, __LINE__, __func__, LIBTELNET_ENOMEM, 0,
					"realloc() failed");
			libtelnet_free(telnet);
			return LIBTELNET_ENOMEM;
		}

		telnet->buffer = new_buffer;
		telnet->buffer_size = _buffer_sizes[i + 1];
	}

	/* push the byte, all set */
	telnet->buffer[telnet->buffer_pos++] = byte;
	return LIBTELNET_EOK;
}

static void _process(libtelnet_t *telnet, unsigned char *buffer,
		unsigned int size) {
	unsigned char byte;
	unsigned int i, start;
	for (i = start = 0; i != size; ++i) {
		byte = buffer[i];
		switch (telnet->state) {
		/* regular data */
		case LIBTELNET_STATE_DATA:
			/* on an IAC byte, pass through all pending bytes and
			 * switch states */
			if (byte == LIBTELNET_IAC) {
				if (i != start)
					_event(telnet, LIBTELNET_EV_DATA, 0, 0, &buffer[start],
							i - start);
				telnet->state = LIBTELNET_STATE_IAC;
			}
			break;

		/* IAC command */
		case LIBTELNET_STATE_IAC:
			switch (byte) {
			/* subnegotiation */
			case LIBTELNET_SB:
				telnet->state = LIBTELNET_STATE_SB;
				break;
			/* negotiation commands */
			case LIBTELNET_WILL:
				telnet->state = LIBTELNET_STATE_WILL;
				break;
			case LIBTELNET_WONT:
				telnet->state = LIBTELNET_STATE_WONT;
				break;
			case LIBTELNET_DO:
				telnet->state = LIBTELNET_STATE_DO;
				break;
			case LIBTELNET_DONT:
				telnet->state = LIBTELNET_STATE_DONT;
				break;
			/* IAC escaping */
			case LIBTELNET_IAC:
				_event(telnet, LIBTELNET_EV_DATA, 0, 0, &byte, 1);
				start = i + 1;
				telnet->state = LIBTELNET_STATE_DATA;
				break;
			/* some other command */
			default:
				_event(telnet, LIBTELNET_EV_IAC, byte, 0, 0, 0);
				start = i + 1;
				telnet->state = LIBTELNET_STATE_DATA;
			}
			break;

		/* negotiation commands */
		case LIBTELNET_STATE_DO:
			_negotiate(telnet, LIBTELNET_DO, byte);
			start = i + 1;
			telnet->state = LIBTELNET_STATE_DATA;
			break;
		case LIBTELNET_STATE_DONT:
			_negotiate(telnet, LIBTELNET_DONT, byte);
			start = i + 1;
			telnet->state = LIBTELNET_STATE_DATA;
			break;
		case LIBTELNET_STATE_WILL:
			_negotiate(telnet, LIBTELNET_WILL, byte);
			start = i + 1;
			telnet->state = LIBTELNET_STATE_DATA;
			break;
		case LIBTELNET_STATE_WONT:
			_negotiate(telnet, LIBTELNET_WONT, byte);
			start = i + 1;
			telnet->state = LIBTELNET_STATE_DATA;
			break;

		/* subnegotiation -- determine subnegotiation telopt */
		case LIBTELNET_STATE_SB:
			telnet->sb_telopt = byte;
			telnet->buffer_pos = 0;
			telnet->state = LIBTELNET_STATE_SB_DATA;
			break;

		/* subnegotiation -- buffer bytes until end request */
		case LIBTELNET_STATE_SB_DATA:
			/* IAC command in subnegotiation -- either IAC SE or IAC IAC */
			if (byte == LIBTELNET_IAC) {
				telnet->state = LIBTELNET_STATE_SB_DATA_IAC;
			/* buffer the byte, or bail if we can't */
			} else if (_buffer_byte(telnet, byte) != LIBTELNET_EOK) {
				start = i + 1;
				telnet->state = LIBTELNET_STATE_DATA;
			}
			break;

		/* IAC escaping inside a subnegotiation */
		case LIBTELNET_STATE_SB_DATA_IAC:
			switch (byte) {
			/* end subnegotiation */
			case LIBTELNET_SE:
				/* return to default state */
				start = i + 1;
				telnet->state = LIBTELNET_STATE_DATA;

				/* invoke callback */
				_event(telnet, LIBTELNET_EV_SUBNEGOTIATION, 0,
						telnet->sb_telopt, telnet->buffer, telnet->buffer_pos);

#ifdef HAVE_ZLIB
				/* if we are a client or a proxy and just received the
				 * COMPRESS2 begin marker, setup our zlib box and start
				 * handling the compressed stream if it's not already.
				 */
				if (telnet->sb_telopt == LIBTELNET_TELOPT_COMPRESS2 &&
						telnet->z == 0 &&
						telnet->flags & LIBTELNET_FLAG_PROXY) {

					if (_init_zlib(telnet, 0, 1) != LIBTELNET_EOK)
						break;

					/* notify app that compression was enabled */
					_event(telnet, LIBTELNET_EV_COMPRESS, 1, 0, 0, 0);

					/* any remaining bytes in the buffer are compressed.
					 * we have to re-invoke libtelnet_push to get those
					 * bytes inflated and abort trying to process the
					 * remaining compressed bytes in the current _process
					 * buffer argument
					 */
					libtelnet_push(telnet, &buffer[start], size - start);
					return;
				}
#endif /* HAVE_ZLIB */

				break;
			/* escaped IAC byte */
			case LIBTELNET_IAC:
				/* push IAC into buffer */
				if (_buffer_byte(telnet, LIBTELNET_IAC) !=
						LIBTELNET_EOK) {
					start = i + 1;
					telnet->state = LIBTELNET_STATE_DATA;
				} else {
					telnet->state = LIBTELNET_STATE_SB_DATA;
				}
				break;
			/* something else -- protocol error */
			default:
				_error(telnet, __LINE__, __func__, LIBTELNET_EPROTOCOL, 0,
						"unexpected byte after IAC inside SB: %d",
						byte);
				start = i + 1;
				telnet->state = LIBTELNET_STATE_DATA;
				break;
			}
			break;
		}
	}

	/* pass through any remaining bytes */ 
	if (telnet->state == LIBTELNET_STATE_DATA && i != start)
		_event(telnet, LIBTELNET_EV_DATA, 0, 0, buffer + start, i - start);
}

/* push a bytes into the state tracker */
void libtelnet_push(libtelnet_t *telnet, unsigned char *buffer,
		unsigned int size) {
#ifdef HAVE_ZLIB
	/* if we have an inflate (decompression) zlib stream, use it */
	if (telnet->z != 0 && !(telnet->flags & LIBTELNET_PFLAG_DEFLATE)) {
		unsigned char inflate_buffer[4096];
		int rs;

		/* initialize zlib state */
		telnet->z->next_in = buffer;
		telnet->z->avail_in = size;
		telnet->z->next_out = inflate_buffer;
		telnet->z->avail_out = sizeof(inflate_buffer);

		/* inflate until buffer exhausted and all output is produced */
		while (telnet->z->avail_in > 0 || telnet->z->avail_out == 0) {
			/* reset output buffer */

			/* decompress */
			rs = inflate(telnet->z, Z_SYNC_FLUSH);

			/* process the decompressed bytes on success */
			if (rs == Z_OK || rs == Z_STREAM_END)
				_process(telnet, inflate_buffer, sizeof(inflate_buffer) -
						telnet->z->avail_out);
			else
				_error(telnet, __LINE__, __func__, LIBTELNET_ECOMPRESS, 1,
						"inflate() failed: %s", zError(rs));

			/* prepare output buffer for next run */
			telnet->z->next_out = inflate_buffer;
			telnet->z->avail_out = sizeof(inflate_buffer);

			/* on error (or on end of stream) disable further inflation */
			if (rs != Z_OK) {
				_event(telnet, LIBTELNET_EV_COMPRESS, 0, 0, 0, 0);

				inflateEnd(telnet->z);
				free(telnet->z);
				telnet->z = 0;
				break;
			}
		}

	/* COMPRESS2 is not negotiated, just process */
	} else
#endif /* HAVE_ZLIB */
		_process(telnet, buffer, size);
}

/* send an iac command */
void libtelnet_send_command(libtelnet_t *telnet, unsigned char cmd) {
	unsigned char bytes[2] = { LIBTELNET_IAC, cmd };
	_send(telnet, bytes, 2);
}

/* send negotiation */
void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd,
		unsigned char telopt) {
	libtelnet_rfc1143_t q;

	/* if we're in proxy mode, just send it now */
	if (telnet->flags & LIBTELNET_FLAG_PROXY) {
		unsigned char bytes[3] = { LIBTELNET_IAC, cmd, telopt };
		_send(telnet, bytes, 3);
		return;
	}
	
	/* get current option states */
	q = _get_rfc1143(telnet, telopt);

	switch (cmd) {
	/* advertise willingess to support an option */
	case LIBTELNET_WILL:
		switch (q.us) {
		case RFC1143_NO:
			q.us = RFC1143_WANTYES;
			_set_rfc1143(telnet, q);
			_negotiate(telnet, LIBTELNET_WILL, telopt);
			break;
		case RFC1143_YES:
			break;
		case RFC1143_WANTNO:
			q.us = RFC1143_WANTNO_OP;
			_set_rfc1143(telnet, q);
			break;
		case RFC1143_WANTYES:
			break;
		case RFC1143_WANTNO_OP:
			break;
		case RFC1143_WANTYES_OP:
			q.us = RFC1143_WANTYES;
			_set_rfc1143(telnet, q);
			break;
		}
		break;

	/* force turn-off of locally enabled option */
	case LIBTELNET_WONT:
		switch (q.us) {
		case RFC1143_NO:
			break;
		case RFC1143_YES:
			q.us = RFC1143_WANTNO;
			_set_rfc1143(telnet, q);
			_negotiate(telnet, LIBTELNET_WONT, telopt);
			break;
		case RFC1143_WANTNO:
			break;
		case RFC1143_WANTYES:
			q.us = RFC1143_WANTYES_OP;
			_set_rfc1143(telnet, q);
			break;
		case RFC1143_WANTNO_OP:
			q.us = RFC1143_WANTNO;
			_set_rfc1143(telnet, q);
			break;
		case RFC1143_WANTYES_OP:
			break;
		}
		break;

	/* ask remote end to enable an option */
	case LIBTELNET_DO:
		switch (q.him) {
		case RFC1143_NO:
			q.him = RFC1143_WANTYES;
			_set_rfc1143(telnet, q);
			_negotiate(telnet, LIBTELNET_DO, telopt);
			break;
		case RFC1143_YES:
			break;
		case RFC1143_WANTNO:
			q.him = RFC1143_WANTNO_OP;
			_set_rfc1143(telnet, q);
			break;
		case RFC1143_WANTYES:
			break;
		case RFC1143_WANTNO_OP:
			break;
		case RFC1143_WANTYES_OP:
			q.him = RFC1143_WANTYES;
			_set_rfc1143(telnet, q);
			break;
		}
		break;

	/* demand remote end disable an option */
	case LIBTELNET_DONT:
		switch (q.him) {
		case RFC1143_NO:
			break;
		case RFC1143_YES:
			q.him = RFC1143_WANTNO;
			_set_rfc1143(telnet, q);
			_negotiate(telnet, LIBTELNET_DONT, telopt);
			break;
		case RFC1143_WANTNO:
			break;
		case RFC1143_WANTYES:
			q.him = RFC1143_WANTYES_OP;
			_set_rfc1143(telnet, q);
			break;
		case RFC1143_WANTNO_OP:
			q.him = RFC1143_WANTNO;
			_set_rfc1143(telnet, q);
			break;
		case RFC1143_WANTYES_OP:
			break;
		}
		break;
	}
}

/* send non-command data (escapes IAC bytes) */
void libtelnet_send_data(libtelnet_t *telnet, unsigned char *buffer,
		unsigned int size) {
	unsigned int i, l;
	for (l = i = 0; i != size; ++i) {
		/* dump prior portion of text, send escaped bytes */
		if (buffer[i] == LIBTELNET_IAC) {
			/* dump prior text if any */
			if (i != l)
				_send(telnet, buffer + l, i - l);
			l = i + 1;

			/* send escape */
			libtelnet_send_command(telnet, LIBTELNET_IAC);
		}
	}

	/* send whatever portion of buffer is left */
	if (i != l)
		_send(telnet, buffer + l, i - l);
}

/* send sub-request */
void libtelnet_send_subnegotiation(libtelnet_t *telnet, unsigned char opt,
		unsigned char *buffer, unsigned int size) {
	libtelnet_send_command(telnet, LIBTELNET_SB);
	libtelnet_send_data(telnet, &opt, 1);
	libtelnet_send_data(telnet, buffer, size);
	libtelnet_send_command(telnet, LIBTELNET_SE);

#ifdef HAVE_ZLIB
	/* if we're a proxy and we just sent the COMPRESS2 marker, we must
	 * make sure all further data is compressed if not already.
	 */
	if (telnet->flags & LIBTELNET_FLAG_PROXY &&
			telnet->z == 0 &&
			opt == LIBTELNET_TELOPT_COMPRESS2) {

		if (_init_zlib(telnet, 1, 1) != LIBTELNET_EOK)
			return;

		/* notify app that compression was enabled */
		_event(telnet, LIBTELNET_EV_COMPRESS, 1, 0, 0, 0);
	}
#endif /* HAVE_ZLIB */
}

void libtelnet_begin_compress2(libtelnet_t *telnet) {
#ifdef HAVE_ZLIB
	unsigned char compress2[] = { LIBTELNET_IAC, LIBTELNET_SB,
			LIBTELNET_TELOPT_COMPRESS2, LIBTELNET_IAC, LIBTELNET_SE };

	/* attempt to create output stream first, bail if we can't */
	if (_init_zlib(telnet, 1, 0) != LIBTELNET_EOK)
		return;

	/* send compression marker.  we send directly to the event handler
	 * instead of passing through _send because _send would result in
	 * the compress marker itself being compressed.
	 */
	_event(telnet, LIBTELNET_EV_SEND, 0, 0, compress2, sizeof(compress2));
#endif /* HAVE_ZLIB */
}
