X-Git-Url: http://git.sourceforge.jp/view?p=ffftp%2Fffftp.git;a=blobdiff_plain;f=socket.c;h=db7b69f34feed3c8f30855e4485761c30b5696e5;hp=605abaf2b329ab39f77363dd817fff18a7b7b248;hb=b2a2988febaa229da876d5863ef4bfdf2decc29d;hpb=3efb66ad5ef6a7e965b9b8b23852e826b7302c5f diff --git a/socket.c b/socket.c index 605abaf..db7b69f 100644 --- a/socket.c +++ b/socket.c @@ -1,6 +1,6 @@ -/*============================================================================= +/*============================================================================= * -* ƒ\ƒPƒbƒg +* ソケット * =============================================================================== / Copyright (C) 1997-2007 Sota. All rights reserved. @@ -28,6 +28,8 @@ /============================================================================*/ #define STRICT +// IPv6対応 +#include #include #include #include @@ -45,11 +47,12 @@ -#define FD_CONNECT_BIT 0x0001 -#define FD_CLOSE_BIT 0x0002 -#define FD_ACCEPT_BIT 0x0004 -#define FD_READ_BIT 0x0008 -#define FD_WRITE_BIT 0x0010 +// Winsock2で定義される定数と名前が重複し値が異なるため使用不可 +//#define FD_CONNECT_BIT 0x0001 +//#define FD_CLOSE_BIT 0x0002 +//#define FD_ACCEPT_BIT 0x0004 +//#define FD_READ_BIT 0x0008 +//#define FD_WRITE_BIT 0x0010 @@ -73,17 +76,17 @@ typedef struct { } ASYNCSIGNALDATABASE; -// ƒXƒŒƒbƒhÕ“˂̃oƒOC³ -// ”O‚Ì‚½‚߃e[ƒuƒ‹‚ð‘—Ê +// スレッド衝突のバグ修正 +// 念のためテーブルを増量 //#define MAX_SIGNAL_ENTRY 10 //#define MAX_SIGNAL_ENTRY_DBASE 5 -#define MAX_SIGNAL_ENTRY 100 -#define MAX_SIGNAL_ENTRY_DBASE 50 +#define MAX_SIGNAL_ENTRY 16 +#define MAX_SIGNAL_ENTRY_DBASE 16 -/*===== ƒvƒƒgƒ^ƒCƒv =====*/ +/*===== プロトタイプ =====*/ static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); static int AskAsyncDone(SOCKET s, int *Error, int Mask); @@ -94,12 +97,12 @@ static int UnRegistAsyncTable(SOCKET s); static int UnRegistAsyncTableDbase(HANDLE Async); -/*===== ŠO•”ŽQÆ =====*/ +/*===== 外部参照 =====*/ extern int TimeOut; -/*===== ƒ[ƒJƒ‹‚ȃ[ƒN =====*/ +/*===== ローカルなワーク =====*/ static const char SocketWndClass[] = "FFFTPSocketWnd"; static HWND hWndSocket; @@ -108,7 +111,7 @@ static ASYNCSIGNAL Signal[MAX_SIGNAL_ENTRY]; static ASYNCSIGNALDATABASE SignalDbase[MAX_SIGNAL_ENTRY_DBASE]; //static HANDLE hAsyncTblAccMutex; -// ƒXƒŒƒbƒhÕ“˂̃oƒOC³ +// スレッド衝突のバグ修正 static HANDLE hAsyncTblAccMutex; @@ -120,8 +123,8 @@ static HANDLE hAsyncTblAccMutex; * Parameter * * Return Value -* int ƒXƒe[ƒ^ƒX -* SUCCESS/FAIL +* int ステータス +* FFFTP_SUCCESS/FFFTP_FAIL *----------------------------------------------------------------------------*/ int MakeSocketWin(HWND hWnd, HINSTANCE hInst) @@ -144,7 +147,7 @@ int MakeSocketWin(HWND hWnd, HINSTANCE hInst) wClass.hIconSm = NULL; RegisterClassEx(&wClass); - Sts = FAIL; + Sts = FFFTP_FAIL; hWndSocket = CreateWindowEx(0, SocketWndClass, NULL, WS_BORDER | WS_POPUP, 0, 0, 0, 0, @@ -154,7 +157,7 @@ int MakeSocketWin(HWND hWnd, HINSTANCE hInst) { // hAsyncTblAccMutex = CreateMutex(NULL, FALSE, NULL); - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 // for(i = 0; i < MAX_SIGNAL_ENTRY; i++) // Signal[i].Socket = INVALID_SOCKET; // for(i = 0; i < MAX_SIGNAL_ENTRY_DBASE; i++) @@ -166,7 +169,7 @@ int MakeSocketWin(HWND hWnd, HINSTANCE hInst) for(i = 0; i < MAX_SIGNAL_ENTRY_DBASE; i++) SignalDbase[i].Async = 0; } - Sts = SUCCESS; + Sts = FFFTP_SUCCESS; } return(Sts); } @@ -175,16 +178,16 @@ int MakeSocketWin(HWND hWnd, HINSTANCE hInst) /*----- * * Parameter -* ‚È‚µ +* なし * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ void DeleteSocketWin(void) { // CloseHandle(hAsyncTblAccMutex); - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 CloseHandle(hAsyncTblAccMutex); hAsyncTblAccMutex = NULL; @@ -197,10 +200,10 @@ void DeleteSocketWin(void) /*----- * * Parameter -* HWND hWnd : ƒEƒCƒ“ƒhƒEƒnƒ“ƒhƒ‹ -* UINT message : ƒƒbƒZ[ƒW”ԍ† -* WPARAM wParam : ƒƒbƒZ[ƒW‚Ì WPARAM ˆø” -* LPARAM lParam : ƒƒbƒZ[ƒW‚Ì LPARAM ˆø” +* HWND hWnd : ウインドウハンドル +* UINT message : メッセージ番号 +* WPARAM wParam : メッセージの WPARAM 引数 +* LPARAM lParam : メッセージの LPARAM 引数 * * Return Value * BOOL TRUE/FALSE @@ -213,7 +216,7 @@ static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LP switch(message) { case WM_ASYNC_SOCKET : - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 WaitForSingleObject(hAsyncTblAccMutex, INFINITE); for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) { @@ -266,12 +269,14 @@ static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LP break; } } - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 ReleaseMutex(hAsyncTblAccMutex); break; case WM_ASYNC_DBASE : - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // APIの仕様上ハンドルが登録される前にウィンドウメッセージが呼び出される可能性あり + RegistAsyncTableDbase((HANDLE)wParam); + // スレッド衝突のバグ修正 WaitForSingleObject(hAsyncTblAccMutex, INFINITE); for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++) { @@ -291,7 +296,7 @@ static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LP break; } } - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 ReleaseMutex(hAsyncTblAccMutex); break; @@ -318,7 +323,7 @@ static int AskAsyncDone(SOCKET s, int *Error, int Mask) int Sts; int Pos; - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 WaitForSingleObject(hAsyncTblAccMutex, INFINITE); Sts = NO; *Error = 0; @@ -329,22 +334,22 @@ static int AskAsyncDone(SOCKET s, int *Error, int Mask) *Error = Signal[Pos].Error; if(Signal[Pos].Error != 0) Sts = YES; - if((Mask & FD_CONNECT_BIT) && (Signal[Pos].FdConnect != 0)) + if((Mask & FD_CONNECT) && (Signal[Pos].FdConnect != 0)) { Sts = YES; #if DBG_MSG DoPrintf("### Ask: connect (Sts=%d, Error=%d)", Sts, *Error); #endif } - if((Mask & FD_CLOSE_BIT) && (Signal[Pos].FdClose != 0)) -// if(Mask & FD_CLOSE_BIT) + if((Mask & FD_CLOSE) && (Signal[Pos].FdClose != 0)) +// if(Mask & FD_CLOSE) { Sts = YES; #if DBG_MSG DoPrintf("### Ask: close (Sts=%d, Error=%d)", Sts, *Error); #endif } - if((Mask & FD_ACCEPT_BIT) && (Signal[Pos].FdAccept != 0)) + if((Mask & FD_ACCEPT) && (Signal[Pos].FdAccept != 0)) { Signal[Pos].FdAccept = 0; Sts = YES; @@ -352,7 +357,7 @@ static int AskAsyncDone(SOCKET s, int *Error, int Mask) DoPrintf("### Ask: accept (Sts=%d, Error=%d)", Sts, *Error); #endif } - if((Mask & FD_READ_BIT) && (Signal[Pos].FdRead != 0)) + if((Mask & FD_READ) && (Signal[Pos].FdRead != 0)) { Signal[Pos].FdRead = 0; Sts = YES; @@ -360,7 +365,7 @@ static int AskAsyncDone(SOCKET s, int *Error, int Mask) DoPrintf("### Ask: read (Sts=%d, Error=%d)", Sts, *Error); #endif } - if((Mask & FD_WRITE_BIT) && (Signal[Pos].FdWrite != 0)) + if((Mask & FD_WRITE) && (Signal[Pos].FdWrite != 0)) { Signal[Pos].FdWrite = 0; Sts = YES; @@ -371,12 +376,12 @@ static int AskAsyncDone(SOCKET s, int *Error, int Mask) break; } } - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 ReleaseMutex(hAsyncTblAccMutex); if(Pos == MAX_SIGNAL_ENTRY) { - if(Mask & FD_CLOSE_BIT) + if(Mask & FD_CLOSE) { Sts = YES; } @@ -404,7 +409,7 @@ static int AskAsyncDoneDbase(HANDLE Async, int *Error) int Sts; int Pos; - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 WaitForSingleObject(hAsyncTblAccMutex, INFINITE); Sts = NO; *Error = 0; @@ -423,7 +428,7 @@ static int AskAsyncDoneDbase(HANDLE Async, int *Error) break; } } - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 ReleaseMutex(hAsyncTblAccMutex); if(Pos == MAX_SIGNAL_ENTRY_DBASE) @@ -450,23 +455,25 @@ static int RegistAsyncTable(SOCKET s) int Sts; int Pos; - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 WaitForSingleObject(hAsyncTblAccMutex, INFINITE); Sts = NO; for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) { if(Signal[Pos].Socket == s) { - MessageBox(GetMainHwnd(), "Async socket already registerd.", "FFFTP inner error", MB_OK); - break; + // 強制的に閉じられたソケットがあると重複する可能性あり +// MessageBox(GetMainHwnd(), "Async socket already registerd.", "FFFTP inner error", MB_OK); +// break; + Signal[Pos].Socket = INVALID_SOCKET; } } - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 ReleaseMutex(hAsyncTblAccMutex); if(Pos == MAX_SIGNAL_ENTRY) { - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 WaitForSingleObject(hAsyncTblAccMutex, INFINITE); for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) { @@ -486,7 +493,7 @@ static int RegistAsyncTable(SOCKET s) break; } } - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 ReleaseMutex(hAsyncTblAccMutex); if(Pos == MAX_SIGNAL_ENTRY) @@ -514,23 +521,25 @@ static int RegistAsyncTableDbase(HANDLE Async) int Sts; int Pos; - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 WaitForSingleObject(hAsyncTblAccMutex, INFINITE); Sts = NO; for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++) { if(SignalDbase[Pos].Async == Async) { - MessageBox(GetMainHwnd(), "Async handle already registerd.", "FFFTP inner error", MB_OK); + // 強制的に閉じられたハンドルがあると重複する可能性あり +// MessageBox(GetMainHwnd(), "Async handle already registerd.", "FFFTP inner error", MB_OK); + // APIの仕様上ハンドルが登録される前にウィンドウメッセージが呼び出される可能性あり break; } } - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 ReleaseMutex(hAsyncTblAccMutex); if(Pos == MAX_SIGNAL_ENTRY_DBASE) { - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 WaitForSingleObject(hAsyncTblAccMutex, INFINITE); for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) { @@ -546,7 +555,7 @@ static int RegistAsyncTableDbase(HANDLE Async) break; } } - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 ReleaseMutex(hAsyncTblAccMutex); if(Pos == MAX_SIGNAL_ENTRY_DBASE) @@ -574,7 +583,7 @@ static int UnRegistAsyncTable(SOCKET s) int Sts; int Pos; - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 WaitForSingleObject(hAsyncTblAccMutex, INFINITE); Sts = NO; for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) @@ -589,7 +598,7 @@ static int UnRegistAsyncTable(SOCKET s) break; } } - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 ReleaseMutex(hAsyncTblAccMutex); return(Sts); } @@ -609,7 +618,7 @@ static int UnRegistAsyncTableDbase(HANDLE Async) int Sts; int Pos; - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 WaitForSingleObject(hAsyncTblAccMutex, INFINITE); Sts = NO; for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++) @@ -624,7 +633,7 @@ static int UnRegistAsyncTableDbase(HANDLE Async) break; } } - // ƒXƒŒƒbƒhÕ“˂̃oƒOC³ + // スレッド衝突のバグ修正 ReleaseMutex(hAsyncTblAccMutex); return(Sts); } @@ -636,7 +645,9 @@ static int UnRegistAsyncTableDbase(HANDLE Async) -struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork) +// IPv6対応 +//struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork) +struct hostent *do_gethostbynameIPv4(const char *Name, char *Buf, int Len, int *CancelCheckWork) { #if USE_THIS struct hostent *Ret; @@ -647,9 +658,56 @@ struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *Canc DoPrintf("# Start gethostbyname"); #endif Ret = NULL; - *CancelCheckWork = NO; + // 同時接続対応 +// *CancelCheckWork = NO; - hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len); + // UTF-8対応 +// hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len); + hAsync = WSAAsyncGetHostByNameM(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len); + if(hAsync != NULL) + { + RegistAsyncTableDbase(hAsync); + while((*CancelCheckWork == NO) && (AskAsyncDoneDbase(hAsync, &Error) != YES)) + { + Sleep(1); + if(BackgrndMessageProc() == YES) + *CancelCheckWork = YES; + } + + if(*CancelCheckWork == YES) + { + WSACancelAsyncRequest(hAsync); + } + else if(Error == 0) + { + Ret = (struct hostent *)Buf; + } + UnRegistAsyncTableDbase(hAsync); + } + return(Ret); +#else + return(gethostbyname(Name)); +#endif +} + + +struct hostent *do_gethostbynameIPv6(const char *Name, char *Buf, int Len, int *CancelCheckWork) +{ +#if USE_THIS + struct hostent *Ret; + HANDLE hAsync; + int Error; + +#if DBG_MSG + DoPrintf("# Start gethostbyname"); +#endif + Ret = NULL; + // 同時接続対応 +// *CancelCheckWork = NO; + + // UTF-8対応 +// hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len); + hAsync = WSAAsyncGetHostByNameIPv6M(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len, AF_INET6); if(hAsync != NULL) { RegistAsyncTableDbase(hAsync); @@ -709,16 +767,16 @@ int do_closesocket(SOCKET s) #endif CancelCheckWork = NO; - // FTPS‘Ήž + // スレッド衝突のバグ修正 + WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0); + UnRegistAsyncTable(s); + // FTPS対応 // Ret = closesocket(s); - if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) - Ret = closesocketS(s); - else - Ret = closesocket(s); + Ret = FTPS_closesocket(s); if(Ret == SOCKET_ERROR) { Error = 0; - while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CLOSE_BIT) != YES)) + while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CLOSE) != YES)) { Sleep(1); if(BackgrndMessageProc() == YES) @@ -729,10 +787,12 @@ int do_closesocket(SOCKET s) Ret = 0; } - WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0); + // スレッド衝突のバグ修正 +// WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0); if(BackgrndMessageProc() == YES) CancelCheckWork = YES; - UnRegistAsyncTable(s); + // スレッド衝突のバグ修正 +// UnRegistAsyncTable(s); #if DBG_MSG DoPrintf("# Exit close"); @@ -757,26 +817,24 @@ int do_connect(SOCKET s, const struct sockaddr *name, int namelen, int *CancelCh #if DBG_MSG DoPrintf("# Start connect (S=%x)", s); #endif - *CancelCheckWork = NO; + // 同時接続対応 +// *CancelCheckWork = NO; #if DBG_MSG DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE"); #endif - Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE); + // 高速化のためFD_READとFD_WRITEを使用しない +// Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE); + Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT); if(Ret != SOCKET_ERROR) { - // FTPS‘Ήž -// Ret = connect(s, name, namelen); - if(AskCryptMode() == CRYPT_FTPIS) - Ret = connectS(s, name, namelen); - else - Ret = connect(s, name, namelen); + Ret = connect(s, name, namelen); if(Ret == SOCKET_ERROR) { do { Error = 0; - while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CONNECT_BIT) != YES)) + while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CONNECT) != YES)) { Sleep(1); if(BackgrndMessageProc() == YES) @@ -848,9 +906,9 @@ SOCKET do_accept(SOCKET s, struct sockaddr *addr, int *addrlen) Ret2 = INVALID_SOCKET; Error = 0; - while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_ACCEPT_BIT) != YES)) + while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_ACCEPT) != YES)) { - if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES) + if(AskAsyncDone(s, &Error, FD_CLOSE) == YES) { Error = 1; break; @@ -864,12 +922,7 @@ SOCKET do_accept(SOCKET s, struct sockaddr *addr, int *addrlen) { do { - // FTPS‘Ήž -// Ret2 = accept(s, addr, addrlen); - if(AskCryptMode() == CRYPT_FTPIS) - Ret2 = acceptS(s, addr, addrlen); - else - Ret2 = accept(s, addr, addrlen); + Ret2 = accept(s, addr, addrlen); if(Ret2 != INVALID_SOCKET) { #if DBG_MSG @@ -904,20 +957,20 @@ SOCKET do_accept(SOCKET s, struct sockaddr *addr, int *addrlen) -/*----- recv‘Š“–‚̊֐” -------------------------------------------------------- +/*----- recv相当の関数 -------------------------------------------------------- * * Parameter -* SOCKET s : ƒ\ƒPƒbƒg -* char *buf : ƒf[ƒ^‚ð“ǂݍž‚Þƒoƒbƒtƒ@ -* int len : ’·‚³ -* int flags : recv‚É—^‚¦‚éƒtƒ‰ƒO -* int *TimeOutErr : ƒ^ƒCƒ€ƒAƒEƒg‚µ‚½‚©‚Ç‚¤‚©‚ð•Ô‚·ƒ[ƒN +* SOCKET s : ソケット +* char *buf : データを読み込むバッファ +* int len : 長さ +* int flags : recvに与えるフラグ +* int *TimeOutErr : タイムアウトしたかどうかを返すワーク * * Return Value -* int : recv‚Ì–ß‚è’l‚Æ“¯‚¶ +* int : recvの戻り値と同じ * * Note -* ƒ^ƒCƒ€ƒAƒEƒg‚ÌŽž‚Í TimeOut=YESARet=SOCKET_ERROR ‚É‚È‚é +* タイムアウトの時は TimeOut=YES、Ret=SOCKET_ERROR になる *----------------------------------------------------------------------------*/ int do_recv(SOCKET s, char *buf, int len, int flags, int *TimeOutErr, int *CancelCheckWork) { @@ -931,38 +984,40 @@ int do_recv(SOCKET s, char *buf, int len, int flags, int *TimeOutErr, int *Cance DoPrintf("# Start recv (S=%x)", s); #endif *TimeOutErr = NO; - *CancelCheckWork = NO; + // 同時接続対応 +// *CancelCheckWork = NO; Ret = SOCKET_ERROR; Error = 0; if(TimeOut != 0) time(&StartTime); - // FTPS‘Ήž - // OpenSSL‚Å‚ÍŽóMŠm”F‚ÍFD_READ‚ª•¡”‰ñŽóM‚³‚ê‚é‰Â”\«‚ª‚ ‚é -// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES)) - while(AskCryptMode() == CRYPT_NONE && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES)) - { - if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES) - { - Ret = 0; - break; - } - Sleep(1); - if(BackgrndMessageProc() == YES) - *CancelCheckWork = YES; - else if(TimeOut != 0) - { - time(&ElapseTime); - ElapseTime -= StartTime; - if(ElapseTime >= TimeOut) - { - DoPrintf("do_recv timed out"); - *TimeOutErr = YES; - *CancelCheckWork = YES; - } - } - } + // FTPS対応 + // OpenSSLでは受信確認はFD_READが複数回受信される可能性がある +// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ) != YES)) + // 短時間にFD_READが2回以上通知される対策 +// while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ) != YES)) +// { +// if(AskAsyncDone(s, &Error, FD_CLOSE) == YES) +// { +// Ret = 0; +// break; +// } +// Sleep(1); +// if(BackgrndMessageProc() == YES) +// *CancelCheckWork = YES; +// else if(TimeOut != 0) +// { +// time(&ElapseTime); +// ElapseTime -= StartTime; +// if(ElapseTime >= TimeOut) +// { +// DoPrintf("do_recv timed out"); +// *TimeOutErr = YES; +// *CancelCheckWork = YES; +// } +// } +// } if(/*(Ret != 0) && */(Error == 0) && (*CancelCheckWork == NO) && (*TimeOutErr == NO)) { @@ -972,25 +1027,19 @@ int do_recv(SOCKET s, char *buf, int len, int flags, int *TimeOutErr, int *Cance DoPrintf("## recv()"); #endif - // FTPS‘Ήž + // FTPS対応 // Ret = recv(s, buf, len, flags); - if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) - Ret = recvS(s, buf, len, flags); - else - Ret = recv(s, buf, len, flags); + Ret = FTPS_recv(s, buf, len, flags); if(Ret != SOCKET_ERROR) break; Error = WSAGetLastError(); Sleep(1); if(BackgrndMessageProc() == YES) break; - // FTPS‘Ήž - // ŽóMŠm”F‚ðƒoƒCƒpƒX‚µ‚½‚½‚ß‚±‚±‚Ń^ƒCƒ€ƒAƒEƒg‚ÌŠm”F - if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) - { - if(BackgrndMessageProc() == YES) - *CancelCheckWork = YES; - } + // FTPS対応 + // 受信確認をバイパスしたためここでタイムアウトの確認 + if(BackgrndMessageProc() == YES) + *CancelCheckWork = YES; else if(TimeOut != 0) { time(&ElapseTime); @@ -1034,7 +1083,8 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int DoPrintf("# Start send (S=%x)", s); #endif *TimeOutErr = NO; - *CancelCheckWork = NO; + // 同時接続対応 +// *CancelCheckWork = NO; Ret = SOCKET_ERROR; Error = 0; @@ -1044,36 +1094,40 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int #if DBG_MSG DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE"); #endif - WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE); + // Windows 2000でFD_WRITEが通知されないことがあるバグ修正 + // 毎回通知されたのはNT 4.0までのバグであり仕様ではない + // XP以降は互換性のためか毎回通知される +// WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE); if(BackgrndMessageProc() == YES) *CancelCheckWork = YES; - // FTPS‘Ήž - // ‘—Mƒoƒbƒtƒ@‚Ì‹ó‚«Šm”F‚ɂ͉e‹¿‚µ‚È‚¢‚ª”O‚Ì‚½‚ß -// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES)) - while(AskCryptMode() == CRYPT_NONE && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES)) - { - if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES) - { - Error = 1; - break; - } - - Sleep(1); - if(BackgrndMessageProc() == YES) - *CancelCheckWork = YES; - else if(TimeOut != 0) - { - time(&ElapseTime); - ElapseTime -= StartTime; - if(ElapseTime >= TimeOut) - { - DoPrintf("do_write timed out"); - *TimeOutErr = YES; - *CancelCheckWork = YES; - } - } - } + // FTPS対応 + // 送信バッファの空き確認には影響しないが念のため +// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE) != YES)) + // Windows 2000でFD_WRITEが通知されないことがあるバグ修正 +// while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE) != YES)) +// { +// if(AskAsyncDone(s, &Error, FD_CLOSE) == YES) +// { +// Error = 1; +// break; +// } +// +// Sleep(1); +// if(BackgrndMessageProc() == YES) +// *CancelCheckWork = YES; +// else if(TimeOut != 0) +// { +// time(&ElapseTime); +// ElapseTime -= StartTime; +// if(ElapseTime >= TimeOut) +// { +// DoPrintf("do_write timed out"); +// *TimeOutErr = YES; +// *CancelCheckWork = YES; +// } +// } +// } if((Error == 0) && (*CancelCheckWork == NO) && (*TimeOutErr == NO)) { @@ -1083,12 +1137,9 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int DoPrintf("## send()"); #endif - // FTPS‘Ήž + // FTPS対応 // Ret = send(s, buf, len, flags); - if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) - Ret = sendS(s, buf, len, flags); - else - Ret = send(s, buf, len, flags); + Ret = FTPS_send(s, buf, len, flags); if(Ret != SOCKET_ERROR) { #if DBG_MSG @@ -1100,13 +1151,10 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int Sleep(1); if(BackgrndMessageProc() == YES) break; - // FTPS‘Ήž - // ‘—Mƒoƒbƒtƒ@Šm”F‚ðƒoƒCƒpƒX‚µ‚½‚½‚ß‚±‚±‚Ń^ƒCƒ€ƒAƒEƒg‚ÌŠm”F - if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS) - { - if(BackgrndMessageProc() == YES) - *CancelCheckWork = YES; - } + // FTPS対応 + // 送信バッファ確認をバイパスしたためここでタイムアウトの確認 + if(BackgrndMessageProc() == YES) + *CancelCheckWork = YES; else if(TimeOut != 0) { time(&ElapseTime); @@ -1137,13 +1185,27 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int } +// 同時接続対応 +void RemoveReceivedData(SOCKET s) +{ + char buf[1024]; + int len; + int Error; + while((len = FTPS_recv(s, buf, sizeof(buf), MSG_PEEK)) >= 0) + { + AskAsyncDone(s, &Error, FD_READ); + FTPS_recv(s, buf, len, 0); + } +} + + /*----- * * Parameter * * Return Value -* int ƒXƒe[ƒ^ƒX -* SUCCESS/FAIL +* int ステータス +* FFFTP_SUCCESS/FFFTP_FAIL *----------------------------------------------------------------------------*/ int CheckClosedAndReconnect(void) @@ -1153,8 +1215,8 @@ int CheckClosedAndReconnect(void) //SetTaskMsg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); - Sts = SUCCESS; - if(AskAsyncDone(AskCmdCtrlSkt(), &Error, FD_CLOSE_BIT) == YES) + Sts = FFFTP_SUCCESS; + if(AskAsyncDone(AskCmdCtrlSkt(), &Error, FD_CLOSE) == YES) { Sts = ReConnectCmdSkt(); }