added telnet_send_sb
diff --git a/README b/README
index 6cc058f..3257b9a 100644
--- a/README
+++ b/README
@@ -218,6 +218,47 @@
translated. This should be used if you are attempting to send
raw data inside a subnegotiation or if you have already manually
escaped newlines.
+
+ void telnet_format_sb(telnet_t *telnet, unsigned char telopt,
+ size_t count, ...);
+ This is a helper function for sending the specially formatted
+ data used in the TTYPE, ENVIRON/NEW-ENVIRON, and MSSP telopt
+ subnegotiations.
+
+ The variadic arguments must be given as a series of pairs of
+ markers and strings. The markers are different for each telopt;
+ they are defined in libtelnet.h and include:
+
+ /* TTYPE markers */
+ #define TELNET_TTYPE_IS 0
+ #define TELNET_TTYPE_SEND 1
+
+ /* ENVIRON/NEW-ENVIRON markers */
+ #define TELNET_ENVIRON_IS 0
+ #define TELNET_ENVIRON_SEND 1
+ #define TELNET_ENVIRON_INFO 2
+ #define TELNET_ENVIRON_VAR 0
+ #define TELNET_ENVIRON_VALUE 1
+ #define TELNET_ENVIRON_ESC 2
+ #define TELNET_ENVIRON_USERVAR 3
+
+ /* MSSP markers */
+ #define TELNET_MSSP_VAR 1
+ #define TELNET_MSSP_VAL 2
+
+ So to send a TTYPE subnegotiation from the server (just an IS
+ command), you would use:
+
+ telnet_format_sb(&telnet, TELNET_TELOPT_TTYPE, 1,
+ TELNET_TTYPE_SEND);
+
+ The client response for an xterm-compatible terminal would be:
+
+ telnet_format_sb(&telnet, TELNET_TELOPT_TTYPE, 1,
+ TELNET_TTYPE_IS, "xterm");
+
+ For more information on the meaning of the markers and strings,
+ please refer to the specific RFC for the telopt in question.
IId. Event Handling
diff --git a/libtelnet.c b/libtelnet.c
index 09ffd8d..695d213 100644
--- a/libtelnet.c
+++ b/libtelnet.c
@@ -1058,6 +1058,31 @@
return rs;
}
+/* send formatted subnegotiation data for TTYPE/ENVIRON/NEW-ENVIRON/MSSP */
+void telnet_format_sb(telnet_t *telnet, unsigned char telopt,
+ size_t count, ...) {
+ va_list va;
+ size_t i;
+
+ /* subnegotiation header */
+ telnet_begin_sb(telnet, telopt);
+
+ /* iterate over the arguments pulling out integers and strings */
+ va_start(va, count);
+ for (i = 0; i != count; ++i) {
+ char t;
+ const char* s;
+ t = va_arg(va, int);
+ s = va_arg(va, const char *);
+ telnet_send(telnet, &t, 1);
+ telnet_send(telnet, s, strlen(s));
+ }
+ va_end(va);
+
+ /* footer */
+ telnet_finish_sb(telnet);
+}
+
/* send ZMP data */
void telnet_send_zmp(telnet_t *telnet, size_t argc, const char **argv) {
size_t i;
diff --git a/libtelnet.h b/libtelnet.h
index 6a26fdb..52e2e18 100644
--- a/libtelnet.h
+++ b/libtelnet.h
@@ -266,6 +266,10 @@
extern int telnet_printf2(telnet_t *telnet, const char *fmt, ...)
TELNET_GNU_PRINTF(2, 3);
+/* send TTYPE/ENVIRON/NEW-ENVIRON/MSSP data */
+extern void telnet_format_sb(telnet_t *telnet, unsigned char telopt,
+ size_t count, ...);
+
/* send ZMP commands */
extern void telnet_send_zmp(telnet_t *telnet, size_t argc, const char **argv);
extern void telnet_send_zmpv(telnet_t *telnet, ...) TELNET_GNU_SENTINEL;
diff --git a/telnet-client.c b/telnet-client.c
index aa25e4a..9eb58d6 100644
--- a/telnet-client.c
+++ b/telnet-client.c
@@ -116,17 +116,12 @@
break;
/* respond to particular subnegotiations */
case TELNET_EV_SUBNEGOTIATION:
+ /* if they just asked for our terminal type, response with it */
/* respond with our terminal type */
- if (ev->telopt == TELNET_TELOPT_TTYPE) {
- /* NOTE: we just assume the server sent a legitimate
- * sub-negotiation, as there really isn't anything else
- * it's allowed to send
- */
- char buffer[64];
- buffer[0] = 0; /* IS code for RFC 1091 */
- snprintf(buffer + 1, sizeof(buffer) - 1, "%s", getenv("TERM"));
- telnet_subnegotiation(telnet, TELNET_TELOPT_TTYPE, buffer,
- strlen(getenv("TERM")) + 1);
+ if (ev->telopt == TELNET_TELOPT_TTYPE &&
+ ev->argc >= 1 && ev->argv[0][0] == TELNET_TTYPE_SEND) {
+ telnet_format_sb(telnet, TELNET_TELOPT_TTYPE, 1,
+ TELNET_TTYPE_IS, getenv("TERM"));
}
break;
/* error */