[Ttssh2-commit] [5771] mlukoshkov のパッチを改良して取り込んだ

svnno****@sourc***** svnno****@sourc*****
2015年 1月 31日 (土) 22:47:27 JST


Revision: 5771
          http://sourceforge.jp/projects/ttssh2/scm/svn/commits/5771
Author:   maya
Date:     2015-01-31 22:47:26 +0900 (Sat, 31 Jan 2015)
Log Message:
-----------
mlukoshkov のパッチを改良して取り込んだ
  https://sourceforge.jp/ticket/browse.php?tid=34623&group_id=1412
  最初のパケットサイズは 128 バイトに固定せず、ファイル名の長さにより 1024 バイトになる
キャンセルを正しく処理するようにした
  https://sourceforge.jp/ticket/browse.php?group_id=1412&tid=34667 4番目

Modified Paths:
--------------
    trunk/teraterm/common/ttftypes.h
    trunk/teraterm/ttpfile/ymodem.c

-------------- next part --------------
Modified: trunk/teraterm/common/ttftypes.h
===================================================================
--- trunk/teraterm/common/ttftypes.h	2015-01-30 08:18:25 UTC (rev 5770)
+++ trunk/teraterm/common/ttftypes.h	2015-01-31 13:47:26 UTC (rev 5771)
@@ -208,13 +208,15 @@
   WORD YMode, YOpt, TextFlag;
   WORD NAKMode;
   int NAKCount;
-  WORD DataLen, CheckLen;
+  WORD __DataLen, CheckLen;
   BOOL CRRecv;
   int TOutShort;
   int TOutLong;
   int SendFileInfo;
   int SendEot;
   int LastSendEot;
+  WORD DataLen;
+  BYTE LastMessage;
 } TYVar;
 typedef TYVar far *PYVar;
 

Modified: trunk/teraterm/ttpfile/ymodem.c
===================================================================
--- trunk/teraterm/ttpfile/ymodem.c	2015-01-30 08:18:25 UTC (rev 5770)
+++ trunk/teraterm/ttpfile/ymodem.c	2015-01-31 13:47:26 UTC (rev 5771)
@@ -3,13 +3,15 @@
 All rights reserved. */
 
 /* TTFILE.DLL, YMODEM protocol */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <stdio.h>
+#include <time.h>
+
 #include "teraterm.h"
 #include "tttypes.h"
 #include "ttftypes.h"
-#include <stdio.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 
 #include "tt_res.h"
 #include "ttcommon.h"
@@ -87,17 +89,20 @@
 	switch (yv->YOpt) {
 	case Yopt1K: /* YMODEM */
 		strncat_s(Tmp,sizeof(Tmp),"1k)",_TRUNCATE);
-		yv->DataLen = 1024;
+		yv->__DataLen = STX_DATALEN;
+		yv->DataLen = STX_DATALEN;
 		yv->CheckLen = 2;
 		break;
 	case YoptG: /* YMODEM-g */
 		strncat_s(Tmp,sizeof(Tmp),"-g)",_TRUNCATE);
-		yv->DataLen = 1024;
+		yv->__DataLen = STX_DATALEN;
+		yv->DataLen = STX_DATALEN;
 		yv->CheckLen = 2;
 		break;
 	case YoptSingle: /* YMODEM(-g) single mode */
 		strncat_s(Tmp,sizeof(Tmp),"single mode)",_TRUNCATE);
-		yv->DataLen = 1024;
+		yv->__DataLen = STX_DATALEN;
+		yv->DataLen = STX_DATALEN;
 		yv->CheckLen = 2;
 		break;
 	}
@@ -187,7 +192,7 @@
 	FTSetTimeOut(fv,t);
 }
 
-WORD YCalcCheck(PYVar yv, PCHAR PktBuf)
+WORD YCalcCheck(PYVar yv, const PCHAR PktBuf, const WORD len)
 {
 	int i;
 	WORD Check;
@@ -197,7 +202,7 @@
 	{
 		// Calc sum.
 		Check = 0;
-		for (i = 0 ; i <= yv->DataLen-1 ; i++)
+		for (i = 0 ; i <= len - 1 ; i++)
 			Check = Check + (BYTE)(PktBuf[3 + i]);
 		return (Check & 0xff);
 	}
@@ -205,23 +210,23 @@
 	{
 		// CRC.
 		Check = 0;
-		for (i = 0 ; i <= yv->DataLen-1 ; i++)
+		for (i = 0 ; i <= len - 1 ; i++)
 			Check = UpdateCRC(PktBuf[3 + i],Check);
 		return (Check);
 	}
 }
 
-BOOL YCheckPacket(PYVar yv)
+BOOL YCheckPacket(PYVar yv, const WORD len)
 {
 	WORD Check;
 
-	Check = YCalcCheck(yv, yv->PktIn);
+	Check = YCalcCheck(yv, yv->PktIn, len);
 	// Checksum.
 	if (1 == yv->CheckLen)
-		return ((BYTE)Check == yv->PktIn[yv->DataLen + 3]);
+		return ((BYTE)Check == yv->PktIn[len + 3]);
 	else
-		return ((HIBYTE(Check) == yv->PktIn[yv->DataLen + 3]) &&
-		        (LOBYTE(Check) == yv->PktIn[yv->DataLen + 4]));  
+		return ((HIBYTE(Check) == yv->PktIn[len + 3]) &&
+		        (LOBYTE(Check) == yv->PktIn[len + 4]));
 }
 
 static void initialize_file_info(PFileVar fv, PYVar yv)
@@ -260,6 +265,7 @@
 	yv->SendFileInfo = 0;
 	yv->SendEot = 0;
 	yv->LastSendEot = 0;
+	yv->LastMessage = 0;
 }
 
 void YInit
@@ -396,14 +402,14 @@
 			{
 				yv->PktIn[0] = b;
 				yv->PktReadMode = XpktBLK;
-				yv->DataLen = SOH_DATALEN;
+				yv->__DataLen = SOH_DATALEN;
 				FTSetTimeOut(fv,yv->TOutShort);
 			}
 			else if (b==STX)
 			{
 				yv->PktIn[0] = b;
 				yv->PktReadMode = XpktBLK;
-				yv->DataLen = STX_DATALEN;
+				yv->__DataLen = STX_DATALEN;
 				FTSetTimeOut(fv,yv->TOutShort);
 			}
 			else if (b==EOT)
@@ -461,7 +467,7 @@
 			if (nak == 0)
 			{
 				yv->PktBufPtr = 3;
-				yv->PktBufCount = yv->DataLen + yv->CheckLen;
+				yv->PktBufCount = yv->__DataLen + yv->CheckLen;
 				yv->PktReadMode = XpktDATA;
 				FTSetTimeOut(fv,yv->TOutShort);
 			}
@@ -488,7 +494,7 @@
 
 	if (! GetPkt) return TRUE;
 
-	GetPkt = YCheckPacket(yv);
+	GetPkt = YCheckPacket(yv, yv->__DataLen);
 	if (! GetPkt)
 	{
 		YSendNAK(fv,yv,cv);
@@ -499,7 +505,7 @@
 	if (yv->PktIn[1] == 0x00 && yv->PktIn[2] == 0xFF &&
 		yv->SendFileInfo == 0
 		) {
-		c = yv->DataLen;
+		c = yv->__DataLen;
 		while ((c>0) && (yv->PktIn[2+c]==0x00))
 			c--;
 		if (c == 0) {
@@ -541,9 +547,9 @@
 		BYTE *p;
 		char *name, *nameend;
 
-		p = (BYTE *)malloc(yv->DataLen + 1);
-		memset(p, 0, yv->DataLen + 1);
-		memcpy(p, &(yv->PktIn[3]), yv->DataLen);
+		p = (BYTE *)malloc(yv->__DataLen + 1);
+		memset(p, 0, yv->__DataLen + 1);
+		memcpy(p, &(yv->PktIn[3]), yv->__DataLen);
 		name = p;
 		strncpy_s(&(fv->FullName[fv->DirLen]),
 		          sizeof(fv->FullName) - fv->DirLen, name,
@@ -577,7 +583,7 @@
 	if (yv->PktNum==0)
 		yv->PktNumOffset = yv->PktNumOffset + 256;
 
-	c = yv->DataLen;
+	c = yv->__DataLen;
 	if (yv->TextFlag>0)
 		while ((c>0) && (yv->PktIn[2+c]==0x1A))
 			c--;
@@ -615,24 +621,19 @@
 // \x83t\x83@\x83C\x83\x8B\x91\x97\x90M(local-to-remote)\x8E\x9E\x82ɁAYMODEM\x83T\x81[\x83o\x82\xA9\x82\xE7\x83f\x81[\x83^\x82\xAA\x91\x97\x82\xE7\x82\xEA\x82Ă\xAB\x82\xBD\x82Ƃ\xAB\x82ɌĂяo\x82\xB3\x82\xEA\x82\xE9\x81B
 BOOL YSendPacket(PFileVar fv, PYVar yv, PComVar cv)
 {
-	BYTE b;
-	int i;
-	BOOL SendFlag;
-	WORD Check;
-	BYTE firstch, lastrx;
-
-	SendFlag = FALSE;
+	// If current buffer is empty.
 	if (0 == yv->PktBufCount)
 	{
 		// Main read loop.
-		i = YRead1Byte(fv,yv,cv,&b);
-		do
+		BOOL continue_read = TRUE;
+		while (continue_read)
 		{
-			if (i==0) return TRUE;
-			firstch = b;
+			BYTE isym = 0;
+			int is_success = YRead1Byte(fv, yv, cv, &isym);
+			if (0 == is_success) return TRUE;
 
 			// Analyze responce.
-			switch (b)
+			switch (isym)
 			{
 			case ACK:
 				// 1\x89\xF1\x96ڂ\xCCEOT\x91\x97\x90M\x8C\xE3\x82\xCCACK\x8E\xF3\x90M\x82ŁA\x81u1\x83t\x83@\x83C\x83\x8B\x91\x97\x90M\x81v\x82̏I\x82\xED\x82\xE8\x82Ƃ\xB7\x82\xE9\x81B
@@ -661,6 +662,7 @@
 				if (!fv->FileOpen)
 				{
 					fv->Success = TRUE;
+					yv->LastMessage = isym;
 					return FALSE;
 				}
 				// \x8E\x9F\x82̃u\x83\x8D\x83b\x83N\x82𑗂\xE9
@@ -673,13 +675,13 @@
 						// It is an ACK for file info, wait for 'C' by some reason (?).
 						// \x91\x97\x90M\x8Dς݃t\x83\x89\x83Oon
 						yv->SendFileInfo = 1;
-						SendFlag = FALSE;
+						continue_read = TRUE;
 						break;
 					}
 					yv->PktNum = yv->PktNumSent;
 					if (0 == yv->PktNum)
 						yv->PktNumOffset = yv->PktNumOffset + 256;
-					SendFlag = TRUE;
+					continue_read = FALSE;
 				}
 				break;
 
@@ -692,14 +694,19 @@
 						yv->PktNumOffset = yv->PktNumOffset + 256;
 				}
 
-				SendFlag = TRUE;
+				continue_read = FALSE;
 				break;
 
 			case CAN:
+				// \x92\xBC\x91O\x82\xE0 CAN \x82̏ꍇ\x82̓L\x83\x83\x83\x93\x83Z\x83\x8B
+				if (yv->LastMessage == CAN) {
+					fv->Success = FALSE;       // failure
+					return FALSE;
+				}
 				break;
 
-			case 0x43:  // 'C'(43h)
-			case 0x47:  // 'G'(47h)
+			case 'C':
+			case 'G':
 				// 'C'\x82\xF0\x8E󂯎\xE6\x82\xE9\x82ƁA\x83u\x83\x8D\x83b\x83N\x82̑\x97\x90M\x82\xF0\x8AJ\x8En\x82\xB7\x82\xE9\x81B
 				if ((0 == yv->PktNum) && (0 == yv->PktNumOffset))
 				{
@@ -711,20 +718,28 @@
 							yv->PktNumOffset = yv->PktNumOffset + 256;
 					}
 
-					SendFlag = TRUE;
+					continue_read = FALSE;
 				}
 				else if (yv->LastSendEot)
 				{
-					SendFlag = TRUE;
+					continue_read = FALSE;
 				}
+				else
+				{
+					// TODO: analyze else branch.
+				}
 				break;
+
+			default:
+				assert(0);
+				break;
 			}
-			if (! SendFlag) i = YRead1Byte(fv,yv,cv,&b);
-		} while (!SendFlag);
+			yv->LastMessage = isym;
+		}
 
 		// reset timeout timer
 		FTSetTimeOut(fv, TimeOutVeryLong);
-
+#if 0
 		// \x8C㑱\x82̃T\x81[\x83o\x82\xA9\x82\xE7\x82̃f\x81[\x83^\x82\xF0\x93ǂݎ̂Ă\xE9\x81B
 		do
 		{
@@ -741,6 +756,7 @@
 				}
 			}
 		} while (i != 0);
+#endif
 
 		//================================
 		// Last packet case.
@@ -748,34 +764,40 @@
 		// \x83I\x81[\x83\x8B\x83[\x83\x8D\x82̃u\x83\x8D\x83b\x83N\x82𑗐M\x82\xB5\x82āA\x82\xE0\x82\xA4\x83t\x83@\x83C\x83\x8B\x82\xAA\x82Ȃ\xA2\x82\xB1\x82Ƃ\xF0\x92m\x82点\x82\xE9\x81B
 		if (yv->LastSendEot)
 		{
+			WORD Check;
+			// Always 128 bytes for the last packet.
+			WORD last_packet_size = SOH_DATALEN;
+			int i;
+
 			// Clear the flag.
 			yv->LastSendEot = 0;
 
-			yv->DataLen = SOH_DATALEN;
+			yv->__DataLen = last_packet_size;
 			yv->PktOut[0] = SOH;
 			yv->PktOut[1] = 0;
 			yv->PktOut[2] = ~0;
 
 			i = 0;
-			while (i < yv->DataLen)
+			while (i < last_packet_size)
 			{
 				yv->PktOut[i+3] = 0x00;
 				i++;
 			}
 
-			Check = YCalcCheck(yv, yv->PktOut);
+			Check = YCalcCheck(yv, yv->PktOut, last_packet_size);
+			// TODO: move checksum calculation to a function.
 			if (1 == yv->CheckLen)
 			{
-				yv->PktOut[yv->DataLen + 3] = (BYTE)Check;
+				yv->PktOut[last_packet_size + 3] = (BYTE)Check;
 			}
 			else
 			{
-				yv->PktOut[yv->DataLen + 3] = HIBYTE(Check);
-				yv->PktOut[yv->DataLen + 4] = LOBYTE(Check);
+				yv->PktOut[last_packet_size + 3] = HIBYTE(Check);
+				yv->PktOut[last_packet_size + 4] = LOBYTE(Check);
 			}
 
-			yv->PktBufCount = 3 + yv->DataLen + yv->CheckLen;
-			//fv->Success = TRUE;
+			// TODO: remove magic number.
+			yv->PktBufCount = 3 + last_packet_size + yv->CheckLen;
 		}
 
 		//================================
@@ -788,8 +810,9 @@
 			 /* make a new packet */
 			BYTE *dataptr = &yv->PktOut[3];
 			int eot = 0;  // End Of Transfer
+			WORD current_packet_size = yv->DataLen;
 
-			if (SOH_DATALEN == yv->DataLen)
+			if (SOH_DATALEN == current_packet_size)
 				yv->PktOut[0] = SOH;
 			else
 				yv->PktOut[0] = STX;
@@ -807,12 +830,14 @@
 			if (yv->SendFileInfo == 0)
 			{
 				int ret, total;
+				size_t idx;
+				// TODO: remove magic number.
 				BYTE buf[1024 + 10];
 
-				// ACK \x82\xF0\x8E󂯂Ă\xA9\x82\xE7\x83t\x83\x89\x83O\x82\xF0on\x82Ƃ\xB7\x82\xE9\x81B\x82\xBB\x82\xA4\x82\xB5\x82Ȃ\xA2\x82ƁAACK\x82\xF0\x8E󂯂\xB8\x82ɁA'C'\x82̂\xDD
-				// \x8E󂯎\xE6\x82\xC1\x82\xBD\x82Ƃ\xB5\x82Ă\xE0\x81A\x83u\x83\x8D\x83b\x83N1\x82̑\x97\x90M\x82\xF0\x8En\x82߂Ă\xB5\x82܂\xA4\x81B
-				// (2011.3.21 yutaka)
-				//yv->SendFileInfo = 1;   // \x91\x97\x90M\x8Dς݃t\x83\x89\x83Oon
+				// 128 bytes for the first packet.
+				current_packet_size = SOH_DATALEN;
+				yv->__DataLen = current_packet_size;
+				yv->PktOut[0] = SOH;
 
 				// Timestamp.
 				fv->FileMtime = GetFMtime(fv->FullName);
@@ -827,17 +852,23 @@
 				                  fv->FileSize, fv->FileMtime, 0644|_S_IFREG);
 				total += ret;
 
+				// if bloack0 is long, expand to 1024 bytes.
+				if (total > SOH_DATALEN) {
+					current_packet_size = STX_DATALEN;
+					yv->__DataLen = current_packet_size;
+					yv->PktOut[0] = STX;
+				}
+
 				// Padding.
-				i = total;
-				while (i <= yv->DataLen)
+				idx = total;
+				while (idx <= current_packet_size)
 				{
-					buf[i] = 0x00;
-					i++;
+					buf[idx] = 0x00;
+					++idx;
 				}
 
 				// \x83f\x81[\x83^\x83R\x83s\x81[
-				memcpy(dataptr, buf, yv->DataLen);
-
+				memcpy(dataptr, buf, current_packet_size);
 			}
 
 			//================================
@@ -846,26 +877,24 @@
 
 			else
 			{
-				i = 1;
-				while ((i<=yv->DataLen) && fv->FileOpen &&
-				       (1 == _lread(fv->FileHandle, &b, 1)))
+				BYTE fsym = 0;
+				size_t idx = 1;
+
+				yv->__DataLen = current_packet_size;
+
+				while ((idx <= current_packet_size) && fv->FileOpen &&
+				       (1 == _lread(fv->FileHandle, &fsym, 1)))
 				{
-					yv->PktOut[2+i] = b;
-					i++;
+					// TODO: remove magic number.
+					yv->PktOut[2 + idx] = fsym;
+					++idx;
 					fv->ByteCount++;
 				}
 
-
-				if (i>1)
+				// No bytes were read.
+				if (1 == idx)
 				{
-					while (i<=yv->DataLen)
-					{
-						yv->PktOut[2+i] = 0x1A;
-						i++;
-					}
-
-				}
-				else { /* send EOT */
+					// Close file handle.
 					if (fv->FileOpen)
 					{
 						_lclose(fv->FileHandle);
@@ -873,24 +902,35 @@
 						fv->FileOpen = FALSE;
 					}
 
+					// Send EOT.
 					eot = 1;
 				}
-
+				else
+				{
+					// Padding.
+					while (idx <= current_packet_size)
+					{
+						// TODO: remove magic number.
+						yv->PktOut[2 + idx] = 0x1A;
+						++idx;
+					}
+				}
 			}
 
 			// \x83f\x81[\x83^\x83u\x83\x8D\x83b\x83N
 			if (0 == eot)
 			{
 				// Add CRC if not End-of-Tranfer.
-				Check = YCalcCheck(yv, yv->PktOut);
+				WORD Check = YCalcCheck(yv, yv->PktOut, current_packet_size);
 				// Checksum.
 				if (1 == yv->CheckLen)
-					yv->PktOut[yv->DataLen + 3] = (BYTE)Check;
+					yv->PktOut[current_packet_size + 3] = (BYTE)Check;
 				else {
-					yv->PktOut[yv->DataLen + 3] = HIBYTE(Check);
-					yv->PktOut[yv->DataLen + 4] = LOBYTE(Check);
+					yv->PktOut[current_packet_size + 3] = HIBYTE(Check);
+					yv->PktOut[current_packet_size + 4] = LOBYTE(Check);
 				}
-				yv->PktBufCount = 3 + yv->DataLen + yv->CheckLen;
+				// TODO: remove magic number.
+				yv->PktBufCount = 3 + current_packet_size + yv->CheckLen;
 
 			}
 			else
@@ -912,12 +952,13 @@
 		else
 		{
 			// Resend packet.
-			yv->PktBufCount = 3 + yv->DataLen + yv->CheckLen;
+			yv->PktBufCount = 3 + yv->__DataLen + yv->CheckLen;
 		}
 
 		// Reset counter.
 		yv->PktBufPtr = 0;
 	}
+#if 0
 	/* a NAK or C could have arrived while we were buffering.  Consume it. */
 	// \x8C㑱\x82̃T\x81[\x83o\x82\xA9\x82\xE7\x82̃f\x81[\x83^\x82\xF0\x93ǂݎ̂Ă\xE9\x81B
 	do {
@@ -934,19 +975,20 @@
 			}
 		}
 	} while (i != 0);
+#endif
 
-
 	// Write bytes to COM.
-	i = 1;
-	while ((yv->PktBufCount>0) && (i>0))
+	while (yv->PktBufCount > 0)
 	{
-		b = yv->PktOut[yv->PktBufPtr];
-		i = YWrite(fv, yv, cv, &b, 1);
-		if (i > 0)
+		BYTE osym = yv->PktOut[yv->PktBufPtr];
+		int is_success = YWrite(fv, yv, cv, &osym, 1);
+		if (is_success > 0)
 		{
 			--yv->PktBufCount;
 			++yv->PktBufPtr;
 		}
+		else
+			break;
 	}
 
 	// Update dialog window.



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