static void gui_update_stats(char *name, unsigned long size,
int percentage, unsigned long elapsed);
+/*
+ * The maximum amount of queued data we accept before we stop and
+ * wait for the server to process some.
+ */
+#define MAX_SCP_BUFSIZE 16384
+
void logevent(char *string)
{
}
}
}
+/*
+ * Ask whether the selected cipher is acceptable (since it was
+ * below the configured 'warn' threshold).
+ * cs: 0 = both ways, 1 = client->server, 2 = server->client
+ */
+void askcipher(char *ciphername, int cs)
+{
+ HANDLE hin;
+ DWORD savemode, i;
+
+ static const char msg[] =
+ "The first %scipher supported by the server is\n"
+ "%s, which is below the configured warning threshold.\n"
+ "Continue with connection? (y/n) ";
+ static const char abandoned[] = "Connection abandoned.\n";
+
+ char line[32];
+
+ fprintf(stderr, msg,
+ (cs == 0) ? "" :
+ (cs == 1) ? "client-to-server " :
+ "server-to-client ",
+ ciphername);
+ fflush(stderr);
+
+ hin = GetStdHandle(STD_INPUT_HANDLE);
+ GetConsoleMode(hin, &savemode);
+ SetConsoleMode(hin, (savemode | ENABLE_ECHO_INPUT |
+ ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT));
+ ReadFile(hin, line, sizeof(line) - 1, &i, NULL);
+ SetConsoleMode(hin, savemode);
+
+ if (line[0] == 'y' || line[0] == 'Y') {
+ return;
+ } else {
+ fprintf(stderr, abandoned);
+ exit(0);
+ }
+}
+
/* GUI Adaptation - Sept 2000 */
static void send_msg(HWND h, UINT message, WPARAM wParam)
{
static unsigned outlen; /* how much data required */
static unsigned char *pending = NULL; /* any spare data */
static unsigned pendlen = 0, pendsize = 0; /* length and phys. size of buffer */
-void from_backend(int is_stderr, char *data, int datalen)
+int from_backend(int is_stderr, char *data, int datalen)
{
unsigned char *p = (unsigned char *) data;
unsigned len = (unsigned) datalen;
*/
if (is_stderr) {
fwrite(data, 1, len, stderr);
- return;
+ return 0;
}
inbuf_head = 0;
* If this is before the real session begins, just return.
*/
if (!outptr)
- return;
+ return 0;
if (outlen > 0) {
unsigned used = outlen;
memcpy(pending + pendlen, p, len);
pendlen += len;
}
+
+ return 0;
+}
+static int scp_process_network_event(void)
+{
+ fd_set readfds;
+
+ FD_ZERO(&readfds);
+ FD_SET(scp_ssh_socket, &readfds);
+ if (select(1, &readfds, NULL, NULL, NULL) < 0)
+ return 0; /* doom */
+ select_result((WPARAM) scp_ssh_socket, (LPARAM) FD_READ);
+ return 1;
}
static int ssh_scp_recv(unsigned char *buf, int len)
{
}
while (outlen > 0) {
- fd_set readfds;
-
- FD_ZERO(&readfds);
- FD_SET(scp_ssh_socket, &readfds);
- if (select(1, &readfds, NULL, NULL, NULL) < 0)
+ if (!scp_process_network_event())
return 0; /* doom */
- select_result((WPARAM) scp_ssh_socket, (LPARAM) FD_READ);
}
return len;
for (i = 0; i < size; i += 4096) {
char transbuf[4096];
DWORD j, k = 4096;
+ int bufsize;
+
if (i + k > size)
k = size - i;
if (!ReadFile(f, transbuf, k, &j, NULL) || j != k) {
printf("\n");
bump("%s: Read error", src);
}
- back->send(transbuf, k);
+ bufsize = back->send(transbuf, k);
if (statistics) {
stat_bytes += k;
if (time(NULL) != stat_lasttime || i + k == size) {
stat_starttime, stat_lasttime);
}
}
+
+ /*
+ * If the network transfer is backing up - that is, the
+ * remote site is not accepting data as fast as we can
+ * produce it - then we must loop on network events until
+ * we have space in the buffer again.
+ */
+ while (bufsize > MAX_SCP_BUFSIZE) {
+ if (!scp_process_network_event())
+ bump("%s: Network error occurred", src);
+ bufsize = back->sendbuffer();
+ }
}
CloseHandle(f);