version 1.405, 2024/04/30 02:14:10 |
version 1.406, 2024/05/09 09:46:47 |
|
|
volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ |
volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ |
static int last_was_cr; /* Last character was a newline. */ |
static int last_was_cr; /* Last character was a newline. */ |
static int exit_status; /* Used to store the command exit status. */ |
static int exit_status; /* Used to store the command exit status. */ |
static struct sshbuf *stderr_buffer; /* Used for final exit message. */ |
|
static int connection_in; /* Connection to server (input). */ |
static int connection_in; /* Connection to server (input). */ |
static int connection_out; /* Connection to server (output). */ |
static int connection_out; /* Connection to server (output). */ |
static int need_rekeying; /* Set to non-zero if rekeying is requested. */ |
static int need_rekeying; /* Set to non-zero if rekeying is requested. */ |
|
|
static void |
static void |
quit_message(const char *fmt, ...) |
quit_message(const char *fmt, ...) |
{ |
{ |
char *msg; |
char *msg, *fmt2; |
va_list args; |
va_list args; |
int r; |
xasprintf(&fmt2, "%s\r\n", fmt); |
|
|
va_start(args, fmt); |
va_start(args, fmt); |
xvasprintf(&msg, fmt, args); |
xvasprintf(&msg, fmt2, args); |
va_end(args); |
va_end(args); |
|
|
if ((r = sshbuf_putf(stderr_buffer, "%s\r\n", msg)) != 0) |
(void)atomicio(vwrite, STDERR_FILENO, msg, strlen(msg)); |
fatal_fr(r, "sshbuf_putf"); |
|
free(msg); |
free(msg); |
|
free(fmt2); |
|
|
quit_pending = 1; |
quit_pending = 1; |
} |
} |
|
|
|
|
struct pollfd *pfd = NULL; |
struct pollfd *pfd = NULL; |
u_int npfd_alloc = 0, npfd_active = 0; |
u_int npfd_alloc = 0, npfd_active = 0; |
double start_time, total_time; |
double start_time, total_time; |
int channel_did_enqueue = 0, r, len; |
int channel_did_enqueue = 0, r; |
u_int64_t ibytes, obytes; |
u_int64_t ibytes, obytes; |
int conn_in_ready, conn_out_ready; |
int conn_in_ready, conn_out_ready; |
sigset_t bsigset, osigset; |
sigset_t bsigset, osigset; |
|
|
|
|
quit_pending = 0; |
quit_pending = 0; |
|
|
/* Initialize buffer. */ |
|
if ((stderr_buffer = sshbuf_new()) == NULL) |
|
fatal_f("sshbuf_new failed"); |
|
|
|
client_init_dispatch(ssh); |
client_init_dispatch(ssh); |
|
|
/* |
/* |
|
|
|
|
/* Terminate the session. */ |
/* Terminate the session. */ |
|
|
|
/* |
|
* In interactive mode (with pseudo tty) display a message indicating |
|
* that the connection has been closed. |
|
*/ |
|
if (have_pty && options.log_level >= SYSLOG_LEVEL_INFO) |
|
quit_message("Connection to %s closed.", host); |
|
|
|
|
/* Stop watching for window change. */ |
/* Stop watching for window change. */ |
ssh_signal(SIGWINCH, SIG_DFL); |
ssh_signal(SIGWINCH, SIG_DFL); |
|
|
|
|
verbose("Killed by signal %d.", (int) received_signal); |
verbose("Killed by signal %d.", (int) received_signal); |
cleanup_exit(255); |
cleanup_exit(255); |
} |
} |
|
|
/* |
|
* In interactive mode (with pseudo tty) display a message indicating |
|
* that the connection has been closed. |
|
*/ |
|
if (have_pty && options.log_level >= SYSLOG_LEVEL_INFO) |
|
quit_message("Connection to %s closed.", host); |
|
|
|
/* Output any buffered data for stderr. */ |
|
if (sshbuf_len(stderr_buffer) > 0) { |
|
len = atomicio(vwrite, fileno(stderr), |
|
(u_char *)sshbuf_ptr(stderr_buffer), |
|
sshbuf_len(stderr_buffer)); |
|
if (len < 0 || (u_int)len != sshbuf_len(stderr_buffer)) |
|
error("Write failed flushing stderr buffer."); |
|
else if ((r = sshbuf_consume(stderr_buffer, len)) != 0) |
|
fatal_fr(r, "sshbuf_consume"); |
|
} |
|
|
|
/* Clear and free any buffers. */ |
|
sshbuf_free(stderr_buffer); |
|
|
|
/* Report bytes transferred, and transfer rates. */ |
/* Report bytes transferred, and transfer rates. */ |
total_time = monotime_double() - start_time; |
total_time = monotime_double() - start_time; |