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