]>
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"
17 #include "wx/string.h"
19 // #include "wx/data.h"
20 #define WXSOCK_INTERNAL
21 #include "wx/sckaddr.h"
22 #undef WXSOCK_INTERNAL
23 #include "wx/socket.h"
25 #include "wx/sckstrm.h"
26 #include "wx/protocol/protocol.h"
27 #include "wx/protocol/ftp.h"
33 #define FTP_BSIZE 1024
35 #if !USE_SHARED_LIBRARY
36 IMPLEMENT_DYNAMIC_CLASS(wxFTP
, wxProtocol
)
37 IMPLEMENT_PROTOCOL(wxFTP
, "ftp", "ftp", TRUE
)
40 ////////////////////////////////////////////////////////////////
41 ////// wxFTP constructor and destructor ////////////////////////
42 ////////////////////////////////////////////////////////////////
49 m_lastError
= wxPROTO_NOERR
;
53 wxGetUserName(tmp
, 256);
54 m_passwd
.sprintf("%s@",tmp
);
55 wxGetHostName(tmp
, 256);
63 SendCommand("QUIT", '2');
66 ////////////////////////////////////////////////////////////////
67 ////// wxFTP connect and login methods /////////////////////////
68 ////////////////////////////////////////////////////////////////
69 bool wxFTP::Connect(wxSockAddress
& addr
)
72 m_lastError
= wxPROTO_NOHNDLR
;
76 if (!wxProtocol::Connect(addr
)) {
77 m_lastError
= wxPROTO_NETERR
;
81 if (!m_user
|| !m_passwd
) {
82 m_lastError
= wxPROTO_CONNERR
;
88 if (!GetResult('2')) {
93 command
.sprintf("USER %s", (const char *)m_user
);
94 if (!SendCommand(command
, '3')) {
99 command
.sprintf("PASS %s", (const char *)m_passwd
);
100 if (!SendCommand(command
, '2')) {
108 bool wxFTP::Connect(const wxString
& host
)
111 wxString my_host
= host
;
113 addr
.Hostname(my_host
);
116 return Connect(addr
);
122 m_lastError
= wxPROTO_STREAMING
;
126 SendCommand(wxString("QUIT"), '2');
127 return wxSocketClient::Close();
130 ////////////////////////////////////////////////////////////////
131 ////// wxFTP low-level methods /////////////////////////////////
132 ////////////////////////////////////////////////////////////////
133 bool wxFTP::SendCommand(const wxString
& command
, char exp_ret
)
138 m_lastError
= wxPROTO_STREAMING
;
141 tmp_str
= command
+ "\r\n";
142 if (Write((char *)tmp_str
.GetData(), tmp_str
.Length()).Error()) {
143 m_lastError
= wxPROTO_NETERR
;
146 return GetResult(exp_ret
);
149 bool wxFTP::GetResult(char exp
)
151 if ((m_lastError
= GetLine(this, m_lastResult
)))
153 if (m_lastResult
[0UL] != exp
) {
154 m_lastError
= wxPROTO_PROTERR
;
158 if (m_lastResult
[3UL] == '-') {
159 wxString key
= m_lastResult
.Left((size_t)3);
163 while (m_lastResult
.Index(key
) != 0) {
164 if ((m_lastError
= GetLine(this, m_lastResult
)))
171 ////////////////////////////////////////////////////////////////
172 ////// wxFTP low-level methods /////////////////////////////////
173 ////////////////////////////////////////////////////////////////
174 bool wxFTP::ChDir(const wxString
& dir
)
179 return SendCommand(str
, '2');
182 bool wxFTP::MkDir(const wxString
& dir
)
186 return SendCommand(str
, '2');
189 bool wxFTP::RmDir(const wxString
& dir
)
194 return SendCommand(str
, '2');
197 wxString
wxFTP::Pwd()
201 if (!SendCommand("PWD", '2'))
202 return wxString((char *)NULL
);
204 beg
= m_lastResult
.Find('\"',FALSE
);
205 end
= m_lastResult
.Find('\"',TRUE
);
207 return wxString(beg
+1, end
);
210 bool wxFTP::Rename(const wxString
& src
, const wxString
& dst
)
215 if (!SendCommand(str
, '3'))
219 return SendCommand(str
, '2');
222 bool wxFTP::RmFile(const wxString
& path
)
228 return SendCommand(str
, '2');
231 ////////////////////////////////////////////////////////////////
232 ////// wxFTP download*upload ///////////////////////////////////
233 ////////////////////////////////////////////////////////////////
235 class wxInputFTPStream
: public wxSocketInputStream
{
239 wxInputFTPStream(wxFTP
*ftp_clt
, wxSocketBase
*sock
)
240 : wxSocketInputStream(*sock
), m_ftp(ftp_clt
) {}
241 virtual ~wxInputFTPStream(void)
244 m_ftp
->GetResult('2');
251 class wxOutputFTPStream
: public wxSocketOutputStream
{
255 wxOutputFTPStream(wxFTP
*ftp_clt
, wxSocketBase
*sock
)
256 : wxSocketOutputStream(*sock
), m_ftp(ftp_clt
) {}
257 virtual ~wxOutputFTPStream(void)
260 m_ftp
->GetResult('2');
267 wxSocketClient
*wxFTP::GetPort()
270 wxSocketClient
*client
;
276 if (!SendCommand("PASV", '2'))
279 sin
.sa_family
= AF_INET
;
280 addr_pos
= m_lastResult
.Find('(');
281 if (addr_pos
== -1) {
282 m_lastError
= wxPROTO_PROTERR
;
285 straddr
= m_lastResult(addr_pos
+1, m_lastResult
.Length());
286 sscanf((const char *)straddr
,"%d,%d,%d,%d,%d,%d",&a
[2],&a
[3],&a
[4],&a
[5],&a
[0],&a
[1]);
287 sin
.sa_data
[2] = (char)a
[2];
288 sin
.sa_data
[3] = (char)a
[3];
289 sin
.sa_data
[4] = (char)a
[4];
290 sin
.sa_data
[5] = (char)a
[5];
291 sin
.sa_data
[0] = (char)a
[0];
292 sin
.sa_data
[1] = (char)a
[1];
294 addr
.Disassemble(&sin
, sizeof(sin
));
296 client
= m_handler
->CreateClient();
297 if (!client
->Connect(addr
)) {
301 client
->Notify(FALSE
);
306 bool wxFTP::Abort(void)
309 if (!SendCommand("ABOR", '4'))
311 return GetResult('2');
314 wxInputStream
*wxFTP::GetInputStream(const wxString
& path
)
318 if (!SendCommand("TYPE I", '2'))
321 wxSocketClient
*sock
= GetPort();
324 m_lastError
= wxPROTO_NETERR
;
328 tmp_str
= "RETR " + path
;
329 if (!SendCommand(tmp_str
, '1'))
332 return new wxInputFTPStream(this, sock
);
335 wxOutputStream
*wxFTP::GetOutputStream(const wxString
& path
)
339 if (!SendCommand("TYPE I", '2'))
342 wxSocketClient
*sock
= GetPort();
344 tmp_str
= "STOR " + path
;
345 if (!SendCommand(tmp_str
, '1'))
348 return new wxOutputFTPStream(this, sock
);
351 wxList
*wxFTP::GetList(const wxString
& wildcard
)
353 wxList
*file_list
= new wxList
;
354 wxSocketBase
*sock
= GetPort();
355 wxString tmp_str
= "NLST";
357 if (!wildcard
.IsNull())
360 if (!SendCommand(tmp_str
, '1')) {
366 while (GetLine(sock
, tmp_str
) == wxPROTO_NOERR
) {
367 file_list
->Append((wxObject
*)(new wxString(tmp_str
)));
370 if (!GetResult('2')) {
372 file_list
->DeleteContents(TRUE
);