SEENSB, SUBNEGOT, SUBNEG_IAC, SEENCR
} state;
- Config cfg;
+ Conf *conf;
Pinger pinger;
} *Telnet;
static void process_subneg(Telnet telnet)
{
- unsigned char b[2048], *p, *q;
- int var, value, n;
- char *e;
+ unsigned char *b, *p, *q;
+ int var, value, n, bsize;
+ char *e, *eval, *ekey, *user;
switch (telnet->sb_opt) {
case TELOPT_TSPEED:
if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) {
char *logbuf;
+ char *termspeed = conf_get_str(telnet->conf, CONF_termspeed);
+ b = snewn(20 + strlen(termspeed), unsigned char);
b[0] = IAC;
b[1] = SB;
b[2] = TELOPT_TSPEED;
b[3] = TELQUAL_IS;
- strcpy((char *)(b + 4), telnet->cfg.termspeed);
- n = 4 + strlen(telnet->cfg.termspeed);
+ strcpy((char *)(b + 4), termspeed);
+ n = 4 + strlen(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", telnet->cfg.termspeed);
+ logbuf = dupprintf("client:\tSB TSPEED IS %s", termspeed);
logevent(telnet->frontend, logbuf);
sfree(logbuf);
+ sfree(b);
} else
logevent(telnet->frontend, "server:\tSB TSPEED <something weird>");
break;
case TELOPT_TTYPE:
if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) {
char *logbuf;
+ char *termtype = conf_get_str(telnet->conf, CONF_termtype);
+ b = snewn(20 + strlen(termtype), unsigned char);
b[0] = IAC;
b[1] = SB;
b[2] = TELOPT_TTYPE;
b[3] = TELQUAL_IS;
- 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]);
+ for (n = 0; termtype[n]; n++)
+ b[n + 4] = (termtype[n] >= 'a' && termtype[n] <= 'z' ?
+ termtype[n] + 'A' - 'a' :
+ termtype[n]);
b[n + 4] = IAC;
b[n + 5] = SE;
telnet->bufsize = sk_write(telnet->s, (char *)b, n + 6);
logbuf = dupprintf("client:\tSB TTYPE IS %s", b + 4);
logevent(telnet->frontend, logbuf);
sfree(logbuf);
+ sfree(b);
} else
logevent(telnet->frontend, "server:\tSB TTYPE <something weird>\r\n");
break;
logevent(telnet->frontend, logbuf);
sfree(logbuf);
if (telnet->sb_opt == TELOPT_OLD_ENVIRON) {
- if (telnet->cfg.rfc_environ) {
+ if (conf_get_int(telnet->conf, CONF_rfc_environ)) {
value = RFC_VALUE;
var = RFC_VAR;
} else {
value = RFC_VALUE;
var = RFC_VAR;
}
+ bsize = 20;
+ for (eval = conf_get_str_strs(telnet->conf, CONF_environmt,
+ NULL, &ekey);
+ eval != NULL;
+ eval = conf_get_str_strs(telnet->conf, CONF_environmt,
+ ekey, &ekey))
+ bsize += strlen(ekey) + strlen(eval) + 2;
+ user = get_remote_username(telnet->conf);
+ if (user)
+ bsize += 6 + strlen(user);
+
+ b = snewn(bsize, unsigned char);
b[0] = IAC;
b[1] = SB;
b[2] = telnet->sb_opt;
b[3] = TELQUAL_IS;
n = 4;
- e = telnet->cfg.environmt;
- while (*e) {
+ for (eval = conf_get_str_strs(telnet->conf, CONF_environmt,
+ NULL, &ekey);
+ eval != NULL;
+ eval = conf_get_str_strs(telnet->conf, CONF_environmt,
+ ekey, &ekey)) {
b[n++] = var;
- while (*e && *e != '\t')
- b[n++] = *e++;
- if (*e == '\t')
- e++;
+ for (e = ekey; *e; e++)
+ b[n++] = *e;
b[n++] = value;
- while (*e)
- b[n++] = *e++;
- e++;
+ for (e = eval; *e; e++)
+ b[n++] = *e;
}
- if (*telnet->cfg.username) {
+ if (user) {
b[n++] = var;
b[n++] = 'U';
b[n++] = 'S';
b[n++] = 'E';
b[n++] = 'R';
b[n++] = value;
- e = telnet->cfg.username;
- while (*e)
- b[n++] = *e++;
+ for (e = user; *e; e++)
+ b[n++] = *e;
}
b[n++] = IAC;
b[n++] = SE;
telnet->bufsize = sk_write(telnet->s, (char *)b, n);
- logbuf = dupprintf("client:\tSB %s IS %s%s%s%s",
- telopt(telnet->sb_opt),
- *telnet->cfg.username ? "USER=" : "",
- telnet->cfg.username,
- *telnet->cfg.username ? " " : "",
- n == 6 ? "<nothing>" :
- (*telnet->cfg.environmt ? "<stuff>" : ""));
- logevent(telnet->frontend, logbuf);
- sfree(logbuf);
+ if (n == 6) {
+ logbuf = dupprintf("client:\tSB %s IS <nothing>",
+ telopt(telnet->sb_opt));
+ logevent(telnet->frontend, logbuf);
+ sfree(logbuf);
+ } else {
+ logbuf = dupprintf("client:\tSB %s IS:",
+ telopt(telnet->sb_opt));
+ logevent(telnet->frontend, logbuf);
+ sfree(logbuf);
+ for (eval = conf_get_str_strs(telnet->conf, CONF_environmt,
+ NULL, &ekey);
+ eval != NULL;
+ eval = conf_get_str_strs(telnet->conf, CONF_environmt,
+ ekey, &ekey)) {
+ logbuf = dupprintf("\t%s=%s", ekey, eval);
+ logevent(telnet->frontend, logbuf);
+ sfree(logbuf);
+ }
+ if (user) {
+ logbuf = dupprintf("\tUSER=%s", user);
+ logevent(telnet->frontend, logbuf);
+ sfree(logbuf);
+ }
+ }
+ sfree(b);
+ sfree(user);
}
break;
}
* freed by the caller.
*/
static const char *telnet_init(void *frontend_handle, void **backend_handle,
- Config *cfg,
- char *host, int port, char **realhost,
- int nodelay, int keepalive)
+ Conf *conf, char *host, int port,
+ char **realhost, int nodelay, int keepalive)
{
static const struct plug_function_table fn_table = {
telnet_log,
SockAddr addr;
const char *err;
Telnet telnet;
+ char *loghost;
+ int addressfamily;
telnet = snew(struct telnet_tag);
telnet->fn = &fn_table;
- telnet->cfg = *cfg; /* STRUCTURE COPY */
+ telnet->conf = conf_copy(conf);
telnet->s = NULL;
telnet->echoing = TRUE;
telnet->editing = TRUE;
telnet->sb_buf = NULL;
telnet->sb_size = 0;
telnet->frontend = frontend_handle;
- telnet->term_width = telnet->cfg.width;
- telnet->term_height = telnet->cfg.height;
+ telnet->term_width = conf_get_int(telnet->conf, CONF_width);
+ telnet->term_height = conf_get_int(telnet->conf, CONF_height);
telnet->state = TOP_LEVEL;
telnet->ldisc = NULL;
telnet->pinger = NULL;
*/
{
char *buf;
+ addressfamily = conf_get_int(telnet->conf, CONF_addressfamily);
buf = dupprintf("Looking up host \"%s\"%s", host,
- (cfg->addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
- (cfg->addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" :
+ (addressfamily == ADDRTYPE_IPV4 ? " (IPv4)" :
+ (addressfamily == ADDRTYPE_IPV6 ? " (IPv6)" :
"")));
logevent(telnet->frontend, buf);
sfree(buf);
}
- addr = name_lookup(host, port, realhost, &telnet->cfg, cfg->addressfamily);
+ addr = name_lookup(host, port, realhost, telnet->conf, addressfamily);
if ((err = sk_addr_error(addr)) != NULL) {
sk_addr_free(addr);
return err;
* Open socket.
*/
telnet->s = new_connection(addr, *realhost, port, 0, 1,
- nodelay, keepalive, (Plug) telnet, &telnet->cfg);
+ nodelay, keepalive, (Plug) telnet, telnet->conf);
if ((err = sk_socket_error(telnet->s)) != NULL)
return err;
- telnet->pinger = pinger_new(&telnet->cfg, &telnet_backend, telnet);
+ telnet->pinger = pinger_new(telnet->conf, &telnet_backend, telnet);
/*
* Initialise option states.
*/
- if (telnet->cfg.passive_telnet) {
+ if (conf_get_int(telnet->conf, CONF_passive_telnet)) {
const struct Opt *const *o;
for (o = opts; *o; o++)
/*
* loghost overrides realhost, if specified.
*/
- if (*telnet->cfg.loghost) {
+ loghost = conf_get_str(telnet->conf, CONF_loghost);
+ if (*loghost) {
char *colon;
sfree(*realhost);
- *realhost = dupstr(telnet->cfg.loghost);
+ *realhost = dupstr(loghost);
colon = strrchr(*realhost, ':');
if (colon) {
/*
sk_close(telnet->s);
if (telnet->pinger)
pinger_free(telnet->pinger);
+ conf_free(telnet->conf);
sfree(telnet);
}
/*
* necessary, in this backend: we just save the fresh config for
* any subsequent negotiations.
*/
-static void telnet_reconfig(void *handle, Config *cfg)
+static void telnet_reconfig(void *handle, Conf *conf)
{
Telnet telnet = (Telnet) handle;
- pinger_reconfig(telnet->pinger, &telnet->cfg, cfg);
- telnet->cfg = *cfg; /* STRUCTURE COPY */
+ pinger_reconfig(telnet->pinger, telnet->conf, conf);
+ conf_free(telnet->conf);
+ telnet->conf = conf_copy(conf);
}
/*