Develop and Download Open Source Software

Browse Subversion Repository

Diff of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3075 by yutakapon, Tue Dec 25 14:49:01 2007 UTC revision 3077 by yutakapon, Wed Dec 26 11:33:50 2007 UTC
# Line 89  typedef struct scp { Line 89  typedef struct scp {
89          FILE *sendfp;                  // file pointer          FILE *sendfp;                  // file pointer
90          struct _stat filestat;         // file status information          struct _stat filestat;         // file status information
91          HWND progress;          HWND progress;
92            HANDLE thread;
93            PTInstVar pvar;
94  } scp_t;  } scp_t;
95    
96  typedef struct channel {  typedef struct channel {
# Line 257  static void ssh2_channel_delete(Channel_ Line 259  static void ssh2_channel_delete(Channel_
259    
260          if (c->type == TYPE_SCP) {          if (c->type == TYPE_SCP) {
261                  c->scp.state = SCP_CLOSING;                  c->scp.state = SCP_CLOSING;
262                    if (c->scp.thread != (HANDLE)-1L) {
263                            WaitForSingleObject(c->scp.thread, INFINITE);
264                            CloseHandle(c->scp.thread);
265                            c->scp.thread = (HANDLE)-1L;
266                    }
267                  if (c->scp.progress != NULL) {                  if (c->scp.progress != NULL) {
                         //SendMessage(c->scp.progress, WM_CLOSE, 0, 0);  
268                          DestroyWindow(c->scp.progress);                          DestroyWindow(c->scp.progress);
269                          c->scp.progress = NULL;                          c->scp.progress = NULL;
270                  }                  }
# Line 7023  static void do_SSH2_adjust_window_size(P Line 7029  static void do_SSH2_adjust_window_size(P
7029  }  }
7030    
7031    
7032  void ssh2_channel_remote_close(PTInstVar pvar, Channel_t *c)  void ssh2_channel_send_close(PTInstVar pvar, Channel_t *c)
7033  {  {
7034          if (SSHv2(pvar)) {          if (SSHv2(pvar)) {
7035                  buffer_t *msg;                  buffer_t *msg;
# Line 7046  void ssh2_channel_remote_close(PTInstVar Line 7052  void ssh2_channel_remote_close(PTInstVar
7052          }          }
7053  }  }
7054    
7055  #define WM_START_SENDING_FILE (WM_USER + 1)  #define WM_SENDING_FILE (WM_USER + 1)
7056    
7057  typedef struct scp_thread_parm {  typedef struct scp_dlg_parm {
         PTInstVar pvar;  
7058          Channel_t *c;          Channel_t *c;
7059  } scp_thread_parm_t;          PTInstVar pvar;
7060            char *buf;
7061            size_t buflen;
7062    } scp_dlg_parm_t;
7063    
7064  static LRESULT CALLBACK ssh_scp_dlg_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)  static LRESULT CALLBACK ssh_scp_dlg_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
7065  {  {
         const int RWIN_TIMEOUT = 100;  // 100 msec  
         const int SEND_TIMEOUT = 1;    // 1 msec  
         const int IDC_TIMER = 1;  
         static int instance = 0;  
         static PTInstVar pvar = NULL;  
         static Channel_t *c = NULL;  
         static long long total_size = 0;  
         char buf[8192];  
         size_t ret;  
         scp_thread_parm_t *parm;  
7066    
7067          switch (msg) {          switch (msg) {
7068                  case WM_INITDIALOG:                  case WM_INITDIALOG:
                         if (instance > 0) {  
                                 EndDialog(hWnd, 0);  
                         } else {  
                                 instance++;  
                         }  
7069                          return FALSE;                          return FALSE;
7070    
7071                  case WM_TIMER:                  case WM_SENDING_FILE:
7072                          {                          {
7073                          char s[80];                          scp_dlg_parm_t *parm = (scp_dlg_parm_t *)wp;
   
                         // socket or channelがクローズされたらスレッドを終わる  
                         if (pvar->socket == INVALID_SOCKET || c->scp.state == SCP_CLOSING || c->used == 0)  
                                 goto end;  
   
                         if (sizeof(buf) > c->remote_window) {  
                                 SetTimer(hWnd, 1, RWIN_TIMEOUT, 0);  
                                 return TRUE;  
                         }  
   
                         // ファイルから読み込んだデータはかならずサーバへ送信する。  
                         ret = fread(buf, 1, sizeof(buf), c->scp.sendfp);  
                         if (ret == 0)  
                                 goto eof;  
                         SSH2_send_channel_data(pvar, c, buf, ret);  
                         total_size += ret;  
   
                         _snprintf_s(s, sizeof(s), _TRUNCATE, "%lld / %lld (%d%%)", total_size, (long long)c->scp.filestat.st_size,  
                                 (100 * total_size / c->scp.filestat.st_size)%100 );  
                         SendMessage(GetDlgItem(hWnd, IDC_PROGRESS), WM_SETTEXT, 0, (LPARAM)s);  
                         goto retry;  
   
 eof:  
                         SSH2_send_channel_data(pvar, c, "\0", 1);  
                         c->scp.state = SCP_DATA;  
                         assert(total_size == c->scp.filestat.st_size);  
 end:  
                         c->scp.state = SCP_DATA;  
                         PostMessage(hWnd, WM_CLOSE, 0, 0);  
                         return TRUE;  
7074    
7075  retry:                          SSH2_send_channel_data(parm->pvar, parm->c, parm->buf, parm->buflen);
                         SetTimer(hWnd, IDC_TIMER, SEND_TIMEOUT, 0);  
                         }  
                         return TRUE;  
                         break;  
   
                 case WM_START_SENDING_FILE:  
                         {  
                         parm = (scp_thread_parm_t *)wp;  
                         pvar = parm->pvar;  
                         c = parm->c;  
                         free(parm);   // free!  
                         total_size = 0;  
   
                         SendMessage(GetDlgItem(hWnd, IDC_FILENAME), WM_SETTEXT, 0, (LPARAM)c->scp.sendfile);  
   
                         SetTimer(hWnd, 1, 100, 0);  
7076                          }                          }
7077                          return TRUE;                          return TRUE;
7078                          break;                          break;
# Line 7141  retry: Line 7088  retry:
7088                                          }                                          }
7089    
7090                                  case IDCANCEL:                                  case IDCANCEL:
7091                                          ssh2_channel_remote_close(pvar, c);                                          EndDialog(hWnd, 0);
                                         PostMessage(hWnd, WM_CLOSE, 0, 0);  
                                         //EndDialog(hWnd, 0);  
7092                                          return TRUE;                                          return TRUE;
7093                                  default:                                  default:
7094                                          return FALSE;                                          return FALSE;
# Line 7151  retry: Line 7096  retry:
7096                          break;                          break;
7097    
7098                  case WM_CLOSE:                  case WM_CLOSE:
7099                          KillTimer(hWnd, IDC_TIMER);                          // closeボタンが押下されても window が閉じないようにする。
                         EndDialog(hWnd, 0);  
7100                          return TRUE;                          return TRUE;
7101    
7102                  case WM_DESTROY:                  case WM_DESTROY:
                         instance--;  
7103                          return TRUE;                          return TRUE;
7104    
7105                  default:                  default:
# Line 7165  retry: Line 7108  retry:
7108          return TRUE;          return TRUE;
7109  }  }
7110    
7111    static unsigned __stdcall ssh_scp_thread(void FAR * p)
7112    {
7113            Channel_t *c = (Channel_t *)p;
7114            PTInstVar pvar = c->scp.pvar;
7115            long long total_size = 0;
7116            char buf[8192];
7117            char s[80];
7118            size_t ret;
7119            HWND hWnd = c->scp.progress;
7120            scp_dlg_parm_t parm;
7121    
7122            SendMessage(GetDlgItem(hWnd, IDC_FILENAME), WM_SETTEXT, 0, (LPARAM)c->scp.sendfile);
7123    
7124            do {
7125                    // Cancelボタンが押下されたらウィンドウが消える。
7126                    if (IsWindowVisible(hWnd) == 0)
7127                            goto abort;
7128    
7129                    // ファイルから読み込んだデータはかならずサーバへ送信する。
7130                    ret = fread(buf, 1, sizeof(buf), c->scp.sendfp);
7131                    if (ret == 0)
7132                            break;
7133    
7134                    do {
7135                            // socket or channelがクローズされたらスレッドを終わる
7136                            if (pvar->socket == INVALID_SOCKET || c->scp.state == SCP_CLOSING || c->used == 0)
7137                                    goto abort;
7138    
7139                            if (ret > c->remote_window) {
7140                                    Sleep(100);
7141                            }
7142    
7143                    } while (ret > c->remote_window);
7144    
7145                    // sending data
7146                    parm.buf = buf;
7147                    parm.buflen = ret;
7148                    parm.c = c;
7149                    parm.pvar = pvar;
7150                    SendMessage(hWnd, WM_SENDING_FILE, (WPARAM)&parm, 0);
7151    
7152                    total_size += ret;
7153    
7154                    _snprintf_s(s, sizeof(s), _TRUNCATE, "%lld / %lld (%d%%)", total_size, (long long)c->scp.filestat.st_size,
7155                            (100 * total_size / c->scp.filestat.st_size)%100 );
7156                    SendMessage(GetDlgItem(hWnd, IDC_PROGRESS), WM_SETTEXT, 0, (LPARAM)s);
7157    
7158            } while (ret <= sizeof(buf));
7159    
7160            // eof
7161            buf[0] = '\0';
7162            parm.buf = buf;
7163            parm.buflen = 1;
7164            parm.c = c;
7165            parm.pvar = pvar;
7166            SendMessage(hWnd, WM_SENDING_FILE, (WPARAM)&parm, 0);
7167    
7168            c->scp.state = SCP_DATA;
7169            return 0;
7170    
7171    abort:
7172            ssh2_channel_send_close(pvar, c);
7173    
7174    #if 0
7175            // デッドロック回避のため、自分でハンドルをクローズする。
7176            CloseHandle(c->scp.thread);
7177            c->scp.thread = (HANDLE)-1L;
7178            //ssh2_channel_delete(c);  // free channel
7179    #endif
7180            return 0;
7181    }
7182    
7183  static BOOL handle_SSH2_channel_data(PTInstVar pvar)  static BOOL handle_SSH2_channel_data(PTInstVar pvar)
7184  {        {      
# Line 7236  static BOOL handle_SSH2_channel_data(PTI Line 7250  static BOOL handle_SSH2_channel_data(PTI
7250                                  SSH2_send_channel_data(pvar, c, buf, strlen(buf));                                  SSH2_send_channel_data(pvar, c, buf, strlen(buf));
7251    
7252                          } else if (c->scp.state == SCP_FILEINFO) {                          } else if (c->scp.state == SCP_FILEINFO) {
                                 scp_thread_parm_t *parm = malloc(sizeof(scp_thread_parm_t));  
7253                                  HWND hDlgWnd;                                  HWND hDlgWnd;
7254                                    HANDLE thread;
7255                                    unsigned int tid;
7256    
7257                                  if (parm == NULL) {                                  c->scp.pvar = pvar;
                                         // TODO:  
                                 }  
                                 parm->pvar = pvar;  
                                 parm->c = c;  
7258    
7259                                  hDlgWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_SSHSCP_PROGRESS),                                  hDlgWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_SSHSCP_PROGRESS),
7260                                 pvar->cv->HWin, (DLGPROC)ssh_scp_dlg_proc);                                 pvar->cv->HWin, (DLGPROC)ssh_scp_dlg_proc);
7261                                  if (hDlgWnd != NULL) {                                  if (hDlgWnd != NULL) {
7262                                          c->scp.progress = hDlgWnd;                                          c->scp.progress = hDlgWnd;
7263                                          ShowWindow(hDlgWnd, SW_SHOW);                                          ShowWindow(hDlgWnd, SW_SHOW);
                                         SendMessage(hDlgWnd, WM_START_SENDING_FILE, (WPARAM)parm, 0);  
7264                                  }                                  }
7265    
7266                                    thread = (HANDLE)_beginthreadex(NULL, 0, ssh_scp_thread, c, 0, &tid);
7267                                    if (thread == (HANDLE)-1) {
7268                                            // TODO:
7269                                    }
7270                                    c->scp.thread = thread;
7271    
7272    
7273                          } else if (c->scp.state == SCP_DATA) {                          } else if (c->scp.state == SCP_DATA) {
7274                                  // 送信完了                                  // 送信完了
7275                                  ssh2_channel_delete(c);  // free channel                                  ssh2_channel_delete(c);  // free channel
# Line 7273  static BOOL handle_SSH2_channel_data(PTI Line 7290  static BOOL handle_SSH2_channel_data(PTI
7290                          }                          }
7291                          msg[i] = '\0';                          msg[i] = '\0';
7292    
7293                          ssh2_channel_remote_close(pvar, c);                          ssh2_channel_send_close(pvar, c);
7294                          ssh2_channel_delete(c);  // free channel                          ssh2_channel_delete(c);  // free channel
7295    
7296                          MessageBox(NULL, msg, "TTSSH: SCP error", MB_OK | MB_ICONEXCLAMATION);                          MessageBox(NULL, msg, "TTSSH: SCP error", MB_OK | MB_ICONEXCLAMATION);
# Line 7546  static BOOL handle_SSH2_channel_close(PT Line 7563  static BOOL handle_SSH2_channel_close(PT
7563                  // チャネルの解放漏れを修正 (2007.4.26 yutaka)                  // チャネルの解放漏れを修正 (2007.4.26 yutaka)
7564                  ssh2_channel_delete(c);                  ssh2_channel_delete(c);
7565    
7566            } else if (c->type == TYPE_SCP) {
7567                    ssh2_channel_delete(c);
7568    
7569          } else {          } else {
7570                    ssh2_channel_delete(c);
7571    
7572          }          }
7573    
# Line 7647  static BOOL handle_SSH2_window_adjust(PT Line 7668  static BOOL handle_SSH2_window_adjust(PT
7668          data += 4;          data += 4;
7669    
7670          c = ssh2_channel_lookup(id);          c = ssh2_channel_lookup(id);
7671          if (c == NULL)          if (c == NULL) {
7672                  return FALSE;                  // channel close後にadjust messageが遅れてやってくるケースもあるため、
7673                    // FALSEでは返さないようにする。(2007.12.26 yutaka)
7674                    return TRUE;
7675            }
7676    
7677          adjust = get_uint32_MSBfirst(data);          adjust = get_uint32_MSBfirst(data);
7678          data += 4;          data += 4;

Legend:
Removed from v.3075  
changed lines
  Added in v.3077

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26