mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-02 03:52:49 -05:00
Rework special-commands system to add an integer argument.
In order to list cross-certifiable host keys in the GUI specials menu, the SSH backend has been inventing new values on the end of the Telnet_Special enumeration, starting from the value TS_LOCALSTART. This is inelegant, and also makes it awkward to break up special handlers (e.g. to dispatch different specials to different SSH layers), since if all you know about a special is that it's somewhere in the TS_LOCALSTART+n space, you can't tell what _general kind_ of thing it is. Also, if I ever need another open-ended set of specials in future, I'll have to remember which TS_LOCALSTART+n codes are in which set. So here's a revamp that causes every special to take an extra integer argument. For all previously numbered specials, this argument is passed as zero and ignored, but there's a new main special code for SSH host key cross-certification, in which the integer argument is an index into the backend's list of available keys. TS_LOCALSTART is now a thing of the past: if I need any other open-ended sets of specials in future, I can add a new top-level code with a nicely separated space of arguments. While I'm at it, I've removed the legacy misnomer 'Telnet_Special' from the code completely; the enum is now SessionSpecialCode, the struct containing full details of a menu entry is SessionSpecial, and the enum values now start SS_ rather than TS_.
This commit is contained in:
89
putty.h
89
putty.h
@ -172,34 +172,67 @@ struct unicode_data {
|
||||
#define LGTYP_PACKETS 3 /* logmode: SSH data packets */
|
||||
#define LGTYP_SSHRAW 4 /* logmode: SSH raw data */
|
||||
|
||||
/*
|
||||
* Enumeration of 'special commands' that can be sent during a
|
||||
* session, separately from the byte stream of ordinary session data.
|
||||
*/
|
||||
typedef enum {
|
||||
/* Actual special commands. Originally Telnet, but some codes have
|
||||
* been re-used for similar specials in other protocols. */
|
||||
TS_AYT, TS_BRK, TS_SYNCH, TS_EC, TS_EL, TS_GA, TS_NOP, TS_ABORT,
|
||||
TS_AO, TS_IP, TS_SUSP, TS_EOR, TS_EOF, TS_LECHO, TS_RECHO, TS_PING,
|
||||
TS_EOL,
|
||||
/* Special command for SSH. */
|
||||
TS_REKEY,
|
||||
/* POSIX-style signals. (not Telnet) */
|
||||
TS_SIGABRT, TS_SIGALRM, TS_SIGFPE, TS_SIGHUP, TS_SIGILL,
|
||||
TS_SIGINT, TS_SIGKILL, TS_SIGPIPE, TS_SIGQUIT, TS_SIGSEGV,
|
||||
TS_SIGTERM, TS_SIGUSR1, TS_SIGUSR2,
|
||||
/* Pseudo-specials used for constructing the specials menu. */
|
||||
TS_SEP, /* Separator */
|
||||
TS_SUBMENU, /* Start a new submenu with specified name */
|
||||
TS_EXITMENU, /* Exit current submenu or end of specials */
|
||||
/* Starting point for protocols to invent special-action codes
|
||||
* that can't live in this enum at all, e.g. because they change
|
||||
* with every session.
|
||||
*
|
||||
* Of course, this must remain the last value in this
|
||||
* enumeration. */
|
||||
TS_LOCALSTART
|
||||
} Telnet_Special;
|
||||
/*
|
||||
* Commands that are generally useful in multiple backends.
|
||||
*/
|
||||
SS_BRK, /* serial-line break */
|
||||
SS_EOF, /* end-of-file on session input */
|
||||
SS_NOP, /* transmit data with no effect */
|
||||
SS_PING, /* try to keep the session alive (probably, but not
|
||||
* necessarily, implemented as SS_NOP) */
|
||||
|
||||
struct telnet_special {
|
||||
/*
|
||||
* Commands specific to Telnet.
|
||||
*/
|
||||
SS_AYT, /* Are You There */
|
||||
SS_SYNCH, /* Synch */
|
||||
SS_EC, /* Erase Character */
|
||||
SS_EL, /* Erase Line */
|
||||
SS_GA, /* Go Ahead */
|
||||
SS_ABORT, /* Abort Process */
|
||||
SS_AO, /* Abort Output */
|
||||
SS_IP, /* Interrupt Process */
|
||||
SS_SUSP, /* Suspend Process */
|
||||
SS_EOR, /* End Of Record */
|
||||
SS_EOL, /* Telnet end-of-line sequence (CRLF, as opposed to CR
|
||||
* NUL that escapes a literal CR) */
|
||||
|
||||
/*
|
||||
* Commands specific to SSH.
|
||||
*/
|
||||
SS_REKEY, /* trigger an immediate repeat key exchange */
|
||||
SS_XCERT, /* cross-certify another host key ('arg' indicates which) */
|
||||
|
||||
/*
|
||||
* Send a POSIX-style signal. (Useful in SSH and also pterm.)
|
||||
*/
|
||||
SS_SIGABRT, SS_SIGALRM, SS_SIGFPE, SS_SIGHUP, SS_SIGILL,
|
||||
SS_SIGINT, SS_SIGKILL, SS_SIGPIPE, SS_SIGQUIT, SS_SIGSEGV,
|
||||
SS_SIGTERM, SS_SIGUSR1, SS_SIGUSR2,
|
||||
|
||||
/*
|
||||
* These aren't really special commands, but they appear in the
|
||||
* enumeration because the list returned from
|
||||
* backend_get_specials() will use them to specify the structure
|
||||
* of the GUI specials menu.
|
||||
*/
|
||||
SS_SEP, /* Separator */
|
||||
SS_SUBMENU, /* Start a new submenu with specified name */
|
||||
SS_EXITMENU, /* Exit current submenu, or end of entire specials list */
|
||||
} SessionSpecialCode;
|
||||
|
||||
/*
|
||||
* The structure type returned from backend_get_specials.
|
||||
*/
|
||||
struct SessionSpecial {
|
||||
const char *name;
|
||||
int code;
|
||||
SessionSpecialCode code;
|
||||
int arg;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@ -457,8 +490,8 @@ struct Backend_vtable {
|
||||
/* sendbuffer() does the same thing but without attempting a send */
|
||||
int (*sendbuffer) (Backend *be);
|
||||
void (*size) (Backend *be, int width, int height);
|
||||
void (*special) (Backend *be, Telnet_Special code);
|
||||
const struct telnet_special *(*get_specials) (Backend *be);
|
||||
void (*special) (Backend *be, SessionSpecialCode code, int arg);
|
||||
const SessionSpecial *(*get_specials) (Backend *be);
|
||||
int (*connected) (Backend *be);
|
||||
int (*exitcode) (Backend *be);
|
||||
/* If back->sendok() returns FALSE, the backend doesn't currently
|
||||
@ -488,7 +521,7 @@ struct Backend_vtable {
|
||||
#define backend_send(be, buf, len) ((be)->vt->send(be, buf, len))
|
||||
#define backend_sendbuffer(be) ((be)->vt->sendbuffer(be))
|
||||
#define backend_size(be, w, h) ((be)->vt->size(be, w, h))
|
||||
#define backend_special(be, code) ((be)->vt->special(be, code))
|
||||
#define backend_special(be, code, arg) ((be)->vt->special(be, code, arg))
|
||||
#define backend_get_specials(be) ((be)->vt->get_specials(be))
|
||||
#define backend_connected(be) ((be)->vt->connected(be))
|
||||
#define backend_exitcode(be) ((be)->vt->exitcode(be))
|
||||
|
Reference in New Issue
Block a user