1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-02 20: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:
Simon Tatham
2018-09-11 16:23:38 +01:00
parent c51fe7c217
commit eefebaaa9e
36 changed files with 633 additions and 611 deletions

View File

@ -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 */