|
Lines 84-89
Link Here
|
| 84 |
|
84 |
|
| 85 |
/* import options */ |
85 |
/* import options */ |
| 86 |
extern Options options; |
86 |
extern Options options; |
|
|
87 |
extern int no_tty_flag; |
| 87 |
|
88 |
|
| 88 |
/* Flag indicating that stdin should be redirected from /dev/null. */ |
89 |
/* Flag indicating that stdin should be redirected from /dev/null. */ |
| 89 |
extern int stdin_null_flag; |
90 |
extern int stdin_null_flag; |
|
Lines 121-128
Link Here
|
| 121 |
static int connection_in; /* Connection to server (input). */ |
122 |
static int connection_in; /* Connection to server (input). */ |
| 122 |
static int connection_out; /* Connection to server (output). */ |
123 |
static int connection_out; /* Connection to server (output). */ |
| 123 |
static int need_rekeying; /* Set to non-zero if rekeying is requested. */ |
124 |
static int need_rekeying; /* Set to non-zero if rekeying is requested. */ |
| 124 |
static int session_closed = 0; /* In SSH2: login session closed. */ |
125 |
enum SessionStatus {SessionOpen, SessionClose, SessionWait}; |
| 125 |
|
126 |
static int session_status = SessionOpen; /* In SSH2: login session closed. */ |
| 126 |
void client_init_dispatch(void); |
127 |
void client_init_dispatch(void); |
| 127 |
int session_ident = -1; |
128 |
int session_ident = -1; |
| 128 |
|
129 |
|
|
Lines 324-329
Link Here
|
| 324 |
client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, |
325 |
client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, |
| 325 |
int *maxfdp, int rekeying) |
326 |
int *maxfdp, int rekeying) |
| 326 |
{ |
327 |
{ |
|
|
328 |
struct timeval timer; |
| 329 |
struct timeval *timerp; |
| 330 |
int rc; |
| 331 |
|
| 327 |
/* Add any selections by the channel mechanism. */ |
332 |
/* Add any selections by the channel mechanism. */ |
| 328 |
channel_prepare_select(readsetp, writesetp, maxfdp, rekeying); |
333 |
channel_prepare_select(readsetp, writesetp, maxfdp, rekeying); |
| 329 |
|
334 |
|
|
Lines 346-352
Link Here
|
| 346 |
if (buffer_len(&stderr_buffer) > 0) |
351 |
if (buffer_len(&stderr_buffer) > 0) |
| 347 |
FD_SET(fileno(stderr), *writesetp); |
352 |
FD_SET(fileno(stderr), *writesetp); |
| 348 |
} else { |
353 |
} else { |
| 349 |
FD_SET(connection_in, *readsetp); |
354 |
/* channel_prepare_select could have closed the last channel */ |
|
|
355 |
if ((session_status == SessionClose) |
| 356 |
&& !channel_still_open()) { |
| 357 |
if (!packet_have_data_to_write()) |
| 358 |
return; |
| 359 |
} else { |
| 360 |
FD_SET(connection_in, *readsetp); |
| 361 |
} |
| 350 |
} |
362 |
} |
| 351 |
|
363 |
|
| 352 |
/* Select server connection if have data to write to the server. */ |
364 |
/* Select server connection if have data to write to the server. */ |
|
Lines 362-368
Link Here
|
| 362 |
* SSH_MSG_IGNORE packet when the timeout expires. |
374 |
* SSH_MSG_IGNORE packet when the timeout expires. |
| 363 |
*/ |
375 |
*/ |
| 364 |
|
376 |
|
| 365 |
if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) { |
377 |
if((session_status == SessionWait && options.sleep > 0) || |
|
|
378 |
(no_tty_flag && options.sleep == -1)) { |
| 379 |
timer.tv_sec=options.sleep > 0 ? options.sleep : 0; |
| 380 |
timer.tv_usec=0; |
| 381 |
timerp=&timer; |
| 382 |
} else { |
| 383 |
timerp=NULL; |
| 384 |
} |
| 385 |
|
| 386 |
rc=select((*maxfdp)+1, *readsetp, *writesetp, NULL, timerp); |
| 387 |
if (rc < 0) { |
| 366 |
char buf[100]; |
388 |
char buf[100]; |
| 367 |
|
389 |
|
| 368 |
/* |
390 |
/* |
|
Lines 379-385
Link Here
|
| 379 |
snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); |
401 |
snprintf(buf, sizeof buf, "select: %s\r\n", strerror(errno)); |
| 380 |
buffer_append(&stderr_buffer, buf, strlen(buf)); |
402 |
buffer_append(&stderr_buffer, buf, strlen(buf)); |
| 381 |
quit_pending = 1; |
403 |
quit_pending = 1; |
| 382 |
} |
404 |
} else if (rc == 0 && session_status == SessionWait) |
|
|
405 |
session_status=SessionClose; |
| 383 |
} |
406 |
} |
| 384 |
|
407 |
|
| 385 |
void |
408 |
void |
|
Lines 440-448
Link Here
|
| 440 |
len = read(connection_in, buf, sizeof(buf)); |
463 |
len = read(connection_in, buf, sizeof(buf)); |
| 441 |
if (len == 0) { |
464 |
if (len == 0) { |
| 442 |
/* Received EOF. The remote host has closed the connection. */ |
465 |
/* Received EOF. The remote host has closed the connection. */ |
| 443 |
snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", |
466 |
/* |
| 444 |
host); |
467 |
* This message duplicates the one already in client_loop(). |
| 445 |
buffer_append(&stderr_buffer, buf, strlen(buf)); |
468 |
* |
|
|
469 |
* snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", |
| 470 |
* host); |
| 471 |
* buffer_append(&stderr_buffer, buf, strlen(buf)); |
| 472 |
*/ |
| 446 |
quit_pending = 1; |
473 |
quit_pending = 1; |
| 447 |
return; |
474 |
return; |
| 448 |
} |
475 |
} |
|
Lines 751-757
Link Here
|
| 751 |
if (id != session_ident) |
778 |
if (id != session_ident) |
| 752 |
error("client_channel_closed: id %d != session_ident %d", |
779 |
error("client_channel_closed: id %d != session_ident %d", |
| 753 |
id, session_ident); |
780 |
id, session_ident); |
| 754 |
session_closed = 1; |
781 |
session_status = (options.sleep >= 0) ? SessionWait : SessionClose; |
| 755 |
if (in_raw_mode()) |
782 |
if (in_raw_mode()) |
| 756 |
leave_raw_mode(); |
783 |
leave_raw_mode(); |
| 757 |
} |
784 |
} |
|
Lines 776-781
Link Here
|
| 776 |
start_time = get_current_time(); |
803 |
start_time = get_current_time(); |
| 777 |
|
804 |
|
| 778 |
/* Initialize variables. */ |
805 |
/* Initialize variables. */ |
|
|
806 |
if(!have_pty) session_status=SessionWait; |
| 779 |
escape_pending = 0; |
807 |
escape_pending = 0; |
| 780 |
last_was_cr = 1; |
808 |
last_was_cr = 1; |
| 781 |
exit_status = -1; |
809 |
exit_status = -1; |
|
Lines 840-846
Link Here
|
| 840 |
/* Process buffered packets sent by the server. */ |
868 |
/* Process buffered packets sent by the server. */ |
| 841 |
client_process_buffered_input_packets(); |
869 |
client_process_buffered_input_packets(); |
| 842 |
|
870 |
|
| 843 |
if (compat20 && session_closed && !channel_still_open()) |
871 |
if (compat20 && (session_status == SessionClose) |
|
|
872 |
&& !channel_still_open()) |
| 844 |
break; |
873 |
break; |
| 845 |
|
874 |
|
| 846 |
rekeying = (xxx_kex != NULL && !xxx_kex->done); |
875 |
rekeying = (xxx_kex != NULL && !xxx_kex->done); |