/*
 * 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"

#ifdef ERROR
#  undef ERROR
#endif

#define ERROR(telnet, code, user_data, msg) \
		_error(telnet, __FILE__, __LINE__, code, user_data, "%s", msg)
#define ERROR_NOMEM(telnet, user_data, msg) \
		_error(telnet, __FILE__, __LINE__, LIBTELNET_ERROR_NOMEM, user_data, \
		"%s: %s", msg, strerror(errno))
#define ERROR_ZLIB(telnet, user_data, rs, msg) \
		_error(telnet, __FILE__, __LINE__, LIBTELNET_ERROR_UNKNOWN, \
		user_data, "%s: %s", msg, zError(rs))

/* 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]);

/* error generation function */
static void _error(struct libtelnet_t *telnet, const char *file, unsigned line,
		enum libtelnet_error_t err, void *user_data, const char *fmt, ...) {
	char buffer[512];
	va_list va;

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

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

	/* invoke user's custom error handler if possible; otherwise,
	 * print to stderr
	 */
	if (telnet->cb->error)
		telnet->cb->error(telnet, err, buffer, user_data);
	else
		fprintf(stderr, "**ERROR**: libtelnet: %s\n", buffer);
}

/* initialize a telnet state tracker */
void libtelnet_init(struct libtelnet_t *telnet, struct libtelnet_cb_t *cb,
		enum libtelnet_mode_t mode) {
	memset(telnet, 0, sizeof(struct libtelnet_t));
	telnet->cb = cb;
	telnet->mode = mode;
}

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

	/* free zlib box */
	if (telnet->zlib != 0) {
		if (telnet->mode == LIBTELNET_MODE_SERVER)
			deflateEnd(telnet->zlib);
		else
			inflateEnd(telnet->zlib);
		free(telnet->zlib);
		telnet->zlib = 0;
	}
}

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

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

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

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

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

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

static void _process(struct libtelnet_t *telnet, unsigned char *buffer,
		unsigned int size, void *user_data) {
	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)
					telnet->cb->data(telnet, &buffer[start], i - start,
							user_data);
				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:
				telnet->cb->data(telnet, &byte, 1, user_data);
				start = i + 1;
				telnet->state = LIBTELNET_STATE_DATA;
				break;
			/* some other command */
			default:
				telnet->cb->command(telnet, byte, user_data);
				start = i + 1;
				telnet->state = LIBTELNET_STATE_DATA;
			}
			break;

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

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

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

				/* zero-size buffer is a protocol error */
				if (telnet->length == 0) {
					ERROR(telnet, LIBTELNET_ERROR_PROTOCOL, user_data,
							"subnegotiation has zero data");
					break;
				}

				/* invoke callback */
				telnet->cb->subnegotiation(telnet, telnet->buffer[0],
					telnet->buffer + 1, telnet->length - 1, user_data);
				telnet->length = 0;

#ifdef HAVE_ZLIB
				/* if we are a client and just received the COMPRESS2
				 * begin marker, setup our zlib box and start handling
				 * the compressed stream
				 */
				if (telnet->mode == LIBTELNET_MODE_CLIENT &&
						telnet->buffer[0] == LIBTELNET_TELOPT_COMPRESS2) {
					int rs;

					/* allocate zstream box */
					if ((telnet->zlib = (z_stream *)malloc(sizeof(z_stream)))
							== 0) {
						ERROR_NOMEM(telnet, user_data, "malloc() failed");
					}

					/* initialize */
					memset(telnet->zlib, 0, sizeof(z_stream));
					if ((rs = inflateInit(telnet->zlib)) != Z_OK) {
						free(telnet->zlib);
						telnet->zlib = 0;
						ERROR_ZLIB(telnet, user_data, rs,
								"inflateInit() failed");
						break;
					}

					/* notify app that compression was enabled */
					telnet->cb->compress(telnet, 1, user_data);

					/* 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,
							user_data);
					return;
				}
#endif /* HAVE_ZLIB */

				break;
			/* escaped IAC byte */
			case LIBTELNET_IAC:
				/* push IAC into buffer */
				if (_buffer_byte(telnet, LIBTELNET_IAC, user_data) !=
						LIBTELNET_ERROR_OK) {
					start = i + 1;
					telnet->state = LIBTELNET_STATE_DATA;
				} else {
					telnet->state = LIBTELNET_STATE_SB;
				}
				break;
			/* something else -- protocol error */
			default:
				_error(telnet, __FILE__, __LINE__, LIBTELNET_ERROR_PROTOCOL,
						user_data, "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)
		telnet->cb->data(telnet, &buffer[start], i - start, user_data);
}

/* push a bytes into the state tracker */
void libtelnet_push(struct libtelnet_t *telnet, unsigned char *buffer,
		unsigned int size, void *user_data) {
#ifdef HAVE_ZLIB
	/* if we are a client and we have a zlib box, then COMPRESS2 has been
	 * negotiated and we need to inflate the buffer before processing
	 */
	if (telnet->mode == LIBTELNET_MODE_CLIENT && telnet->zlib != 0) {
		unsigned char inflate_buffer[4096];
		int rs;

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

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

			/* decompress */
			rs = inflate(telnet->zlib, 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->zlib->avail_out, user_data);
			else
				ERROR_ZLIB(telnet, user_data, rs, "inflate() failed");

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

			/* on error (or on end of stream) disable further inflation */
			if (rs != Z_OK) {
				telnet->cb->compress(telnet, 0, user_data);

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

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

static void _send(struct libtelnet_t *telnet, unsigned char *buffer,
		unsigned int size, void *user_data) {
#ifdef HAVE_ZLIB
	/* if we are a server and we have a zlib box, then COMPRESS2 has been
	 * negotiated and we need to deflate the buffer before sending it out
	 */
	if (telnet->mode == LIBTELNET_MODE_SERVER && telnet->zlib != 0) {
		unsigned char deflate_buffer[1024];
		int rs;

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

		/* deflate until buffer exhausted and all output is produced */
		while (telnet->zlib->avail_in > 0 || telnet->zlib->avail_out == 0) {
			/* compress */
			if ((rs = deflate(telnet->zlib, Z_SYNC_FLUSH)) != Z_OK) {
				ERROR_ZLIB(telnet, user_data, rs, "deflate() failed");
				deflateEnd(telnet->zlib);
				free(telnet->zlib);
				telnet->zlib = 0;
				break;
			}

			telnet->cb->send(telnet, deflate_buffer, sizeof(deflate_buffer) -
					telnet->zlib->avail_out, user_data);

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

	/* COMPRESS2 is not negotiated, just send */
	} else
#endif /* HAVE_ZLIB */
		telnet->cb->send(telnet, buffer, size, user_data);
}

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

/* send negotiation */
void libtelnet_send_negotiate(struct libtelnet_t *telnet, unsigned char cmd,
		unsigned char opt, void *user_data) {
	unsigned char bytes[3] = { LIBTELNET_IAC, cmd, opt };
	_send(telnet, bytes, 3, user_data);
}

/* send non-command data (escapes IAC bytes) */
void libtelnet_send_data(struct libtelnet_t *telnet, unsigned char *buffer,
		unsigned int size, void *user_data) {
	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, user_data);
			l = i + 1;

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

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

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

#ifdef HAVE_ZLIB
	/* if we're a server and we just sent the COMPRESS2 marker, we must
	 * make sure all further data is compressed
	 */
	if (telnet->mode == LIBTELNET_MODE_SERVER && opt ==
			LIBTELNET_TELOPT_COMPRESS2) {
		int rs;

		/* allocate zstream box */
		if ((telnet->zlib = (z_stream *)malloc(sizeof(z_stream))) == 0) {
			ERROR_NOMEM(telnet, user_data, "malloc() failed");
			return;
		}

		/* initialize */
		memset(telnet->zlib, 0, sizeof(z_stream));
		if ((rs = deflateInit(telnet->zlib, Z_DEFAULT_COMPRESSION)) != Z_OK) {
			free(telnet->zlib);
			telnet->zlib = 0;
			ERROR_ZLIB(telnet, user_data, rs, "delateInit() failed");
			return;
		}

		/* notify app that compression was enabled */
		telnet->cb->compress(telnet, 1, user_data);
	}
#endif /* HAVE_ZLIB */
}
