]>
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/data.h"
36 #define WXSOCK_INTERNAL
37 #include "wx/sckaddr.h"
38 #undef WXSOCK_INTERNAL
39 #include "wx/socket.h"
41 #include "wx/sckstrm.h"
42 #include "wx/protocol/protocol.h"
43 #include "wx/protocol/ftp.h"
49 #define FTP_BSIZE 1024
51 #if !USE_SHARED_LIBRARY
52 IMPLEMENT_DYNAMIC_CLASS(wxFTP
, wxProtocol
)
53 IMPLEMENT_PROTOCOL(wxFTP
, _T("ftp"), _T("ftp"), TRUE
)
56 ////////////////////////////////////////////////////////////////
57 ////// wxFTP constructor and destructor ////////////////////////
58 ////////////////////////////////////////////////////////////////
65 m_lastError
= wxPROTO_NOERR
;
68 m_user
= _T("anonymous");
69 wxGetUserName(tmp
, 256);
70 m_passwd
.sprintf(_T("%s@"),tmp
);
71 wxGetHostName(tmp
, 256);
79 SendCommand("QUIT", '2');
82 ////////////////////////////////////////////////////////////////
83 ////// wxFTP connect and login methods /////////////////////////
84 ////////////////////////////////////////////////////////////////
85 bool wxFTP::Connect(wxSockAddress
& addr
, bool WXUNUSED(wait
))
88 m_lastError
= wxPROTO_NOHNDLR
;
92 if (!wxProtocol::Connect(addr
)) {
93 m_lastError
= wxPROTO_NETERR
;
97 if (!m_user
|| !m_passwd
) {
98 m_lastError
= wxPROTO_CONNERR
;
104 if (!GetResult('2')) {
109 command
.sprintf(_T("USER %s"), (const wxChar
*)m_user
);
110 if (!SendCommand(command
, '3')) {
115 command
.sprintf(_T("PASS %s"), (const wxChar
*)m_passwd
);
116 if (!SendCommand(command
, '2')) {
124 bool wxFTP::Connect(const wxString
& host
)
127 wxString my_host
= host
;
129 addr
.Hostname(my_host
);
130 addr
.Service(_T("ftp"));
132 return Connect(addr
);
138 m_lastError
= wxPROTO_STREAMING
;
142 SendCommand(wxString(_T("QUIT")), '2');
143 return wxSocketClient::Close();
146 ////////////////////////////////////////////////////////////////
147 ////// wxFTP low-level methods /////////////////////////////////
148 ////////////////////////////////////////////////////////////////
149 bool wxFTP::SendCommand(const wxString
& command
, char exp_ret
)
154 m_lastError
= wxPROTO_STREAMING
;
157 tmp_str
= command
+ _T("\r\n");
158 const wxWX2MBbuf tmp_buf
= tmp_str
.mb_str();
159 if (Write(MBSTRINGCAST tmp_buf
, strlen(tmp_buf
)).Error()) {
160 m_lastError
= wxPROTO_NETERR
;
163 return GetResult(exp_ret
);
166 bool wxFTP::GetResult(char exp
)
168 if ((m_lastError
= GetLine(this, m_lastResult
)))
170 if (m_lastResult
.GetChar(0) != exp
) {
171 m_lastError
= wxPROTO_PROTERR
;
175 if (m_lastResult
.GetChar(3) == '-') {
176 wxString key
= m_lastResult
.Left((size_t)3);
180 while (m_lastResult
.Index(key
) != 0) {
181 if ((m_lastError
= GetLine(this, m_lastResult
)))
188 ////////////////////////////////////////////////////////////////
189 ////// wxFTP low-level methods /////////////////////////////////
190 ////////////////////////////////////////////////////////////////
191 bool wxFTP::ChDir(const wxString
& dir
)
195 str
.Prepend(_T("CWD "));
196 return SendCommand(str
, '2');
199 bool wxFTP::MkDir(const wxString
& dir
)
202 str
.Prepend(_T("MKD "));
203 return SendCommand(str
, '2');
206 bool wxFTP::RmDir(const wxString
& dir
)
210 str
.Prepend(_T("PWD "));
211 return SendCommand(str
, '2');
214 wxString
wxFTP::Pwd()
218 if (!SendCommand(_T("PWD"), '2'))
219 return wxString((char *)NULL
);
221 beg
= m_lastResult
.Find(_T('\"'),FALSE
);
222 end
= m_lastResult
.Find(_T('\"'),TRUE
);
224 return wxString(beg
+1, end
);
227 bool wxFTP::Rename(const wxString
& src
, const wxString
& dst
)
231 str
= _T("RNFR ") + src
;
232 if (!SendCommand(str
, '3'))
235 str
= _T("RNTO ") + dst
;
236 return SendCommand(str
, '2');
239 bool wxFTP::RmFile(const wxString
& path
)
245 return SendCommand(str
, '2');
248 ////////////////////////////////////////////////////////////////
249 ////// wxFTP download*upload ///////////////////////////////////
250 ////////////////////////////////////////////////////////////////
252 class wxInputFTPStream
: public wxSocketInputStream
{
257 wxInputFTPStream(wxFTP
*ftp_clt
, wxSocketBase
*sock
)
258 : wxSocketInputStream(*sock
), m_ftp(ftp_clt
) {}
259 size_t StreamSize() const { return m_ftpsize
; }
260 virtual ~wxInputFTPStream(void)
262 if (LastError() != wxStream_NOERROR
)
263 m_ftp
->GetResult('2');
270 class wxOutputFTPStream
: public wxSocketOutputStream
{
274 wxOutputFTPStream(wxFTP
*ftp_clt
, wxSocketBase
*sock
)
275 : wxSocketOutputStream(*sock
), m_ftp(ftp_clt
) {}
276 virtual ~wxOutputFTPStream(void)
278 if (LastError() != wxStream_NOERROR
)
279 m_ftp
->GetResult('2');
286 wxSocketClient
*wxFTP::GetPort()
289 wxSocketClient
*client
;
295 if (!SendCommand(_T("PASV"), '2'))
298 sin
.sa_family
= AF_INET
;
299 addr_pos
= m_lastResult
.Find(_T('('));
300 if (addr_pos
== -1) {
301 m_lastError
= wxPROTO_PROTERR
;
304 straddr
= m_lastResult(addr_pos
+1, m_lastResult
.Length());
305 wxSscanf((const wxChar
*)straddr
,_T("%d,%d,%d,%d,%d,%d"),&a
[2],&a
[3],&a
[4],&a
[5],&a
[0],&a
[1]);
306 sin
.sa_data
[2] = (char)a
[2];
307 sin
.sa_data
[3] = (char)a
[3];
308 sin
.sa_data
[4] = (char)a
[4];
309 sin
.sa_data
[5] = (char)a
[5];
310 sin
.sa_data
[0] = (char)a
[0];
311 sin
.sa_data
[1] = (char)a
[1];
313 addr
.Disassemble(&sin
, sizeof(sin
));
315 client
= m_handler
->CreateClient();
316 if (!client
->Connect(addr
)) {
320 client
->Notify(FALSE
);
325 bool wxFTP::Abort(void)
328 if (!SendCommand(_T("ABOR"), '4'))
330 return GetResult('2');
333 wxInputStream
*wxFTP::GetInputStream(const wxString
& path
)
337 wxInputFTPStream
*in_stream
;
339 if (!SendCommand(_T("TYPE I"), '2'))
342 wxSocketClient
*sock
= GetPort();
345 m_lastError
= wxPROTO_NETERR
;
349 tmp_str
= _T("RETR ") + path
;
350 if (!SendCommand(tmp_str
, '1'))
353 in_stream
= new wxInputFTPStream(this, sock
);
355 pos_size
= m_lastResult
.Index(_T('('));
356 if (pos_size
!= wxNOT_FOUND
) {
357 wxString str_size
= m_lastResult(pos_size
+1, m_lastResult
.Index(_T(')'))-1);
359 in_stream
->m_ftpsize
= wxAtoi(WXSTRINGCAST str_size
);
365 wxOutputStream
*wxFTP::GetOutputStream(const wxString
& path
)
369 if (!SendCommand(_T("TYPE I"), '2'))
372 wxSocketClient
*sock
= GetPort();
374 tmp_str
= _T("STOR ") + path
;
375 if (!SendCommand(tmp_str
, '1'))
378 return new wxOutputFTPStream(this, sock
);
381 wxList
*wxFTP::GetList(const wxString
& wildcard
)
383 wxList
*file_list
= new wxList
;
384 wxSocketBase
*sock
= GetPort();
385 wxString tmp_str
= _T("NLST");
387 if (!wildcard
.IsNull())
390 if (!SendCommand(tmp_str
, '1')) {
396 while (GetLine(sock
, tmp_str
) == wxPROTO_NOERR
) {
397 file_list
->Append((wxObject
*)(new wxString(tmp_str
)));
400 if (!GetResult('2')) {
402 file_list
->DeleteContents(TRUE
);
407 sock
->SetEventHandler(*GetNextHandler(), m_id
);
408 sock
->Notify(m_notifyme
);
409 sock
->SetNotify(m_neededreq
);