1. patch from Søren Erland Vestø implementing wxFTP::GetFileSize()
with my fixes to the patch 2. significantly updated/cleaned FTP tests in the sample 3. don't log FTP passwords in wxLogTrace git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@9159 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -11,6 +11,7 @@ wxBase:
|
|||||||
|
|
||||||
- wxMimeTypesManager now can create file associations too
|
- wxMimeTypesManager now can create file associations too
|
||||||
- wxCopyFile() respects the file permissions (Roland Scholz)
|
- wxCopyFile() respects the file permissions (Roland Scholz)
|
||||||
|
- wxFTP::GetFileSize() added (S<>ren Erland Vest<73>)
|
||||||
|
|
||||||
wxMSW:
|
wxMSW:
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
#define __WX_FTP_H__
|
#define __WX_FTP_H__
|
||||||
|
|
||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
#pragma interface
|
#pragma interface "ftp.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/object.h"
|
#include "wx/object.h"
|
||||||
@@ -27,6 +27,7 @@ class WXDLLEXPORT wxFTP : public wxProtocol
|
|||||||
public:
|
public:
|
||||||
enum TransferMode
|
enum TransferMode
|
||||||
{
|
{
|
||||||
|
NONE, // not set by user explicitly
|
||||||
ASCII,
|
ASCII,
|
||||||
BINARY
|
BINARY
|
||||||
};
|
};
|
||||||
@@ -77,6 +78,16 @@ public:
|
|||||||
bool Rename(const wxString& src, const wxString& dst);
|
bool Rename(const wxString& src, const wxString& dst);
|
||||||
bool RmFile(const wxString& path);
|
bool RmFile(const wxString& path);
|
||||||
|
|
||||||
|
// Get the size of a file in the current dir.
|
||||||
|
// this function tries its best to deliver the size in bytes using BINARY
|
||||||
|
// (the SIZE command reports different sizes depending on whether
|
||||||
|
// type is set to ASCII or BINARY)
|
||||||
|
// returns -1 if file is non-existant or size could not be found
|
||||||
|
int GetFileSize(const wxString& fileName);
|
||||||
|
|
||||||
|
// Check to see if a file exists in the current dir
|
||||||
|
bool FileExists(const wxString& fileName);
|
||||||
|
|
||||||
// Download methods
|
// Download methods
|
||||||
bool Abort();
|
bool Abort();
|
||||||
|
|
||||||
@@ -135,8 +146,9 @@ protected:
|
|||||||
// true if there is an FTP transfer going on
|
// true if there is an FTP transfer going on
|
||||||
bool m_streaming;
|
bool m_streaming;
|
||||||
|
|
||||||
// true if the user had set the transfer mode
|
// although this should be set to ASCII by default according to STD9,
|
||||||
bool m_modeSet;
|
// we will use BINARY transfer mode by default for backwards compatibility
|
||||||
|
TransferMode m_currentTransfermode;
|
||||||
|
|
||||||
friend class wxInputFTPStream;
|
friend class wxInputFTPStream;
|
||||||
friend class wxOutputFTPStream;
|
friend class wxOutputFTPStream;
|
||||||
@@ -145,4 +157,8 @@ protected:
|
|||||||
DECLARE_PROTOCOL(wxFTP)
|
DECLARE_PROTOCOL(wxFTP)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// the trace mask used by assorted wxLogTrace() in ftp code, do
|
||||||
|
// wxLog::AddTraceMask(FTP_TRACE_MASK) to see them in output
|
||||||
|
#define FTP_TRACE_MASK _T("ftp")
|
||||||
|
|
||||||
#endif // __WX_FTP_H__
|
#endif // __WX_FTP_H__
|
||||||
|
@@ -45,12 +45,12 @@
|
|||||||
//#define TEST_FILE
|
//#define TEST_FILE
|
||||||
//#define TEST_FILECONF
|
//#define TEST_FILECONF
|
||||||
//#define TEST_FILENAME
|
//#define TEST_FILENAME
|
||||||
//#define TEST_FTP
|
#define TEST_FTP
|
||||||
//#define TEST_HASH
|
//#define TEST_HASH
|
||||||
//#define TEST_LIST
|
//#define TEST_LIST
|
||||||
//#define TEST_LOG
|
//#define TEST_LOG
|
||||||
//#define TEST_LONGLONG
|
//#define TEST_LONGLONG
|
||||||
#define TEST_MIME
|
//#define TEST_MIME
|
||||||
//#define TEST_INFO_FUNCTIONS
|
//#define TEST_INFO_FUNCTIONS
|
||||||
//#define TEST_REGISTRY
|
//#define TEST_REGISTRY
|
||||||
//#define TEST_SOCKETS
|
//#define TEST_SOCKETS
|
||||||
@@ -1508,17 +1508,70 @@ static void TestSocketClient()
|
|||||||
|
|
||||||
#endif // TEST_SOCKETS
|
#endif // TEST_SOCKETS
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// FTP
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef TEST_FTP
|
#ifdef TEST_FTP
|
||||||
|
|
||||||
#include <wx/protocol/ftp.h>
|
#include <wx/protocol/ftp.h>
|
||||||
|
|
||||||
static void TestProtocolFtp()
|
static wxFTP ftp;
|
||||||
|
|
||||||
|
#define FTP_ANONYMOUS
|
||||||
|
|
||||||
|
#ifdef FTP_ANONYMOUS
|
||||||
|
static const char *directory = "/pub";
|
||||||
|
static const char *filename = "welcome.msg";
|
||||||
|
#else
|
||||||
|
static const char *directory = "/etc";
|
||||||
|
static const char *filename = "issue";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool TestFtpConnect()
|
||||||
{
|
{
|
||||||
puts("*** Testing wxFTP download ***\n");
|
puts("*** Testing FTP connect ***");
|
||||||
|
|
||||||
|
#ifdef FTP_ANONYMOUS
|
||||||
|
static const char *hostname = "ftp.wxwindows.org";
|
||||||
|
|
||||||
|
printf("--- Attempting to connect to %s:21 anonymously...\n", hostname);
|
||||||
|
#else // !FTP_ANONYMOUS
|
||||||
|
static const char *hostname = "localhost";
|
||||||
|
|
||||||
|
char user[256];
|
||||||
|
fgets(user, WXSIZEOF(user), stdin);
|
||||||
|
user[strlen(user) - 1] = '\0'; // chop off '\n'
|
||||||
|
ftp.SetUser(user);
|
||||||
|
|
||||||
|
char password[256];
|
||||||
|
printf("Password for %s: ", password);
|
||||||
|
fgets(password, WXSIZEOF(password), stdin);
|
||||||
|
password[strlen(password) - 1] = '\0'; // chop off '\n'
|
||||||
|
ftp.SetPassword(password);
|
||||||
|
|
||||||
|
printf("--- Attempting to connect to %s:21 as %s...\n", hostname, user);
|
||||||
|
#endif // FTP_ANONYMOUS/!FTP_ANONYMOUS
|
||||||
|
|
||||||
|
if ( !ftp.Connect(hostname) )
|
||||||
|
{
|
||||||
|
printf("ERROR: failed to connect to %s\n", hostname);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("--- Connected to %s, current directory is '%s'\n",
|
||||||
|
hostname, ftp.Pwd().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
|
||||||
|
static void TestFtpWuFtpd()
|
||||||
|
{
|
||||||
wxFTP ftp;
|
wxFTP ftp;
|
||||||
|
|
||||||
#ifdef TEST_WUFTPD // test (fixed?) wxFTP bug with wu-ftpd >= 2.6.0?
|
|
||||||
static const char *hostname = "ftp.eudora.com";
|
static const char *hostname = "ftp.eudora.com";
|
||||||
if ( !ftp.Connect(hostname) )
|
if ( !ftp.Connect(hostname) )
|
||||||
{
|
{
|
||||||
@@ -1551,33 +1604,11 @@ static void TestProtocolFtp()
|
|||||||
delete in;
|
delete in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else // !TEST_WUFTPD
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
static const char *hostname = "ftp.wxwindows.org";
|
|
||||||
static const char *directory = "pub";
|
|
||||||
static const char *filename = "welcome.msg";
|
|
||||||
|
|
||||||
printf("--- Attempting to connect to %s:21 anonymously...\n", hostname);
|
|
||||||
#else
|
|
||||||
static const char *hostname = "localhost";
|
|
||||||
static const char *user = "zeitlin";
|
|
||||||
static const char *directory = "/tmp";
|
|
||||||
|
|
||||||
ftp.SetUser(user);
|
|
||||||
ftp.SetPassword("password");
|
|
||||||
|
|
||||||
printf("--- Attempting to connect to %s:21 as %s...\n", hostname, user);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( !ftp.Connect(hostname) )
|
|
||||||
{
|
|
||||||
printf("ERROR: failed to connect to %s\n", hostname);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
static void TestFtpList()
|
||||||
{
|
{
|
||||||
printf("--- Connected to %s, current directory is '%s'\n",
|
puts("*** Testing wxFTP file listing ***\n");
|
||||||
hostname, ftp.Pwd().c_str());
|
|
||||||
|
|
||||||
// test CWD
|
// test CWD
|
||||||
if ( !ftp.ChDir(directory) )
|
if ( !ftp.ChDir(directory) )
|
||||||
@@ -1585,6 +1616,8 @@ static void TestProtocolFtp()
|
|||||||
printf("ERROR: failed to cd to %s\n", directory);
|
printf("ERROR: failed to cd to %s\n", directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Current directory is '%s'\n", ftp.Pwd().c_str());
|
||||||
|
|
||||||
// test NLIST and LIST
|
// test NLIST and LIST
|
||||||
wxArrayString files;
|
wxArrayString files;
|
||||||
if ( !ftp.GetFilesList(files) )
|
if ( !ftp.GetFilesList(files) )
|
||||||
@@ -1622,6 +1655,13 @@ static void TestProtocolFtp()
|
|||||||
puts("ERROR: failed to cd to ..");
|
puts("ERROR: failed to cd to ..");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("Current directory is '%s'\n", ftp.Pwd().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TestFtpDownload()
|
||||||
|
{
|
||||||
|
puts("*** Testing wxFTP download ***\n");
|
||||||
|
|
||||||
// test RETR
|
// test RETR
|
||||||
wxInputStream *in = ftp.GetInputStream(filename);
|
wxInputStream *in = ftp.GetInputStream(filename);
|
||||||
if ( !in )
|
if ( !in )
|
||||||
@@ -1632,6 +1672,7 @@ static void TestProtocolFtp()
|
|||||||
{
|
{
|
||||||
size_t size = in->StreamSize();
|
size_t size = in->StreamSize();
|
||||||
printf("Reading file %s (%u bytes)...", filename, size);
|
printf("Reading file %s (%u bytes)...", filename, size);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
char *data = new char[size];
|
char *data = new char[size];
|
||||||
if ( !in->Read(data, size) )
|
if ( !in->Read(data, size) )
|
||||||
@@ -1646,8 +1687,37 @@ static void TestProtocolFtp()
|
|||||||
delete [] data;
|
delete [] data;
|
||||||
delete in;
|
delete in;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TestFtpFileSize()
|
||||||
|
{
|
||||||
|
puts("*** Testing FTP SIZE command ***");
|
||||||
|
|
||||||
|
if ( !ftp.ChDir(directory) )
|
||||||
|
{
|
||||||
|
printf("ERROR: failed to cd to %s\n", directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Current directory is '%s'\n", ftp.Pwd().c_str());
|
||||||
|
|
||||||
|
if ( ftp.FileExists(filename) )
|
||||||
|
{
|
||||||
|
int size = ftp.GetFileSize(filename);
|
||||||
|
if ( size == -1 )
|
||||||
|
printf("ERROR: couldn't get size of '%s'\n", filename);
|
||||||
|
else
|
||||||
|
printf("Size of '%s' is %d bytes.\n", filename, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("ERROR: '%s' doesn't exist\n", filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TestFtpMisc()
|
||||||
|
{
|
||||||
|
puts("*** Testing miscellaneous wxFTP functions ***");
|
||||||
|
|
||||||
// test some other FTP commands
|
|
||||||
if ( ftp.SendCommand("STAT") != '2' )
|
if ( ftp.SendCommand("STAT") != '2' )
|
||||||
{
|
{
|
||||||
puts("ERROR: STAT failed");
|
puts("ERROR: STAT failed");
|
||||||
@@ -1667,28 +1737,67 @@ static void TestProtocolFtp()
|
|||||||
ftp.GetLastResult().c_str());
|
ftp.GetLastResult().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // TEST_WUFTPD/!TEST_WUFTPD
|
|
||||||
}
|
|
||||||
|
|
||||||
static void TestProtocolFtpUpload()
|
static void TestFtpInteractive()
|
||||||
{
|
{
|
||||||
puts("*** Testing wxFTP uploading ***\n");
|
puts("\n*** Interactive wxFTP test ***");
|
||||||
|
|
||||||
static const char *hostname = "localhost";
|
char buf[128];
|
||||||
|
|
||||||
printf("--- Attempting to connect to %s:21...\n", hostname);
|
for ( ;; )
|
||||||
|
|
||||||
wxFTP ftp;
|
|
||||||
ftp.SetUser("zeitlin");
|
|
||||||
ftp.SetPassword("password");
|
|
||||||
if ( !ftp.Connect(hostname) )
|
|
||||||
{
|
{
|
||||||
printf("ERROR: failed to connect to %s\n", hostname);
|
printf("Enter FTP command: ");
|
||||||
|
if ( !fgets(buf, WXSIZEOF(buf), stdin) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
// kill the last '\n'
|
||||||
|
buf[strlen(buf) - 1] = 0;
|
||||||
|
|
||||||
|
// special handling of LIST and NLST as they require data connection
|
||||||
|
wxString start(buf, 4);
|
||||||
|
start.MakeUpper();
|
||||||
|
if ( start == "LIST" || start == "NLST" )
|
||||||
|
{
|
||||||
|
wxString wildcard;
|
||||||
|
if ( strlen(buf) > 4 )
|
||||||
|
wildcard = buf + 5;
|
||||||
|
|
||||||
|
wxArrayString files;
|
||||||
|
if ( !ftp.GetList(files, wildcard, start == "LIST") )
|
||||||
|
{
|
||||||
|
printf("ERROR: failed to get %s of files\n", start.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("--- Connected to %s, current directory is '%s'\n",
|
printf("--- %s of '%s' under '%s':\n",
|
||||||
hostname, ftp.Pwd().c_str());
|
start.c_str(), wildcard.c_str(), ftp.Pwd().c_str());
|
||||||
|
size_t count = files.GetCount();
|
||||||
|
for ( size_t n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
printf("\t%s\n", files[n].c_str());
|
||||||
|
}
|
||||||
|
puts("--- End of the file list");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // !list
|
||||||
|
{
|
||||||
|
char ch = ftp.SendCommand(buf);
|
||||||
|
printf("Command %s", ch ? "succeeded" : "failed");
|
||||||
|
if ( ch )
|
||||||
|
{
|
||||||
|
printf(" (return code %c)", ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(", server reply:\n%s\n\n", ftp.GetLastResult().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("\n*** done ***");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TestFtpUpload()
|
||||||
|
{
|
||||||
|
puts("*** Testing wxFTP uploading ***\n");
|
||||||
|
|
||||||
// upload a file
|
// upload a file
|
||||||
static const char *file1 = "test1";
|
static const char *file1 = "test1";
|
||||||
@@ -1720,7 +1829,6 @@ static void TestProtocolFtpUpload()
|
|||||||
delete out;
|
delete out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif // TEST_FTP
|
#endif // TEST_FTP
|
||||||
|
|
||||||
@@ -2957,7 +3065,7 @@ static void TestTimeParse()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TestInteractive()
|
static void TestDateTimeInteractive()
|
||||||
{
|
{
|
||||||
puts("\n*** interactive wxDateTime tests ***");
|
puts("\n*** interactive wxDateTime tests ***");
|
||||||
|
|
||||||
@@ -4121,10 +4229,24 @@ int main(int argc, char **argv)
|
|||||||
#endif // TEST_SOCKETS
|
#endif // TEST_SOCKETS
|
||||||
|
|
||||||
#ifdef TEST_FTP
|
#ifdef TEST_FTP
|
||||||
wxLog::AddTraceMask(_T("ftp"));
|
wxLog::AddTraceMask(FTP_TRACE_MASK);
|
||||||
TestProtocolFtp();
|
if ( TestFtpConnect() )
|
||||||
|
{
|
||||||
|
TestFtpFileSize();
|
||||||
if ( 0 )
|
if ( 0 )
|
||||||
TestProtocolFtpUpload();
|
{
|
||||||
|
TestFtpList();
|
||||||
|
TestFtpDownload();
|
||||||
|
TestFtpMisc();
|
||||||
|
TestFtpUpload();
|
||||||
|
}
|
||||||
|
if ( 0 )
|
||||||
|
TestFtpInteractive();
|
||||||
|
}
|
||||||
|
//else: connecting to the FTP server failed
|
||||||
|
|
||||||
|
if ( 0 )
|
||||||
|
TestFtpWuFtpd();
|
||||||
#endif // TEST_FTP
|
#endif // TEST_FTP
|
||||||
|
|
||||||
#ifdef TEST_STREAMS
|
#ifdef TEST_STREAMS
|
||||||
@@ -4156,7 +4278,7 @@ int main(int argc, char **argv)
|
|||||||
TestTimeZoneBug();
|
TestTimeZoneBug();
|
||||||
}
|
}
|
||||||
if ( 0 )
|
if ( 0 )
|
||||||
TestInteractive();
|
TestDateTimeInteractive();
|
||||||
#endif // TEST_DATETIME
|
#endif // TEST_DATETIME
|
||||||
|
|
||||||
#ifdef TEST_VCARD
|
#ifdef TEST_VCARD
|
||||||
|
@@ -83,7 +83,7 @@ wxFTP::wxFTP()
|
|||||||
{
|
{
|
||||||
m_lastError = wxPROTO_NOERR;
|
m_lastError = wxPROTO_NOERR;
|
||||||
m_streaming = FALSE;
|
m_streaming = FALSE;
|
||||||
m_modeSet = FALSE;
|
m_currentTransfermode = NONE;
|
||||||
|
|
||||||
m_user = wxT("anonymous");
|
m_user = wxT("anonymous");
|
||||||
m_passwd << wxGetUserId() << wxT('@') << wxGetFullHostName();
|
m_passwd << wxGetUserId() << wxT('@') << wxGetFullHostName();
|
||||||
@@ -204,7 +204,20 @@ char wxFTP::SendCommand(const wxString& command)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxLogTrace(_T("ftp"), _T("==> %s"), command.c_str());
|
#ifdef __WXDEBUG__
|
||||||
|
// don't show the passwords in the logs (even in debug ones)
|
||||||
|
wxString cmd, password;
|
||||||
|
if ( command.Upper().StartsWith(_T("PASS "), &password) )
|
||||||
|
{
|
||||||
|
cmd << _T("PASS ") << wxString(_T('*'), password.length());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmd = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxLogTrace(FTP_TRACE_MASK, _T("==> %s"), cmd.c_str());
|
||||||
|
#endif // __WXDEBUG__
|
||||||
|
|
||||||
return GetResult();
|
return GetResult();
|
||||||
}
|
}
|
||||||
@@ -256,7 +269,7 @@ char wxFTP::GetResult()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxLogTrace(_T("ftp"), _T("<== %s %s"),
|
wxLogTrace(FTP_TRACE_MASK, _T("<== %s %s"),
|
||||||
code.c_str(), line.c_str());
|
code.c_str(), line.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,7 +281,7 @@ char wxFTP::GetResult()
|
|||||||
if ( firstLine )
|
if ( firstLine )
|
||||||
{
|
{
|
||||||
code = wxString(line, LEN_CODE);
|
code = wxString(line, LEN_CODE);
|
||||||
wxLogTrace(_T("ftp"), _T("<== %s %s"),
|
wxLogTrace(FTP_TRACE_MASK, _T("<== %s %s"),
|
||||||
code.c_str(), line.c_str() + LEN_CODE + 1);
|
code.c_str(), line.c_str() + LEN_CODE + 1);
|
||||||
|
|
||||||
switch ( chMarker )
|
switch ( chMarker )
|
||||||
@@ -295,13 +308,13 @@ char wxFTP::GetResult()
|
|||||||
endOfReply = TRUE;
|
endOfReply = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxLogTrace(_T("ftp"), _T("<== %s %s"),
|
wxLogTrace(FTP_TRACE_MASK, _T("<== %s %s"),
|
||||||
code.c_str(), line.c_str() + LEN_CODE + 1);
|
code.c_str(), line.c_str() + LEN_CODE + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// just part of reply
|
// just part of reply
|
||||||
wxLogTrace(_T("ftp"), _T("<== %s %s"),
|
wxLogTrace(FTP_TRACE_MASK, _T("<== %s %s"),
|
||||||
code.c_str(), line.c_str());
|
code.c_str(), line.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,6 +341,12 @@ char wxFTP::GetResult()
|
|||||||
|
|
||||||
bool wxFTP::SetTransferMode(TransferMode transferMode)
|
bool wxFTP::SetTransferMode(TransferMode transferMode)
|
||||||
{
|
{
|
||||||
|
if ( transferMode == m_currentTransfermode )
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
wxString mode;
|
wxString mode;
|
||||||
switch ( transferMode )
|
switch ( transferMode )
|
||||||
{
|
{
|
||||||
@@ -352,7 +371,9 @@ bool wxFTP::SetTransferMode(TransferMode transferMode)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_modeSet = TRUE;
|
// If we get here the operation has been succesfully completed
|
||||||
|
// Set the status-member
|
||||||
|
m_currentTransfermode = transferMode;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -497,6 +518,8 @@ public:
|
|||||||
{
|
{
|
||||||
m_ftp->Abort();
|
m_ftp->Abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete m_i_socket; // moved to top of destructor to accomodate wu-FTPd >= 2.6.0
|
||||||
}
|
}
|
||||||
|
|
||||||
wxFTP *m_ftp;
|
wxFTP *m_ftp;
|
||||||
@@ -608,7 +631,7 @@ wxInputStream *wxFTP::GetInputStream(const wxString& path)
|
|||||||
int pos_size;
|
int pos_size;
|
||||||
wxInputFTPStream *in_stream;
|
wxInputFTPStream *in_stream;
|
||||||
|
|
||||||
if ( !m_modeSet && !SetTransferMode(BINARY) )
|
if ( ( m_currentTransfermode == NONE ) && !SetTransferMode(BINARY) )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
wxSocketClient *sock = GetPort();
|
wxSocketClient *sock = GetPort();
|
||||||
@@ -642,7 +665,7 @@ wxInputStream *wxFTP::GetInputStream(const wxString& path)
|
|||||||
|
|
||||||
wxOutputStream *wxFTP::GetOutputStream(const wxString& path)
|
wxOutputStream *wxFTP::GetOutputStream(const wxString& path)
|
||||||
{
|
{
|
||||||
if ( !m_modeSet && !SetTransferMode(BINARY) )
|
if ( ( m_currentTransfermode == NONE ) && !SetTransferMode(BINARY) )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
wxSocketClient *sock = GetPort();
|
wxSocketClient *sock = GetPort();
|
||||||
@@ -697,6 +720,170 @@ bool wxFTP::GetList(wxArrayString& files,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxFTP::FileExists(const wxString& fileName)
|
||||||
|
{
|
||||||
|
// This function checks if the file specified in fileName exists in the
|
||||||
|
// current dir. It does so by simply doing an NLST (via GetList).
|
||||||
|
// If this succeeds (and the list is not empty) the file exists.
|
||||||
|
|
||||||
|
bool retval = FALSE;
|
||||||
|
wxArrayString fileList;
|
||||||
|
|
||||||
|
if ( GetList(fileList, fileName, FALSE) )
|
||||||
|
{
|
||||||
|
// Some ftp-servers (Ipswitch WS_FTP Server 1.0.5 does this)
|
||||||
|
// displays this behaviour when queried on a non-existing file:
|
||||||
|
// NLST this_file_does_not_exist
|
||||||
|
// 150 Opening ASCII data connection for directory listing
|
||||||
|
// (no data transferred)
|
||||||
|
// 226 Transfer complete
|
||||||
|
// Here wxFTP::GetList(...) will succeed but it will return an empty
|
||||||
|
// list.
|
||||||
|
retval = !fileList.IsEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// FTP GetSize
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int wxFTP::GetFileSize(const wxString& fileName)
|
||||||
|
{
|
||||||
|
// return the filesize of the given file if possible
|
||||||
|
// return -1 otherwise (predominantly if file doesn't exist
|
||||||
|
// in current dir)
|
||||||
|
|
||||||
|
int filesize = -1;
|
||||||
|
|
||||||
|
// Check for existance of file via wxFTP::FileExists(...)
|
||||||
|
if ( FileExists(fileName) )
|
||||||
|
{
|
||||||
|
wxString command;
|
||||||
|
|
||||||
|
// First try "SIZE" command using BINARY(IMAGE) transfermode
|
||||||
|
// Especially UNIX ftp-servers distinguish between the different
|
||||||
|
// transfermodes and reports different filesizes accordingly.
|
||||||
|
// The BINARY size is the interesting one: How much memory
|
||||||
|
// will we need to hold this file?
|
||||||
|
TransferMode oldTransfermode = m_currentTransfermode;
|
||||||
|
SetTransferMode(BINARY);
|
||||||
|
command << _T("SIZE ") << fileName;
|
||||||
|
|
||||||
|
bool ok = CheckCommand(command, '2');
|
||||||
|
|
||||||
|
if ( ok )
|
||||||
|
{
|
||||||
|
// The answer should be one line: "213 <filesize>\n"
|
||||||
|
// 213 is File Status (STD9)
|
||||||
|
// "SIZE" is not described anywhere..? It works on most servers
|
||||||
|
int statuscode;
|
||||||
|
if ( wxSscanf(GetLastResult().c_str(), _T("%i %i"),
|
||||||
|
&statuscode, &filesize) == 2 )
|
||||||
|
{
|
||||||
|
// We've gotten a good reply.
|
||||||
|
ok = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Something bad happened.. A "2yz" reply with no size
|
||||||
|
// Fallback
|
||||||
|
ok = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set transfermode back to the original. Only the "SIZE"-command
|
||||||
|
// is dependant on transfermode
|
||||||
|
if ( oldTransfermode != NONE )
|
||||||
|
{
|
||||||
|
SetTransferMode(oldTransfermode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !ok ) // this is not a direct else clause.. The size command might return an invalid "2yz" reply
|
||||||
|
{
|
||||||
|
// The server didn't understand the "SIZE"-command or it
|
||||||
|
// returned an invalid reply.
|
||||||
|
// We now try to get details for the file with a "LIST"-command
|
||||||
|
// and then parse the output from there..
|
||||||
|
wxArrayString fileList;
|
||||||
|
if ( GetList(fileList, fileName, TRUE) )
|
||||||
|
{
|
||||||
|
if ( !fileList.IsEmpty() )
|
||||||
|
{
|
||||||
|
// We _should_ only get one line in return, but just to be
|
||||||
|
// safe we run through the line(s) returned and look for a
|
||||||
|
// substring containing the name we are looking for. We
|
||||||
|
// stop the iteration at the first occurrence of the
|
||||||
|
// filename. The search is not case-sensitive.
|
||||||
|
bool foundIt = FALSE;
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
for ( i = 0; !foundIt && i < fileList.Count(); i++ )
|
||||||
|
{
|
||||||
|
foundIt = fileList[i].Upper().Contains(fileName.Upper());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( foundIt )
|
||||||
|
{
|
||||||
|
// The index i points to the first occurrence of
|
||||||
|
// fileName in the array Now we have to find out what
|
||||||
|
// format the LIST has returned. There are two
|
||||||
|
// "schools": Unix-like
|
||||||
|
//
|
||||||
|
// '-rw-rw-rw- owner group size month day time filename'
|
||||||
|
//
|
||||||
|
// or Windows-like
|
||||||
|
//
|
||||||
|
// 'date size filename'
|
||||||
|
|
||||||
|
// check if the first character is '-'. This would
|
||||||
|
// indicate Unix-style (this also limits this function
|
||||||
|
// to searching for files, not directories)
|
||||||
|
if ( fileList[i].Mid(0, 1) == _T("-") )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( wxSscanf(fileList[i].c_str(),
|
||||||
|
_("%*s %*s %*s %*s %i %*s %*s %*s %*s"),
|
||||||
|
&filesize) == 9 )
|
||||||
|
{
|
||||||
|
// We've gotten a good response
|
||||||
|
ok = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Hmm... Invalid response
|
||||||
|
wxLogTrace(FTP_TRACE_MASK,
|
||||||
|
_T("Invalid LIST response"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Windows-style response (?)
|
||||||
|
{
|
||||||
|
if ( wxSscanf(fileList[i].c_str(),
|
||||||
|
_T("%*s %*s %i %*s"),
|
||||||
|
&filesize) == 4 )
|
||||||
|
{
|
||||||
|
// valid response
|
||||||
|
ok = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// something bad happened..?
|
||||||
|
wxLogTrace(FTP_TRACE_MASK,
|
||||||
|
_T("Invalid or unknown LIST response"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// filesize might still be -1 when exiting
|
||||||
|
return filesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef WXWIN_COMPATIBILITY_2
|
#ifdef WXWIN_COMPATIBILITY_2
|
||||||
// deprecated
|
// deprecated
|
||||||
wxList *wxFTP::GetList(const wxString& wildcard, bool details)
|
wxList *wxFTP::GetList(const wxString& wildcard, bool details)
|
||||||
|
Reference in New Issue
Block a user