void copy_writer(SshStreamNotification op, void *context) { int len; int len2; unsigned char buf[100]; if (op != SSH_STREAM_CAN_OUTPUT) return; for (;;) { len = ssh_buffer_len(testdata) - test_data_index; len2 = ssh_rand() % 100000; if (len <= 0) { if (ssh_rand() % 2 == 0) ssh_stream_output_eof(ts1); ssh_stream_destroy(ts1); ts1 = NULL; destroy_count++; return; } if (len > len2) len = len2; len = ssh_stream_write(ts1, (unsigned char *)ssh_buffer_ptr(testdata) + test_data_index, len); if (len == 0) { if (ssh_rand() % 2 == 0) ssh_stream_output_eof(ts1); ssh_stream_destroy(ts1); ts1 = NULL; destroy_count++; return; /* Eof while writing. */ } if (len < 0) return; /* Cannot write more at this time */ test_data_index += len; if (ssh_rand() % 5 == 0) { len = ssh_stream_read(ts1, buf, sizeof(buf)); if (len == 0 && !reader_sent_eof) ssh_fatal("copy_writer: read returned EOF when not sent"); if (len > 0) ssh_fatal("copy_writer: read > 0"); } } }
Boolean handler_output_outgoing(Handler c) { int len; #ifdef DEBUG ssh_debug("handler_output_outgoing"); #endif #ifdef DUMP_PACKETS buffer_dump(&c->outgoing); #endif while (ssh_buffer_len(&c->outgoing) > 0) { len = ssh_buffer_len(&c->outgoing); len = ssh_stream_write(c->stream, ssh_buffer_ptr(&c->outgoing), len); if (len == 0) ssh_fatal("%s: handler_output: error writing to stream", c->side); if (len < 0) return FALSE; ssh_buffer_consume(&c->outgoing, len); } if (c->outgoing_eof) ssh_stream_output_eof(c->stream); return TRUE; }
void ssh_packet_wrapper_send_eof(SshPacketWrapper down) { /* If EOF already sent, return immediately. */ if (down->outgoing_eof) return; /* Otherwise, send EOF now. */ down->outgoing_eof = TRUE; if (ssh_buffer_len(&down->outgoing) == 0) ssh_stream_output_eof(down->stream); }
void connect1_write(SshStream stream) { int len; while (ssh_buffer_len(&send_buffer) > 0) { len = ssh_buffer_len(&send_buffer); len = ssh_stream_write(stream, ssh_buffer_ptr(&send_buffer), len); if (len < 0) return; if (len == 0) ssh_fatal("connect1_write failed"); ssh_buffer_consume(&send_buffer, len); } ssh_stream_output_eof(stream); ssh_stream_destroy(stream); }
void copy_reader(SshStreamNotification op, void *context) { unsigned char *buf; int len; if (op != SSH_STREAM_INPUT_AVAILABLE) return; buf = ssh_xmalloc(T_STREAMPAIR_BIG_BUF_LEN); for (;;) { len = ssh_stream_read(ts2, buf, T_STREAMPAIR_BIG_BUF_LEN); if (len == 0) { ssh_stream_destroy(ts2); ts2 = NULL; destroy_count++; ssh_xfree(buf); return; /* EOF received */ } if (len < 0) { ssh_xfree(buf); return; } ssh_buffer_append(received_data, buf, len); if (break_test && ssh_rand() % 10 == 0) { ssh_stream_destroy(ts2); ts2 = NULL; destroy_count++; ssh_xfree(buf); return; } if (!reader_sent_eof && ssh_rand() % 10 == 0) { ssh_stream_output_eof(ts2); reader_sent_eof = TRUE; } } /*NOTREACHED*/ }
void ssh_packet_impl_output_eof(void *context) { SshPacketImpl up = (SshPacketImpl)context; /* If shortcircuited, process the operation immediately. */ if (up->shortcircuit_stream) { ssh_stream_output_eof(up->shortcircuit_stream); return; } /* Mark that we have received EOF. */ up->incoming_eof = TRUE; /* Clear any partial packet that might be buffered. */ ssh_buffer_clear(&up->incoming); /* Call the protocol callback. */ if (up->received_eof) (*up->received_eof)(up->context); }
void ssh_pipe_stream_output_eof(void *context) { SshPipeStream pipes = (SshPipeStream)context; ssh_stream_output_eof(pipes->stdio_stream); }
Boolean ssh_packet_wrapper_output(SshPacketWrapper down) { int len; Boolean return_value = FALSE; /* Loop while we have data to output. When all data has been sent, we check whether we need to send EOF. */ while (ssh_buffer_len(&down->outgoing) > 0) { /* Write as much data as possible. */ len = ssh_stream_write(down->stream, ssh_buffer_ptr(&down->outgoing), ssh_buffer_len(&down->outgoing)); if (len < 0) return return_value; /* Cannot write more now. */ if (len == 0) { /* EOF on output; will not be able to write any more. */ down->outgoing_eof = TRUE; ssh_buffer_clear(&down->outgoing); return TRUE; } /* Consume written data. */ ssh_buffer_consume(&down->outgoing, len); /* We've done something, so return TRUE. */ return_value = TRUE; } /* All output has drained. There is no more buffered data. */ if (down->send_blocked) { down->cannot_destroy = TRUE; if (down->can_send) (*down->can_send)(down->context); down->cannot_destroy = FALSE; if (down->destroy_requested) { ssh_packet_wrapper_destroy(down); return FALSE; } down->send_blocked = FALSE; } /* If we should send EOF after output has drained, do it now. */ if (down->outgoing_eof) ssh_stream_output_eof(down->stream); /* If we get here and the stream is shortcircuited, that means we had output data to drain before shortcircuiting. */ if (down->shortcircuit_up_stream && !down->shortcircuited) { down->shortcircuited = TRUE; ssh_packet_impl_shortcircuit_now(down->shortcircuit_up_stream, down->stream); } /* If there's a destroy pending (that is, waiting for buffers to drain), do the destroy now. */ if (down->destroy_pending) { /* Destroy the context now. This also closes the stream. */ ssh_packet_wrapper_destroy_now(down); /* Return FALSE to ensure that the loop in ssh_packet_wrapper_callback exits without looking at the context again. */ return FALSE; } return return_value; }