diff --git a/libtelnet.c b/libtelnet.c index ad8d1e4..7235975 100644 --- a/libtelnet.c +++ b/libtelnet.c @@ -49,7 +49,7 @@ static const unsigned int _buffer_sizes_count = sizeof(_buffer_sizes) / * event struct after dispatch; used for the funky REQUEST event */ static int _event(libtelnet_t *telnet, libtelnet_event_type_t type, unsigned char command, unsigned char telopt, - const unsigned char *buffer, unsigned int size) { + const char *buffer, unsigned int size) { libtelnet_event_t ev; ev.buffer = buffer; ev.size = size; @@ -79,7 +79,7 @@ static libtelnet_error_t _error(libtelnet_t *telnet, unsigned line, va_end(va); _event(telnet, fatal ? LIBTELNET_EV_ERROR : LIBTELNET_EV_WARNING, err, - 0, (unsigned char *)buffer, strlen(buffer)); + 0, (char *)buffer, strlen(buffer)); return err; } @@ -128,18 +128,18 @@ libtelnet_error_t _init_zlib(libtelnet_t *telnet, int deflate, int err_fatal) { #endif /* push bytes out, compressing them first if need be */ -static void _send(libtelnet_t *telnet, const unsigned char *buffer, +static void _send(libtelnet_t *telnet, const char *buffer, unsigned int size) { #ifdef HAVE_ZLIB /* if we have a deflate (compression) zlib box, use it */ if (telnet->z != 0 && telnet->flags & LIBTELNET_PFLAG_DEFLATE) { - unsigned char deflate_buffer[1024]; + char deflate_buffer[1024]; int rs; /* initialize z state */ telnet->z->next_in = (unsigned char *)buffer; telnet->z->avail_in = size; - telnet->z->next_out = deflate_buffer; + telnet->z->next_out = (unsigned char *)deflate_buffer; telnet->z->avail_out = sizeof(deflate_buffer); /* deflate until buffer exhausted and all output is produced */ @@ -158,7 +158,7 @@ static void _send(libtelnet_t *telnet, const unsigned char *buffer, sizeof(deflate_buffer) - telnet->z->avail_out); /* prepare output buffer for next run */ - telnet->z->next_out = deflate_buffer; + telnet->z->next_out = (unsigned char *)deflate_buffer; telnet->z->avail_out = sizeof(deflate_buffer); } @@ -416,7 +416,7 @@ void libtelnet_free(libtelnet_t *telnet) { /* push a byte into the telnet buffer */ static libtelnet_error_t _buffer_byte(libtelnet_t *telnet, unsigned char byte) { - unsigned char *new_buffer; + char *new_buffer; unsigned int i; /* check if we're out of room */ @@ -436,7 +436,7 @@ static libtelnet_error_t _buffer_byte(libtelnet_t *telnet, } /* (re)allocate buffer */ - new_buffer = (unsigned char *)realloc(telnet->buffer, + new_buffer = (char *)realloc(telnet->buffer, _buffer_sizes[i + 1]); if (new_buffer == 0) { _error(telnet, __LINE__, __func__, LIBTELNET_ENOMEM, 0, @@ -454,7 +454,7 @@ static libtelnet_error_t _buffer_byte(libtelnet_t *telnet, return LIBTELNET_EOK; } -static void _process(libtelnet_t *telnet, const unsigned char *buffer, +static void _process(libtelnet_t *telnet, const char *buffer, unsigned int size) { unsigned char byte; unsigned int i, start; @@ -495,7 +495,7 @@ static void _process(libtelnet_t *telnet, const unsigned char *buffer, break; /* IAC escaping */ case LIBTELNET_IAC: - _event(telnet, LIBTELNET_EV_DATA, 0, 0, &byte, 1); + _event(telnet, LIBTELNET_EV_DATA, 0, 0, (char*)&byte, 1); start = i + 1; telnet->state = LIBTELNET_STATE_DATA; break; @@ -614,18 +614,18 @@ static void _process(libtelnet_t *telnet, const unsigned char *buffer, } /* push a bytes into the state tracker */ -void libtelnet_push(libtelnet_t *telnet, const unsigned char *buffer, +void libtelnet_push(libtelnet_t *telnet, const char *buffer, unsigned int size) { #ifdef HAVE_ZLIB /* if we have an inflate (decompression) zlib stream, use it */ if (telnet->z != 0 && !(telnet->flags & LIBTELNET_PFLAG_DEFLATE)) { - unsigned char inflate_buffer[4096]; + char inflate_buffer[4096]; int rs; /* initialize zlib state */ - telnet->z->next_in = (unsigned char *)buffer; + telnet->z->next_in = (unsigned char*)buffer; telnet->z->avail_in = size; - telnet->z->next_out = inflate_buffer; + telnet->z->next_out = (unsigned char *)inflate_buffer; telnet->z->avail_out = sizeof(inflate_buffer); /* inflate until buffer exhausted and all output is produced */ @@ -644,7 +644,7 @@ void libtelnet_push(libtelnet_t *telnet, const unsigned char *buffer, "inflate() failed: %s", zError(rs)); /* prepare output buffer for next run */ - telnet->z->next_out = inflate_buffer; + telnet->z->next_out = (unsigned char *)inflate_buffer; telnet->z->avail_out = sizeof(inflate_buffer); /* on error (or on end of stream) disable further inflation */ @@ -666,14 +666,14 @@ void libtelnet_push(libtelnet_t *telnet, const unsigned char *buffer, /* send an iac command */ void libtelnet_send_command(libtelnet_t *telnet, unsigned char cmd) { - unsigned char bytes[2] = { LIBTELNET_IAC, cmd }; + char bytes[2] = { LIBTELNET_IAC, cmd }; _send(telnet, bytes, 2); } /* send an iac command with telopt */ void libtelnet_send_telopt(libtelnet_t *telnet, unsigned char cmd, unsigned char telopt) { - unsigned char bytes[3] = { LIBTELNET_IAC, cmd, telopt }; + char bytes[3] = { LIBTELNET_IAC, cmd, telopt }; _send(telnet, bytes, 3); } @@ -684,7 +684,7 @@ void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd, /* if we're in proxy mode, just send it now */ if (telnet->flags & LIBTELNET_FLAG_PROXY) { - unsigned char bytes[3] = { LIBTELNET_IAC, cmd, telopt }; + char bytes[3] = { LIBTELNET_IAC, cmd, telopt }; _send(telnet, bytes, 3); return; } @@ -796,7 +796,7 @@ void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd, } /* send non-command data (escapes IAC bytes) */ -void libtelnet_send_data(libtelnet_t *telnet, const unsigned char *buffer, +void libtelnet_send_data(libtelnet_t *telnet, const char *buffer, unsigned int size) { unsigned int i, l; @@ -820,7 +820,7 @@ void libtelnet_send_data(libtelnet_t *telnet, const unsigned char *buffer, /* send sub-request */ void libtelnet_send_subnegotiation(libtelnet_t *telnet, unsigned char telopt, - const unsigned char *buffer, unsigned int size) { + const char *buffer, unsigned int size) { libtelnet_send_telopt(telnet, LIBTELNET_SB, telopt); libtelnet_send_data(telnet, buffer, size); libtelnet_send_command(telnet, LIBTELNET_SE); @@ -843,7 +843,7 @@ void libtelnet_send_subnegotiation(libtelnet_t *telnet, unsigned char telopt, void libtelnet_begin_compress2(libtelnet_t *telnet) { #ifdef HAVE_ZLIB - static const unsigned char compress2[] = { LIBTELNET_IAC, LIBTELNET_SB, + static const char compress2[] = { LIBTELNET_IAC, LIBTELNET_SB, LIBTELNET_TELOPT_COMPRESS2, LIBTELNET_IAC, LIBTELNET_SE }; /* attempt to create output stream first, bail if we can't */ @@ -873,15 +873,15 @@ int libtelnet_printf(libtelnet_t *telnet, const char *fmt, ...) { va_end(va); /* send */ - libtelnet_send_data(telnet, (unsigned char *)buffer, rs); + libtelnet_send_data(telnet, (char *)buffer, rs); return rs; } /* send formatted data with \r and \n translation in addition to IAC IAC */ int libtelnet_printf2(libtelnet_t *telnet, const char *fmt, ...) { - static const unsigned char CRLF[] = { '\r', '\n' }; - static const unsigned char CRNUL[] = { '\r', '\0' }; + static const char CRLF[] = { '\r', '\n' }; + static const char CRNUL[] = { '\r', '\0' }; char buffer[4096]; va_list va; int rs, i, l; @@ -898,7 +898,7 @@ int libtelnet_printf2(libtelnet_t *telnet, const char *fmt, ...) { buffer[i] == '\n') { /* dump prior portion of text */ if (i != l) - _send(telnet, (unsigned char *)buffer + l, i - l); + _send(telnet, (char *)buffer + l, i - l); l = i + 1; /* IAC -> IAC IAC */ @@ -915,7 +915,7 @@ int libtelnet_printf2(libtelnet_t *telnet, const char *fmt, ...) { /* send whatever portion of buffer is left */ if (i != l) - _send(telnet, (unsigned char *)buffer + l, i - l); + _send(telnet, (char *)buffer + l, i - l); return rs; } diff --git a/libtelnet.h b/libtelnet.h index 1e1cef2..4f26640 100644 --- a/libtelnet.h +++ b/libtelnet.h @@ -135,7 +135,7 @@ typedef enum libtelnet_event_type_t libtelnet_event_type_t; /* event information */ struct libtelnet_event_t { /* data buffer: for DATA, SEND, SUBNEGOTIATION, and ERROR events */ - const unsigned char *buffer; + const char *buffer; unsigned int size; /* type of event */ enum libtelnet_event_type_t type; @@ -170,7 +170,7 @@ struct libtelnet_t { /* RFC1143 option negotiation states */ struct libtelnet_rfc1143_t *q; /* sub-request buffer */ - unsigned char *buffer; + char *buffer; /* current size of the buffer */ unsigned int buffer_size; /* current buffer write position (also length of buffer data) */ @@ -193,7 +193,7 @@ extern void libtelnet_init(libtelnet_t *telnet, libtelnet_event_handler_t eh, extern void libtelnet_free(libtelnet_t *telnet); /* push a byte buffer into the state tracker */ -extern void libtelnet_push(libtelnet_t *telnet, const unsigned char *buffer, +extern void libtelnet_push(libtelnet_t *telnet, const char *buffer, unsigned int size); /* send an iac command */ @@ -212,7 +212,7 @@ extern void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd, /* send non-command data (escapes IAC bytes) */ extern void libtelnet_send_data(libtelnet_t *telnet, - const unsigned char *buffer, unsigned int size); + const char *buffer, unsigned int size); /* send sub-request, equivalent to: * libtelnet_send_telopt(telnet, LIBTELNET_SB, telopt) @@ -222,7 +222,7 @@ extern void libtelnet_send_data(libtelnet_t *telnet, * thare are most easily implemented with a series of send_data calls. */ extern void libtelnet_send_subnegotiation(libtelnet_t *telnet, - unsigned char telopt, const unsigned char *buffer, unsigned int size); + unsigned char telopt, const char *buffer, unsigned int size); /* begin sending compressed data (server only) */ extern void libtelnet_begin_compress2(libtelnet_t *telnet); diff --git a/telnet-chatd.c b/telnet-chatd.c deleted file mode 100644 index 5d9d204..0000000 --- a/telnet-chatd.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Sean Middleditch - * sean@sourcemud.org - * - * The author or authors of this code dedicate any and all copyright interest - * in this code to the public domain. We make this dedication for the benefit - * of the public at large and to the detriment of our heirs and successors. We - * intend this dedication to be an overt act of relinquishment in perpetuity of - * all present and future rights to this code under copyright law. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_ZLIB -#include "zlib.h" -#endif - -#include "libtelnet.h" - -#define MAX_USERS 64 -#define LINEBUFFER_SIZE 256 - -struct user_t { - char *name; - int sock; - libtelnet_t telnet; - char linebuf[256]; - int linepos; -}; - -static struct user_t users[MAX_USERS]; - -static void linebuffer_push(char *buffer, size_t size, int *linepos, - char ch, void (*cb)(const char *line, int overflow, void *ud), - void *ud) { - - /* CRLF -- line terminator */ - if (ch == '\n' && *linepos > 0 && buffer[*linepos - 1] == '\r') { - /* NUL terminate (replaces \r in buffer), notify app, clear */ - buffer[*linepos - 1] = 0; - cb(buffer, 0, ud); - *linepos = 0; - - /* CRNUL -- just a CR */ - } else if (ch == 0 && *linepos > 0 && buffer[*linepos - 1] == '\r') { - /* do nothing, the CR is already in the buffer */ - - /* anything else (including technically invalid CR followed by - * anything besides LF or NUL -- just buffer if we have room - * \r - */ - } else if (*linepos != size) { - buffer[(*linepos)++] = ch; - - /* buffer overflow */ - } else { - /* terminate (NOTE: eats a byte), notify app, clear buffer */ - buffer[size - 1] = 0; - cb(buffer, size - 1, ud); - *linepos = 0; - } -} - -static void _message(const char *from, const char *msg) { - int i; - for (i = 0; i != MAX_USERS; ++i) { - if (users[i].sock != -1) { - libtelnet_printf2(&users[i].telnet, "%s: %s\n", from, msg); - } - } -} - -static void _send(int sock, const unsigned char *buffer, unsigned int size) { - int rs; - - /* ignore on invalid socket */ - if (sock == -1) - return; - - /* send data */ - while (size > 0) { - if ((rs = send(sock, buffer, size, 0)) == -1) { - if (errno != EINTR && errno != ECONNRESET) { - fprintf(stderr, "send() failed: %s\n", strerror(errno)); - exit(1); - } else { - return; - } - } else if (rs == 0) { - fprintf(stderr, "send() unexpectedly returned 0\n"); - exit(1); - } - - /* update pointer and size to see if we've got more to send */ - buffer += rs; - size -= rs; - } -} - -/* process input line */ -static void _online(const char *line, int overflow, void *ud) { - struct user_t *user = (struct user_t*)ud; - int i; - - /* if the user has no name, this is his "login" */ - if (user->name == 0) { - /* must not be empty, must be at least 32 chars */ - if (strlen(line) == 0 || strlen(line) > 32) { - libtelnet_printf2(&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) { - libtelnet_printf2(&user->telnet, "Name in use.\nEnter name: "); - return; - } - } - - /* keep name */ - user->name = strdup(line); - libtelnet_printf2(&user->telnet, "Welcome, %s!\n", line); - return; - } - - /* if line is "quit" then, well, quit */ - if (strcmp(line, "quit") == 0) { - close(user->sock); - user->sock = -1; - _message(user->name, "** HAS QUIT **"); - free(user->name); - user->name = 0; - return; - } - - /* just a message -- send to all users */ - _message(user->name, line); -} - -static void _input(struct user_t *user, const unsigned char *buffer, - unsigned int size) { - unsigned int i; - for (i = 0; i != size; ++i) - linebuffer_push(user->linebuf, sizeof(user->linebuf), &user->linepos, - (char)buffer[i], _online, user); -} - -static void _event_handler(libtelnet_t *telnet, libtelnet_event_t *ev, - void *user_data) { - struct user_t *user = (struct user_t*)user_data; - - switch (ev->type) { - /* data received */ - case LIBTELNET_EV_DATA: - _input(user, ev->buffer, ev->size); - break; - /* data must be sent */ - case LIBTELNET_EV_SEND: - _send(user->sock, ev->buffer, ev->size); - break; - /* error */ - case LIBTELNET_EV_ERROR: - close(user->sock); - user->sock = -1; - if (user->name != 0) { - _message(user->name, "** HAS HAD AN ERROR **"); - free(user->name); - user->name = 0; - } - libtelnet_free(&user->telnet); - break; - default: - /* ignore */ - break; - } -} - -int main(int argc, char **argv) { - unsigned char buffer[512]; - short listen_port; - int listen_sock; - int rs; - int i; - struct sockaddr_in addr; - socklen_t addrlen; - struct pollfd pfd[MAX_USERS + 1]; - - /* check usage */ - if (argc != 2) { - fprintf(stderr, "Usage:\n ./telnet-chatd \n"); - return 1; - } - - /* initialize data structures */ - memset(&pfd, 0, sizeof(pfd)); - memset(users, 0, sizeof(users)); - for (i = 0; i != MAX_USERS; ++i) - users[i].sock = -1; - - /* parse listening port */ - listen_port = strtol(argv[1], 0, 10); - - /* create listening socket */ - if ((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - fprintf(stderr, "socket() failed: %s\n", strerror(errno)); - return 1; - } - - /* reuse address option */ - rs = 1; - setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &rs, sizeof(rs)); - - /* bind to listening addr/port */ - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_port = htons(listen_port); - if (bind(listen_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - fprintf(stderr, "bind() failed: %s\n", strerror(errno)); - return 1; - } - - /* listen for clients */ - if (listen(listen_sock, 5) == -1) { - fprintf(stderr, "listen() failed: %s\n", strerror(errno)); - return 1; - } - - printf("LISTENING ON PORT %d\n", listen_port); - - /* initialize listening descriptors */ - pfd[MAX_USERS].fd = listen_sock; - pfd[MAX_USERS].events = POLLIN; - - /* loop for ever */ - for (;;) { - /* prepare for poll */ - for (i = 0; i != MAX_USERS; ++i) { - if (users[i].sock != -1) { - pfd[i].fd = users[i].sock; - pfd[i].events = POLLIN; - } else { - pfd[i].fd = -1; - pfd[i].events = 0; - } - } - - /* poll */ - rs = poll(pfd, MAX_USERS + 1, -1); - if (rs == -1 && errno != EINTR) { - fprintf(stderr, "poll() failed: %s\n", strerror(errno)); - return 1; - } - - /* new connection */ - if (pfd[MAX_USERS].revents & POLLIN) { - /* acept the sock */ - addrlen = sizeof(addr); - if ((rs = accept(listen_sock, (struct sockaddr *)&addr, - &addrlen)) == -1) { - fprintf(stderr, "accept() failed: %s\n", strerror(errno)); - return 1; - } - - printf("Connection received.\n"); - - /* find a free user */ - for (i = 0; i != MAX_USERS; ++i) - if (users[i].sock == -1) - break; - if (i == MAX_USERS) { - printf(" rejected (too many users)\n"); - _send(rs, (unsigned char *)"Too many users.\r\n", 14); - close(rs); - } - - /* init, welcome */ - users[i].sock = rs; - libtelnet_init(&users[i].telnet, _event_handler, 0, &users[i]); - libtelnet_printf2(&users[i].telnet, "Enter name: "); - } - - /* read from client */ - for (i = 0; i != MAX_USERS; ++i) { - /* skip users that aren't actually connected */ - if (users[i].sock == -1) - continue; - - if (pfd[i].revents & POLLIN) { - if ((rs = recv(users[i].sock, buffer, sizeof(buffer), 0)) > 0) { - libtelnet_push(&users[i].telnet, buffer, rs); - } else if (rs == 0) { - printf("Connection closed.\n"); - close(users[i].sock); - if (users[i].name != 0) { - _message(users[i].name, "** HAS DISCONNECTED **"); - free(users[i].name); - users[i].name = 0; - } - libtelnet_free(&users[i].telnet); - users[i].sock = -1; - break; - } else if (errno != EINTR) { - fprintf(stderr, "recv(client) failed: %s\n", - strerror(errno)); - exit(1); - } - } - } - } - - /* not that we can reach this, but GCC will cry if it's not here */ - return 0; -} diff --git a/telnet-client.c b/telnet-client.c index e801611..d58f76b 100644 --- a/telnet-client.c +++ b/telnet-client.c @@ -36,8 +36,8 @@ static void _cleanup(void) { tcsetattr(STDOUT_FILENO, TCSADRAIN, &orig_tios); } -static void _input(unsigned char *buffer, int size) { - static unsigned char crlf[] = { '\r', '\n' }; +static void _input(char *buffer, int size) { + static char crlf[] = { '\r', '\n' }; int i; for (i = 0; i != size; ++i) { @@ -57,7 +57,7 @@ static void _input(unsigned char *buffer, int size) { } } -static void _send(int sock, const unsigned char *buffer, unsigned int size) { +static void _send(int sock, const char *buffer, unsigned int size) { int rs; /* send data */ @@ -127,7 +127,7 @@ static void _event_handler(libtelnet_t *telnet, libtelnet_event_t *ev, buffer[0] = 0; /* IS code for RFC 1091 */ snprintf(buffer + 1, sizeof(buffer) - 1, "%s", getenv("TERM")); libtelnet_send_subnegotiation(telnet, LIBTELNET_TELOPT_TTYPE, - (unsigned char *)buffer, 1 + strlen(buffer + 1)); + (char *)buffer, 1 + strlen(buffer + 1)); } break; /* error */ @@ -141,7 +141,7 @@ static void _event_handler(libtelnet_t *telnet, libtelnet_event_t *ev, } int main(int argc, char **argv) { - unsigned char buffer[512]; + char buffer[512]; int rs; int sock; struct sockaddr_in addr; diff --git a/telnet-proxy.c b/telnet-proxy.c index e8f2661..f71e4dd 100644 --- a/telnet-proxy.c +++ b/telnet-proxy.c @@ -129,7 +129,7 @@ static const char *get_opt(unsigned char opt) { } } -static void print_buffer(const unsigned char *buffer, unsigned int size) { +static void print_buffer(const char *buffer, unsigned int size) { unsigned int i; for (i = 0; i != size; ++i) { if (buffer[i] == ' ' || (isprint(buffer[i]) && !isspace(buffer[i]))) @@ -142,7 +142,7 @@ static void print_buffer(const unsigned char *buffer, unsigned int size) { } } -static void _send(int sock, const unsigned char *buffer, unsigned int size) { +static void _send(int sock, const char *buffer, unsigned int size) { int rs; /* send data */ @@ -254,7 +254,7 @@ static void _event_handler(libtelnet_t *telnet, libtelnet_event_t *ev, } int main(int argc, char **argv) { - unsigned char buffer[512]; + char buffer[512]; short listen_port; int listen_sock; int rs;