Make filezilla compatible with ftpanywhere
Filezilla
FTP is a well-known open-source standard FTP client software, but its current version is incompatible with the grid FTP provided by ftpanywhere, currently, it cannot be compatible with the settings provided by it. Therefore, I download its source code snapshot.
[2009.4.16] to check whether it is possible to make it compatible by modifying the source code.
Decompress its source code, go to the subdirectory/src/engine, and open ftpcontrolsocket. CPP file, which is the core of filezilla used to support standard FTP commands. What needs to be transformed is its list mode and analysis code for PASV feedback.
[Including epsv commands under IPv6, but it is not necessary to modify it because there is no IPV6 at the moment]. Modify its PASV parsing code.
Make filezilla compatible with ftpanywhere
Bool
Cftpcontrolsocket: parsepasvresponse (crawler transferopdata * pdata)
{
// Validate IP Address
Wxstring digit = _ T ("0 * [0-9] {1, 3 }");
Const wxchar * dot =
_ T (",");
Wxstring exp = _ T ("(| // () (") + digit + dot +
Digit + _ T (") (| //) | $ )");
Wxregex RegEx;
RegEx. Compile (exp );
If
(! RegEx. Matches (m_response ))
Return false;
Pdata-> host = RegEx. getmatch (m_response, 2 );
Int I =
Pdata-> host. Find (',',
True );
Long number;
If (I =-1 |
! Pdata-> host. mid (I + 1). tolong (& number ))
Return false;
Pdata-> Port = number; // get ls byte
Server socket
Pdata-> host = pdata-> host. Left (I );
I = pdata-> host. Find (',', true );
If (I =-1 |
! Pdata-> host. mid (I + 1). tolong (& number ))
Return false;
Pdata-> port + = 256 * number; // Add MS
Byte of server socket
Pdata-> host = pdata-> host. Left (I );
Pdata-> host. Replace (_ T (","), _ T ("."));
If (m_pproxybackend)
{
// We do not have any information about
Proxy's inner workings
Return true;
}
Const wxstring peerip =
M_psocket-> getpeerip ();
If
(! Isroutableaddress (pdata-> host, m_psocket-> getaddressfamily ())&&
Isroutableaddress (peerip, m_psocket-> getaddressfamily ()))
{
If
(! M_pengine-> getoptions ()-> getoptionval (option_pasvreplyfallbackmode) |
Pdata-> btriedactive)
{
Logmessage (status, _ ("server sent passive
Reply with unroutable address. Using server address instead ."));
Logmessage (debug_info, _ T ("reply: % s,
Peer: % s "), pdata-> host. c_str (), peerip. c_str ());
Pdata-> host = peerip;
}
Else
{
Logmessage (status, _ ("server sent passive
Reply with unroutable address. Passive mode failed ."));
Logmessage (debug_info, _ T ("reply: % s,
Peer: % s "), pdata-> host. c_str (),
Peerip. c_str ());
Return false;
}
}
Return true;
}
Here is the original code. The problem that PASV mode cannot be downloaded is that it does not know P2P transmission, so it adds a security judgment function, ftpanywhere can be used as long as it is deregistered. In general, as long as the FTP server is a regular server, the code is completely wasted.
Make filezilla compatible with ftpanywhere
Bool
Cftpcontrolsocket: parsepasvresponse (crawler transferopdata * pdata)
{
// Validate IP Address
Wxstring digit = _ T ("0 * [0-9] {1, 3 }");
Const wxchar * dot =
_ T (",");
Wxstring exp = _ T ("(| // () (") + digit + dot +
Digit + _ T (") (| //) | $ )");
Wxregex RegEx;
RegEx. Compile (exp );
If
(! RegEx. Matches (m_response ))
Return false;
Pdata-> host = RegEx. getmatch (m_response, 2 );
Int I =
Pdata-> host. Find (',',
True );
Long number;
If (I =-1 |
! Pdata-> host. mid (I + 1). tolong (& number ))
Return false;
Pdata-> Port = number; // get ls byte
Server socket
Pdata-> host = pdata-> host. Left (I );
I = pdata-> host. Find (',', true );
If (I =-1 |
! Pdata-> host. mid (I + 1). tolong (& number ))
Return false;
Pdata-> port + = 256 * number; // Add MS
Byte of server socket
Pdata-> host = pdata-> host. Left (I );
Pdata-> host. Replace (_ T (","), _ T ("."));
If (m_pproxybackend)
{
// We do not have any information about
Proxy's inner workings
Return true;
}
// Note that the following code can be deregistered to support P2P
The connection in PASV mode is transmitted
// Const wxstring peerip =
M_psocket-> getpeerip ();
// If
(! Isroutableaddress (pdata-> host, m_psocket-> getaddressfamily ())&&
Isroutableaddress (peerip, m_psocket-> getaddressfamily ()))
//{
// If
(! M_pengine-> getoptions ()-> getoptionval (option_pasvreplyfallbackmode) |
Pdata-> btriedactive)
//{
// Logmessage (status, _ ("server sent passive reply with unroutable address. Using server address
Instead ."));
// Logmessage (debug_info, _ T ("reply: % s, peer: % s"), pdata-> host. c_str (), peerip. c_str ());
// Pdata-> host = peerip;
//}
// Else
//{
// Logmessage (status, _ ("server sent passive reply with unroutable address. Passive Mode
Failed ."));
// Logmessage (debug_info, _ T ("reply: % s, peer: % s"), pdata-> host. c_str (),
Peerip. c_str ());
// Return false;
//}
//}
Return true;
}
Now, as long as the port is specified as priority in the connection mode of the site attribute, if the connection fails in the port mode, it is set to automatically switch to the PASV mode, and conditional compatibility is available, this is only because the first download will fail. Next we will transform its list mode to make it more compatible.
Of course, you can disable the PASV list under the root directory on the ftpanywhere server to enable filezilla to automatically determine the connection mode, but from its code, it still has some compatibility problems. therefore, transforming list into active mode takes priority, which is the best choice.
Here is the problem
Crawtransferopdata: FIG ()
: Copdata (pai_rawtransfer)
{
Btriedpasv = btriedactive = false;
Bpasv = true;
}
Its initialization takes precedence over the passive mode. In this way, a problem occurs during the list, but the download is successful. However, I read the code and found that unless an additional list is specified, the mode variable is preferentially used, otherwise, it is difficult to modify the code, because the list in the Code is consistent with the file transmission priority mode, but also to adapt to other standard FTP sites, after all, I cannot optimize it for my ftpanywhere by using the ftpcontrolsocket. class defined in H
Class crawler transferopdata: Public copdata
{
Public:
Crawtransferopdata ();
Wxstring cmd;
Cftptransferopdata * polddata;
Bool bpasv;
Bool btriedpasv;
Bool btriedactive;
Wxstring host;
Int port;
};
Add an extra variable to it, such as bool bftpanywhere; then, before the LIST Command, determine whether to use PASV or port before determining
Whether bftpanywhere is true. If it is true, the List should adopt the port mode first; otherwise, the default action will continue; while the bftpanywhere initialization should be sent to the server
Whether the vdsi command returns 2XX to determine whether it is an ftpanywhere server, because too many modifications are involved here, unless agreed by the filezilla code maintainer, it makes no sense. Therefore, the simplest and fastest way is to directly log out of the code I provided above. Although it cannot be 100% compatible, it is basically compatible, and manual compatibility can be achieved by setting projects.