void chan_ibuf_empty(Channel *c) { debug2("channel %d: ibuf empty", c->self); if (buffer_len(&c->input)) { error("channel %d: chan_ibuf_empty for non empty buffer", c->self); return; } switch (c->istate) { case CHAN_INPUT_WAIT_DRAIN: if (compat20) { if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL))) chan_send_eof2(c); chan_set_istate(c, CHAN_INPUT_CLOSED); } else { chan_send_ieof1(c); chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE); } break; default: error("channel %d: chan_ibuf_empty for istate %d", c->self, c->istate); break; } }
/* * the same for SSH2 */ static void chan_rcvd_close2(Channel *c) { debug("channel %d: rcvd close", c->self); if (c->flags & CHAN_CLOSE_RCVD) error("channel %d: protocol error: close rcvd twice", c->self); c->flags |= CHAN_CLOSE_RCVD; if (c->type == SSH_CHANNEL_LARVAL) { /* tear down larval channels immediately */ chan_set_ostate(c, CHAN_OUTPUT_CLOSED); chan_set_istate(c, CHAN_INPUT_CLOSED); return; } switch (c->ostate) { case CHAN_OUTPUT_OPEN: /* * wait until a data from the channel is consumed if a CLOSE * is received */ chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); break; } switch (c->istate) { case CHAN_INPUT_OPEN: chan_shutdown_read(c); chan_set_istate(c, CHAN_INPUT_CLOSED); break; case CHAN_INPUT_WAIT_DRAIN: chan_send_eof2(c); chan_set_istate(c, CHAN_INPUT_CLOSED); break; } }
void chan_ibuf_empty(Channel *c) { debug2("channel %d: ibuf empty", c->self); if (buffer_len(&c->input)) { error("channel %d: chan_ibuf_empty for non empty buffer", c->self); return; } switch (c->istate) { case CHAN_INPUT_WAIT_DRAIN: if (compat20) { if (!(c->flags & (CHAN_CLOSE_SENT | CHAN_LOCAL))) { #ifdef WIN32_FIXME // reset the other side if tty to be how it was before if (c->isatty) { char *inittermseq = "\033[?7h" // end-of-line autowrap ON mode "\033[20l"; // force NewLineMode off buffer_append(&c->input, inittermseq, strlen(inittermseq)); int state = c->istate; c->istate = CHAN_INPUT_WAIT_DRAIN; channel_output_poll(); packet_write_poll(); // packet_write_wait(); c->istate = state; } #endif chan_send_eof2(c); } chan_set_istate(c, CHAN_INPUT_CLOSED); } else { chan_send_ieof1(c); chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE); } break; default: error("channel %d: chan_ibuf_empty for istate %d", c->self, c->istate); break; } }
void chan_ibuf_empty(struct ssh *ssh, Channel *c) { debug2("channel %d: ibuf empty", c->self); if (sshbuf_len(c->input)) { error("channel %d: chan_ibuf_empty for non empty buffer", c->self); return; } switch (c->istate) { case CHAN_INPUT_WAIT_DRAIN: if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL))) chan_send_eof2(ssh, c); chan_set_istate(c, CHAN_INPUT_CLOSED); break; default: error("channel %d: chan_ibuf_empty for istate %d", c->self, c->istate); break; } }