added telnet_send_sb

This commit is contained in:
Sean Middleditch 2009-03-22 23:04:28 -04:00
parent 8c11179961
commit eb950a89f0
4 changed files with 75 additions and 10 deletions

41
README
View File

@ -218,6 +218,47 @@ IIc. Sending Data
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

View File

@ -1058,6 +1058,31 @@ int telnet_printf2(telnet_t *telnet, const char *fmt, ...) {
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;

View File

@ -266,6 +266,10 @@ extern int telnet_printf(telnet_t *telnet, const char *fmt, ...)
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;

View File

@ -116,17 +116,12 @@ static void _event_handler(telnet_t *telnet, telnet_event_t *ev,
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 */