minor cleanup, added libtelnet_send_telopt()
diff --git a/README b/README
index bcb55c8..dc332a3 100644
--- a/README
+++ b/README
@@ -110,6 +110,11 @@
Sends a single "simple" TELNET command, such as the GO-AHEAD
commands (255 249).
+ void libtelnet_send_command(libtelnet_t *telnet, unsigned char cmd,
+ unsigned char telopt);
+ Sends a TELNET command with an option code following. This is
+ only useful for the WILL, WONT, DO, DONT, and SB commands.
+
void libtelnet_send_negotiate(libtelnet_t *telnet,
unsigned char cmd, unsigned char opt);
Sends a TELNET negotiation command. The cmd parameter must be
@@ -123,10 +128,23 @@
a server or the user input from a client.
void libtelnet_send_subnegotiation(libtelnet_t *telnet,
- unsigned char opt, unsigned char *buffer, unsigned int size);
- Sends a TELNET sub-negotiation command. The opt parameter
+ unsigned char telopt, unsigned char *buffer, unsigned int size);
+ Sends a TELNET sub-negotiation command. The telopt parameter
is the sub-negotiation option.
+ Note that the above function is just a shorthand for:
+ libtelnet_send_telopt(telnet, LIBTELNET_SB, telopt);
+ libtelnet_send_data(telnet, buffer, size);
+ libtelnet_send_command(telnet, LIBTELNET_SE);
+
+ For some subnegotiations that involve a lot of complex formatted
+ data to be sent, it may be easier to manually send the SB telopt
+ header and SE footer around mulitple calls to send_data.
+
+ NOTE: libtelnet_send_subrequest() does have special behavior in
+ PROXY mode, as in that mode this function will automatically
+ detect the COMPRESS2 marker and enable zlib compression.
+
IId. Event Handling
libtelnet relies on an event-handling mechanism for processing
diff --git a/libtelnet.c b/libtelnet.c
index 5bf5295..cf786a9 100644
--- a/libtelnet.c
+++ b/libtelnet.c
@@ -206,13 +206,6 @@
telnet->q[telnet->q_size++] = q;
}
-/* send a negotiation without going through the RFC1143 checks */
-static void _send_negotiate(libtelnet_t *telnet, unsigned char cmd,
- unsigned char opt) {
- unsigned char bytes[3] = { LIBTELNET_IAC, cmd, opt };
- _send(telnet, bytes, 3);
-}
-
/* negotiation handling magic for RFC1143 */
static void _negotiate(libtelnet_t *telnet, unsigned char cmd,
unsigned char telopt) {
@@ -249,9 +242,9 @@
if (_event(telnet, LIBTELNET_EV_WILL, cmd, telopt, 0, 0) == 1) {
q.him = RFC1143_YES;
_set_rfc1143(telnet, q);
- _send_negotiate(telnet, LIBTELNET_DO, telopt);
+ libtelnet_send_telopt(telnet, LIBTELNET_DO, telopt);
} else
- _send_negotiate(telnet, LIBTELNET_DONT, telopt);
+ libtelnet_send_telopt(telnet, LIBTELNET_DONT, telopt);
break;
case RFC1143_YES:
break;
@@ -274,7 +267,7 @@
case RFC1143_WANTYES_OP:
q.him = RFC1143_WANTNO;
_set_rfc1143(telnet, q);
- _send_negotiate(telnet, LIBTELNET_DONT, telopt);
+ libtelnet_send_telopt(telnet, LIBTELNET_DONT, telopt);
break;
}
break;
@@ -287,7 +280,7 @@
case RFC1143_YES:
q.him = RFC1143_NO;
_set_rfc1143(telnet, q);
- _send_negotiate(telnet, LIBTELNET_DONT, telopt);
+ libtelnet_send_telopt(telnet, LIBTELNET_DONT, telopt);
_event(telnet, LIBTELNET_EV_WONT, 0, telopt,
0, 0);
break;
@@ -318,9 +311,9 @@
if (_event(telnet, LIBTELNET_EV_DO, cmd, telopt, 0, 0) == 1) {
q.us = RFC1143_YES;
_set_rfc1143(telnet, q);
- _send_negotiate(telnet, LIBTELNET_WILL, telopt);
+ libtelnet_send_telopt(telnet, LIBTELNET_WILL, telopt);
} else
- _send_negotiate(telnet, LIBTELNET_WONT, telopt);
+ libtelnet_send_telopt(telnet, LIBTELNET_WONT, telopt);
break;
case RFC1143_YES:
break;
@@ -343,7 +336,7 @@
case RFC1143_WANTYES_OP:
q.us = RFC1143_WANTNO;
_set_rfc1143(telnet, q);
- _send_negotiate(telnet, LIBTELNET_WONT, telopt);
+ libtelnet_send_telopt(telnet, LIBTELNET_WONT, telopt);
break;
}
break;
@@ -356,7 +349,7 @@
case RFC1143_YES:
q.us = RFC1143_NO;
_set_rfc1143(telnet, q);
- _send_negotiate(telnet, LIBTELNET_WONT, telopt);
+ libtelnet_send_telopt(telnet, LIBTELNET_WONT, telopt);
_event(telnet, LIBTELNET_EV_DONT, 0, telopt, 0, 0);
break;
case RFC1143_WANTNO:
@@ -673,6 +666,13 @@
_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 };
+ _send(telnet, bytes, 3);
+}
+
/* send negotiation */
void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd,
unsigned char telopt) {
@@ -814,10 +814,9 @@
}
/* send sub-request */
-void libtelnet_send_subnegotiation(libtelnet_t *telnet, unsigned char opt,
+void libtelnet_send_subnegotiation(libtelnet_t *telnet, unsigned char telopt,
unsigned char *buffer, unsigned int size) {
- libtelnet_send_command(telnet, LIBTELNET_SB);
- libtelnet_send_data(telnet, &opt, 1);
+ libtelnet_send_telopt(telnet, LIBTELNET_SB, telopt);
libtelnet_send_data(telnet, buffer, size);
libtelnet_send_command(telnet, LIBTELNET_SE);
@@ -826,8 +825,7 @@
* make sure all further data is compressed if not already.
*/
if (telnet->flags & LIBTELNET_FLAG_PROXY &&
- telnet->z == 0 &&
- opt == LIBTELNET_TELOPT_COMPRESS2) {
+ telopt == LIBTELNET_TELOPT_COMPRESS2) {
if (_init_zlib(telnet, 1, 1) != LIBTELNET_EOK)
return;
@@ -852,5 +850,8 @@
* the compress marker itself being compressed.
*/
_event(telnet, LIBTELNET_EV_SEND, 0, 0, compress2, sizeof(compress2));
+
+ /* notify app that compression was successfully enabled */
+ _event(telnet, LIBTELNET_EV_COMPRESS, 1, 0, 0, 0);
#endif /* HAVE_ZLIB */
}
diff --git a/libtelnet.h b/libtelnet.h
index 8db4d6c..e27dc3e 100644
--- a/libtelnet.h
+++ b/libtelnet.h
@@ -200,7 +200,14 @@
/* send an iac command */
extern void libtelnet_send_command(libtelnet_t *telnet, unsigned char cmd);
-/* send negotiation */
+/* send an iac command with a telopt */
+extern void libtelnet_send_telopt(libtelnet_t *telnet, unsigned char cmd,
+ unsigned char telopt);
+
+/* send negotiation, with RFC1143 checking.
+ * will not actually send unless necessary, but will update internal
+ * negotiation queue.
+ */
extern void libtelnet_send_negotiate(libtelnet_t *telnet, unsigned char cmd,
unsigned char opt);
@@ -208,9 +215,15 @@
extern void libtelnet_send_data(libtelnet_t *telnet, unsigned char *buffer,
unsigned int size);
-/* send sub-request */
+/* send sub-request, equivalent to:
+ * libtelnet_send_telopt(telnet, LIBTELNET_SB, telopt)
+ * libtelnet_send_data(telnet, buffer, size);
+ * libtelnet_send_command(telnet, LIBTELNET_SE);
+ * manually generating sequence may be easier for complex subnegotiations
+ * thare are most easily implemented with a series of send_data calls.
+ */
extern void libtelnet_send_subnegotiation(libtelnet_t *telnet,
- unsigned char opt, unsigned char *buffer, unsigned int size);
+ unsigned char telopt, unsigned char *buffer, unsigned int size);
/* begin sending compressed data (server only) */
extern void libtelnet_begin_compress2(libtelnet_t *telnet);