]>
git.saurik.com Git - wxWidgets.git/blob - src/common/ftp.cpp
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"
28 #if defined(__WXMAC__)
29 #include "/wx/mac/macsock.h"
33 #include "wx/string.h"
35 #include "wx/sckaddr.h"
36 #include "wx/socket.h"
38 #include "wx/sckstrm.h"
39 #include "wx/protocol/protocol.h"
40 #include "wx/protocol/ftp.h"
46 #define FTP_BSIZE 1024
48 IMPLEMENT_DYNAMIC_CLASS(wxFTP
, wxProtocol
)
49 IMPLEMENT_PROTOCOL(wxFTP
, wxT("ftp"), wxT("ftp"), TRUE
)
51 ////////////////////////////////////////////////////////////////
52 ////// wxFTP constructor and destructor ////////////////////////
53 ////////////////////////////////////////////////////////////////
58 m_lastError
= wxPROTO_NOERR
;
61 m_user
= wxT("anonymous");
62 m_passwd
= wxGetUserId();
64 m_passwd
+= wxGetHostName();
67 SetFlags(wxSOCKET_NONE
);
72 SendCommand("QUIT", '2');
75 ////////////////////////////////////////////////////////////////
76 ////// wxFTP connect and login methods /////////////////////////
77 ////////////////////////////////////////////////////////////////
78 bool wxFTP::Connect(wxSockAddress
& addr
, bool WXUNUSED(wait
))
80 if (!wxProtocol::Connect(addr
)) {
81 m_lastError
= wxPROTO_NETERR
;
85 if (!m_user
|| !m_passwd
) {
86 m_lastError
= wxPROTO_CONNERR
;
92 if (!GetResult('2')) {
97 command
.sprintf(wxT("USER %s"), (const wxChar
*)m_user
);
98 if (!SendCommand(command
, '3')) {
103 command
.sprintf(wxT("PASS %s"), (const wxChar
*)m_passwd
);
104 if (!SendCommand(command
, '2')) {
112 bool wxFTP::Connect(const wxString
& host
)
115 wxString my_host
= host
;
117 addr
.Hostname(my_host
);
118 addr
.Service(wxT("ftp"));
120 return Connect(addr
);
126 m_lastError
= wxPROTO_STREAMING
;
130 SendCommand(wxString(wxT("QUIT")), '2');
132 return wxSocketClient::Close();
135 ////////////////////////////////////////////////////////////////
136 ////// wxFTP low-level methods /////////////////////////////////
137 ////////////////////////////////////////////////////////////////
138 bool wxFTP::SendCommand(const wxString
& command
, char exp_ret
)
143 m_lastError
= wxPROTO_STREAMING
;
146 tmp_str
= command
+ wxT("\r\n");
147 const wxWX2MBbuf tmp_buf
= tmp_str
.mb_str();
148 if (Write(wxMBSTRINGCAST tmp_buf
, strlen(tmp_buf
)).Error()) {
149 m_lastError
= wxPROTO_NETERR
;
152 return GetResult(exp_ret
);
155 bool wxFTP::GetResult(char exp
)
157 m_lastError
= GetLine(this, m_lastResult
);
160 if (m_lastResult
.GetChar(0) != exp
) {
161 m_lastError
= wxPROTO_PROTERR
;
165 if (m_lastResult
.GetChar(3) == '-') {
166 wxString key
= m_lastResult
.Left((size_t)3);
170 while (m_lastResult
.Index(key
) != 0) {
171 m_lastError
= GetLine(this, m_lastResult
);
179 ////////////////////////////////////////////////////////////////
180 ////// wxFTP low-level methods /////////////////////////////////
181 ////////////////////////////////////////////////////////////////
182 bool wxFTP::ChDir(const wxString
& dir
)
186 str
.Prepend(wxT("CWD "));
187 return SendCommand(str
, '2');
190 bool wxFTP::MkDir(const wxString
& dir
)
193 str
.Prepend(wxT("MKD "));
194 return SendCommand(str
, '2');
197 bool wxFTP::RmDir(const wxString
& dir
)
201 str
.Prepend(wxT("PWD "));
202 return SendCommand(str
, '2');
205 wxString
wxFTP::Pwd()
209 if (!SendCommand(wxT("PWD"), '2'))
210 return wxString((char *)NULL
);
212 beg
= m_lastResult
.Find(wxT('\"'),FALSE
);
213 end
= m_lastResult
.Find(wxT('\"'),TRUE
);
215 return wxString(beg
+1, end
);
218 bool wxFTP::Rename(const wxString
& src
, const wxString
& dst
)
222 str
= wxT("RNFR ") + src
;
223 if (!SendCommand(str
, '3'))
226 str
= wxT("RNTO ") + dst
;
227 return SendCommand(str
, '2');
230 bool wxFTP::RmFile(const wxString
& path
)
236 return SendCommand(str
, '2');
239 ////////////////////////////////////////////////////////////////
240 ////// wxFTP download*upload ///////////////////////////////////
241 ////////////////////////////////////////////////////////////////
243 class wxInputFTPStream
: public wxSocketInputStream
{
248 wxInputFTPStream(wxFTP
*ftp_clt
, wxSocketBase
*sock
)
249 : wxSocketInputStream(*sock
), m_ftp(ftp_clt
) {}
250 size_t GetSize() const { return m_ftpsize
; }
251 virtual ~wxInputFTPStream(void)
253 if (LastError() == wxStream_NOERROR
)
254 m_ftp
->GetResult('2');
261 class wxOutputFTPStream
: public wxSocketOutputStream
{
265 wxOutputFTPStream(wxFTP
*ftp_clt
, wxSocketBase
*sock
)
266 : wxSocketOutputStream(*sock
), m_ftp(ftp_clt
) {}
267 virtual ~wxOutputFTPStream(void)
269 if (LastError() != wxStream_NOERROR
)
270 m_ftp
->GetResult('2');
277 wxSocketClient
*wxFTP::GetPort()
280 wxSocketClient
*client
;
287 if (!SendCommand(wxT("PASV"), '2'))
290 addr_pos
= m_lastResult
.Find(wxT('('));
291 if (addr_pos
== -1) {
292 m_lastError
= wxPROTO_PROTERR
;
295 straddr
= m_lastResult(addr_pos
+1, m_lastResult
.Length());
296 wxSscanf((const wxChar
*)straddr
,wxT("%d,%d,%d,%d,%d,%d"),&a
[2],&a
[3],&a
[4],&a
[5],&a
[0],&a
[1]);
298 hostaddr
= (wxUint16
)a
[5] << 24 | (wxUint16
)a
[4] << 16 |
299 (wxUint16
)a
[3] << 8 | a
[2];
300 addr
.Hostname(hostaddr
);
302 port
= (wxUint16
)a
[0] << 8 | a
[1];
305 client
= new wxSocketClient();
306 if (!client
->Connect(addr
)) {
310 client
->Notify(FALSE
);
315 bool wxFTP::Abort(void)
318 if (!SendCommand(wxT("ABOR"), '4'))
320 return GetResult('2');
323 wxInputStream
*wxFTP::GetInputStream(const wxString
& path
)
327 wxInputFTPStream
*in_stream
;
329 if (!SendCommand(wxT("TYPE I"), '2'))
332 wxSocketClient
*sock
= GetPort();
335 m_lastError
= wxPROTO_NETERR
;
339 tmp_str
= wxT("RETR ") + wxURL::ConvertFromURI(path
);
340 if (!SendCommand(tmp_str
, '1'))
343 in_stream
= new wxInputFTPStream(this, sock
);
345 pos_size
= m_lastResult
.Index(wxT('('));
346 if (pos_size
!= wxNOT_FOUND
) {
347 wxString str_size
= m_lastResult(pos_size
+1, m_lastResult
.Index(wxT(')'))-1);
349 in_stream
->m_ftpsize
= wxAtoi(WXSTRINGCAST str_size
);
351 sock
->SetFlags(wxSOCKET_WAITALL
);
356 wxOutputStream
*wxFTP::GetOutputStream(const wxString
& path
)
360 if (!SendCommand(wxT("TYPE I"), '2'))
363 wxSocketClient
*sock
= GetPort();
365 tmp_str
= wxT("STOR ") + path
;
366 if (!SendCommand(tmp_str
, '1'))
369 return new wxOutputFTPStream(this, sock
);
372 wxList
*wxFTP::GetList(const wxString
& wildcard
)
374 wxList
*file_list
= new wxList
;
375 wxSocketBase
*sock
= GetPort();
376 wxString tmp_str
= wxT("NLST");
378 if (!wildcard
.IsNull())
381 if (!SendCommand(tmp_str
, '1')) {
387 while (GetLine(sock
, tmp_str
) == wxPROTO_NOERR
) {
388 file_list
->Append((wxObject
*)(new wxString(tmp_str
)));
391 if (!GetResult('2')) {
393 file_list
->DeleteContents(TRUE
);