make libtelnet_t private; libtelnet_init now returns a pointer instead of taking one, and libtelnet_free frees the pointer passed in

This commit is contained in:
Sean Middleditch 2009-09-19 14:35:48 -07:00
parent d08d812c30
commit d2466a01b6
5 changed files with 76 additions and 63 deletions

View File

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

View File

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

View File

@ -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) {

View File

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

View File

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