Merge branch 'master' into rfc1143

Conflicts:
	libtelnet.c
diff --git a/README b/README
index 51156ae..f6b234d 100644
--- a/README
+++ b/README
@@ -57,9 +57,8 @@
    its own libtelnet_t structure, which is passed to all libtelnet
    API calls.
 
- void libtelnet_init(struct libtelnet_t *telnet,
-     libtelnet_event_handler_t handler, enum libtelnet_mode_t mode,
-     void *user_data);
+ void libtelnet_init(libtelnet_t *telnet, libtelnet_event_handler_t handler,
+     unsigned char flags, void *user_data);
    The libtelnet_init() function is responsible for initializing
    the data in a libtelnet_t structure.  It must be called
    immediately after establishing a connection and before any other
@@ -74,22 +73,19 @@
    information about the connection, including a socket descriptor
    for implementing LIBTELNET_EV_SEND event handling.
 
-   The mode parameter must be one of LIBTELNET_MODE_SERVER,
-   LIBTELNET_MODE_CLIENT, or LIBTELNET_MODE_PROXY.  These slightly
-   alter the behavior of libtelnet in certain instances.  If you are
-   implementing a TELNET server, use the SERVER mode.  If you are
-   implementing a client, use the CLIENT mode.  The PROXY mode
-   enables special behavior for telnet-proxy (or similar
-   applications).
+   The flags parameter can be any of the following flag constants
+   bit-or'd together, or 0 to leave all options disabled.
+
+    LIBTELNET_FLAG_PROXY   - operate in proxy mode
  
- boid libtelnet_free(struct libtelnet_t *telnet);
+ boid libtelnet_free(libtelnet_t *telnet);
    Releases any internal memory allocated by libtelnet.  This must
    be called whenever a connection is closed, or you will incur
    memory leaks.
 
 IIb. Receiving Data
 
- void libtelnet_push(struct libtelnet_t *telnet,
+ void libtelnet_push(libtelnet_t *telnet,
      unsigned char *buffer, unsigned int size, void *user_data);
    When your application receives data over the socket from the
    remote end, it must pass the received bytes into this function.
@@ -111,24 +107,23 @@
  to libtelnet_send_data().  Do NOT send or buffer unprocessed output
  data directly!
 
- void libtelnet_send_command(struct libtelnet_t *telnet,
-     unsigned char cmd);
+ void libtelnet_send_command(libtelnet_t *telnet, unsigned char cmd);
    Sends a single "simple" TELNET command, such as the GO-AHEAD
    commands (255 249).
 
- void libtelnet_send_negotiate(struct libtelnet_t *telnet,
+ void libtelnet_send_negotiate(libtelnet_t *telnet,
      unsigned char cmd, unsigned char opt);
    Sends a TELNET negotiation command.  The cmd parameter must be
    one of LIBTELNET_WILL, LIBTELNET_DONT, LIBTELNET_DO, or
    LIBTELNET_DONT.  The opt parameter is the option to
    negotiate.
 
- void libtelnet_send_data(struct libtelnet_t *telnet,
-     unsigned char *buffer, unsigned int size);
+ void libtelnet_send_data(libtelnet_t *telnet, unsigned char *buffer,
+     unsigned int size);
    Sends raw data, which would be either the process output from
    a server or the user input from a client.
 
- void libtelnet_send_subnegotiation(struct libtelnet_t *telnet,
+ void libtelnet_send_subnegotiation(libtelnet_t *telnet,
      unsigned char opt, unsigned char *buffer, unsigned int size);
    Sends a TELNET sub-negotiation command.  The opt parameter
    is the sub-negotiation option.
@@ -150,11 +145,12 @@
  pointer passed to libtelnet_init().
 
   struct libtelnet_event_t {
-    enum libtelnet_event_type_t type;
-    unsigned char command;
-    unsigned char telopt;
     unsigned char *buffer;
     unsigned int size;
+    libtelnet_event_type_t type;
+    unsigned char command;
+    unsigned char telopt;
+    unsigned char accept;
   };
  
  The enumeration values of libtelnet_event_type_t are described in
@@ -169,8 +165,8 @@
  Here is an example event handler implementation which includes
  handlers for several important events.
 
-  void my_event_handler(struct libtelnet_t *telnet,
-      libtelnet_event_t *ev, void *user_data) {
+  void my_event_handler(libtelnet_t *telnet, libtelnet_event_t *ev,
+      void *user_data) {
     struct user_info *user = (struct user_info *)user_data;
 
     switch (ev->type) {
diff --git a/libtelnet.c b/libtelnet.c
index 700cca1..0fe3ce0 100644
--- a/libtelnet.c
+++ b/libtelnet.c
@@ -42,15 +42,15 @@
 	8192,
 	16384,
 };
-static const unsigned int _buffer_sizes_count =
-	sizeof(_buffer_sizes) / sizeof(_buffer_sizes[0]);
+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(struct libtelnet_t *telnet,
-		enum libtelnet_event_type_t type, unsigned char command,
-		unsigned char telopt, unsigned char *buffer, unsigned int size) {
-	struct libtelnet_event_t ev;
+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;
@@ -64,14 +64,14 @@
 }
 
 /* error generation function */
-static void _error(struct libtelnet_t *telnet, unsigned line, const char* func,
-		enum libtelnet_error_t err, int fatal, const char *fmt, ...) {
+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);
+	snprintf(buffer, sizeof(buffer), "%s:%u in %s: ", __FILE__, line, func);
 
 	va_start(va, fmt);
 	vsnprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer),
@@ -80,42 +80,49 @@
 
 	_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)
+ * (decompression).  returns LIBTELNET_EOK on success, something else on
+ * failure.
  */
-z_stream *_init_zlib(struct libtelnet_t *telnet, int deflate, int err_fatal) {
-	z_stream *zlib;
+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 ((zlib = (z_stream *)calloc(1, sizeof(z_stream)))
-			== 0) {
-		_error(telnet, __LINE__, __func__, LIBTELNET_ENOMEM, err_fatal,
+	if ((z= (z_stream *)calloc(1, sizeof(z_stream))) == 0)
+		return _error(telnet, __LINE__, __func__, LIBTELNET_ENOMEM, err_fatal,
 				"malloc() failed: %s", strerror(errno));
-		return 0;
-	}
 
 	/* initialize */
 	if (deflate) {
-		if ((rs = deflateInit(zlib, Z_DEFAULT_COMPRESSION)) != Z_OK) {
-			free(zlib);
-			_error(telnet, __LINE__, __func__, LIBTELNET_ECOMPRESS, err_fatal,
-					"deflateInit() failed: %s", zError(rs));
-			return 0;
+		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(zlib)) != Z_OK) {
-			free(zlib);
-			_error(telnet, __LINE__, __func__, LIBTELNET_ECOMPRESS, err_fatal,
-					"inflateInit() failed: %s", zError(rs));
-			return 0;
+		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;
 	}
 
-	return zlib;
+	telnet->z = z;
+
+	return LIBTELNET_EOK;
 }
 
 /* negotiation handling magic */
@@ -295,16 +302,16 @@
 }
 
 /* initialize a telnet state tracker */
-void libtelnet_init(struct libtelnet_t *telnet, libtelnet_event_handler_t eh,
-		enum libtelnet_mode_t mode, void *user_data) {
-	memset(telnet, 0, sizeof(struct libtelnet_t));
+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->mode = mode;
+	telnet->flags = flags;
 }
 
 /* free up any memory allocated by a state tracker */
-void libtelnet_free(struct libtelnet_t *telnet) {
+void libtelnet_free(libtelnet_t *telnet) {
 	/* free sub-request buffer */
 	if (telnet->buffer != 0) {
 		free(telnet->buffer);
@@ -313,16 +320,14 @@
 		telnet->buffer_pos = 0;
 	}
 
-	/* free zlib box(es) */
-	if (telnet->z_inflate != 0) {
-		inflateEnd(telnet->z_inflate);
-		free(telnet->z_inflate);
-		telnet->z_inflate = 0;
-	}
-	if (telnet->z_deflate != 0) {
-		deflateEnd(telnet->z_deflate);
-		free(telnet->z_deflate);
-		telnet->z_deflate = 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 */
@@ -334,7 +339,7 @@
 }
 
 /* push a byte into the telnet buffer */
-static enum libtelnet_error_t _buffer_byte(struct libtelnet_t *telnet,
+static libtelnet_error_t _buffer_byte(libtelnet_t *telnet,
 		unsigned char byte) {
 	unsigned char *new_buffer;
 	int i;
@@ -374,7 +379,7 @@
 	return LIBTELNET_EOK;
 }
 
-static void _process(struct libtelnet_t *telnet, unsigned char *buffer,
+static void _process(libtelnet_t *telnet, unsigned char *buffer,
 		unsigned int size) {
 	unsigned char byte;
 	unsigned int i, start;
@@ -487,11 +492,10 @@
 				 * handling the compressed stream if it's not already.
 				 */
 				if (telnet->sb_telopt == LIBTELNET_TELOPT_COMPRESS2 &&
-						telnet->z_inflate == 0 &&
-						(telnet->mode == LIBTELNET_MODE_CLIENT ||
-						 telnet->mode == LIBTELNET_MODE_PROXY)) {
+						telnet->z == 0 &&
+						telnet->flags & LIBTELNET_FLAG_PROXY) {
 
-					if ((telnet->z_inflate = _init_zlib(telnet, 0, 1)) == 0)
+					if (_init_zlib(telnet, 0, 1) != LIBTELNET_EOK)
 						break;
 
 					/* notify app that compression was enabled */
@@ -539,47 +543,46 @@
 }
 
 /* push a bytes into the state tracker */
-void libtelnet_push(struct libtelnet_t *telnet, unsigned char *buffer,
+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_inflate != 0) {
+	if (telnet->z != 0) {
 		unsigned char inflate_buffer[4096];
 		int rs;
 
 		/* initialize zlib state */
-		telnet->z_inflate->next_in = buffer;
-		telnet->z_inflate->avail_in = size;
-		telnet->z_inflate->next_out = inflate_buffer;
-		telnet->z_inflate->avail_out = sizeof(inflate_buffer);
+		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_inflate->avail_in > 0 ||
-				telnet->z_inflate->avail_out == 0) {
+		while (telnet->z->avail_in > 0 || telnet->z->avail_out == 0) {
 			/* reset output buffer */
 
 			/* decompress */
-			rs = inflate(telnet->z_inflate, Z_SYNC_FLUSH);
+			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_inflate->avail_out);
+						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_inflate->next_out = inflate_buffer;
-			telnet->z_inflate->avail_out = sizeof(inflate_buffer);
+			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_inflate);
-				free(telnet->z_inflate);
-				telnet->z_inflate = 0;
+				inflateEnd(telnet->z);
+				free(telnet->z);
+				telnet->z = 0;
 				break;
 			}
 		}
@@ -590,39 +593,38 @@
 		_process(telnet, buffer, size);
 }
 
-static void _send(struct libtelnet_t *telnet, unsigned char *buffer,
+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_deflate != 0) {
+	if (telnet->z != 0) {
 		unsigned char deflate_buffer[1024];
 		int rs;
 
-		/* initialize z_deflate state */
-		telnet->z_deflate->next_in = buffer;
-		telnet->z_deflate->avail_in = size;
-		telnet->z_deflate->next_out = deflate_buffer;
-		telnet->z_deflate->avail_out = sizeof(deflate_buffer);
+		/* 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_deflate->avail_in > 0 ||
-				telnet->z_deflate->avail_out == 0) {
+		while (telnet->z->avail_in > 0 || telnet->z->avail_out == 0) {
 			/* compress */
-			if ((rs = deflate(telnet->z_deflate, Z_SYNC_FLUSH)) != Z_OK) {
+			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_deflate);
-				free(telnet->z_deflate);
-				telnet->z_deflate = 0;
+				deflateEnd(telnet->z);
+				free(telnet->z);
+				telnet->z = 0;
 				break;
 			}
 
 			_event(telnet, LIBTELNET_EV_SEND, 0, 0, deflate_buffer,
-					sizeof(deflate_buffer) - telnet->z_deflate->avail_out);
+					sizeof(deflate_buffer) - telnet->z->avail_out);
 
 			/* prepare output buffer for next run */
-			telnet->z_deflate->next_out = deflate_buffer;
-			telnet->z_deflate->avail_out = sizeof(deflate_buffer);
+			telnet->z->next_out = deflate_buffer;
+			telnet->z->avail_out = sizeof(deflate_buffer);
 		}
 
 	/* COMPRESS2 is not negotiated, just send */
@@ -632,20 +634,20 @@
 }
 
 /* send an iac command */
-void libtelnet_send_command(struct libtelnet_t *telnet, unsigned char cmd) {
+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(struct libtelnet_t *telnet, unsigned char cmd,
+void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd,
 		unsigned char opt) {
 	unsigned char bytes[3] = { LIBTELNET_IAC, cmd, opt };
 	_send(telnet, bytes, 3);
 }
 
 /* send non-command data (escapes IAC bytes) */
-void libtelnet_send_data(struct libtelnet_t *telnet, unsigned char *buffer,
+void libtelnet_send_data(libtelnet_t *telnet, unsigned char *buffer,
 		unsigned int size) {
 	unsigned int i, l;
 	for (l = i = 0; i != size; ++i) {
@@ -667,8 +669,8 @@
 }
 
 /* send sub-request */
-void libtelnet_send_subnegotiation(struct libtelnet_t *telnet,
-		unsigned char opt, unsigned char *buffer, unsigned int size) {
+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);
@@ -678,11 +680,11 @@
 	/* 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->mode == LIBTELNET_MODE_PROXY &&
-			telnet->z_deflate == 0 &&
+	if (telnet->flags & LIBTELNET_FLAG_PROXY &&
+			telnet->z == 0 &&
 			opt == LIBTELNET_TELOPT_COMPRESS2) {
 
-		if ((telnet->z_deflate = _init_zlib(telnet, 1, 1)) == 0)
+		if (_init_zlib(telnet, 1, 1) != LIBTELNET_EOK)
 			return;
 
 		/* notify app that compression was enabled */
@@ -691,33 +693,27 @@
 #endif /* HAVE_ZLIB */
 }
 
-void libtelnet_begin_compress2(struct libtelnet_t *telnet) {
+void libtelnet_begin_compress2(libtelnet_t *telnet) {
 #ifdef HAVE_ZLIB
-	z_stream *zlib;
+	unsigned char compress2[] = { LIBTELNET_IAC, LIBTELNET_SB,
+			LIBTELNET_TELOPT_COMPRESS2, LIBTELNET_IAC, LIBTELNET_SE };
 
 	/* don't do this if we've already got a compression stream */
-	if (telnet->z_deflate != 0) {
+	if (telnet->z != 0) {
 		_error(telnet, __LINE__, __func__, LIBTELNET_EBADVAL, 0,
 				"compression already enabled");
 		return;
 	}
-	
-	/* only supported by servers */
-	if (telnet->mode != LIBTELNET_MODE_SERVER) {
-		_error(telnet, __LINE__, __func__, LIBTELNET_EBADVAL, 0,
-				"only supported in SERVER mode");
-		return;
-	}
 
 	/* attempt to create output stream first, bail if we can't */
-	if ((zlib = _init_zlib(telnet, 1, 0)) == 0)
+	if (_init_zlib(telnet, 1, 0) != LIBTELNET_EOK)
 		return;
 
-	/* send compression marker */
-	libtelnet_send_subnegotiation(telnet, LIBTELNET_TELOPT_COMPRESS2, 0, 0);
-
-	/* set our deflate stream */
-	telnet->z_deflate = zlib;
+	/* 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 */
 }
 
diff --git a/libtelnet.h b/libtelnet.h
index 6c872b8..2ac577b 100644
--- a/libtelnet.h
+++ b/libtelnet.h
@@ -13,8 +13,12 @@
 #define LIBTELNET_INCLUDE 1
 
 /* forward declarations */
-struct libtelnet_t;
-struct libtelnet_cb_t;
+typedef struct libtelnet_t libtelnet_t;
+typedef struct libtelnet_event_t libtelnet_event_t;
+typedef enum libtelnet_mode_t libtelnet_mode_t;
+typedef enum libtelnet_state_t libtelnet_state_t;
+typedef enum libtelnet_error_t libtelnet_error_t;
+typedef enum libtelnet_event_type_t libtelnet_event_type_t;
 
 /* telnet special values */
 #define LIBTELNET_IAC 255
@@ -85,12 +89,10 @@
 #define LIBTELNET_TELOPT_ZMP 93
 #define LIBTELNET_TELOPT_EXOPL 255
 
-/* libtelnet modes */
-enum libtelnet_mode_t {
-	LIBTELNET_MODE_SERVER = 0,
-	LIBTELNET_MODE_CLIENT,
-	LIBTELNET_MODE_PROXY
-};
+/* libtelnet feature flags */
+#define LIBTELNET_FLAG_PROXY (1<<0)
+
+#define LIBTELNET_PFLAG_DEFLATE (1<<7)
 
 /* telnet states */
 enum libtelnet_state_t {
@@ -152,8 +154,8 @@
 };
 
 /* event handler declaration */
-typedef void (*libtelnet_event_handler_t)(struct libtelnet_t *telnet,
-		struct libtelnet_event_t *event, void *user_data);
+typedef void (*libtelnet_event_handler_t)(libtelnet_t *telnet,
+		libtelnet_event_t *event, void *user_data);
 
 /* state tracker */
 struct libtelnet_t {
@@ -163,8 +165,7 @@
 	libtelnet_event_handler_t eh;
 #ifdef HAVE_ZLIB
 	/* zlib (mccp2) compression */
-	z_stream *z_deflate;
-	z_stream *z_inflate;
+	z_stream *z;
 #endif
 	/* RFC1143 option negotiation states */
 	struct libtelnet_rfc1143_t *q;
@@ -176,8 +177,8 @@
 	unsigned int buffer_pos;
 	/* current state */
 	enum libtelnet_state_t state;
-	/* processing mode */
-	enum libtelnet_mode_t mode;
+	/* option flags */
+	unsigned char flags;
 	/* current subnegotiation telopt */
 	unsigned char sb_telopt;
 	/* length of RFC1143 queue */
@@ -185,35 +186,33 @@
 };
 
 /* initialize a telnet state tracker */
-extern void libtelnet_init(struct libtelnet_t *telnet,
-		libtelnet_event_handler_t eh, enum libtelnet_mode_t mode,
-		void *user_data);
+extern void libtelnet_init(libtelnet_t *telnet, libtelnet_event_handler_t eh,
+		unsigned char flags, void *user_data);
 
 /* free up any memory allocated by a state tracker */
-extern void libtelnet_free(struct libtelnet_t *telnet);
+extern void libtelnet_free(libtelnet_t *telnet);
 
 /* push a byte buffer into the state tracker */
-extern void libtelnet_push(struct libtelnet_t *telnet,
-		unsigned char *buffer, unsigned int size);
+extern void libtelnet_push(libtelnet_t *telnet, unsigned char *buffer,
+		unsigned int size);
 
 /* send an iac command */
-extern void libtelnet_send_command(struct libtelnet_t *telnet,
-		unsigned char cmd);
+extern void libtelnet_send_command(libtelnet_t *telnet, unsigned char cmd);
 
 /* send negotiation */
-extern void libtelnet_send_negotiate(struct libtelnet_t *telnet,
-		unsigned char cmd, unsigned char opt);
+extern void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd,
+		unsigned char opt);
 
 /* send non-command data (escapes IAC bytes) */
-extern void libtelnet_send_data(struct libtelnet_t *telnet,
-		unsigned char *buffer, unsigned int size);
+extern void libtelnet_send_data(libtelnet_t *telnet, unsigned char *buffer,
+		unsigned int size);
 
 /* send sub-request */
-extern void libtelnet_send_subnegotiation(struct libtelnet_t *telnet,
+extern void libtelnet_send_subnegotiation(libtelnet_t *telnet,
 		unsigned char opt, unsigned char *buffer, unsigned int size);
 
 /* begin sending compressed data (server only) */
-extern void libtelnet_begin_compress2(struct libtelnet_t *telnet);
+extern void libtelnet_begin_compress2(libtelnet_t *telnet);
 
 /* return the status of a specific TELNET option on our end (US) */
 extern int libtelnet_get_telopt_local(struct libtelnet_t *telnet,
diff --git a/telnet-client.c b/telnet-client.c
index 3e5f645..ef1b8e6 100644
--- a/telnet-client.c
+++ b/telnet-client.c
@@ -29,7 +29,7 @@
 #include "libtelnet.h"
 
 static struct termios orig_tios;
-static struct libtelnet_t telnet;
+static libtelnet_t telnet;
 static int do_echo;
 
 static void _cleanup(void) {
@@ -76,8 +76,8 @@
 	}
 }
 
-static void _event_handler(struct libtelnet_t *telnet,
-		struct libtelnet_event_t *ev, void *user_data) {
+static void _event_handler(libtelnet_t *telnet, libtelnet_event_t *ev,
+		void *user_data) {
 	int sock = *(int*)user_data;
 
 	switch (ev->type) {
@@ -202,7 +202,7 @@
 	do_echo = 1;
 
 	/* initialize telnet box */
-	libtelnet_init(&telnet, _event_handler, LIBTELNET_MODE_CLIENT, &sock);
+	libtelnet_init(&telnet, _event_handler, 0, &sock);
 
 	/* initialize poll descriptors */
 	memset(pfd, 0, sizeof(pfd));
diff --git a/telnet-proxy.c b/telnet-proxy.c
index 34b2aa1..45480d8 100644
--- a/telnet-proxy.c
+++ b/telnet-proxy.c
@@ -44,7 +44,7 @@
 struct conn_t {
 	const char *name;
 	int sock;
-	struct libtelnet_t telnet;
+	libtelnet_t telnet;
 	struct conn_t *remote;
 };
 
@@ -161,8 +161,8 @@
 	}
 }
 
-static void _event_handler(struct libtelnet_t *telnet,
-		struct libtelnet_event_t *ev, void *user_data) {
+static void _event_handler(libtelnet_t *telnet, libtelnet_event_t *ev,
+		void *user_data) {
 	struct conn_t *conn = (struct conn_t*)user_data;
 
 	switch (ev->type) {
@@ -355,9 +355,9 @@
 		client.remote = &server;
 
 		/* initialize telnet boxes */
-		libtelnet_init(&server.telnet, _event_handler, LIBTELNET_MODE_PROXY,
+		libtelnet_init(&server.telnet, _event_handler, LIBTELNET_FLAG_PROXY,
 				&server);
-		libtelnet_init(&client.telnet, _event_handler, LIBTELNET_MODE_PROXY,
+		libtelnet_init(&client.telnet, _event_handler, LIBTELNET_FLAG_PROXY,
 				&client);
 
 		/* initialize poll descriptors */