libtelnet.h(3)
π¦ 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_tunion telnet_event_tstruct telnet_event_t::data_tstruct telnet_event_t::error_tstruct telnet_event_t::iac_tstruct telnet_event_t::negotiate_tstruct telnet_event_t::subnegotiate_tstruct telnet_event_t::zmp_tstruct telnet_event_t::ttype_tstruct telnet_event_t::compress_tstruct telnet_event_t::environ_tstruct telnet_event_t::mssp_tstruct 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_COMPRESS2andTELNET_TELOPT_MCCP2are both86. 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_tis 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:
- RFC854 β http://www.faqs.org/rfcs/rfc854.html
- RFC855 β http://www.faqs.org/rfcs/rfc855.html
- RFC1091 β http://www.faqs.org/rfcs/rfc1091.html
- RFC1143 β http://www.faqs.org/rfcs/rfc1143.html
- RFC1408 β http://www.faqs.org/rfcs/rfc1408.html
- RFC1572 β http://www.faqs.org/rfcs/rfc1572.html
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 happeneduser_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 ofTELNET_ENVIRON_SEND,TELNET_ENVIRON_IS, orTELNET_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 theTELNET_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β0orTELNET_FLAG_PROXY.user_dataβ Optional data pointer that will be passed toeh.
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, orTELNET_DONT.optβ One of theTELNET_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 ofTELNET_ENVIRON_VAR,TELNET_ENVIRON_USERVAR, orTELNET_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 bybuffer.
π 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 theTELNET_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
- epel 10: libtelnet-devel 0.23-11.el10_1 Β· LicenseRef-Fedora-Public-Domain
- fedora 43: libtelnet-devel 0.23-12.fc43 Β· Unlicense-libtelnet
- fedora 43: libtelnet-devel 0.23-12.fc43 Β· Unlicense-libtelnet
- fedora 44: libtelnet-devel 0.23-13.fc44 Β· Unlicense-libtelnet
- fedora 44: libtelnet-devel 0.23-13.fc44 Β· Unlicense-libtelnet
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms