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.