1
0
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:
Simon Tatham
2018-09-24 09:35:52 +01:00
parent 26f7a2ac72
commit f4fbaa1bd9
19 changed files with 224 additions and 194 deletions

89
putty.h
View File

@ -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))