scrap the multiple callbacks thing, just use a single event handler callback
diff --git a/libtelnet.c b/libtelnet.c
index 0c3496b..755ebed 100644
--- a/libtelnet.c
+++ b/libtelnet.c
@@ -22,10 +22,10 @@
#include "libtelnet.h"
+/* error handler helpers */
#ifdef ERROR
# undef ERROR
#endif
-
#define ERROR(telnet, code, user_data, msg) \
_error(telnet, __FILE__, __LINE__, code, user_data, "%s", msg)
#define ERROR_NOMEM(telnet, user_data, msg) \
@@ -46,6 +46,21 @@
static const unsigned int _buffer_sizes_count =
sizeof(_buffer_sizes) / sizeof(_buffer_sizes[0]);
+/* event dispatch helper */
+static void _event(struct libtelnet_t *telnet,
+ enum libtelnet_event_type_t type, unsigned char command,
+ unsigned char telopt, unsigned char *buffer, unsigned int size,
+ void *user_data) {
+ struct libtelnet_event_t ev;
+ ev.type = type;
+ ev.command = command;
+ ev.telopt = telopt;
+ ev.buffer = buffer;
+ ev.size = size;
+
+ telnet->eh(telnet, &ev, user_data);
+}
+
/* error generation function */
static void _error(struct libtelnet_t *telnet, const char *file, unsigned line,
enum libtelnet_error_t err, void *user_data, const char *fmt, ...) {
@@ -61,13 +76,7 @@
fmt, va);
va_end(va);
- /* invoke user's custom error handler if possible; otherwise,
- * print to stderr
- */
- if (telnet->cb->error)
- telnet->cb->error(telnet, err, buffer, user_data);
- else
- fprintf(stderr, "**ERROR**: libtelnet: %s\n", buffer);
+ _event(telnet, LIBTELNET_EV_ERROR, err, 0, 0, 0, user_data);
}
/* initialize the zlib box for a telnet box; if deflate is non-zero, it
@@ -105,10 +114,10 @@
}
/* initialize a telnet state tracker */
-void libtelnet_init(struct libtelnet_t *telnet, struct libtelnet_cb_t *cb,
+void libtelnet_init(struct libtelnet_t *telnet, libtelnet_event_handler_t eh,
enum libtelnet_mode_t mode) {
memset(telnet, 0, sizeof(struct libtelnet_t));
- telnet->cb = cb;
+ telnet->eh = eh;
telnet->mode = mode;
}
@@ -188,8 +197,8 @@
* switch states */
if (byte == LIBTELNET_IAC) {
if (i != start)
- telnet->cb->data(telnet, &buffer[start], i - start,
- user_data);
+ _event(telnet, LIBTELNET_EV_DATA, 0, 0, &buffer[start],
+ i - start, user_data);
telnet->state = LIBTELNET_STATE_IAC;
}
break;
@@ -216,13 +225,13 @@
break;
/* IAC escaping */
case LIBTELNET_IAC:
- telnet->cb->data(telnet, &byte, 1, user_data);
+ _event(telnet, LIBTELNET_EV_DATA, 0, 0, &byte, 1, user_data);
start = i + 1;
telnet->state = LIBTELNET_STATE_DATA;
break;
/* some other command */
default:
- telnet->cb->command(telnet, byte, user_data);
+ _event(telnet, LIBTELNET_EV_IAC, byte, 0, 0, 0, user_data);
start = i + 1;
telnet->state = LIBTELNET_STATE_DATA;
}
@@ -230,22 +239,26 @@
/* negotiation commands */
case LIBTELNET_STATE_DO:
- telnet->cb->negotiate(telnet, LIBTELNET_DO, byte, user_data);
+ _event(telnet, LIBTELNET_EV_NEGOTIATE, LIBTELNET_DO, byte,
+ 0, 0, user_data);
start = i + 1;
telnet->state = LIBTELNET_STATE_DATA;
break;
case LIBTELNET_STATE_DONT:
- telnet->cb->negotiate(telnet, LIBTELNET_DONT, byte, user_data);
+ _event(telnet, LIBTELNET_EV_NEGOTIATE, LIBTELNET_DONT, byte,
+ 0, 0, user_data);
start = i + 1;
telnet->state = LIBTELNET_STATE_DATA;
break;
case LIBTELNET_STATE_WILL:
- telnet->cb->negotiate(telnet, LIBTELNET_WILL, byte, user_data);
+ _event(telnet, LIBTELNET_EV_NEGOTIATE, LIBTELNET_WILL, byte,
+ 0, 0, user_data);
start = i + 1;
telnet->state = LIBTELNET_STATE_DATA;
break;
case LIBTELNET_STATE_WONT:
- telnet->cb->negotiate(telnet, LIBTELNET_WONT, byte, user_data);
+ _event(telnet, LIBTELNET_EV_NEGOTIATE, LIBTELNET_WONT, byte,
+ 0, 0, user_data);
start = i + 1;
telnet->state = LIBTELNET_STATE_DATA;
break;
@@ -280,8 +293,9 @@
}
/* invoke callback */
- telnet->cb->subnegotiation(telnet, telnet->buffer[0],
- telnet->buffer + 1, telnet->length - 1, user_data);
+ _event(telnet, LIBTELNET_EV_SUBNEGOTIATION, 0,
+ telnet->buffer[0], telnet->buffer + 1,
+ telnet->length - 1, user_data);
telnet->length = 0;
#ifdef HAVE_ZLIB
@@ -299,7 +313,8 @@
break;
/* notify app that compression was enabled */
- telnet->cb->compress(telnet, 1, user_data);
+ _event(telnet, LIBTELNET_EV_COMPRESS, 1, 0, 0, 0,
+ user_data);
/* any remaining bytes in the buffer are compressed.
* we have to re-invoke libtelnet_push to get those
@@ -340,7 +355,8 @@
/* pass through any remaining bytes */
if (telnet->state == LIBTELNET_STATE_DATA && i != start)
- telnet->cb->data(telnet, &buffer[start], i - start, user_data);
+ _event(telnet, LIBTELNET_EV_DATA, 0, 0, buffer + start, i - start,
+ user_data);
}
/* push a bytes into the state tracker */
@@ -378,7 +394,7 @@
/* on error (or on end of stream) disable further inflation */
if (rs != Z_OK) {
- telnet->cb->compress(telnet, 0, user_data);
+ _event(telnet, LIBTELNET_EV_COMPRESS, 0, 0, 0, 0, user_data);
inflateEnd(telnet->z_inflate);
free(telnet->z_inflate);
@@ -418,8 +434,9 @@
break;
}
- telnet->cb->send(telnet, deflate_buffer, sizeof(deflate_buffer) -
- telnet->z_deflate->avail_out, user_data);
+ _event(telnet, LIBTELNET_EV_SEND, 0, 0, deflate_buffer,
+ sizeof(deflate_buffer) - telnet->z_deflate->avail_out,
+ user_data);
/* prepare output buffer for next run */
telnet->z_deflate->next_out = deflate_buffer;
@@ -429,7 +446,7 @@
/* COMPRESS2 is not negotiated, just send */
} else
#endif /* HAVE_ZLIB */
- telnet->cb->send(telnet, buffer, size, user_data);
+ _event(telnet, LIBTELNET_EV_SEND, 0, 0, buffer, size, user_data);
}
/* send an iac command */
@@ -489,7 +506,7 @@
return;
/* notify app that compression was enabled */
- telnet->cb->compress(telnet, 1, user_data);
+ _event(telnet, LIBTELNET_EV_COMPRESS, 1, 0, 0, 0, user_data);
}
#endif /* HAVE_ZLIB */
}