X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=getput.c;h=d3ca963bd4388a3b5fd454bbc05bec4ccbf59dd0;hb=6fe24d210e4c0a798422445c04170ebb89a0b240;hp=48f0d632635dcd8e8f8b0ef7bf3080286a0bab49;hpb=27e47ec02a3553a6e9b4e935a43dc28919d91c0d;p=ffftp%2Fffftp.git diff --git a/getput.c b/getput.c index 48f0d63..d3ca963 100644 --- a/getput.c +++ b/getput.c @@ -88,7 +88,9 @@ 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 int DispUpDownErrDialog(int ResID, HWND hWnd, char *Fname); +static int DispUpDownErrDialog(int ResID, HWND hWnd, TRANSPACKET *Pkt); static BOOL 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); @@ -104,7 +106,11 @@ static int SetUploadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *M 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); @@ -155,6 +161,9 @@ static HANDLE hErrMsgMutex; // 同時接続対応 static int WaitForMainThread = NO; +// 再転送対応 +static int TransferErrorMode = EXIST_OVW; +static int TransferErrorNotify = NO; /*===== 外部参照 =====*/ @@ -373,6 +382,9 @@ int RemoveTmpTransFileListItem(TRANSPACKET **Base, int Num) void AddTransFileList(TRANSPACKET *Pkt) { + // 同時接続対応 + TRANSPACKET *Pos; + DispTransPacket(Pkt); // 同時接続対応 @@ -384,6 +396,13 @@ void AddTransFileList(TRANSPACKET *Pkt) 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) || @@ -395,7 +414,12 @@ void AddTransFileList(TRANSPACKET *Pkt) } // 同時接続対応 if(NextTransPacketBase == NULL) - NextTransPacketBase = TransPacketBase; + { + if(Pos) + NextTransPacketBase = Pos->Next; + else + NextTransPacketBase = TransPacketBase; + } ReleaseMutex(hListAccMutex); // 同時接続対応 WaitForMainThread = NO; @@ -441,7 +465,7 @@ void AppendTransFileList(TRANSPACKET *Pkt) } // 同時接続対応 if(NextTransPacketBase == NULL) - NextTransPacketBase = TransPacketBase; + NextTransPacketBase = Pkt; while(Pkt != NULL) { @@ -545,7 +569,7 @@ static void EraseTransFileList(void) } TransPacketBase = NotDel; // 同時接続対応 - NextTransPacketBase = TransPacketBase; + NextTransPacketBase = NotDel; TransFiles = 0; PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0); ReleaseMutex(hListAccMutex); @@ -1169,6 +1193,10 @@ static ULONG WINAPI TransferThread(void *Dummy) PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_AUTO_EXIT, 0), 0); GoExit = NO; } + + // 再転送対応 + TransferErrorMode = AskTransferErrorMode(); + TransferErrorNotify = AskTransferErrorNotify(); } else { @@ -1316,7 +1344,10 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) SOCKET listen_socket = INVALID_SOCKET; // data listen socket char Buf[1024]; int CreateMode; - struct sockaddr_in saSockAddr1; + // IPv6対応 +// struct sockaddr_in saSockAddr1; + struct sockaddr_in saSockAddrIPv4; + struct sockaddr_in6 saSockAddrIPv6; char Reply[ERR_MSG_LEN+7]; if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, CancelCheckWork)) != INVALID_SOCKET) @@ -1331,8 +1362,20 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) // 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()); @@ -1345,7 +1388,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) @@ -1403,15 +1458,29 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork) SOCKET data_socket = INVALID_SOCKET; // data channel socket char Buf[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) { @@ -2208,8 +2277,22 @@ 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) + { + if(TransferErrorNotify == YES && DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Pkt) == NO) + ClearAll = YES; + else + { + Pkt->Mode = TransferErrorMode; + AddTransFileList(Pkt); + } + } + } } } else @@ -2243,13 +2326,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)); } @@ -2267,29 +2354,53 @@ static int DispUpDownErrDialog(int ResID, HWND hWnd, char *Fname) static BOOL 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); + 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); } @@ -2475,7 +2586,10 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) SOCKET data_socket = INVALID_SOCKET; // data channel socket SOCKET listen_socket = INVALID_SOCKET; // data listen socket char Buf[1024]; - struct sockaddr_in saSockAddr1; + // IPv6対応 +// struct sockaddr_in saSockAddr1; + struct sockaddr_in saSockAddrIPv4; + struct sockaddr_in6 saSockAddrIPv6; int Resume; char Reply[ERR_MSG_LEN+7]; @@ -2498,8 +2612,20 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) // 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()); @@ -2512,7 +2638,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) @@ -2566,7 +2704,9 @@ static int UpLoadPassive(TRANSPACKET *Pkt) int iRetCode; SOCKET data_socket = INVALID_SOCKET; // data channel socket char Buf[1024]; - char Adrs[20]; + // IPv6対応 +// char Adrs[20]; + char Adrs[40]; int Port; int Flg; int Resume; @@ -2574,10 +2714,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) @@ -3366,8 +3518,22 @@ 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) + { + if(TransferErrorNotify == YES && DispUpDownErrDialog(uperr_dlg, Pkt->hWndTrans, Pkt) == NO) + ClearAll = YES; + else + { + Pkt->Mode = TransferErrorMode; + AddTransFileList(Pkt); + } + } + } } } else @@ -3675,10 +3841,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; @@ -3694,24 +3881,30 @@ static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max) if(Btm != NULL) { Btm++; - Btm = strchr(Btm, ','); // コンマではなくドットを返すホストがあるため +// Btm = strchr(Btm, ','); + OldBtm = Btm; + Btm = strchr(OldBtm, ','); if(Btm == NULL) - Btm = strchr(Btm, '.'); + Btm = strchr(OldBtm, '.'); if(Btm != NULL) { Btm++; - Btm = strchr(Btm, ','); // コンマではなくドットを返すホストがあるため +// Btm = strchr(Btm, ','); + OldBtm = Btm; + Btm = strchr(OldBtm, ','); if(Btm == NULL) - Btm = strchr(Btm, '.'); + Btm = strchr(OldBtm, '.'); if(Btm != NULL) { Btm++; - Btm = strchr(Btm, ','); // コンマではなくドットを返すホストがあるため +// Btm = strchr(Btm, ','); + OldBtm = Btm; + Btm = strchr(OldBtm, ','); if(Btm == NULL) - Btm = strchr(Btm, '.'); + Btm = strchr(OldBtm, '.'); if(Btm != NULL) { if((Btm - Pos) <= Max) @@ -3742,49 +3935,55 @@ static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max) // IPv6対応 -static int GetAdrsAndPortIPv6(char *Str, char *Adrs, int *Port, int Max, short *Family) +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; - Pos = strchr(Str, '|'); - if(Pos != NULL) + Btm = strchr(Str, '('); + if(Btm != NULL) { - Pos++; - Btm = strchr(Pos, '|'); + Btm++; + Btm = strchr(Btm, '|'); if(Btm != NULL) { - switch(atoi(Pos)) - { - case 1: - *Family = AF_INET; - break; - case 2: - *Family = AF_INET6; - break; - } Pos = Btm + 1; Btm = strchr(Pos, '|'); if(Btm != NULL) { - if((Btm - Pos) <= Max) + Pos = Btm + 1; + Btm = strchr(Pos, '|'); + if(Btm != NULL) { - if((Btm - Pos) > 0) + if((Btm - Pos) <= Max) { - strncpy(Adrs, Pos, Btm - Pos); - *(Adrs + (Btm - Pos)) = NUL; - } + 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) + AddressToStringIPv6(Adrs, &SockAddr.sin6_addr); + } - Pos = Btm + 1; - Btm = strchr(Pos, '|'); - if(Btm != NULL) - { - Btm++; - *Port = atoi(Pos); - Sts = FFFTP_SUCCESS; + Pos = Btm + 1; + Btm = strchr(Pos, '|'); + if(Btm != NULL) + { + Btm++; + *Port = atoi(Pos); + Btm = strchr(Btm, ')'); + if(Btm != NULL) + Sts = FFFTP_SUCCESS; + } } } }