/* * Generate side effects of enabling or disabling an option. */ static void option_side_effects(Telnet telnet, const struct Opt *o, int enabled) { if (o->option == TELOPT_ECHO && o->send == DO) telnet->echoing = !enabled; else if (o->option == TELOPT_SGA && o->send == DO) telnet->editing = !enabled; if (telnet->ldisc) /* cause ldisc to notice the change */ ldisc_send(telnet->ldisc, NULL, 0, 0); /* Ensure we get the minimum options */ if (!telnet->activated) { if (telnet->opt_states[o_echo.index] == INACTIVE) { telnet->opt_states[o_echo.index] = REQUESTED; send_opt(telnet, o_echo.send, o_echo.option); } if (telnet->opt_states[o_we_sga.index] == INACTIVE) { telnet->opt_states[o_we_sga.index] = REQUESTED; send_opt(telnet, o_we_sga.send, o_we_sga.option); } if (telnet->opt_states[o_they_sga.index] == INACTIVE) { telnet->opt_states[o_they_sga.index] = REQUESTED; send_opt(telnet, o_they_sga.send, o_they_sga.option); } telnet->activated = TRUE; } }
static void proc_rec_opt(Telnet telnet, int cmd, int option) { const struct Opt *const *o; log_option(telnet, "server", cmd, option); for (o = opts; *o; o++) { if ((*o)->option == option && (*o)->ack == cmd) { switch (telnet->opt_states[(*o)->index]) { case REQUESTED: telnet->opt_states[(*o)->index] = ACTIVE; activate_option(telnet, *o); break; case ACTIVE: break; case INACTIVE: telnet->opt_states[(*o)->index] = ACTIVE; send_opt(telnet, (*o)->send, option); activate_option(telnet, *o); break; case REALLY_INACTIVE: send_opt(telnet, (*o)->nsend, option); break; } return; } else if ((*o)->option == option && (*o)->nak == cmd) { switch (telnet->opt_states[(*o)->index]) { case REQUESTED: telnet->opt_states[(*o)->index] = INACTIVE; refused_option(telnet, *o); break; case ACTIVE: telnet->opt_states[(*o)->index] = INACTIVE; send_opt(telnet, (*o)->nsend, option); option_side_effects(telnet, *o, 0); break; case INACTIVE: case REALLY_INACTIVE: break; } return; } } /* * If we reach here, the option was one we weren't prepared to * cope with. If the request was positive (WILL or DO), we send * a negative ack to indicate refusal. If the request was * negative (WONT / DONT), we must do nothing. */ if (cmd == WILL || cmd == DO) send_opt(telnet, (cmd == WILL ? DONT : WONT), option); }
static void deactivate_option(Telnet telnet, const struct Opt *o) { if (telnet->opt_states[o->index] == REQUESTED || telnet->opt_states[o->index] == ACTIVE) send_opt(telnet, o->nsend, o->option); telnet->opt_states[o->index] = REALLY_INACTIVE; }
static void refused_option(Telnet telnet, const struct Opt *o) { if (o->send == WILL && o->option == TELOPT_NEW_ENVIRON && telnet->opt_states[o_oenv.index] == INACTIVE) { send_opt(telnet, WILL, TELOPT_OLD_ENVIRON); telnet->opt_states[o_oenv.index] = REQUESTED; } option_side_effects(telnet, o, 0); }
static void proc_rec_opt (int cmd, int option) { struct Opt **o; for (o = opts; *o; o++) { if ((*o)->option == option && (*o)->ack == cmd) { switch ((*o)->state) { case REQUESTED: (*o)->state = ACTIVE; break; case ACTIVE: break; case INACTIVE: (*o)->state = ACTIVE; send_opt ((*o)->send, option); break; } return; } else if ((*o)->option == option && (*o)->nak == cmd) { switch ((*o)->state) { case REQUESTED: (*o)->state = INACTIVE; break; case ACTIVE: (*o)->state = INACTIVE; send_opt ((*o)->nsend, option); break; case INACTIVE: break; } return; } } /* * If we reach here, the option was one we weren't prepared to * cope with. So send a negative ack. */ send_opt ((cmd == WILL ? DONT : WONT), option); }
static void do_telnet_init (void) { struct Opt **o; /* * Initialise option states. */ for (o = opts; *o; o++) if ((*o)->state == REQUESTED) send_opt ((*o)->send, (*o)->option); /* * Set up SYNCH state. */ in_synch = FALSE; }