| 96 |
HWND progress; |
HWND progress; |
| 97 |
HANDLE thread; |
HANDLE thread; |
| 98 |
PTInstVar pvar; |
PTInstVar pvar; |
| 99 |
|
|
| 100 |
|
// receiving file |
| 101 |
|
long long filetotalsize; |
| 102 |
|
long long filercvsize; |
| 103 |
} scp_t; |
} scp_t; |
| 104 |
|
|
| 105 |
typedef struct channel { |
typedef struct channel { |
| 195 |
if (type == TYPE_SCP) { |
if (type == TYPE_SCP) { |
| 196 |
c->scp.state = SCP_INIT; |
c->scp.state = SCP_INIT; |
| 197 |
c->scp.progress = NULL; |
c->scp.progress = NULL; |
| 198 |
|
c->scp.thread = (HANDLE)-1; |
| 199 |
} |
} |
| 200 |
|
|
| 201 |
return (c); |
return (c); |
| 3456 |
int SSH_start_scp(PTInstVar pvar, char *sendfile) |
int SSH_start_scp(PTInstVar pvar, char *sendfile) |
| 3457 |
{ |
{ |
| 3458 |
return SSH_scp_transaction(pvar, sendfile, TOLOCAL); |
return SSH_scp_transaction(pvar, sendfile, TOLOCAL); |
| 3459 |
//return SSH_scp_transaction(pvar, "remote5.bin", FROMREMOTE); |
|
| 3460 |
|
//return SSH_scp_transaction(pvar, "bigfile100.dat", FROMREMOTE); |
| 3461 |
} |
} |
| 3462 |
|
|
| 3463 |
|
|
| 7319 |
} |
} |
| 7320 |
} |
} |
| 7321 |
|
|
| 7322 |
static void SSH2_scp_fromremote(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen) |
static BOOL SSH2_scp_fromremote(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen) |
| 7323 |
{ |
{ |
| 7324 |
|
int permission; |
| 7325 |
|
long long size; |
| 7326 |
|
char filename[MAX_PATH]; |
| 7327 |
|
char s[80]; |
| 7328 |
|
char ch; |
| 7329 |
|
HWND hDlgWnd; |
| 7330 |
|
MSG msg; |
| 7331 |
|
int i; |
| 7332 |
|
|
| 7333 |
|
if (buflen == 0) |
| 7334 |
|
return FALSE; |
| 7335 |
|
|
| 7336 |
|
if (c->scp.state == SCP_INIT) { |
| 7337 |
|
if (data[0] == '\01' || data[1] == '\02') { // error |
| 7338 |
|
return FALSE; |
| 7339 |
|
} |
| 7340 |
|
|
| 7341 |
|
if (data[0] == 'T') { // Tmtime.sec mtime.usec atime.sec atime.usec |
| 7342 |
|
// TODO: |
| 7343 |
|
|
| 7344 |
|
// リプライを返す |
| 7345 |
|
goto reply; |
| 7346 |
|
|
| 7347 |
|
} else if (data[0] == 'C') { // C0666 size file |
| 7348 |
|
sscanf_s(data, "C%o %lld %s", &permission, &size, filename, sizeof(filename)); |
| 7349 |
|
|
| 7350 |
|
// Windowsなのでパーミッションは無視。サイズのみ記録。 |
| 7351 |
|
c->scp.filetotalsize = size; |
| 7352 |
|
c->scp.filercvsize = 0; |
| 7353 |
|
|
| 7354 |
|
c->scp.state = SCP_DATA; |
| 7355 |
|
|
| 7356 |
|
// 進捗ウィンドウ |
| 7357 |
|
c->scp.pvar = pvar; |
| 7358 |
|
hDlgWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_SSHSCP_PROGRESS), |
| 7359 |
|
pvar->cv->HWin, (DLGPROC)ssh_scp_dlg_proc); |
| 7360 |
|
if (hDlgWnd != NULL) { |
| 7361 |
|
c->scp.progress = hDlgWnd; |
| 7362 |
|
SetWindowText(hDlgWnd, "TTSSH: SCP receiving file"); |
| 7363 |
|
SendMessage(GetDlgItem(hDlgWnd, IDC_FILENAME), WM_SETTEXT, 0, (LPARAM)c->scp.sendfile); |
| 7364 |
|
ShowWindow(hDlgWnd, SW_SHOW); |
| 7365 |
|
} |
| 7366 |
|
|
| 7367 |
|
c->scp.thread = (HANDLE)-1; |
| 7368 |
|
|
| 7369 |
|
goto reply; |
| 7370 |
|
|
| 7371 |
|
} else { |
| 7372 |
|
// TODO: |
| 7373 |
|
|
| 7374 |
|
} |
| 7375 |
|
|
| 7376 |
|
} else if (c->scp.state == SCP_DATA) { // payloadの受信 |
| 7377 |
|
// Cancelボタンが押下されたらウィンドウが消える。 |
| 7378 |
|
if (IsWindowVisible(c->scp.progress) == 0) |
| 7379 |
|
goto cancel_abort; |
| 7380 |
|
|
| 7381 |
|
c->scp.filercvsize += buflen; |
| 7382 |
|
|
| 7383 |
|
if (fwrite(data, 1, buflen, c->scp.sendfp) < buflen) { // error |
| 7384 |
|
// TODO: |
| 7385 |
|
} |
| 7386 |
|
|
| 7387 |
|
if (c->scp.filercvsize >= c->scp.filetotalsize) { // EOF |
| 7388 |
|
c->scp.state = SCP_CLOSING; |
| 7389 |
|
} |
| 7390 |
|
|
| 7391 |
|
_snprintf_s(s, sizeof(s), _TRUNCATE, "%lld / %lld (%d%%)", c->scp.filercvsize, c->scp.filetotalsize, |
| 7392 |
|
(100 * c->scp.filercvsize / c->scp.filetotalsize)%100 ); |
| 7393 |
|
SendMessage(GetDlgItem(c->scp.progress, IDC_PROGRESS), WM_SETTEXT, 0, (LPARAM)s); |
| 7394 |
|
|
| 7395 |
|
// 以下の workaround がないと、モードレスダイアログの操作すらできない。 |
| 7396 |
|
// この処置でもTeraTermウィンドウの操作ができない。要検討。 |
| 7397 |
|
#if 1 |
| 7398 |
|
for (i = 0 ; i < 10 ; i++) { |
| 7399 |
|
if (PeekMessage(&msg, c->scp.progress, 0, 0, PM_REMOVE)) { |
| 7400 |
|
TranslateMessage(&msg); |
| 7401 |
|
DispatchMessage(&msg); |
| 7402 |
|
} |
| 7403 |
|
Sleep(0); |
| 7404 |
|
} |
| 7405 |
|
#endif |
| 7406 |
|
|
| 7407 |
|
} else if (c->scp.state == SCP_CLOSING) { // EOFの受信 |
| 7408 |
|
ssh2_channel_send_close(pvar, c); |
| 7409 |
|
|
| 7410 |
|
} |
| 7411 |
|
return TRUE; |
| 7412 |
|
|
| 7413 |
|
reply: |
| 7414 |
|
ch = '\0'; |
| 7415 |
|
SSH2_send_channel_data(pvar, c, &ch, 1); |
| 7416 |
|
return TRUE; |
| 7417 |
|
|
| 7418 |
|
cancel_abort: |
| 7419 |
|
ssh2_channel_send_close(pvar, c); |
| 7420 |
|
|
| 7421 |
|
return TRUE; |
| 7422 |
} |
} |
| 7423 |
|
|
| 7424 |
|
|
| 7425 |
static void SSH2_scp_response(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen) |
static void SSH2_scp_response(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen) |
| 7426 |
{ |
{ |
| 7427 |
if (c->scp.dir == FROMREMOTE) { |
if (c->scp.dir == FROMREMOTE) { |
| 7428 |
SSH2_scp_fromremote(pvar, c, data, buflen); |
if (SSH2_scp_fromremote(pvar, c, data, buflen) == FALSE) |
| 7429 |
|
goto error; |
| 7430 |
|
|
| 7431 |
} else if (c->scp.dir == TOLOCAL) { |
} else if (c->scp.dir == TOLOCAL) { |
| 7432 |
if (buflen == 1 && data[0] == '\0') { // OK |
if (buflen == 1 && data[0] == '\0') { // OK |