libtelnet.h(3)

πŸ“¦
version 0.23 Β· 2 versions
, in epel 10, fedora 43, fedora 44

πŸ¦‹ libtelnet.h β€” NAME πŸ¦‹

okay bestie, pull up a chair πŸ’– this is libtelnet.h(3), the manual page for libtelnet β€” the TELNET protocol handling library. yes, that TELNET. vintage, iconic, still serving πŸ’…


✨ SYNOPSIS ✨

first you gotta manifest the headers, no cap:

#include <stdarg.h>
#include <stddef.h>

🌸 Data Structures

the whole little squad of structs and unions, here they are:

  • struct telnet_environ_t
  • union telnet_event_t
  • struct telnet_event_t::data_t
  • struct telnet_event_t::error_t
  • struct telnet_event_t::iac_t
  • struct telnet_event_t::negotiate_t
  • struct telnet_event_t::subnegotiate_t
  • struct telnet_event_t::zmp_t
  • struct telnet_event_t::ttype_t
  • struct telnet_event_t::compress_t
  • struct telnet_event_t::environ_t
  • struct telnet_event_t::mssp_t
  • struct telnet_telopt_t

πŸ’œ Macros

πŸŽ€ Telnet commands

the full command lineup, straight up:

#define TELNET_IAC   255
#define TELNET_DONT   254
#define TELNET_DO   253
#define TELNET_WONT   252
#define TELNET_WILL   251
#define TELNET_SB   250
#define TELNET_GA   249
#define TELNET_EL   248
#define TELNET_EC   247
#define TELNET_AYT   246
#define TELNET_AO   245
#define TELNET_IP   244
#define TELNET_BREAK   243
#define TELNET_DM   242
#define TELNET_NOP   241
#define TELNET_SE   240
#define TELNET_EOR   239
#define TELNET_ABORT   238
#define TELNET_SUSP   237
#define TELNET_EOF   236

πŸ¦‹ Telnet option values.

every single option code, zero skips, we don't do that here:

#define TELNET_TELOPT_BINARY   0
#define TELNET_TELOPT_ECHO   1
#define TELNET_TELOPT_RCP   2
#define TELNET_TELOPT_SGA   3
#define TELNET_TELOPT_NAMS   4
#define TELNET_TELOPT_STATUS   5
#define TELNET_TELOPT_TM   6
#define TELNET_TELOPT_RCTE   7
#define TELNET_TELOPT_NAOL   8
#define TELNET_TELOPT_NAOP   9
#define TELNET_TELOPT_NAOCRD   10
#define TELNET_TELOPT_NAOHTS   11
#define TELNET_TELOPT_NAOHTD   12
#define TELNET_TELOPT_NAOFFD   13
#define TELNET_TELOPT_NAOVTS   14
#define TELNET_TELOPT_NAOVTD   15
#define TELNET_TELOPT_NAOLFD   16
#define TELNET_TELOPT_XASCII   17
#define TELNET_TELOPT_LOGOUT   18
#define TELNET_TELOPT_BM   19
#define TELNET_TELOPT_DET   20
#define TELNET_TELOPT_SUPDUP   21
#define TELNET_TELOPT_SUPDUPOUTPUT   22
#define TELNET_TELOPT_SNDLOC   23
#define TELNET_TELOPT_TTYPE   24
#define TELNET_TELOPT_EOR   25
#define TELNET_TELOPT_TUID   26
#define TELNET_TELOPT_OUTMRK   27
#define TELNET_TELOPT_TTYLOC   28
#define TELNET_TELOPT_3270REGIME   29
#define TELNET_TELOPT_X3PAD   30
#define TELNET_TELOPT_NAWS   31
#define TELNET_TELOPT_TSPEED   32
#define TELNET_TELOPT_LFLOW   33
#define TELNET_TELOPT_LINEMODE   34
#define TELNET_TELOPT_XDISPLOC   35
#define TELNET_TELOPT_ENVIRON   36
#define TELNET_TELOPT_AUTHENTICATION   37
#define TELNET_TELOPT_ENCRYPT   38
#define TELNET_TELOPT_NEW_ENVIRON   39
#define TELNET_TELOPT_MSSP   70
#define TELNET_TELOPT_COMPRESS   85
#define TELNET_TELOPT_COMPRESS2   86
#define TELNET_TELOPT_ZMP   93
#define TELNET_TELOPT_EXOPL   255
#define TELNET_TELOPT_MCCP2   86
note: TELNET_TELOPT_COMPRESS2 and TELNET_TELOPT_MCCP2 are both 86. yes really. they're the same number, that's canon, don't come for me 🫢

πŸ’… Protocol codes for TERMINAL-TYPE commands.

#define TELNET_TTYPE_IS   0
#define TELNET_TTYPE_SEND   1

🌈 Protocol codes for NEW-ENVIRON/ENVIRON commands.

#define TELNET_ENVIRON_IS   0
#define TELNET_ENVIRON_SEND   1
#define TELNET_ENVIRON_INFO   2
#define TELNET_ENVIRON_VAR   0
#define TELNET_ENVIRON_VALUE   1
#define TELNET_ENVIRON_ESC   2
#define TELNET_ENVIRON_USERVAR   3

⭐ Protocol codes for MSSP commands.

#define TELNET_MSSP_VAR   1
#define TELNET_MSSP_VAL   2

πŸ‘‘ Typedefs

the little aliases, obsessed with them:

typedef struct telnet_t telnet_t
typedef union telnet_event_t telnet_event_t
typedef struct telnet_telopt_t telnet_telopt_t

🧚 Telnet state tracker flags.

these are the flags that control the behavior of the telnet state tracker:

#define TELNET_FLAG_PROXY   (1<<0)
#define TELNET_FLAG_NVT_EOL   (1<<1)
#define TELNET_FLAG_TRANSMIT_BINARY   (1<<5)
#define TELNET_FLAG_RECEIVE_BINARY   (1<<6)
#define TELNET_PFLAG_DEFLATE   (1<<7)

and these cute little macro shortcuts:

  • #define telnet_finish_sb(telnet) β€” Finish a sub-negotiation command.
  • #define telnet_finish_newenviron(telnet) β€” Finish a NEW-ENVIRON command.
  • #define telnet_finish_zmp(telnet) β€” Finish a ZMP command.

the error codes, in their exact order (don't reorder these, bestie):

enum telnet_error_t { TELNET_EOK = 0, TELNET_EBADVAL, TELNET_ENOMEM,
    TELNET_EOVERFLOW, TELNET_EPROTOCOL, TELNET_ECOMPRESS }

and the event types, also exact order:

enum telnet_event_type_t { TELNET_EV_DATA = 0, TELNET_EV_SEND,
    TELNET_EV_IAC, TELNET_EV_WILL, TELNET_EV_WONT, TELNET_EV_DO,
    TELNET_EV_DONT, TELNET_EV_SUBNEGOTIATION, TELNET_EV_COMPRESS,
    TELNET_EV_ZMP, TELNET_EV_TTYPE, TELNET_EV_ENVIRON, TELNET_EV_MSSP,
    TELNET_EV_WARNING, TELNET_EV_ERROR }

and the typedefs for those:

typedef enum telnet_error_t telnet_error_t
typedef enum telnet_event_type_t telnet_event_type_t
typedef void(* telnet_event_handler_t) (telnet_t *telnet, telnet_event_t
    *event, void *user_data)
  • the telnet_event_handler_t is your event handler πŸ’–

🌟 the functions

here's the whole function roster with their one-liners, don't skip any:

  • telnet_t * telnet_init (const telnet_telopt_t *telopts, telnet_event_handler_t eh, unsigned char flags, void *user_data) β€” Initialize a telnet state tracker.
  • void telnet_free (telnet_t *telnet) β€” Free up any memory allocated by a state tracker.
  • void telnet_recv (telnet_t *telnet, const char *buffer, size_t size) β€” Push a byte buffer into the state tracker.
  • void telnet_iac (telnet_t *telnet, unsigned char cmd) β€” Send a telnet command.
  • void telnet_negotiate (telnet_t *telnet, unsigned char cmd, unsigned char opt) β€” Send negotiation command.
  • void telnet_send (telnet_t *telnet, const char *buffer, size_t size)
  • void telnet_send_text (telnet_t *telnet, const char *buffer, size_t size)
  • void telnet_begin_sb (telnet_t *telnet, unsigned char telopt) β€” Begin a sub-negotiation command.
  • void telnet_subnegotiation (telnet_t *telnet, unsigned char telopt, const char *buffer, size_t size) β€” Shortcut for sending a complete subnegotiation buffer.
  • void telnet_begin_compress2 (telnet_t *telnet) β€” Begin sending compressed data.
  • int telnet_printf (telnet_t *telnet, const char *fmt,...) β€” TELNET_GNU_PRINTF(2 β€” Send formatted data.
  • int int telnet_vprintf (telnet_t *telnet, const char *fmt, va_list va) β€” Send formatted data.
  • int telnet_raw_printf (telnet_t *telnet, const char *fmt,...) β€” TELNET_GNU_PRINTF(2 β€” Send formatted data (no newline escaping).
  • int int telnet_raw_vprintf (telnet_t *telnet, const char *fmt, va_list va) β€” Send formatted data (no newline escaping).
  • void telnet_begin_newenviron (telnet_t *telnet, unsigned char type) β€” Begin a new set of NEW-ENVIRON values to request or send.
  • void telnet_newenviron_value (telnet_t *telnet, unsigned char type, const char *string) β€” Send a NEW-ENVIRON variable name or value.
  • void telnet_ttype_send (telnet_t *telnet) β€” Send the TERMINAL-TYPE SEND command.
  • void telnet_ttype_is (telnet_t *telnet, const char *ttype) β€” Send the TERMINAL-TYPE IS command.
  • void telnet_send_zmp (telnet_t *telnet, size_t argc, const char **argv) β€” Send a ZMP command.
  • void telnet_send_zmpv (telnet_t *telnet,...) TELNET_GNU_SENTINEL β€” Send a ZMP command.
  • void telnet_send_vzmpv (telnet_t *telnet, va_list va) β€” Send a ZMP command.
  • void telnet_begin_zmp (telnet_t *telnet, const char *cmd) β€” Begin sending a ZMP command.
  • void telnet_zmp_arg (telnet_t *telnet, const char *arg) β€” Send a ZMP command argument.

πŸ’– Detailed Description πŸ’–

libtelnet β€” TELNET protocol handling library ✨

SUMMARY:

libtelnet is a library for handling the TELNET protocol. it's got routines for parsing incoming data from a remote peer and for formatting data to send to the remote peer. both directions, she does it all πŸ’…

libtelnet uses a callback-oriented API, which lets the application handle various events in its own application-specific way. the callback system is also what buffers outgoing protocol data β€” so the application keeps control over the actual socket connection. main character energy, honestly πŸ‘‘

features supported include the full TELNET protocol, Q-method option negotiation, ZMP, MCCP2, MSSP, and NEW-ENVIRON. the range? unmatched. periodt.

CONFORMS TO:

LICENSE:

The author or authors of this code dedicate any and all copyright interest in this code to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this code under copyright law.

(public domain, bestie. she's free. she's for the people 🫢)

Version 0.23

Author Sean Middleditch sean@sourcemud.org


πŸŽ€ Macro Definition Documentation πŸŽ€

⭐ #define TELNET_ENVIRON_IS 0

NEW-ENVIRON/ENVIRON codes.

🌸 #define telnet_finish_newenviron( telnet)

Value:

telnet_finish_sb((telnet))

Finish a NEW-ENVIRON command. this one must be called after a call to telnet_begin_newenviron() to finish a NEW-ENVIRON variable list.

Parameters

  • telnet β€” Telnet state tracker object.

πŸ¦‹ #define telnet_finish_sb( telnet)

Value:

telnet_iac((telnet), TELNET_SE)

Finish a sub-negotiation command. this one must be called after a call to telnet_begin_sb() to finish a sub-negotiation command.

Parameters

  • telnet β€” Telnet state tracker object.

πŸ’œ #define telnet_finish_zmp( telnet)

Value:

telnet_finish_sb((telnet))

Finish a ZMP command. this one must be called after a call to telnet_begin_zmp() to finish a ZMP argument list.

Parameters

  • telnet β€” Telnet state tracker object.

✨ #define TELNET_FLAG_PROXY (1<<0)

Control behavior of telnet state tracker.

πŸ“ #define TELNET_GNU_PRINTF( f, a)

Value:

internal helper

πŸ’… #define TELNET_GNU_SENTINEL

internal helper

πŸ”₯ #define TELNET_IAC 255

Telnet commands and special values.

🌈 #define TELNET_MSSP_VAR 1

MSSP codes.

πŸ‘‘ #define TELNET_TELOPT_BINARY 0

Telnet options.

🧚 #define TELNET_TTYPE_IS 0

TERMINAL-TYPE codes.

✨ Typedef Documentation ✨

Bestie, these are the lil' name-tags you're gonna see all over the place, so let's get acquainted πŸ’…

🫢 telnet_error_t

typedef enum telnet_error_t telnet_error_t

It's the error code type. Like, when something goes wrong, this is the vibe of the bad news. Periodt.


πŸŽ€ telnet_event_handler_t

typedef void(* telnet_event_handler_t) (telnet_t *telnet,
                                        telnet_event_t *event,
                                        void *user_data)

event handler β€” okay so THIS is the type of function you absolutely must pass to telnet_init() when you're making a new telnet object, no cap. The function gets invoked once for every single event the libtelnet protocol parser generates. Every. One. She's attentive like that 🌸

Parameters

  • telnet β€” the telnet object that generated the event, like, the one that started it all πŸ‘‘
  • event β€” the event structure with all the deets about what actually happened
  • user_data β€” the user-supplied pointer you handed over earlier, coming back to you like a boomerang πŸ¦‹

πŸ’œ telnet_event_t

typedef union telnet_event_t telnet_event_t

The Telnet event object type. A union, so it's one of the squad at a time, iykyk.


🌈 telnet_event_type_t

typedef enum telnet_event_type_t telnet_event_type_t

The Telnet event type β€” the enum that tells you which kind of moment we're having.


πŸ’– telnet_t

typedef struct telnet_t telnet_t

The Telnet state tracker object type. She remembers everything so you don't have to. Main character energy fr fr.


πŸ¦‹ telnet_telopt_t

typedef struct telnet_telopt_t telnet_telopt_t

The Telnet option table element type β€” one lil' entry in your option table, doing her part πŸŽ€


🌟 Enumeration Type Documentation 🌟

πŸ’€ enum telnet_error_t

error codes β€” the whole roster of ways things can go sideways.

Enumerator

  • TELNET_EOK β€” no error. We ate, nothing's wrong, iconic ✨
  • TELNET_EBADVAL β€” invalid parameter, or API misuse. Bestie, that's on you πŸ™ˆ
  • TELNET_ENOMEM β€” memory allocation failure. The malloc said no 😭
  • TELNET_EOVERFLOW β€” data exceeds buffer size. Too much, too fast πŸ’€
  • TELNET_EPROTOCOL β€” invalid sequence of special bytes. The bytes are not byte-ing correctly πŸ“
  • TELNET_ECOMPRESS β€” error handling compressed streams. The zip file said "not today" 🧚

πŸ”₯ enum telnet_event_type_t

event codes β€” every event that can slide into your handler's DMs.

Enumerator

  • TELNET_EV_DATA β€” raw text data has been received πŸ“₯
  • TELNET_EV_SEND β€” data needs to be sent to the peer, so get to sending πŸ“€
  • TELNET_EV_IAC β€” generic IAC code received ⭐
  • TELNET_EV_WILL β€” WILL option negotiation received πŸ’–
  • TELNET_EV_WONT β€” WONT option neogitation received πŸ™…
  • TELNET_EV_DO β€” DO option negotiation received πŸ‘‘
  • TELNET_EV_DONT β€” DONT option negotiation received 🚫
  • TELNET_EV_SUBNEGOTIATION β€” sub-negotiation data received 🌸
  • TELNET_EV_COMPRESS β€” compression has been enabled. Squish mode activated 🫧
  • TELNET_EV_ZMP β€” ZMP command has been received 🌈
  • TELNET_EV_TTYPE β€” TTYPE command has been received πŸŽ€
  • TELNET_EV_ENVIRON β€” ENVIRON command has been received 🌿
  • TELNET_EV_MSSP β€” MSSP command has been received πŸ¦‹
  • TELNET_EV_WARNING β€” recoverable error has occured. Not great, not fatal, breathe πŸ’œ
  • TELNET_EV_ERROR β€” non-recoverable error has occured. Yeah... that one's for real πŸ’€

✨ FUNCTION DOCUMENTATION ✨

okay bestie, this is the main event. every function libtelnet hands you, in alphabetical order, nothing skipped, nothing merged. hydrate first. πŸ“


πŸ’– telnet_begin_compress2()

void telnet_begin_compress2 (telnet_t * telnet) [extern]

Starts sending compressed data. This kicks off sending data using the COMPRESS2 option, which turns on zlib compression for everything headed to the client. Two prerequisites though, no skipping: the client has to offer COMPRESS2 support via option negotiation, and zlib support has to be compiled into libtelnet. πŸ’…

Only the server may call this command. like... the server. not the client. know your role bestie πŸ‘‘

Parameters

  • telnet β€” Telnet state tracker object.

🌸 telnet_begin_newenviron()

void telnet_begin_newenviron (telnet_t * telnet, unsigned char type) [extern]

Opens up a fresh set of NEW-ENVIRON values to request or send. It starts the sub-negotiation block for sending or requesting NEW-ENVIRON values.

Heads up: you must call the telnet_finish_newenviron() macro after this one to terminate the NEW-ENVIRON command. Don't leave it hanging, it's giving unfinished sentence energy 😭

Parameters

  • telnet β€” Telnet state tracker object.
  • type β€” One of TELNET_ENVIRON_SEND, TELNET_ENVIRON_IS, or TELNET_ENVIRON_INFO.

πŸ¦‹ telnet_begin_sb()

void telnet_begin_sb (telnet_t * telnet, unsigned char telopt) [extern]

Begins a sub-negotiation command. It sends IAC SB followed by the telopt code. Everything you send after this becomes part of the sub-negotiation β€” right up until telnet_finish_sb() gets called. it's a whole vibe window, open then closed ✨

Parameters

  • telnet β€” Telnet state tracker object.
  • telopt β€” One of the TELNET_TELOPT_* values.

πŸŽ€ telnet_begin_zmp()

void telnet_begin_zmp (telnet_t * telnet, const char * cmd) [extern]

Begins sending a ZMP command.

Parameters

  • telnet β€” Telnet state tracker object.
  • cmd β€” The first argument (command name) for the ZMP command.

🧚 telnet_free()

void telnet_free (telnet_t * telnet) [extern]

Frees up any memory a state tracker allocated. You must call this when a telnet state tracker is no longer needed (like, say, after the connection has closed) so all the memory resources it was using get released. clean up after yourself bestie, no leaks in this house 🫢

Parameters

  • telnet β€” Telnet state tracker object.

πŸ’œ telnet_iac()

void telnet_iac (telnet_t * telnet, unsigned char cmd) [extern]

Sends a telnet command.

Parameters

  • telnet β€” Telnet state tracker object.
  • cmd β€” Command to send.

πŸ‘‘ telnet_init()

telnet_t * telnet_init (const telnet_telopt_t * telopts, telnet_event_handler_t eh, unsigned char flags, void * user_data) [extern]

Initializes a telnet state tracker. This sets up a brand new state tracker, and that's the object every other libtelnet function is gonna use. Important: each connection must have its own telnet state tracker object. no sharing, no borrowing, main character energy only, one tracker per connection πŸ’…

Parameters

  • telopts β€” Table of TELNET options the application supports.
  • eh β€” Event handler function called for every event.
  • flags β€” 0 or TELNET_FLAG_PROXY.
  • user_data β€” Optional data pointer that will be passed to eh.

Returns

Telnet state tracker object.


🌈 telnet_negotiate()

void telnet_negotiate (telnet_t * telnet, unsigned char cmd, unsigned char opt) [extern]

Sends a negotiation command. Under the hood, libtelnet follows RFC1143 option negotiation rules β€” so the negotiation commands you send through this function may be ignored if they get flagged as redundant. it's not being rude, it's just efficient ✨

Parameters

  • telnet β€” Telnet state tracker object.
  • cmd β€” TELNET_WILL, TELNET_WONT, TELNET_DO, or TELNET_DONT.
  • opt β€” One of the TELNET_TELOPT_* values.

πŸ“ telnet_newenviron_value()

void telnet_newenviron_value (telnet_t * telnet, unsigned char type, const char * string) [extern]

Sends a NEW-ENVIRON variable name or value. Big rule: this can only be called between calls to telnet_begin_newenviron() and telnet_finish_newenviron(). outside that window? nope. not happening πŸ™ˆ

Parameters

  • telnet β€” Telnet state tracker object.
  • type β€” One of TELNET_ENVIRON_VAR, TELNET_ENVIRON_USERVAR, or TELNET_ENVIRON_VALUE.
  • string β€” Variable name or value.

⭐ telnet_printf()

int telnet_printf (telnet_t * telnet, const char * fmt,  ...) [extern]

Sends formatted data. It's a wrapper around telnet_send(), so you get to use printf-style formatting. cute right?

And there's more: this one also translates \r into the CR NUL construct and \n into CR LF, and it automatically escapes IAC bytes exactly like telnet_send() does. it does everything, honestly πŸŽ€

Parameters

  • telnet β€” Telnet state tracker object.
  • fmt β€” Format string.

Returns

Number of bytes sent.


πŸ”₯ telnet_raw_printf()

int telnet_raw_printf (telnet_t * telnet, const char * fmt,  ...) [extern]

Sends formatted data with no newline escaping. Behaves identically to telnet_printf(), except the \r and \n characters don't get translated. The IAC byte still gets escaped like normal with telnet_send() though β€” that part stays. raw but not that raw πŸ’…

Parameters

  • telnet β€” Telnet state tracker object.
  • fmt β€” Format string.

Returns

Number of bytes sent.


πŸ¦‹ telnet_raw_vprintf()

int int telnet_raw_vprintf (telnet_t * telnet, const char * fmt, va_list va) [extern]

Sends formatted data with no newline escaping. See telnet_raw_printf().

yes bestie, that signature really does say int int. it is printed exactly like that in the docs and we do not touch it. we respect the source. πŸ’€

🌸 telnet_recv()

void telnet_recv (telnet_t * telnet, const char * buffer, size_t size) [extern]

Pushes a byte buffer into the state tracker. This passes one or more bytes over for protocol parsing. Most of the time that byte buffer is gonna be the same buffer you called recv() on while handling the connection. it's the handoff moment 🀝

Parameters

  • telnet β€” Telnet state tracker object.
  • buffer β€” Pointer to byte buffer.
  • size β€” Number of bytes pointed to by buffer.

πŸ’œ telnet_send()

void telnet_send (telnet_t * telnet, const char * buffer, size_t size) [extern]

Sends non-command data (and yes, it escapes IAC bytes).

Parameters

  • telnet β€” Telnet state tracker object.
  • buffer β€” Buffer of bytes to send.
  • size β€” Number of bytes to send.

✨ telnet_send_text()

void telnet_send_text (telnet_t * telnet, const char * buffer, size_t size) [extern]

Sends non-command text β€” it escapes IAC bytes and translates \r -> CR-NUL and \n -> CR-LF, unless you're in BINARY mode. text mode with the full glow-up basically 🌈

Parameters

  • telnet β€” Telnet state tracker object.
  • buffer β€” Buffer of bytes to send.
  • size β€” Number of bytes to send.

πŸŽ€ telnet_send_vzmpv()

void telnet_send_vzmpv (telnet_t * telnet, va_list va) [extern]

Sends a ZMP command. See telnet_send_zmpv().


πŸ‘‘ telnet_send_zmp()

void telnet_send_zmp (telnet_t * telnet, size_t argc, const char ** argv) [extern]

Sends a ZMP command.

Parameters

  • telnet β€” Telnet state tracker object.
  • argc β€” Number of ZMP commands being sent.
  • argv β€” Array of argument strings.

🧚 telnet_send_zmpv()

void telnet_send_zmpv (telnet_t * telnet,  ...) [extern]

Sends a ZMP command. Arguments get listed out in var-args style β€” and after the last argument you must pass in a NULL pointer as a sentinel value. don't forget the sentinel bestie, it's the whole point 🫢

Parameters

  • telnet β€” Telnet state tracker object.

πŸ“ telnet_subnegotiation()

void telnet_subnegotiation (telnet_t * telnet, unsigned char telopt, const char * buffer, size_t size) [extern]

Shortcut for sending a complete subnegotiation buffer. Equivalent to:

telnet_begin_sb(telnet, telopt); telnet_send(telnet, buffer, size); telnet_finish_sb(telnet);

three calls, one function. efficiency icon πŸ’…

Parameters

  • telnet β€” Telnet state tracker format.
  • telopt β€” One of the TELNET_TELOPT_* values.
  • buffer β€” Byte buffer for sub-negotiation data.
  • size β€” Number of bytes to use for sub-negotiation data.

🌸 telnet_ttype_is()

void telnet_ttype_is (telnet_t * telnet, const char * ttype) [extern]

Sends the TERMINAL-TYPE IS command. The sequence it sends is IAC TERMINAL-TYPE IS "string".

okay now the RFC lore, because it matters, stay with me πŸ“–βœ¨

Per the RFC, whoever receives a TERMINAL-TYPE SEND shall send the next possible terminal-type the client supports. Once the type is sent, the client should switch modes and begin acting as the terminal type it just sent.

The server may keep sending TERMINAL-TYPE IS until it receives a terminal type it understands. To signal that it's hit the end of the available options, the client must send the last terminal type a second time. So when the server sees the same terminal type twice in a row, it knows it's seen every available terminal type. that's the little handshake tell πŸ‘€

After the last terminal type is sent, if the client gets another TERMINAL-TYPE SEND command, it must begin enumerating the available terminal types from the very beginning. This lets the server scan the available types for a preferred one and, if it finds none, ask the client to switch to an acceptable alternative.

One note for the minimalists: if the client only supports a single terminal type, then simply sending that one type in response to every SEND will satisfy the behavior requirements. one type, endless confidence πŸ‘‘

Parameters

  • telnet β€” Telnet state tracker object.
  • ttype β€” Name of the terminal-type being sent.

🌈 telnet_ttype_send()

void telnet_ttype_send (telnet_t * telnet) [extern]

Sends the TERMINAL-TYPE SEND command. The sequence it sends is IAC TERMINAL-TYPE SEND.

Parameters

  • telnet β€” Telnet state tracker object.

⭐ telnet_vprintf()

int int telnet_vprintf (telnet_t * telnet, const char * fmt, va_list va) [extern]

Sends formatted data. See telnet_printf().

and yeah, this one says int int too. printed exactly like that. untouched. periodt. πŸ’€

πŸ’– telnet_zmp_arg()

void telnet_zmp_arg (telnet_t * telnet, const char * arg) [extern]

Sends a ZMP command argument.

Parameters

  • telnet β€” Telnet state tracker object.
  • arg β€” Telnet argument string.

πŸ‘‘ AUTHOR πŸ‘‘

Generated automatically by Doxygen for My Project from the source code.


and that's the whole page bestie 🫢 this was My Project, page libtelnet.h(3) β€” that's your source and your version, straight from the footer. no date on it, just vibes and a Doxygen signature. go forth and negotiate, you absolute icon βœ¨πŸ’…πŸŒΈ

πŸ“¦ where this page comes from