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);