shorten the output function names to something more reasonable

This commit is contained in:
Sean Middleditch 2009-03-20 23:08:55 -04:00
parent 9b07e92022
commit 4f0c37fc1b
6 changed files with 63 additions and 64 deletions

52
README
View File

@ -18,11 +18,14 @@ code under copyright law.
*** TODO ***
- automatic MCCP2 handling (controllable by host app)
- the negotiate callback behavior needs to be redone so that the
app immediately confirms; right now if you set ev->accept=1 when
receiving a request to enable you can't immediately start sending
ubnegotiations because the confirmation hasn't been sent yet. :/
? ZMP parsing
? MSSP parsing
? TTYPE parsing
? ENVIRON/NEW-ENVIRON parsing
? telnet-status testing tool
I. INTRODUCTION
=====================================================================
@ -43,7 +46,7 @@ II. LIBTELNET API
The libtelnet API contains several distinct parts. The first part is
the basic initialization and deinitialization routines. The second
part is a single function for pushing received data into the telnet
processor. The third part is the telnet_send_*() functions, which
processor. The third part is the libtelnet output functions, which
generate TELNET commands and ensure data is properly formatted before
sending over the wire. The final part is the event handler
interface.
@ -86,7 +89,7 @@ IIa. Initialization
IIb. Receiving Data
void telnet_push(telnet_t *telnet,
void telnet_recv(telnet_t *telnet,
const char *buffer, unsigned int size, void *user_data);
When your application receives data over the socket from the
remote end, it must pass the received bytes into this function.
@ -99,8 +102,7 @@ IIb. Receiving Data
IIc. Sending Data
All of the telnet_send_*() functions will invoke the TELNET_EV_SEND
event.
All of the output functions will invoke the TELNET_EV_SEND event.
Note: it is very important that ALL data sent to the remote end of
the connection be passed through libtelnet. All user input or
@ -108,11 +110,11 @@ IIc. Sending Data
to one of the following functions. Do NOT send or buffer
unprocessed output data directly!
void telnet_send_command(telnet_t *telnet, unsigned char cmd);
void telnet_iac(telnet_t *telnet, unsigned char cmd);
Sends a single "simple" TELNET command, such as the GO-AHEAD
commands (255 249).
void telnet_send_negotiate(telnet_t *telnet, unsigned char cmd,
void telnet_negotiate(telnet_t *telnet, unsigned char cmd,
unsigned char opt);
Sends a TELNET negotiation command. The cmd parameter must be one
of TELNET_WILL, TELNET_DONT, TELNET_DO, or TELNET_DONT. The opt
@ -123,8 +125,7 @@ IIc. Sending Data
invocations, such as asking for WILL NAWS when NAWS is already on
or is currently awaiting response from the remote end.
void telnet_send_data(telnet_t *telnet, const char *buffer,
unsigned int size);
void telnet_send(telnet_t *telnet, const char *buffer, size_t size);
Sends raw data, which would be either the process output from a
server or the user input from a client.
@ -148,22 +149,22 @@ IIc. Sending Data
telnet_begin_subnegotiation() and any negotiation data has been
sent.
void telnet_send_subnegotiation(telnet_t *telnet,
unsigned char telopt, const char *buffer, unsigned int size);
void telnet_subnegotiation(telnet_t *telnet, unsigned char telopt,
const char *buffer, unsigned int size);
Sends a TELNET sub-negotiation command. The telopt parameter is
the sub-negotiation option.
Note that this function is just a shorthand for:
telnet_begin_subnegotiation(telnet, telopt);
telnet_send_data(telnet, buffer, size);
telnet_end_subnegotiation(telnet);
telnet_begin_sb(telnet, telopt);
telnet_send(telnet, buffer, size);
telnet_end_sb(telnet);
For some subnegotiations that involve a lot of complex formatted
data to be sent, it may be easier to make calls to both
telnet_begin_negotiation() and telnet_end_subnegotiation() and
using telnet_send_data() or telnet_printf2() to format the data.
telnet_begin_sb() and telnet_finish_sb() and using telnet_send()
or telnet_printf2() to format the data.
NOTE: telnet_send_subnegotiation() does have special behavior in
NOTE: telnet_subnegotiation() does have special behavior in
PROXY mode, as in that mode this function will automatically
detect the COMPRESS2 marker and enable zlib compression.
@ -414,20 +415,19 @@ the TELNET protocol, not least of which is the need to escape any
byte value 0xFF with a special TELNET command.
For these reasons, it is very important that applications making use
of libtelnet always make use of the telnet_send_*() family of
functions for all data being sent over the TELNET connection.
of libtelnet always make use of the libtelnet output functions for
all data being sent over the TELNET connection.
In particular, if you are writing a client, all user input must be
passed through to telnet_send_data(). This also includes any input
passed through to telnet_send(). This also includes any input
generated automatically by scripts, triggers, or macros.
For a server, any and all output -- including ANSI/VT100 escape
codes, regular text, newlines, and so on -- must be passed through to
telnet_send_data().
telnet_send().
Any TELNET commands that are to be sent must be given to one of the
following: telnet_send_command, telnet_send_negotiate, or
telnet_send_subnegotiation().
following: telnet_iac, telnet_negotiate, or telnet_subnegotiation().
If you are attempting to enable COMPRESS2/MCCP2, you must use the
telnet_begin_compress2() function.
@ -447,9 +447,9 @@ zlib shared library.
libtelnet transparently supports MCCP2. For a server to support
MCCP2, the application must begin negotiation of the COMPRESS2 option
using telnet_send_negotiate(), for example:
using telnet_negotiate(), for example:
telnet_send_negotiate(&telnet, TELNET_WILL,
telnet_negotiate(&telnet, TELNET_WILL,
TELNET_OPTION_COMPRESS2, user_data);
If a favorable DO COMPRESS2 is sent back from the client then the

View File

@ -591,12 +591,12 @@ static void _process(telnet_t *telnet, const char *buffer,
_event(telnet, TELNET_EV_COMPRESS, 1, 0, 0, 0);
/* any remaining bytes in the buffer are compressed.
* we have to re-invoke telnet_push to get those
* we have to re-invoke telnet_recv to get those
* bytes inflated and abort trying to process the
* remaining compressed bytes in the current _process
* buffer argument
*/
telnet_push(telnet, &buffer[start], size - start);
telnet_recv(telnet, &buffer[start], size - start);
return;
}
#endif /* HAVE_ZLIB */
@ -632,7 +632,7 @@ static void _process(telnet_t *telnet, const char *buffer,
}
/* push a bytes into the state tracker */
void telnet_push(telnet_t *telnet, const char *buffer,
void telnet_recv(telnet_t *telnet, const char *buffer,
size_t size) {
#ifdef HAVE_ZLIB
/* if we have an inflate (decompression) zlib stream, use it */
@ -683,13 +683,13 @@ void telnet_push(telnet_t *telnet, const char *buffer,
}
/* send an iac command */
void telnet_send_command(telnet_t *telnet, unsigned char cmd) {
void telnet_iac(telnet_t *telnet, unsigned char cmd) {
char bytes[2] = { TELNET_IAC, cmd };
_send(telnet, bytes, 2);
}
/* send negotiation */
void telnet_send_negotiate(telnet_t *telnet, unsigned char cmd,
void telnet_negotiate(telnet_t *telnet, unsigned char cmd,
unsigned char telopt) {
telnet_rfc1143_t q;
@ -783,7 +783,7 @@ void telnet_send_negotiate(telnet_t *telnet, unsigned char cmd,
}
/* send non-command data (escapes IAC bytes) */
void telnet_send_data(telnet_t *telnet, const char *buffer,
void telnet_send(telnet_t *telnet, const char *buffer,
size_t size) {
size_t i, l;
@ -796,7 +796,7 @@ void telnet_send_data(telnet_t *telnet, const char *buffer,
l = i + 1;
/* send escape */
telnet_send_command(telnet, TELNET_IAC);
telnet_iac(telnet, TELNET_IAC);
}
}
@ -813,13 +813,13 @@ void telnet_begin_subnegotiation(telnet_t *telnet, unsigned char telopt) {
/* send complete subnegotiation */
void telnet_send_subnegotiation(telnet_t *telnet, unsigned char telopt,
void telnet_subnegotiation(telnet_t *telnet, unsigned char telopt,
const char *buffer, size_t size) {
const char sb[3] = { TELNET_IAC, TELNET_SB, telopt };
static const char se[2] = { TELNET_IAC, TELNET_SE };
_send(telnet, sb, 3);
telnet_send_data(telnet, buffer, size);
telnet_send(telnet, buffer, size);
_send(telnet, se, 2);
#ifdef HAVE_ZLIB
@ -883,7 +883,7 @@ int telnet_printf(telnet_t *telnet, const char *fmt, ...) {
/* IAC -> IAC IAC */
if (buffer[i] == TELNET_IAC)
telnet_send_command(telnet, TELNET_IAC);
telnet_iac(telnet, TELNET_IAC);
/* automatic translation of \r -> CRNUL */
else if (buffer[i] == '\r')
_send(telnet, CRNUL, 2);
@ -912,7 +912,7 @@ int telnet_printf2(telnet_t *telnet, const char *fmt, ...) {
va_end(va);
/* send */
telnet_send_data(telnet, (char *)buffer, rs);
telnet_send(telnet, (char *)buffer, rs);
return rs;
}

View File

@ -186,38 +186,37 @@ extern void telnet_init(telnet_t *telnet, telnet_event_handler_t eh,
extern void telnet_free(telnet_t *telnet);
/* push a byte buffer into the state tracker */
extern void telnet_push(telnet_t *telnet, const char *buffer,
extern void telnet_recv(telnet_t *telnet, const char *buffer,
size_t size);
/* send an iac command */
extern void telnet_send_command(telnet_t *telnet, unsigned char cmd);
extern void telnet_iac(telnet_t *telnet, unsigned char cmd);
/* send negotiation, with RFC1143 checking.
* will not actually send unless necessary, but will update internal
* negotiation queue.
*/
extern void telnet_send_negotiate(telnet_t *telnet, unsigned char cmd,
extern void telnet_negotiate(telnet_t *telnet, unsigned char cmd,
unsigned char opt);
/* send non-command data (escapes IAC bytes) */
extern void telnet_send_data(telnet_t *telnet,
extern void telnet_send(telnet_t *telnet,
const char *buffer, size_t size);
/* send IAC SB followed by the telopt code */
extern void telnet_begin_subnegotiation(telnet_t *telnet,
extern void telnet_begin_sb(telnet_t *telnet,
unsigned char telopt);
/* send IAC SE */
#define telnet_finish_subnegotiation(telnet) \
telnet_send_command((telnet), TELNET_SE)
#define telnet_finish_sb(telnet) telnet_iac((telnet), TELNET_SE)
/* shortcut for sending a complete subnegotiation buffer.
* equivalent to:
* telnet_begin_subnegotiation(telnet, telopt);
* telnet_send_data(telnet, buffer, size);
* telnet_finish_subnegotiation(telnet);
* telnet_begin_sb(telnet, telopt);
* telnet_send(telnet, buffer, size);
* telnet_finish_sb(telnet);
*/
extern void telnet_send_subnegotiation(telnet_t *telnet, unsigned char telopt,
extern void telnet_subnegotiation(telnet_t *telnet, unsigned char telopt,
const char *buffer, size_t size);
/* begin sending compressed data (server only) */

View File

@ -292,7 +292,7 @@ int main(int argc, char **argv) {
/* init, welcome */
users[i].sock = rs;
telnet_init(&users[i].telnet, _event_handler, 0, &users[i]);
telnet_send_negotiate(&users[i].telnet, TELNET_WILL,
telnet_negotiate(&users[i].telnet, TELNET_WILL,
TELNET_TELOPT_COMPRESS2);
telnet_printf(&users[i].telnet, "Enter name: ");
}
@ -305,7 +305,7 @@ int main(int argc, char **argv) {
if (pfd[i].revents & POLLIN) {
if ((rs = recv(users[i].sock, buffer, sizeof(buffer), 0)) > 0) {
telnet_push(&users[i].telnet, buffer, rs);
telnet_recv(&users[i].telnet, buffer, rs);
} else if (rs == 0) {
printf("Connection closed.\n");
close(users[i].sock);

View File

@ -48,11 +48,11 @@ static void _input(char *buffer, int size) {
if (buffer[i] == '\r' || buffer[i] == '\n') {
if (do_echo)
write(STDOUT_FILENO, crlf, 2);
telnet_send_data(&telnet, crlf, 2);
telnet_send(&telnet, crlf, 2);
} else {
if (do_echo)
write(STDOUT_FILENO, buffer + i, 1);
telnet_send_data(&telnet, buffer + i, 1);
telnet_send(&telnet, buffer + i, 1);
}
}
}
@ -126,8 +126,8 @@ static void _event_handler(telnet_t *telnet, telnet_event_t *ev,
char buffer[64];
buffer[0] = 0; /* IS code for RFC 1091 */
snprintf(buffer + 1, sizeof(buffer) - 1, "%s", getenv("TERM"));
telnet_send_subnegotiation(telnet, TELNET_TELOPT_TTYPE,
(char *)buffer, 1 + strlen(buffer + 1));
telnet_subnegotiation(telnet, TELNET_TELOPT_TTYPE, buffer,
1 + strlen(buffer + 1));
}
break;
/* error */
@ -229,7 +229,7 @@ int main(int argc, char **argv) {
/* read from client */
if (pfd[1].revents & POLLIN) {
if ((rs = recv(sock, buffer, sizeof(buffer), 0)) > 0) {
telnet_push(&telnet, buffer, rs);
telnet_recv(&telnet, buffer, rs);
} else if (rs == 0) {
break;
} else {

View File

@ -176,7 +176,7 @@ static void _event_handler(telnet_t *telnet, telnet_event_t *ev,
print_buffer(ev->buffer, ev->size);
printf(COLOR_NORMAL "\n");
telnet_send_data(&conn->remote->telnet, ev->buffer, ev->size);
telnet_send(&conn->remote->telnet, ev->buffer, ev->size);
break;
/* data must be sent */
case TELNET_EV_SEND:
@ -193,33 +193,33 @@ static void _event_handler(telnet_t *telnet, telnet_event_t *ev,
printf("%s IAC %s" COLOR_NORMAL "\n", conn->name,
get_cmd(ev->command));
telnet_send_command(&conn->remote->telnet, ev->command);
telnet_iac(&conn->remote->telnet, ev->command);
break;
/* negotiation, WILL */
case TELNET_EV_WILL:
printf("%s IAC WILL %d (%s)" COLOR_NORMAL "\n", conn->name,
(int)ev->telopt, get_opt(ev->telopt));
telnet_send_negotiate(&conn->remote->telnet, TELNET_WILL,
telnet_negotiate(&conn->remote->telnet, TELNET_WILL,
ev->telopt);
break;
/* negotiation, WONT */
case TELNET_EV_WONT:
printf("%s IAC WONT %d (%s)" COLOR_NORMAL "\n", conn->name,
(int)ev->telopt, get_opt(ev->telopt));
telnet_send_negotiate(&conn->remote->telnet, TELNET_WONT,
telnet_negotiate(&conn->remote->telnet, TELNET_WONT,
ev->telopt);
break;
/* negotiation, DO */
case TELNET_EV_DO:
printf("%s IAC DO %d (%s)" COLOR_NORMAL "\n", conn->name,
(int)ev->telopt, get_opt(ev->telopt));
telnet_send_negotiate(&conn->remote->telnet, TELNET_DO,
telnet_negotiate(&conn->remote->telnet, TELNET_DO,
ev->telopt);
break;
case TELNET_EV_DONT:
printf("%s IAC DONT %d (%s)" COLOR_NORMAL "\n", conn->name,
(int)ev->telopt, get_opt(ev->telopt));
telnet_send_negotiate(&conn->remote->telnet, TELNET_DONT,
telnet_negotiate(&conn->remote->telnet, TELNET_DONT,
ev->telopt);
break;
/* subnegotiation */
@ -232,7 +232,7 @@ static void _event_handler(telnet_t *telnet, telnet_event_t *ev,
}
printf(COLOR_NORMAL "\n");
telnet_send_subnegotiation(&conn->remote->telnet, ev->telopt,
telnet_subnegotiation(&conn->remote->telnet, ev->telopt,
ev->buffer, ev->size);
break;
/* compression notification */
@ -374,7 +374,7 @@ int main(int argc, char **argv) {
/* read from server */
if (pfd[0].revents & POLLIN) {
if ((rs = recv(server.sock, buffer, sizeof(buffer), 0)) > 0) {
telnet_push(&server.telnet, buffer, rs);
telnet_recv(&server.telnet, buffer, rs);
} else if (rs == 0) {
printf("%s DISCONNECTED" COLOR_NORMAL "\n", server.name);
break;
@ -390,7 +390,7 @@ int main(int argc, char **argv) {
/* read from client */
if (pfd[1].revents & POLLIN) {
if ((rs = recv(client.sock, buffer, sizeof(buffer), 0)) > 0) {
telnet_push(&client.telnet, buffer, rs);
telnet_recv(&client.telnet, buffer, rs);
} else if (rs == 0) {
printf("%s DISCONNECTED" COLOR_NORMAL "\n", client.name);
break;