mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 09:58:01 +00: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:
parent
26f7a2ac72
commit
f4fbaa1bd9
2
defs.h
2
defs.h
@ -70,6 +70,8 @@ typedef struct settings_w settings_w;
|
||||
typedef struct settings_r settings_r;
|
||||
typedef struct settings_e settings_e;
|
||||
|
||||
typedef struct SessionSpecial SessionSpecial;
|
||||
|
||||
/* Note indirection: for historical reasons (it used to be closer to
|
||||
* the OS socket type), the type that most code uses for a socket is
|
||||
* 'Socket', not 'Socket *'. So an implementation of Socket or Plug
|
||||
|
20
ldisc.c
20
ldisc.c
@ -217,7 +217,7 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
|
||||
bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
|
||||
ldisc->buflen--;
|
||||
}
|
||||
backend_special(ldisc->backend, TS_EL);
|
||||
backend_special(ldisc->backend, SS_EL, 0);
|
||||
/*
|
||||
* We don't send IP, SUSP or ABORT if the user has
|
||||
* configured telnet specials off! This breaks
|
||||
@ -226,11 +226,11 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
|
||||
if (!ldisc->telnet_keyboard)
|
||||
goto default_case;
|
||||
if (c == CTRL('C'))
|
||||
backend_special(ldisc->backend, TS_IP);
|
||||
backend_special(ldisc->backend, SS_IP, 0);
|
||||
if (c == CTRL('Z'))
|
||||
backend_special(ldisc->backend, TS_SUSP);
|
||||
backend_special(ldisc->backend, SS_SUSP, 0);
|
||||
if (c == CTRL('\\'))
|
||||
backend_special(ldisc->backend, TS_ABORT);
|
||||
backend_special(ldisc->backend, SS_ABORT, 0);
|
||||
break;
|
||||
case CTRL('R'): /* redraw line */
|
||||
if (ECHOING) {
|
||||
@ -245,7 +245,7 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
|
||||
break;
|
||||
case CTRL('D'): /* logout or send */
|
||||
if (ldisc->buflen == 0) {
|
||||
backend_special(ldisc->backend, TS_EOF);
|
||||
backend_special(ldisc->backend, SS_EOF, 0);
|
||||
} else {
|
||||
backend_send(ldisc->backend, ldisc->buf, ldisc->buflen);
|
||||
ldisc->buflen = 0;
|
||||
@ -288,7 +288,7 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
|
||||
if (ldisc->protocol == PROT_RAW)
|
||||
backend_send(ldisc->backend, "\r\n", 2);
|
||||
else if (ldisc->protocol == PROT_TELNET && ldisc->telnet_newline)
|
||||
backend_special(ldisc->backend, TS_EOL);
|
||||
backend_special(ldisc->backend, SS_EOL, 0);
|
||||
else
|
||||
backend_send(ldisc->backend, "\r", 1);
|
||||
if (ECHOING)
|
||||
@ -325,24 +325,24 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
|
||||
switch (buf[0]) {
|
||||
case CTRL('M'):
|
||||
if (ldisc->protocol == PROT_TELNET && ldisc->telnet_newline)
|
||||
backend_special(ldisc->backend, TS_EOL);
|
||||
backend_special(ldisc->backend, SS_EOL, 0);
|
||||
else
|
||||
backend_send(ldisc->backend, "\r", 1);
|
||||
break;
|
||||
case CTRL('?'):
|
||||
case CTRL('H'):
|
||||
if (ldisc->telnet_keyboard) {
|
||||
backend_special(ldisc->backend, TS_EC);
|
||||
backend_special(ldisc->backend, SS_EC, 0);
|
||||
break;
|
||||
}
|
||||
case CTRL('C'):
|
||||
if (ldisc->telnet_keyboard) {
|
||||
backend_special(ldisc->backend, TS_IP);
|
||||
backend_special(ldisc->backend, SS_IP, 0);
|
||||
break;
|
||||
}
|
||||
case CTRL('Z'):
|
||||
if (ldisc->telnet_keyboard) {
|
||||
backend_special(ldisc->backend, TS_SUSP);
|
||||
backend_special(ldisc->backend, SS_SUSP, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
4
pinger.c
4
pinger.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* pinger.c: centralised module that deals with sending TS_PING
|
||||
* pinger.c: centralised module that deals with sending SS_PING
|
||||
* keepalives, to avoid replicating this code in multiple backends.
|
||||
*/
|
||||
|
||||
@ -19,7 +19,7 @@ static void pinger_timer(void *ctx, unsigned long now)
|
||||
Pinger pinger = (Pinger)ctx;
|
||||
|
||||
if (pinger->pending && now == pinger->next) {
|
||||
backend_special(pinger->backend, TS_PING);
|
||||
backend_special(pinger->backend, SS_PING, 0);
|
||||
pinger->pending = FALSE;
|
||||
pinger_schedule(pinger);
|
||||
}
|
||||
|
4
pscp.c
4
pscp.c
@ -293,7 +293,7 @@ static void bump(const char *fmt, ...)
|
||||
|
||||
if (backend && backend_connected(backend)) {
|
||||
char ch;
|
||||
backend_special(backend, TS_EOF);
|
||||
backend_special(backend, SS_EOF, 0);
|
||||
sent_eof = TRUE;
|
||||
ssh_scp_recv(&ch, 1);
|
||||
}
|
||||
@ -2367,7 +2367,7 @@ int psftp_main(int argc, char *argv[])
|
||||
|
||||
if (backend && backend_connected(backend)) {
|
||||
char ch;
|
||||
backend_special(backend, TS_EOF);
|
||||
backend_special(backend, SS_EOF, 0);
|
||||
sent_eof = TRUE;
|
||||
ssh_scp_recv(&ch, 1);
|
||||
}
|
||||
|
6
psftp.c
6
psftp.c
@ -973,7 +973,7 @@ int sftp_cmd_close(struct sftp_command *cmd)
|
||||
|
||||
if (backend_connected(backend)) {
|
||||
char ch;
|
||||
backend_special(backend, TS_EOF);
|
||||
backend_special(backend, SS_EOF, 0);
|
||||
sent_eof = TRUE;
|
||||
sftp_recvdata(&ch, 1);
|
||||
}
|
||||
@ -2355,7 +2355,7 @@ void do_sftp_cleanup()
|
||||
{
|
||||
char ch;
|
||||
if (backend) {
|
||||
backend_special(backend, TS_EOF);
|
||||
backend_special(backend, SS_EOF, 0);
|
||||
sent_eof = TRUE;
|
||||
sftp_recvdata(&ch, 1);
|
||||
backend_free(backend);
|
||||
@ -2965,7 +2965,7 @@ int psftp_main(int argc, char *argv[])
|
||||
|
||||
if (backend && backend_connected(backend)) {
|
||||
char ch;
|
||||
backend_special(backend, TS_EOF);
|
||||
backend_special(backend, SS_EOF, 0);
|
||||
sent_eof = TRUE;
|
||||
sftp_recvdata(&ch, 1);
|
||||
}
|
||||
|
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))
|
||||
|
6
raw.c
6
raw.c
@ -231,10 +231,10 @@ static void raw_size(Backend *be, int width, int height)
|
||||
/*
|
||||
* Send raw special codes. We only handle outgoing EOF here.
|
||||
*/
|
||||
static void raw_special(Backend *be, Telnet_Special code)
|
||||
static void raw_special(Backend *be, SessionSpecialCode code, int arg)
|
||||
{
|
||||
Raw raw = FROMFIELD(be, struct raw_backend_data, backend);
|
||||
if (code == TS_EOF && raw->s) {
|
||||
if (code == SS_EOF && raw->s) {
|
||||
sk_write_eof(raw->s);
|
||||
raw->sent_socket_eof= TRUE;
|
||||
raw_check_close(raw);
|
||||
@ -247,7 +247,7 @@ static void raw_special(Backend *be, Telnet_Special code)
|
||||
* Return a list of the special codes that make sense in this
|
||||
* protocol.
|
||||
*/
|
||||
static const struct telnet_special *raw_get_specials(Backend *be)
|
||||
static const SessionSpecial *raw_get_specials(Backend *be)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
4
rlogin.c
4
rlogin.c
@ -328,7 +328,7 @@ static void rlogin_size(Backend *be, int width, int height)
|
||||
/*
|
||||
* Send rlogin special codes.
|
||||
*/
|
||||
static void rlogin_special(Backend *be, Telnet_Special code)
|
||||
static void rlogin_special(Backend *be, SessionSpecialCode code, int arg)
|
||||
{
|
||||
/* Do nothing! */
|
||||
return;
|
||||
@ -338,7 +338,7 @@ static void rlogin_special(Backend *be, Telnet_Special code)
|
||||
* Return a list of the special codes that make sense in this
|
||||
* protocol.
|
||||
*/
|
||||
static const struct telnet_special *rlogin_get_specials(Backend *be)
|
||||
static const SessionSpecial *rlogin_get_specials(Backend *be)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
119
ssh.c
119
ssh.c
@ -313,7 +313,7 @@ static void ssh1_protocol_setup(Ssh ssh);
|
||||
static void ssh2_protocol_setup(Ssh ssh);
|
||||
static void ssh2_bare_connection_protocol_setup(Ssh ssh);
|
||||
static void ssh_size(Backend *be, int width, int height);
|
||||
static void ssh_special(Backend *be, Telnet_Special);
|
||||
static void ssh_special(Backend *be, SessionSpecialCode, int arg);
|
||||
static int ssh2_try_send(struct ssh_channel *c);
|
||||
static int ssh_send_channel_data(struct ssh_channel *c,
|
||||
const char *buf, int len);
|
||||
@ -592,7 +592,7 @@ struct ssh_tag {
|
||||
/*
|
||||
* The last list returned from get_specials.
|
||||
*/
|
||||
struct telnet_special *specials;
|
||||
SessionSpecial *specials;
|
||||
|
||||
/*
|
||||
* List of host key algorithms for which we _don't_ have a stored
|
||||
@ -3243,7 +3243,7 @@ static void do_ssh1_connection(void *vctx)
|
||||
if (ssh->size_needed)
|
||||
backend_size(&ssh->backend, ssh->term_width, ssh->term_height);
|
||||
if (ssh->eof_needed)
|
||||
backend_special(&ssh->backend, TS_EOF);
|
||||
backend_special(&ssh->backend, SS_EOF, 0);
|
||||
|
||||
if (ssh->ldisc)
|
||||
ldisc_echoedit_update(ssh->ldisc); /* cause ldisc to notice changes */
|
||||
@ -8524,7 +8524,7 @@ static void do_ssh2_connection(void *vctx)
|
||||
if (ssh->size_needed)
|
||||
backend_size(&ssh->backend, ssh->term_width, ssh->term_height);
|
||||
if (ssh->eof_needed)
|
||||
backend_special(&ssh->backend, TS_EOF);
|
||||
backend_special(&ssh->backend, SS_EOF, 0);
|
||||
|
||||
/*
|
||||
* Transfer data!
|
||||
@ -9514,40 +9514,40 @@ static void ssh_size(Backend *be, int width, int height)
|
||||
* Return a list of the special codes that make sense in this
|
||||
* protocol.
|
||||
*/
|
||||
static const struct telnet_special *ssh_get_specials(Backend *be)
|
||||
static const SessionSpecial *ssh_get_specials(Backend *be)
|
||||
{
|
||||
static const struct telnet_special ssh1_ignore_special[] = {
|
||||
{"IGNORE message", TS_NOP}
|
||||
static const SessionSpecial ssh1_ignore_special[] = {
|
||||
{"IGNORE message", SS_NOP}
|
||||
};
|
||||
static const struct telnet_special ssh2_ignore_special[] = {
|
||||
{"IGNORE message", TS_NOP},
|
||||
static const SessionSpecial ssh2_ignore_special[] = {
|
||||
{"IGNORE message", SS_NOP},
|
||||
};
|
||||
static const struct telnet_special ssh2_rekey_special[] = {
|
||||
{"Repeat key exchange", TS_REKEY},
|
||||
static const SessionSpecial ssh2_rekey_special[] = {
|
||||
{"Repeat key exchange", SS_REKEY},
|
||||
};
|
||||
static const struct telnet_special ssh2_session_specials[] = {
|
||||
{NULL, TS_SEP},
|
||||
{"Break", TS_BRK},
|
||||
static const SessionSpecial ssh2_session_specials[] = {
|
||||
{NULL, SS_SEP},
|
||||
{"Break", SS_BRK},
|
||||
/* These are the signal names defined by RFC 4254.
|
||||
* They include all the ISO C signals, but are a subset of the POSIX
|
||||
* required signals. */
|
||||
{"SIGINT (Interrupt)", TS_SIGINT},
|
||||
{"SIGTERM (Terminate)", TS_SIGTERM},
|
||||
{"SIGKILL (Kill)", TS_SIGKILL},
|
||||
{"SIGQUIT (Quit)", TS_SIGQUIT},
|
||||
{"SIGHUP (Hangup)", TS_SIGHUP},
|
||||
{"More signals", TS_SUBMENU},
|
||||
{"SIGABRT", TS_SIGABRT}, {"SIGALRM", TS_SIGALRM},
|
||||
{"SIGFPE", TS_SIGFPE}, {"SIGILL", TS_SIGILL},
|
||||
{"SIGPIPE", TS_SIGPIPE}, {"SIGSEGV", TS_SIGSEGV},
|
||||
{"SIGUSR1", TS_SIGUSR1}, {"SIGUSR2", TS_SIGUSR2},
|
||||
{NULL, TS_EXITMENU}
|
||||
{"SIGINT (Interrupt)", SS_SIGINT},
|
||||
{"SIGTERM (Terminate)", SS_SIGTERM},
|
||||
{"SIGKILL (Kill)", SS_SIGKILL},
|
||||
{"SIGQUIT (Quit)", SS_SIGQUIT},
|
||||
{"SIGHUP (Hangup)", SS_SIGHUP},
|
||||
{"More signals", SS_SUBMENU},
|
||||
{"SIGABRT", SS_SIGABRT}, {"SIGALRM", SS_SIGALRM},
|
||||
{"SIGFPE", SS_SIGFPE}, {"SIGILL", SS_SIGILL},
|
||||
{"SIGPIPE", SS_SIGPIPE}, {"SIGSEGV", SS_SIGSEGV},
|
||||
{"SIGUSR1", SS_SIGUSR1}, {"SIGUSR2", SS_SIGUSR2},
|
||||
{NULL, SS_EXITMENU}
|
||||
};
|
||||
static const struct telnet_special specials_end[] = {
|
||||
{NULL, TS_EXITMENU}
|
||||
static const SessionSpecial specials_end[] = {
|
||||
{NULL, SS_EXITMENU}
|
||||
};
|
||||
|
||||
struct telnet_special *specials = NULL;
|
||||
SessionSpecial *specials = NULL;
|
||||
int nspecials = 0, specialsize = 0;
|
||||
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
@ -9559,9 +9559,9 @@ static const struct telnet_special *ssh_get_specials(Backend *be)
|
||||
int len = lenof(name); \
|
||||
if (nspecials + len > specialsize) { \
|
||||
specialsize = (nspecials + len) * 5 / 4 + 32; \
|
||||
specials = sresize(specials, specialsize, struct telnet_special); \
|
||||
specials = sresize(specials, specialsize, SessionSpecial); \
|
||||
} \
|
||||
memcpy(specials+nspecials, name, len*sizeof(struct telnet_special)); \
|
||||
memcpy(specials+nspecials, name, len*sizeof(SessionSpecial)); \
|
||||
nspecials += len; \
|
||||
} while (0)
|
||||
|
||||
@ -9580,22 +9580,23 @@ static const struct telnet_special *ssh_get_specials(Backend *be)
|
||||
ADD_SPECIALS(ssh2_session_specials);
|
||||
|
||||
if (ssh->n_uncert_hostkeys) {
|
||||
static const struct telnet_special uncert_start[] = {
|
||||
{NULL, TS_SEP},
|
||||
{"Cache new host key type", TS_SUBMENU},
|
||||
static const SessionSpecial uncert_start[] = {
|
||||
{NULL, SS_SEP},
|
||||
{"Cache new host key type", SS_SUBMENU},
|
||||
};
|
||||
static const struct telnet_special uncert_end[] = {
|
||||
{NULL, TS_EXITMENU},
|
||||
static const SessionSpecial uncert_end[] = {
|
||||
{NULL, SS_EXITMENU},
|
||||
};
|
||||
int i;
|
||||
|
||||
ADD_SPECIALS(uncert_start);
|
||||
for (i = 0; i < ssh->n_uncert_hostkeys; i++) {
|
||||
struct telnet_special uncert[1];
|
||||
SessionSpecial uncert[1];
|
||||
const ssh_keyalg *alg =
|
||||
hostkey_algs[ssh->uncert_hostkeys[i]].alg;
|
||||
uncert[0].name = alg->ssh_id;
|
||||
uncert[0].code = TS_LOCALSTART + ssh->uncert_hostkeys[i];
|
||||
uncert[0].code = SS_XCERT;
|
||||
uncert[0].arg = ssh->uncert_hostkeys[i];
|
||||
ADD_SPECIALS(uncert);
|
||||
}
|
||||
ADD_SPECIALS(uncert_end);
|
||||
@ -9616,22 +9617,22 @@ static const struct telnet_special *ssh_get_specials(Backend *be)
|
||||
}
|
||||
|
||||
/*
|
||||
* Send special codes. TS_EOF is useful for `plink', so you
|
||||
* Send special codes. SS_EOF is useful for `plink', so you
|
||||
* can send an EOF and collect resulting output (e.g. `plink
|
||||
* hostname sort').
|
||||
*/
|
||||
static void ssh_special(Backend *be, Telnet_Special code)
|
||||
static void ssh_special(Backend *be, SessionSpecialCode code, int arg)
|
||||
{
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
PktOut *pktout;
|
||||
|
||||
if (code == TS_EOF) {
|
||||
if (code == SS_EOF) {
|
||||
if (ssh->state != SSH_STATE_SESSION) {
|
||||
/*
|
||||
* Buffer the EOF in case we are pre-SESSION, so we can
|
||||
* send it as soon as we reach SESSION.
|
||||
*/
|
||||
if (code == TS_EOF)
|
||||
if (code == SS_EOF)
|
||||
ssh->eof_needed = TRUE;
|
||||
return;
|
||||
}
|
||||
@ -9643,7 +9644,7 @@ static void ssh_special(Backend *be, Telnet_Special code)
|
||||
ssh->send_ok = 0; /* now stop trying to read from stdin */
|
||||
}
|
||||
logevent("Sent EOF message");
|
||||
} else if (code == TS_PING || code == TS_NOP) {
|
||||
} else if (code == SS_PING || code == SS_NOP) {
|
||||
if (ssh->state == SSH_STATE_CLOSED
|
||||
|| ssh->state == SSH_STATE_PREPACKET) return;
|
||||
if (ssh->version == 1) {
|
||||
@ -9659,15 +9660,15 @@ static void ssh_special(Backend *be, Telnet_Special code)
|
||||
ssh_pkt_write(ssh, pktout);
|
||||
}
|
||||
}
|
||||
} else if (code == TS_REKEY) {
|
||||
} else if (code == SS_REKEY) {
|
||||
if (!ssh->kex_in_progress && !ssh->bare_connection &&
|
||||
ssh->version == 2) {
|
||||
ssh->rekey_reason = "at user request";
|
||||
ssh->rekey_class = RK_NORMAL;
|
||||
queue_idempotent_callback(&ssh->ssh2_transport_icb);
|
||||
}
|
||||
} else if (code >= TS_LOCALSTART) {
|
||||
ssh->hostkey_alg = hostkey_algs[code - TS_LOCALSTART].alg;
|
||||
} else if (code == SS_XCERT) {
|
||||
ssh->hostkey_alg = hostkey_algs[arg].alg;
|
||||
ssh->cross_certifying = TRUE;
|
||||
if (!ssh->kex_in_progress && !ssh->bare_connection &&
|
||||
ssh->version == 2) {
|
||||
@ -9675,7 +9676,7 @@ static void ssh_special(Backend *be, Telnet_Special code)
|
||||
ssh->rekey_class = RK_NORMAL;
|
||||
queue_idempotent_callback(&ssh->ssh2_transport_icb);
|
||||
}
|
||||
} else if (code == TS_BRK) {
|
||||
} else if (code == SS_BRK) {
|
||||
if (ssh->state == SSH_STATE_CLOSED
|
||||
|| ssh->state == SSH_STATE_PREPACKET) return;
|
||||
if (ssh->version == 1) {
|
||||
@ -9688,19 +9689,19 @@ static void ssh_special(Backend *be, Telnet_Special code)
|
||||
} else {
|
||||
/* Is is a POSIX signal? */
|
||||
const char *signame = NULL;
|
||||
if (code == TS_SIGABRT) signame = "ABRT";
|
||||
if (code == TS_SIGALRM) signame = "ALRM";
|
||||
if (code == TS_SIGFPE) signame = "FPE";
|
||||
if (code == TS_SIGHUP) signame = "HUP";
|
||||
if (code == TS_SIGILL) signame = "ILL";
|
||||
if (code == TS_SIGINT) signame = "INT";
|
||||
if (code == TS_SIGKILL) signame = "KILL";
|
||||
if (code == TS_SIGPIPE) signame = "PIPE";
|
||||
if (code == TS_SIGQUIT) signame = "QUIT";
|
||||
if (code == TS_SIGSEGV) signame = "SEGV";
|
||||
if (code == TS_SIGTERM) signame = "TERM";
|
||||
if (code == TS_SIGUSR1) signame = "USR1";
|
||||
if (code == TS_SIGUSR2) signame = "USR2";
|
||||
if (code == SS_SIGABRT) signame = "ABRT";
|
||||
if (code == SS_SIGALRM) signame = "ALRM";
|
||||
if (code == SS_SIGFPE) signame = "FPE";
|
||||
if (code == SS_SIGHUP) signame = "HUP";
|
||||
if (code == SS_SIGILL) signame = "ILL";
|
||||
if (code == SS_SIGINT) signame = "INT";
|
||||
if (code == SS_SIGKILL) signame = "KILL";
|
||||
if (code == SS_SIGPIPE) signame = "PIPE";
|
||||
if (code == SS_SIGQUIT) signame = "QUIT";
|
||||
if (code == SS_SIGSEGV) signame = "SEGV";
|
||||
if (code == SS_SIGTERM) signame = "TERM";
|
||||
if (code == SS_SIGUSR1) signame = "USR1";
|
||||
if (code == SS_SIGUSR2) signame = "USR2";
|
||||
/* The SSH-2 protocol does in principle support arbitrary named
|
||||
* signals, including signame@domain, but we don't support those. */
|
||||
if (signame) {
|
||||
|
81
telnet.c
81
telnet.c
@ -914,7 +914,7 @@ static void telnet_size(Backend *be, int width, int height)
|
||||
/*
|
||||
* Send Telnet special codes.
|
||||
*/
|
||||
static void telnet_special(Backend *be, Telnet_Special code)
|
||||
static void telnet_special(Backend *be, SessionSpecialCode code, int arg)
|
||||
{
|
||||
Telnet telnet = FROMFIELD(be, struct telnet_tag, backend);
|
||||
unsigned char b[2];
|
||||
@ -924,55 +924,55 @@ static void telnet_special(Backend *be, Telnet_Special code)
|
||||
|
||||
b[0] = IAC;
|
||||
switch (code) {
|
||||
case TS_AYT:
|
||||
case SS_AYT:
|
||||
b[1] = AYT;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
break;
|
||||
case TS_BRK:
|
||||
case SS_BRK:
|
||||
b[1] = BREAK;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
break;
|
||||
case TS_EC:
|
||||
case SS_EC:
|
||||
b[1] = EC;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
break;
|
||||
case TS_EL:
|
||||
case SS_EL:
|
||||
b[1] = EL;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
break;
|
||||
case TS_GA:
|
||||
case SS_GA:
|
||||
b[1] = GA;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
break;
|
||||
case TS_NOP:
|
||||
case SS_NOP:
|
||||
b[1] = NOP;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
break;
|
||||
case TS_ABORT:
|
||||
case SS_ABORT:
|
||||
b[1] = ABORT;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
break;
|
||||
case TS_AO:
|
||||
case SS_AO:
|
||||
b[1] = AO;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
break;
|
||||
case TS_IP:
|
||||
case SS_IP:
|
||||
b[1] = IP;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
break;
|
||||
case TS_SUSP:
|
||||
case SS_SUSP:
|
||||
b[1] = SUSP;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
break;
|
||||
case TS_EOR:
|
||||
case SS_EOR:
|
||||
b[1] = EOR;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
break;
|
||||
case TS_EOF:
|
||||
case SS_EOF:
|
||||
b[1] = xEOF;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
break;
|
||||
case TS_EOL:
|
||||
case SS_EOL:
|
||||
/* In BINARY mode, CR-LF becomes just CR -
|
||||
* and without the NUL suffix too. */
|
||||
if (telnet->opt_states[o_we_bin.index] == ACTIVE)
|
||||
@ -980,25 +980,12 @@ static void telnet_special(Backend *be, Telnet_Special code)
|
||||
else
|
||||
telnet->bufsize = sk_write(telnet->s, "\r\n", 2);
|
||||
break;
|
||||
case TS_SYNCH:
|
||||
case SS_SYNCH:
|
||||
b[1] = DM;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 1);
|
||||
telnet->bufsize = sk_write_oob(telnet->s, b + 1, 1);
|
||||
break;
|
||||
case TS_RECHO:
|
||||
if (telnet->opt_states[o_echo.index] == INACTIVE ||
|
||||
telnet->opt_states[o_echo.index] == REALLY_INACTIVE) {
|
||||
telnet->opt_states[o_echo.index] = REQUESTED;
|
||||
send_opt(telnet, o_echo.send, o_echo.option);
|
||||
}
|
||||
break;
|
||||
case TS_LECHO:
|
||||
if (telnet->opt_states[o_echo.index] == ACTIVE) {
|
||||
telnet->opt_states[o_echo.index] = REQUESTED;
|
||||
send_opt(telnet, o_echo.nsend, o_echo.option);
|
||||
}
|
||||
break;
|
||||
case TS_PING:
|
||||
case SS_PING:
|
||||
if (telnet->opt_states[o_they_sga.index] == ACTIVE) {
|
||||
b[1] = NOP;
|
||||
telnet->bufsize = sk_write(telnet->s, b, 2);
|
||||
@ -1009,25 +996,25 @@ static void telnet_special(Backend *be, Telnet_Special code)
|
||||
}
|
||||
}
|
||||
|
||||
static const struct telnet_special *telnet_get_specials(Backend *be)
|
||||
static const SessionSpecial *telnet_get_specials(Backend *be)
|
||||
{
|
||||
static const struct telnet_special specials[] = {
|
||||
{"Are You There", TS_AYT},
|
||||
{"Break", TS_BRK},
|
||||
{"Synch", TS_SYNCH},
|
||||
{"Erase Character", TS_EC},
|
||||
{"Erase Line", TS_EL},
|
||||
{"Go Ahead", TS_GA},
|
||||
{"No Operation", TS_NOP},
|
||||
{NULL, TS_SEP},
|
||||
{"Abort Process", TS_ABORT},
|
||||
{"Abort Output", TS_AO},
|
||||
{"Interrupt Process", TS_IP},
|
||||
{"Suspend Process", TS_SUSP},
|
||||
{NULL, TS_SEP},
|
||||
{"End Of Record", TS_EOR},
|
||||
{"End Of File", TS_EOF},
|
||||
{NULL, TS_EXITMENU}
|
||||
static const SessionSpecial specials[] = {
|
||||
{"Are You There", SS_AYT},
|
||||
{"Break", SS_BRK},
|
||||
{"Synch", SS_SYNCH},
|
||||
{"Erase Character", SS_EC},
|
||||
{"Erase Line", SS_EL},
|
||||
{"Go Ahead", SS_GA},
|
||||
{"No Operation", SS_NOP},
|
||||
{NULL, SS_SEP},
|
||||
{"Abort Process", SS_ABORT},
|
||||
{"Abort Output", SS_AO},
|
||||
{"Interrupt Process", SS_IP},
|
||||
{"Suspend Process", SS_SUSP},
|
||||
{NULL, SS_SEP},
|
||||
{"End Of Record", SS_EOR},
|
||||
{"End Of File", SS_EOF},
|
||||
{NULL, SS_EXITMENU}
|
||||
};
|
||||
return specials;
|
||||
}
|
||||
|
@ -43,8 +43,8 @@ static int null_send(Backend *, const char *, int);
|
||||
static int loop_send(Backend *, const char *, int);
|
||||
static int null_sendbuffer(Backend *);
|
||||
static void null_size(Backend *, int, int);
|
||||
static void null_special(Backend *, Telnet_Special);
|
||||
static const struct telnet_special *null_get_specials(Backend *);
|
||||
static void null_special(Backend *, SessionSpecialCode, int);
|
||||
static const SessionSpecial *null_get_specials(Backend *);
|
||||
static int null_connected(Backend *);
|
||||
static int null_exitcode(Backend *);
|
||||
static int null_sendok(Backend *);
|
||||
@ -126,11 +126,11 @@ static void null_size(Backend *be, int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
static void null_special(Backend *be, Telnet_Special code) {
|
||||
static void null_special(Backend *be, SessionSpecialCode code, int arg) {
|
||||
|
||||
}
|
||||
|
||||
static const struct telnet_special *null_get_specials (Backend *be) {
|
||||
static const SessionSpecial *null_get_specials (Backend *be) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#define g_signal_handler_disconnect gtk_signal_disconnect
|
||||
#define g_object_get_data gtk_object_get_data
|
||||
#define g_object_set_data gtk_object_set_data
|
||||
#define g_object_set_data_full gtk_object_set_data_full
|
||||
#define g_object_ref_sink gtk_object_sink
|
||||
|
||||
#define GDK_GRAB_SUCCESS GrabSuccess
|
||||
|
@ -1573,10 +1573,10 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
||||
if (event->keyval == GDK_KEY_Break &&
|
||||
(event->state & GDK_CONTROL_MASK)) {
|
||||
#ifdef KEY_EVENT_DIAGNOSTICS
|
||||
debug((" - Ctrl-Break special case, sending TS_BRK\n"));
|
||||
debug((" - Ctrl-Break special case, sending SS_BRK\n"));
|
||||
#endif
|
||||
if (inst->backend)
|
||||
backend_special(inst->backend, TS_BRK);
|
||||
backend_special(inst->backend, SS_BRK, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -4414,11 +4414,10 @@ void copy_all_menuitem(GtkMenuItem *item, gpointer data)
|
||||
void special_menuitem(GtkMenuItem *item, gpointer data)
|
||||
{
|
||||
Frontend *inst = (Frontend *)data;
|
||||
int code = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item),
|
||||
"user-data"));
|
||||
SessionSpecial *sc = g_object_get_data(G_OBJECT(item), "user-data");
|
||||
|
||||
if (inst->backend)
|
||||
backend_special(inst->backend, code);
|
||||
backend_special(inst->backend, sc->code, sc->arg);
|
||||
}
|
||||
|
||||
void about_menuitem(GtkMenuItem *item, gpointer data)
|
||||
@ -4915,9 +4914,11 @@ void set_window_icon(GtkWidget *window, const char *const *const *icon,
|
||||
#endif
|
||||
}
|
||||
|
||||
static void free_special_cmd(gpointer data) { sfree(data); }
|
||||
|
||||
void update_specials_menu(Frontend *inst)
|
||||
{
|
||||
const struct telnet_special *specials;
|
||||
const SessionSpecial *specials;
|
||||
|
||||
if (inst->backend)
|
||||
specials = backend_get_specials(inst->backend);
|
||||
@ -4936,7 +4937,7 @@ void update_specials_menu(Frontend *inst)
|
||||
for (i = 0; nesting > 0; i++) {
|
||||
GtkWidget *menuitem = NULL;
|
||||
switch (specials[i].code) {
|
||||
case TS_SUBMENU:
|
||||
case SS_SUBMENU:
|
||||
assert (nesting < 2);
|
||||
saved_menu = menu; /* XXX lame stacking */
|
||||
menu = gtk_menu_new();
|
||||
@ -4947,20 +4948,24 @@ void update_specials_menu(Frontend *inst)
|
||||
menuitem = NULL;
|
||||
nesting++;
|
||||
break;
|
||||
case TS_EXITMENU:
|
||||
case SS_EXITMENU:
|
||||
nesting--;
|
||||
if (nesting) {
|
||||
menu = saved_menu; /* XXX lame stacking */
|
||||
saved_menu = NULL;
|
||||
}
|
||||
break;
|
||||
case TS_SEP:
|
||||
case SS_SEP:
|
||||
menuitem = gtk_menu_item_new();
|
||||
break;
|
||||
default:
|
||||
menuitem = gtk_menu_item_new_with_label(specials[i].name);
|
||||
g_object_set_data(G_OBJECT(menuitem), "user-data",
|
||||
GINT_TO_POINTER(specials[i].code));
|
||||
{
|
||||
SessionSpecial *sc = snew(SessionSpecial);
|
||||
*sc = specials[i]; /* structure copy */
|
||||
g_object_set_data_full(G_OBJECT(menuitem), "user-data",
|
||||
sc, free_special_cmd);
|
||||
}
|
||||
g_signal_connect(G_OBJECT(menuitem), "activate",
|
||||
G_CALLBACK(special_menuitem), inst);
|
||||
break;
|
||||
|
@ -464,7 +464,7 @@ static void from_tty(void *vbuf, unsigned len)
|
||||
break;
|
||||
case FF00:
|
||||
if (*p == '\0') {
|
||||
backend_special(backend, TS_BRK);
|
||||
backend_special(backend, SS_BRK, 0);
|
||||
} else {
|
||||
/*
|
||||
* Pretend that PARMRK wasn't set. This involves
|
||||
@ -991,7 +991,7 @@ int main(int argc, char **argv)
|
||||
perror("stdin: read");
|
||||
exit(1);
|
||||
} else if (ret == 0) {
|
||||
backend_special(backend, TS_EOF);
|
||||
backend_special(backend, SS_EOF, 0);
|
||||
sending = FALSE; /* send nothing further after this */
|
||||
} else {
|
||||
if (local_tty)
|
||||
|
@ -1159,7 +1159,7 @@ static void pty_size(Backend *be, int width, int height)
|
||||
/*
|
||||
* Send special codes.
|
||||
*/
|
||||
static void pty_special(Backend *be, Telnet_Special code)
|
||||
static void pty_special(Backend *be, SessionSpecialCode code, int arg)
|
||||
{
|
||||
/* Pty pty = FROMFIELD(be, struct pty_tag, backend); */
|
||||
/* Do nothing! */
|
||||
@ -1170,7 +1170,7 @@ static void pty_special(Backend *be, Telnet_Special code)
|
||||
* Return a list of the special codes that make sense in this
|
||||
* protocol.
|
||||
*/
|
||||
static const struct telnet_special *pty_get_specials(Backend *be)
|
||||
static const SessionSpecial *pty_get_specials(Backend *be)
|
||||
{
|
||||
/* Pty pty = FROMFIELD(be, struct pty_tag, backend); */
|
||||
/*
|
||||
|
12
unix/uxser.c
12
unix/uxser.c
@ -496,11 +496,11 @@ static void serial_size(Backend *be, int width, int height)
|
||||
/*
|
||||
* Send serial special codes.
|
||||
*/
|
||||
static void serial_special(Backend *be, Telnet_Special code)
|
||||
static void serial_special(Backend *be, SessionSpecialCode code, int arg)
|
||||
{
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
|
||||
if (serial->fd >= 0 && code == TS_BRK) {
|
||||
if (serial->fd >= 0 && code == SS_BRK) {
|
||||
tcsendbreak(serial->fd, 0);
|
||||
logevent(serial->frontend, "Sending serial break at user request");
|
||||
}
|
||||
@ -512,11 +512,11 @@ static void serial_special(Backend *be, Telnet_Special code)
|
||||
* Return a list of the special codes that make sense in this
|
||||
* protocol.
|
||||
*/
|
||||
static const struct telnet_special *serial_get_specials(Backend *be)
|
||||
static const SessionSpecial *serial_get_specials(Backend *be)
|
||||
{
|
||||
static const struct telnet_special specials[] = {
|
||||
{"Break", TS_BRK},
|
||||
{NULL, TS_EXITMENU}
|
||||
static const struct SessionSpecial specials[] = {
|
||||
{"Break", SS_BRK},
|
||||
{NULL, SS_EXITMENU}
|
||||
};
|
||||
return specials;
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ static struct unicode_data ucsdata;
|
||||
static int session_closed;
|
||||
static int reconfiguring = FALSE;
|
||||
|
||||
static const struct telnet_special *specials = NULL;
|
||||
static const SessionSpecial *specials = NULL;
|
||||
static HMENU specials_menu = NULL;
|
||||
static int n_specials = 0;
|
||||
|
||||
@ -965,10 +965,10 @@ void update_specials_menu(Frontend *frontend)
|
||||
for (i = 0; nesting > 0; i++) {
|
||||
assert(IDM_SPECIAL_MIN + 0x10 * i < IDM_SPECIAL_MAX);
|
||||
switch (specials[i].code) {
|
||||
case TS_SEP:
|
||||
case SS_SEP:
|
||||
AppendMenu(new_menu, MF_SEPARATOR, 0, 0);
|
||||
break;
|
||||
case TS_SUBMENU:
|
||||
case SS_SUBMENU:
|
||||
assert(nesting < 2);
|
||||
nesting++;
|
||||
saved_menu = new_menu; /* XXX lame stacking */
|
||||
@ -976,7 +976,7 @@ void update_specials_menu(Frontend *frontend)
|
||||
AppendMenu(saved_menu, MF_POPUP | MF_ENABLED,
|
||||
(UINT_PTR) new_menu, specials[i].name);
|
||||
break;
|
||||
case TS_EXITMENU:
|
||||
case SS_EXITMENU:
|
||||
nesting--;
|
||||
if (nesting) {
|
||||
new_menu = saved_menu; /* XXX lame stacking */
|
||||
@ -2415,7 +2415,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
||||
if (i >= n_specials)
|
||||
break;
|
||||
if (backend)
|
||||
backend_special(backend, specials[i].code);
|
||||
backend_special(
|
||||
backend, specials[i].code, specials[i].arg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -4406,7 +4407,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
|
||||
}
|
||||
if (wParam == VK_CANCEL && shift_state == 2) { /* Ctrl-Break */
|
||||
if (backend)
|
||||
backend_special(backend, TS_BRK);
|
||||
backend_special(backend, SS_BRK, 0);
|
||||
return 0;
|
||||
}
|
||||
if (wParam == VK_PAUSE) { /* Break/Pause */
|
||||
|
@ -247,7 +247,7 @@ int stdin_gotdata(struct handle *h, void *data, int len)
|
||||
if (len > 0) {
|
||||
return backend_send(backend, data, len);
|
||||
} else {
|
||||
backend_special(backend, TS_EOF);
|
||||
backend_special(backend, SS_EOF, 0);
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
|
@ -348,11 +348,11 @@ static void serbreak_timer(void *ctx, unsigned long now)
|
||||
/*
|
||||
* Send serial special codes.
|
||||
*/
|
||||
static void serial_special(Backend *be, Telnet_Special code)
|
||||
static void serial_special(Backend *be, SessionSpecialCode code, int arg)
|
||||
{
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
|
||||
if (serial->port && code == TS_BRK) {
|
||||
if (serial->port && code == SS_BRK) {
|
||||
logevent(serial->frontend, "Starting serial break at user request");
|
||||
SetCommBreak(serial->port);
|
||||
/*
|
||||
@ -377,11 +377,11 @@ static void serial_special(Backend *be, Telnet_Special code)
|
||||
* Return a list of the special codes that make sense in this
|
||||
* protocol.
|
||||
*/
|
||||
static const struct telnet_special *serial_get_specials(Backend *be)
|
||||
static const SessionSpecial *serial_get_specials(Backend *be)
|
||||
{
|
||||
static const struct telnet_special specials[] = {
|
||||
{"Break", TS_BRK},
|
||||
{NULL, TS_EXITMENU}
|
||||
static const SessionSpecial specials[] = {
|
||||
{"Break", SS_BRK},
|
||||
{NULL, SS_EXITMENU}
|
||||
};
|
||||
return specials;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user