mirror of https://gerrit.osmocom.org/libtelnet
clean up and document the telopt table stuff
parent
0092336886
commit
bfc641efb1
55
README
55
README
|
@ -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.
|
||||
|
|
13
libtelnet.c
13
libtelnet.c
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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: ");
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue