]>
git.saurik.com Git - wxWidgets.git/blob - src/common/ftp.cpp
d0b2a80211366cb6a46014c6f99d8231fa83a051
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: FTP protocol
4 // Author: Guilhem Lavaux
8 // Copyright: (c) 1997, 1998 Guilhem Lavaux
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "ftp.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
26 #if defined(__WXMAC__)
27 #include "/wx/mac/macsock.h"
31 #include "wx/string.h"
33 // #include "wx/data.h"
34 #define WXSOCK_INTERNAL
35 #include "wx/sckaddr.h"
36 #undef WXSOCK_INTERNAL
37 #include "wx/socket.h"
39 #include "wx/sckstrm.h"
40 #include "wx/protocol/protocol.h"
41 #include "wx/protocol/ftp.h"
47 #define FTP_BSIZE 1024
49 #if !USE_SHARED_LIBRARY
50 IMPLEMENT_DYNAMIC_CLASS(wxFTP
, wxProtocol
)
51 IMPLEMENT_PROTOCOL(wxFTP
, "ftp", "ftp", TRUE
)
54 ////////////////////////////////////////////////////////////////
55 ////// wxFTP constructor and destructor ////////////////////////
56 ////////////////////////////////////////////////////////////////
63 m_lastError
= wxPROTO_NOERR
;
67 wxGetUserName(tmp
, 256);
68 m_passwd
.sprintf("%s@",tmp
);
69 wxGetHostName(tmp
, 256);
77 SendCommand("QUIT", '2');
80 ////////////////////////////////////////////////////////////////
81 ////// wxFTP connect and login methods /////////////////////////
82 ////////////////////////////////////////////////////////////////
83 bool wxFTP::Connect(wxSockAddress
& addr
, bool WXUNUSED(wait
))
86 m_lastError
= wxPROTO_NOHNDLR
;
90 if (!wxProtocol::Connect(addr
)) {
91 m_lastError
= wxPROTO_NETERR
;
95 if (!m_user
|| !m_passwd
) {
96 m_lastError
= wxPROTO_CONNERR
;
102 if (!GetResult('2')) {
107 command
.sprintf("USER %s", (const char *)m_user
);
108 if (!SendCommand(command
, '3')) {
113 command
.sprintf("PASS %s", (const char *)m_passwd
);
114 if (!SendCommand(command
, '2')) {
122 bool wxFTP::Connect(const wxString
& host
)
125 wxString my_host
= host
;
127 addr
.Hostname(my_host
);
130 return Connect(addr
);
136 m_lastError
= wxPROTO_STREAMING
;
140 SendCommand(wxString("QUIT"), '2');
141 return wxSocketClient::Close();
144 ////////////////////////////////////////////////////////////////
145 ////// wxFTP low-level methods /////////////////////////////////
146 ////////////////////////////////////////////////////////////////
147 bool wxFTP::SendCommand(const wxString
& command
, char exp_ret
)
152 m_lastError
= wxPROTO_STREAMING
;
155 tmp_str
= command
+ "\r\n";
156 if (Write((char *)tmp_str
.GetData(), tmp_str
.Length()).Error()) {
157 m_lastError
= wxPROTO_NETERR
;
160 return GetResult(exp_ret
);
163 bool wxFTP::GetResult(char exp
)
165 if ((m_lastError
= GetLine(this, m_lastResult
)))
167 if (m_lastResult
.GetChar(0) != exp
) {
168 m_lastError
= wxPROTO_PROTERR
;
172 if (m_lastResult
.GetChar(3) == '-') {
173 wxString key
= m_lastResult
.Left((size_t)3);
177 while (m_lastResult
.Index(key
) != 0) {
178 if ((m_lastError
= GetLine(this, m_lastResult
)))
185 ////////////////////////////////////////////////////////////////
186 ////// wxFTP low-level methods /////////////////////////////////
187 ////////////////////////////////////////////////////////////////
188 bool wxFTP::ChDir(const wxString
& dir
)
193 return SendCommand(str
, '2');
196 bool wxFTP::MkDir(const wxString
& dir
)
200 return SendCommand(str
, '2');
203 bool wxFTP::RmDir(const wxString
& dir
)
208 return SendCommand(str
, '2');
211 wxString
wxFTP::Pwd()
215 if (!SendCommand("PWD", '2'))
216 return wxString((char *)NULL
);
218 beg
= m_lastResult
.Find('\"',FALSE
);
219 end
= m_lastResult
.Find('\"',TRUE
);
221 return wxString(beg
+1, end
);
224 bool wxFTP::Rename(const wxString
& src
, const wxString
& dst
)
229 if (!SendCommand(str
, '3'))
233 return SendCommand(str
, '2');
236 bool wxFTP::RmFile(const wxString
& path
)
242 return SendCommand(str
, '2');
245 ////////////////////////////////////////////////////////////////
246 ////// wxFTP download*upload ///////////////////////////////////
247 ////////////////////////////////////////////////////////////////
249 class wxInputFTPStream
: public wxSocketInputStream
{
254 wxInputFTPStream(wxFTP
*ftp_clt
, wxSocketBase
*sock
)
255 : wxSocketInputStream(*sock
), m_ftp(ftp_clt
) {}
256 size_t StreamSize() { return m_ftpsize
; }
257 virtual ~wxInputFTPStream(void)
259 if (LastError() != wxStream_NOERROR
)
260 m_ftp
->GetResult('2');
267 class wxOutputFTPStream
: public wxSocketOutputStream
{
271 wxOutputFTPStream(wxFTP
*ftp_clt
, wxSocketBase
*sock
)
272 : wxSocketOutputStream(*sock
), m_ftp(ftp_clt
) {}
273 virtual ~wxOutputFTPStream(void)
275 if (LastError() != wxStream_NOERROR
)
276 m_ftp
->GetResult('2');
283 wxSocketClient
*wxFTP::GetPort()
286 wxSocketClient
*client
;
292 if (!SendCommand("PASV", '2'))
295 sin
.sa_family
= AF_INET
;
296 addr_pos
= m_lastResult
.Find('(');
297 if (addr_pos
== -1) {
298 m_lastError
= wxPROTO_PROTERR
;
301 straddr
= m_lastResult(addr_pos
+1, m_lastResult
.Length());
302 sscanf((const char *)straddr
,"%d,%d,%d,%d,%d,%d",&a
[2],&a
[3],&a
[4],&a
[5],&a
[0],&a
[1]);
303 sin
.sa_data
[2] = (char)a
[2];
304 sin
.sa_data
[3] = (char)a
[3];
305 sin
.sa_data
[4] = (char)a
[4];
306 sin
.sa_data
[5] = (char)a
[5];
307 sin
.sa_data
[0] = (char)a
[0];
308 sin
.sa_data
[1] = (char)a
[1];
310 addr
.Disassemble(&sin
, sizeof(sin
));
312 client
= m_handler
->CreateClient();
313 if (!client
->Connect(addr
)) {
317 client
->Notify(FALSE
);
322 bool wxFTP::Abort(void)
325 if (!SendCommand("ABOR", '4'))
327 return GetResult('2');
330 wxInputStream
*wxFTP::GetInputStream(const wxString
& path
)
334 wxInputFTPStream
*in_stream
;
336 if (!SendCommand("TYPE I", '2'))
339 wxSocketClient
*sock
= GetPort();
342 m_lastError
= wxPROTO_NETERR
;
346 tmp_str
= "RETR " + path
;
347 if (!SendCommand(tmp_str
, '1'))
350 in_stream
= new wxInputFTPStream(this, sock
);
352 pos_size
= m_lastResult
.Index('(');
353 if (pos_size
!= wxNOT_FOUND
) {
354 wxString str_size
= m_lastResult(pos_size
, m_lastResult
.Index(')'));
356 in_stream
->m_ftpsize
= atoi(WXSTRINGCAST str_size
);
362 wxOutputStream
*wxFTP::GetOutputStream(const wxString
& path
)
366 if (!SendCommand("TYPE I", '2'))
369 wxSocketClient
*sock
= GetPort();
371 tmp_str
= "STOR " + path
;
372 if (!SendCommand(tmp_str
, '1'))
375 return new wxOutputFTPStream(this, sock
);
378 wxList
*wxFTP::GetList(const wxString
& wildcard
)
380 wxList
*file_list
= new wxList
;
381 wxSocketBase
*sock
= GetPort();
382 wxString tmp_str
= "NLST";
384 if (!wildcard
.IsNull())
387 if (!SendCommand(tmp_str
, '1')) {
393 while (GetLine(sock
, tmp_str
) == wxPROTO_NOERR
) {
394 file_list
->Append((wxObject
*)(new wxString(tmp_str
)));
397 if (!GetResult('2')) {
399 file_list
->DeleteContents(TRUE
);