mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-01 11:32: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:
@ -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,
|
||||
|
Reference in New Issue
Block a user