SEENSB, SUBNEGOT, SUBNEG_IAC, SEENCR
} state;
+ Config cfg;
} *Telnet;
#define TELNET_MAX_BACKLOG 4096
b[1] = SB;
b[2] = TELOPT_TSPEED;
b[3] = TELQUAL_IS;
- strcpy((char *)(b + 4), cfg.termspeed);
- n = 4 + strlen(cfg.termspeed);
+ strcpy((char *)(b + 4), telnet->cfg.termspeed);
+ n = 4 + strlen(telnet->cfg.termspeed);
b[n] = IAC;
b[n + 1] = SE;
telnet->bufsize = sk_write(telnet->s, (char *)b, n + 2);
logevent(telnet->frontend, "server:\tSB TSPEED SEND");
- logbuf = dupprintf("client:\tSB TSPEED IS %s", cfg.termspeed);
+ logbuf = dupprintf("client:\tSB TSPEED IS %s", telnet->cfg.termspeed);
logevent(telnet->frontend, logbuf);
sfree(logbuf);
} else
b[1] = SB;
b[2] = TELOPT_TTYPE;
b[3] = TELQUAL_IS;
- for (n = 0; cfg.termtype[n]; n++)
- b[n + 4] = (cfg.termtype[n] >= 'a'
- && cfg.termtype[n] <=
- 'z' ? cfg.termtype[n] + 'A' -
- 'a' : cfg.termtype[n]);
+ for (n = 0; telnet->cfg.termtype[n]; n++)
+ b[n + 4] = (telnet->cfg.termtype[n] >= 'a'
+ && telnet->cfg.termtype[n] <=
+ 'z' ? telnet->cfg.termtype[n] + 'A' -
+ 'a' : telnet->cfg.termtype[n]);
b[n + 4] = IAC;
b[n + 5] = SE;
telnet->bufsize = sk_write(telnet->s, (char *)b, n + 6);
logevent(telnet->frontend, logbuf);
sfree(logbuf);
if (telnet->sb_opt == TELOPT_OLD_ENVIRON) {
- if (cfg.rfc_environ) {
+ if (telnet->cfg.rfc_environ) {
value = RFC_VALUE;
var = RFC_VAR;
} else {
b[2] = telnet->sb_opt;
b[3] = TELQUAL_IS;
n = 4;
- e = cfg.environmt;
+ e = telnet->cfg.environmt;
while (*e) {
b[n++] = var;
while (*e && *e != '\t')
b[n++] = *e++;
e++;
}
- if (*cfg.username) {
+ if (*telnet->cfg.username) {
b[n++] = var;
b[n++] = 'U';
b[n++] = 'S';
b[n++] = 'E';
b[n++] = 'R';
b[n++] = value;
- e = cfg.username;
+ e = telnet->cfg.username;
while (*e)
b[n++] = *e++;
}
* freed by the caller.
*/
static char *telnet_init(void *frontend_handle, void **backend_handle,
+ Config *cfg,
char *host, int port, char **realhost, int nodelay)
{
static const struct plug_function_table fn_table = {
telnet = smalloc(sizeof(*telnet));
telnet->fn = &fn_table;
+ telnet->cfg = *cfg; /* STRUCTURE COPY */
telnet->s = NULL;
telnet->echoing = TRUE;
telnet->editing = TRUE;
telnet->sb_buf = NULL;
telnet->sb_size = 0;
telnet->frontend = frontend_handle;
- telnet->term_width = cfg.width;
- telnet->term_height = cfg.height;
+ telnet->term_width = telnet->cfg.width;
+ telnet->term_height = telnet->cfg.height;
telnet->state = TOP_LEVEL;
*backend_handle = telnet;
logevent(telnet->frontend, buf);
sfree(buf);
}
- addr = name_lookup(host, port, realhost);
+ addr = name_lookup(host, port, realhost, &telnet->cfg);
if ((err = sk_addr_error(addr)) != NULL)
return err;
sfree(buf);
}
telnet->s = new_connection(addr, *realhost, port, 0, 1,
- nodelay, (Plug) telnet);
+ nodelay, (Plug) telnet, &telnet->cfg);
if ((err = sk_socket_error(telnet->s)) != NULL)
return err;
/*
* Initialise option states.
*/
- if (cfg.passive_telnet) {
+ if (telnet->cfg.passive_telnet) {
const struct Opt *const *o;
for (o = opts; *o; o++)
return NULL;
}
+static void telnet_free(void *handle)
+{
+ Telnet telnet = (Telnet) handle;
+
+ sfree(telnet->sb_buf);
+ if (telnet->s)
+ sk_close(telnet->s);
+ sfree(telnet);
+}
+/*
+ * Reconfigure the Telnet backend. There's no immediate action
+ * necessary, in this backend: we just save the fresh config for
+ * any subsequent negotiations.
+ */
+static void telnet_reconfig(void *handle, Config *cfg)
+{
+ Telnet telnet = (Telnet) handle;
+ telnet->cfg = *cfg; /* STRUCTURE COPY */
+}
+
/*
* Called to send data down the Telnet connection.
*/
{
Telnet telnet = (Telnet) handle;
unsigned char *p, *end;
- static unsigned char iac[2] = { IAC, IAC };
- static unsigned char cr[2] = { CR, NUL };
+ static const unsigned char iac[2] = { IAC, IAC };
+ static const unsigned char cr[2] = { CR, NUL };
#if 0
- static unsigned char nl[2] = { CR, LF };
+ static const unsigned char nl[2] = { CR, LF };
#endif
if (telnet->s == NULL)
Backend telnet_backend = {
telnet_init,
+ telnet_free,
+ telnet_reconfig,
telnet_send,
telnet_sendbuffer,
telnet_size,