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 IIa. Initialization
struct telnet_t; Using libtelnet requires the initialization of a telnet_t structure
This structure represents the state of the TELNET protocol for a which stores all current state for a single TELNET connection.
single connection. Each connection utilizing TELNET must have its
own telnet_t structure, which is passed to all libtelnet API
calls.
void telnet_init(telnet_t *telnet, telnet_event_handler_t handler, Initializing a telnet_t structure requires several pieces of data.
unsigned char flags, void *user_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 The telnet_init() function is responsible for initializing the
data in a telnet_t structure. It must be called immediately after data in a telnet_t structure. It must be called immediately after
establishing a connection and before any other libtelnet API calls establishing a connection and before any other libtelnet API calls
are made. are made.
The telopts field is the telopt support table as described above.
The handler parameter must be a function matching the The handler parameter must be a function matching the
telnet_event_handler_t definition. More information about events telnet_event_handler_t definition. More information about events
can be found in section IId. 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; return 0;
/* loop unti found or end marker (us and him both 0) */ /* loop unti found or end marker (us and him both 0) */
for (i = 0; telnet->telopts[i].telopt != -1; ++i) for (i = 0; telnet->telopts[i].telopt != -1; ++i) {
if (telnet->telopts[i].telopt == telopt) if (telnet->telopts[i].telopt == telopt) {
return us ? telnet->telopts[i].us : telnet->telopts[i].him; 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 */ /* not found, so not supported */
return 0; return 0;

View File

@ -24,7 +24,6 @@ typedef struct telnet_telopt_t telnet_telopt_t;
#define TELNET_WONT 252 #define TELNET_WONT 252
#define TELNET_WILL 251 #define TELNET_WILL 251
#define TELNET_SB 250 #define TELNET_SB 250
#define TELNET_SB 250
#define TELNET_GA 249 #define TELNET_GA 249
#define TELNET_EL 248 #define TELNET_EL 248
#define TELNET_EC 247 #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 */ /* telopt support table element; use telopt of -1 for end marker */
struct telnet_telopt_t { struct telnet_telopt_t {
short telopt; short telopt; /* one of the TELOPT codes or -1 */
short us:1, him:1; unsigned char us; /* TELNET_WILL or TELNET_WONT */
unsigned char him; /* TELNET_DO or TELNET_DONT */
}; };
/* state tracker */ /* state tracker */

View File

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

View File

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