make libtelnet_t private; libtelnet_init now returns a pointer instead of taking one, and libtelnet_free frees the pointer passed in
diff --git a/libtelnet.c b/libtelnet.c
index aa1117e..0442305 100644
--- a/libtelnet.c
+++ b/libtelnet.c
@@ -35,6 +35,36 @@
 # define INLINE
 #endif
 
+/* telnet state */
+struct telnet_t {
+	/* user data */
+	void *ud;
+	/* telopt support table */
+	const telnet_telopt_t *telopts;
+	/* event handler */
+	telnet_event_handler_t eh;
+#ifdef HAVE_ZLIB
+	/* zlib (mccp2) compression */
+	z_stream *z;
+#endif
+	/* RFC1143 option negotiation states */
+	struct telnet_rfc1143_t *q;
+	/* sub-request buffer */
+	char *buffer;
+	/* current size of the buffer */
+	size_t buffer_size;
+	/* current buffer write position (also length of buffer data) */
+	size_t buffer_pos;
+	/* current state */
+	enum telnet_state_t state;
+	/* option flags */
+	unsigned char flags;
+	/* current subnegotiation telopt */
+	unsigned char sb_telopt;
+	/* length of RFC1143 queue */
+	unsigned char q_size;
+};
+
 /* RFC1143 option negotiation state */
 typedef struct telnet_rfc1143_t {
 	unsigned char telopt;
@@ -559,13 +589,20 @@
 }
 
 /* initialize a telnet state tracker */
-void telnet_init(telnet_t *telnet, const telnet_telopt_t *telopts,
+telnet_t *telnet_init(const telnet_telopt_t *telopts,
 		telnet_event_handler_t eh, unsigned char flags, void *user_data) {
-	memset(telnet, 0, sizeof(telnet_t));
+	/* allocate structure */
+	struct telnet_t *telnet = (telnet_t*)calloc(1, sizeof(telnet_t));
+	if (telnet == 0)
+		return 0;
+
+	/* initialize data */
 	telnet->ud = user_data;
 	telnet->telopts = telopts;
 	telnet->eh = eh;
 	telnet->flags = flags;
+
+	return telnet;
 }
 
 /* free up any memory allocated by a state tracker */
@@ -596,6 +633,9 @@
 		telnet->q = 0;
 		telnet->q_size = 0;
 	}
+
+	/* free the telnet structure itself */
+	free(telnet);
 }
 
 /* push a byte into the telnet buffer */
diff --git a/libtelnet.h b/libtelnet.h
index 69eb864..84f48ff 100644
--- a/libtelnet.h
+++ b/libtelnet.h
@@ -186,38 +186,11 @@
 	unsigned char him; /* TELNET_DO or TELNET_DONT */
 };
 
-/* state tracker */
-struct telnet_t {
-	/* user data */
-	void *ud;
-	/* telopt support table */
-	const telnet_telopt_t *telopts;
-	/* event handler */
-	telnet_event_handler_t eh;
-#ifdef HAVE_ZLIB
-	/* zlib (mccp2) compression */
-	z_stream *z;
-#endif
-	/* RFC1143 option negotiation states */
-	struct telnet_rfc1143_t *q;
-	/* sub-request buffer */
-	char *buffer;
-	/* current size of the buffer */
-	size_t buffer_size;
-	/* current buffer write position (also length of buffer data) */
-	size_t buffer_pos;
-	/* current state */
-	enum telnet_state_t state;
-	/* option flags */
-	unsigned char flags;
-	/* current subnegotiation telopt */
-	unsigned char sb_telopt;
-	/* length of RFC1143 queue */
-	unsigned char q_size;
-};
+/* state tracker -- private data structure */
+struct telnet_t;
 
 /* initialize a telnet state tracker */
-extern void telnet_init(telnet_t *telnet, const telnet_telopt_t *telopts,
+extern telnet_t* telnet_init(const telnet_telopt_t *telopts,
 		telnet_event_handler_t eh, unsigned char flags, void *user_data);
 
 /* free up any memory allocated by a state tracker */
diff --git a/telnet-chatd.c b/telnet-chatd.c
index aa56e63..7bad622 100644
--- a/telnet-chatd.c
+++ b/telnet-chatd.c
@@ -37,7 +37,7 @@
 struct user_t {
 	char *name;
 	int sock;
-	telnet_t telnet;
+	telnet_t *telnet;
 	char linebuf[256];
 	int linepos;
 };
@@ -79,7 +79,7 @@
 	int i;
 	for (i = 0; i != MAX_USERS; ++i) {
 		if (users[i].sock != -1) {
-			telnet_printf(&users[i].telnet, "%s: %s\n", from, msg);
+			telnet_printf(users[i].telnet, "%s: %s\n", from, msg);
 		}
 	}
 }
@@ -120,21 +120,21 @@
 	if (user->name == 0) {
 		/* must not be empty, must be at least 32 chars */
 		if (strlen(line) == 0 || strlen(line) > 32) {
-			telnet_printf(&user->telnet, "Invalid name.\nEnter name: ");
+			telnet_printf(user->telnet, "Invalid name.\nEnter name: ");
 			return;
 		}
 
 		/* must not already be in use */
 		for (i = 0; i != MAX_USERS; ++i) {
 			if (users[i].name != 0 && strcmp(users[i].name, line) == 0) {
-				telnet_printf(&user->telnet, "Name in use.\nEnter name: ");
+				telnet_printf(user->telnet, "Name in use.\nEnter name: ");
 				return;
 			}
 		}
 
 		/* keep name */
 		user->name = strdup(line);
-		telnet_printf(&user->telnet, "Welcome, %s!\n", line);
+		telnet_printf(user->telnet, "Welcome, %s!\n", line);
 		return;
 	}
 
@@ -187,7 +187,7 @@
 			free(user->name);
 			user->name = 0;
 		}
-		telnet_free(&user->telnet);
+		telnet_free(user->telnet);
 		break;
 	default:
 		/* ignore */
@@ -296,11 +296,11 @@
 
 			/* init, welcome */
 			users[i].sock = rs;
-			telnet_init(&users[i].telnet, telopts, _event_handler, 0,
+			users[i].telnet = telnet_init(telopts, _event_handler, 0,
 					&users[i]);
-			telnet_negotiate(&users[i].telnet, TELNET_WILL,
+			telnet_negotiate(users[i].telnet, TELNET_WILL,
 					TELNET_TELOPT_COMPRESS2);
-			telnet_printf(&users[i].telnet, "Enter name: ");
+			telnet_printf(users[i].telnet, "Enter name: ");
 		}
 
 		/* read from client */
@@ -311,7 +311,7 @@
 
 			if (pfd[i].revents & POLLIN) {
 				if ((rs = recv(users[i].sock, buffer, sizeof(buffer), 0)) > 0) {
-					telnet_recv(&users[i].telnet, buffer, rs);
+					telnet_recv(users[i].telnet, buffer, rs);
 				} else if (rs == 0) {
 					printf("Connection closed.\n");
 					close(users[i].sock);
@@ -320,7 +320,7 @@
 						free(users[i].name);
 						users[i].name = 0;
 					}
-					telnet_free(&users[i].telnet);
+					telnet_free(users[i].telnet);
 					users[i].sock = -1;
 					break;
 				} else if (errno != EINTR) {
diff --git a/telnet-client.c b/telnet-client.c
index 42a5ba5..5565656 100644
--- a/telnet-client.c
+++ b/telnet-client.c
@@ -29,7 +29,7 @@
 #include "libtelnet.h"
 
 static struct termios orig_tios;
-static telnet_t telnet;
+static telnet_t *telnet;
 static int do_echo;
 
 static const telnet_telopt_t telopts[] = {
@@ -56,11 +56,11 @@
 		if (buffer[i] == '\r' || buffer[i] == '\n') {
 			if (do_echo)
 				printf("\r\n");
-			telnet_send(&telnet, crlf, 2);
+			telnet_send(telnet, crlf, 2);
 		} else {
 			if (do_echo)
 				putchar(buffer[i]);
-			telnet_send(&telnet, buffer + i, 1);
+			telnet_send(telnet, buffer + i, 1);
 		}
 	}
 	fflush(stdout);
@@ -197,7 +197,7 @@
 	do_echo = 1;
 
 	/* initialize telnet box */
-	telnet_init(&telnet, telopts, _event_handler, 0, &sock);
+	telnet = telnet_init(telopts, _event_handler, 0, &sock);
 
 	/* initialize poll descriptors */
 	memset(pfd, 0, sizeof(pfd));
@@ -224,7 +224,7 @@
 		/* read from client */
 		if (pfd[1].revents & POLLIN) {
 			if ((rs = recv(sock, buffer, sizeof(buffer), 0)) > 0) {
-				telnet_recv(&telnet, buffer, rs);
+				telnet_recv(telnet, buffer, rs);
 			} else if (rs == 0) {
 				break;
 			} else {
@@ -236,7 +236,7 @@
 	}
 
 	/* clean up */
-	telnet_free(&telnet);
+	telnet_free(telnet);
 	close(sock);
 
 	return 0;
diff --git a/telnet-proxy.c b/telnet-proxy.c
index 2956f88..04fe28d 100644
--- a/telnet-proxy.c
+++ b/telnet-proxy.c
@@ -44,7 +44,7 @@
 struct conn_t {
 	const char *name;
 	int sock;
-	telnet_t telnet;
+	telnet_t *telnet;
 	struct conn_t *remote;
 };
 
@@ -176,7 +176,7 @@
 		print_buffer(ev->buffer, ev->size);
 		printf(COLOR_NORMAL "\n");
 
-		telnet_send(&conn->remote->telnet, ev->buffer, ev->size);
+		telnet_send(conn->remote->telnet, ev->buffer, ev->size);
 		break;
 	/* data must be sent */
 	case TELNET_EV_SEND:
@@ -193,33 +193,33 @@
 		printf("%s IAC %s" COLOR_NORMAL "\n", conn->name,
 				get_cmd(ev->command));
 
-		telnet_iac(&conn->remote->telnet, ev->command);
+		telnet_iac(conn->remote->telnet, ev->command);
 		break;
 	/* negotiation, WILL */
 	case TELNET_EV_WILL:
 		printf("%s IAC WILL %d (%s)" COLOR_NORMAL "\n", conn->name,
 				(int)ev->telopt, get_opt(ev->telopt));
-		telnet_negotiate(&conn->remote->telnet, TELNET_WILL,
+		telnet_negotiate(conn->remote->telnet, TELNET_WILL,
 				ev->telopt);
 		break;
 	/* negotiation, WONT */
 	case TELNET_EV_WONT:
 		printf("%s IAC WONT %d (%s)" COLOR_NORMAL "\n", conn->name,
 				(int)ev->telopt, get_opt(ev->telopt));
-		telnet_negotiate(&conn->remote->telnet, TELNET_WONT,
+		telnet_negotiate(conn->remote->telnet, TELNET_WONT,
 				ev->telopt);
 		break;
 	/* negotiation, DO */
 	case TELNET_EV_DO:
 		printf("%s IAC DO %d (%s)" COLOR_NORMAL "\n", conn->name,
 				(int)ev->telopt, get_opt(ev->telopt));
-		telnet_negotiate(&conn->remote->telnet, TELNET_DO,
+		telnet_negotiate(conn->remote->telnet, TELNET_DO,
 				ev->telopt);
 		break;
 	case TELNET_EV_DONT:
 		printf("%s IAC DONT %d (%s)" COLOR_NORMAL "\n", conn->name,
 				(int)ev->telopt, get_opt(ev->telopt));
-		telnet_negotiate(&conn->remote->telnet, TELNET_DONT,
+		telnet_negotiate(conn->remote->telnet, TELNET_DONT,
 				ev->telopt);
 		break;
 	/* subnegotiation */
@@ -264,7 +264,7 @@
 		}
 
 		/* forward */
-		telnet_subnegotiation(&conn->remote->telnet, ev->telopt,
+		telnet_subnegotiation(conn->remote->telnet, ev->telopt,
 				ev->buffer, ev->size);
 		break;
 	/* compression notification */
@@ -389,9 +389,9 @@
 		client.remote = &server;
 
 		/* initialize telnet boxes */
-		telnet_init(&server.telnet, 0, _event_handler, TELNET_FLAG_PROXY,
+		server.telnet = telnet_init(0, _event_handler, TELNET_FLAG_PROXY,
 				&server);
-		telnet_init(&client.telnet, 0, _event_handler, TELNET_FLAG_PROXY,
+		client.telnet = telnet_init(0, _event_handler, TELNET_FLAG_PROXY,
 				&client);
 
 		/* initialize poll descriptors */
@@ -406,7 +406,7 @@
 			/* read from server */
 			if (pfd[0].revents & POLLIN) {
 				if ((rs = recv(server.sock, buffer, sizeof(buffer), 0)) > 0) {
-					telnet_recv(&server.telnet, buffer, rs);
+					telnet_recv(server.telnet, buffer, rs);
 				} else if (rs == 0) {
 					printf("%s DISCONNECTED" COLOR_NORMAL "\n", server.name);
 					break;
@@ -422,7 +422,7 @@
 			/* read from client */
 			if (pfd[1].revents & POLLIN) {
 				if ((rs = recv(client.sock, buffer, sizeof(buffer), 0)) > 0) {
-					telnet_recv(&client.telnet, buffer, rs);
+					telnet_recv(client.telnet, buffer, rs);
 				} else if (rs == 0) {
 					printf("%s DISCONNECTED" COLOR_NORMAL "\n", client.name);
 					break;
@@ -437,8 +437,8 @@
 		}
 
 		/* clean up */
-		telnet_free(&server.telnet);
-		telnet_free(&client.telnet);
+		telnet_free(server.telnet);
+		telnet_free(client.telnet);
 		close(server.sock);
 		close(client.sock);