mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-06-30 19:12:48 -05: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:
@ -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.
|
||||
|
Reference in New Issue
Block a user