svnno****@sourc*****
svnno****@sourc*****
2012年 5月 4日 (金) 23:39:22 JST
Revision: 4930 http://sourceforge.jp/projects/ttssh2/svn/view?view=rev&revision=4930 Author: yutakapon Date: 2012-05-04 23:39:22 +0900 (Fri, 04 May 2012) Log Message: ----------- SFTP: - コマンドラインコンソール(モードレスダイアログ)を追加した。これが将来的にFFFTPやWinSCPの2ペイン方式になる(予定)。 - インタラクティブループに入る前のパス送信処理を追加した。 ※一人言 SCPを実装したときもそうだったが、WindowsアプリはUNIXプログラムのようにブロックさせないようにしなければならないため、 1つのコマンドを送受信するだけでも、状態遷移管理をしなければならず、ロジックが煩雑になる。 SFTP用の別プロセスを起こして、Tera Term(TTSSH)本体とプロセス間通信するようにしたほうがよいのかも。 Modified Paths: -------------- trunk/ttssh2/ttxssh/resource.h trunk/ttssh2/ttxssh/sftp.c trunk/ttssh2/ttxssh/ssh.h trunk/ttssh2/ttxssh/ttxssh.rc -------------- next part -------------- Modified: trunk/ttssh2/ttxssh/resource.h =================================================================== --- trunk/ttssh2/ttxssh/resource.h 2012-05-03 16:17:09 UTC (rev 4929) +++ trunk/ttssh2/ttxssh/resource.h 2012-05-04 14:39:22 UTC (rev 4930) @@ -14,6 +14,7 @@ #define IDD_SSHAUTH 106 #define IDD_SSHSCP_PROGRESS 107 #define IDD_SSHPASSWD_INPUT 108 +#define IDD_SFTP_DIALOG 109 #define IDD_HOSTDLG 600 #define IDC_HOSTTCPIP 601 #define IDD_SSHDIFFERENTKEY 601 @@ -116,6 +117,7 @@ #define IDC_SENDFILE_EDIT 1069 #define IDC_PASSWD 1069 #define IDC_ECDSA521_TYPE 1069 +#define IDC_SFTP_EDIT 1069 #define IDC_STATIC1 1070 #define IDC_COMPRESSLABEL 1070 #define IDC_SSHVERSIONS 1070 @@ -194,13 +196,14 @@ #define IDC_EDIT2 1208 #define IDC_NEW_PASSWD 1208 #define IDC_SENDFILE_TO 1208 +#define IDC_SFTP_CONSOLE 1208 #define IDC_PUTTY_VERSION 1209 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 109 +#define _APS_NEXT_RESOURCE_VALUE 110 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1210 #define _APS_NEXT_SYMED_VALUE 101 Modified: trunk/ttssh2/ttxssh/sftp.c =================================================================== --- trunk/ttssh2/ttxssh/sftp.c 2012-05-03 16:17:09 UTC (rev 4929) +++ trunk/ttssh2/ttxssh/sftp.c 2012-05-04 14:39:22 UTC (rev 4930) @@ -51,6 +51,22 @@ #include <sys/stat.h> #include <assert.h> + +#define WM_USER_CONSOLE (WM_USER + 1) + +static void sftp_console_message(PTInstVar pvar, Channel_t *c, char *fmt, ...) +{ + char tmp[1024]; + va_list arg; + + va_start(arg, fmt); + _vsnprintf(tmp, sizeof(tmp), fmt, arg); + va_end(arg); + + SendMessage(c->sftp.console_window, WM_USER_CONSOLE, 0, (LPARAM)tmp); + notify_verbose_message(pvar, tmp, LOG_LEVEL_VERBOSE); +} + static void sftp_do_syslog(PTInstVar pvar, int level, char *fmt, ...) { char tmp[1024]; @@ -148,8 +164,23 @@ return; } +static void sftp_send_string_request(PTInstVar pvar, Channel_t *c, unsigned int id, unsigned int code, + char *s, unsigned int len) +{ + buffer_t *msg; + + sftp_buffer_alloc(&msg); + buffer_put_char(msg, code); + buffer_put_int(msg, id); + buffer_put_string(msg, s, len); + sftp_send_msg(pvar, c, msg); + sftp_syslog(pvar, "Sent message fd %d T:%u I:%u", c->remote_id, code, id); + sftp_buffer_free(msg); +} + + // SFTP\x92ʐM\x8AJ\x8En\x91O\x82̃l\x83S\x83V\x83G\x81[\x83V\x83\x87\x83\x93 -// based on do_init()#sftp-client.c +// based on do_init()#sftp-client.c(OpenSSH 6.0) void sftp_do_init(PTInstVar pvar, Channel_t *c) { buffer_t *msg; @@ -224,15 +255,205 @@ // TODO: } + sftp_syslog(pvar, "Connected to SFTP server."); + error: return; } -// SFTP\x8E\xF3\x90M\x8F\x88\x97\x9D -\x83\x81\x83C\x83\x93\x83\x8B\x81[\x83`\x83\x93- +// \x83p\x83X\x82̑\x97\x90M +// based on do_realpath()#sftp-client.c(OpenSSH 6.0) +static void sftp_do_realpath(PTInstVar pvar, Channel_t *c, char *path) +{ + unsigned int id; + + strncpy_s(c->sftp.path, sizeof(c->sftp.path), path, _TRUNCATE); + id = c->sftp.msg_id++; + sftp_send_string_request(pvar, c, id, SSH2_FXP_REALPATH, path, strlen(path)); +} + +/* Convert from SSH2_FX_ status to text error message */ +static const char *fx2txt(int status) +{ + switch (status) { + case SSH2_FX_OK: + return("No error"); + case SSH2_FX_EOF: + return("End of file"); + case SSH2_FX_NO_SUCH_FILE: + return("No such file or directory"); + case SSH2_FX_PERMISSION_DENIED: + return("Permission denied"); + case SSH2_FX_FAILURE: + return("Failure"); + case SSH2_FX_BAD_MESSAGE: + return("Bad message"); + case SSH2_FX_NO_CONNECTION: + return("No connection"); + case SSH2_FX_CONNECTION_LOST: + return("Connection lost"); + case SSH2_FX_OP_UNSUPPORTED: + return("Operation unsupported"); + default: + return("Unknown status"); + } + /* NOTREACHED */ +} + +static char *sftp_do_realpath_recv(PTInstVar pvar, Channel_t *c, buffer_t *msg) +{ + unsigned int type, expected_id, count, id; + char *filename = NULL, *longname; + + type = buffer_get_char(msg); + id = buffer_get_int(msg); + + expected_id = c->sftp.msg_id - 1; + if (id != expected_id) { + sftp_syslog(pvar, "ID mismatch (%u != %u)", id, expected_id); + goto error; + } + + if (type == SSH2_FXP_STATUS) { + unsigned int status = buffer_get_int(msg); + + sftp_syslog(pvar, "Couldn't canonicalise: %s", fx2txt(status)); + goto error; + } else if (type != SSH2_FXP_NAME) { + sftp_syslog(pvar, "Expected SSH2_FXP_NAME(%u) packet, got %u", + SSH2_FXP_NAME, type); + goto error; + } + + count = buffer_get_int(msg); + if (count != 1) { + sftp_syslog(pvar, "Got multiple names (%d) from SSH_FXP_REALPATH", count); + goto error; + } + + filename = buffer_get_string_msg(msg, NULL); + longname = buffer_get_string_msg(msg, NULL); + //a = decode_attrib(&msg); + + sftp_console_message(pvar, c, "SSH_FXP_REALPATH %s -> %s", c->sftp.path, filename); + + free(longname); + +error: + return (filename); +} + + +/* + * SFTP \x83R\x83}\x83\x93\x83h\x83\x89\x83C\x83\x93\x83R\x83\x93\x83\\x81[\x83\x8B + */ +static WNDPROC hEditProc; + +static LRESULT CALLBACK EditProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) { + case WM_KEYDOWN: + if ((int)wParam == VK_RETURN) { + char buf[512]; + + GetWindowText(hwnd, buf, sizeof(buf)); + SetWindowText(hwnd, ""); + if (buf[0] != '\0') { + SendDlgItemMessage(GetParent(hwnd), IDC_SFTP_CONSOLE, EM_REPLACESEL, 0, (LPARAM) buf); + SendDlgItemMessage(GetParent(hwnd), IDC_SFTP_CONSOLE, EM_REPLACESEL, 0, + (LPARAM) (char FAR *) "\r\n"); + } + } + break; + default: + return (CallWindowProc(hEditProc, hwnd, uMsg, wParam, lParam)); + } + + return 0L; +} + +static LRESULT CALLBACK OnSftpConsoleDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp) +{ + static HFONT DlgDragDropFont = NULL; + LOGFONT logfont; + HFONT font; + HWND hEdit; + + switch (msg) { + case WM_INITDIALOG: + font = (HFONT)SendMessage(hDlgWnd, WM_GETFONT, 0, 0); + GetObject(font, sizeof(LOGFONT), &logfont); + DlgDragDropFont = NULL; + + hEdit = GetDlgItem(hDlgWnd, IDC_SFTP_EDIT); + SetFocus(hEdit); + + // \x83G\x83f\x83B\x83b\x83g\x83R\x83\x93\x83g\x83\x8D\x81[\x83\x8B\x82̃T\x83u\x83N\x83\x89\x83X\x89\xBB + hEditProc = (WNDPROC)GetWindowLong(hEdit, GWL_WNDPROC); + SetWindowLong(hEdit, GWL_WNDPROC, (LONG)EditProc); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wp)) { + case IDOK: + break; + + case IDCANCEL: + if (DlgDragDropFont != NULL) { + DeleteObject(DlgDragDropFont); + } + EndDialog(hDlgWnd, IDCANCEL); + DestroyWindow(hDlgWnd); + break; + + default: + return FALSE; + } + + case WM_USER_CONSOLE: + SendDlgItemMessage(hDlgWnd, IDC_SFTP_CONSOLE, EM_REPLACESEL, 0, (LPARAM) lp); + SendDlgItemMessage(hDlgWnd, IDC_SFTP_CONSOLE, EM_REPLACESEL, 0, + (LPARAM) (char FAR *) "\r\n"); + return TRUE; + +#if 0 + case WM_SIZE: + { + // \x8DĔz\x92u + int dlg_w, dlg_h; + RECT rc_dlg; + RECT rc; + POINT p; + + // \x90V\x82\xB5\x82\xA2\x83_\x83C\x83A\x83\x8D\x83O\x82̃T\x83C\x83Y\x82\xE9 + GetClientRect(hDlgWnd, &rc_dlg); + dlg_w = rc_dlg.right; + dlg_h = rc_dlg.bottom; + + // \x83R\x83}\x83\x93\x83h\x83v\x83\x8D\x83\x93\x83v\x83g + GetWindowRect(GetDlgItem(hDlgWnd, IDC_SFTP_EDIT), &rc); + p.x = rc.left; + p.y = rc.top; + ScreenToClient(hDlgWnd, &p); + SetWindowPos(GetDlgItem(hDlgWnd, IDC_SFTP_EDIT), 0, + 0, 0, dlg_w, p.y, + SWP_NOSIZE | SWP_NOZORDER); + } + return TRUE; +#endif + + default: + return FALSE; + } + return TRUE; +} + +// SFTP\x8E\xF3\x90M\x8F\x88\x97\x9D -\x83X\x83e\x81[\x83g\x83}\x83V\x81[\x83\x93- void sftp_response(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen) { buffer_t *msg; - int state; + HWND hDlgWnd; /* * Allocate buffer @@ -240,10 +461,26 @@ sftp_buffer_alloc(&msg); sftp_get_msg(pvar, c, data, buflen, &msg); - state = c->sftp.state; - if (state == SFTP_INIT) { + if (c->sftp.state == SFTP_INIT) { sftp_do_init_recv(pvar, c, msg); - sftp_syslog(pvar, "Connected to SFTP server."); + + // \x83R\x83\x93\x83\\x81[\x83\x8B\x82\xF0\x8BN\x93\xAE\x82\xB7\x82\xE9\x81B + hDlgWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_SFTP_DIALOG), + pvar->cv->HWin, (DLGPROC)OnSftpConsoleDlgProc); + if (hDlgWnd != NULL) { + c->sftp.console_window = hDlgWnd; + ShowWindow(hDlgWnd, SW_SHOW); + } + + sftp_do_realpath(pvar, c, "."); + c->sftp.state = SFTP_CONNECTED; + + } else if (c->sftp.state == SFTP_CONNECTED) { + char *remote_path; + remote_path = sftp_do_realpath_recv(pvar, c, msg); + + c->sftp.state = SFTP_REALPATH; + } /* Modified: trunk/ttssh2/ttxssh/ssh.h =================================================================== --- trunk/ttssh2/ttxssh/ssh.h 2012-05-03 16:17:09 UTC (rev 4929) +++ trunk/ttssh2/ttxssh/ssh.h 2012-05-04 14:39:22 UTC (rev 4930) @@ -659,11 +659,12 @@ } scp_t; enum sftp_state { - SFTP_INIT, + SFTP_INIT, SFTP_CONNECTED, SFTP_REALPATH, }; typedef struct sftp { enum sftp_state state; + HWND console_window; unsigned int transfer_buflen; unsigned int num_requests; unsigned int version; @@ -675,6 +676,7 @@ unsigned int exts; unsigned long long limit_kbps; //struct bwlimit bwlimit_in, bwlimit_out; + char path[1024]; } sftp_t; typedef struct channel { Modified: trunk/ttssh2/ttxssh/ttxssh.rc =================================================================== --- trunk/ttssh2/ttxssh/ttxssh.rc 2012-05-03 16:17:09 UTC (rev 4929) +++ trunk/ttssh2/ttxssh/ttxssh.rc 2012-05-04 14:39:22 UTC (rev 4930) @@ -13,6 +13,52 @@ #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// +// \x93\xFA\x96{\x8C\xEA resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN) +#ifdef _WIN32 +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT +#pragma code_page(932) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_SFTP_DIALOG DIALOGEX 0, 0, 266, 150 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "TTSSH: SFTP console" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IDC_SFTP_EDIT,7,7,252,14,ES_AUTOHSCROLL + EDITTEXT IDC_SFTP_CONSOLE,7,33,252,110,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_SFTP_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 259 + TOPMARGIN, 7 + BOTTOMMARGIN, 143 + END +END +#endif // APSTUDIO_INVOKED + +#endif // \x93\xFA\x96{\x8C\xEA resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// // \x89p\x8C\xEA (\x95č\x91) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)