From d2466a01b6929ac44d18001162510a2aee51c4fc Mon Sep 17 00:00:00 2001 From: Sean Middleditch Date: Sat, 19 Sep 2009 14:35:48 -0700 Subject: [PATCH] make libtelnet_t private; libtelnet_init now returns a pointer instead of taking one, and libtelnet_free frees the pointer passed in --- libtelnet.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- libtelnet.h | 33 +++------------------------------ telnet-chatd.c | 22 +++++++++++----------- telnet-client.c | 12 ++++++------ telnet-proxy.c | 28 ++++++++++++++-------------- 5 files changed, 76 insertions(+), 63 deletions(-) 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 @@ static int _subnegotiate(telnet_t *telnet) { } /* 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 @@ void telnet_free(telnet_t *telnet) { 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 @@ struct telnet_telopt_t { 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 @@ const telnet_telopt_t telopts[] = { struct user_t { char *name; int sock; - telnet_t telnet; + telnet_t *telnet; char linebuf[256]; int linepos; }; @@ -79,7 +79,7 @@ static void _message(const char *from, const char *msg) { 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 @@ static void _online(const char *line, int overflow, void *ud) { 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 @@ static void _event_handler(telnet_t *telnet, telnet_event_t *ev, free(user->name); user->name = 0; } - telnet_free(&user->telnet); + telnet_free(user->telnet); break; default: /* ignore */ @@ -296,11 +296,11 @@ int main(int argc, char **argv) { /* 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 @@ int main(int argc, char **argv) { 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 @@ int main(int argc, char **argv) { 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 @@ static void _input(char *buffer, int size) { 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 @@ int main(int argc, char **argv) { 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 @@ int main(int argc, char **argv) { /* 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 @@ int main(int argc, char **argv) { } /* 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 @@ static void _event_handler(telnet_t *telnet, telnet_event_t *ev, 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 @@ static void _event_handler(telnet_t *telnet, telnet_event_t *ev, 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 @@ static void _event_handler(telnet_t *telnet, telnet_event_t *ev, } /* 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 @@ int main(int argc, char **argv) { 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 @@ int main(int argc, char **argv) { /* 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 @@ int main(int argc, char **argv) { /* 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 @@ int main(int argc, char **argv) { } /* clean up */ - telnet_free(&server.telnet); - telnet_free(&client.telnet); + telnet_free(server.telnet); + telnet_free(client.telnet); close(server.sock); close(client.sock);