mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Turn Backend into a sensible classoid.
Nearly every part of the code that ever handles a full backend structure has historically done it using a pair of pointer variables, one pointing at a constant struct full of function pointers, and the other pointing to a 'void *' state object that's passed to each of those. While I'm modernising the rest of the code, this seems like a good time to turn that into the same more or less type-safe and less cumbersome system as I'm using for other parts of the code, such as Socket, Plug, BinaryPacketProtocol and so forth: the Backend structure contains a vtable pointer, and a system of macro wrappers handles dispatching through that vtable.
This commit is contained in:
parent
c51fe7c217
commit
eefebaaa9e
2
be_all.c
2
be_all.c
@ -22,7 +22,7 @@ const int be_default_protocol = PROT_TELNET;
|
||||
const int be_default_protocol = PROT_SSH;
|
||||
#endif
|
||||
|
||||
Backend *backends[] = {
|
||||
const struct Backend_vtable *const backends[] = {
|
||||
&ssh_backend,
|
||||
&telnet_backend,
|
||||
&rlogin_backend,
|
||||
|
@ -22,7 +22,7 @@ const int be_default_protocol = PROT_TELNET;
|
||||
const int be_default_protocol = PROT_SSH;
|
||||
#endif
|
||||
|
||||
Backend *backends[] = {
|
||||
const struct Backend_vtable *const backends[] = {
|
||||
&ssh_backend,
|
||||
&telnet_backend,
|
||||
&rlogin_backend,
|
||||
|
@ -6,6 +6,6 @@
|
||||
#include <stdio.h>
|
||||
#include "putty.h"
|
||||
|
||||
Backend *backends[] = {
|
||||
const struct Backend_vtable *const backends[] = {
|
||||
NULL
|
||||
};
|
||||
|
@ -10,7 +10,7 @@ const int be_default_protocol = PROT_TELNET;
|
||||
|
||||
const char *const appname = "PuTTYtel";
|
||||
|
||||
Backend *backends[] = {
|
||||
const struct Backend_vtable *const backends[] = {
|
||||
&telnet_backend,
|
||||
&rlogin_backend,
|
||||
&raw_backend,
|
||||
|
@ -10,7 +10,7 @@ const int be_default_protocol = PROT_TELNET;
|
||||
|
||||
const char *const appname = "PuTTYtel";
|
||||
|
||||
Backend *backends[] = {
|
||||
const struct Backend_vtable *const backends[] = {
|
||||
&telnet_backend,
|
||||
&rlogin_backend,
|
||||
&raw_backend,
|
||||
|
2
be_ssh.c
2
be_ssh.c
@ -10,7 +10,7 @@
|
||||
|
||||
const int be_default_protocol = PROT_SSH;
|
||||
|
||||
Backend *backends[] = {
|
||||
const struct Backend_vtable *const backends[] = {
|
||||
&ssh_backend,
|
||||
NULL
|
||||
};
|
||||
|
@ -275,13 +275,14 @@ int cmdline_process_param(const char *p, char *value,
|
||||
const char *comma = strchr(p, ',');
|
||||
if (comma) {
|
||||
char *prefix = dupprintf("%.*s", (int)(comma - p), p);
|
||||
const Backend *b = backend_from_name(prefix);
|
||||
const struct Backend_vtable *vt =
|
||||
backend_vt_from_name(prefix);
|
||||
|
||||
if (b) {
|
||||
default_protocol = b->protocol;
|
||||
if (vt) {
|
||||
default_protocol = vt->protocol;
|
||||
conf_set_int(conf, CONF_protocol,
|
||||
default_protocol);
|
||||
port_override = b->default_port;
|
||||
port_override = vt->default_port;
|
||||
} else {
|
||||
cmdline_error("unrecognised protocol prefix '%s'",
|
||||
prefix);
|
||||
|
23
config.c
23
config.c
@ -267,10 +267,10 @@ void config_protocolbuttons_handler(union control *ctrl, void *dlg,
|
||||
conf_set_int(conf, CONF_protocol, newproto);
|
||||
|
||||
if (oldproto != newproto) {
|
||||
Backend *ob = backend_from_proto(oldproto);
|
||||
Backend *nb = backend_from_proto(newproto);
|
||||
assert(ob);
|
||||
assert(nb);
|
||||
const struct Backend_vtable *ovt = backend_vt_from_proto(oldproto);
|
||||
const struct Backend_vtable *nvt = backend_vt_from_proto(newproto);
|
||||
assert(ovt);
|
||||
assert(nvt);
|
||||
/* Iff the user hasn't changed the port from the old protocol's
|
||||
* default, update it with the new protocol's default.
|
||||
* (This includes a "default" of 0, implying that there is no
|
||||
@ -281,8 +281,8 @@ void config_protocolbuttons_handler(union control *ctrl, void *dlg,
|
||||
* getting to the protocol; we want that non-default port
|
||||
* to be preserved. */
|
||||
port = conf_get_int(conf, CONF_port);
|
||||
if (port == ob->default_port)
|
||||
conf_set_int(conf, CONF_port, nb->default_port);
|
||||
if (port == ovt->default_port)
|
||||
conf_set_int(conf, CONF_port, nvt->default_port);
|
||||
}
|
||||
dlg_refresh(hp->host, dlg);
|
||||
dlg_refresh(hp->port, dlg);
|
||||
@ -1503,7 +1503,7 @@ void setup_config_box(struct controlbox *b, int midsession,
|
||||
hp->port = c;
|
||||
ctrl_columns(s, 1, 100);
|
||||
|
||||
if (!backend_from_proto(PROT_SSH)) {
|
||||
if (!backend_vt_from_proto(PROT_SSH)) {
|
||||
ctrl_radiobuttons(s, "Connection type:", NO_SHORTCUT, 3,
|
||||
HELPCTX(session_hostname),
|
||||
config_protocolbuttons_handler, P(hp),
|
||||
@ -1594,7 +1594,7 @@ void setup_config_box(struct controlbox *b, int midsession,
|
||||
{
|
||||
const char *sshlogname, *sshrawlogname;
|
||||
if ((midsession && protocol == PROT_SSH) ||
|
||||
(!midsession && backend_from_proto(PROT_SSH))) {
|
||||
(!midsession && backend_vt_from_proto(PROT_SSH))) {
|
||||
sshlogname = "SSH packets";
|
||||
sshrawlogname = "SSH packets and raw data";
|
||||
} else {
|
||||
@ -1630,7 +1630,7 @@ void setup_config_box(struct controlbox *b, int midsession,
|
||||
conf_checkbox_handler, I(CONF_logflush));
|
||||
|
||||
if ((midsession && protocol == PROT_SSH) ||
|
||||
(!midsession && backend_from_proto(PROT_SSH))) {
|
||||
(!midsession && backend_vt_from_proto(PROT_SSH))) {
|
||||
s = ctrl_getset(b, "Session/Logging", "ssh",
|
||||
"Options specific to SSH packet logging");
|
||||
ctrl_checkbox(s, "Omit known password fields", 'k',
|
||||
@ -2107,7 +2107,7 @@ void setup_config_box(struct controlbox *b, int midsession,
|
||||
#endif
|
||||
|
||||
{
|
||||
const char *label = backend_from_proto(PROT_SSH) ?
|
||||
const char *label = backend_vt_from_proto(PROT_SSH) ?
|
||||
"Logical name of remote host (e.g. for SSH key lookup):" :
|
||||
"Logical name of remote host:";
|
||||
s = ctrl_getset(b, "Connection", "identity",
|
||||
@ -2319,7 +2319,8 @@ void setup_config_box(struct controlbox *b, int midsession,
|
||||
* when we're not doing SSH.
|
||||
*/
|
||||
|
||||
if (backend_from_proto(PROT_SSH) && (!midsession || protocol == PROT_SSH)) {
|
||||
if (backend_vt_from_proto(PROT_SSH) &&
|
||||
(!midsession || protocol == PROT_SSH)) {
|
||||
|
||||
/*
|
||||
* The Connection/SSH panel.
|
||||
|
5
defs.h
5
defs.h
@ -21,7 +21,6 @@
|
||||
#endif
|
||||
|
||||
typedef struct conf_tag Conf;
|
||||
typedef struct backend_tag Backend;
|
||||
typedef struct terminal_tag Terminal;
|
||||
|
||||
typedef struct Filename Filename;
|
||||
@ -44,10 +43,14 @@ typedef struct SockAddr_tag *SockAddr;
|
||||
typedef struct Socket_vtable Socket_vtable;
|
||||
typedef struct Plug_vtable Plug_vtable;
|
||||
|
||||
typedef struct Backend Backend;
|
||||
typedef struct Backend_vtable Backend_vtable;
|
||||
|
||||
typedef struct Ldisc_tag Ldisc;
|
||||
typedef struct LogContext_tag LogContext;
|
||||
|
||||
typedef struct ssh_tag *Ssh;
|
||||
|
||||
/* 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
|
||||
|
55
ldisc.c
55
ldisc.c
@ -15,11 +15,11 @@
|
||||
|
||||
#define ECHOING (ldisc->localecho == FORCE_ON || \
|
||||
(ldisc->localecho == AUTO && \
|
||||
(ldisc->back->ldisc(ldisc->backhandle, LD_ECHO) || \
|
||||
(backend_ldisc_option_state(ldisc->backend, LD_ECHO) || \
|
||||
term_ldisc(ldisc->term, LD_ECHO))))
|
||||
#define EDITING (ldisc->localedit == FORCE_ON || \
|
||||
(ldisc->localedit == AUTO && \
|
||||
(ldisc->back->ldisc(ldisc->backhandle, LD_EDIT) || \
|
||||
(backend_ldisc_option_state(ldisc->backend, LD_EDIT) || \
|
||||
term_ldisc(ldisc->term, LD_EDIT))))
|
||||
|
||||
static void c_write(Ldisc *ldisc, const void *buf, int len)
|
||||
@ -78,8 +78,7 @@ static void bsb(Ldisc *ldisc, int n)
|
||||
#define KCTRL(x) ((x^'@') | 0x100)
|
||||
|
||||
Ldisc *ldisc_create(Conf *conf, Terminal *term,
|
||||
Backend *back, void *backhandle,
|
||||
void *frontend)
|
||||
Backend *backend, void *frontend)
|
||||
{
|
||||
Ldisc *ldisc = snew(Ldisc);
|
||||
|
||||
@ -88,8 +87,7 @@ Ldisc *ldisc_create(Conf *conf, Terminal *term,
|
||||
ldisc->bufsiz = 0;
|
||||
ldisc->quotenext = 0;
|
||||
|
||||
ldisc->back = back;
|
||||
ldisc->backhandle = backhandle;
|
||||
ldisc->backend = backend;
|
||||
ldisc->term = term;
|
||||
ldisc->frontend = frontend;
|
||||
|
||||
@ -98,8 +96,8 @@ Ldisc *ldisc_create(Conf *conf, Terminal *term,
|
||||
/* Link ourselves into the backend and the terminal */
|
||||
if (term)
|
||||
term->ldisc = ldisc;
|
||||
if (back)
|
||||
back->provide_ldisc(backhandle, ldisc);
|
||||
if (backend)
|
||||
backend_provide_ldisc(backend, ldisc);
|
||||
|
||||
return ldisc;
|
||||
}
|
||||
@ -117,8 +115,8 @@ void ldisc_free(Ldisc *ldisc)
|
||||
{
|
||||
if (ldisc->term)
|
||||
ldisc->term->ldisc = NULL;
|
||||
if (ldisc->back)
|
||||
ldisc->back->provide_ldisc(ldisc->backhandle, NULL);
|
||||
if (ldisc->backend)
|
||||
backend_provide_ldisc(ldisc->backend, NULL);
|
||||
if (ldisc->buf)
|
||||
sfree(ldisc->buf);
|
||||
sfree(ldisc);
|
||||
@ -219,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--;
|
||||
}
|
||||
ldisc->back->special(ldisc->backhandle, TS_EL);
|
||||
backend_special(ldisc->backend, TS_EL);
|
||||
/*
|
||||
* We don't send IP, SUSP or ABORT if the user has
|
||||
* configured telnet specials off! This breaks
|
||||
@ -228,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'))
|
||||
ldisc->back->special(ldisc->backhandle, TS_IP);
|
||||
backend_special(ldisc->backend, TS_IP);
|
||||
if (c == CTRL('Z'))
|
||||
ldisc->back->special(ldisc->backhandle, TS_SUSP);
|
||||
backend_special(ldisc->backend, TS_SUSP);
|
||||
if (c == CTRL('\\'))
|
||||
ldisc->back->special(ldisc->backhandle, TS_ABORT);
|
||||
backend_special(ldisc->backend, TS_ABORT);
|
||||
break;
|
||||
case CTRL('R'): /* redraw line */
|
||||
if (ECHOING) {
|
||||
@ -247,9 +245,9 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
|
||||
break;
|
||||
case CTRL('D'): /* logout or send */
|
||||
if (ldisc->buflen == 0) {
|
||||
ldisc->back->special(ldisc->backhandle, TS_EOF);
|
||||
backend_special(ldisc->backend, TS_EOF);
|
||||
} else {
|
||||
ldisc->back->send(ldisc->backhandle, ldisc->buf, ldisc->buflen);
|
||||
backend_send(ldisc->backend, ldisc->buf, ldisc->buflen);
|
||||
ldisc->buflen = 0;
|
||||
}
|
||||
break;
|
||||
@ -285,13 +283,14 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
|
||||
/* FALLTHROUGH */
|
||||
case KCTRL('M'): /* send with newline */
|
||||
if (ldisc->buflen > 0)
|
||||
ldisc->back->send(ldisc->backhandle, ldisc->buf, ldisc->buflen);
|
||||
backend_send(ldisc->backend,
|
||||
ldisc->buf, ldisc->buflen);
|
||||
if (ldisc->protocol == PROT_RAW)
|
||||
ldisc->back->send(ldisc->backhandle, "\r\n", 2);
|
||||
backend_send(ldisc->backend, "\r\n", 2);
|
||||
else if (ldisc->protocol == PROT_TELNET && ldisc->telnet_newline)
|
||||
ldisc->back->special(ldisc->backhandle, TS_EOL);
|
||||
backend_special(ldisc->backend, TS_EOL);
|
||||
else
|
||||
ldisc->back->send(ldisc->backhandle, "\r", 1);
|
||||
backend_send(ldisc->backend, "\r", 1);
|
||||
if (ECHOING)
|
||||
c_write(ldisc, "\r\n", 2);
|
||||
ldisc->buflen = 0;
|
||||
@ -313,7 +312,7 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
|
||||
}
|
||||
} else {
|
||||
if (ldisc->buflen != 0) {
|
||||
ldisc->back->send(ldisc->backhandle, ldisc->buf, ldisc->buflen);
|
||||
backend_send(ldisc->backend, ldisc->buf, ldisc->buflen);
|
||||
while (ldisc->buflen > 0) {
|
||||
bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
|
||||
ldisc->buflen--;
|
||||
@ -326,33 +325,33 @@ 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)
|
||||
ldisc->back->special(ldisc->backhandle, TS_EOL);
|
||||
backend_special(ldisc->backend, TS_EOL);
|
||||
else
|
||||
ldisc->back->send(ldisc->backhandle, "\r", 1);
|
||||
backend_send(ldisc->backend, "\r", 1);
|
||||
break;
|
||||
case CTRL('?'):
|
||||
case CTRL('H'):
|
||||
if (ldisc->telnet_keyboard) {
|
||||
ldisc->back->special(ldisc->backhandle, TS_EC);
|
||||
backend_special(ldisc->backend, TS_EC);
|
||||
break;
|
||||
}
|
||||
case CTRL('C'):
|
||||
if (ldisc->telnet_keyboard) {
|
||||
ldisc->back->special(ldisc->backhandle, TS_IP);
|
||||
backend_special(ldisc->backend, TS_IP);
|
||||
break;
|
||||
}
|
||||
case CTRL('Z'):
|
||||
if (ldisc->telnet_keyboard) {
|
||||
ldisc->back->special(ldisc->backhandle, TS_SUSP);
|
||||
backend_special(ldisc->backend, TS_SUSP);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ldisc->back->send(ldisc->backhandle, buf, len);
|
||||
backend_send(ldisc->backend, buf, len);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
ldisc->back->send(ldisc->backhandle, buf, len);
|
||||
backend_send(ldisc->backend, buf, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
3
ldisc.h
3
ldisc.h
@ -10,8 +10,7 @@
|
||||
|
||||
struct Ldisc_tag {
|
||||
Terminal *term;
|
||||
Backend *back;
|
||||
void *backhandle;
|
||||
Backend *backend;
|
||||
void *frontend;
|
||||
|
||||
/*
|
||||
|
10
pinger.c
10
pinger.c
@ -9,8 +9,7 @@ struct pinger_tag {
|
||||
int interval;
|
||||
int pending;
|
||||
unsigned long when_set, next;
|
||||
Backend *back;
|
||||
void *backhandle;
|
||||
Backend *backend;
|
||||
};
|
||||
|
||||
static void pinger_schedule(Pinger pinger);
|
||||
@ -20,7 +19,7 @@ static void pinger_timer(void *ctx, unsigned long now)
|
||||
Pinger pinger = (Pinger)ctx;
|
||||
|
||||
if (pinger->pending && now == pinger->next) {
|
||||
pinger->back->special(pinger->backhandle, TS_PING);
|
||||
backend_special(pinger->backend, TS_PING);
|
||||
pinger->pending = FALSE;
|
||||
pinger_schedule(pinger);
|
||||
}
|
||||
@ -45,14 +44,13 @@ static void pinger_schedule(Pinger pinger)
|
||||
}
|
||||
}
|
||||
|
||||
Pinger pinger_new(Conf *conf, Backend *back, void *backhandle)
|
||||
Pinger pinger_new(Conf *conf, Backend *backend)
|
||||
{
|
||||
Pinger pinger = snew(struct pinger_tag);
|
||||
|
||||
pinger->interval = conf_get_int(conf, CONF_ping_interval);
|
||||
pinger->pending = FALSE;
|
||||
pinger->back = back;
|
||||
pinger->backhandle = backhandle;
|
||||
pinger->backend = backend;
|
||||
pinger_schedule(pinger);
|
||||
|
||||
return pinger;
|
||||
|
80
pscp.c
80
pscp.c
@ -43,8 +43,7 @@ static int fallback_cmd_is_sftp = 0;
|
||||
static int using_sftp = 0;
|
||||
static int uploading = 0;
|
||||
|
||||
static Backend *back;
|
||||
static void *backhandle;
|
||||
static Backend *backend;
|
||||
static Conf *conf;
|
||||
int sent_eof = FALSE;
|
||||
|
||||
@ -247,7 +246,7 @@ static int ssh_scp_recv(void *buf, int len)
|
||||
}
|
||||
|
||||
while (outlen > 0) {
|
||||
if (back->exitcode(backhandle) >= 0 || ssh_sftp_loop_iteration() < 0)
|
||||
if (backend_exitcode(backend) >= 0 || ssh_sftp_loop_iteration() < 0)
|
||||
return 0; /* doom */
|
||||
}
|
||||
|
||||
@ -259,8 +258,8 @@ static int ssh_scp_recv(void *buf, int len)
|
||||
*/
|
||||
static void ssh_scp_init(void)
|
||||
{
|
||||
while (!back->sendok(backhandle)) {
|
||||
if (back->exitcode(backhandle) >= 0) {
|
||||
while (!backend_sendok(backend)) {
|
||||
if (backend_exitcode(backend) >= 0) {
|
||||
errs++;
|
||||
return;
|
||||
}
|
||||
@ -271,7 +270,7 @@ static void ssh_scp_init(void)
|
||||
}
|
||||
|
||||
/* Work out which backend we ended up using. */
|
||||
if (!ssh_fallback_cmd(backhandle))
|
||||
if (!ssh_fallback_cmd(backend))
|
||||
using_sftp = main_cmd_is_sftp;
|
||||
else
|
||||
using_sftp = fallback_cmd_is_sftp;
|
||||
@ -300,9 +299,9 @@ static void bump(const char *fmt, ...)
|
||||
sfree(str2);
|
||||
errs++;
|
||||
|
||||
if (back != NULL && back->connected(backhandle)) {
|
||||
if (backend && backend_connected(backend)) {
|
||||
char ch;
|
||||
back->special(backhandle, TS_EOF);
|
||||
backend_special(backend, TS_EOF);
|
||||
sent_eof = TRUE;
|
||||
ssh_scp_recv(&ch, 1);
|
||||
}
|
||||
@ -498,21 +497,19 @@ static void do_cmd(char *host, char *user, char *cmd)
|
||||
}
|
||||
conf_set_int(conf, CONF_nopty, TRUE);
|
||||
|
||||
back = &ssh_backend;
|
||||
|
||||
logctx = log_init(NULL, conf);
|
||||
console_provide_logctx(logctx);
|
||||
|
||||
platform_psftp_pre_conn_setup();
|
||||
|
||||
err = back->init(NULL, &backhandle, conf,
|
||||
conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port),
|
||||
&realhost, 0,
|
||||
conf_get_int(conf, CONF_tcp_keepalives));
|
||||
err = backend_init(&ssh_backend, NULL, &backend, conf,
|
||||
conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port),
|
||||
&realhost, 0,
|
||||
conf_get_int(conf, CONF_tcp_keepalives));
|
||||
if (err != NULL)
|
||||
bump("ssh_init: %s", err);
|
||||
back->provide_logctx(backhandle, logctx);
|
||||
backend_provide_logctx(backend, logctx);
|
||||
ssh_scp_init();
|
||||
if (verbose && realhost != NULL && errs == 0)
|
||||
tell_user(stderr, "Connected to %s", realhost);
|
||||
@ -644,12 +641,12 @@ int sftp_recvdata(char *buf, int len)
|
||||
}
|
||||
int sftp_senddata(char *buf, int len)
|
||||
{
|
||||
back->send(backhandle, buf, len);
|
||||
backend_send(backend, buf, len);
|
||||
return 1;
|
||||
}
|
||||
int sftp_sendbuffer(void)
|
||||
{
|
||||
return back->sendbuffer(backhandle);
|
||||
return backend_sendbuffer(backend);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -806,8 +803,8 @@ int scp_send_errmsg(char *str)
|
||||
if (using_sftp) {
|
||||
/* do nothing; we never need to send our errors to the server */
|
||||
} else {
|
||||
back->send(backhandle, "\001", 1);/* scp protocol error prefix */
|
||||
back->send(backhandle, str, strlen(str));
|
||||
backend_send(backend, "\001", 1);/* scp protocol error prefix */
|
||||
backend_send(backend, str, strlen(str));
|
||||
}
|
||||
return 0; /* can't fail */
|
||||
}
|
||||
@ -822,7 +819,7 @@ int scp_send_filetimes(unsigned long mtime, unsigned long atime)
|
||||
} else {
|
||||
char buf[80];
|
||||
sprintf(buf, "T%lu 0 %lu 0\n", mtime, atime);
|
||||
back->send(backhandle, buf, strlen(buf));
|
||||
backend_send(backend, buf, strlen(buf));
|
||||
return response();
|
||||
}
|
||||
}
|
||||
@ -869,9 +866,9 @@ int scp_send_filename(const char *name, uint64 size, int permissions)
|
||||
if (permissions < 0)
|
||||
permissions = 0644;
|
||||
sprintf(buf, "C%04o %s ", (int)(permissions & 07777), sizestr);
|
||||
back->send(backhandle, buf, strlen(buf));
|
||||
back->send(backhandle, name, strlen(name));
|
||||
back->send(backhandle, "\n", 1);
|
||||
backend_send(backend, buf, strlen(buf));
|
||||
backend_send(backend, name, strlen(name));
|
||||
backend_send(backend, "\n", 1);
|
||||
return response();
|
||||
}
|
||||
}
|
||||
@ -903,7 +900,7 @@ int scp_send_filedata(char *data, int len)
|
||||
scp_sftp_fileoffset = uint64_add32(scp_sftp_fileoffset, len);
|
||||
return 0;
|
||||
} else {
|
||||
int bufsize = back->send(backhandle, data, len);
|
||||
int bufsize = backend_send(backend, data, len);
|
||||
|
||||
/*
|
||||
* If the network transfer is backing up - that is, the
|
||||
@ -914,7 +911,7 @@ int scp_send_filedata(char *data, int len)
|
||||
while (bufsize > MAX_SCP_BUFSIZE) {
|
||||
if (ssh_sftp_loop_iteration() < 0)
|
||||
return 1;
|
||||
bufsize = back->sendbuffer(backhandle);
|
||||
bufsize = backend_sendbuffer(backend);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -963,7 +960,7 @@ int scp_send_finish(void)
|
||||
scp_has_times = 0;
|
||||
return 0;
|
||||
} else {
|
||||
back->send(backhandle, "", 1);
|
||||
backend_send(backend, "", 1);
|
||||
return response();
|
||||
}
|
||||
}
|
||||
@ -1033,9 +1030,9 @@ int scp_send_dirname(const char *name, int modes)
|
||||
} else {
|
||||
char buf[40];
|
||||
sprintf(buf, "D%04o 0 ", modes);
|
||||
back->send(backhandle, buf, strlen(buf));
|
||||
back->send(backhandle, name, strlen(name));
|
||||
back->send(backhandle, "\n", 1);
|
||||
backend_send(backend, buf, strlen(buf));
|
||||
backend_send(backend, name, strlen(name));
|
||||
backend_send(backend, "\n", 1);
|
||||
return response();
|
||||
}
|
||||
}
|
||||
@ -1046,7 +1043,7 @@ int scp_send_enddir(void)
|
||||
sfree(scp_sftp_remotepath);
|
||||
return 0;
|
||||
} else {
|
||||
back->send(backhandle, "E\n", 2);
|
||||
backend_send(backend, "E\n", 2);
|
||||
return response();
|
||||
}
|
||||
}
|
||||
@ -1144,7 +1141,7 @@ int scp_sink_setup(const char *source, int preserve, int recursive)
|
||||
int scp_sink_init(void)
|
||||
{
|
||||
if (!using_sftp) {
|
||||
back->send(backhandle, "", 1);
|
||||
backend_send(backend, "", 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1457,14 +1454,14 @@ int scp_get_sink_action(struct scp_sink_action *act)
|
||||
case '\02': /* fatal error */
|
||||
bump("%s", act->buf);
|
||||
case 'E':
|
||||
back->send(backhandle, "", 1);
|
||||
backend_send(backend, "", 1);
|
||||
act->action = SCP_SINK_ENDDIR;
|
||||
return 0;
|
||||
case 'T':
|
||||
if (sscanf(act->buf, "%lu %*d %lu %*d",
|
||||
&act->mtime, &act->atime) == 2) {
|
||||
act->settime = 1;
|
||||
back->send(backhandle, "", 1);
|
||||
backend_send(backend, "", 1);
|
||||
continue; /* go round again */
|
||||
}
|
||||
bump("Protocol error: Illegal time format");
|
||||
@ -1521,7 +1518,7 @@ int scp_accept_filexfer(void)
|
||||
sfree(scp_sftp_currentname);
|
||||
return 0;
|
||||
} else {
|
||||
back->send(backhandle, "", 1);
|
||||
backend_send(backend, "", 1);
|
||||
return 0; /* can't fail */
|
||||
}
|
||||
}
|
||||
@ -1606,7 +1603,7 @@ int scp_finish_filerecv(void)
|
||||
fxp_close_recv(pktin, req);
|
||||
return 0;
|
||||
} else {
|
||||
back->send(backhandle, "", 1);
|
||||
backend_send(backend, "", 1);
|
||||
return response();
|
||||
}
|
||||
}
|
||||
@ -2355,7 +2352,7 @@ int psftp_main(int argc, char *argv[])
|
||||
}
|
||||
argc -= i;
|
||||
argv += i;
|
||||
back = NULL;
|
||||
backend = NULL;
|
||||
|
||||
if (list) {
|
||||
if (argc != 1)
|
||||
@ -2375,9 +2372,9 @@ int psftp_main(int argc, char *argv[])
|
||||
tolocal(argc, argv);
|
||||
}
|
||||
|
||||
if (back != NULL && back->connected(backhandle)) {
|
||||
if (backend && backend_connected(backend)) {
|
||||
char ch;
|
||||
back->special(backhandle, TS_EOF);
|
||||
backend_special(backend, TS_EOF);
|
||||
sent_eof = TRUE;
|
||||
ssh_scp_recv(&ch, 1);
|
||||
}
|
||||
@ -2385,9 +2382,8 @@ int psftp_main(int argc, char *argv[])
|
||||
|
||||
cmdline_cleanup();
|
||||
console_provide_logctx(NULL);
|
||||
back->free(backhandle);
|
||||
backhandle = NULL;
|
||||
back = NULL;
|
||||
backend_free(backend);
|
||||
backend = NULL;
|
||||
sk_cleanup();
|
||||
return (errs == 0 ? 0 : 1);
|
||||
}
|
||||
|
74
psftp.c
74
psftp.c
@ -34,8 +34,7 @@ void do_sftp_cleanup();
|
||||
*/
|
||||
|
||||
char *pwd, *homedir;
|
||||
static Backend *back;
|
||||
static void *backhandle;
|
||||
static Backend *backend;
|
||||
static Conf *conf;
|
||||
int sent_eof = FALSE;
|
||||
|
||||
@ -967,14 +966,14 @@ int sftp_cmd_quit(struct sftp_command *cmd)
|
||||
|
||||
int sftp_cmd_close(struct sftp_command *cmd)
|
||||
{
|
||||
if (back == NULL) {
|
||||
if (!backend) {
|
||||
not_connected();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (back != NULL && back->connected(backhandle)) {
|
||||
if (backend_connected(backend)) {
|
||||
char ch;
|
||||
back->special(backhandle, TS_EOF);
|
||||
backend_special(backend, TS_EOF);
|
||||
sent_eof = TRUE;
|
||||
sftp_recvdata(&ch, 1);
|
||||
}
|
||||
@ -999,7 +998,7 @@ int sftp_cmd_ls(struct sftp_command *cmd)
|
||||
struct sftp_request *req;
|
||||
int i;
|
||||
|
||||
if (back == NULL) {
|
||||
if (!backend) {
|
||||
not_connected();
|
||||
return 0;
|
||||
}
|
||||
@ -1123,7 +1122,7 @@ int sftp_cmd_cd(struct sftp_command *cmd)
|
||||
struct sftp_request *req;
|
||||
char *dir;
|
||||
|
||||
if (back == NULL) {
|
||||
if (!backend) {
|
||||
not_connected();
|
||||
return 0;
|
||||
}
|
||||
@ -1164,7 +1163,7 @@ int sftp_cmd_cd(struct sftp_command *cmd)
|
||||
*/
|
||||
int sftp_cmd_pwd(struct sftp_command *cmd)
|
||||
{
|
||||
if (back == NULL) {
|
||||
if (!backend) {
|
||||
not_connected();
|
||||
return 0;
|
||||
}
|
||||
@ -1188,7 +1187,7 @@ int sftp_general_get(struct sftp_command *cmd, int restart, int multiple)
|
||||
int i, ret;
|
||||
int recurse = FALSE;
|
||||
|
||||
if (back == NULL) {
|
||||
if (!backend) {
|
||||
not_connected();
|
||||
return 0;
|
||||
}
|
||||
@ -1304,7 +1303,7 @@ int sftp_general_put(struct sftp_command *cmd, int restart, int multiple)
|
||||
int i, ret;
|
||||
int recurse = FALSE;
|
||||
|
||||
if (back == NULL) {
|
||||
if (!backend) {
|
||||
not_connected();
|
||||
return 0;
|
||||
}
|
||||
@ -1405,7 +1404,7 @@ int sftp_cmd_mkdir(struct sftp_command *cmd)
|
||||
int result;
|
||||
int i, ret;
|
||||
|
||||
if (back == NULL) {
|
||||
if (!backend) {
|
||||
not_connected();
|
||||
return 0;
|
||||
}
|
||||
@ -1463,7 +1462,7 @@ int sftp_cmd_rmdir(struct sftp_command *cmd)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
if (back == NULL) {
|
||||
if (!backend) {
|
||||
not_connected();
|
||||
return 0;
|
||||
}
|
||||
@ -1504,7 +1503,7 @@ int sftp_cmd_rm(struct sftp_command *cmd)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
if (back == NULL) {
|
||||
if (!backend) {
|
||||
not_connected();
|
||||
return 0;
|
||||
}
|
||||
@ -1597,7 +1596,7 @@ int sftp_cmd_mv(struct sftp_command *cmd)
|
||||
struct sftp_context_mv actx, *ctx = &actx;
|
||||
int i, ret;
|
||||
|
||||
if (back == NULL) {
|
||||
if (!backend) {
|
||||
not_connected();
|
||||
return 0;
|
||||
}
|
||||
@ -1689,7 +1688,7 @@ int sftp_cmd_chmod(struct sftp_command *cmd)
|
||||
int i, ret;
|
||||
struct sftp_context_chmod actx, *ctx = &actx;
|
||||
|
||||
if (back == NULL) {
|
||||
if (!backend) {
|
||||
not_connected();
|
||||
return 0;
|
||||
}
|
||||
@ -1815,7 +1814,7 @@ static int sftp_cmd_open(struct sftp_command *cmd)
|
||||
{
|
||||
int portnumber;
|
||||
|
||||
if (back != NULL) {
|
||||
if (backend) {
|
||||
printf("psftp: already connected\n");
|
||||
return 0;
|
||||
}
|
||||
@ -1835,7 +1834,7 @@ static int sftp_cmd_open(struct sftp_command *cmd)
|
||||
portnumber = 0;
|
||||
|
||||
if (psftp_connect(cmd->words[1], NULL, portnumber)) {
|
||||
back = NULL; /* connection is already closed */
|
||||
backend = NULL; /* connection is already closed */
|
||||
return -1; /* this is fatal */
|
||||
}
|
||||
do_sftp_init();
|
||||
@ -2214,7 +2213,7 @@ struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags)
|
||||
printf("psftp> ");
|
||||
line = fgetline(fp);
|
||||
} else {
|
||||
line = ssh_sftp_get_cmdline("psftp> ", back == NULL);
|
||||
line = ssh_sftp_get_cmdline("psftp> ", !backend);
|
||||
}
|
||||
|
||||
if (!line || !*line) {
|
||||
@ -2355,14 +2354,13 @@ static int do_sftp_init(void)
|
||||
void do_sftp_cleanup()
|
||||
{
|
||||
char ch;
|
||||
if (back) {
|
||||
back->special(backhandle, TS_EOF);
|
||||
if (backend) {
|
||||
backend_special(backend, TS_EOF);
|
||||
sent_eof = TRUE;
|
||||
sftp_recvdata(&ch, 1);
|
||||
back->free(backhandle);
|
||||
backend_free(backend);
|
||||
sftp_cleanup_request();
|
||||
back = NULL;
|
||||
backhandle = NULL;
|
||||
backend = NULL;
|
||||
}
|
||||
if (pwd) {
|
||||
sfree(pwd);
|
||||
@ -2602,7 +2600,7 @@ int sftp_recvdata(char *buf, int len)
|
||||
}
|
||||
|
||||
while (outlen > 0) {
|
||||
if (back->exitcode(backhandle) >= 0 || ssh_sftp_loop_iteration() < 0)
|
||||
if (backend_exitcode(backend) >= 0 || ssh_sftp_loop_iteration() < 0)
|
||||
return 0; /* doom */
|
||||
}
|
||||
|
||||
@ -2610,12 +2608,12 @@ int sftp_recvdata(char *buf, int len)
|
||||
}
|
||||
int sftp_senddata(char *buf, int len)
|
||||
{
|
||||
back->send(backhandle, buf, len);
|
||||
backend_send(backend, buf, len);
|
||||
return 1;
|
||||
}
|
||||
int sftp_sendbuffer(void)
|
||||
{
|
||||
return back->sendbuffer(backhandle);
|
||||
return backend_sendbuffer(backend);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2826,25 +2824,23 @@ static int psftp_connect(char *userhost, char *user, int portnumber)
|
||||
"exec sftp-server");
|
||||
conf_set_int(conf, CONF_ssh_subsys2, FALSE);
|
||||
|
||||
back = &ssh_backend;
|
||||
|
||||
logctx = log_init(NULL, conf);
|
||||
console_provide_logctx(logctx);
|
||||
|
||||
platform_psftp_pre_conn_setup();
|
||||
|
||||
err = back->init(NULL, &backhandle, conf,
|
||||
conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port),
|
||||
&realhost, 0,
|
||||
conf_get_int(conf, CONF_tcp_keepalives));
|
||||
err = backend_init(&ssh_backend, NULL, &backend, conf,
|
||||
conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port),
|
||||
&realhost, 0,
|
||||
conf_get_int(conf, CONF_tcp_keepalives));
|
||||
if (err != NULL) {
|
||||
fprintf(stderr, "ssh_init: %s\n", err);
|
||||
return 1;
|
||||
}
|
||||
back->provide_logctx(backhandle, logctx);
|
||||
while (!back->sendok(backhandle)) {
|
||||
if (back->exitcode(backhandle) >= 0)
|
||||
backend_provide_logctx(backend, logctx);
|
||||
while (!backend_sendok(backend)) {
|
||||
if (backend_exitcode(backend) >= 0)
|
||||
return 1;
|
||||
if (ssh_sftp_loop_iteration() < 0) {
|
||||
fprintf(stderr, "ssh_init: error during SSH connection setup\n");
|
||||
@ -2945,7 +2941,7 @@ int psftp_main(int argc, char *argv[])
|
||||
}
|
||||
argc -= i;
|
||||
argv += i;
|
||||
back = NULL;
|
||||
backend = NULL;
|
||||
|
||||
/*
|
||||
* If the loaded session provides a hostname, and a hostname has not
|
||||
@ -2975,9 +2971,9 @@ int psftp_main(int argc, char *argv[])
|
||||
|
||||
ret = do_sftp(mode, modeflags, batchfile);
|
||||
|
||||
if (back != NULL && back->connected(backhandle)) {
|
||||
if (backend && backend_connected(backend)) {
|
||||
char ch;
|
||||
back->special(backhandle, TS_EOF);
|
||||
backend_special(backend, TS_EOF);
|
||||
sent_eof = TRUE;
|
||||
sftp_recvdata(&ch, 1);
|
||||
}
|
||||
|
102
putty.h
102
putty.h
@ -441,43 +441,67 @@ enum {
|
||||
ADDRTYPE_UNSPEC, ADDRTYPE_IPV4, ADDRTYPE_IPV6, ADDRTYPE_NAME
|
||||
};
|
||||
|
||||
struct backend_tag {
|
||||
const char *(*init) (void *frontend_handle, void **backend_handle,
|
||||
struct Backend {
|
||||
const Backend_vtable *vt;
|
||||
};
|
||||
struct Backend_vtable {
|
||||
const char *(*init) (void *frontend_handle, Backend **backend_out,
|
||||
Conf *conf, const char *host, int port,
|
||||
char **realhost, int nodelay, int keepalive);
|
||||
void (*free) (void *handle);
|
||||
/* back->reconfig() passes in a replacement configuration. */
|
||||
void (*reconfig) (void *handle, Conf *conf);
|
||||
/* back->send() returns the current amount of buffered data. */
|
||||
int (*send) (void *handle, const char *buf, int len);
|
||||
/* back->sendbuffer() does the same thing but without attempting a send */
|
||||
int (*sendbuffer) (void *handle);
|
||||
void (*size) (void *handle, int width, int height);
|
||||
void (*special) (void *handle, Telnet_Special code);
|
||||
const struct telnet_special *(*get_specials) (void *handle);
|
||||
int (*connected) (void *handle);
|
||||
int (*exitcode) (void *handle);
|
||||
/* If back->sendok() returns FALSE, data sent to it from the frontend
|
||||
* may be lost. */
|
||||
int (*sendok) (void *handle);
|
||||
int (*ldisc) (void *handle, int);
|
||||
void (*provide_ldisc) (void *handle, Ldisc *ldisc);
|
||||
void (*provide_logctx) (void *handle, LogContext *logctx);
|
||||
/*
|
||||
* back->unthrottle() tells the back end that the front end
|
||||
* buffer is clearing.
|
||||
*/
|
||||
void (*unthrottle) (void *handle, int);
|
||||
int (*cfg_info) (void *handle);
|
||||
|
||||
void (*free) (Backend *be);
|
||||
/* Pass in a replacement configuration. */
|
||||
void (*reconfig) (Backend *be, Conf *conf);
|
||||
/* send() returns the current amount of buffered data. */
|
||||
int (*send) (Backend *be, const char *buf, int len);
|
||||
/* 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);
|
||||
int (*connected) (Backend *be);
|
||||
int (*exitcode) (Backend *be);
|
||||
/* If back->sendok() returns FALSE, the backend doesn't currently
|
||||
* want input data, so the frontend should avoid acquiring any if
|
||||
* possible (passing back-pressure on to its sender). */
|
||||
int (*sendok) (Backend *be);
|
||||
int (*ldisc_option_state) (Backend *be, int);
|
||||
void (*provide_ldisc) (Backend *be, Ldisc *ldisc);
|
||||
void (*provide_logctx) (Backend *be, LogContext *logctx);
|
||||
/* Tells the back end that the front end buffer is clearing. */
|
||||
void (*unthrottle) (Backend *be, int bufsize);
|
||||
int (*cfg_info) (Backend *be);
|
||||
|
||||
/* Only implemented in the SSH protocol: check whether a
|
||||
* connection-sharing upstream exists for a given configuration. */
|
||||
int (*test_for_upstream)(const char *host, int port, Conf *conf);
|
||||
|
||||
const char *name;
|
||||
int protocol;
|
||||
int default_port;
|
||||
};
|
||||
|
||||
extern Backend *backends[];
|
||||
#define backend_init(vt, fe, out, conf, host, port, rhost, nd, ka) \
|
||||
((vt)->init(fe, out, conf, host, port, rhost, nd, ka))
|
||||
#define backend_free(be) ((be)->vt->free(be))
|
||||
#define backend_reconfig(be, conf) ((be)->vt->reconfig(be, conf))
|
||||
#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_get_specials(be) ((be)->vt->get_specials(be))
|
||||
#define backend_connected(be) ((be)->vt->connected(be))
|
||||
#define backend_exitcode(be) ((be)->vt->exitcode(be))
|
||||
#define backend_sendok(be) ((be)->vt->sendok(be))
|
||||
#define backend_ldisc_option_state(be, opt) \
|
||||
((be)->vt->ldisc_option_state(be, opt))
|
||||
#define backend_provide_ldisc(be, ldisc) ((be)->vt->provide_ldisc(be, ldisc))
|
||||
#define backend_provide_logctx(be, logctx) \
|
||||
((be)->vt->provide_logctx(be, logctx))
|
||||
#define backend_unthrottle(be, bufsize) ((be)->vt->unthrottle(be, bufsize))
|
||||
#define backend_cfg_info(be) ((be)->vt->cfg_info(be))
|
||||
|
||||
extern const struct Backend_vtable *const backends[];
|
||||
|
||||
/*
|
||||
* Suggested default protocol provided by the backend link module.
|
||||
@ -1046,8 +1070,8 @@ void random_destroy_seed(void);
|
||||
/*
|
||||
* Exports from settings.c.
|
||||
*/
|
||||
Backend *backend_from_name(const char *name);
|
||||
Backend *backend_from_proto(int proto);
|
||||
const struct Backend_vtable *backend_vt_from_name(const char *name);
|
||||
const struct Backend_vtable *backend_vt_from_proto(int proto);
|
||||
char *get_remote_username(Conf *conf); /* dynamically allocated */
|
||||
char *save_settings(const char *section, Conf *conf);
|
||||
void save_open_settings(void *sesskey, Conf *conf);
|
||||
@ -1107,9 +1131,7 @@ void term_request_paste(Terminal *, int clipboard);
|
||||
void term_seen_key_event(Terminal *);
|
||||
int term_data(Terminal *, int is_stderr, const void *data, int len);
|
||||
int term_data_untrusted(Terminal *, const void *data, int len);
|
||||
void term_provide_resize_fn(Terminal *term,
|
||||
void (*resize_fn)(void *, int, int),
|
||||
void *resize_ctx);
|
||||
void term_provide_backend(Terminal *term, Backend *backend);
|
||||
void term_provide_logctx(Terminal *term, LogContext *logctx);
|
||||
void term_set_focus(Terminal *term, int has_focus);
|
||||
char *term_get_ttymode(Terminal *term, const char *mode);
|
||||
@ -1145,36 +1167,36 @@ void log_packet(LogContext *logctx, int direction, int type,
|
||||
* Exports from testback.c
|
||||
*/
|
||||
|
||||
extern Backend null_backend;
|
||||
extern Backend loop_backend;
|
||||
extern const struct Backend_vtable null_backend;
|
||||
extern const struct Backend_vtable loop_backend;
|
||||
|
||||
/*
|
||||
* Exports from raw.c.
|
||||
*/
|
||||
|
||||
extern Backend raw_backend;
|
||||
extern const struct Backend_vtable raw_backend;
|
||||
|
||||
/*
|
||||
* Exports from rlogin.c.
|
||||
*/
|
||||
|
||||
extern Backend rlogin_backend;
|
||||
extern const struct Backend_vtable rlogin_backend;
|
||||
|
||||
/*
|
||||
* Exports from telnet.c.
|
||||
*/
|
||||
|
||||
extern Backend telnet_backend;
|
||||
extern const struct Backend_vtable telnet_backend;
|
||||
|
||||
/*
|
||||
* Exports from ssh.c.
|
||||
*/
|
||||
extern Backend ssh_backend;
|
||||
extern const struct Backend_vtable ssh_backend;
|
||||
|
||||
/*
|
||||
* Exports from ldisc.c.
|
||||
*/
|
||||
Ldisc *ldisc_create(Conf *, Terminal *, Backend *, void *, void *);
|
||||
Ldisc *ldisc_create(Conf *, Terminal *, Backend *, void *);
|
||||
void ldisc_configure(Ldisc *, Conf *);
|
||||
void ldisc_free(Ldisc *);
|
||||
void ldisc_send(Ldisc *, const void *buf, int len, int interactive);
|
||||
@ -1205,7 +1227,7 @@ void random_unref(void);
|
||||
* Exports from pinger.c.
|
||||
*/
|
||||
typedef struct pinger_tag *Pinger;
|
||||
Pinger pinger_new(Conf *conf, Backend *back, void *backhandle);
|
||||
Pinger pinger_new(Conf *conf, Backend *backend);
|
||||
void pinger_reconfig(Pinger, Conf *oldconf, Conf *newconf);
|
||||
void pinger_free(Pinger);
|
||||
|
||||
|
54
raw.c
54
raw.c
@ -20,9 +20,10 @@ typedef struct raw_backend_data {
|
||||
Conf *conf;
|
||||
|
||||
const Plug_vtable *plugvt;
|
||||
Backend backend;
|
||||
} *Raw;
|
||||
|
||||
static void raw_size(void *handle, int width, int height);
|
||||
static void raw_size(Backend *be, int width, int height);
|
||||
|
||||
static void c_write(Raw raw, const void *buf, int len)
|
||||
{
|
||||
@ -116,7 +117,7 @@ static const Plug_vtable Raw_plugvt = {
|
||||
* Also places the canonical host name into `realhost'. It must be
|
||||
* freed by the caller.
|
||||
*/
|
||||
static const char *raw_init(void *frontend_handle, void **backend_handle,
|
||||
static const char *raw_init(void *frontend_handle, Backend **backend_handle,
|
||||
Conf *conf,
|
||||
const char *host, int port, char **realhost,
|
||||
int nodelay, int keepalive)
|
||||
@ -129,9 +130,10 @@ static const char *raw_init(void *frontend_handle, void **backend_handle,
|
||||
|
||||
raw = snew(struct raw_backend_data);
|
||||
raw->plugvt = &Raw_plugvt;
|
||||
raw->backend.vt = &raw_backend;
|
||||
raw->s = NULL;
|
||||
raw->closed_on_socket_error = FALSE;
|
||||
*backend_handle = raw;
|
||||
*backend_handle = &raw->backend;
|
||||
raw->sent_console_eof = raw->sent_socket_eof = FALSE;
|
||||
raw->bufsize = 0;
|
||||
raw->session_started = FALSE;
|
||||
@ -176,9 +178,9 @@ static const char *raw_init(void *frontend_handle, void **backend_handle,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void raw_free(void *handle)
|
||||
static void raw_free(Backend *be)
|
||||
{
|
||||
Raw raw = (Raw) handle;
|
||||
Raw raw = FROMFIELD(be, struct raw_backend_data, backend);
|
||||
|
||||
if (raw->s)
|
||||
sk_close(raw->s);
|
||||
@ -189,16 +191,16 @@ static void raw_free(void *handle)
|
||||
/*
|
||||
* Stub routine (we don't have any need to reconfigure this backend).
|
||||
*/
|
||||
static void raw_reconfig(void *handle, Conf *conf)
|
||||
static void raw_reconfig(Backend *be, Conf *conf)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to send data down the raw connection.
|
||||
*/
|
||||
static int raw_send(void *handle, const char *buf, int len)
|
||||
static int raw_send(Backend *be, const char *buf, int len)
|
||||
{
|
||||
Raw raw = (Raw) handle;
|
||||
Raw raw = FROMFIELD(be, struct raw_backend_data, backend);
|
||||
|
||||
if (raw->s == NULL)
|
||||
return 0;
|
||||
@ -211,16 +213,16 @@ static int raw_send(void *handle, const char *buf, int len)
|
||||
/*
|
||||
* Called to query the current socket sendability status.
|
||||
*/
|
||||
static int raw_sendbuffer(void *handle)
|
||||
static int raw_sendbuffer(Backend *be)
|
||||
{
|
||||
Raw raw = (Raw) handle;
|
||||
Raw raw = FROMFIELD(be, struct raw_backend_data, backend);
|
||||
return raw->bufsize;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to set the size of the window
|
||||
*/
|
||||
static void raw_size(void *handle, int width, int height)
|
||||
static void raw_size(Backend *be, int width, int height)
|
||||
{
|
||||
/* Do nothing! */
|
||||
return;
|
||||
@ -229,9 +231,9 @@ static void raw_size(void *handle, int width, int height)
|
||||
/*
|
||||
* Send raw special codes. We only handle outgoing EOF here.
|
||||
*/
|
||||
static void raw_special(void *handle, Telnet_Special code)
|
||||
static void raw_special(Backend *be, Telnet_Special code)
|
||||
{
|
||||
Raw raw = (Raw) handle;
|
||||
Raw raw = FROMFIELD(be, struct raw_backend_data, backend);
|
||||
if (code == TS_EOF && raw->s) {
|
||||
sk_write_eof(raw->s);
|
||||
raw->sent_socket_eof= TRUE;
|
||||
@ -245,48 +247,48 @@ static void raw_special(void *handle, Telnet_Special code)
|
||||
* Return a list of the special codes that make sense in this
|
||||
* protocol.
|
||||
*/
|
||||
static const struct telnet_special *raw_get_specials(void *handle)
|
||||
static const struct telnet_special *raw_get_specials(Backend *be)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int raw_connected(void *handle)
|
||||
static int raw_connected(Backend *be)
|
||||
{
|
||||
Raw raw = (Raw) handle;
|
||||
Raw raw = FROMFIELD(be, struct raw_backend_data, backend);
|
||||
return raw->s != NULL;
|
||||
}
|
||||
|
||||
static int raw_sendok(void *handle)
|
||||
static int raw_sendok(Backend *be)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void raw_unthrottle(void *handle, int backlog)
|
||||
static void raw_unthrottle(Backend *be, int backlog)
|
||||
{
|
||||
Raw raw = (Raw) handle;
|
||||
Raw raw = FROMFIELD(be, struct raw_backend_data, backend);
|
||||
sk_set_frozen(raw->s, backlog > RAW_MAX_BACKLOG);
|
||||
}
|
||||
|
||||
static int raw_ldisc(void *handle, int option)
|
||||
static int raw_ldisc(Backend *be, int option)
|
||||
{
|
||||
if (option == LD_EDIT || option == LD_ECHO)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void raw_provide_ldisc(void *handle, Ldisc *ldisc)
|
||||
static void raw_provide_ldisc(Backend *be, Ldisc *ldisc)
|
||||
{
|
||||
/* This is a stub. */
|
||||
}
|
||||
|
||||
static void raw_provide_logctx(void *handle, LogContext *logctx)
|
||||
static void raw_provide_logctx(Backend *be, LogContext *logctx)
|
||||
{
|
||||
/* This is a stub. */
|
||||
}
|
||||
|
||||
static int raw_exitcode(void *handle)
|
||||
static int raw_exitcode(Backend *be)
|
||||
{
|
||||
Raw raw = (Raw) handle;
|
||||
Raw raw = FROMFIELD(be, struct raw_backend_data, backend);
|
||||
if (raw->s != NULL)
|
||||
return -1; /* still connected */
|
||||
else if (raw->closed_on_socket_error)
|
||||
@ -299,12 +301,12 @@ static int raw_exitcode(void *handle)
|
||||
/*
|
||||
* cfg_info for Raw does nothing at all.
|
||||
*/
|
||||
static int raw_cfg_info(void *handle)
|
||||
static int raw_cfg_info(Backend *be)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Backend raw_backend = {
|
||||
const struct Backend_vtable raw_backend = {
|
||||
raw_init,
|
||||
raw_free,
|
||||
raw_reconfig,
|
||||
|
61
rlogin.c
61
rlogin.c
@ -26,10 +26,9 @@ typedef struct rlogin_tag {
|
||||
prompts_t *prompt;
|
||||
|
||||
const Plug_vtable *plugvt;
|
||||
Backend backend;
|
||||
} *Rlogin;
|
||||
|
||||
static void rlogin_size(void *handle, int width, int height);
|
||||
|
||||
static void c_write(Rlogin rlogin, const void *buf, int len)
|
||||
{
|
||||
int backlog = from_backend(rlogin->frontend, 0, buf, len);
|
||||
@ -80,7 +79,8 @@ static void rlogin_receive(Plug plug, int urgent, char *data, int len)
|
||||
len--;
|
||||
if (c == '\x80') {
|
||||
rlogin->cansize = 1;
|
||||
rlogin_size(rlogin, rlogin->term_width, rlogin->term_height);
|
||||
backend_size(&rlogin->backend,
|
||||
rlogin->term_width, rlogin->term_height);
|
||||
}
|
||||
/*
|
||||
* We should flush everything (aka Telnet SYNCH) if we see
|
||||
@ -148,7 +148,7 @@ static const Plug_vtable Rlogin_plugvt = {
|
||||
* Also places the canonical host name into `realhost'. It must be
|
||||
* freed by the caller.
|
||||
*/
|
||||
static const char *rlogin_init(void *frontend_handle, void **backend_handle,
|
||||
static const char *rlogin_init(void *frontend_handle, Backend **backend_handle,
|
||||
Conf *conf,
|
||||
const char *host, int port, char **realhost,
|
||||
int nodelay, int keepalive)
|
||||
@ -162,6 +162,7 @@ static const char *rlogin_init(void *frontend_handle, void **backend_handle,
|
||||
|
||||
rlogin = snew(struct rlogin_tag);
|
||||
rlogin->plugvt = &Rlogin_plugvt;
|
||||
rlogin->backend.vt = &rlogin_backend;
|
||||
rlogin->s = NULL;
|
||||
rlogin->closed_on_socket_error = FALSE;
|
||||
rlogin->frontend = frontend_handle;
|
||||
@ -171,7 +172,7 @@ static const char *rlogin_init(void *frontend_handle, void **backend_handle,
|
||||
rlogin->cansize = 0;
|
||||
rlogin->prompt = NULL;
|
||||
rlogin->conf = conf_copy(conf);
|
||||
*backend_handle = rlogin;
|
||||
*backend_handle = &rlogin->backend;
|
||||
|
||||
addressfamily = conf_get_int(conf, CONF_addressfamily);
|
||||
/*
|
||||
@ -232,9 +233,9 @@ static const char *rlogin_init(void *frontend_handle, void **backend_handle,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rlogin_free(void *handle)
|
||||
static void rlogin_free(Backend *be)
|
||||
{
|
||||
Rlogin rlogin = (Rlogin) handle;
|
||||
Rlogin rlogin = FROMFIELD(be, struct rlogin_tag, backend);
|
||||
|
||||
if (rlogin->prompt)
|
||||
free_prompts(rlogin->prompt);
|
||||
@ -247,16 +248,16 @@ static void rlogin_free(void *handle)
|
||||
/*
|
||||
* Stub routine (we don't have any need to reconfigure this backend).
|
||||
*/
|
||||
static void rlogin_reconfig(void *handle, Conf *conf)
|
||||
static void rlogin_reconfig(Backend *be, Conf *conf)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to send data down the rlogin connection.
|
||||
*/
|
||||
static int rlogin_send(void *handle, const char *buf, int len)
|
||||
static int rlogin_send(Backend *be, const char *buf, int len)
|
||||
{
|
||||
Rlogin rlogin = (Rlogin) handle;
|
||||
Rlogin rlogin = FROMFIELD(be, struct rlogin_tag, backend);
|
||||
bufchain bc;
|
||||
|
||||
if (rlogin->s == NULL)
|
||||
@ -296,18 +297,18 @@ static int rlogin_send(void *handle, const char *buf, int len)
|
||||
/*
|
||||
* Called to query the current socket sendability status.
|
||||
*/
|
||||
static int rlogin_sendbuffer(void *handle)
|
||||
static int rlogin_sendbuffer(Backend *be)
|
||||
{
|
||||
Rlogin rlogin = (Rlogin) handle;
|
||||
Rlogin rlogin = FROMFIELD(be, struct rlogin_tag, backend);
|
||||
return rlogin->bufsize;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to set the size of the window
|
||||
*/
|
||||
static void rlogin_size(void *handle, int width, int height)
|
||||
static void rlogin_size(Backend *be, int width, int height)
|
||||
{
|
||||
Rlogin rlogin = (Rlogin) handle;
|
||||
Rlogin rlogin = FROMFIELD(be, struct rlogin_tag, backend);
|
||||
char b[12] = { '\xFF', '\xFF', 0x73, 0x73, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
rlogin->term_width = width;
|
||||
@ -327,7 +328,7 @@ static void rlogin_size(void *handle, int width, int height)
|
||||
/*
|
||||
* Send rlogin special codes.
|
||||
*/
|
||||
static void rlogin_special(void *handle, Telnet_Special code)
|
||||
static void rlogin_special(Backend *be, Telnet_Special code)
|
||||
{
|
||||
/* Do nothing! */
|
||||
return;
|
||||
@ -337,48 +338,48 @@ static void rlogin_special(void *handle, Telnet_Special code)
|
||||
* Return a list of the special codes that make sense in this
|
||||
* protocol.
|
||||
*/
|
||||
static const struct telnet_special *rlogin_get_specials(void *handle)
|
||||
static const struct telnet_special *rlogin_get_specials(Backend *be)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int rlogin_connected(void *handle)
|
||||
static int rlogin_connected(Backend *be)
|
||||
{
|
||||
Rlogin rlogin = (Rlogin) handle;
|
||||
Rlogin rlogin = FROMFIELD(be, struct rlogin_tag, backend);
|
||||
return rlogin->s != NULL;
|
||||
}
|
||||
|
||||
static int rlogin_sendok(void *handle)
|
||||
static int rlogin_sendok(Backend *be)
|
||||
{
|
||||
/* Rlogin rlogin = (Rlogin) handle; */
|
||||
/* Rlogin rlogin = FROMFIELD(be, struct rlogin_tag, backend); */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void rlogin_unthrottle(void *handle, int backlog)
|
||||
static void rlogin_unthrottle(Backend *be, int backlog)
|
||||
{
|
||||
Rlogin rlogin = (Rlogin) handle;
|
||||
Rlogin rlogin = FROMFIELD(be, struct rlogin_tag, backend);
|
||||
sk_set_frozen(rlogin->s, backlog > RLOGIN_MAX_BACKLOG);
|
||||
}
|
||||
|
||||
static int rlogin_ldisc(void *handle, int option)
|
||||
static int rlogin_ldisc(Backend *be, int option)
|
||||
{
|
||||
/* Rlogin rlogin = (Rlogin) handle; */
|
||||
/* Rlogin rlogin = FROMFIELD(be, struct rlogin_tag, backend); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rlogin_provide_ldisc(void *handle, Ldisc *ldisc)
|
||||
static void rlogin_provide_ldisc(Backend *be, Ldisc *ldisc)
|
||||
{
|
||||
/* This is a stub. */
|
||||
}
|
||||
|
||||
static void rlogin_provide_logctx(void *handle, LogContext *logctx)
|
||||
static void rlogin_provide_logctx(Backend *be, LogContext *logctx)
|
||||
{
|
||||
/* This is a stub. */
|
||||
}
|
||||
|
||||
static int rlogin_exitcode(void *handle)
|
||||
static int rlogin_exitcode(Backend *be)
|
||||
{
|
||||
Rlogin rlogin = (Rlogin) handle;
|
||||
Rlogin rlogin = FROMFIELD(be, struct rlogin_tag, backend);
|
||||
if (rlogin->s != NULL)
|
||||
return -1; /* still connected */
|
||||
else if (rlogin->closed_on_socket_error)
|
||||
@ -391,12 +392,12 @@ static int rlogin_exitcode(void *handle)
|
||||
/*
|
||||
* cfg_info for rlogin does nothing at all.
|
||||
*/
|
||||
static int rlogin_cfg_info(void *handle)
|
||||
static int rlogin_cfg_info(Backend *be)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Backend rlogin_backend = {
|
||||
const struct Backend_vtable rlogin_backend = {
|
||||
rlogin_init,
|
||||
rlogin_free,
|
||||
rlogin_reconfig,
|
||||
|
21
settings.c
21
settings.c
@ -74,18 +74,18 @@ const char *const ttymodes[] = {
|
||||
* (which is only present in tools that manage settings).
|
||||
*/
|
||||
|
||||
Backend *backend_from_name(const char *name)
|
||||
const struct Backend_vtable *backend_vt_from_name(const char *name)
|
||||
{
|
||||
Backend **p;
|
||||
const struct Backend_vtable *const *p;
|
||||
for (p = backends; *p != NULL; p++)
|
||||
if (!strcmp((*p)->name, name))
|
||||
return *p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Backend *backend_from_proto(int proto)
|
||||
const struct Backend_vtable *backend_vt_from_proto(int proto)
|
||||
{
|
||||
Backend **p;
|
||||
const struct Backend_vtable *const *p;
|
||||
for (p = backends; *p != NULL; p++)
|
||||
if ((*p)->protocol == proto)
|
||||
return *p;
|
||||
@ -528,9 +528,10 @@ void save_open_settings(void *sesskey, Conf *conf)
|
||||
write_setting_i(sesskey, "SSHLogOmitData", conf_get_int(conf, CONF_logomitdata));
|
||||
p = "raw";
|
||||
{
|
||||
const Backend *b = backend_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
if (b)
|
||||
p = b->name;
|
||||
const struct Backend_vtable *vt =
|
||||
backend_vt_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
if (vt)
|
||||
p = vt->name;
|
||||
}
|
||||
write_setting_s(sesskey, "Protocol", p);
|
||||
write_setting_i(sesskey, "PortNumber", conf_get_int(conf, CONF_port));
|
||||
@ -791,9 +792,9 @@ void load_open_settings(void *sesskey, Conf *conf)
|
||||
conf_set_int(conf, CONF_protocol, default_protocol);
|
||||
conf_set_int(conf, CONF_port, default_port);
|
||||
{
|
||||
const Backend *b = backend_from_name(prot);
|
||||
if (b) {
|
||||
conf_set_int(conf, CONF_protocol, b->protocol);
|
||||
const struct Backend_vtable *vt = backend_vt_from_name(prot);
|
||||
if (vt) {
|
||||
conf_set_int(conf, CONF_protocol, vt->protocol);
|
||||
gppi(sesskey, "PortNumber", default_port, conf, CONF_port);
|
||||
}
|
||||
}
|
||||
|
92
ssh.c
92
ssh.c
@ -561,14 +561,14 @@ struct ssh_portfwd {
|
||||
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(void *handle, int width, int height);
|
||||
static void ssh_special(void *handle, Telnet_Special);
|
||||
static void ssh_size(Backend *be, int width, int height);
|
||||
static void ssh_special(Backend *be, Telnet_Special);
|
||||
static int ssh2_try_send(struct ssh_channel *c);
|
||||
static int ssh_send_channel_data(struct ssh_channel *c,
|
||||
const char *buf, int len);
|
||||
static void ssh_throttle_all(Ssh ssh, int enable, int bufsize);
|
||||
static void ssh2_set_window(struct ssh_channel *c, int newwin);
|
||||
static int ssh_sendbuffer(void *handle);
|
||||
static int ssh_sendbuffer(Backend *be);
|
||||
static int ssh_do_close(Ssh ssh, int notify_exit);
|
||||
static void ssh2_timer(void *ctx, unsigned long now);
|
||||
static int ssh2_timer_update(Ssh ssh, unsigned long rekey_time);
|
||||
@ -699,6 +699,7 @@ struct ssh_tag {
|
||||
Socket s;
|
||||
|
||||
const Plug_vtable *plugvt;
|
||||
Backend backend;
|
||||
|
||||
Ldisc *ldisc;
|
||||
LogContext *logctx;
|
||||
@ -1877,7 +1878,7 @@ static void do_ssh_init(Ssh ssh)
|
||||
|
||||
update_specials_menu(ssh->frontend);
|
||||
ssh->state = SSH_STATE_BEFORE_SIZE;
|
||||
ssh->pinger = pinger_new(ssh->conf, &ssh_backend, ssh);
|
||||
ssh->pinger = pinger_new(ssh->conf, &ssh->backend);
|
||||
|
||||
sfree(s->vstring);
|
||||
|
||||
@ -2029,7 +2030,7 @@ static void do_ssh_connection_init(Ssh ssh)
|
||||
|
||||
update_specials_menu(ssh->frontend);
|
||||
ssh->state = SSH_STATE_BEFORE_SIZE;
|
||||
ssh->pinger = pinger_new(ssh->conf, &ssh_backend, ssh);
|
||||
ssh->pinger = pinger_new(ssh->conf, &ssh->backend);
|
||||
|
||||
/*
|
||||
* Get connection protocol under way.
|
||||
@ -4726,9 +4727,9 @@ static void do_ssh1_connection(void *vctx)
|
||||
|
||||
ssh->state = SSH_STATE_SESSION;
|
||||
if (ssh->size_needed)
|
||||
ssh_size(ssh, ssh->term_width, ssh->term_height);
|
||||
backend_size(&ssh->backend, ssh->term_width, ssh->term_height);
|
||||
if (ssh->eof_needed)
|
||||
ssh_special(ssh, TS_EOF);
|
||||
backend_special(&ssh->backend, TS_EOF);
|
||||
|
||||
if (ssh->ldisc)
|
||||
ldisc_echoedit_update(ssh->ldisc); /* cause ldisc to notice changes */
|
||||
@ -10110,9 +10111,9 @@ static void do_ssh2_connection(void *vctx)
|
||||
|
||||
ssh->state = SSH_STATE_SESSION;
|
||||
if (ssh->size_needed)
|
||||
ssh_size(ssh, ssh->term_width, ssh->term_height);
|
||||
backend_size(&ssh->backend, ssh->term_width, ssh->term_height);
|
||||
if (ssh->eof_needed)
|
||||
ssh_special(ssh, TS_EOF);
|
||||
backend_special(&ssh->backend, TS_EOF);
|
||||
|
||||
/*
|
||||
* Transfer data!
|
||||
@ -10664,7 +10665,7 @@ static void ssh_cache_conf_values(Ssh ssh)
|
||||
*
|
||||
* Returns an error message, or NULL on success.
|
||||
*/
|
||||
static const char *ssh_init(void *frontend_handle, void **backend_handle,
|
||||
static const char *ssh_init(void *frontend_handle, Backend **backend_handle,
|
||||
Conf *conf,
|
||||
const char *host, int port, char **realhost,
|
||||
int nodelay, int keepalive)
|
||||
@ -10777,7 +10778,8 @@ static const char *ssh_init(void *frontend_handle, void **backend_handle,
|
||||
#endif
|
||||
ssh->gss_kex_used = FALSE;
|
||||
|
||||
*backend_handle = ssh;
|
||||
ssh->backend.vt = &ssh_backend;
|
||||
*backend_handle = &ssh->backend;
|
||||
|
||||
ssh->frontend = frontend_handle;
|
||||
ssh->term_width = conf_get_int(ssh->conf, CONF_width);
|
||||
@ -10826,9 +10828,9 @@ static const char *ssh_init(void *frontend_handle, void **backend_handle,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ssh_free(void *handle)
|
||||
static void ssh_free(Backend *be)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
struct ssh_channel *c;
|
||||
struct ssh_rportfwd *pf;
|
||||
struct X11FakeAuth *auth;
|
||||
@ -10937,9 +10939,9 @@ static void ssh_free(void *handle)
|
||||
/*
|
||||
* Reconfigure the SSH backend.
|
||||
*/
|
||||
static void ssh_reconfig(void *handle, Conf *conf)
|
||||
static void ssh_reconfig(Backend *be, Conf *conf)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
const char *rekeying = NULL;
|
||||
int rekey_mandatory = FALSE;
|
||||
unsigned long old_max_data_size;
|
||||
@ -10999,9 +11001,9 @@ static void ssh_reconfig(void *handle, Conf *conf)
|
||||
/*
|
||||
* Called to send data down the SSH connection.
|
||||
*/
|
||||
static int ssh_send(void *handle, const char *buf, int len)
|
||||
static int ssh_send(Backend *be, const char *buf, int len)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
|
||||
if (ssh == NULL || ssh->s == NULL)
|
||||
return 0;
|
||||
@ -11009,15 +11011,15 @@ static int ssh_send(void *handle, const char *buf, int len)
|
||||
bufchain_add(&ssh->user_input, buf, len);
|
||||
queue_idempotent_callback(&ssh->user_input_consumer);
|
||||
|
||||
return ssh_sendbuffer(ssh);
|
||||
return backend_sendbuffer(&ssh->backend);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to query the current amount of buffered stdin data.
|
||||
*/
|
||||
static int ssh_sendbuffer(void *handle)
|
||||
static int ssh_sendbuffer(Backend *be)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
int override_value;
|
||||
|
||||
if (ssh == NULL || ssh->s == NULL)
|
||||
@ -11047,9 +11049,9 @@ static int ssh_sendbuffer(void *handle)
|
||||
/*
|
||||
* Called to set the size of the window from SSH's POV.
|
||||
*/
|
||||
static void ssh_size(void *handle, int width, int height)
|
||||
static void ssh_size(Backend *be, int width, int height)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
PktOut *pktout;
|
||||
|
||||
ssh->term_width = width;
|
||||
@ -11090,7 +11092,7 @@ static void ssh_size(void *handle, 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(void *handle)
|
||||
static const struct telnet_special *ssh_get_specials(Backend *be)
|
||||
{
|
||||
static const struct telnet_special ssh1_ignore_special[] = {
|
||||
{"IGNORE message", TS_NOP}
|
||||
@ -11126,7 +11128,7 @@ static const struct telnet_special *ssh_get_specials(void *handle)
|
||||
struct telnet_special *specials = NULL;
|
||||
int nspecials = 0, specialsize = 0;
|
||||
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
|
||||
sfree(ssh->specials);
|
||||
|
||||
@ -11196,9 +11198,9 @@ static const struct telnet_special *ssh_get_specials(void *handle)
|
||||
* can send an EOF and collect resulting output (e.g. `plink
|
||||
* hostname sort').
|
||||
*/
|
||||
static void ssh_special(void *handle, Telnet_Special code)
|
||||
static void ssh_special(Backend *be, Telnet_Special code)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
PktOut *pktout;
|
||||
|
||||
if (code == TS_EOF) {
|
||||
@ -11344,9 +11346,9 @@ void ssh_send_packet_from_downstream(Ssh ssh, unsigned id, int type,
|
||||
* This is called when stdout/stderr (the entity to which
|
||||
* from_backend sends data) manages to clear some backlog.
|
||||
*/
|
||||
static void ssh_unthrottle(void *handle, int bufsize)
|
||||
static void ssh_unthrottle(Backend *be, int bufsize)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
|
||||
if (ssh->version == 1) {
|
||||
if (ssh->v1_stdout_throttling && bufsize < SSH1_BUFFER_LIMIT) {
|
||||
@ -11405,21 +11407,21 @@ void ssh_send_port_open(void *channel, const char *hostname, int port,
|
||||
}
|
||||
}
|
||||
|
||||
static int ssh_connected(void *handle)
|
||||
static int ssh_connected(Backend *be)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
return ssh->s != NULL;
|
||||
}
|
||||
|
||||
static int ssh_sendok(void *handle)
|
||||
static int ssh_sendok(Backend *be)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
return ssh->send_ok;
|
||||
}
|
||||
|
||||
static int ssh_ldisc(void *handle, int option)
|
||||
static int ssh_ldisc(Backend *be, int option)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
if (option == LD_ECHO)
|
||||
return ssh->echoing;
|
||||
if (option == LD_EDIT)
|
||||
@ -11427,21 +11429,21 @@ static int ssh_ldisc(void *handle, int option)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void ssh_provide_ldisc(void *handle, Ldisc *ldisc)
|
||||
static void ssh_provide_ldisc(Backend *be, Ldisc *ldisc)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
ssh->ldisc = ldisc;
|
||||
}
|
||||
|
||||
static void ssh_provide_logctx(void *handle, LogContext *logctx)
|
||||
static void ssh_provide_logctx(Backend *be, LogContext *logctx)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
ssh->logctx = logctx;
|
||||
}
|
||||
|
||||
static int ssh_return_exitcode(void *handle)
|
||||
static int ssh_return_exitcode(Backend *be)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
if (ssh->s != NULL)
|
||||
return -1;
|
||||
else
|
||||
@ -11453,9 +11455,9 @@ static int ssh_return_exitcode(void *handle)
|
||||
* (1 or 2 for the full SSH-1 or SSH-2 protocol; -1 for the bare
|
||||
* SSH-2 connection protocol, i.e. a downstream; 0 for not-decided-yet.)
|
||||
*/
|
||||
static int ssh_cfg_info(void *handle)
|
||||
static int ssh_cfg_info(Backend *be)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
if (ssh->version == 0)
|
||||
return 0; /* don't know yet */
|
||||
else if (ssh->bare_connection)
|
||||
@ -11469,13 +11471,13 @@ static int ssh_cfg_info(void *handle)
|
||||
* that fails. This variable is the means by which scp.c can reach
|
||||
* into the SSH code and find out which one it got.
|
||||
*/
|
||||
extern int ssh_fallback_cmd(void *handle)
|
||||
extern int ssh_fallback_cmd(Backend *be)
|
||||
{
|
||||
Ssh ssh = (Ssh) handle;
|
||||
Ssh ssh = FROMFIELD(be, struct ssh_tag, backend);
|
||||
return ssh->fallback_cmd;
|
||||
}
|
||||
|
||||
Backend ssh_backend = {
|
||||
const struct Backend_vtable ssh_backend = {
|
||||
ssh_init,
|
||||
ssh_free,
|
||||
ssh_reconfig,
|
||||
|
2
ssh.h
2
ssh.h
@ -629,7 +629,7 @@ extern const char sshver[];
|
||||
* that fails. This variable is the means by which scp.c can reach
|
||||
* into the SSH code and find out which one it got.
|
||||
*/
|
||||
extern int ssh_fallback_cmd(void *handle);
|
||||
extern int ssh_fallback_cmd(Backend *backend);
|
||||
|
||||
void SHATransform(word32 * digest, word32 * data);
|
||||
|
||||
|
69
telnet.c
69
telnet.c
@ -117,8 +117,6 @@ static const char *telopt(int opt)
|
||||
#undef telnet_str
|
||||
}
|
||||
|
||||
static void telnet_size(void *handle, int width, int height);
|
||||
|
||||
struct Opt {
|
||||
int send; /* what we initially send */
|
||||
int nsend; /* -ve send if requested to stop it */
|
||||
@ -199,6 +197,7 @@ typedef struct telnet_tag {
|
||||
Pinger pinger;
|
||||
|
||||
const Plug_vtable *plugvt;
|
||||
Backend backend;
|
||||
} *Telnet;
|
||||
|
||||
#define TELNET_MAX_BACKLOG 4096
|
||||
@ -280,7 +279,8 @@ static void option_side_effects(Telnet telnet, const struct Opt *o, int enabled)
|
||||
static void activate_option(Telnet telnet, const struct Opt *o)
|
||||
{
|
||||
if (o->send == WILL && o->option == TELOPT_NAWS)
|
||||
telnet_size(telnet, telnet->term_width, telnet->term_height);
|
||||
backend_size(&telnet->backend,
|
||||
telnet->term_width, telnet->term_height);
|
||||
if (o->send == WILL &&
|
||||
(o->option == TELOPT_NEW_ENVIRON ||
|
||||
o->option == TELOPT_OLD_ENVIRON)) {
|
||||
@ -705,7 +705,7 @@ static const Plug_vtable Telnet_plugvt = {
|
||||
* Also places the canonical host name into `realhost'. It must be
|
||||
* freed by the caller.
|
||||
*/
|
||||
static const char *telnet_init(void *frontend_handle, void **backend_handle,
|
||||
static const char *telnet_init(void *frontend_handle, Backend **backend_handle,
|
||||
Conf *conf, const char *host, int port,
|
||||
char **realhost, int nodelay, int keepalive)
|
||||
{
|
||||
@ -717,6 +717,7 @@ static const char *telnet_init(void *frontend_handle, void **backend_handle,
|
||||
|
||||
telnet = snew(struct telnet_tag);
|
||||
telnet->plugvt = &Telnet_plugvt;
|
||||
telnet->backend.vt = &telnet_backend;
|
||||
telnet->conf = conf_copy(conf);
|
||||
telnet->s = NULL;
|
||||
telnet->closed_on_socket_error = FALSE;
|
||||
@ -732,7 +733,7 @@ static const char *telnet_init(void *frontend_handle, void **backend_handle,
|
||||
telnet->ldisc = NULL;
|
||||
telnet->pinger = NULL;
|
||||
telnet->session_started = TRUE;
|
||||
*backend_handle = telnet;
|
||||
*backend_handle = &telnet->backend;
|
||||
|
||||
/*
|
||||
* Try to find host.
|
||||
@ -756,7 +757,7 @@ static const char *telnet_init(void *frontend_handle, void **backend_handle,
|
||||
if ((err = sk_socket_error(telnet->s)) != NULL)
|
||||
return err;
|
||||
|
||||
telnet->pinger = pinger_new(telnet->conf, &telnet_backend, telnet);
|
||||
telnet->pinger = pinger_new(telnet->conf, &telnet->backend);
|
||||
|
||||
/*
|
||||
* Initialise option states.
|
||||
@ -805,9 +806,9 @@ static const char *telnet_init(void *frontend_handle, void **backend_handle,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void telnet_free(void *handle)
|
||||
static void telnet_free(Backend *be)
|
||||
{
|
||||
Telnet telnet = (Telnet) handle;
|
||||
Telnet telnet = FROMFIELD(be, struct telnet_tag, backend);
|
||||
|
||||
sfree(telnet->sb_buf);
|
||||
if (telnet->s)
|
||||
@ -822,9 +823,9 @@ static void telnet_free(void *handle)
|
||||
* necessary, in this backend: we just save the fresh config for
|
||||
* any subsequent negotiations.
|
||||
*/
|
||||
static void telnet_reconfig(void *handle, Conf *conf)
|
||||
static void telnet_reconfig(Backend *be, Conf *conf)
|
||||
{
|
||||
Telnet telnet = (Telnet) handle;
|
||||
Telnet telnet = FROMFIELD(be, struct telnet_tag, backend);
|
||||
pinger_reconfig(telnet->pinger, telnet->conf, conf);
|
||||
conf_free(telnet->conf);
|
||||
telnet->conf = conf_copy(conf);
|
||||
@ -833,9 +834,9 @@ static void telnet_reconfig(void *handle, Conf *conf)
|
||||
/*
|
||||
* Called to send data down the Telnet connection.
|
||||
*/
|
||||
static int telnet_send(void *handle, const char *buf, int len)
|
||||
static int telnet_send(Backend *be, const char *buf, int len)
|
||||
{
|
||||
Telnet telnet = (Telnet) handle;
|
||||
Telnet telnet = FROMFIELD(be, struct telnet_tag, backend);
|
||||
unsigned char *p, *end;
|
||||
static const unsigned char iac[2] = { IAC, IAC };
|
||||
static const unsigned char cr[2] = { CR, NUL };
|
||||
@ -868,18 +869,18 @@ static int telnet_send(void *handle, const char *buf, int len)
|
||||
/*
|
||||
* Called to query the current socket sendability status.
|
||||
*/
|
||||
static int telnet_sendbuffer(void *handle)
|
||||
static int telnet_sendbuffer(Backend *be)
|
||||
{
|
||||
Telnet telnet = (Telnet) handle;
|
||||
Telnet telnet = FROMFIELD(be, struct telnet_tag, backend);
|
||||
return telnet->bufsize;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to set the size of the window from Telnet's POV.
|
||||
*/
|
||||
static void telnet_size(void *handle, int width, int height)
|
||||
static void telnet_size(Backend *be, int width, int height)
|
||||
{
|
||||
Telnet telnet = (Telnet) handle;
|
||||
Telnet telnet = FROMFIELD(be, struct telnet_tag, backend);
|
||||
unsigned char b[24];
|
||||
int n;
|
||||
char *logbuf;
|
||||
@ -913,9 +914,9 @@ static void telnet_size(void *handle, int width, int height)
|
||||
/*
|
||||
* Send Telnet special codes.
|
||||
*/
|
||||
static void telnet_special(void *handle, Telnet_Special code)
|
||||
static void telnet_special(Backend *be, Telnet_Special code)
|
||||
{
|
||||
Telnet telnet = (Telnet) handle;
|
||||
Telnet telnet = FROMFIELD(be, struct telnet_tag, backend);
|
||||
unsigned char b[2];
|
||||
|
||||
if (telnet->s == NULL)
|
||||
@ -1008,7 +1009,7 @@ static void telnet_special(void *handle, Telnet_Special code)
|
||||
}
|
||||
}
|
||||
|
||||
static const struct telnet_special *telnet_get_specials(void *handle)
|
||||
static const struct telnet_special *telnet_get_specials(Backend *be)
|
||||
{
|
||||
static const struct telnet_special specials[] = {
|
||||
{"Are You There", TS_AYT},
|
||||
@ -1031,27 +1032,27 @@ static const struct telnet_special *telnet_get_specials(void *handle)
|
||||
return specials;
|
||||
}
|
||||
|
||||
static int telnet_connected(void *handle)
|
||||
static int telnet_connected(Backend *be)
|
||||
{
|
||||
Telnet telnet = (Telnet) handle;
|
||||
Telnet telnet = FROMFIELD(be, struct telnet_tag, backend);
|
||||
return telnet->s != NULL;
|
||||
}
|
||||
|
||||
static int telnet_sendok(void *handle)
|
||||
static int telnet_sendok(Backend *be)
|
||||
{
|
||||
/* Telnet telnet = (Telnet) handle; */
|
||||
/* Telnet telnet = FROMFIELD(be, struct telnet_tag, backend); */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void telnet_unthrottle(void *handle, int backlog)
|
||||
static void telnet_unthrottle(Backend *be, int backlog)
|
||||
{
|
||||
Telnet telnet = (Telnet) handle;
|
||||
Telnet telnet = FROMFIELD(be, struct telnet_tag, backend);
|
||||
sk_set_frozen(telnet->s, backlog > TELNET_MAX_BACKLOG);
|
||||
}
|
||||
|
||||
static int telnet_ldisc(void *handle, int option)
|
||||
static int telnet_ldisc(Backend *be, int option)
|
||||
{
|
||||
Telnet telnet = (Telnet) handle;
|
||||
Telnet telnet = FROMFIELD(be, struct telnet_tag, backend);
|
||||
if (option == LD_ECHO)
|
||||
return telnet->echoing;
|
||||
if (option == LD_EDIT)
|
||||
@ -1059,20 +1060,20 @@ static int telnet_ldisc(void *handle, int option)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void telnet_provide_ldisc(void *handle, Ldisc *ldisc)
|
||||
static void telnet_provide_ldisc(Backend *be, Ldisc *ldisc)
|
||||
{
|
||||
Telnet telnet = (Telnet) handle;
|
||||
Telnet telnet = FROMFIELD(be, struct telnet_tag, backend);
|
||||
telnet->ldisc = ldisc;
|
||||
}
|
||||
|
||||
static void telnet_provide_logctx(void *handle, LogContext *logctx)
|
||||
static void telnet_provide_logctx(Backend *be, LogContext *logctx)
|
||||
{
|
||||
/* This is a stub. */
|
||||
}
|
||||
|
||||
static int telnet_exitcode(void *handle)
|
||||
static int telnet_exitcode(Backend *be)
|
||||
{
|
||||
Telnet telnet = (Telnet) handle;
|
||||
Telnet telnet = FROMFIELD(be, struct telnet_tag, backend);
|
||||
if (telnet->s != NULL)
|
||||
return -1; /* still connected */
|
||||
else if (telnet->closed_on_socket_error)
|
||||
@ -1085,12 +1086,12 @@ static int telnet_exitcode(void *handle)
|
||||
/*
|
||||
* cfg_info for Telnet does nothing at all.
|
||||
*/
|
||||
static int telnet_cfg_info(void *handle)
|
||||
static int telnet_cfg_info(Backend *be)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Backend telnet_backend = {
|
||||
const struct Backend_vtable telnet_backend = {
|
||||
telnet_init,
|
||||
telnet_free,
|
||||
telnet_reconfig,
|
||||
|
21
terminal.c
21
terminal.c
@ -1693,8 +1693,7 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata,
|
||||
term->lastbeep = FALSE;
|
||||
term->beep_overloaded = FALSE;
|
||||
term->attr_mask = 0xffffffff;
|
||||
term->resize_fn = NULL;
|
||||
term->resize_ctx = NULL;
|
||||
term->backend = NULL;
|
||||
term->in_term_out = FALSE;
|
||||
term->ltemp = NULL;
|
||||
term->ltemp_size = 0;
|
||||
@ -1964,22 +1963,18 @@ void term_size(Terminal *term, int newrows, int newcols, int newsavelines)
|
||||
|
||||
update_sbar(term);
|
||||
term_update(term);
|
||||
if (term->resize_fn)
|
||||
term->resize_fn(term->resize_ctx, term->cols, term->rows);
|
||||
if (term->backend)
|
||||
backend_size(term->backend, term->cols, term->rows);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hand a function and context pointer to the terminal which it can
|
||||
* use to notify a back end of resizes.
|
||||
* Hand a backend to the terminal, so it can be notified of resizes.
|
||||
*/
|
||||
void term_provide_resize_fn(Terminal *term,
|
||||
void (*resize_fn)(void *, int, int),
|
||||
void *resize_ctx)
|
||||
void term_provide_backend(Terminal *term, Backend *backend)
|
||||
{
|
||||
term->resize_fn = resize_fn;
|
||||
term->resize_ctx = resize_ctx;
|
||||
if (resize_fn && term->cols > 0 && term->rows > 0)
|
||||
resize_fn(resize_ctx, term->cols, term->rows);
|
||||
term->backend = backend;
|
||||
if (term->backend && term->cols > 0 && term->rows > 0)
|
||||
backend_size(term->backend, term->cols, term->rows);
|
||||
}
|
||||
|
||||
/* Find the bottom line on the screen that has any content.
|
||||
|
@ -227,8 +227,7 @@ struct terminal_tag {
|
||||
wchar_t *paste_buffer;
|
||||
int paste_len, paste_pos;
|
||||
|
||||
void (*resize_fn)(void *, int, int);
|
||||
void *resize_ctx;
|
||||
Backend *backend;
|
||||
|
||||
Ldisc *ldisc;
|
||||
|
||||
|
90
testback.c
90
testback.c
@ -32,36 +32,36 @@
|
||||
|
||||
#include "putty.h"
|
||||
|
||||
static const char *null_init(void *, void **, Conf *, const char *, int,
|
||||
static const char *null_init(void *, Backend **, Conf *, const char *, int,
|
||||
char **, int, int);
|
||||
static const char *loop_init(void *, void **, Conf *, const char *, int,
|
||||
static const char *loop_init(void *, Backend **, Conf *, const char *, int,
|
||||
char **, int, int);
|
||||
static void null_free(void *);
|
||||
static void loop_free(void *);
|
||||
static void null_reconfig(void *, Conf *);
|
||||
static int null_send(void *, const char *, int);
|
||||
static int loop_send(void *, const char *, int);
|
||||
static int null_sendbuffer(void *);
|
||||
static void null_size(void *, int, int);
|
||||
static void null_special(void *, Telnet_Special);
|
||||
static const struct telnet_special *null_get_specials(void *handle);
|
||||
static int null_connected(void *);
|
||||
static int null_exitcode(void *);
|
||||
static int null_sendok(void *);
|
||||
static int null_ldisc(void *, int);
|
||||
static void null_provide_ldisc(void *, Ldisc *);
|
||||
static void null_provide_logctx(void *, LogContext *);
|
||||
static void null_unthrottle(void *, int);
|
||||
static int null_cfg_info(void *);
|
||||
static void null_free(Backend *);
|
||||
static void loop_free(Backend *);
|
||||
static void null_reconfig(Backend *, Conf *);
|
||||
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 int null_connected(Backend *);
|
||||
static int null_exitcode(Backend *);
|
||||
static int null_sendok(Backend *);
|
||||
static int null_ldisc(Backend *, int);
|
||||
static void null_provide_ldisc(Backend *, Ldisc *);
|
||||
static void null_provide_logctx(Backend *, LogContext *);
|
||||
static void null_unthrottle(Backend *, int);
|
||||
static int null_cfg_info(Backend *);
|
||||
|
||||
Backend null_backend = {
|
||||
const struct Backend_vtable null_backend = {
|
||||
null_init, null_free, null_reconfig, null_send, null_sendbuffer, null_size,
|
||||
null_special, null_get_specials, null_connected, null_exitcode, null_sendok,
|
||||
null_ldisc, null_provide_ldisc, null_provide_logctx, null_unthrottle,
|
||||
null_cfg_info, NULL /* test_for_upstream */, "null", -1, 0
|
||||
};
|
||||
|
||||
Backend loop_backend = {
|
||||
const struct Backend_vtable loop_backend = {
|
||||
loop_init, loop_free, null_reconfig, loop_send, null_sendbuffer, null_size,
|
||||
null_special, null_get_specials, null_connected, null_exitcode, null_sendok,
|
||||
null_ldisc, null_provide_ldisc, null_provide_logctx, null_unthrottle,
|
||||
@ -70,102 +70,104 @@ Backend loop_backend = {
|
||||
|
||||
struct loop_state {
|
||||
Terminal *term;
|
||||
Backend backend;
|
||||
};
|
||||
|
||||
static const char *null_init(void *frontend_handle, void **backend_handle,
|
||||
static const char *null_init(void *frontend_handle, Backend **backend_handle,
|
||||
Conf *conf, const char *host, int port,
|
||||
char **realhost, int nodelay, int keepalive) {
|
||||
|
||||
*backend_handle = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *loop_init(void *frontend_handle, void **backend_handle,
|
||||
static const char *loop_init(void *frontend_handle, Backend **backend_handle,
|
||||
Conf *conf, const char *host, int port,
|
||||
char **realhost, int nodelay, int keepalive) {
|
||||
struct loop_state *st = snew(struct loop_state);
|
||||
|
||||
st->term = frontend_handle;
|
||||
*backend_handle = st;
|
||||
*backend_handle = &st->backend;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void null_free(void *handle)
|
||||
static void null_free(Backend *be)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void loop_free(void *handle)
|
||||
static void loop_free(Backend *be)
|
||||
{
|
||||
struct loop_state *st = FROMFIELD(be, struct loop_state, backend);
|
||||
|
||||
sfree(handle);
|
||||
sfree(st);
|
||||
}
|
||||
|
||||
static void null_reconfig(void *handle, Conf *conf) {
|
||||
static void null_reconfig(Backend *be, Conf *conf) {
|
||||
|
||||
}
|
||||
|
||||
static int null_send(void *handle, const char *buf, int len) {
|
||||
static int null_send(Backend *be, const char *buf, int len) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loop_send(void *handle, const char *buf, int len) {
|
||||
struct loop_state *st = handle;
|
||||
static int loop_send(Backend *be, const char *buf, int len) {
|
||||
struct loop_state *st = FROMFIELD(be, struct loop_state, backend);
|
||||
|
||||
return from_backend(st->term, 0, buf, len);
|
||||
}
|
||||
|
||||
static int null_sendbuffer(void *handle) {
|
||||
static int null_sendbuffer(Backend *be) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void null_size(void *handle, int width, int height) {
|
||||
static void null_size(Backend *be, int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
static void null_special(void *handle, Telnet_Special code) {
|
||||
static void null_special(Backend *be, Telnet_Special code) {
|
||||
|
||||
}
|
||||
|
||||
static const struct telnet_special *null_get_specials (void *handle) {
|
||||
static const struct telnet_special *null_get_specials (Backend *be) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int null_connected(void *handle) {
|
||||
static int null_connected(Backend *be) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int null_exitcode(void *handle) {
|
||||
static int null_exitcode(Backend *be) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int null_sendok(void *handle) {
|
||||
static int null_sendok(Backend *be) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void null_unthrottle(void *handle, int backlog) {
|
||||
static void null_unthrottle(Backend *be, int backlog) {
|
||||
|
||||
}
|
||||
|
||||
static int null_ldisc(void *handle, int option) {
|
||||
static int null_ldisc(Backend *be, int option) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void null_provide_ldisc (void *handle, Ldisc *ldisc) {
|
||||
static void null_provide_ldisc (Backend *be, Ldisc *ldisc) {
|
||||
|
||||
}
|
||||
|
||||
static void null_provide_logctx(void *handle, LogContext *logctx) {
|
||||
static void null_provide_logctx(Backend *be, LogContext *logctx) {
|
||||
|
||||
}
|
||||
|
||||
static int null_cfg_info(void *handle)
|
||||
static int null_cfg_info(Backend *be)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -159,8 +159,7 @@ struct gui_data {
|
||||
char *icontitle;
|
||||
int master_fd, master_func_id;
|
||||
Ldisc *ldisc;
|
||||
Backend *back;
|
||||
void *backhandle;
|
||||
Backend *backend;
|
||||
Terminal *term;
|
||||
LogContext *logctx;
|
||||
int exited;
|
||||
@ -1609,8 +1608,8 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
||||
#ifdef KEY_EVENT_DIAGNOSTICS
|
||||
debug((" - Ctrl-Break special case, sending TS_BRK\n"));
|
||||
#endif
|
||||
if (inst->back)
|
||||
inst->back->special(inst->backhandle, TS_BRK);
|
||||
if (inst->backend)
|
||||
backend_special(inst->backend, TS_BRK);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2399,7 +2398,7 @@ static void exit_callback(void *vinst)
|
||||
int exitcode, close_on_exit;
|
||||
|
||||
if (!inst->exited &&
|
||||
(exitcode = inst->back->exitcode(inst->backhandle)) >= 0) {
|
||||
(exitcode = backend_exitcode(inst->backend)) >= 0) {
|
||||
destroy_inst_connection(inst);
|
||||
|
||||
close_on_exit = conf_get_int(inst->conf, CONF_close_on_exit);
|
||||
@ -2424,13 +2423,12 @@ static void destroy_inst_connection(struct gui_data *inst)
|
||||
ldisc_free(inst->ldisc);
|
||||
inst->ldisc = NULL;
|
||||
}
|
||||
if (inst->backhandle) {
|
||||
inst->back->free(inst->backhandle);
|
||||
inst->backhandle = NULL;
|
||||
inst->back = NULL;
|
||||
if (inst->backend) {
|
||||
backend_free(inst->backend);
|
||||
inst->backend = NULL;
|
||||
}
|
||||
if (inst->term)
|
||||
term_provide_resize_fn(inst->term, NULL, NULL);
|
||||
term_provide_backend(inst->term, NULL);
|
||||
if (inst->menu) {
|
||||
update_specials_menu(inst);
|
||||
gtk_widget_set_sensitive(inst->restartitem, TRUE);
|
||||
@ -4480,8 +4478,8 @@ void special_menuitem(GtkMenuItem *item, gpointer data)
|
||||
int code = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item),
|
||||
"user-data"));
|
||||
|
||||
if (inst->back)
|
||||
inst->back->special(inst->backhandle, code);
|
||||
if (inst->backend)
|
||||
backend_special(inst->backend, code);
|
||||
}
|
||||
|
||||
void about_menuitem(GtkMenuItem *item, gpointer data)
|
||||
@ -4582,7 +4580,7 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data)
|
||||
|
||||
dialog = create_config_box(
|
||||
title, ctx->newconf, 1,
|
||||
inst->back ? inst->back->cfg_info(inst->backhandle) : 0,
|
||||
inst->backend ? backend_cfg_info(inst->backend) : 0,
|
||||
after_change_settings_dialog, ctx);
|
||||
register_dialog(inst, DIALOG_SLOT_RECONFIGURE, dialog);
|
||||
|
||||
@ -4633,8 +4631,8 @@ static void after_change_settings_dialog(void *vctx, int retval)
|
||||
term_reconfig(inst->term, inst->conf);
|
||||
setup_clipboards(inst, inst->term, inst->conf);
|
||||
/* Pass new config data to the back end */
|
||||
if (inst->back)
|
||||
inst->back->reconfig(inst->backhandle, inst->conf);
|
||||
if (inst->backend)
|
||||
backend_reconfig(inst->backend, inst->conf);
|
||||
|
||||
cache_conf_values(inst);
|
||||
|
||||
@ -4851,7 +4849,7 @@ void restart_session_menuitem(GtkMenuItem *item, gpointer data)
|
||||
{
|
||||
struct gui_data *inst = (struct gui_data *)data;
|
||||
|
||||
if (!inst->back) {
|
||||
if (!inst->backend) {
|
||||
logevent(inst, "----- Session restarted -----");
|
||||
term_pwron(inst->term, FALSE);
|
||||
start_backend(inst);
|
||||
@ -4984,8 +4982,8 @@ void update_specials_menu(void *frontend)
|
||||
|
||||
const struct telnet_special *specials;
|
||||
|
||||
if (inst->back)
|
||||
specials = inst->back->get_specials(inst->backhandle);
|
||||
if (inst->backend)
|
||||
specials = backend_get_specials(inst->backend);
|
||||
else
|
||||
specials = NULL;
|
||||
|
||||
@ -5045,20 +5043,20 @@ void update_specials_menu(void *frontend)
|
||||
|
||||
static void start_backend(struct gui_data *inst)
|
||||
{
|
||||
extern Backend *select_backend(Conf *conf);
|
||||
const struct Backend_vtable *vt;
|
||||
char *realhost;
|
||||
const char *error;
|
||||
char *s;
|
||||
|
||||
inst->back = select_backend(inst->conf);
|
||||
vt = select_backend(inst->conf);
|
||||
|
||||
error = inst->back->init((void *)inst, &inst->backhandle,
|
||||
inst->conf,
|
||||
conf_get_str(inst->conf, CONF_host),
|
||||
conf_get_int(inst->conf, CONF_port),
|
||||
&realhost,
|
||||
conf_get_int(inst->conf, CONF_tcp_nodelay),
|
||||
conf_get_int(inst->conf, CONF_tcp_keepalives));
|
||||
error = backend_init(vt, (void *)inst, &inst->backend,
|
||||
inst->conf,
|
||||
conf_get_str(inst->conf, CONF_host),
|
||||
conf_get_int(inst->conf, CONF_port),
|
||||
&realhost,
|
||||
conf_get_int(inst->conf, CONF_tcp_nodelay),
|
||||
conf_get_int(inst->conf, CONF_tcp_keepalives));
|
||||
|
||||
if (error) {
|
||||
char *msg = dupprintf("Unable to open connection to %s:\n%s",
|
||||
@ -5079,13 +5077,11 @@ static void start_backend(struct gui_data *inst)
|
||||
}
|
||||
sfree(realhost);
|
||||
|
||||
inst->back->provide_logctx(inst->backhandle, inst->logctx);
|
||||
backend_provide_logctx(inst->backend, inst->logctx);
|
||||
|
||||
term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle);
|
||||
term_provide_backend(inst->term, inst->backend);
|
||||
|
||||
inst->ldisc =
|
||||
ldisc_create(inst->conf, inst->term, inst->back, inst->backhandle,
|
||||
inst);
|
||||
inst->ldisc = ldisc_create(inst->conf, inst->term, inst->backend, inst);
|
||||
|
||||
gtk_widget_set_sensitive(inst->restartitem, FALSE);
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ struct FontSpec *fontspec_new(const char *name);
|
||||
|
||||
typedef void *Context; /* FIXME: probably needs changing */
|
||||
|
||||
extern Backend pty_backend;
|
||||
extern const struct Backend_vtable pty_backend;
|
||||
|
||||
#define BROKEN_PIPE_ERROR_CODE EPIPE /* used in sshshare.c */
|
||||
|
||||
@ -178,6 +178,8 @@ void window_setup_error(const char *errmsg);
|
||||
GtkWidget *make_gtk_toplevel_window(void *frontend);
|
||||
#endif
|
||||
|
||||
const struct Backend_vtable *select_backend(Conf *conf);
|
||||
|
||||
/* Defined in gtkcomm.c */
|
||||
void gtkcomm_setup(void);
|
||||
|
||||
@ -324,9 +326,9 @@ void *sk_getxdmdata(Socket sock, int *lenp);
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Exports from winser.c.
|
||||
* Exports from uxser.c.
|
||||
*/
|
||||
extern Backend serial_backend;
|
||||
extern const struct Backend_vtable serial_backend;
|
||||
|
||||
/*
|
||||
* uxpeer.c, wrapping getsockopt(SO_PEERCRED).
|
||||
|
@ -91,8 +91,7 @@ void cmdline_error(const char *p, ...)
|
||||
|
||||
static int local_tty = FALSE; /* do we have a local tty? */
|
||||
|
||||
static Backend *back;
|
||||
static void *backhandle;
|
||||
static Backend *backend;
|
||||
static Conf *conf;
|
||||
|
||||
/*
|
||||
@ -459,13 +458,13 @@ static void from_tty(void *vbuf, unsigned len)
|
||||
} else {
|
||||
q = memchr(p, '\xff', end - p);
|
||||
if (q == NULL) q = end;
|
||||
back->send(backhandle, p, q - p);
|
||||
backend_send(backend, p, q - p);
|
||||
p = q;
|
||||
}
|
||||
break;
|
||||
case FF:
|
||||
if (*p == '\xff') {
|
||||
back->send(backhandle, p, 1);
|
||||
backend_send(backend, p, 1);
|
||||
p++;
|
||||
state = NORMAL;
|
||||
} else if (*p == '\0') {
|
||||
@ -475,7 +474,7 @@ static void from_tty(void *vbuf, unsigned len)
|
||||
break;
|
||||
case FF00:
|
||||
if (*p == '\0') {
|
||||
back->special(backhandle, TS_BRK);
|
||||
backend_special(backend, TS_BRK);
|
||||
} else {
|
||||
/*
|
||||
* Pretend that PARMRK wasn't set. This involves
|
||||
@ -494,11 +493,11 @@ static void from_tty(void *vbuf, unsigned len)
|
||||
if (!(orig_termios.c_iflag & IGNPAR)) {
|
||||
/* PE/FE get passed on as NUL. */
|
||||
*p = 0;
|
||||
back->send(backhandle, p, 1);
|
||||
backend_send(backend, p, 1);
|
||||
}
|
||||
} else {
|
||||
/* INPCK not set. Assume we got a parity error. */
|
||||
back->send(backhandle, p, 1);
|
||||
backend_send(backend, p, 1);
|
||||
}
|
||||
}
|
||||
p++;
|
||||
@ -606,6 +605,7 @@ int main(int argc, char **argv)
|
||||
int just_test_share_exists = FALSE;
|
||||
unsigned long now;
|
||||
struct winsize size;
|
||||
const struct Backend_vtable *backvt;
|
||||
|
||||
fdlist = NULL;
|
||||
fdcount = fdsize = 0;
|
||||
@ -643,10 +643,10 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
char *p = getenv("PLINK_PROTOCOL");
|
||||
if (p) {
|
||||
const Backend *b = backend_from_name(p);
|
||||
if (b) {
|
||||
default_protocol = b->protocol;
|
||||
default_port = b->default_port;
|
||||
const struct Backend_vtable *vt = backend_vt_from_name(p);
|
||||
if (vt) {
|
||||
default_protocol = vt->protocol;
|
||||
default_port = vt->default_port;
|
||||
conf_set_int(conf, CONF_protocol, default_protocol);
|
||||
conf_set_int(conf, CONF_port, default_port);
|
||||
}
|
||||
@ -766,8 +766,8 @@ int main(int argc, char **argv)
|
||||
* Select protocol. This is farmed out into a table in a
|
||||
* separate file to enable an ssh-free variant.
|
||||
*/
|
||||
back = backend_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
if (back == NULL) {
|
||||
backvt = backend_vt_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
if (!backvt) {
|
||||
fprintf(stderr,
|
||||
"Internal fault: Unsupported protocol found\n");
|
||||
return 1;
|
||||
@ -817,13 +817,13 @@ int main(int argc, char **argv)
|
||||
conf_set_int(conf, CONF_ssh_simple, TRUE);
|
||||
|
||||
if (just_test_share_exists) {
|
||||
if (!back->test_for_upstream) {
|
||||
if (!backvt->test_for_upstream) {
|
||||
fprintf(stderr, "Connection sharing not supported for connection "
|
||||
"type '%s'\n", back->name);
|
||||
"type '%s'\n", backvt->name);
|
||||
return 1;
|
||||
}
|
||||
if (back->test_for_upstream(conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port), conf))
|
||||
if (backvt->test_for_upstream(conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port), conf))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
@ -845,17 +845,17 @@ int main(int argc, char **argv)
|
||||
__AFL_INIT();
|
||||
#endif
|
||||
|
||||
error = back->init(NULL, &backhandle, conf,
|
||||
conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port),
|
||||
&realhost, nodelay,
|
||||
conf_get_int(conf, CONF_tcp_keepalives));
|
||||
error = backend_init(backvt, NULL, &backend, conf,
|
||||
conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port),
|
||||
&realhost, nodelay,
|
||||
conf_get_int(conf, CONF_tcp_keepalives));
|
||||
if (error) {
|
||||
fprintf(stderr, "Unable to open connection:\n%s\n", error);
|
||||
return 1;
|
||||
}
|
||||
back->provide_logctx(backhandle, logctx);
|
||||
ldisc_create(conf, NULL, back, backhandle, NULL);
|
||||
backend_provide_logctx(backend, logctx);
|
||||
ldisc_create(conf, NULL, backend, NULL);
|
||||
sfree(realhost);
|
||||
}
|
||||
|
||||
@ -885,9 +885,9 @@ int main(int argc, char **argv)
|
||||
FD_SET_MAX(signalpipe[0], maxfd, rset);
|
||||
|
||||
if (!sending &&
|
||||
back->connected(backhandle) &&
|
||||
back->sendok(backhandle) &&
|
||||
back->sendbuffer(backhandle) < MAX_STDIN_BACKLOG) {
|
||||
backend_connected(backend) &&
|
||||
backend_sendok(backend) &&
|
||||
backend_sendbuffer(backend) < MAX_STDIN_BACKLOG) {
|
||||
/* If we're OK to send, then try to read from stdin. */
|
||||
FD_SET_MAX(STDIN_FILENO, maxfd, rset);
|
||||
}
|
||||
@ -988,46 +988,46 @@ int main(int argc, char **argv)
|
||||
/* ignore error */;
|
||||
/* ignore its value; it'll be `x' */
|
||||
if (ioctl(STDIN_FILENO, TIOCGWINSZ, (void *)&size) >= 0)
|
||||
back->size(backhandle, size.ws_col, size.ws_row);
|
||||
backend_size(backend, size.ws_col, size.ws_row);
|
||||
}
|
||||
|
||||
if (FD_ISSET(STDIN_FILENO, &rset)) {
|
||||
char buf[4096];
|
||||
int ret;
|
||||
|
||||
if (back->connected(backhandle)) {
|
||||
if (backend_connected(backend)) {
|
||||
ret = read(STDIN_FILENO, buf, sizeof(buf));
|
||||
if (ret < 0) {
|
||||
perror("stdin: read");
|
||||
exit(1);
|
||||
} else if (ret == 0) {
|
||||
back->special(backhandle, TS_EOF);
|
||||
backend_special(backend, TS_EOF);
|
||||
sending = FALSE; /* send nothing further after this */
|
||||
} else {
|
||||
if (local_tty)
|
||||
from_tty(buf, ret);
|
||||
else
|
||||
back->send(backhandle, buf, ret);
|
||||
backend_send(backend, buf, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(STDOUT_FILENO, &wset)) {
|
||||
back->unthrottle(backhandle, try_output(FALSE));
|
||||
backend_unthrottle(backend, try_output(FALSE));
|
||||
}
|
||||
|
||||
if (FD_ISSET(STDERR_FILENO, &wset)) {
|
||||
back->unthrottle(backhandle, try_output(TRUE));
|
||||
backend_unthrottle(backend, try_output(TRUE));
|
||||
}
|
||||
|
||||
run_toplevel_callbacks();
|
||||
|
||||
if (!back->connected(backhandle) &&
|
||||
if (!backend_connected(backend) &&
|
||||
bufchain_size(&stdout_data) == 0 &&
|
||||
bufchain_size(&stderr_data) == 0)
|
||||
break; /* we closed the connection */
|
||||
}
|
||||
exitcode = back->exitcode(backhandle);
|
||||
exitcode = backend_exitcode(backend);
|
||||
if (exitcode < 0) {
|
||||
fprintf(stderr, "Remote process exit code unavailable\n");
|
||||
exitcode = 1; /* this is an error condition */
|
||||
|
@ -13,7 +13,7 @@ const int new_session = 0, saved_sessions = 0; /* or these */
|
||||
const int dup_check_launchable = 0; /* no need to check host name in conf */
|
||||
const int use_pty_argv = TRUE;
|
||||
|
||||
Backend *select_backend(Conf *conf)
|
||||
const struct Backend_vtable *select_backend(Conf *conf)
|
||||
{
|
||||
return &pty_backend;
|
||||
}
|
||||
|
74
unix/uxpty.c
74
unix/uxpty.c
@ -78,6 +78,7 @@ struct pty_tag {
|
||||
int child_dead, finished;
|
||||
int exit_code;
|
||||
bufchain output_data;
|
||||
Backend backend;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -728,9 +729,9 @@ static void pty_uxsel_setup(Pty pty)
|
||||
* Also places the canonical host name into `realhost'. It must be
|
||||
* freed by the caller.
|
||||
*/
|
||||
static const char *pty_init(void *frontend, void **backend_handle, Conf *conf,
|
||||
const char *host, int port, char **realhost,
|
||||
int nodelay, int keepalive)
|
||||
static const char *pty_init(void *frontend, Backend **backend_handle,
|
||||
Conf *conf, const char *host, int port,
|
||||
char **realhost, int nodelay, int keepalive)
|
||||
{
|
||||
int slavefd;
|
||||
pid_t pid, pgrp;
|
||||
@ -752,7 +753,8 @@ static const char *pty_init(void *frontend, void **backend_handle, Conf *conf,
|
||||
}
|
||||
|
||||
pty->frontend = frontend;
|
||||
*backend_handle = NULL; /* we can't sensibly use this, sadly */
|
||||
pty->backend.vt = &pty_backend;
|
||||
*backend_handle = &pty->backend;
|
||||
|
||||
pty->conf = conf_copy(conf);
|
||||
pty->term_width = conf_get_int(conf, CONF_width);
|
||||
@ -1025,16 +1027,14 @@ static const char *pty_init(void *frontend, void **backend_handle, Conf *conf,
|
||||
}
|
||||
pty_uxsel_setup(pty);
|
||||
|
||||
*backend_handle = pty;
|
||||
|
||||
*realhost = dupstr("");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void pty_reconfig(void *handle, Conf *conf)
|
||||
static void pty_reconfig(Backend *be, Conf *conf)
|
||||
{
|
||||
Pty pty = (Pty)handle;
|
||||
Pty pty = FROMFIELD(be, struct pty_tag, backend);
|
||||
/*
|
||||
* We don't have much need to reconfigure this backend, but
|
||||
* unfortunately we do need to pick up the setting of Close On
|
||||
@ -1046,9 +1046,9 @@ static void pty_reconfig(void *handle, Conf *conf)
|
||||
/*
|
||||
* Stub routine (never called in pterm).
|
||||
*/
|
||||
static void pty_free(void *handle)
|
||||
static void pty_free(Backend *be)
|
||||
{
|
||||
Pty pty = (Pty)handle;
|
||||
Pty pty = FROMFIELD(be, struct pty_tag, backend);
|
||||
|
||||
/* Either of these may fail `not found'. That's fine with us. */
|
||||
del234(ptys_by_pid, pty);
|
||||
@ -1099,9 +1099,9 @@ static void pty_try_write(Pty pty)
|
||||
/*
|
||||
* Called to send data down the pty.
|
||||
*/
|
||||
static int pty_send(void *handle, const char *buf, int len)
|
||||
static int pty_send(Backend *be, const char *buf, int len)
|
||||
{
|
||||
Pty pty = (Pty)handle;
|
||||
Pty pty = FROMFIELD(be, struct pty_tag, backend);
|
||||
|
||||
if (pty->master_fd < 0)
|
||||
return 0; /* ignore all writes if fd closed */
|
||||
@ -1129,18 +1129,18 @@ static void pty_close(Pty pty)
|
||||
/*
|
||||
* Called to query the current socket sendability status.
|
||||
*/
|
||||
static int pty_sendbuffer(void *handle)
|
||||
static int pty_sendbuffer(Backend *be)
|
||||
{
|
||||
/* Pty pty = (Pty)handle; */
|
||||
/* Pty pty = FROMFIELD(be, struct pty_tag, backend); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to set the size of the window
|
||||
*/
|
||||
static void pty_size(void *handle, int width, int height)
|
||||
static void pty_size(Backend *be, int width, int height)
|
||||
{
|
||||
Pty pty = (Pty)handle;
|
||||
Pty pty = FROMFIELD(be, struct pty_tag, backend);
|
||||
struct winsize size;
|
||||
|
||||
pty->term_width = width;
|
||||
@ -1159,9 +1159,9 @@ static void pty_size(void *handle, int width, int height)
|
||||
/*
|
||||
* Send special codes.
|
||||
*/
|
||||
static void pty_special(void *handle, Telnet_Special code)
|
||||
static void pty_special(Backend *be, Telnet_Special code)
|
||||
{
|
||||
/* Pty pty = (Pty)handle; */
|
||||
/* Pty pty = FROMFIELD(be, struct pty_tag, backend); */
|
||||
/* Do nothing! */
|
||||
return;
|
||||
}
|
||||
@ -1170,9 +1170,9 @@ static void pty_special(void *handle, Telnet_Special code)
|
||||
* Return a list of the special codes that make sense in this
|
||||
* protocol.
|
||||
*/
|
||||
static const struct telnet_special *pty_get_specials(void *handle)
|
||||
static const struct telnet_special *pty_get_specials(Backend *be)
|
||||
{
|
||||
/* Pty pty = (Pty)handle; */
|
||||
/* Pty pty = FROMFIELD(be, struct pty_tag, backend); */
|
||||
/*
|
||||
* Hmm. When I get round to having this actually usable, it
|
||||
* might be quite nice to have the ability to deliver a few
|
||||
@ -1182,58 +1182,58 @@ static const struct telnet_special *pty_get_specials(void *handle)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int pty_connected(void *handle)
|
||||
static int pty_connected(Backend *be)
|
||||
{
|
||||
/* Pty pty = (Pty)handle; */
|
||||
/* Pty pty = FROMFIELD(be, struct pty_tag, backend); */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int pty_sendok(void *handle)
|
||||
static int pty_sendok(Backend *be)
|
||||
{
|
||||
/* Pty pty = (Pty)handle; */
|
||||
/* Pty pty = FROMFIELD(be, struct pty_tag, backend); */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void pty_unthrottle(void *handle, int backlog)
|
||||
static void pty_unthrottle(Backend *be, int backlog)
|
||||
{
|
||||
/* Pty pty = (Pty)handle; */
|
||||
/* Pty pty = FROMFIELD(be, struct pty_tag, backend); */
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
static int pty_ldisc(void *handle, int option)
|
||||
static int pty_ldisc(Backend *be, int option)
|
||||
{
|
||||
/* Pty pty = (Pty)handle; */
|
||||
/* Pty pty = FROMFIELD(be, struct pty_tag, backend); */
|
||||
return 0; /* neither editing nor echoing */
|
||||
}
|
||||
|
||||
static void pty_provide_ldisc(void *handle, Ldisc *ldisc)
|
||||
static void pty_provide_ldisc(Backend *be, Ldisc *ldisc)
|
||||
{
|
||||
/* Pty pty = (Pty)handle; */
|
||||
/* Pty pty = FROMFIELD(be, struct pty_tag, backend); */
|
||||
/* This is a stub. */
|
||||
}
|
||||
|
||||
static void pty_provide_logctx(void *handle, LogContext *logctx)
|
||||
static void pty_provide_logctx(Backend *be, LogContext *logctx)
|
||||
{
|
||||
/* Pty pty = (Pty)handle; */
|
||||
/* Pty pty = FROMFIELD(be, struct pty_tag, backend); */
|
||||
/* This is a stub. */
|
||||
}
|
||||
|
||||
static int pty_exitcode(void *handle)
|
||||
static int pty_exitcode(Backend *be)
|
||||
{
|
||||
Pty pty = (Pty)handle;
|
||||
Pty pty = FROMFIELD(be, struct pty_tag, backend);
|
||||
if (!pty->finished)
|
||||
return -1; /* not dead yet */
|
||||
else
|
||||
return pty->exit_code;
|
||||
}
|
||||
|
||||
static int pty_cfg_info(void *handle)
|
||||
static int pty_cfg_info(Backend *be)
|
||||
{
|
||||
/* Pty pty = (Pty)handle; */
|
||||
/* Pty pty = FROMFIELD(be, struct pty_tag, backend); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
Backend pty_backend = {
|
||||
const struct Backend_vtable pty_backend = {
|
||||
pty_init,
|
||||
pty_free,
|
||||
pty_reconfig,
|
||||
|
@ -37,11 +37,12 @@ void cleanup_exit(int code)
|
||||
exit(code);
|
||||
}
|
||||
|
||||
Backend *select_backend(Conf *conf)
|
||||
const struct Backend_vtable *select_backend(Conf *conf)
|
||||
{
|
||||
Backend *back = backend_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
assert(back != NULL);
|
||||
return back;
|
||||
const struct Backend_vtable *vt =
|
||||
backend_vt_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
assert(vt != NULL);
|
||||
return vt;
|
||||
}
|
||||
|
||||
void initial_config_box(Conf *conf, post_dialog_fn_t after, void *afterctx)
|
||||
@ -83,9 +84,10 @@ void setup(int single)
|
||||
default_protocol = be_default_protocol;
|
||||
/* Find the appropriate default port. */
|
||||
{
|
||||
Backend *b = backend_from_proto(default_protocol);
|
||||
const struct Backend_vtable *vt =
|
||||
backend_vt_from_proto(default_protocol);
|
||||
default_port = 0; /* illegal */
|
||||
if (b)
|
||||
default_port = b->default_port;
|
||||
if (vt)
|
||||
default_port = vt->default_port;
|
||||
}
|
||||
}
|
||||
|
52
unix/uxser.c
52
unix/uxser.c
@ -23,6 +23,7 @@ typedef struct serial_backend_data {
|
||||
int finished;
|
||||
int inbufsize;
|
||||
bufchain output_data;
|
||||
Backend backend;
|
||||
} *Serial;
|
||||
|
||||
/*
|
||||
@ -287,7 +288,7 @@ static const char *serial_configure(Serial serial, Conf *conf)
|
||||
* Also places the canonical host name into `realhost'. It must be
|
||||
* freed by the caller.
|
||||
*/
|
||||
static const char *serial_init(void *frontend_handle, void **backend_handle,
|
||||
static const char *serial_init(void *frontend_handle, Backend **backend_handle,
|
||||
Conf *conf,
|
||||
const char *host, int port, char **realhost,
|
||||
int nodelay, int keepalive)
|
||||
@ -297,7 +298,8 @@ static const char *serial_init(void *frontend_handle, void **backend_handle,
|
||||
char *line;
|
||||
|
||||
serial = snew(struct serial_backend_data);
|
||||
*backend_handle = serial;
|
||||
serial->backend.vt = &serial_backend;
|
||||
*backend_handle = &serial->backend;
|
||||
|
||||
serial->frontend = frontend_handle;
|
||||
serial->finished = FALSE;
|
||||
@ -345,9 +347,9 @@ static void serial_close(Serial serial)
|
||||
}
|
||||
}
|
||||
|
||||
static void serial_free(void *handle)
|
||||
static void serial_free(Backend *be)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
|
||||
serial_close(serial);
|
||||
|
||||
@ -356,9 +358,9 @@ static void serial_free(void *handle)
|
||||
sfree(serial);
|
||||
}
|
||||
|
||||
static void serial_reconfig(void *handle, Conf *conf)
|
||||
static void serial_reconfig(Backend *be, Conf *conf)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
|
||||
/*
|
||||
* FIXME: what should we do if this returns an error?
|
||||
@ -460,9 +462,9 @@ static void serial_try_write(Serial serial)
|
||||
/*
|
||||
* Called to send data down the serial connection.
|
||||
*/
|
||||
static int serial_send(void *handle, const char *buf, int len)
|
||||
static int serial_send(Backend *be, const char *buf, int len)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
|
||||
if (serial->fd < 0)
|
||||
return 0;
|
||||
@ -476,16 +478,16 @@ static int serial_send(void *handle, const char *buf, int len)
|
||||
/*
|
||||
* Called to query the current sendability status.
|
||||
*/
|
||||
static int serial_sendbuffer(void *handle)
|
||||
static int serial_sendbuffer(Backend *be)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
return bufchain_size(&serial->output_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to set the size of the window
|
||||
*/
|
||||
static void serial_size(void *handle, int width, int height)
|
||||
static void serial_size(Backend *be, int width, int height)
|
||||
{
|
||||
/* Do nothing! */
|
||||
return;
|
||||
@ -494,9 +496,9 @@ static void serial_size(void *handle, int width, int height)
|
||||
/*
|
||||
* Send serial special codes.
|
||||
*/
|
||||
static void serial_special(void *handle, Telnet_Special code)
|
||||
static void serial_special(Backend *be, Telnet_Special code)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
|
||||
if (serial->fd >= 0 && code == TS_BRK) {
|
||||
tcsendbreak(serial->fd, 0);
|
||||
@ -510,7 +512,7 @@ static void serial_special(void *handle, Telnet_Special code)
|
||||
* Return a list of the special codes that make sense in this
|
||||
* protocol.
|
||||
*/
|
||||
static const struct telnet_special *serial_get_specials(void *handle)
|
||||
static const struct telnet_special *serial_get_specials(Backend *be)
|
||||
{
|
||||
static const struct telnet_special specials[] = {
|
||||
{"Break", TS_BRK},
|
||||
@ -519,24 +521,24 @@ static const struct telnet_special *serial_get_specials(void *handle)
|
||||
return specials;
|
||||
}
|
||||
|
||||
static int serial_connected(void *handle)
|
||||
static int serial_connected(Backend *be)
|
||||
{
|
||||
return 1; /* always connected */
|
||||
}
|
||||
|
||||
static int serial_sendok(void *handle)
|
||||
static int serial_sendok(Backend *be)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void serial_unthrottle(void *handle, int backlog)
|
||||
static void serial_unthrottle(Backend *be, int backlog)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
serial->inbufsize = backlog;
|
||||
serial_uxsel_setup(serial);
|
||||
}
|
||||
|
||||
static int serial_ldisc(void *handle, int option)
|
||||
static int serial_ldisc(Backend *be, int option)
|
||||
{
|
||||
/*
|
||||
* Local editing and local echo are off by default.
|
||||
@ -544,19 +546,19 @@ static int serial_ldisc(void *handle, int option)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void serial_provide_ldisc(void *handle, Ldisc *ldisc)
|
||||
static void serial_provide_ldisc(Backend *be, Ldisc *ldisc)
|
||||
{
|
||||
/* This is a stub. */
|
||||
}
|
||||
|
||||
static void serial_provide_logctx(void *handle, LogContext *logctx)
|
||||
static void serial_provide_logctx(Backend *be, LogContext *logctx)
|
||||
{
|
||||
/* This is a stub. */
|
||||
}
|
||||
|
||||
static int serial_exitcode(void *handle)
|
||||
static int serial_exitcode(Backend *be)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
if (serial->fd >= 0)
|
||||
return -1; /* still connected */
|
||||
else
|
||||
@ -567,12 +569,12 @@ static int serial_exitcode(void *handle)
|
||||
/*
|
||||
* cfg_info for Serial does nothing at all.
|
||||
*/
|
||||
static int serial_cfg_info(void *handle)
|
||||
static int serial_cfg_info(Backend *be)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Backend serial_backend = {
|
||||
const struct Backend_vtable serial_backend = {
|
||||
serial_init,
|
||||
serial_free,
|
||||
serial_reconfig,
|
||||
|
@ -393,7 +393,7 @@ void win_setup_config_box(struct controlbox *b, HWND *hwndp, int has_help,
|
||||
* $XAUTHORITY is not reliable on Windows, so we provide a
|
||||
* means to override it.
|
||||
*/
|
||||
if (!midsession && backend_from_proto(PROT_SSH)) {
|
||||
if (!midsession && backend_vt_from_proto(PROT_SSH)) {
|
||||
s = ctrl_getset(b, "Connection/SSH/X11", "x11", "X11 forwarding");
|
||||
ctrl_filesel(s, "X authority file for local display", 't',
|
||||
NULL, FALSE, "Select X authority file",
|
||||
|
@ -126,8 +126,7 @@ static int caret_x = -1, caret_y = -1;
|
||||
static int kbd_codepage;
|
||||
|
||||
static Ldisc *ldisc;
|
||||
static Backend *back;
|
||||
static void *backhandle;
|
||||
static Backend *backend;
|
||||
|
||||
static struct unicode_data ucsdata;
|
||||
static int session_closed;
|
||||
@ -248,6 +247,7 @@ char *get_ttymode(void *frontend, const char *mode)
|
||||
|
||||
static void start_backend(void)
|
||||
{
|
||||
const struct Backend_vtable *vt;
|
||||
const char *error;
|
||||
char msg[1024], *title;
|
||||
char *realhost;
|
||||
@ -257,8 +257,8 @@ static void start_backend(void)
|
||||
* Select protocol. This is farmed out into a table in a
|
||||
* separate file to enable an ssh-free variant.
|
||||
*/
|
||||
back = backend_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
if (back == NULL) {
|
||||
vt = backend_vt_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
if (!vt) {
|
||||
char *str = dupprintf("%s Internal Error", appname);
|
||||
MessageBox(NULL, "Unsupported protocol number found",
|
||||
str, MB_OK | MB_ICONEXCLAMATION);
|
||||
@ -266,13 +266,13 @@ static void start_backend(void)
|
||||
cleanup_exit(1);
|
||||
}
|
||||
|
||||
error = back->init(NULL, &backhandle, conf,
|
||||
conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port),
|
||||
&realhost,
|
||||
conf_get_int(conf, CONF_tcp_nodelay),
|
||||
conf_get_int(conf, CONF_tcp_keepalives));
|
||||
back->provide_logctx(backhandle, logctx);
|
||||
error = backend_init(vt, NULL, &backend, conf,
|
||||
conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port),
|
||||
&realhost,
|
||||
conf_get_int(conf, CONF_tcp_nodelay),
|
||||
conf_get_int(conf, CONF_tcp_keepalives));
|
||||
backend_provide_logctx(backend, logctx);
|
||||
if (error) {
|
||||
char *str = dupprintf("%s Error", appname);
|
||||
sprintf(msg, "Unable to open connection to\n"
|
||||
@ -294,12 +294,12 @@ static void start_backend(void)
|
||||
/*
|
||||
* Connect the terminal to the backend for resize purposes.
|
||||
*/
|
||||
term_provide_resize_fn(term, back->size, backhandle);
|
||||
term_provide_backend(term, backend);
|
||||
|
||||
/*
|
||||
* Set up a line discipline.
|
||||
*/
|
||||
ldisc = ldisc_create(conf, term, back, backhandle, NULL);
|
||||
ldisc = ldisc_create(conf, term, backend, NULL);
|
||||
|
||||
/*
|
||||
* Destroy the Restart Session menu item. (This will return
|
||||
@ -329,11 +329,10 @@ static void close_session(void *ignored_context)
|
||||
ldisc_free(ldisc);
|
||||
ldisc = NULL;
|
||||
}
|
||||
if (back) {
|
||||
back->free(backhandle);
|
||||
backhandle = NULL;
|
||||
back = NULL;
|
||||
term_provide_resize_fn(term, NULL, NULL);
|
||||
if (backend) {
|
||||
backend_free(backend);
|
||||
backend = NULL;
|
||||
term_provide_backend(term, NULL);
|
||||
update_specials_menu(NULL);
|
||||
}
|
||||
|
||||
@ -413,10 +412,11 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
default_protocol = be_default_protocol;
|
||||
/* Find the appropriate default port. */
|
||||
{
|
||||
Backend *b = backend_from_proto(default_protocol);
|
||||
const struct Backend_vtable *vt =
|
||||
backend_vt_from_proto(default_protocol);
|
||||
default_port = 0; /* illegal */
|
||||
if (b)
|
||||
default_port = b->default_port;
|
||||
if (vt)
|
||||
default_port = vt->default_port;
|
||||
}
|
||||
conf_set_int(conf, CONF_logtype, LGTYP_NONE);
|
||||
|
||||
@ -951,8 +951,8 @@ void update_specials_menu(void *frontend)
|
||||
HMENU new_menu;
|
||||
int i, j;
|
||||
|
||||
if (back)
|
||||
specials = back->get_specials(backhandle);
|
||||
if (backend)
|
||||
specials = backend_get_specials(backend);
|
||||
else
|
||||
specials = NULL;
|
||||
|
||||
@ -1975,7 +1975,7 @@ void notify_remote_exit(void *fe)
|
||||
int exitcode, close_on_exit;
|
||||
|
||||
if (!session_closed &&
|
||||
(exitcode = back->exitcode(backhandle)) >= 0) {
|
||||
(exitcode = backend_exitcode(backend)) >= 0) {
|
||||
close_on_exit = conf_get_int(conf, CONF_close_on_exit);
|
||||
/* Abnormal exits will already have set session_closed and taken
|
||||
* appropriate action. */
|
||||
@ -2161,7 +2161,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
||||
}
|
||||
break;
|
||||
case IDM_RESTART:
|
||||
if (!back) {
|
||||
if (!backend) {
|
||||
logevent(NULL, "----- Session restarted -----");
|
||||
term_pwron(term, FALSE);
|
||||
start_backend();
|
||||
@ -2190,7 +2190,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
||||
prev_conf = conf_copy(conf);
|
||||
|
||||
reconfig_result =
|
||||
do_reconfig(hwnd, back ? back->cfg_info(backhandle) : 0);
|
||||
do_reconfig(hwnd, backend ? backend_cfg_info(backend) : 0);
|
||||
reconfiguring = FALSE;
|
||||
if (!reconfig_result) {
|
||||
conf_free(prev_conf);
|
||||
@ -2237,8 +2237,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
||||
setup_clipboards(term, conf);
|
||||
|
||||
/* Pass new config data to the back end */
|
||||
if (back)
|
||||
back->reconfig(backhandle, conf);
|
||||
if (backend)
|
||||
backend_reconfig(backend, conf);
|
||||
|
||||
/* Screen size changed ? */
|
||||
if (conf_get_int(conf, CONF_height) !=
|
||||
@ -2414,8 +2414,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
|
||||
*/
|
||||
if (i >= n_specials)
|
||||
break;
|
||||
if (back)
|
||||
back->special(backhandle, specials[i].code);
|
||||
if (backend)
|
||||
backend_special(backend, specials[i].code);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -4405,8 +4405,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
|
||||
return p - output;
|
||||
}
|
||||
if (wParam == VK_CANCEL && shift_state == 2) { /* Ctrl-Break */
|
||||
if (back)
|
||||
back->special(backhandle, TS_BRK);
|
||||
if (backend)
|
||||
backend_special(backend, TS_BRK);
|
||||
return 0;
|
||||
}
|
||||
if (wParam == VK_PAUSE) { /* Break/Pause */
|
||||
|
@ -76,8 +76,7 @@ DWORD orig_console_mode;
|
||||
|
||||
WSAEVENT netevent;
|
||||
|
||||
static Backend *back;
|
||||
static void *backhandle;
|
||||
static Backend *backend;
|
||||
static Conf *conf;
|
||||
|
||||
int term_ldisc(Terminal *term, int mode)
|
||||
@ -254,11 +253,11 @@ int stdin_gotdata(struct handle *h, void *data, int len)
|
||||
cleanup_exit(0);
|
||||
}
|
||||
noise_ultralight(len);
|
||||
if (back->connected(backhandle)) {
|
||||
if (backend_connected(backend)) {
|
||||
if (len > 0) {
|
||||
return back->send(backhandle, data, len);
|
||||
return backend_send(backend, data, len);
|
||||
} else {
|
||||
back->special(backhandle, TS_EOF);
|
||||
backend_special(backend, TS_EOF);
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
@ -281,9 +280,9 @@ void stdouterr_sent(struct handle *h, int new_backlog)
|
||||
(h == stdout_handle ? "output" : "error"), buf);
|
||||
cleanup_exit(0);
|
||||
}
|
||||
if (back->connected(backhandle)) {
|
||||
back->unthrottle(backhandle, (handle_backlog(stdout_handle) +
|
||||
handle_backlog(stderr_handle)));
|
||||
if (backend_connected(backend)) {
|
||||
backend_unthrottle(backend, (handle_backlog(stdout_handle) +
|
||||
handle_backlog(stderr_handle)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -300,6 +299,7 @@ int main(int argc, char **argv)
|
||||
int use_subsystem = 0;
|
||||
int just_test_share_exists = FALSE;
|
||||
unsigned long now, next, then;
|
||||
const struct Backend_vtable *vt;
|
||||
|
||||
dll_hijacking_protection();
|
||||
|
||||
@ -334,10 +334,10 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
char *p = getenv("PLINK_PROTOCOL");
|
||||
if (p) {
|
||||
const Backend *b = backend_from_name(p);
|
||||
if (b) {
|
||||
default_protocol = b->protocol;
|
||||
default_port = b->default_port;
|
||||
const struct Backend_vtable *vt = backend_vt_from_name(p);
|
||||
if (vt) {
|
||||
default_protocol = vt->protocol;
|
||||
default_port = vt->default_port;
|
||||
conf_set_int(conf, CONF_protocol, default_protocol);
|
||||
conf_set_int(conf, CONF_port, default_port);
|
||||
}
|
||||
@ -432,8 +432,8 @@ int main(int argc, char **argv)
|
||||
* Select protocol. This is farmed out into a table in a
|
||||
* separate file to enable an ssh-free variant.
|
||||
*/
|
||||
back = backend_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
if (back == NULL) {
|
||||
vt = backend_vt_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
if (vt == NULL) {
|
||||
fprintf(stderr,
|
||||
"Internal fault: Unsupported protocol found\n");
|
||||
return 1;
|
||||
@ -460,13 +460,13 @@ int main(int argc, char **argv)
|
||||
console_provide_logctx(logctx);
|
||||
|
||||
if (just_test_share_exists) {
|
||||
if (!back->test_for_upstream) {
|
||||
if (!vt->test_for_upstream) {
|
||||
fprintf(stderr, "Connection sharing not supported for connection "
|
||||
"type '%s'\n", back->name);
|
||||
"type '%s'\n", vt->name);
|
||||
return 1;
|
||||
}
|
||||
if (back->test_for_upstream(conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port), conf))
|
||||
if (vt->test_for_upstream(conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port), conf))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
@ -487,16 +487,16 @@ int main(int argc, char **argv)
|
||||
int nodelay = conf_get_int(conf, CONF_tcp_nodelay) &&
|
||||
(GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_CHAR);
|
||||
|
||||
error = back->init(NULL, &backhandle, conf,
|
||||
conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port),
|
||||
&realhost, nodelay,
|
||||
conf_get_int(conf, CONF_tcp_keepalives));
|
||||
error = backend_init(vt, NULL, &backend, conf,
|
||||
conf_get_str(conf, CONF_host),
|
||||
conf_get_int(conf, CONF_port),
|
||||
&realhost, nodelay,
|
||||
conf_get_int(conf, CONF_tcp_keepalives));
|
||||
if (error) {
|
||||
fprintf(stderr, "Unable to open connection:\n%s", error);
|
||||
return 1;
|
||||
}
|
||||
back->provide_logctx(backhandle, logctx);
|
||||
backend_provide_logctx(backend, logctx);
|
||||
sfree(realhost);
|
||||
}
|
||||
|
||||
@ -532,7 +532,7 @@ int main(int argc, char **argv)
|
||||
int n;
|
||||
DWORD ticks;
|
||||
|
||||
if (!sending && back->sendok(backhandle)) {
|
||||
if (!sending && backend_sendok(backend)) {
|
||||
stdin_handle = handle_input_new(inhandle, stdin_gotdata, NULL,
|
||||
0);
|
||||
sending = TRUE;
|
||||
@ -643,13 +643,13 @@ int main(int argc, char **argv)
|
||||
sfree(handles);
|
||||
|
||||
if (sending)
|
||||
handle_unthrottle(stdin_handle, back->sendbuffer(backhandle));
|
||||
handle_unthrottle(stdin_handle, backend_sendbuffer(backend));
|
||||
|
||||
if (!back->connected(backhandle) &&
|
||||
if (!backend_connected(backend) &&
|
||||
handle_backlog(stdout_handle) + handle_backlog(stderr_handle) == 0)
|
||||
break; /* we closed the connection */
|
||||
}
|
||||
exitcode = back->exitcode(backhandle);
|
||||
exitcode = backend_exitcode(backend);
|
||||
if (exitcode < 0) {
|
||||
fprintf(stderr, "Remote process exit code unavailable\n");
|
||||
exitcode = 1; /* this is an error condition */
|
||||
|
@ -17,6 +17,7 @@ typedef struct serial_backend_data {
|
||||
int bufsize;
|
||||
long clearbreak_time;
|
||||
int break_in_progress;
|
||||
Backend backend;
|
||||
} *Serial;
|
||||
|
||||
static void serial_terminate(Serial serial)
|
||||
@ -198,7 +199,7 @@ static const char *serial_configure(Serial serial, HANDLE serport, Conf *conf)
|
||||
* Also places the canonical host name into `realhost'. It must be
|
||||
* freed by the caller.
|
||||
*/
|
||||
static const char *serial_init(void *frontend_handle, void **backend_handle,
|
||||
static const char *serial_init(void *frontend_handle, Backend **backend_handle,
|
||||
Conf *conf, const char *host, int port,
|
||||
char **realhost, int nodelay, int keepalive)
|
||||
{
|
||||
@ -212,7 +213,8 @@ static const char *serial_init(void *frontend_handle, void **backend_handle,
|
||||
serial->out = serial->in = NULL;
|
||||
serial->bufsize = 0;
|
||||
serial->break_in_progress = FALSE;
|
||||
*backend_handle = serial;
|
||||
serial->backend.vt = &serial_backend;
|
||||
*backend_handle = &serial->backend;
|
||||
|
||||
serial->frontend = frontend_handle;
|
||||
|
||||
@ -279,18 +281,18 @@ static const char *serial_init(void *frontend_handle, void **backend_handle,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void serial_free(void *handle)
|
||||
static void serial_free(Backend *be)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
|
||||
serial_terminate(serial);
|
||||
expire_timer_context(serial);
|
||||
sfree(serial);
|
||||
}
|
||||
|
||||
static void serial_reconfig(void *handle, Conf *conf)
|
||||
static void serial_reconfig(Backend *be, Conf *conf)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
|
||||
serial_configure(serial, serial->port, conf);
|
||||
|
||||
@ -303,9 +305,9 @@ static void serial_reconfig(void *handle, Conf *conf)
|
||||
/*
|
||||
* Called to send data down the serial connection.
|
||||
*/
|
||||
static int serial_send(void *handle, const char *buf, int len)
|
||||
static int serial_send(Backend *be, const char *buf, int len)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
|
||||
if (serial->out == NULL)
|
||||
return 0;
|
||||
@ -317,16 +319,16 @@ static int serial_send(void *handle, const char *buf, int len)
|
||||
/*
|
||||
* Called to query the current sendability status.
|
||||
*/
|
||||
static int serial_sendbuffer(void *handle)
|
||||
static int serial_sendbuffer(Backend *be)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
return serial->bufsize;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to set the size of the window
|
||||
*/
|
||||
static void serial_size(void *handle, int width, int height)
|
||||
static void serial_size(Backend *be, int width, int height)
|
||||
{
|
||||
/* Do nothing! */
|
||||
return;
|
||||
@ -346,9 +348,9 @@ static void serbreak_timer(void *ctx, unsigned long now)
|
||||
/*
|
||||
* Send serial special codes.
|
||||
*/
|
||||
static void serial_special(void *handle, Telnet_Special code)
|
||||
static void serial_special(Backend *be, Telnet_Special code)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
|
||||
if (serial->port && code == TS_BRK) {
|
||||
logevent(serial->frontend, "Starting serial break at user request");
|
||||
@ -375,7 +377,7 @@ static void serial_special(void *handle, Telnet_Special code)
|
||||
* Return a list of the special codes that make sense in this
|
||||
* protocol.
|
||||
*/
|
||||
static const struct telnet_special *serial_get_specials(void *handle)
|
||||
static const struct telnet_special *serial_get_specials(Backend *be)
|
||||
{
|
||||
static const struct telnet_special specials[] = {
|
||||
{"Break", TS_BRK},
|
||||
@ -384,24 +386,24 @@ static const struct telnet_special *serial_get_specials(void *handle)
|
||||
return specials;
|
||||
}
|
||||
|
||||
static int serial_connected(void *handle)
|
||||
static int serial_connected(Backend *be)
|
||||
{
|
||||
return 1; /* always connected */
|
||||
}
|
||||
|
||||
static int serial_sendok(void *handle)
|
||||
static int serial_sendok(Backend *be)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void serial_unthrottle(void *handle, int backlog)
|
||||
static void serial_unthrottle(Backend *be, int backlog)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
if (serial->in)
|
||||
handle_unthrottle(serial->in, backlog);
|
||||
}
|
||||
|
||||
static int serial_ldisc(void *handle, int option)
|
||||
static int serial_ldisc(Backend *be, int option)
|
||||
{
|
||||
/*
|
||||
* Local editing and local echo are off by default.
|
||||
@ -409,19 +411,19 @@ static int serial_ldisc(void *handle, int option)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void serial_provide_ldisc(void *handle, Ldisc *ldisc)
|
||||
static void serial_provide_ldisc(Backend *be, Ldisc *ldisc)
|
||||
{
|
||||
/* This is a stub. */
|
||||
}
|
||||
|
||||
static void serial_provide_logctx(void *handle, LogContext *logctx)
|
||||
static void serial_provide_logctx(Backend *be, LogContext *logctx)
|
||||
{
|
||||
/* This is a stub. */
|
||||
}
|
||||
|
||||
static int serial_exitcode(void *handle)
|
||||
static int serial_exitcode(Backend *be)
|
||||
{
|
||||
Serial serial = (Serial) handle;
|
||||
Serial serial = FROMFIELD(be, struct serial_backend_data, backend);
|
||||
if (serial->port != INVALID_HANDLE_VALUE)
|
||||
return -1; /* still connected */
|
||||
else
|
||||
@ -432,12 +434,12 @@ static int serial_exitcode(void *handle)
|
||||
/*
|
||||
* cfg_info for Serial does nothing at all.
|
||||
*/
|
||||
static int serial_cfg_info(void *handle)
|
||||
static int serial_cfg_info(Backend *be)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Backend serial_backend = {
|
||||
const struct Backend_vtable serial_backend = {
|
||||
serial_init,
|
||||
serial_free,
|
||||
serial_reconfig,
|
||||
|
@ -596,7 +596,7 @@ void agent_schedule_callback(void (*callback)(void *, void *, int),
|
||||
/*
|
||||
* Exports from winser.c.
|
||||
*/
|
||||
extern Backend serial_backend;
|
||||
extern const struct Backend_vtable serial_backend;
|
||||
|
||||
/*
|
||||
* Exports from winjump.c.
|
||||
|
Loading…
Reference in New Issue
Block a user