[Ttssh2-commit] [5039] SSH2遅延送信の不具合で、SSHデータが壊れる問題を修正した。

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2012年 10月 14日 (日) 01:18:30 JST


Revision: 5039
          http://sourceforge.jp/projects/ttssh2/scm/svn/commits/5039
Author:   yutakapon
Date:     2012-10-14 01:18:29 +0900 (Sun, 14 Oct 2012)
Log Message:
-----------
SSH2遅延送信の不具合で、SSHデータが壊れる問題を修正した。

Modified Paths:
--------------
    trunk/doc/en/html/about/history.html
    trunk/doc/ja/html/about/history.html
    trunk/ttssh2/ttxssh/fwd.c
    trunk/ttssh2/ttxssh/sftp.c
    trunk/ttssh2/ttxssh/ssh.c
    trunk/ttssh2/ttxssh/ssh.h

-------------- next part --------------
Modified: trunk/doc/en/html/about/history.html
===================================================================
--- trunk/doc/en/html/about/history.html	2012-10-13 15:37:56 UTC (rev 5038)
+++ trunk/doc/en/html/about/history.html	2012-10-13 16:18:29 UTC (rev 5039)
@@ -1959,6 +1959,7 @@
   <li>Bug fixes
     <ul>
       <li>SCP sending will be failed for Dropbear 2012.55(SSH server).</li>
+      <li>The SSH data will be corrupted by SSH2 delay re-transmit bug.</li>
     </ul>
   </li>
 

Modified: trunk/doc/ja/html/about/history.html
===================================================================
--- trunk/doc/ja/html/about/history.html	2012-10-13 15:37:56 UTC (rev 5038)
+++ trunk/doc/ja/html/about/history.html	2012-10-13 16:18:29 UTC (rev 5039)
@@ -1960,6 +1960,7 @@
   <li>\x83o\x83O\x8FC\x90\xB3
     <ul>
       <li>Dropbear 2012.55(SSH\x83T\x81[\x83o)\x82ɑ΂\xB5\x82āASCP\x91\x97\x90M\x82\xAA\x8E\xB8\x94s\x82\xB7\x82\xE9\x96\xE2\x91\xE8\x82\xF0\x8FC\x90\xB3\x82\xB5\x82\xBD\x81B</li>
+      <li>SSH2\x92x\x89\x84\x91\x97\x90M\x82̕s\x8B\x82ŁASSH\x83f\x81[\x83^\x82\xAA\x89\xF3\x82\xEA\x82\xE9\x96\xE2\x91\xE8\x82\xF0\x8FC\x90\xB3\x82\xB5\x82\xBD\x81B</li>
     </ul>
   </li>
 

Modified: trunk/ttssh2/ttxssh/fwd.c
===================================================================
--- trunk/ttssh2/ttxssh/fwd.c	2012-10-13 15:37:56 UTC (rev 5038)
+++ trunk/ttssh2/ttxssh/fwd.c	2012-10-13 16:18:29 UTC (rev 5039)
@@ -769,7 +769,7 @@
 			 && (channel->status & FWD_CLOSED_REMOTE_OUT) == 0) {
 				// \x83|\x81[\x83g\x83t\x83H\x83\x8F\x81[\x83f\x83B\x83\x93\x83O\x82ɂ\xA8\x82\xA2\x82ăN\x83\x89\x83C\x83A\x83\x93\x83g\x82\xA9\x82\xE7\x82̑\x97\x90M\x97v\x8B\x81\x82\xF0\x81ASSH\x92ʐM\x82ɏ悹\x82ăT\x81[\x83o\x82܂ő\x97\x82\xE8\x93͂\xAF\x82\xE9\x81B
 				SSH_channel_send(pvar, channel_num, channel->remote_num, new_buf,
-				                 amount);
+				                 amount, 0);
 			}
 
 			switch (action) {

Modified: trunk/ttssh2/ttxssh/sftp.c
===================================================================
--- trunk/ttssh2/ttxssh/sftp.c	2012-10-13 15:37:56 UTC (rev 5038)
+++ trunk/ttssh2/ttxssh/sftp.c	2012-10-13 16:18:29 UTC (rev 5039)
@@ -216,7 +216,7 @@
 	// \x8Dŏ\x89\x82Ƀ\x81\x83b\x83Z\x81[\x83W\x83T\x83C\x83Y\x82\xF0\x8Ai\x94[\x82\xB7\x82\xE9\x81B
 	set_uint32(p, len - 4);
 	// \x83y\x83C\x83\x8D\x81[\x83h\x82̑\x97\x90M\x81B
-	SSH2_send_channel_data(pvar, c, p, len);
+	SSH2_send_channel_data(pvar, c, p, len, 0);
 }
 
 // \x83T\x81[\x83o\x82\xA9\x82\xE7\x8E\xF3\x90M\x82\xB5\x82\xBDSFTP\x83p\x83P\x83b\x83g\x82\xF0\x83o\x83b\x83t\x83@\x82Ɋi\x94[\x82\xB7\x82\xE9\x81B
@@ -433,204 +433,204 @@
     return conn->version;
 } 
 
-static void
-help(void)
-{
-	sftp_console_message(g_pvar, g_channel, 
-		"Available commands:\r\n"
-	    "bye                                Quit sftp\r\n"
-	    "cd path                            Change remote directory to 'path'\r\n"
-	    "chgrp grp path                     Change group of file 'path' to 'grp'\r\n"
-	    "chmod mode path                    Change permissions of file 'path' to 'mode'\r\n"
-	    "chown own path                     Change owner of file 'path' to 'own'\r\n"
-	    "df [-hi] [path]                    Display statistics for current directory or\r\n"
-	    "                                   filesystem containing 'path'\r\n"
-	    "exit                               Quit sftp\r\n"
-	    "get [-Ppr] remote [local]          Download file\r\n"
-	    "help                               Display this help text\r\n"
-	    "lcd path                           Change local directory to 'path'\r\n"
-	    "lls [ls-options [path]]            Display local directory listing\r\n"
-	    "lmkdir path                        Create local directory\r\n"
-	    "ln [-s] oldpath newpath            Link remote file (-s for symlink)\r\n"
-	    "lpwd                               Print local working directory\r\n"
-	    "ls [-1afhlnrSt] [path]             Display remote directory listing\r\n"
-	    "lumask umask                       Set local umask to 'umask'\r\n"
-	    "mkdir path                         Create remote directory\r\n"
-	    "progress                           Toggle display of progress meter\r\n"
-	    "put [-Ppr] local [remote]          Upload file\r\n"
-	    "pwd                                Display remote working directory\r\n"
-	    "quit                               Quit sftp\r\n"
-	    "rename oldpath newpath             Rename remote file\r\n"
-	    "rm path                            Delete remote file\r\n"
-	    "rmdir path                         Remove remote directory\r\n"
-	    "symlink oldpath newpath            Symlink remote file\r\n"
-	    "version                            Show SFTP version\r\n"
-	    "!command                           Execute 'command' in local shell\r\n"
-	    "!                                  Escape to local shell\r\n"
-	    "?                                  Synonym for help\r\n");
-}
+static void
+help(void)
+{
+	sftp_console_message(g_pvar, g_channel, 
+		"Available commands:\r\n"
+	    "bye                                Quit sftp\r\n"
+	    "cd path                            Change remote directory to 'path'\r\n"
+	    "chgrp grp path                     Change group of file 'path' to 'grp'\r\n"
+	    "chmod mode path                    Change permissions of file 'path' to 'mode'\r\n"
+	    "chown own path                     Change owner of file 'path' to 'own'\r\n"
+	    "df [-hi] [path]                    Display statistics for current directory or\r\n"
+	    "                                   filesystem containing 'path'\r\n"
+	    "exit                               Quit sftp\r\n"
+	    "get [-Ppr] remote [local]          Download file\r\n"
+	    "help                               Display this help text\r\n"
+	    "lcd path                           Change local directory to 'path'\r\n"
+	    "lls [ls-options [path]]            Display local directory listing\r\n"
+	    "lmkdir path                        Create local directory\r\n"
+	    "ln [-s] oldpath newpath            Link remote file (-s for symlink)\r\n"
+	    "lpwd                               Print local working directory\r\n"
+	    "ls [-1afhlnrSt] [path]             Display remote directory listing\r\n"
+	    "lumask umask                       Set local umask to 'umask'\r\n"
+	    "mkdir path                         Create remote directory\r\n"
+	    "progress                           Toggle display of progress meter\r\n"
+	    "put [-Ppr] local [remote]          Upload file\r\n"
+	    "pwd                                Display remote working directory\r\n"
+	    "quit                               Quit sftp\r\n"
+	    "rename oldpath newpath             Rename remote file\r\n"
+	    "rm path                            Delete remote file\r\n"
+	    "rmdir path                         Remove remote directory\r\n"
+	    "symlink oldpath newpath            Symlink remote file\r\n"
+	    "version                            Show SFTP version\r\n"
+	    "!command                           Execute 'command' in local shell\r\n"
+	    "!                                  Escape to local shell\r\n"
+	    "?                                  Synonym for help\r\n");
+}
 
-/*
- * Split a string into an argument vector using sh(1)-style quoting,
- * comment and escaping rules, but with some tweaks to handle glob(3)
- * wildcards.
- * The "sloppy" flag allows for recovery from missing terminating quote, for
- * use in parsing incomplete commandlines during tab autocompletion.
- *
- * Returns NULL on error or a NULL-terminated array of arguments.
- *
- * If "lastquote" is not NULL, the quoting character used for the last
- * argument is placed in *lastquote ("\0", "'" or "\"").
- * 
- * If "terminated" is not NULL, *terminated will be set to 1 when the
- * last argument's quote has been properly terminated or 0 otherwise.
- * This parameter is only of use if "sloppy" is set.
- */
-#define MAXARGS 	128
-#define MAXARGLEN	8192
-static char **
-makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
-    u_int *terminated)
-{
-	int argc, quot;
-	size_t i, j;
-	static char argvs[MAXARGLEN];
-	static char *argv[MAXARGS + 1];
-	enum { MA_START, MA_SQUOTE, MA_DQUOTE, MA_UNQUOTED } state, q;
-
-	*argcp = argc = 0;
-	if (strlen(arg) > sizeof(argvs) - 1) {
- args_too_longs:
-		sftp_syslog(g_pvar, "string too long");
-		return NULL;
-	}
-	if (terminated != NULL)
-		*terminated = 1;
-	if (lastquote != NULL)
-		*lastquote = '\0';
-	state = MA_START;
-	i = j = 0;
-	for (;;) {
-		if (isspace(arg[i])) {
-			if (state == MA_UNQUOTED) {
-				/* Terminate current argument */
-				argvs[j++] = '\0';
-				argc++;
-				state = MA_START;
-			} else if (state != MA_START)
-				argvs[j++] = arg[i];
-		} else if (arg[i] == '"' || arg[i] == '\'') {
-			q = arg[i] == '"' ? MA_DQUOTE : MA_SQUOTE;
-			if (state == MA_START) {
-				argv[argc] = argvs + j;
-				state = q;
-				if (lastquote != NULL)
-					*lastquote = arg[i];
-			} else if (state == MA_UNQUOTED) 
-				state = q;
-			else if (state == q)
-				state = MA_UNQUOTED;
-			else
-				argvs[j++] = arg[i];
-		} else if (arg[i] == '\\') {
-			if (state == MA_SQUOTE || state == MA_DQUOTE) {
-				quot = state == MA_SQUOTE ? '\'' : '"';
-				/* Unescape quote we are in */
-				/* XXX support \n and friends? */
-				if (arg[i + 1] == quot) {
-					i++;
-					argvs[j++] = arg[i];
-				} else if (arg[i + 1] == '?' ||
-				    arg[i + 1] == '[' || arg[i + 1] == '*') {
-					/*
-					 * Special case for sftp: append
-					 * double-escaped glob sequence -
-					 * glob will undo one level of
-					 * escaping. NB. string can grow here.
-					 */
-					if (j >= sizeof(argvs) - 5)
-						goto args_too_longs;
-					argvs[j++] = '\\';
-					argvs[j++] = arg[i++];
-					argvs[j++] = '\\';
-					argvs[j++] = arg[i];
-				} else {
-					argvs[j++] = arg[i++];
-					argvs[j++] = arg[i];
-				}
-			} else {
-				if (state == MA_START) {
-					argv[argc] = argvs + j;
-					state = MA_UNQUOTED;
-					if (lastquote != NULL)
-						*lastquote = '\0';
-				}
-				if (arg[i + 1] == '?' || arg[i + 1] == '[' ||
-				    arg[i + 1] == '*' || arg[i + 1] == '\\') {
-					/*
-					 * Special case for sftp: append
-					 * escaped glob sequence -
-					 * glob will undo one level of
-					 * escaping.
-					 */
-					argvs[j++] = arg[i++];
-					argvs[j++] = arg[i];
-				} else {
-					/* Unescape everything */
-					/* XXX support \n and friends? */
-					i++;
-					argvs[j++] = arg[i];
-				}
-			}
-		} else if (arg[i] == '#') {
-			if (state == MA_SQUOTE || state == MA_DQUOTE)
-				argvs[j++] = arg[i];
-			else
-				goto string_done;
-		} else if (arg[i] == '\0') {
-			if (state == MA_SQUOTE || state == MA_DQUOTE) {
-				if (sloppy) {
-					state = MA_UNQUOTED;
-					if (terminated != NULL)
-						*terminated = 0;
-					goto string_done;
-				}
-				sftp_syslog(g_pvar, "Unterminated quoted argument");
-				return NULL;
-			}
- string_done:
-			if (state == MA_UNQUOTED) {
-				argvs[j++] = '\0';
-				argc++;
-			}
-			break;
-		} else {
-			if (state == MA_START) {
-				argv[argc] = argvs + j;
-				state = MA_UNQUOTED;
-				if (lastquote != NULL)
-					*lastquote = '\0';
-			}
-			if ((state == MA_SQUOTE || state == MA_DQUOTE) &&
-			    (arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) {
-				/*
-				 * Special case for sftp: escape quoted
-				 * glob(3) wildcards. NB. string can grow
-				 * here.
-				 */
-				if (j >= sizeof(argvs) - 3)
-					goto args_too_longs;
-				argvs[j++] = '\\';
-				argvs[j++] = arg[i];
-			} else
-				argvs[j++] = arg[i];
-		}
-		i++;
-	}
-	*argcp = argc;
-	return argv;
-}
+/*
+ * Split a string into an argument vector using sh(1)-style quoting,
+ * comment and escaping rules, but with some tweaks to handle glob(3)
+ * wildcards.
+ * The "sloppy" flag allows for recovery from missing terminating quote, for
+ * use in parsing incomplete commandlines during tab autocompletion.
+ *
+ * Returns NULL on error or a NULL-terminated array of arguments.
+ *
+ * If "lastquote" is not NULL, the quoting character used for the last
+ * argument is placed in *lastquote ("\0", "'" or "\"").
+ * 
+ * If "terminated" is not NULL, *terminated will be set to 1 when the
+ * last argument's quote has been properly terminated or 0 otherwise.
+ * This parameter is only of use if "sloppy" is set.
+ */
+#define MAXARGS 	128
+#define MAXARGLEN	8192
+static char **
+makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
+    u_int *terminated)
+{
+	int argc, quot;
+	size_t i, j;
+	static char argvs[MAXARGLEN];
+	static char *argv[MAXARGS + 1];
+	enum { MA_START, MA_SQUOTE, MA_DQUOTE, MA_UNQUOTED } state, q;
 
+	*argcp = argc = 0;
+	if (strlen(arg) > sizeof(argvs) - 1) {
+ args_too_longs:
+		sftp_syslog(g_pvar, "string too long");
+		return NULL;
+	}
+	if (terminated != NULL)
+		*terminated = 1;
+	if (lastquote != NULL)
+		*lastquote = '\0';
+	state = MA_START;
+	i = j = 0;
+	for (;;) {
+		if (isspace(arg[i])) {
+			if (state == MA_UNQUOTED) {
+				/* Terminate current argument */
+				argvs[j++] = '\0';
+				argc++;
+				state = MA_START;
+			} else if (state != MA_START)
+				argvs[j++] = arg[i];
+		} else if (arg[i] == '"' || arg[i] == '\'') {
+			q = arg[i] == '"' ? MA_DQUOTE : MA_SQUOTE;
+			if (state == MA_START) {
+				argv[argc] = argvs + j;
+				state = q;
+				if (lastquote != NULL)
+					*lastquote = arg[i];
+			} else if (state == MA_UNQUOTED) 
+				state = q;
+			else if (state == q)
+				state = MA_UNQUOTED;
+			else
+				argvs[j++] = arg[i];
+		} else if (arg[i] == '\\') {
+			if (state == MA_SQUOTE || state == MA_DQUOTE) {
+				quot = state == MA_SQUOTE ? '\'' : '"';
+				/* Unescape quote we are in */
+				/* XXX support \n and friends? */
+				if (arg[i + 1] == quot) {
+					i++;
+					argvs[j++] = arg[i];
+				} else if (arg[i + 1] == '?' ||
+				    arg[i + 1] == '[' || arg[i + 1] == '*') {
+					/*
+					 * Special case for sftp: append
+					 * double-escaped glob sequence -
+					 * glob will undo one level of
+					 * escaping. NB. string can grow here.
+					 */
+					if (j >= sizeof(argvs) - 5)
+						goto args_too_longs;
+					argvs[j++] = '\\';
+					argvs[j++] = arg[i++];
+					argvs[j++] = '\\';
+					argvs[j++] = arg[i];
+				} else {
+					argvs[j++] = arg[i++];
+					argvs[j++] = arg[i];
+				}
+			} else {
+				if (state == MA_START) {
+					argv[argc] = argvs + j;
+					state = MA_UNQUOTED;
+					if (lastquote != NULL)
+						*lastquote = '\0';
+				}
+				if (arg[i + 1] == '?' || arg[i + 1] == '[' ||
+				    arg[i + 1] == '*' || arg[i + 1] == '\\') {
+					/*
+					 * Special case for sftp: append
+					 * escaped glob sequence -
+					 * glob will undo one level of
+					 * escaping.
+					 */
+					argvs[j++] = arg[i++];
+					argvs[j++] = arg[i];
+				} else {
+					/* Unescape everything */
+					/* XXX support \n and friends? */
+					i++;
+					argvs[j++] = arg[i];
+				}
+			}
+		} else if (arg[i] == '#') {
+			if (state == MA_SQUOTE || state == MA_DQUOTE)
+				argvs[j++] = arg[i];
+			else
+				goto string_done;
+		} else if (arg[i] == '\0') {
+			if (state == MA_SQUOTE || state == MA_DQUOTE) {
+				if (sloppy) {
+					state = MA_UNQUOTED;
+					if (terminated != NULL)
+						*terminated = 0;
+					goto string_done;
+				}
+				sftp_syslog(g_pvar, "Unterminated quoted argument");
+				return NULL;
+			}
+ string_done:
+			if (state == MA_UNQUOTED) {
+				argvs[j++] = '\0';
+				argc++;
+			}
+			break;
+		} else {
+			if (state == MA_START) {
+				argv[argc] = argvs + j;
+				state = MA_UNQUOTED;
+				if (lastquote != NULL)
+					*lastquote = '\0';
+			}
+			if ((state == MA_SQUOTE || state == MA_DQUOTE) &&
+			    (arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) {
+				/*
+				 * Special case for sftp: escape quoted
+				 * glob(3) wildcards. NB. string can grow
+				 * here.
+				 */
+				if (j >= sizeof(argvs) - 3)
+					goto args_too_longs;
+				argvs[j++] = '\\';
+				argvs[j++] = arg[i];
+			} else
+				argvs[j++] = arg[i];
+		}
+		i++;
+	}
+	*argcp = argc;
+	return argv;
+}
+
 static int parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
     int *hflag, int *sflag, unsigned long *n_arg, char **path1, char **path2)
 {
@@ -658,150 +658,150 @@
     if ((argv = makeargv(cp, &argc, 0, NULL, NULL)) == NULL)
         return -1;
 
-	/* Figure out which command we have */
-	for (i = 0; cmds[i].c != NULL; i++) {
-		if (_strcmpi(cmds[i].c, argv[0]) == 0)
-			break;
-	}
-	cmdnum = cmds[i].n;
-	cmd = cmds[i].c;
-
-	/* Special case */
-	if (*cp == '!') {
-		cp++;
-		cmdnum = I_SHELL;
-	} else if (cmdnum == -1) {
-		sftp_syslog(g_pvar, "Invalid command.");
-		return -1;
-	}
-
-	/* Get arguments and parse flags */
-	*lflag = *pflag = *rflag = *hflag = *n_arg = 0;
-	*path1 = *path2 = NULL;
-	optidx = 1;
-	switch (cmdnum) {
-#if 0
-	case I_GET:
-	case I_PUT:
-		if ((optidx = parse_getput_flags(cmd, argv, argc,
-		    pflag, rflag)) == -1)
-			return -1;
-		/* Get first pathname (mandatory) */
-		if (argc - optidx < 1) {
-			error("You must specify at least one path after a "
-			    "%s command.", cmd);
-			return -1;
-		}
-		*path1 = xstrdup(argv[optidx]);
-		/* Get second pathname (optional) */
-		if (argc - optidx > 1) {
-			*path2 = xstrdup(argv[optidx + 1]);
-			/* Destination is not globbed */
-			undo_glob_escape(*path2);
-		}
-		break;
-	case I_LINK:
-		if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1)
-			return -1;
-	case I_SYMLINK:
-	case I_RENAME:
-		if (argc - optidx < 2) {
-			error("You must specify two paths after a %s "
-			    "command.", cmd);
-			return -1;
-		}
-		*path1 = xstrdup(argv[optidx]);
-		*path2 = xstrdup(argv[optidx + 1]);
-		/* Paths are not globbed */
-		undo_glob_escape(*path1);
-		undo_glob_escape(*path2);
-		break;
-	case I_RM:
-	case I_MKDIR:
-	case I_RMDIR:
-	case I_CHDIR:
-	case I_LCHDIR:
-	case I_LMKDIR:
-		/* Get pathname (mandatory) */
-		if (argc - optidx < 1) {
-			error("You must specify a path after a %s command.",
-			    cmd);
-			return -1;
-		}
-		*path1 = xstrdup(argv[optidx]);
-		/* Only "rm" globs */
-		if (cmdnum != I_RM)
-			undo_glob_escape(*path1);
-		break;
-	case I_DF:
-		if ((optidx = parse_df_flags(cmd, argv, argc, hflag,
-		    iflag)) == -1)
-			return -1;
-		/* Default to current directory if no path specified */
-		if (argc - optidx < 1)
-			*path1 = NULL;
-		else {
-			*path1 = xstrdup(argv[optidx]);
-			undo_glob_escape(*path1);
-		}
-		break;
-	case I_LS:
-		if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
-			return(-1);
-		/* Path is optional */
-		if (argc - optidx > 0)
-			*path1 = xstrdup(argv[optidx]);
-		break;
-	case I_LLS:
-		/* Skip ls command and following whitespace */
-		cp = cp + strlen(cmd) + strspn(cp, WHITESPACE);
-	case I_SHELL:
-		/* Uses the rest of the line */
-		break;
-	case I_LUMASK:
-	case I_CHMOD:
-		base = 8;
-	case I_CHOWN:
-	case I_CHGRP:
-		/* Get numeric arg (mandatory) */
-		if (argc - optidx < 1)
-			goto need_num_arg;
-		errno = 0;
-		l = strtol(argv[optidx], &cp2, base);
-		if (cp2 == argv[optidx] || *cp2 != '\0' ||
-		    ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) ||
-		    l < 0) {
- need_num_arg:
-			error("You must supply a numeric argument "
-			    "to the %s command.", cmd);
-			return -1;
-		}
-		*n_arg = l;
-		if (cmdnum == I_LUMASK)
-			break;
-		/* Get pathname (mandatory) */
-		if (argc - optidx < 2) {
-			error("You must specify a path after a %s command.",
-			    cmd);
-			return -1;
-		}
-		*path1 = xstrdup(argv[optidx + 1]);
-		break;
-#endif
-	case I_QUIT:
-	case I_PWD:
-	case I_LPWD:
-	case I_HELP:
-	case I_VERSION:
-	case I_PROGRESS:
-		break;
-	default:
-		//fatal("Command not implemented");
-		return -1;
-	}
-
-	*cpp = cp;
-	return(cmdnum);
+	/* Figure out which command we have */
+	for (i = 0; cmds[i].c != NULL; i++) {
+		if (_strcmpi(cmds[i].c, argv[0]) == 0)
+			break;
+	}
+	cmdnum = cmds[i].n;
+	cmd = cmds[i].c;
+
+	/* Special case */
+	if (*cp == '!') {
+		cp++;
+		cmdnum = I_SHELL;
+	} else if (cmdnum == -1) {
+		sftp_syslog(g_pvar, "Invalid command.");
+		return -1;
+	}
+
+	/* Get arguments and parse flags */
+	*lflag = *pflag = *rflag = *hflag = *n_arg = 0;
+	*path1 = *path2 = NULL;
+	optidx = 1;
+	switch (cmdnum) {
+#if 0
+	case I_GET:
+	case I_PUT:
+		if ((optidx = parse_getput_flags(cmd, argv, argc,
+		    pflag, rflag)) == -1)
+			return -1;
+		/* Get first pathname (mandatory) */
+		if (argc - optidx < 1) {
+			error("You must specify at least one path after a "
+			    "%s command.", cmd);
+			return -1;
+		}
+		*path1 = xstrdup(argv[optidx]);
+		/* Get second pathname (optional) */
+		if (argc - optidx > 1) {
+			*path2 = xstrdup(argv[optidx + 1]);
+			/* Destination is not globbed */
+			undo_glob_escape(*path2);
+		}
+		break;
+	case I_LINK:
+		if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1)
+			return -1;
+	case I_SYMLINK:
+	case I_RENAME:
+		if (argc - optidx < 2) {
+			error("You must specify two paths after a %s "
+			    "command.", cmd);
+			return -1;
+		}
+		*path1 = xstrdup(argv[optidx]);
+		*path2 = xstrdup(argv[optidx + 1]);
+		/* Paths are not globbed */
+		undo_glob_escape(*path1);
+		undo_glob_escape(*path2);
+		break;
+	case I_RM:
+	case I_MKDIR:
+	case I_RMDIR:
+	case I_CHDIR:
+	case I_LCHDIR:
+	case I_LMKDIR:
+		/* Get pathname (mandatory) */
+		if (argc - optidx < 1) {
+			error("You must specify a path after a %s command.",
+			    cmd);
+			return -1;
+		}
+		*path1 = xstrdup(argv[optidx]);
+		/* Only "rm" globs */
+		if (cmdnum != I_RM)
+			undo_glob_escape(*path1);
+		break;
+	case I_DF:
+		if ((optidx = parse_df_flags(cmd, argv, argc, hflag,
+		    iflag)) == -1)
+			return -1;
+		/* Default to current directory if no path specified */
+		if (argc - optidx < 1)
+			*path1 = NULL;
+		else {
+			*path1 = xstrdup(argv[optidx]);
+			undo_glob_escape(*path1);
+		}
+		break;
+	case I_LS:
+		if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
+			return(-1);
+		/* Path is optional */
+		if (argc - optidx > 0)
+			*path1 = xstrdup(argv[optidx]);
+		break;
+	case I_LLS:
+		/* Skip ls command and following whitespace */
+		cp = cp + strlen(cmd) + strspn(cp, WHITESPACE);
+	case I_SHELL:
+		/* Uses the rest of the line */
+		break;
+	case I_LUMASK:
+	case I_CHMOD:
+		base = 8;
+	case I_CHOWN:
+	case I_CHGRP:
+		/* Get numeric arg (mandatory) */
+		if (argc - optidx < 1)
+			goto need_num_arg;
+		errno = 0;
+		l = strtol(argv[optidx], &cp2, base);
+		if (cp2 == argv[optidx] || *cp2 != '\0' ||
+		    ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) ||
+		    l < 0) {
+ need_num_arg:
+			error("You must supply a numeric argument "
+			    "to the %s command.", cmd);
+			return -1;
+		}
+		*n_arg = l;
+		if (cmdnum == I_LUMASK)
+			break;
+		/* Get pathname (mandatory) */
+		if (argc - optidx < 2) {
+			error("You must specify a path after a %s command.",
+			    cmd);
+			return -1;
+		}
+		*path1 = xstrdup(argv[optidx + 1]);
+		break;
+#endif
+	case I_QUIT:
+	case I_PWD:
+	case I_LPWD:
+	case I_HELP:
+	case I_VERSION:
+	case I_PROGRESS:
+		break;
+	default:
+		//fatal("Command not implemented");
+		return -1;
+	}
+
+	*cpp = cp;
+	return(cmdnum);
 }
 
 
@@ -818,9 +818,9 @@
     int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, sflag = 0;
     int cmdnum, i = 0;
     unsigned long n_arg = 0;
-	//Attrib a, *aa;
-	char path_buf[1024] = {0};
-	int err = 0;
+	//Attrib a, *aa;
+	char path_buf[1024] = {0};
+	int err = 0;
 	//glob_t g;
 	int err_abort;
 
@@ -849,229 +849,229 @@
 	cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag,
 		&sflag, &n_arg, &path1, &path2);
 
-	if (iflag != 0)
-		err_abort = 0;
-
-	//memset(&g, 0, sizeof(g));
-
-	/* Perform command */
-	switch (cmdnum) {
-	case 0:
-		/* Blank line */
-		break;
-	case -1:
-		/* Unrecognized command */
-		err = -1;
-		break;
-#if 0
-	case I_GET:
-		err = process_get(conn, path1, path2, *pwd, pflag, rflag);
-		break;
-	case I_PUT:
-		err = process_put(conn, path1, path2, *pwd, pflag, rflag);
-		break;
-	case I_RENAME:
-		path1 = make_absolute(path1, *pwd);
-		path2 = make_absolute(path2, *pwd);
-		err = do_rename(conn, path1, path2);
-		break;
-	case I_SYMLINK:
-		sflag = 1;
-	case I_LINK:
-		path1 = make_absolute(path1, *pwd);
-		path2 = make_absolute(path2, *pwd);
-		err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2);
-		break;
-	case I_RM:
-		path1 = make_absolute(path1, *pwd);
-		remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
-		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
-			printf("Removing %s\n", g.gl_pathv[i]);
-			err = do_rm(conn, g.gl_pathv[i]);
-			if (err != 0 && err_abort)
-				break;
-		}
-		break;
-	case I_MKDIR:
-		path1 = make_absolute(path1, *pwd);
-		attrib_clear(&a);
-		a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
-		a.perm = 0777;
-		err = do_mkdir(conn, path1, &a, 1);
-		break;
-	case I_RMDIR:
-		path1 = make_absolute(path1, *pwd);
-		err = do_rmdir(conn, path1);
-		break;
-	case I_CHDIR:
-		path1 = make_absolute(path1, *pwd);
-		if ((tmp = do_realpath(conn, path1)) == NULL) {
-			err = 1;
-			break;
-		}
-		if ((aa = do_stat(conn, tmp, 0)) == NULL) {
-			xfree(tmp);
-			err = 1;
-			break;
-		}
-		if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
-			error("Can't change directory: Can't check target");
-			xfree(tmp);
-			err = 1;
-			break;
-		}
-		if (!S_ISDIR(aa->perm)) {
-			error("Can't change directory: \"%s\" is not "
-			    "a directory", tmp);
-			xfree(tmp);
-			err = 1;
-			break;
-		}
-		xfree(*pwd);
-		*pwd = tmp;
-		break;
-	case I_LS:
-		if (!path1) {
-			do_ls_dir(conn, *pwd, *pwd, lflag);
-			break;
-		}
-
-		/* Strip pwd off beginning of non-absolute paths */
-		tmp = NULL;
-		if (*path1 != '/')
-			tmp = *pwd;
-
-		path1 = make_absolute(path1, *pwd);
-		err = do_globbed_ls(conn, path1, tmp, lflag);
-		break;
-	case I_DF:
-		/* Default to current directory if no path specified */
-		if (path1 == NULL)
-			path1 = xstrdup(*pwd);
-		path1 = make_absolute(path1, *pwd);
-		err = do_df(conn, path1, hflag, iflag);
-		break;
-	case I_LCHDIR:
-		if (chdir(path1) == -1) {
-			error("Couldn't change local directory to "
-			    "\"%s\": %s", path1, strerror(errno));
-			err = 1;
-		}
-		break;
-	case I_LMKDIR:
-		if (mkdir(path1, 0777) == -1) {
-			error("Couldn't create local directory "
-			    "\"%s\": %s", path1, strerror(errno));
-			err = 1;
-		}
-		break;
-	case I_LLS:
-		local_do_ls(cmd);
-		break;
-	case I_SHELL:
-		local_do_shell(cmd);
-		break;
-	case I_LUMASK:
-		umask(n_arg);
-		printf("Local umask: %03lo\n", n_arg);
-		break;
-	case I_CHMOD:
-		path1 = make_absolute(path1, *pwd);
-		attrib_clear(&a);
-		a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
-		a.perm = n_arg;
-		remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
-		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
-			printf("Changing mode on %s\n", g.gl_pathv[i]);
-			err = do_setstat(conn, g.gl_pathv[i], &a);
-			if (err != 0 && err_abort)
-				break;
-		}
-		break;
-	case I_CHOWN:
-	case I_CHGRP:
-		path1 = make_absolute(path1, *pwd);
-		remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
-		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
-			if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) {
-				if (err_abort) {
-					err = -1;
-					break;
-				} else
-					continue;
-			}
-			if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
-				error("Can't get current ownership of "
-				    "remote file \"%s\"", g.gl_pathv[i]);
-				if (err_abort) {
-					err = -1;
-					break;
-				} else
-					continue;
-			}
-			aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
-			if (cmdnum == I_CHOWN) {
-				printf("Changing owner on %s\n", g.gl_pathv[i]);
-				aa->uid = n_arg;
-			} else {
-				printf("Changing group on %s\n", g.gl_pathv[i]);
-				aa->gid = n_arg;
-			}
-			err = do_setstat(conn, g.gl_pathv[i], aa);
-			if (err != 0 && err_abort)
-				break;
-		}
-		break;
-	case I_PWD:
-		printf("Remote working directory: %s\n", *pwd);
-		break;
-	case I_LPWD:
-		if (!getcwd(path_buf, sizeof(path_buf))) {
-			error("Couldn't get local cwd: %s", strerror(errno));
-			err = -1;
-			break;
-		}
-		printf("Local working directory: %s\n", path_buf);
-		break;
-#endif
-	case I_QUIT:
-		/* Processed below */
-		break;
-	case I_HELP:
-		help();
-		break;
-	case I_VERSION:
-		printf("SFTP protocol version %u\n", sftp_proto_version(&g_channel->sftp));
-		break;
-#if 0
-	case I_PROGRESS:
-		showprogress = !showprogress;
-		if (showprogress)
-			printf("Progress meter enabled\n");
-		else
-			printf("Progress meter disabled\n");
-		break;
-#endif
-	default:
-		//fatal("%d is not implemented", cmdnum);
-		err = -1;
-	}
-
-#if 0
-	if (g.gl_pathc)
-		globfree(&g);
-	if (path1)
-		xfree(path1);
-	if (path2)
-		xfree(path2);
-
-	/* If an unignored error occurs in batch mode we should abort. */
-	if (err_abort && err != 0)
-		return (-1);
-	else if (cmdnum == I_QUIT)
-		return (1);
-#endif
+	if (iflag != 0)
+		err_abort = 0;
 
+	//memset(&g, 0, sizeof(g));
+
+	/* Perform command */
+	switch (cmdnum) {
+	case 0:
+		/* Blank line */
+		break;
+	case -1:
+		/* Unrecognized command */
+		err = -1;
+		break;
+#if 0
+	case I_GET:
+		err = process_get(conn, path1, path2, *pwd, pflag, rflag);
+		break;
+	case I_PUT:
+		err = process_put(conn, path1, path2, *pwd, pflag, rflag);
+		break;
+	case I_RENAME:
+		path1 = make_absolute(path1, *pwd);
+		path2 = make_absolute(path2, *pwd);
+		err = do_rename(conn, path1, path2);
+		break;
+	case I_SYMLINK:
+		sflag = 1;
+	case I_LINK:
+		path1 = make_absolute(path1, *pwd);
+		path2 = make_absolute(path2, *pwd);
+		err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2);
+		break;
+	case I_RM:
+		path1 = make_absolute(path1, *pwd);
+		remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
+			printf("Removing %s\n", g.gl_pathv[i]);
+			err = do_rm(conn, g.gl_pathv[i]);
+			if (err != 0 && err_abort)
+				break;
+		}
+		break;
+	case I_MKDIR:
+		path1 = make_absolute(path1, *pwd);
+		attrib_clear(&a);
+		a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
+		a.perm = 0777;
+		err = do_mkdir(conn, path1, &a, 1);
+		break;
+	case I_RMDIR:
+		path1 = make_absolute(path1, *pwd);
+		err = do_rmdir(conn, path1);
+		break;
+	case I_CHDIR:
+		path1 = make_absolute(path1, *pwd);
+		if ((tmp = do_realpath(conn, path1)) == NULL) {
+			err = 1;
+			break;
+		}
+		if ((aa = do_stat(conn, tmp, 0)) == NULL) {
+			xfree(tmp);
+			err = 1;
+			break;
+		}
+		if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
+			error("Can't change directory: Can't check target");
+			xfree(tmp);
+			err = 1;
+			break;
+		}
+		if (!S_ISDIR(aa->perm)) {
+			error("Can't change directory: \"%s\" is not "
+			    "a directory", tmp);
+			xfree(tmp);
+			err = 1;
+			break;
+		}
+		xfree(*pwd);
+		*pwd = tmp;
+		break;
+	case I_LS:
+		if (!path1) {
+			do_ls_dir(conn, *pwd, *pwd, lflag);
+			break;
+		}
+
+		/* Strip pwd off beginning of non-absolute paths */
+		tmp = NULL;
+		if (*path1 != '/')
+			tmp = *pwd;
+
+		path1 = make_absolute(path1, *pwd);
+		err = do_globbed_ls(conn, path1, tmp, lflag);
+		break;
+	case I_DF:
+		/* Default to current directory if no path specified */
+		if (path1 == NULL)
+			path1 = xstrdup(*pwd);
+		path1 = make_absolute(path1, *pwd);
+		err = do_df(conn, path1, hflag, iflag);
+		break;
+	case I_LCHDIR:
+		if (chdir(path1) == -1) {
+			error("Couldn't change local directory to "
+			    "\"%s\": %s", path1, strerror(errno));
+			err = 1;
+		}
+		break;
+	case I_LMKDIR:
+		if (mkdir(path1, 0777) == -1) {
+			error("Couldn't create local directory "
+			    "\"%s\": %s", path1, strerror(errno));
+			err = 1;
+		}
+		break;
+	case I_LLS:
+		local_do_ls(cmd);
+		break;
+	case I_SHELL:
+		local_do_shell(cmd);
+		break;
+	case I_LUMASK:
+		umask(n_arg);
+		printf("Local umask: %03lo\n", n_arg);
+		break;
+	case I_CHMOD:
+		path1 = make_absolute(path1, *pwd);
+		attrib_clear(&a);
+		a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
+		a.perm = n_arg;
+		remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
+			printf("Changing mode on %s\n", g.gl_pathv[i]);
+			err = do_setstat(conn, g.gl_pathv[i], &a);
+			if (err != 0 && err_abort)
+				break;
+		}
+		break;
+	case I_CHOWN:
+	case I_CHGRP:
+		path1 = make_absolute(path1, *pwd);
+		remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
+			if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) {
+				if (err_abort) {
+					err = -1;
+					break;
+				} else
+					continue;
+			}
+			if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
+				error("Can't get current ownership of "
+				    "remote file \"%s\"", g.gl_pathv[i]);
+				if (err_abort) {
+					err = -1;
+					break;
+				} else
+					continue;
+			}
+			aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
+			if (cmdnum == I_CHOWN) {
+				printf("Changing owner on %s\n", g.gl_pathv[i]);
+				aa->uid = n_arg;
+			} else {
+				printf("Changing group on %s\n", g.gl_pathv[i]);
+				aa->gid = n_arg;
+			}
+			err = do_setstat(conn, g.gl_pathv[i], aa);
+			if (err != 0 && err_abort)
+				break;
+		}
+		break;
+	case I_PWD:
+		printf("Remote working directory: %s\n", *pwd);
+		break;
+	case I_LPWD:
+		if (!getcwd(path_buf, sizeof(path_buf))) {
+			error("Couldn't get local cwd: %s", strerror(errno));
+			err = -1;
+			break;
+		}
+		printf("Local working directory: %s\n", path_buf);
+		break;
+#endif
+	case I_QUIT:
+		/* Processed below */
+		break;
+	case I_HELP:
+		help();
+		break;
+	case I_VERSION:
+		printf("SFTP protocol version %u\n", sftp_proto_version(&g_channel->sftp));
+		break;
+#if 0
+	case I_PROGRESS:
+		showprogress = !showprogress;
+		if (showprogress)
+			printf("Progress meter enabled\n");
+		else
+			printf("Progress meter disabled\n");
+		break;
+#endif
+	default:
+		//fatal("%d is not implemented", cmdnum);
+		err = -1;
+	}
+
+#if 0
+	if (g.gl_pathc)
+		globfree(&g);
+	if (path1)
+		xfree(path1);
+	if (path2)
+		xfree(path2);
+
+	/* If an unignored error occurs in batch mode we should abort. */
+	if (err_abort && err != 0)
+		return (-1);
+	else if (cmdnum == I_QUIT)
+		return (1);
+#endif
+
 	return 0L;
 }
 

Modified: trunk/ttssh2/ttxssh/ssh.c
===================================================================
--- trunk/ttssh2/ttxssh/ssh.c	2012-10-13 15:37:56 UTC (rev 5038)
+++ trunk/ttssh2/ttxssh/ssh.c	2012-10-13 16:18:29 UTC (rev 5039)
@@ -209,9 +209,9 @@
 			break;
 
 		if (c->local_num == -1) { // shell or SCP
-			SSH2_send_channel_data(pvar, c, buffer_ptr(ch->msg), size);
+			SSH2_send_channel_data(pvar, c, buffer_ptr(ch->msg), size, TRUE);
 		} else { // port-forwarding
-			SSH_channel_send(pvar, c->local_num, -1, buffer_ptr(ch->msg), size);
+			SSH_channel_send(pvar, c->local_num, -1, buffer_ptr(ch->msg), size, TRUE);
 		}
 
 		c->bufchain = ch->next;
@@ -2982,7 +2982,7 @@
 
 	} else { // for SSH2(yutaka)
 		Channel_t *c = ssh2_channel_lookup(pvar->shell_id);
-		SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen);
+		SSH2_send_channel_data(pvar, c, (unsigned char *)buf, buflen, 0);
 	}
 
 }
@@ -3218,7 +3218,7 @@
 
 }
 
-void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen)
+void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen, int retry)
 {
 	buffer_t *msg;
 	unsigned char *outmsg;
@@ -3237,11 +3237,21 @@
 	if (c == NULL)
 		return;
 
+	// \x83\x8A\x83g\x83\x89\x83C\x82ł͂Ȃ\xA2\x81A\x92ʏ\xED\x82̃p\x83P\x83b\x83g\x91\x97\x90M\x82̍ہA\x88ȑO\x91\x97\x82\xEA\x82Ȃ\xA9\x82\xC1\x82\xBD\x83f\x81[\x83^\x82\xAA
+	// \x83\x8A\x83\x93\x83N\x83h\x83\x8A\x83X\x83g\x82Ɏc\x82\xC1\x82Ă\xA2\x82\xE9\x82悤\x82ł\xA0\x82\xEA\x82΁A\x83\x8A\x83X\x83g\x82̖\x96\x94\xF6\x82Ɍq\x82\xAE\x81B
+	// \x82\xB1\x82\xEA\x82ɂ\xE6\x82\xE8\x83p\x83P\x83b\x83g\x82\xAA\x89\xF3\x82ꂽ\x82悤\x82Ɍ\xA9\x82\xA6\x82錻\x8Fۂ\xAA\x89\xFC\x91P\x82\xB3\x82\xEA\x82\xE9\x81B
+	// (2012.10.14 yutaka)
+	if (retry == 0 && c->bufchain) {
+		ssh2_channel_add_bufchain(c, buf, buflen);
+		return;
+	}
+
 	if ((unsigned int)buflen > c->remote_window) {
-		unsigned int offset = c->remote_window;
+		unsigned int offset = 0;
 		// \x91\x97\x82\xEA\x82Ȃ\xA2\x83f\x81[\x83^\x82͂\xA2\x82\xC1\x82\xBD\x82\xF1\x95ۑ\xB6\x82\xB5\x82Ă\xA8\x82\xAD
 		ssh2_channel_add_bufchain(c, buf + offset, buflen - offset);
 		buflen = offset;
+		return;
 	}
 	if (buflen > 0) {
 		msg = buffer_init();
@@ -3276,7 +3286,7 @@
 /* support for port forwarding */
 void SSH_channel_send(PTInstVar pvar, int channel_num,
                       uint32 remote_channel_num,
-                      unsigned char FAR * buf, int len)
+                      unsigned char FAR * buf, int len, int retry)
 {
 	if (SSHv1(pvar)) {
 		unsigned char FAR *outmsg =
@@ -3323,7 +3333,7 @@
 	} else {
 		// \x83|\x81[\x83g\x83t\x83H\x83\x8F\x81[\x83f\x83B\x83\x93\x83O\x82ɂ\xA8\x82\xA2\x82ăN\x83\x89\x83C\x83A\x83\x93\x83g\x82\xA9\x82\xE7\x82̑\x97\x90M\x97v\x8B\x81\x82\xF0\x81ASSH\x92ʐM\x82ɏ悹\x82ăT\x81[\x83o\x82܂ő\x97\x82\xE8\x93͂\xAF\x82\xE9\x81B
 		Channel_t *c = ssh2_local_channel_lookup(channel_num);
-		SSH2_send_channel_data(pvar, c, buf, len);
+		SSH2_send_channel_data(pvar, c, buf, len, retry);
 	}
 
 }
@@ -7280,7 +7290,7 @@
 		// (2007.12.27 yutaka)
 		if (c->scp.dir == FROMREMOTE) {
 			char ch = '\0';
-			SSH2_send_channel_data(pvar, c, &ch, 1);
+			SSH2_send_channel_data(pvar, c, &ch, 1, 0);
 		}
 
 	} else if (c->type == TYPE_SFTP) {
@@ -7581,7 +7591,7 @@
 			{
 			scp_dlg_parm_t *parm = (scp_dlg_parm_t *)wp;
 
-			SSH2_send_channel_data(parm->pvar, parm->c, parm->buf, parm->buflen);
+			SSH2_send_channel_data(parm->pvar, parm->c, parm->buf, parm->buflen, 0);
 			}
 			return TRUE;
 			break;
@@ -7787,7 +7797,7 @@
 			(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));
+		SSH2_send_channel_data(pvar, c, buf, strlen(buf), 0);
 
 	} else if (c->scp.state == SCP_TIMESTAMP) {
 		char buf[128];
@@ -7796,7 +7806,7 @@
 			c->scp.filestat.st_size, c->scp.localfile);
 
 		c->scp.state = SCP_FILEINFO;
-		SSH2_send_channel_data(pvar, c, buf, strlen(buf));
+		SSH2_send_channel_data(pvar, c, buf, strlen(buf), 0);
 
 	} else if (c->scp.state == SCP_FILEINFO) {
 		HWND hDlgWnd;
@@ -8017,7 +8027,7 @@
 
 reply:
 	ch = '\0';
-	SSH2_send_channel_data(pvar, c, &ch, 1);
+	SSH2_send_channel_data(pvar, c, &ch, 1, 0);
 	return TRUE;
 }
 
@@ -8657,11 +8667,11 @@
 	}
 
 	if (SSHv2(pvar)) {
-		SSH2_send_channel_data(pvar, c, response, resplen);
+		SSH2_send_channel_data(pvar, c, response, resplen, 0);
 	}
 	else {
 		SSH_channel_send(pvar, local_channel_num, fc->remote_num,
-		                 response, resplen);
+		                 response, resplen, 0);
 	}
 	safefree(response);
 

Modified: trunk/ttssh2/ttxssh/ssh.h
===================================================================
--- trunk/ttssh2/ttxssh/ssh.h	2012-10-13 15:37:56 UTC (rev 5038)
+++ trunk/ttssh2/ttxssh/ssh.h	2012-10-13 16:18:29 UTC (rev 5039)
@@ -572,7 +572,7 @@
 /* len must be <= SSH_MAX_SEND_PACKET_SIZE */
 void SSH_channel_send(PTInstVar pvar, int channel_num,
                       uint32 remote_channel_num,
-                      unsigned char FAR * buf, int len);
+                      unsigned char FAR * buf, int len, int retry);
 void SSH_fail_channel_open(PTInstVar pvar, uint32 remote_channel_num);
 void SSH_confirm_channel_open(PTInstVar pvar, uint32 remote_channel_num, uint32 local_channel_num);
 void SSH_channel_output_eof(PTInstVar pvar, uint32 remote_channel_num);
@@ -701,7 +701,7 @@
 
 unsigned char FAR *begin_send_packet(PTInstVar pvar, int type, int len);
 void finish_send_packet_special(PTInstVar pvar, int skip_compress);
-void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen);
+void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char FAR * buf, unsigned int buflen, int retry);
 
 #define finish_send_packet(pvar) finish_send_packet_special((pvar), 0)
 #define get_payload_uint32(pvar, offset) get_uint32_MSBfirst((pvar)->ssh_state.payload + (offset))



Ttssh2-commit メーリングリストの案内
Back to archive index