[Ttssh2-commit] [4929] SFTP: 最初のネゴシエーションまで完了。

svnno****@sourc***** svnno****@sourc*****
2012年 5月 4日 (金) 01:17:09 JST


Revision: 4929
          http://sourceforge.jp/projects/ttssh2/svn/view?view=rev&revision=4929
Author:   yutakapon
Date:     2012-05-04 01:17:09 +0900 (Fri, 04 May 2012)
Log Message:
-----------
SFTP: 最初のネゴシエーションまで完了。

Modified Paths:
--------------
    trunk/ttssh2/ttxssh/buffer.c
    trunk/ttssh2/ttxssh/buffer.h
    trunk/ttssh2/ttxssh/sftp.c
    trunk/ttssh2/ttxssh/sftp.h
    trunk/ttssh2/ttxssh/ssh.h

-------------- next part --------------
Modified: trunk/ttssh2/ttxssh/buffer.c
===================================================================
--- trunk/ttssh2/ttxssh/buffer.c	2012-05-03 14:39:47 UTC (rev 4928)
+++ trunk/ttssh2/ttxssh/buffer.c	2012-05-03 16:17:09 UTC (rev 4929)
@@ -151,28 +151,28 @@
 	ret = buffer_append(msg, ptr, size);
 }
 
-int buffer_get_ret(buffer_t *msg, void *buf, int len)
-{
-	if (len > msg->len - msg->offset) {
-		// TODO: \x83G\x83\x89\x81[\x8F\x88\x97\x9D
-		OutputDebugPrintf("buffer_get_ret: trying to get more bytes %d than in buffer %d",
-		    len, msg->len - msg->offset);
-		return (-1);
-	}
-	memcpy(buf, msg->buf + msg->offset, len);
-	msg->offset += len;
-	return (0);
+int buffer_get_ret(buffer_t *msg, void *buf, int len)
+{
+	if (len > msg->len - msg->offset) {
+		// TODO: \x83G\x83\x89\x81[\x8F\x88\x97\x9D
+		OutputDebugPrintf("buffer_get_ret: trying to get more bytes %d than in buffer %d",
+		    len, msg->len - msg->offset);
+		return (-1);
+	}
+	memcpy(buf, msg->buf + msg->offset, len);
+	msg->offset += len;
+	return (0);
 }
 
-int buffer_get_int_ret(int *ret, buffer_t *msg)
-{
-	unsigned char buf[4];
-
-	if (buffer_get_ret(msg, (char *) buf, 4) == -1)
-		return (-1);
-	if (ret != NULL)
-		*ret = get_uint32(buf);
-	return (0);
+int buffer_get_int_ret(int *ret, buffer_t *msg)
+{
+	unsigned char buf[4];
+
+	if (buffer_get_ret(msg, (char *) buf, 4) == -1)
+		return (-1);
+	if (ret != NULL)
+		*ret = get_uint32(buf);
+	return (0);
 }
 
 int buffer_get_int(buffer_t *msg)
@@ -186,11 +186,11 @@
 	return (ret);
 }
 
-int buffer_get_char_ret(char *ret, buffer_t *msg)
-{
-	if (buffer_get_ret(msg, ret, 1) == -1)
-		return (-1);
-	return (0);
+int buffer_get_char_ret(char *ret, buffer_t *msg)
+{
+	if (buffer_get_ret(msg, ret, 1) == -1)
+		return (-1);
+	return (0);
 }
 
 int buffer_get_char(buffer_t *msg)
@@ -236,6 +236,21 @@
 	return(ptr);
 }
 
+// buffer_get_string() \x82\xCC buffer_t \x94ŁB\x96{\x97\x88\x82͂\xB1\x82\xBF\x82炪 OpenSSH \x83X\x83^\x83C\x83\x8B\x81B
+// NOTE: You should free the return pointer if it's unused.
+void *buffer_get_string_msg(buffer_t *msg, int *buflen_ptr)
+{
+	char *data, *olddata;
+	void *ret;
+	int off;
+
+	data = olddata = buffer_tail_ptr(msg);
+	ret = buffer_get_string(&data, buflen_ptr);
+	off = data - olddata;
+	msg->offset += off;
+	return (ret);
+}
+
 void buffer_put_string(buffer_t *msg, char *ptr, int size)
 {
 	char buf[4];
@@ -281,6 +296,12 @@
 	return (msg->len);
 }
 
+// \x82܂\xBE\x93ǂݍ\x9E\x82\xF1\x82ł\xA2\x82Ȃ\xA2\x8Ec\x82\xE8\x82̃T\x83C\x83Y\x82\xF0\x95Ԃ\xB7\x81B\x96{\x97\x88\x82͂\xB1\x82\xBF\x82炪 OpenSSH \x83X\x83^\x83C\x83\x8B\x81B
+int buffer_remain_len(buffer_t *msg)
+{
+	return (msg->len - msg->offset);
+}
+
 // buffer_append() \x82\xE2 buffer_append_space() \x82Ń\x81\x83b\x83Z\x81[\x83W\x83o\x83b\x83t\x83@\x82ɒlj\xC1\x82\xF0\x8Ds\x82\xA4\x82ƁA
 // \x93\xE0\x95\x94\x82\xC5 realloc() \x82ɂ\xE6\x82\xE8\x83o\x83b\x83t\x83@\x83|\x83C\x83\x93\x83^\x82\xAA\x95ς\xED\x82\xC1\x82Ă\xB5\x82܂\xA4\x82\xB1\x82Ƃ\xAA\x82\xA0\x82\xE9\x81B
 // \x83\x81\x83b\x83Z\x81[\x83W\x83o\x83b\x83t\x83@\x82̃|\x83C\x83\x93\x83^\x82\xF0\x8E擾\x82\xB7\x82\xE9\x8Dۂ́A\x83o\x83b\x83t\x83@\x92lj\xC1\x82\xAA\x8A\xAE\x97\xB9\x82\xB5\x82\xBD\x8C\xE3\x82\xC9

Modified: trunk/ttssh2/ttxssh/buffer.h
===================================================================
--- trunk/ttssh2/ttxssh/buffer.h	2012-05-03 14:39:47 UTC (rev 4928)
+++ trunk/ttssh2/ttxssh/buffer.h	2012-05-03 16:17:09 UTC (rev 4929)
@@ -36,11 +36,13 @@
 void buffer_consume(buffer_t *buf, int shift_byte);
 int buffer_compress(z_stream *zstream, char *payload, int len, buffer_t *compbuf);
 int buffer_decompress(z_stream *zstream, char *payload, int len, buffer_t *compbuf);
-int buffer_get_ret(buffer_t *msg, void *buf, int len);
-int buffer_get_int_ret(int *ret, buffer_t *msg);
+int buffer_get_ret(buffer_t *msg, void *buf, int len);
+int buffer_get_int_ret(int *ret, buffer_t *msg);
 int buffer_get_int(buffer_t *msg);
-int buffer_get_char_ret(char *ret, buffer_t *msg);
+int buffer_get_char_ret(char *ret, buffer_t *msg);
 int buffer_get_char(buffer_t *msg);
 void buffer_rewind(buffer_t *buf);
+void *buffer_get_string_msg(buffer_t *msg, int *buflen_ptr);
+int buffer_remain_len(buffer_t *msg);
 
 #endif				/* BUFFER_H */

Modified: trunk/ttssh2/ttxssh/sftp.c
===================================================================
--- trunk/ttssh2/ttxssh/sftp.c	2012-05-03 14:39:47 UTC (rev 4928)
+++ trunk/ttssh2/ttxssh/sftp.c	2012-05-03 16:17:09 UTC (rev 4929)
@@ -76,6 +76,13 @@
 }
 
 // SFTP\x90\xEA\x97p\x83o\x83b\x83t\x83@\x82\xF0\x8Am\x95ۂ\xB7\x82\xE9\x81BSCP\x82Ƃ͈قȂ\xE8\x81A\x90擪\x82Ɍ㑱\x82̃f\x81[\x83^\x83T\x83C\x83Y\x82𖄂ߍ\x9E\x82ށB
+//
+// buffer_t
+//    +---------+------------------------------------+
+//    | msg_len | data                               |  
+//    +---------+------------------------------------+
+//       4byte   <------------- msg_len ------------->
+//
 static void sftp_buffer_alloc(buffer_t **message)
 {
 	buffer_t *msg;
@@ -113,6 +120,7 @@
 	SSH2_send_channel_data(pvar, c, p, len);
 }
 
+// \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
 static void sftp_get_msg(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen, buffer_t **message)
 {
 	buffer_t *msg = *message;
@@ -127,12 +135,12 @@
 	msg_len = buffer_get_int(msg);
 	if (msg_len > SFTP_MAX_MSG_LENGTH) {
 		// TODO:
-		OutputDebugPrintf("Received message too long %u", msg_len);
+		sftp_syslog(pvar, "Received message too long %u", msg_len);
 		goto error;
 	}
 	if (msg_len + 4 != buflen) {
 		// TODO:
-		OutputDebugPrintf("Buffer length %u is invalid", buflen);
+		sftp_syslog(pvar, "Buffer length %u is invalid", buflen);
 		goto error;
 	}
 
@@ -146,8 +154,15 @@
 {
 	buffer_t *msg;
 
+	// SFTP\x8AǗ\x9D\x8D\\x91\xA2\x91̂̏\x89\x8A\xFA\x89\xBB
+	memset(&c->sftp, 0, sizeof(c->sftp));
 	c->sftp.state = SFTP_INIT;
+	c->sftp.transfer_buflen = DEFAULT_COPY_BUFLEN;
+	c->sftp.num_requests = DEFAULT_NUM_REQUESTS;
+	c->sftp.exts = 0;
+	c->sftp.limit_kbps = 0;
 
+	// \x83l\x83S\x83V\x83G\x81[\x83V\x83\x87\x83\x93\x82̊J\x8En
 	sftp_buffer_alloc(&msg);
 	buffer_put_char(msg, SSH2_FXP_INIT); 
 	buffer_put_int(msg, SSH2_FILEXFER_VERSION);
@@ -157,7 +172,7 @@
 	sftp_syslog(pvar, "SFTP client version %u", SSH2_FILEXFER_VERSION);
 }
 
-static void sftp_do_init_recv(PTInstVar pvar, buffer_t *msg)
+static void sftp_do_init_recv(PTInstVar pvar, Channel_t *c, buffer_t *msg)
 {
 	unsigned int type;
 
@@ -165,8 +180,50 @@
 	if (type != SSH2_FXP_VERSION) {
 		goto error;
 	}
-	sftp_syslog(pvar, "SFTP server version %u", type);
+	c->sftp.version = buffer_get_int(msg);
+	sftp_syslog(pvar, "SFTP server version %u, remote version %u", type, c->sftp.version);
 
+	while (buffer_remain_len(msg) > 0) {
+		char *name = buffer_get_string_msg(msg, NULL);
+		char *value = buffer_get_string_msg(msg, NULL);
+		int known = 0;
+
+        if (strcmp(name, "posix****@opens*****") == 0 &&
+            strcmp(value, "1") == 0) {
+            c->sftp.exts |= SFTP_EXT_POSIX_RENAME;
+            known = 1;
+        } else if (strcmp(name, "statv****@opens*****") == 0 &&
+            strcmp(value, "2") == 0) {
+            c->sftp.exts |= SFTP_EXT_STATVFS;
+            known = 1;
+        } else if (strcmp(name, "fstat****@opens*****") == 0 &&
+            strcmp(value, "2") == 0) {
+            c->sftp.exts |= SFTP_EXT_FSTATVFS;
+            known = 1;
+        } else if (strcmp(name, "hardl****@opens*****") == 0 &&
+            strcmp(value, "1") == 0) {
+            c->sftp.exts |= SFTP_EXT_HARDLINK;
+            known = 1;
+        }
+        if (known) {
+            sftp_syslog(pvar, "Server supports extension \"%s\" revision %s",
+                name, value);
+        } else {
+            sftp_syslog(pvar, "Unrecognised server extension \"%s\"", name);
+        }
+
+		free(name);
+		free(value);
+	}
+
+	if (c->sftp.version == 0) {
+		c->sftp.transfer_buflen = min(c->sftp.transfer_buflen, 20480);
+	}
+	c->sftp.limit_kbps = 0;
+	if (c->sftp.limit_kbps > 0) {
+		// TODO:
+	}
+
 error:
 	return;
 }
@@ -177,8 +234,6 @@
 	buffer_t *msg;
 	int state;
 
-	OutputDebugPrintf("len %d\n", buflen);
-
 	/*
 	 * Allocate buffer
 	 */
@@ -187,7 +242,8 @@
 
 	state = c->sftp.state;
 	if (state == SFTP_INIT) {
-		sftp_do_init_recv(pvar, msg);
+		sftp_do_init_recv(pvar, c, msg);
+		sftp_syslog(pvar, "Connected to SFTP server.");
 	}
 
 	/*

Modified: trunk/ttssh2/ttxssh/sftp.h
===================================================================
--- trunk/ttssh2/ttxssh/sftp.h	2012-05-03 14:39:47 UTC (rev 4928)
+++ trunk/ttssh2/ttxssh/sftp.h	2012-05-03 16:17:09 UTC (rev 4929)
@@ -99,9 +99,12 @@
 #define SSH2_FX_OP_UNSUPPORTED		8
 #define SSH2_FX_MAX			8
 
-/* Maximum packet that we are willing to send/accept */
-#define SFTP_MAX_MSG_LENGTH	(256 * 1024)
+/* Maximum packet that we are willing to send/accept */
+#define SFTP_MAX_MSG_LENGTH	(256 * 1024)
 
+#define DEFAULT_COPY_BUFLEN 32768   /* Size of buffer for up/download */
+#define DEFAULT_NUM_REQUESTS    64  /* # concurrent outstanding requests */
+
 void sftp_do_init(PTInstVar pvar, Channel_t *c);
 void sftp_response(PTInstVar pvar, Channel_t *c, unsigned char *data, unsigned int buflen);
 

Modified: trunk/ttssh2/ttxssh/ssh.h
===================================================================
--- trunk/ttssh2/ttxssh/ssh.h	2012-05-03 14:39:47 UTC (rev 4928)
+++ trunk/ttssh2/ttxssh/ssh.h	2012-05-03 16:17:09 UTC (rev 4929)
@@ -664,6 +664,17 @@
 
 typedef struct sftp {
 	enum sftp_state state;
+	unsigned int transfer_buflen;
+	unsigned int num_requests;
+	unsigned int version;
+	unsigned int msg_id;
+#define SFTP_EXT_POSIX_RENAME   0x00000001
+#define SFTP_EXT_STATVFS    0x00000002
+#define SFTP_EXT_FSTATVFS   0x00000004
+#define SFTP_EXT_HARDLINK   0x00000008
+	unsigned int exts;
+	unsigned long long limit_kbps;
+	//struct bwlimit bwlimit_in, bwlimit_out;
 } sftp_t;
 
 typedef struct channel {



Ttssh2-commit メーリングリストの案内