X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=getput.c;h=d542b53d8c03d5d48853c798cf368ba5c63d8431;hb=6797149e0f2d76c8902ca7a10d5fa903fdae5745;hp=1c287b64c5100a4546cba59b85bd66636248c957;hpb=12476c0b20b5a710f06aeec7eb34effc9f9a8590;p=ffftp%2Fffftp.git diff --git a/getput.c b/getput.c index 1c287b6..d542b53 100644 --- a/getput.c +++ b/getput.c @@ -41,7 +41,9 @@ #include #include #include -#include +// IPv6対応 +//#include +#include #include #include #include @@ -82,31 +84,45 @@ static void DispTransPacket(TRANSPACKET *Pkt); static void EraseTransFileList(void); static ULONG WINAPI TransferThread(void *Dummy); static int MakeNonFullPath(TRANSPACKET *Pkt, char *CurDir, char *Tmp); -static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork); -static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork); -static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *CancelCheckWork); +static int DownloadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork); +static int DownloadPassive(TRANSPACKET *Pkt, int *CancelCheckWork); +static int DownloadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *CancelCheckWork); static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode); -static int DispUpDownErrDialog(int ResID, HWND hWnd, char *Fname); -static BOOL CALLBACK UpDownErrorDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +// 再転送対応 +//static int DispUpDownErrDialog(int ResID, HWND hWnd, char *Fname); +static int DispUpDownErrDialog(int ResID, HWND hWnd, TRANSPACKET *Pkt); +// 64ビット対応 +//static BOOL CALLBACK UpDownErrorDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK UpDownErrorDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); static int SetDownloadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *Mode, int *CancelCheckWork); -static BOOL CALLBACK NoResumeWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); -static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt); -static int UpLoadNonPassive(TRANSPACKET *Pkt); -static int UpLoadPassive(TRANSPACKET *Pkt); -static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt); +// 64ビット対応 +//static BOOL CALLBACK NoResumeWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK NoResumeWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); +static int DoUpload(SOCKET cSkt, TRANSPACKET *Pkt); +static int UploadNonPassive(TRANSPACKET *Pkt); +static int UploadPassive(TRANSPACKET *Pkt); +static int UploadFile(TRANSPACKET *Pkt, SOCKET dSkt); // 同時接続対応 //static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii); -static int TermCodeConvAndSend(int ThreadCount, TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii); +static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii, int *CancelCheckWork); static void DispUploadFinishMsg(TRANSPACKET *Pkt, int iRetCode); static int SetUploadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *Mode); static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam); static void DispTransferStatus(HWND hWnd, int End, TRANSPACKET *Pkt); static void DispTransFileInfo(TRANSPACKET *Pkt, char *Title, int SkipButton, int Info); -static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max); +// IPv6対応 +//static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max); +static int GetAdrsAndPort(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max); +static int GetAdrsAndPortIPv4(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max); +static int GetAdrsAndPortIPv6(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max); static int IsSpecialDevice(char *Fname); static int MirrorDelNotify(int Cur, int Notify, TRANSPACKET *Pkt); -static BOOL CALLBACK MirrorDeleteDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); +// 64ビット対応 +//static BOOL CALLBACK MirrorDeleteDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK MirrorDeleteDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); static void SetErrorMsg(char *fmt, ...); +// 同時接続対応 +static char* GetErrMsg(); /*===== ローカルなワーク =====*/ @@ -140,8 +156,24 @@ static time_t TimeStart[MAX_DATA_CONNECTION]; /* 転送開始時間 */ static int KeepDlg = NO; /* 転送中ダイアログを消さないかどうか (YES/NO) */ static int MoveToForeground = NO; /* ウインドウを前面に移動するかどうか (YES/NO) */ -static char CurDir[FMAX_PATH+1] = { "" }; -static char ErrMsg[ERR_MSG_LEN+7]; +// 同時接続対応 +//static char CurDir[FMAX_PATH+1] = { "" }; +static char CurDir[MAX_DATA_CONNECTION][FMAX_PATH+1]; +// 同時接続対応 +//static char ErrMsg[ERR_MSG_LEN+7]; +static char ErrMsg[MAX_DATA_CONNECTION+1][ERR_MSG_LEN+7]; +static DWORD ErrMsgThreadId[MAX_DATA_CONNECTION+1]; +static HANDLE hErrMsgMutex; + +// 同時接続対応 +static int WaitForMainThread = NO; +// 再転送対応 +static int TransferErrorMode = EXIST_OVW; +static int TransferErrorNotify = NO; +// タスクバー進捗表示 +static LONGLONG TransferSizeLeft = 0; +static LONGLONG TransferSizeTotal = 0; +static int TransferErrorDisplay = 0; /*===== 外部参照 =====*/ @@ -154,6 +186,10 @@ extern int MirUpDelNotify; extern int MirDownDelNotify; extern int FolderAttr; extern int FolderAttrNum; +// 同時接続対応 +extern int SendQuit; +// 自動切断対策 +extern time_t LastDataConnectionTime; /*----- ファイル転送スレッドを起動する ---------------------------------------- @@ -172,6 +208,8 @@ int MakeTransferThread(void) hListAccMutex = CreateMutex( NULL, FALSE, NULL ); hRunMutex = CreateMutex( NULL, TRUE, NULL ); + // 同時接続対応 + hErrMsgMutex = CreateMutex( NULL, FALSE, NULL ); ClearAll = NO; ForceAbort = NO; @@ -233,6 +271,8 @@ void CloseTransferThread(void) CloseHandle( hListAccMutex ); CloseHandle( hRunMutex ); + // 同時接続対応 + CloseHandle( hErrMsgMutex ); return; } @@ -356,34 +396,64 @@ int RemoveTmpTransFileListItem(TRANSPACKET **Base, int Num) void AddTransFileList(TRANSPACKET *Pkt) { + // 同時接続対応 + TRANSPACKET *Pos; + DispTransPacket(Pkt); // 同時接続対応 // WaitForSingleObject(hListAccMutex, INFINITE); while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) { + WaitForMainThread = YES; BackgrndMessageProc(); Sleep(1); } + // 同時接続対応 + Pos = TransPacketBase; + if(Pos != NULL) + { + while(Pos->Next != NULL) + Pos = Pos->Next; + } if(AddTmpTransFileList(Pkt, &TransPacketBase) == FFFTP_SUCCESS) { if((strncmp(Pkt->Cmd, "RETR", 4) == 0) || (strncmp(Pkt->Cmd, "STOR", 4) == 0)) { TransFiles++; + // タスクバー進捗表示 + TransferSizeLeft += Pkt->Size; + TransferSizeTotal += Pkt->Size; PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0); } } // 同時接続対応 if(NextTransPacketBase == NULL) - NextTransPacketBase = TransPacketBase; + { + if(Pos) + NextTransPacketBase = Pos->Next; + else + NextTransPacketBase = TransPacketBase; + } ReleaseMutex(hListAccMutex); + // 同時接続対応 + WaitForMainThread = NO; return; } +// バグ対策 +void AddNullTransFileList() +{ + TRANSPACKET Pkt; + memset(&Pkt, 0, sizeof(TRANSPACKET)); + strcpy(Pkt.Cmd, "NULL"); + AddTransFileList(&Pkt); +} + /*----- 転送ファイル情報を転送ファイルリストに追加する ------------------------ * * Parameter @@ -405,6 +475,7 @@ void AppendTransFileList(TRANSPACKET *Pkt) // WaitForSingleObject(hListAccMutex, INFINITE); while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) { + WaitForMainThread = YES; BackgrndMessageProc(); Sleep(1); } @@ -420,7 +491,7 @@ void AppendTransFileList(TRANSPACKET *Pkt) } // 同時接続対応 if(NextTransPacketBase == NULL) - NextTransPacketBase = TransPacketBase; + NextTransPacketBase = Pkt; while(Pkt != NULL) { @@ -430,12 +501,17 @@ void AppendTransFileList(TRANSPACKET *Pkt) (strncmp(Pkt->Cmd, "STOR", 4) == 0)) { TransFiles++; + // タスクバー進捗表示 + TransferSizeLeft += Pkt->Size; + TransferSizeTotal += Pkt->Size; PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0); } Pkt = Pkt->Next; } ReleaseMutex(hListAccMutex); + // 同時接続対応 + WaitForMainThread = NO; return; } @@ -484,7 +560,7 @@ static void EraseTransFileList(void) TRANSPACKET *New; TRANSPACKET *Next; TRANSPACKET *NotDel; - TRANSPACKET Pkt; +// TRANSPACKET Pkt; NotDel = NULL; @@ -492,6 +568,7 @@ static void EraseTransFileList(void) // WaitForSingleObject(hListAccMutex, INFINITE); while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) { + WaitForMainThread = YES; BackgrndMessageProc(); Sleep(1); } @@ -521,13 +598,19 @@ static void EraseTransFileList(void) } TransPacketBase = NotDel; // 同時接続対応 - NextTransPacketBase = TransPacketBase; + NextTransPacketBase = NotDel; TransFiles = 0; + // タスクバー進捗表示 + TransferSizeLeft = 0; + TransferSizeTotal = 0; PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0); ReleaseMutex(hListAccMutex); + // 同時接続対応 + WaitForMainThread = NO; - strcpy(Pkt.Cmd, "GOQUIT"); - AddTransFileList(&Pkt); + // 同時接続対応 +// strcpy(Pkt.Cmd, "GOQUIT"); +// AddTransFileList(&Pkt); return; } @@ -605,7 +688,11 @@ void GoForwardTransWindow(void) void InitTransCurDir(void) { - strcpy(CurDir, ""); + // 同時接続対応 +// strcpy(CurDir, ""); + int i; + for(i = 0; i < MAX_DATA_CONNECTION; i++) + strcpy(CurDir[i], ""); return; } @@ -637,6 +724,9 @@ static ULONG WINAPI TransferThread(void *Dummy) SOCKET TrnSkt; RECT WndRect; int i; + DWORD LastUsed; + int LastError; + int Sts; hWndTrans = NULL; Down = NO; @@ -649,6 +739,8 @@ static ULONG WINAPI TransferThread(void *Dummy) CmdSkt = INVALID_SOCKET; NewCmdSkt = INVALID_SOCKET; TrnSkt = INVALID_SOCKET; + LastError = NO; + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); while((TransPacketBase != NULL) || (WaitForSingleObject(hRunMutex, 200) == WAIT_TIMEOUT)) @@ -656,13 +748,21 @@ static ULONG WINAPI TransferThread(void *Dummy) if(fTransferThreadExit == TRUE) break; + if(WaitForMainThread == YES) + { + BackgrndMessageProc(); + Sleep(100); + continue; + } + // WaitForSingleObject(hListAccMutex, INFINITE); while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) { BackgrndMessageProc(); Sleep(1); } - memset(ErrMsg, NUL, ERR_MSG_LEN+7); +// memset(ErrMsg, NUL, ERR_MSG_LEN+7); + memset(GetErrMsg(), NUL, ERR_MSG_LEN+7); // Canceled = NO; Canceled[ThreadCount] = NO; @@ -672,14 +772,24 @@ static ULONG WINAPI TransferThread(void *Dummy) Pos = TransPacketBase; TransPacketBase = TransPacketBase->Next; free(Pos); + if(TransPacketBase == NULL) + GoExit = YES; } NewCmdSkt = AskCmdCtrlSkt(); - if(TransPacketBase && NewCmdSkt != INVALID_SOCKET && ThreadCount < AskMaxThreadCount()) + if(AskReuseCmdSkt() == YES && ThreadCount == 0) + { + if(TransPacketBase && ThreadCount < AskMaxThreadCount()) + TrnSkt = AskTrnCtrlSkt(); + } + else { - if(TrnSkt == INVALID_SOCKET || NewCmdSkt != CmdSkt) + // セッションあたりの転送量制限対策 + if(AskErrorReconnect() == YES && LastError == YES) { ReleaseMutex(hListAccMutex); - ReConnectTrnSkt(&TrnSkt); + DoQUIT(TrnSkt, &Canceled[ThreadCount]); + DoClose(TrnSkt); + TrnSkt = INVALID_SOCKET; // WaitForSingleObject(hListAccMutex, INFINITE); while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) { @@ -687,14 +797,27 @@ static ULONG WINAPI TransferThread(void *Dummy) Sleep(1); } } - } - else - { - if(TrnSkt != INVALID_SOCKET) + if(TransPacketBase && NewCmdSkt != INVALID_SOCKET && ThreadCount < AskMaxThreadCount()) { ReleaseMutex(hListAccMutex); - DoClose(TrnSkt); - TrnSkt = INVALID_SOCKET; + if(TrnSkt == INVALID_SOCKET || NewCmdSkt != CmdSkt) + ReConnectTrnSkt(&TrnSkt, &Canceled[ThreadCount]); + else + CheckClosedAndReconnectTrnSkt(&TrnSkt, &Canceled[ThreadCount]); + // 同時ログイン数制限対策 + if(TrnSkt == INVALID_SOCKET) + { + // 同時ログイン数制限に引っかかった可能性あり + // 負荷を下げるために約10秒間待機 + i = 10000; + while(NewCmdSkt != CmdSkt && i > 0) + { + BackgrndMessageProc(); + Sleep(1); + i--; + } + } + LastUsed = timeGetTime(); // WaitForSingleObject(hListAccMutex, INFINITE); while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) { @@ -702,8 +825,30 @@ static ULONG WINAPI TransferThread(void *Dummy) Sleep(1); } } + else + { + if(TrnSkt != INVALID_SOCKET) + { + // 同時ログイン数制限対策 + // 60秒間使用されなければログアウト + if(timeGetTime() - LastUsed > 60000 || NewCmdSkt == INVALID_SOCKET) + { + ReleaseMutex(hListAccMutex); + DoQUIT(TrnSkt, &Canceled[ThreadCount]); + DoClose(TrnSkt); + TrnSkt = INVALID_SOCKET; +// WaitForSingleObject(hListAccMutex, INFINITE); + while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) + { + BackgrndMessageProc(); + Sleep(1); + } + } + } + } } CmdSkt = NewCmdSkt; + LastError = NO; // if(TransPacketBase != NULL) if(TrnSkt != INVALID_SOCKET && NextTransPacketBase != NULL) { @@ -735,6 +880,7 @@ static ULONG WINAPI TransferThread(void *Dummy) // TransPacketBase->hWndTrans = hWndTrans; Pos->hWndTrans = hWndTrans; Pos->ctrl_skt = TrnSkt; + Pos->Abort = ABORT_NONE; Pos->ThreadCount = ThreadCount; if(hWndTrans != NULL) @@ -750,6 +896,9 @@ static ULONG WINAPI TransferThread(void *Dummy) // SendMessage(hWndTrans, WM_SET_PACKET, 0, (LPARAM)TransPacketBase); SendMessage(hWndTrans, WM_SET_PACKET, 0, (LPARAM)Pos); + // 中断後に受信バッファに応答が残っていると次のコマンドの応答が正しく処理できない + RemoveReceivedData(TrnSkt); + /* ダウンロード */ // if(strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) if(strncmp(Pos->Cmd, "RETR", 4) == 0) @@ -762,7 +911,7 @@ static ULONG WINAPI TransferThread(void *Dummy) { /* フルパスを使わないための処理 */ // if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS) - if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS) + if(MakeNonFullPath(Pos, CurDir[Pos->ThreadCount], Tmp) == FFFTP_SUCCESS) { // if(strncmp(TransPacketBase->Cmd, "RETR-S", 6) == 0) if(strncmp(Pos->Cmd, "RETR-S", 6) == 0) @@ -771,17 +920,19 @@ static ULONG WINAPI TransferThread(void *Dummy) // DoSIZE(TransPacketBase->RemoteFile, &TransPacketBase->Size); // DoMDTM(TransPacketBase->RemoteFile, &TransPacketBase->Time); // strcpy(TransPacketBase->Cmd, "RETR "); - DoSIZE(TrnSkt, Pos->RemoteFile, &Pos->Size); - DoMDTM(TrnSkt, Pos->RemoteFile, &Pos->Time); + DoSIZE(TrnSkt, Pos->RemoteFile, &Pos->Size, &Canceled[Pos->ThreadCount]); + DoMDTM(TrnSkt, Pos->RemoteFile, &Pos->Time, &Canceled[Pos->ThreadCount]); strcpy(Pos->Cmd, "RETR "); } Down = YES; -// if(DoDownLoad(AskTrnCtrlSkt(), TransPacketBase, NO) == 429) +// if(DoDownload(AskTrnCtrlSkt(), TransPacketBase, NO) == 429) // { // if(ReConnectTrnSkt() == FFFTP_SUCCESS) -// DoDownLoad(AskTrnCtrlSkt(), TransPacketBase, NO, &Canceled); - DoDownLoad(TrnSkt, Pos, NO, &Canceled[Pos->ThreadCount]); +// DoDownload(AskTrnCtrlSkt(), TransPacketBase, NO, &Canceled); + Sts = DoDownload(TrnSkt, Pos, NO, &Canceled[Pos->ThreadCount]) / 100; + if(Sts != FTP_COMPLETE) + LastError = YES; // } } } @@ -796,15 +947,25 @@ static ULONG WINAPI TransferThread(void *Dummy) // ReleaseMutex(hListAccMutex); /* フルパスを使わないための処理 */ // if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS) - if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS) + if(MakeNonFullPath(Pos, CurDir[Pos->ThreadCount], Tmp) == FFFTP_SUCCESS) { Up = YES; -// if(DoUpLoad(AskTrnCtrlSkt(), TransPacketBase) == 429) +// if(DoUpload(AskTrnCtrlSkt(), TransPacketBase) == 429) // { // if(ReConnectTrnSkt() == FFFTP_SUCCESS) -// DoUpLoad(AskTrnCtrlSkt(), TransPacketBase); - DoUpLoad(TrnSkt, Pos); +// DoUpload(AskTrnCtrlSkt(), TransPacketBase); + Sts = DoUpload(TrnSkt, Pos) / 100; + if(Sts != FTP_COMPLETE) + LastError = YES; // } + + // ホスト側の日時設定 + /* ファイルのタイムスタンプを合わせる */ + if((SaveTimeStamp == YES) && + ((Pos->Time.dwLowDateTime != 0) || (Pos->Time.dwHighDateTime != 0))) + { + DoMFMT(TrnSkt, Pos->RemoteFile, &Pos->Time, &Canceled[Pos->ThreadCount]); + } } // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため ReleaseMutex(hListAccMutex); @@ -825,7 +986,7 @@ static ULONG WINAPI TransferThread(void *Dummy) // strcpy(Tmp, TransPacketBase->RemoteFile); strcpy(Tmp, Pos->RemoteFile); // if(ProcForNonFullpath(Tmp, CurDir, hWndTrans, 1) == FFFTP_FAIL) - if(ProcForNonFullpath(Tmp, CurDir, hWndTrans, (int)TrnSkt + 1) == FFFTP_FAIL) + if(ProcForNonFullpath(TrnSkt, Tmp, CurDir[Pos->ThreadCount], hWndTrans, &Canceled[Pos->ThreadCount]) == FFFTP_FAIL) { ClearAll = YES; CwdSts = FTP_ERROR; @@ -835,13 +996,13 @@ static ULONG WINAPI TransferThread(void *Dummy) { Up = YES; // CommandProcTrn(NULL, "MKD %s", Tmp); - CommandProcTrn(TrnSkt, NULL, "MKD %s", Tmp); + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "MKD %s", Tmp); /* すでにフォルダがある場合もあるので、 */ /* ここではエラーチェックはしない */ if(FolderAttr) // CommandProcTrn(NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Tmp); - CommandProcTrn(TrnSkt, NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Tmp); + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Tmp); } } // else if(strlen(TransPacketBase->LocalFile) > 0) @@ -862,15 +1023,15 @@ static ULONG WINAPI TransferThread(void *Dummy) /* フルパスを使わないための処理 */ // if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS) - if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS) + if(MakeNonFullPath(Pos, CurDir[Pos->ThreadCount], Tmp) == FFFTP_SUCCESS) { Up = YES; // CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile); - CommandProcTrn(TrnSkt, NULL, "%s%s", Pos->Cmd+2, Pos->RemoteFile); + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "%s%s", Pos->Cmd+2, Pos->RemoteFile); if(FolderAttr) // CommandProcTrn(NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, TransPacketBase->RemoteFile); - CommandProcTrn(TrnSkt, NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Pos->RemoteFile); + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Pos->RemoteFile); } ReleaseMutex(hListAccMutex); } @@ -887,11 +1048,11 @@ static ULONG WINAPI TransferThread(void *Dummy) { /* フルパスを使わないための処理 */ // if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS) - if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS) + if(MakeNonFullPath(Pos, CurDir[Pos->ThreadCount], Tmp) == FFFTP_SUCCESS) { Up = YES; // CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile); - CommandProcTrn(TrnSkt, NULL, "%s%s", Pos->Cmd+2, Pos->RemoteFile); + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "%s%s", Pos->Cmd+2, Pos->RemoteFile); } } ReleaseMutex(hListAccMutex); @@ -900,7 +1061,6 @@ static ULONG WINAPI TransferThread(void *Dummy) // else if(strncmp(TransPacketBase->Cmd, "R-DELE", 6) == 0) else if(strncmp(Pos->Cmd, "R-DELE", 6) == 0) { - ReleaseMutex(hListAccMutex); // DispTransFileInfo(TransPacketBase, MSGJPN081, FALSE, YES); DispTransFileInfo(Pos, MSGJPN081, FALSE, YES); @@ -910,13 +1070,14 @@ static ULONG WINAPI TransferThread(void *Dummy) { /* フルパスを使わないための処理 */ // if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS) - if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS) + if(MakeNonFullPath(Pos, CurDir[Pos->ThreadCount], Tmp) == FFFTP_SUCCESS) { Up = YES; // CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile); - CommandProcTrn(TrnSkt, NULL, "%s%s", Pos->Cmd+2, Pos->RemoteFile); + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "%s%s", Pos->Cmd+2, Pos->RemoteFile); } } + ReleaseMutex(hListAccMutex); } /* ディレクトリ作成(常にローカル側) */ // else if(strncmp(TransPacketBase->Cmd, "L-MKD", 5) == 0) @@ -968,13 +1129,14 @@ static ULONG WINAPI TransferThread(void *Dummy) // else if(strcmp(TransPacketBase->Cmd, "SETCUR") == 0) else if(strcmp(Pos->Cmd, "SETCUR") == 0) { - if(AskShareProh() == YES) +// if(AskShareProh() == YES) + if(AskReuseCmdSkt() == NO || AskShareProh() == YES) { // if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0) - if(strcmp(CurDir, Pos->RemoteFile) != 0) + if(strcmp(CurDir[Pos->ThreadCount], Pos->RemoteFile) != 0) { // if(CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile)/100 != FTP_COMPLETE) - if(CommandProcTrn(TrnSkt, NULL, "CWD %s", Pos->RemoteFile)/100 != FTP_COMPLETE) + if(CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "CWD %s", Pos->RemoteFile)/100 != FTP_COMPLETE) { DispCWDerror(hWndTrans); ClearAll = YES; @@ -982,31 +1144,32 @@ static ULONG WINAPI TransferThread(void *Dummy) } } // strcpy(CurDir, TransPacketBase->RemoteFile); - strcpy(CurDir, Pos->RemoteFile); + strcpy(CurDir[Pos->ThreadCount], Pos->RemoteFile); ReleaseMutex(hListAccMutex); } /* カレントディレクトリを戻す */ // else if(strcmp(TransPacketBase->Cmd, "BACKCUR") == 0) else if(strcmp(Pos->Cmd, "BACKCUR") == 0) { - if(AskShareProh() == NO) +// if(AskShareProh() == NO) + if(AskReuseCmdSkt() == YES && AskShareProh() == NO) { // if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0) // CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile); // strcpy(CurDir, TransPacketBase->RemoteFile); - if(strcmp(CurDir, Pos->RemoteFile) != 0) - CommandProcTrn(TrnSkt, NULL, "CWD %s", Pos->RemoteFile); - strcpy(CurDir, Pos->RemoteFile); + if(strcmp(CurDir[Pos->ThreadCount], Pos->RemoteFile) != 0) + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "CWD %s", Pos->RemoteFile); + strcpy(CurDir[Pos->ThreadCount], Pos->RemoteFile); } ReleaseMutex(hListAccMutex); } /* 自動終了のための通知 */ // else if(strcmp(TransPacketBase->Cmd, "GOQUIT") == 0) - else if(strcmp(Pos->Cmd, "GOQUIT") == 0) - { - ReleaseMutex(hListAccMutex); - GoExit = YES; - } +// else if(strcmp(Pos->Cmd, "GOQUIT") == 0) +// { +// ReleaseMutex(hListAccMutex); +// GoExit = YES; +// } else ReleaseMutex(hListAccMutex); @@ -1025,26 +1188,37 @@ static ULONG WINAPI TransferThread(void *Dummy) { for(i = 0; i < MAX_DATA_CONNECTION; i++) Canceled[i] = YES; - EraseTransFileList(); + if(Pos != NULL) + strcpy(Pos->Cmd, ""); Pos = NULL; + EraseTransFileList(); + GoExit = YES; } else { // if((strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) || // (strncmp(TransPacketBase->Cmd, "STOR", 4) == 0)) if((strncmp(Pos->Cmd, "RETR", 4) == 0) || - (strncmp(Pos->Cmd, "STOR", 4) == 0)) + (strncmp(Pos->Cmd, "STOR", 4) == 0) || + (strncmp(Pos->Cmd, "STOU", 4) == 0)) { // TransFiles--; if(TransFiles > 0) TransFiles--; + // タスクバー進捗表示 + if(TransferSizeLeft > 0) + TransferSizeLeft -= Pos->Size; + if(TransferSizeLeft < 0) + TransferSizeLeft = 0; + if(TransFiles == 0) + TransferSizeTotal = 0; PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0); } // Pos = TransPacketBase; // TransPacketBase = TransPacketBase->Next; // free(Pos); } - ClearAll = NO; +// ClearAll = NO; ReleaseMutex(hListAccMutex); if(BackgrndMessageProc() == YES) @@ -1058,12 +1232,30 @@ static ULONG WINAPI TransferThread(void *Dummy) SendMessage(hWndTrans, WM_SET_PACKET, 0, 0); if(Pos != NULL) strcpy(Pos->Cmd, ""); + LastUsed = timeGetTime(); } // else else if(TransPacketBase == NULL) { + ClearAll = NO; DelNotify = NO; + if(GoExit == YES) + { + SoundPlay(SND_TRANS); + if(AskAutoExit() == NO) + { + if(Down == YES) + PostMessage(GetMainHwnd(), WM_REFRESH_LOCAL_FLG, 0, 0); + if(Up == YES) + PostMessage(GetMainHwnd(), WM_REFRESH_REMOTE_FLG, 0, 0); + } + Down = NO; + Up = NO; + PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_AUTO_EXIT, 0), 0); + GoExit = NO; + } + ReleaseMutex(hListAccMutex); if(KeepDlg == NO) { @@ -1089,23 +1281,12 @@ static ULONG WINAPI TransferThread(void *Dummy) } } BackgrndMessageProc(); - Sleep(1); +// Sleep(1); + Sleep(100); - if(GoExit == YES) - { - SoundPlay(SND_TRANS); - if(AskAutoExit() == NO) - { - if(Down == YES) - PostMessage(GetMainHwnd(), WM_REFRESH_LOCAL_FLG, 0, 0); - if(Up == YES) - PostMessage(GetMainHwnd(), WM_REFRESH_REMOTE_FLG, 0, 0); - } - Down = NO; - Up = NO; - PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_AUTO_EXIT, 0), 0); - GoExit = NO; - } + // 再転送対応 + TransferErrorMode = AskTransferErrorMode(); + TransferErrorNotify = AskTransferErrorNotify(); } else { @@ -1116,11 +1297,20 @@ static ULONG WINAPI TransferThread(void *Dummy) hWndTrans = NULL; } BackgrndMessageProc(); - Sleep(1); + if(ThreadCount < AskMaxThreadCount()) + Sleep(1); + else + Sleep(100); + } + } + if(AskReuseCmdSkt() == NO || ThreadCount > 0) + { + if(TrnSkt != INVALID_SOCKET) + { + SendData(TrnSkt, "QUIT\r\n", 6, 0, &Canceled[ThreadCount]); + DoClose(TrnSkt); } } - if(TrnSkt != INVALID_SOCKET) - DoClose(TrnSkt); return 0; } @@ -1147,7 +1337,7 @@ static int MakeNonFullPath(TRANSPACKET *Pkt, char *Cur, char *Tmp) int Sts; // Sts = ProcForNonFullpath(Pkt->RemoteFile, Cur, Pkt->hWndTrans, 1); - Sts = ProcForNonFullpath(Pkt->RemoteFile, Cur, Pkt->hWndTrans, (int)Pkt->ctrl_skt + 1); + Sts = ProcForNonFullpath(Pkt->ctrl_skt, Pkt->RemoteFile, Cur, Pkt->hWndTrans, &Canceled[Pkt->ThreadCount]); if(Sts == FFFTP_FAIL) ClearAll = YES; @@ -1172,7 +1362,7 @@ static int MakeNonFullPath(TRANSPACKET *Pkt, char *Cur, char *Tmp) * からも呼ばれる。メインのスレッドから呼ばれる時は Pkt->hWndTrans == NULL。 *----------------------------------------------------------------------------*/ -int DoDownLoad(SOCKET cSkt, TRANSPACKET *Pkt, int DirList, int *CancelCheckWork) +int DoDownload(SOCKET cSkt, TRANSPACKET *Pkt, int DirList, int *CancelCheckWork) { int iRetCode; char Reply[ERR_MSG_LEN+7]; @@ -1182,7 +1372,8 @@ int DoDownLoad(SOCKET cSkt, TRANSPACKET *Pkt, int DirList, int *CancelCheckWork) { iRetCode = 500; SetTaskMsg(MSGJPN085, GetFileName(Pkt->LocalFile)); - DispDownloadFinishMsg(Pkt, iRetCode); + // エラーによってはダイアログが表示されない場合があるバグ対策 +// DispDownloadFinishMsg(Pkt, iRetCode); } else if(Pkt->Mode != EXIST_IGNORE) { @@ -1207,15 +1398,17 @@ int DoDownLoad(SOCKET cSkt, TRANSPACKET *Pkt, int DirList, int *CancelCheckWork) if(BackgrndMessageProc() == NO) { if(AskPasvMode() != YES) - iRetCode = DownLoadNonPassive(Pkt, CancelCheckWork); + iRetCode = DownloadNonPassive(Pkt, CancelCheckWork); else - iRetCode = DownLoadPassive(Pkt, CancelCheckWork); + iRetCode = DownloadPassive(Pkt, CancelCheckWork); } else iRetCode = 500; } else SetErrorMsg(Reply); + // エラーによってはダイアログが表示されない場合があるバグ対策 + DispDownloadFinishMsg(Pkt, iRetCode); } else { @@ -1236,15 +1429,22 @@ int DoDownLoad(SOCKET cSkt, TRANSPACKET *Pkt, int DirList, int *CancelCheckWork) * int 応答コード *----------------------------------------------------------------------------*/ -static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) +static int DownloadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) { int iRetCode; int iLength; SOCKET data_socket = INVALID_SOCKET; // data channel socket SOCKET listen_socket = INVALID_SOCKET; // data listen socket - char Buf[1024]; + // 念のため +// char Buf[1024]; + char Buf[FMAX_PATH+1024]; int CreateMode; - struct sockaddr_in saSockAddr1; + // IPv6対応 +// struct sockaddr_in saSockAddr1; + struct sockaddr_in saSockAddrIPv4; + struct sockaddr_in6 saSockAddrIPv6; + // UPnP対応 + int Port; char Reply[ERR_MSG_LEN+7]; if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, CancelCheckWork)) != INVALID_SOCKET) @@ -1255,13 +1455,33 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) iRetCode = command(Pkt->ctrl_skt, Reply, CancelCheckWork, "%s", Buf); if(iRetCode/100 == FTP_PRELIM) { - if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL) + // 同時接続対応 +// if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL) + if(SocksGet2ndBindReply(listen_socket, &data_socket, CancelCheckWork) == FFFTP_FAIL) { - iLength = sizeof(saSockAddr1); - data_socket = do_accept(listen_socket, (struct sockaddr *)&saSockAddr1, (int *)&iLength); + // IPv6対応 +// iLength = sizeof(saSockAddr1); +// data_socket = do_accept(listen_socket, (struct sockaddr *)&saSockAddr1, (int *)&iLength); + switch(AskCurNetType()) + { + case NTYPE_IPV4: + iLength=sizeof(saSockAddrIPv4); + data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddrIPv4, (int *)&iLength); + break; + case NTYPE_IPV6: + iLength=sizeof(saSockAddrIPv6); + data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddrIPv6, (int *)&iLength); + break; + } if(shutdown(listen_socket, 1) != 0) ReportWSError("shutdown listen", WSAGetLastError()); + // UPnP対応 + if(IsUPnPLoaded() == YES) + { + if(GetAsyncTableDataMapPort(listen_socket, &Port) == YES) + RemovePortMapping(Port); + } listen_socket = DoClose(listen_socket); if(data_socket == INVALID_SOCKET) @@ -1271,7 +1491,19 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) iRetCode = 500; } else - DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port)); + // IPv6対応 +// DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port)); + { + switch(AskCurNetType()) + { + case NTYPE_IPV4: + DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddrIPv4.sin_addr), ntohs(saSockAddrIPv4.sin_port)); + break; + case NTYPE_IPV6: + DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet6_ntoa(saSockAddrIPv6.sin6_addr), ntohs(saSockAddrIPv6.sin6_port)); + break; + } + } } if(data_socket != INVALID_SOCKET) @@ -1279,16 +1511,16 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため ReleaseMutex(hListAccMutex); // FTPS対応 -// iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); - if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) +// iRetCode = DownloadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + if(IsSSLAttached(Pkt->ctrl_skt)) { - if(AttachSSL(data_socket)) - iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + if(AttachSSL(data_socket, Pkt->ctrl_skt, CancelCheckWork, FALSE)) + iRetCode = DownloadFile(Pkt, data_socket, CreateMode, CancelCheckWork); else - iRetCode = FTP_ERROR; + iRetCode = 500; } else - iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + iRetCode = DownloadFile(Pkt, data_socket, CreateMode, CancelCheckWork); // data_socket = DoClose(data_socket); } } @@ -1296,19 +1528,37 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) { SetErrorMsg(Reply); SetTaskMsg(MSGJPN090); + // UPnP対応 + if(IsUPnPLoaded() == YES) + { + if(GetAsyncTableDataMapPort(listen_socket, &Port) == YES) + RemovePortMapping(Port); + } listen_socket = DoClose(listen_socket); iRetCode = 500; } } else + // バグ修正 +// iRetCode = 500; + { + // UPnP対応 + if(IsUPnPLoaded() == YES) + { + if(GetAsyncTableDataMapPort(listen_socket, &Port) == YES) + RemovePortMapping(Port); + } + listen_socket = DoClose(listen_socket); iRetCode = 500; + } } else { iRetCode = 500; SetErrorMsg(MSGJPN279); } - DispDownloadFinishMsg(Pkt, iRetCode); + // エラーによってはダイアログが表示されない場合があるバグ対策 +// DispDownloadFinishMsg(Pkt, iRetCode); return(iRetCode); } @@ -1323,21 +1573,37 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) * int 応答コード *----------------------------------------------------------------------------*/ -static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork) +static int DownloadPassive(TRANSPACKET *Pkt, int *CancelCheckWork) { int iRetCode; SOCKET data_socket = INVALID_SOCKET; // data channel socket - char Buf[1024]; + // 念のため +// char Buf[1024]; + char Buf[FMAX_PATH+1024]; int CreateMode; - char Adrs[20]; + // IPv6対応 +// char Adrs[20]; + char Adrs[40]; int Port; int Flg; char Reply[ERR_MSG_LEN+7]; - iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "PASV"); + // IPv6対応 +// iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "PASV"); + switch(AskCurNetType()) + { + case NTYPE_IPV4: + iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "PASV"); + break; + case NTYPE_IPV6: + iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "EPSV"); + break; + } if(iRetCode/100 == FTP_COMPLETE) { - if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS) + // IPv6対応 +// if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS) + if(GetAdrsAndPort(Pkt->ctrl_skt, Buf, Adrs, &Port, 39) == FFFTP_SUCCESS) { if((data_socket = connectsock(Adrs, Port, MSGJPN091, CancelCheckWork)) != INVALID_SOCKET) { @@ -1355,16 +1621,16 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork) // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため ReleaseMutex(hListAccMutex); // FTPS対応 -// iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); - if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) +// iRetCode = DownloadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + if(IsSSLAttached(Pkt->ctrl_skt)) { - if(AttachSSL(data_socket)) - iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + if(AttachSSL(data_socket, Pkt->ctrl_skt, CancelCheckWork, FALSE)) + iRetCode = DownloadFile(Pkt, data_socket, CreateMode, CancelCheckWork); else - iRetCode = FTP_ERROR; + iRetCode = 500; } else - iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + iRetCode = DownloadFile(Pkt, data_socket, CreateMode, CancelCheckWork); // data_socket = DoClose(data_socket); } else @@ -1391,7 +1657,8 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork) else SetErrorMsg(Buf); - DispDownloadFinishMsg(Pkt, iRetCode); + // エラーによってはダイアログが表示されない場合があるバグ対策 +// DispDownloadFinishMsg(Pkt, iRetCode); return(iRetCode); } @@ -1413,7 +1680,7 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork) * ダイアログを出さない場合、このルーチンからDispDownloadSize()を呼ぶ *----------------------------------------------------------------------------*/ -static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *CancelCheckWork) +static int DownloadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *CancelCheckWork) { int iNumBytes; char Buf[BUFSIZE]; @@ -1467,8 +1734,12 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc char Buf3[(BUFSIZE + 3) * 4]; CODECONVINFO cInfo2; int ProcessedBOM = NO; + // 4GB超対応(kaokunさん提供) + DWORD High = 0; if(CreateMode == OPEN_ALWAYS) - SetFilePointer(iFileHandle, 0, 0, FILE_END); + // 4GB超対応(kaokunさん提供) +// SetFilePointer(iFileHandle, 0, 0, FILE_END); + SetFilePointer(iFileHandle, 0, &High, FILE_END); if(Pkt->hWndTrans != NULL) { @@ -1546,8 +1817,6 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc // Continue = ConvJIStoSJIS(&cInfo); // else // Continue = ConvEUCtoSJIS(&cInfo); - char Buf3[(BUFSIZE + 3) * 4]; - CODECONVINFO cInfo2; switch(Pkt->KanjiCode) { case KANJI_SJIS: @@ -1576,6 +1845,11 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc cInfo2.OutLen = cInfo.OutLen; break; case KANJI_UTF8N: + Continue = ConvSJIStoUTF8N(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8BOM: if(ProcessedBOM == NO) { memcpy(Buf3, "\xEF\xBB\xBF", 3); @@ -1619,6 +1893,14 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc ConvSJIStoEUC(&cInfo2); break; case KANJI_UTF8N: + Continue = ConvJIStoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + case KANJI_UTF8BOM: if(ProcessedBOM == NO) { memcpy(Buf3, "\xEF\xBB\xBF", 3); @@ -1665,6 +1947,14 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc ConvSJIStoEUC(&cInfo2); break; case KANJI_UTF8N: + Continue = ConvEUCtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + case KANJI_UTF8BOM: if(ProcessedBOM == NO) { memcpy(Buf3, "\xEF\xBB\xBF", 3); @@ -1683,6 +1973,50 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc } break; case KANJI_UTF8N: + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + Continue = ConvUTF8NtoSJIS(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + Continue = ConvUTF8NtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + Continue = ConvUTF8NtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; + case KANJI_UTF8BOM: + if(ProcessedBOM == NO) + { + memcpy(Buf3, "\xEF\xBB\xBF", 3); + cInfo2.OutLen = 3; + Continue = YES; + ProcessedBOM = YES; + break; + } + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; + } + break; + case KANJI_UTF8BOM: if(ProcessedBOM == NO) { if(memcmp(Buf, "\xEF\xBB\xBF", 3) == 0) @@ -1693,7 +2027,7 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc cInfo2.OutLen = 0; switch(Pkt->KanjiCodeDesired) { - case KANJI_UTF8N: + case KANJI_UTF8BOM: memcpy(Buf3, "\xEF\xBB\xBF", 3); cInfo2.OutLen = 3; break; @@ -1730,6 +2064,11 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc cInfo2.OutLen = cInfo.StrLen; Continue = NO; break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; } break; } @@ -1791,6 +2130,10 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc memcpy(Buf3, cInfo.Buf, cInfo.OutLen); cInfo2.OutLen = cInfo.OutLen; break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; } break; case KANJI_JIS: @@ -1822,6 +2165,13 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc cInfo2.BufSize = (BUFSIZE + 3) * 4; ConvSJIStoUTF8N(&cInfo2); break; + case KANJI_UTF8BOM: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; } break; case KANJI_EUC: @@ -1853,6 +2203,13 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc cInfo2.BufSize = (BUFSIZE + 3) * 4; ConvSJIStoUTF8N(&cInfo2); break; + case KANJI_UTF8BOM: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; } break; case KANJI_UTF8N: @@ -1880,6 +2237,41 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc memcpy(Buf3, cInfo.Buf, cInfo.OutLen); cInfo2.OutLen = cInfo.OutLen; break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + } + break; + case KANJI_UTF8BOM: + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; } break; } @@ -1931,6 +2323,8 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc if(shutdown(dSkt, 1) != 0) ReportWSError("shutdown", WSAGetLastError()); + // 自動切断対策 + LastDataConnectionTime = time(NULL); DoClose(dSkt); if(ForceAbort == NO) @@ -1954,7 +2348,9 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc SetErrorMsg(MSGJPN096); SetTaskMsg(MSGJPN096); } - if(iRetCode >= FTP_RETRY) + // バグ修正 +// if(iRetCode >= FTP_RETRY) + if((iRetCode/100) >= FTP_RETRY) SetErrorMsg(Buf); if(Pkt->Abort != ABORT_NONE) iRetCode = 500; @@ -1977,6 +2373,8 @@ static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode) { char Fname[FMAX_PATH+1]; + // 同時接続対応 + ReleaseMutex(hListAccMutex); if(ForceAbort == NO) { if((iRetCode/100) >= FTP_CONTINUE) @@ -1989,8 +2387,16 @@ static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode) if (AskHostType() == HTYPE_VMS) return; #endif +#if defined(HAVE_TANDEM) + /* HP Nonstop Server の場合、ファイルのない subvol へ移動すると550 File not found + * になるが問題ないのでエラーダイアログやエラーメッセージを出さないため */ + if (AskHostType() == HTYPE_TANDEM) + return; +#endif - if((strncmp(Pkt->Cmd, "NLST", 4) == 0) || (strncmp(Pkt->Cmd, "LIST", 4) == 0)) + // MLSD対応 +// if((strncmp(Pkt->Cmd, "NLST", 4) == 0) || (strncmp(Pkt->Cmd, "LIST", 4) == 0)) + if((strncmp(Pkt->Cmd, "NLST", 4) == 0) || (strncmp(Pkt->Cmd, "LIST", 4) == 0) || (strncmp(Pkt->Cmd, "MLSD", 4) == 0)) { SetTaskMsg(MSGJPN097); strcpy(Fname, MSGJPN098); @@ -2007,19 +2413,42 @@ static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode) { // 全て中止を選択後にダイアログが表示されるバグ対策 // if(DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Fname) == NO) - if(Canceled[Pkt->ThreadCount] == NO && ClearAll == NO && DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Fname) == NO) - ClearAll = YES; + // 再転送対応 +// if(Canceled[Pkt->ThreadCount] == NO && ClearAll == NO && DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Fname) == NO) +// ClearAll = YES; + if(Canceled[Pkt->ThreadCount] == NO && ClearAll == NO) + { + if(strncmp(Pkt->Cmd, "RETR", 4) == 0 || strncmp(Pkt->Cmd, "STOR", 4) == 0) + { + // タスクバー進捗表示 + TransferErrorDisplay++; + if(TransferErrorNotify == YES && DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Pkt) == NO) + ClearAll = YES; + else + { + Pkt->Mode = TransferErrorMode; + AddTransFileList(Pkt); + } + // タスクバー進捗表示 + TransferErrorDisplay--; + } + } } } else { - if((strncmp(Pkt->Cmd, "NLST", 4) == 0) || (strncmp(Pkt->Cmd, "LIST", 4) == 0)) + // MLSD対応 +// if((strncmp(Pkt->Cmd, "NLST", 4) == 0) || (strncmp(Pkt->Cmd, "LIST", 4) == 0)) + if((strncmp(Pkt->Cmd, "NLST", 4) == 0) || (strncmp(Pkt->Cmd, "LIST", 4) == 0) || (strncmp(Pkt->Cmd, "MLSD", 4) == 0)) SetTaskMsg(MSGJPN101, Pkt->ExistSize); // 同時接続対応 // else if((Pkt->hWndTrans != NULL) && (TimeStart != 0)) // SetTaskMsg(MSGJPN102, TimeStart, Pkt->ExistSize/TimeStart); else if((Pkt->hWndTrans != NULL) && (TimeStart[Pkt->ThreadCount] != 0)) - SetTaskMsg(MSGJPN102, TimeStart[Pkt->ThreadCount], Pkt->ExistSize/TimeStart[Pkt->ThreadCount]); + // "0 B/S"と表示されるバグを修正 + // 原因は%dにあたる部分に64ビット値が渡されているため +// SetTaskMsg(MSGJPN102, TimeStart[Pkt->ThreadCount], Pkt->ExistSize/TimeStart[Pkt->ThreadCount]); + SetTaskMsg(MSGJPN102, (LONG)TimeStart[Pkt->ThreadCount], (LONG)(Pkt->ExistSize/TimeStart[Pkt->ThreadCount])); else SetTaskMsg(MSGJPN103, Pkt->ExistSize); } @@ -2039,13 +2468,17 @@ static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode) * int ステータス (YES=中止/NO=全て中止) *----------------------------------------------------------------------------*/ -static int DispUpDownErrDialog(int ResID, HWND hWnd, char *Fname) +// 再転送対応 +//static int DispUpDownErrDialog(int ResID, HWND hWnd, char *Fname) +static int DispUpDownErrDialog(int ResID, HWND hWnd, TRANSPACKET *Pkt) { if(hWnd == NULL) hWnd = GetMainHwnd(); SoundPlay(SND_ERROR); - return(DialogBoxParam(GetFtpInst(), MAKEINTRESOURCE(ResID), hWnd, UpDownErrorDialogProc, (LPARAM)Fname)); + // 再転送対応 +// return(DialogBoxParam(GetFtpInst(), MAKEINTRESOURCE(ResID), hWnd, UpDownErrorDialogProc, (LPARAM)Fname)); + return(DialogBoxParam(GetFtpInst(), MAKEINTRESOURCE(ResID), hWnd, UpDownErrorDialogProc, (LPARAM)Pkt)); } @@ -2061,29 +2494,57 @@ static int DispUpDownErrDialog(int ResID, HWND hWnd, char *Fname) * BOOL TRUE/FALSE *----------------------------------------------------------------------------*/ -static BOOL CALLBACK UpDownErrorDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +// 64ビット対応 +//static BOOL CALLBACK UpDownErrorDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK UpDownErrorDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + static TRANSPACKET *Pkt; + static const RADIOBUTTON DownExistButton[] = { + { DOWN_EXIST_OVW, EXIST_OVW }, + { DOWN_EXIST_RESUME, EXIST_RESUME }, + { DOWN_EXIST_IGNORE, EXIST_IGNORE } + }; + #define DOWNEXISTBUTTONS (sizeof(DownExistButton)/sizeof(RADIOBUTTON)) + switch (message) { case WM_INITDIALOG : - SendDlgItemMessage(hDlg, UPDOWN_ERR_FNAME, WM_SETTEXT, 0, (LPARAM)lParam); - SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)ErrMsg); + Pkt = (TRANSPACKET *)lParam; +// SendDlgItemMessage(hDlg, UPDOWN_ERR_FNAME, WM_SETTEXT, 0, (LPARAM)lParam); + SendDlgItemMessage(hDlg, UPDOWN_ERR_FNAME, WM_SETTEXT, 0, (LPARAM)Pkt->RemoteFile); + // 同時接続対応 +// SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)ErrMsg); + SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)GetErrMsg()); + + if((Pkt->Type == TYPE_A) || (Pkt->ExistSize <= 0)) + EnableWindow(GetDlgItem(hDlg, DOWN_EXIST_RESUME), FALSE); + + SetRadioButtonByValue(hDlg, TransferErrorMode, DownExistButton, DOWNEXISTBUTTONS); return(TRUE); case WM_COMMAND : switch(GET_WM_COMMAND_ID(wParam, lParam)) { + case IDOK_ALL : + TransferErrorNotify = NO; + /* ここに break はない */ + case IDOK : + TransferErrorMode = AskRadioButtonValue(hDlg, DownExistButton, DOWNEXISTBUTTONS); EndDialog(hDlg, YES); break; case IDCANCEL : EndDialog(hDlg, NO); break; + + case IDHELP : +// hHelpWin = HtmlHelp(NULL, AskHelpFilePath(), HH_HELP_CONTEXT, IDH_HELP_TOPIC_0000009); + break; } - return(TRUE); + return(TRUE); } - return(FALSE); + return(FALSE); } @@ -2151,7 +2612,9 @@ static int SetDownloadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int * BOOL TRUE/FALSE *----------------------------------------------------------------------------*/ -static BOOL CALLBACK NoResumeWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) +// 64ビット対応 +//static BOOL CALLBACK NoResumeWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK NoResumeWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) { switch (iMessage) { @@ -2190,7 +2653,7 @@ static BOOL CALLBACK NoResumeWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LP * int 応答コード *----------------------------------------------------------------------------*/ -static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt) +static int DoUpload(SOCKET cSkt, TRANSPACKET *Pkt) { int iRetCode; char Reply[ERR_MSG_LEN+7]; @@ -2218,9 +2681,9 @@ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt) if(BackgrndMessageProc() == NO) { if(AskPasvMode() != YES) - iRetCode = UpLoadNonPassive(Pkt); + iRetCode = UploadNonPassive(Pkt); else - iRetCode = UpLoadPassive(Pkt); + iRetCode = UploadPassive(Pkt); } else iRetCode = 500; @@ -2240,8 +2703,11 @@ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt) SetTaskMsg(MSGJPN105, Pkt->LocalFile); iRetCode = 500; Pkt->Abort = ABORT_ERROR; - DispUploadFinishMsg(Pkt, iRetCode); + // エラーによってはダイアログが表示されない場合があるバグ対策 +// DispUploadFinishMsg(Pkt, iRetCode); } + // エラーによってはダイアログが表示されない場合があるバグ対策 + DispUploadFinishMsg(Pkt, iRetCode); } else { @@ -2262,14 +2728,21 @@ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt) * int 応答コード *----------------------------------------------------------------------------*/ -static int UpLoadNonPassive(TRANSPACKET *Pkt) +static int UploadNonPassive(TRANSPACKET *Pkt) { int iRetCode; int iLength; SOCKET data_socket = INVALID_SOCKET; // data channel socket SOCKET listen_socket = INVALID_SOCKET; // data listen socket - char Buf[1024]; - struct sockaddr_in saSockAddr1; + // 念のため +// char Buf[1024]; + char Buf[FMAX_PATH+1024]; + // IPv6対応 +// struct sockaddr_in saSockAddr1; + struct sockaddr_in saSockAddrIPv4; + struct sockaddr_in6 saSockAddrIPv6; + // UPnP対応 + int Port; int Resume; char Reply[ERR_MSG_LEN+7]; @@ -2279,6 +2752,16 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) { SetUploadResume(Pkt, Pkt->Mode, Pkt->ExistSize, &Resume); if(Resume == NO) +#if defined(HAVE_TANDEM) + if(AskHostType() == HTYPE_TANDEM && AskOSS() == NO && Pkt->Type != TYPE_A) { + if( Pkt->PriExt == DEF_PRIEXT && Pkt->SecExt == DEF_SECEXT && Pkt->MaxExt == DEF_MAXEXT) { + // EXTENTがデフォルトのときはコードのみ + sprintf(Buf, "%s%s,%d", Pkt->Cmd, Pkt->RemoteFile, Pkt->FileCode); + } else { + sprintf(Buf, "%s%s,%d,%d,%d,%d", Pkt->Cmd, Pkt->RemoteFile, Pkt->FileCode, Pkt->PriExt, Pkt->SecExt, Pkt->MaxExt); + } + } else +#endif sprintf(Buf, "%s%s", Pkt->Cmd, Pkt->RemoteFile); else sprintf(Buf, "%s%s", "APPE ", Pkt->RemoteFile); @@ -2288,13 +2771,37 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "%s", Buf); if((iRetCode/100) == FTP_PRELIM) { - if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL) + // STOUの応答を処理 + // 応答の形式に規格が無くファイル名を取得できないため属性変更を無効化 + if(Pkt->Mode == EXIST_UNIQUE) + Pkt->Attr = -1; + // 同時接続対応 +// if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL) + if(SocksGet2ndBindReply(listen_socket, &data_socket, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL) { - iLength=sizeof(saSockAddr1); - data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddr1, (int *)&iLength); + // IPv6対応 +// iLength=sizeof(saSockAddr1); +// data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddr1, (int *)&iLength); + switch(AskCurNetType()) + { + case NTYPE_IPV4: + iLength=sizeof(saSockAddrIPv4); + data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddrIPv4, (int *)&iLength); + break; + case NTYPE_IPV6: + iLength=sizeof(saSockAddrIPv6); + data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddrIPv6, (int *)&iLength); + break; + } if(shutdown(listen_socket, 1) != 0) ReportWSError("shutdown listen", WSAGetLastError()); + // UPnP対応 + if(IsUPnPLoaded() == YES) + { + if(GetAsyncTableDataMapPort(listen_socket, &Port) == YES) + RemovePortMapping(Port); + } listen_socket = DoClose(listen_socket); if(data_socket == INVALID_SOCKET) @@ -2304,7 +2811,19 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) iRetCode = 500; } else - DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port)); + // IPv6対応 +// DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port)); + { + switch(AskCurNetType()) + { + case NTYPE_IPV4: + DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddrIPv4.sin_addr), ntohs(saSockAddrIPv4.sin_port)); + break; + case NTYPE_IPV6: + DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet6_ntoa(saSockAddrIPv6.sin6_addr), ntohs(saSockAddrIPv6.sin6_port)); + break; + } + } } if(data_socket != INVALID_SOCKET) @@ -2312,16 +2831,16 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため ReleaseMutex(hListAccMutex); // FTPS対応 -// iRetCode = UpLoadFile(Pkt, data_socket); - if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) +// iRetCode = UploadFile(Pkt, data_socket); + if(IsSSLAttached(Pkt->ctrl_skt)) { - if(AttachSSL(data_socket)) - iRetCode = UpLoadFile(Pkt, data_socket); + if(AttachSSL(data_socket, Pkt->ctrl_skt, &Canceled[Pkt->ThreadCount], FALSE)) + iRetCode = UploadFile(Pkt, data_socket); else - iRetCode = FTP_ERROR; + iRetCode = 500; } else - iRetCode = UpLoadFile(Pkt, data_socket); + iRetCode = UploadFile(Pkt, data_socket); data_socket = DoClose(data_socket); } } @@ -2329,6 +2848,12 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) { SetErrorMsg(Reply); SetTaskMsg(MSGJPN108); + // UPnP対応 + if(IsUPnPLoaded() == YES) + { + if(GetAsyncTableDataMapPort(listen_socket, &Port) == YES) + RemovePortMapping(Port); + } listen_socket = DoClose(listen_socket); iRetCode = 500; } @@ -2338,7 +2863,8 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) SetErrorMsg(MSGJPN279); iRetCode = 500; } - DispUploadFinishMsg(Pkt, iRetCode); + // エラーによってはダイアログが表示されない場合があるバグ対策 +// DispUploadFinishMsg(Pkt, iRetCode); return(iRetCode); } @@ -2353,12 +2879,16 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) * int 応答コード *----------------------------------------------------------------------------*/ -static int UpLoadPassive(TRANSPACKET *Pkt) +static int UploadPassive(TRANSPACKET *Pkt) { int iRetCode; SOCKET data_socket = INVALID_SOCKET; // data channel socket - char Buf[1024]; - char Adrs[20]; + // 念のため +// char Buf[1024]; + char Buf[FMAX_PATH+1024]; + // IPv6対応 +// char Adrs[20]; + char Adrs[40]; int Port; int Flg; int Resume; @@ -2366,10 +2896,22 @@ static int UpLoadPassive(TRANSPACKET *Pkt) // 同時接続対応 // iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled, "PASV"); - iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "PASV"); + // IPv6対応 +// iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "PASV"); + switch(AskCurNetType()) + { + case NTYPE_IPV4: + iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "PASV"); + break; + case NTYPE_IPV6: + iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "EPSV"); + break; + } if(iRetCode/100 == FTP_COMPLETE) { - if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS) + // IPv6対応 +// if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS) + if(GetAdrsAndPort(Pkt->ctrl_skt, Buf, Adrs, &Port, 39) == FFFTP_SUCCESS) { // 同時接続対応 // if((data_socket = connectsock(Adrs, Port, MSGJPN109, &Canceled)) != INVALID_SOCKET) @@ -2382,6 +2924,16 @@ static int UpLoadPassive(TRANSPACKET *Pkt) SetUploadResume(Pkt, Pkt->Mode, Pkt->ExistSize, &Resume); if(Resume == NO) +#if defined(HAVE_TANDEM) + if(AskHostType() == HTYPE_TANDEM && AskOSS() == NO && Pkt->Type != TYPE_A) { + if( Pkt->PriExt == DEF_PRIEXT && Pkt->SecExt == DEF_SECEXT && Pkt->MaxExt == DEF_MAXEXT) { + // EXTENTがデフォルトのときはコードのみ + sprintf(Buf, "%s%s,%d", Pkt->Cmd, Pkt->RemoteFile, Pkt->FileCode); + } else { + sprintf(Buf, "%s%s,%d,%d,%d,%d", Pkt->Cmd, Pkt->RemoteFile, Pkt->FileCode, Pkt->PriExt, Pkt->SecExt, Pkt->MaxExt); + } + } else +#endif sprintf(Buf, "%s%s", Pkt->Cmd, Pkt->RemoteFile); else sprintf(Buf, "%s%s", "APPE ", Pkt->RemoteFile); @@ -2391,19 +2943,23 @@ static int UpLoadPassive(TRANSPACKET *Pkt) iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "%s", Buf); if(iRetCode/100 == FTP_PRELIM) { + // STOUの応答を処理 + // 応答の形式に規格が無くファイル名を取得できないため属性変更を無効化 + if(Pkt->Mode == EXIST_UNIQUE) + Pkt->Attr = -1; // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため ReleaseMutex(hListAccMutex); // FTPS対応 -// iRetCode = UpLoadFile(Pkt, data_socket); - if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) +// iRetCode = UploadFile(Pkt, data_socket); + if(IsSSLAttached(Pkt->ctrl_skt)) { - if(AttachSSL(data_socket)) - iRetCode = UpLoadFile(Pkt, data_socket); + if(AttachSSL(data_socket, Pkt->ctrl_skt, &Canceled[Pkt->ThreadCount], FALSE)) + iRetCode = UploadFile(Pkt, data_socket); else - iRetCode = FTP_ERROR; + iRetCode = 500; } else - iRetCode = UpLoadFile(Pkt, data_socket); + iRetCode = UploadFile(Pkt, data_socket); data_socket = DoClose(data_socket); } @@ -2431,7 +2987,8 @@ static int UpLoadPassive(TRANSPACKET *Pkt) else SetErrorMsg(Buf); - DispUploadFinishMsg(Pkt, iRetCode); + // エラーによってはダイアログが表示されない場合があるバグ対策 +// DispUploadFinishMsg(Pkt, iRetCode); return(iRetCode); } @@ -2451,7 +3008,7 @@ static int UpLoadPassive(TRANSPACKET *Pkt) * 転送ダイアログを出さないでアップロードすることはない *----------------------------------------------------------------------------*/ -static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) +static int UploadFile(TRANSPACKET *Pkt, SOCKET dSkt) { DWORD iNumBytes; HANDLE iFileHandle; @@ -2581,6 +3138,11 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) cInfo2.OutLen = cInfo.OutLen; break; case KANJI_UTF8N: + Continue = ConvSJIStoUTF8N(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8BOM: if(ProcessedBOM == NO) { memcpy(Buf3, "\xEF\xBB\xBF", 3); @@ -2624,6 +3186,14 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) ConvSJIStoEUC(&cInfo2); break; case KANJI_UTF8N: + Continue = ConvJIStoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + case KANJI_UTF8BOM: if(ProcessedBOM == NO) { memcpy(Buf3, "\xEF\xBB\xBF", 3); @@ -2670,6 +3240,14 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) ConvSJIStoEUC(&cInfo2); break; case KANJI_UTF8N: + Continue = ConvEUCtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + case KANJI_UTF8BOM: if(ProcessedBOM == NO) { memcpy(Buf3, "\xEF\xBB\xBF", 3); @@ -2688,6 +3266,50 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) } break; case KANJI_UTF8N: + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + Continue = ConvUTF8NtoSJIS(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + Continue = ConvUTF8NtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + Continue = ConvUTF8NtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; + case KANJI_UTF8BOM: + if(ProcessedBOM == NO) + { + memcpy(Buf3, "\xEF\xBB\xBF", 3); + cInfo2.OutLen = 3; + Continue = YES; + ProcessedBOM = YES; + break; + } + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; + } + break; + case KANJI_UTF8BOM: if(ProcessedBOM == NO) { if(memcmp(Buf, "\xEF\xBB\xBF", 3) == 0) @@ -2698,7 +3320,7 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) cInfo2.OutLen = 0; switch(Pkt->KanjiCode) { - case KANJI_UTF8N: + case KANJI_UTF8BOM: memcpy(Buf3, "\xEF\xBB\xBF", 3); cInfo2.OutLen = 3; break; @@ -2735,12 +3357,17 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) cInfo2.OutLen = cInfo.StrLen; Continue = NO; break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; } break; } // if(TermCodeConvAndSend(&tInfo, dSkt, Buf2, cInfo.OutLen, Pkt->Type) == FFFTP_FAIL) - if(TermCodeConvAndSend(Pkt->ThreadCount, &tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type) == FFFTP_FAIL) + if(TermCodeConvAndSend(&tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL) { Pkt->Abort = ABORT_ERROR; break; @@ -2752,7 +3379,7 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) { // 同時接続対応 // if(TermCodeConvAndSend(&tInfo, dSkt, Buf, iNumBytes, Pkt->Type) == FFFTP_FAIL) - if(TermCodeConvAndSend(Pkt->ThreadCount, &tInfo, dSkt, Buf, iNumBytes, Pkt->Type) == FFFTP_FAIL) + if(TermCodeConvAndSend(&tInfo, dSkt, Buf, iNumBytes, Pkt->Type, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL) Pkt->Abort = ABORT_ERROR; } @@ -2802,6 +3429,10 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) memcpy(Buf3, cInfo.Buf, cInfo.OutLen); cInfo2.OutLen = cInfo.OutLen; break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; } break; case KANJI_JIS: @@ -2833,6 +3464,13 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) cInfo2.BufSize = (BUFSIZE + 3) * 4; ConvSJIStoUTF8N(&cInfo2); break; + case KANJI_UTF8BOM: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; } break; case KANJI_EUC: @@ -2864,6 +3502,13 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) cInfo2.BufSize = (BUFSIZE + 3) * 4; ConvSJIStoUTF8N(&cInfo2); break; + case KANJI_UTF8BOM: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; } break; case KANJI_UTF8N: @@ -2891,17 +3536,52 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) memcpy(Buf3, cInfo.Buf, cInfo.OutLen); cInfo2.OutLen = cInfo.OutLen; break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + } + break; + case KANJI_UTF8BOM: + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; } break; } // if(TermCodeConvAndSend(&tInfo, dSkt, Buf2, cInfo.OutLen, Pkt->Type) == FFFTP_FAIL) - if(TermCodeConvAndSend(Pkt->ThreadCount, &tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type) == FFFTP_FAIL) + if(TermCodeConvAndSend(&tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL) Pkt->Abort = ABORT_ERROR; cInfo2.Buf = Buf3; cInfo2.BufSize = (BUFSIZE + 3) * 4; FlushRestData(&cInfo2); - if(TermCodeConvAndSend(Pkt->ThreadCount, &tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type) == FFFTP_FAIL) + if(TermCodeConvAndSend(&tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL) Pkt->Abort = ABORT_ERROR; } @@ -2932,6 +3612,8 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) Pkt->Abort = ABORT_ERROR; } + // 自動切断対策 + LastDataConnectionTime = time(NULL); if(shutdown(dSkt, 1) != 0) ReportWSError("shutdown", WSAGetLastError()); @@ -2948,7 +3630,9 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) //#pragma aaa //DoPrintf("##UP REPLY : %s", Buf); - if(iRetCode >= FTP_RETRY) + // バグ修正 +// if(iRetCode >= FTP_RETRY) + if((iRetCode/100) >= FTP_RETRY) SetErrorMsg(Buf); if(Pkt->Abort != ABORT_NONE) @@ -2973,7 +3657,7 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) // 同時接続対応 //static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii) -static int TermCodeConvAndSend(int ThreadCount, TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii) +static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii, int *CancelCheckWork) { char Buf3[BUFSIZE*2]; int Continue; @@ -2993,7 +3677,7 @@ static int TermCodeConvAndSend(int ThreadCount, TERMCODECONVINFO *tInfo, SOCKET Continue = ConvTermCodeToCRLF(tInfo); // 同時接続対応 // if((Ret = SendData(Skt, Buf3, tInfo->OutLen, 0, &Canceled)) == FFFTP_FAIL) - if((Ret = SendData(Skt, Buf3, tInfo->OutLen, 0, &Canceled[ThreadCount])) == FFFTP_FAIL) + if((Ret = SendData(Skt, Buf3, tInfo->OutLen, 0, CancelCheckWork)) == FFFTP_FAIL) break; } while(Continue == YES); @@ -3001,7 +3685,7 @@ static int TermCodeConvAndSend(int ThreadCount, TERMCODECONVINFO *tInfo, SOCKET else // 同時接続対応 // Ret = SendData(Skt, Data, Size, 0, &Canceled); - Ret = SendData(Skt, Data, Size, 0, &Canceled[ThreadCount]); + Ret = SendData(Skt, Data, Size, 0, CancelCheckWork); return(Ret); } @@ -3019,6 +3703,8 @@ static int TermCodeConvAndSend(int ThreadCount, TERMCODECONVINFO *tInfo, SOCKET static void DispUploadFinishMsg(TRANSPACKET *Pkt, int iRetCode) { + // 同時接続対応 + ReleaseMutex(hListAccMutex); if(ForceAbort == NO) { if((iRetCode/100) >= FTP_CONTINUE) @@ -3035,8 +3721,26 @@ static void DispUploadFinishMsg(TRANSPACKET *Pkt, int iRetCode) { // 全て中止を選択後にダイアログが表示されるバグ対策 // if(DispUpDownErrDialog(uperr_dlg, Pkt->hWndTrans, Pkt->LocalFile) == NO) - if(Canceled[Pkt->ThreadCount] == NO && ClearAll == NO && DispUpDownErrDialog(uperr_dlg, Pkt->hWndTrans, Pkt->LocalFile) == NO) - ClearAll = YES; + // 再転送対応 +// if(Canceled[Pkt->ThreadCount] == NO && ClearAll == NO && DispUpDownErrDialog(uperr_dlg, Pkt->hWndTrans, Pkt->LocalFile) == NO) +// ClearAll = YES; + if(Canceled[Pkt->ThreadCount] == NO && ClearAll == NO) + { + if(strncmp(Pkt->Cmd, "RETR", 4) == 0 || strncmp(Pkt->Cmd, "STOR", 4) == 0) + { + // タスクバー進捗表示 + TransferErrorDisplay++; + if(TransferErrorNotify == YES && DispUpDownErrDialog(uperr_dlg, Pkt->hWndTrans, Pkt) == NO) + ClearAll = YES; + else + { + Pkt->Mode = TransferErrorMode; + AddTransFileList(Pkt); + } + // タスクバー進捗表示 + TransferErrorDisplay--; + } + } } } else @@ -3142,7 +3846,9 @@ static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM /* ここに break はない */ case IDCANCEL : - if(!(Pkt = (TRANSPACKET*)GetWindowLong(hDlg, GWL_USERDATA))) + // 64ビット対応 +// if(!(Pkt = (TRANSPACKET*)GetWindowLong(hDlg, GWL_USERDATA))) + if(!(Pkt = (TRANSPACKET*)GetWindowLongPtr(hDlg, GWLP_USERDATA))) break; Pkt->Abort = ABORT_USER; // Canceled = YES; @@ -3158,10 +3864,10 @@ static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM SetForegroundWindow(hDlg); MoveToForeground = NO; KillTimer(hDlg, TIMER_DISPLAY); - if(!(Pkt = (TRANSPACKET*)GetWindowLong(hDlg, GWL_USERDATA))) + // 64ビット対応 +// if(!(Pkt = (TRANSPACKET*)GetWindowLong(hDlg, GWL_USERDATA))) + if(!(Pkt = (TRANSPACKET*)GetWindowLongPtr(hDlg, GWLP_USERDATA))) break; - if(Canceled[Pkt->ThreadCount] == YES) - Pkt->Abort = ABORT_USER; DispTransferStatus(hDlg, NO, Pkt); SetTimer(hDlg, TIMER_DISPLAY, DISPLAY_TIMING, NULL); } @@ -3169,7 +3875,9 @@ static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM case WM_SET_PACKET : // Pkt = (TRANSPACKET *)lParam; - SetWindowLong(hDlg, GWL_USERDATA, (LONG)lParam); + // 64ビット対応 +// SetWindowLong(hDlg, GWL_USERDATA, (LONG)lParam); + SetWindowLongPtr(hDlg, GWLP_USERDATA, (LONG_PTR)lParam); break; } return(FALSE); @@ -3316,6 +4024,8 @@ static void DispTransFileInfo(TRANSPACKET *Pkt, char *Title, int SkipButton, int SendDlgItemMessage(Pkt->hWndTrans, TRANS_KANJI, WM_SETTEXT, 0, (LPARAM)MSGJPN123); else if(Pkt->KanjiCode == KANJI_UTF8N) SendDlgItemMessage(Pkt->hWndTrans, TRANS_KANJI, WM_SETTEXT, 0, (LPARAM)MSGJPN306); + else if(Pkt->KanjiCode == KANJI_UTF8BOM) + SendDlgItemMessage(Pkt->hWndTrans, TRANS_KANJI, WM_SETTEXT, 0, (LPARAM)MSGJPN329); } else { @@ -3342,10 +4052,31 @@ static void DispTransFileInfo(TRANSPACKET *Pkt, char *Title, int SkipButton, int * FFFTP_SUCCESS/FFFTP_FAIL *----------------------------------------------------------------------------*/ -static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max) +static int GetAdrsAndPort(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max) +{ + int Result; + Result = FFFTP_FAIL; + switch(AskCurNetType()) + { + case NTYPE_IPV4: + Result = GetAdrsAndPortIPv4(Skt, Str, Adrs, Port, Max); + break; + case NTYPE_IPV6: + Result = GetAdrsAndPortIPv6(Skt, Str, Adrs, Port, Max); + break; + } + return Result; +} + + +// IPv6対応 +//static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max) +static int GetAdrsAndPortIPv4(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max) { char *Pos; char *Btm; + // コンマではなくドットを返すホストがあるため + char *OldBtm; int Sts; Sts = FFFTP_FAIL; @@ -3355,18 +4086,36 @@ static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max) { Pos++; Btm = strchr(Pos, ','); + // コンマではなくドットを返すホストがあるため + if(Btm == NULL) + Btm = strchr(Pos, '.'); if(Btm != NULL) { Btm++; - Btm = strchr(Btm, ','); + // コンマではなくドットを返すホストがあるため +// Btm = strchr(Btm, ','); + OldBtm = Btm; + Btm = strchr(OldBtm, ','); + if(Btm == NULL) + Btm = strchr(OldBtm, '.'); if(Btm != NULL) { Btm++; - Btm = strchr(Btm, ','); + // コンマではなくドットを返すホストがあるため +// Btm = strchr(Btm, ','); + OldBtm = Btm; + Btm = strchr(OldBtm, ','); + if(Btm == NULL) + Btm = strchr(OldBtm, '.'); if(Btm != NULL) { Btm++; - Btm = strchr(Btm, ','); + // コンマではなくドットを返すホストがあるため +// Btm = strchr(Btm, ','); + OldBtm = Btm; + Btm = strchr(OldBtm, ','); + if(Btm == NULL) + Btm = strchr(OldBtm, '.'); if(Btm != NULL) { if((Btm - Pos) <= Max) @@ -3377,6 +4126,9 @@ static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max) Pos = Btm + 1; Btm = strchr(Pos, ','); + // コンマではなくドットを返すホストがあるため + if(Btm == NULL) + Btm = strchr(Pos, '.'); if(Btm != NULL) { Btm++; @@ -3393,6 +4145,66 @@ static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max) } +// IPv6対応 +static int GetAdrsAndPortIPv6(SOCKET Skt, char *Str, char *Adrs, int *Port, int Max) +{ + char *Pos; + char *Btm; + int Sts; +// int i; + struct sockaddr_in6 SockAddr; + + Sts = FFFTP_FAIL; + + Btm = strchr(Str, '('); + if(Btm != NULL) + { + Btm++; + Btm = strchr(Btm, '|'); + if(Btm != NULL) + { + Pos = Btm + 1; + Btm = strchr(Pos, '|'); + if(Btm != NULL) + { + Pos = Btm + 1; + Btm = strchr(Pos, '|'); + if(Btm != NULL) + { + if((Btm - Pos) <= Max) + { + if((Btm - Pos) > 0) + { + strncpy(Adrs, Pos, Btm - Pos); + *(Adrs + (Btm - Pos)) = NUL; + } + else + { +// i = sizeof(SockAddr); +// if(getpeername(Skt, (struct sockaddr*)&SockAddr, &i) != SOCKET_ERROR) + if(GetAsyncTableDataIPv6(Skt, &SockAddr, NULL) == YES) + AddressToStringIPv6(Adrs, &SockAddr.sin6_addr); + } + + Pos = Btm + 1; + Btm = strchr(Pos, '|'); + if(Btm != NULL) + { + Btm++; + *Port = atoi(Pos); + Btm = strchr(Btm, ')'); + if(Btm != NULL) + Sts = FFFTP_SUCCESS; + } + } + } + } + } + } + return(Sts); +} + + /*----- Windowsのスペシャルデバイスかどうかを返す ----------------------------- * * Parameter @@ -3481,7 +4293,9 @@ static int MirrorDelNotify(int Cur, int Notify, TRANSPACKET *Pkt) * BOOL TRUE/FALSE *----------------------------------------------------------------------------*/ -static BOOL CALLBACK MirrorDeleteDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) +// 64ビット対応 +//static BOOL CALLBACK MirrorDeleteDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK MirrorDeleteDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) { static MIRRORDELETEINFO *DelInfo; switch (iMessage) @@ -3534,10 +4348,14 @@ static void SetErrorMsg(char *fmt, ...) { va_list Args; - if(strlen(ErrMsg) == 0) + // 同時接続対応 +// if(strlen(ErrMsg) == 0) + if(strlen(GetErrMsg()) == 0) { va_start(Args, fmt); - wvsprintf(ErrMsg, fmt, Args); + // 同時接続対応 +// wvsprintf(ErrMsg, fmt, Args); + wvsprintf(GetErrMsg(), fmt, Args); va_end(Args); } return; @@ -3579,3 +4397,56 @@ int CheckPathViolation(TRANSPACKET *packet) } +// 同時接続対応 +static char* GetErrMsg() +{ + char* r; + DWORD ThreadId; + int i; + r = NULL; + WaitForSingleObject(hErrMsgMutex, INFINITE); + ThreadId = GetCurrentThreadId(); + i = 0; + while(i < MAX_DATA_CONNECTION + 1) + { + if(ErrMsgThreadId[i] == ThreadId) + { + r = ErrMsg[i]; + break; + } + i++; + } + if(!r) + { + i = 0; + while(i < MAX_DATA_CONNECTION + 1) + { + if(ErrMsgThreadId[i] == 0) + { + ErrMsgThreadId[i] = ThreadId; + r = ErrMsg[i]; + break; + } + i++; + } + } + ReleaseMutex(hErrMsgMutex); + return r; +} + +// タスクバー進捗表示 +LONGLONG AskTransferSizeLeft(void) +{ + return(TransferSizeLeft); +} + +LONGLONG AskTransferSizeTotal(void) +{ + return(TransferSizeTotal); +} + +int AskTransferErrorDisplay(void) +{ + return(TransferErrorDisplay); +} +