clean up and document the telopt table stuff

This commit is contained in:
Sean Middleditch 2009-03-22 16:26:06 -04:00
parent 0092336886
commit bfc641efb1
5 changed files with 71 additions and 17 deletions

55
README
View File

@ -53,19 +53,60 @@ interface.
IIa. Initialization
struct telnet_t;
This structure represents the state of the TELNET protocol for a
single connection. Each connection utilizing TELNET must have its
own telnet_t structure, which is passed to all libtelnet API
calls.
Using libtelnet requires the initialization of a telnet_t structure
which stores all current state for a single TELNET connection.
void telnet_init(telnet_t *telnet, telnet_event_handler_t handler,
unsigned char flags, void *user_data);
Initializing a telnet_t structure requires several pieces of data.
One of these is the telopt support table, which specifies which
TELNET options your application supports both locally and remotely.
This table is comprised of telnet_telopt_t structures, one for each
supported option. Each entry specifies the option supported,
whether the option is supported locally or remotely.
struct telnet_telopt_t {
short telopt;
unsigned char us;
unsigned char him;
};
The us field denotes whether your application supporst the telopt
locally. It should be set to TELNET_WILL if you support it and to
TELNET_WONT if you don't. The him field denotes whether the telopt
is supported on the remote end, and should be TELNET_DO if yes and
TELNET_DONT if not.
When definition the telopt table you must include an end marker
entry, which is simply an entry with telopt set to -1. For
example:
static const telnet_telopt_t my_telopts[] = {
{ TELNET_TELOPT_ECHO, TELNET_WILL, TELNET_DONT },
{ TELNET_TELOPT_TTYPE, TELNET_WILL, TELNET_DONT },
{ TELNET_TELOPT_COMPRESS2, TELNET_WONT, TELNET_DO },
{ TELNET_TELOPT_ZMP, TELNET_WONT, TELNET_DO },
{ TELNET_TELOPT_MSSP, TELNET_WONT, TELNET_DO },
{ TELNET_TELOPT_BINARY, TELNET_WILL, TELNET_DO },
{ TELNET_TELOPT_NAWS, TELNET_WILL, TELNET_DONT },
{ -1, 0, 0 }
};
If you need to dynamically alter supported options on a
per-connection basis then you may use a different tables
(dynamically allocated if necessary) per call to telnet_init() or
you share a single constant table like the above example between
all connections if you support a fixed set of options. Most
applications will support only a fixed set of options.
void telnet_init(telnet_t *telnet, const telnet_telopts_t *telopts,
telnet_event_handler_t handler, unsigned char flags,
void *user_data);
The telnet_init() function is responsible for initializing the
data in a telnet_t structure. It must be called immediately after
establishing a connection and before any other libtelnet API calls
are made.
The telopts field is the telopt support table as described above.
The handler parameter must be a function matching the
telnet_event_handler_t definition. More information about events
can be found in section IId.

View File

@ -188,9 +188,16 @@ static INLINE int _check_telopt(telnet_t *telnet, unsigned char telopt,
return 0;
/* loop unti found or end marker (us and him both 0) */
for (i = 0; telnet->telopts[i].telopt != -1; ++i)
if (telnet->telopts[i].telopt == telopt)
return us ? telnet->telopts[i].us : telnet->telopts[i].him;
for (i = 0; telnet->telopts[i].telopt != -1; ++i) {
if (telnet->telopts[i].telopt == telopt) {
if (us && telnet->telopts[i].us == TELNET_WILL)
return 1;
else if (!us && telnet->telopts[i].him == TELNET_DO)
return 1;
else
return 0;
}
}
/* not found, so not supported */
return 0;

View File

@ -24,7 +24,6 @@ typedef struct telnet_telopt_t telnet_telopt_t;
#define TELNET_WONT 252
#define TELNET_WILL 251
#define TELNET_SB 250
#define TELNET_SB 250
#define TELNET_GA 249
#define TELNET_EL 248
#define TELNET_EC 247
@ -153,8 +152,9 @@ typedef void (*telnet_event_handler_t)(telnet_t *telnet,
/* telopt support table element; use telopt of -1 for end marker */
struct telnet_telopt_t {
short telopt;
short us:1, him:1;
short telopt; /* one of the TELOPT codes or -1 */
unsigned char us; /* TELNET_WILL or TELNET_WONT */
unsigned char him; /* TELNET_DO or TELNET_DONT */
};
/* state tracker */

View File

@ -29,6 +29,11 @@
#define MAX_USERS 64
#define LINEBUFFER_SIZE 256
const telnet_telopt_t telopts[] = {
{ TELNET_TELOPT_COMPRESS2, TELNET_WILL, TELNET_DONT },
{ -1, 0, 0 }
};
struct user_t {
char *name;
int sock;
@ -291,7 +296,8 @@ int main(int argc, char **argv) {
/* init, welcome */
users[i].sock = rs;
telnet_init(&users[i].telnet, 0, _event_handler, 0, &users[i]);
telnet_init(&users[i].telnet, telopts, _event_handler, 0,
&users[i]);
telnet_negotiate(&users[i].telnet, TELNET_WILL,
TELNET_TELOPT_COMPRESS2);
telnet_printf(&users[i].telnet, "Enter name: ");

View File

@ -33,9 +33,9 @@ static telnet_t telnet;
static int do_echo;
static const telnet_telopt_t telopts[] = {
{ TELNET_TELOPT_ECHO, 0, 1 },
{ TELNET_TELOPT_COMPRESS2, 0, 1 },
{ TELNET_TELOPT_TTYPE, 1, 0 },
{ TELNET_TELOPT_ECHO, TELNET_WONT, TELNET_DO },
{ TELNET_TELOPT_COMPRESS2, TELNET_WONT, TELNET_DO },
{ TELNET_TELOPT_TTYPE, TELNET_WILL, TELNET_DONT },
{ -1, 0, 0 }
};