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 3080 by yutakapon, Wed Dec 26 14:26:43 2007 UTC revision 3081 by yutakapon, Thu Dec 27 13:18:47 2007 UTC
# Line 77  enum scp_state { Line 77  enum scp_state {
77          SCP_INIT, SCP_TIMESTAMP, SCP_FILEINFO, SCP_DATA, SCP_CLOSING,          SCP_INIT, SCP_TIMESTAMP, SCP_FILEINFO, SCP_DATA, SCP_CLOSING,
78  };  };
79    
80    enum scp_dir {
81            TOLOCAL, FROMREMOTE,
82    };
83    
84  typedef struct bufchain {  typedef struct bufchain {
85          buffer_t *msg;          buffer_t *msg;
86          struct bufchain *next;          struct bufchain *next;
87  } bufchain_t;  } bufchain_t;
88    
89  typedef struct scp {  typedef struct scp {
90          enum scp_state state;      // SCP state          enum scp_dir dir;              // transfer direction
91            enum scp_state state;          // SCP state
92          char sendfile[MAX_PATH];       // sending filename          char sendfile[MAX_PATH];       // sending filename
93          char sendfilefull[MAX_PATH];   // sending filename fullpath          char sendfilefull[MAX_PATH];   // sending filename fullpath
94          FILE *sendfp;                  // file pointer          FILE *sendfp;                  // file pointer
# Line 259  static void ssh2_channel_delete(Channel_ Line 264  static void ssh2_channel_delete(Channel_
264    
265          if (c->type == TYPE_SCP) {          if (c->type == TYPE_SCP) {
266                  c->scp.state = SCP_CLOSING;                  c->scp.state = SCP_CLOSING;
267                    fclose(c->scp.sendfp);
268                    if (c->scp.progress != NULL) {
269                            DestroyWindow(c->scp.progress);
270                            c->scp.progress = NULL;
271                    }
272                  if (c->scp.thread != (HANDLE)-1L) {                  if (c->scp.thread != (HANDLE)-1L) {
273                          WaitForSingleObject(c->scp.thread, INFINITE);                          WaitForSingleObject(c->scp.thread, INFINITE);
274                          CloseHandle(c->scp.thread);                          CloseHandle(c->scp.thread);
275                          c->scp.thread = (HANDLE)-1L;                          c->scp.thread = (HANDLE)-1L;
276                  }                  }
                 if (c->scp.progress != NULL) {  
                         DestroyWindow(c->scp.progress);  
                         c->scp.progress = NULL;  
                 }  
                 fclose(c->scp.sendfp);  
277          }          }
278    
279          memset(c, 0, sizeof(Channel_t));          memset(c, 0, sizeof(Channel_t));
# Line 3358  void SSH_open_channel(PTInstVar pvar, ui Line 3363  void SSH_open_channel(PTInstVar pvar, ui
3363  //  //
3364  // (2007.12.21 yutaka)  // (2007.12.21 yutaka)
3365  //  //
3366  int SSH_start_scp(PTInstVar pvar, char *sendfile)  static int SSH_scp_transaction(PTInstVar pvar, char *sendfile, enum scp_dir direction)
3367  {  {
3368          buffer_t *msg;          buffer_t *msg;
3369          char *s;          char *s;
# Line 3375  int SSH_start_scp(PTInstVar pvar, char * Line 3380  int SSH_start_scp(PTInstVar pvar, char *
3380          if (SSHv1(pvar))      // SSH1サポートはTBD          if (SSHv1(pvar))      // SSH1サポートはTBD
3381                  goto error;                  goto error;
3382    
         fp = fopen(sendfile, "rb");  
         if (fp == NULL)  
                 goto error;  
   
3383          // チャネル設定          // チャネル設定
3384          c = ssh2_channel_new(CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT, TYPE_SCP, -1);          c = ssh2_channel_new(CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT, TYPE_SCP, -1);
3385          if (c == NULL) {          if (c == NULL) {
# Line 3387  int SSH_start_scp(PTInstVar pvar, char * Line 3388  int SSH_start_scp(PTInstVar pvar, char *
3388                  notify_fatal_error(pvar, pvar->ts->UIMsg);                  notify_fatal_error(pvar, pvar->ts->UIMsg);
3389                  goto error;                  goto error;
3390          }          }
3391    
3392            if (direction == TOLOCAL) {  // copy local to remote
3393                    fp = fopen(sendfile, "rb");
3394                    if (fp == NULL)
3395                            goto error;
3396    
3397                    strncpy_s(c->scp.sendfilefull, sizeof(c->scp.sendfilefull), sendfile, _TRUNCATE);  // full path
3398                    ExtractFileName(sendfile, c->scp.sendfile, sizeof(c->scp.sendfile));   // file name only
3399                    c->scp.sendfp = fp;     // file pointer
3400    
3401                    if (_stat(c->scp.sendfilefull, &st) == 0) {
3402                            c->scp.filestat = st;
3403                    } else {
3404                            goto error;
3405                    }
3406            } else { // copy remote to local
3407                    fp = fopen(sendfile, "wb");
3408                    if (fp == NULL)
3409                            goto error;
3410    
3411                    strncpy_s(c->scp.sendfilefull, sizeof(c->scp.sendfilefull), sendfile, _TRUNCATE);
3412                    strncpy_s(c->scp.sendfile, sizeof(c->scp.sendfile), sendfile, _TRUNCATE);
3413            }
3414    
3415          // setup SCP data          // setup SCP data
3416            c->scp.dir = direction;    
3417          c->scp.state = SCP_INIT;          c->scp.state = SCP_INIT;
         strncpy_s(c->scp.sendfilefull, sizeof(c->scp.sendfilefull), sendfile, _TRUNCATE);  // full path  
         ExtractFileName(sendfile, c->scp.sendfile, sizeof(c->scp.sendfile));   // file name only  
         c->scp.sendfp = fp;     // file pointer  
         if (_stat(c->scp.sendfilefull, &st) == 0) {  
                 c->scp.filestat = st;  
         } else {  
                 goto error;  
         }  
3418    
3419          // session open          // session open
3420          msg = buffer_init();          msg = buffer_init();
# Line 3425  error: Line 3443  error:
3443          return FALSE;          return FALSE;
3444  }  }
3445    
3446    int SSH_start_scp(PTInstVar pvar, char *sendfile)
3447    {
3448            return SSH_scp_transaction(pvar, sendfile, TOLOCAL);
3449    }
3450    
3451    
3452  /////////////////////////////////////////////////////////////////////////////  /////////////////////////////////////////////////////////////////////////////
3453  //  //
# Line 6833  static BOOL handle_SSH2_open_confirm(PTI Line 6856  static BOOL handle_SSH2_open_confirm(PTI
6856    
6857          if (c->type == TYPE_SCP) {          if (c->type == TYPE_SCP) {
6858                  char sbuf[MAX_PATH + 30];                  char sbuf[MAX_PATH + 30];
6859                  _snprintf_s(sbuf, sizeof(sbuf), _TRUNCATE, "scp -t %s", c->scp.sendfile);                  if (c->scp.dir == TOLOCAL) {
6860                            _snprintf_s(sbuf, sizeof(sbuf), _TRUNCATE, "scp -t %s", c->scp.sendfile);
6861    
6862                    } else {                
6863                            _snprintf_s(sbuf, sizeof(sbuf), _TRUNCATE, "scp -f %s", c->scp.sendfile);
6864    
6865                    }
6866                  buffer_put_string(msg, sbuf, strlen(sbuf));                  buffer_put_string(msg, sbuf, strlen(sbuf));
6867                  goto done;                  goto done;
6868          }          }
# Line 7161  static unsigned __stdcall ssh_scp_thread Line 7190  static unsigned __stdcall ssh_scp_thread
7190          do {          do {
7191                  // Cancelボタンが押下されたらウィンドウが消える。                  // Cancelボタンが押下されたらウィンドウが消える。
7192                  if (IsWindowVisible(hWnd) == 0)                  if (IsWindowVisible(hWnd) == 0)
7193                          goto abort;                          goto cancel_abort;
7194    
7195                  // ファイルから読み込んだデータはかならずサーバへ送信する。                  // ファイルから読み込んだデータはかならずサーバへ送信する。
7196                  ret = fread(buf, 1, sizeof(buf), c->scp.sendfp);                  ret = fread(buf, 1, sizeof(buf), c->scp.sendfp);
# Line 7207  static unsigned __stdcall ssh_scp_thread Line 7236  static unsigned __stdcall ssh_scp_thread
7236          c->scp.state = SCP_DATA;          c->scp.state = SCP_DATA;
7237          return 0;          return 0;
7238    
7239  abort:  cancel_abort:
7240          ssh2_channel_send_close(pvar, c);          ssh2_channel_send_close(pvar, c);
7241    
7242  #if 0  abort:
7243          // デッドロック回避のため、自分でハンドルをクローズする。  
         CloseHandle(c->scp.thread);  
         c->scp.thread = (HANDLE)-1L;  
         //ssh2_channel_delete(c);  // free channel  
 #endif  
7244          return 0;          return 0;
7245  }  }
7246    
7247    
7248    static void SSH2_scp_tolocal(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen)
7249    {
7250            if (c->scp.state == SCP_INIT) {
7251                    char buf[128];
7252    
7253                    _snprintf_s(buf, sizeof(buf), _TRUNCATE, "T%lu 0 %lu 0\n",
7254                            (unsigned long)c->scp.filestat.st_mtime,  (unsigned long)c->scp.filestat.st_atime);
7255    
7256                    c->scp.state = SCP_TIMESTAMP;
7257                    SSH2_send_channel_data(pvar, c, buf, strlen(buf));
7258    
7259            } else if (c->scp.state == SCP_TIMESTAMP) {
7260                    char buf[128];
7261    
7262                    _snprintf_s(buf, sizeof(buf), _TRUNCATE, "C0644 %lld %s\n",
7263                            (long long)c->scp.filestat.st_size, c->scp.sendfile);
7264    
7265                    c->scp.state = SCP_FILEINFO;
7266                    SSH2_send_channel_data(pvar, c, buf, strlen(buf));
7267    
7268            } else if (c->scp.state == SCP_FILEINFO) {
7269                    HWND hDlgWnd;
7270                    HANDLE thread;
7271                    unsigned int tid;
7272    
7273                    c->scp.pvar = pvar;
7274    
7275                    hDlgWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_SSHSCP_PROGRESS),
7276                                       pvar->cv->HWin, (DLGPROC)ssh_scp_dlg_proc);
7277                    if (hDlgWnd != NULL) {
7278                            c->scp.progress = hDlgWnd;
7279                            ShowWindow(hDlgWnd, SW_SHOW);
7280                    }
7281    
7282                    thread = (HANDLE)_beginthreadex(NULL, 0, ssh_scp_thread, c, 0, &tid);
7283                    if (thread == (HANDLE)-1) {
7284                            // TODO:
7285                    }
7286                    c->scp.thread = thread;
7287    
7288    
7289            } else if (c->scp.state == SCP_DATA) {
7290                    // 送信完了
7291                    ssh2_channel_send_close(pvar, c);
7292                    //ssh2_channel_delete(c);  // free channel
7293    
7294                    //MessageBox(NULL, "SCP sending done.", "TTSSH", MB_OK);
7295            }
7296    }
7297    
7298    static void SSH2_scp_response(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen)
7299    {
7300            if (buflen == 1 && data[0] == '\0') {  // OK
7301                    if (c->scp.dir == TOLOCAL) {
7302                            SSH2_scp_tolocal(pvar, c, data, buflen);
7303                    } else {
7304                            //SSH2_scp_fromremote(pvar, c, data, buflen);
7305                    }
7306    
7307            } else {  // error
7308                    char msg[2048];
7309                    unsigned int i, max;
7310    
7311                    if (buflen > sizeof(msg))
7312                            max = sizeof(msg);
7313                    else
7314                            max = buflen - 1;
7315                    for (i = 0 ; i < max ; i++) {
7316                            msg[i] = data[i + 1];
7317                    }
7318                    msg[i] = '\0';
7319    
7320                    ssh2_channel_send_close(pvar, c);
7321                    //ssh2_channel_delete(c);  // free channel
7322    
7323                    MessageBox(NULL, msg, "TTSSH: SCP error", MB_OK | MB_ICONEXCLAMATION);
7324            }
7325    }
7326    
7327    
7328  static BOOL handle_SSH2_channel_data(PTInstVar pvar)  static BOOL handle_SSH2_channel_data(PTInstVar pvar)
7329  {        {      
7330          int len;          int len;
# Line 7268  static BOOL handle_SSH2_channel_data(PTI Line 7374  static BOOL handle_SSH2_channel_data(PTI
7374                  FWD_received_data(pvar, c->local_num, data, str_len);                  FWD_received_data(pvar, c->local_num, data, str_len);
7375    
7376          } else if (c->type == TYPE_SCP) {  // SCP          } else if (c->type == TYPE_SCP) {  // SCP
7377                  if (str_len == 1 && data[0] == '\0') {  // OK                  SSH2_scp_response(pvar, c, data, str_len);
   
                         if (c->scp.state == SCP_INIT) {  
                                 char buf[128];  
   
                                 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "T%lu 0 %lu 0\n",  
                                         (unsigned long)c->scp.filestat.st_mtime,  (unsigned long)c->scp.filestat.st_atime);  
   
                                 c->scp.state = SCP_TIMESTAMP;  
                                 SSH2_send_channel_data(pvar, c, buf, strlen(buf));  
   
                         } else if (c->scp.state == SCP_TIMESTAMP) {  
                                 char buf[128];  
   
                                 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "C0644 %lld %s\n",  
                                         (long long)c->scp.filestat.st_size, c->scp.sendfile);  
   
                                 c->scp.state = SCP_FILEINFO;  
                                 SSH2_send_channel_data(pvar, c, buf, strlen(buf));  
   
                         } else if (c->scp.state == SCP_FILEINFO) {  
                                 HWND hDlgWnd;  
                                 HANDLE thread;  
                                 unsigned int tid;  
   
                                 c->scp.pvar = pvar;  
   
                                 hDlgWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_SSHSCP_PROGRESS),  
                                pvar->cv->HWin, (DLGPROC)ssh_scp_dlg_proc);  
                                 if (hDlgWnd != NULL) {  
                                         c->scp.progress = hDlgWnd;  
                                         ShowWindow(hDlgWnd, SW_SHOW);  
                                 }  
   
                                 thread = (HANDLE)_beginthreadex(NULL, 0, ssh_scp_thread, c, 0, &tid);  
                                 if (thread == (HANDLE)-1) {  
                                         // TODO:  
                                 }  
                                 c->scp.thread = thread;  
   
   
                         } else if (c->scp.state == SCP_DATA) {  
                                 // 送信完了  
                                 ssh2_channel_send_close(pvar, c);  
                                 //ssh2_channel_delete(c);  // free channel  
   
                                 //MessageBox(NULL, "SCP sending done.", "TTSSH", MB_OK);  
                         }  
   
                 } else {  // error  
                         char msg[2048];  
                         unsigned int i, max;  
   
                         if (str_len > sizeof(msg))  
                                 max = sizeof(msg);  
                         else  
                                 max = str_len - 1;  
                         for (i = 0 ; i < max ; i++) {  
                                 msg[i] = data[i + 1];  
                         }  
                         msg[i] = '\0';  
   
                         ssh2_channel_send_close(pvar, c);  
                         //ssh2_channel_delete(c);  // free channel  
   
                         MessageBox(NULL, msg, "TTSSH: SCP error", MB_OK | MB_ICONEXCLAMATION);  
                 }  
7378          }          }
7379    
7380          //debug_print(200, data, strlen);          //debug_print(200, data, strlen);

Legend:
Removed from v.3080  
changed lines
  Added in v.3081

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