12f86921cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
32f86921cSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
42f86921cSAndrew Rist * or more contributor license agreements. See the NOTICE file
52f86921cSAndrew Rist * distributed with this work for additional information
62f86921cSAndrew Rist * regarding copyright ownership. The ASF licenses this file
72f86921cSAndrew Rist * to you under the Apache License, Version 2.0 (the
82f86921cSAndrew Rist * "License"); you may not use this file except in compliance
92f86921cSAndrew Rist * with the License. You may obtain a copy of the License at
102f86921cSAndrew Rist *
112f86921cSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
122f86921cSAndrew Rist *
132f86921cSAndrew Rist * Unless required by applicable law or agreed to in writing,
142f86921cSAndrew Rist * software distributed under the License is distributed on an
152f86921cSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
162f86921cSAndrew Rist * KIND, either express or implied. See the License for the
172f86921cSAndrew Rist * specific language governing permissions and limitations
182f86921cSAndrew Rist * under the License.
192f86921cSAndrew Rist *
202f86921cSAndrew Rist *************************************************************/
212f86921cSAndrew Rist
222f86921cSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_ucb.hxx"
26cdf0e10cSrcweir /**************************************************************************
27cdf0e10cSrcweir TODO
28cdf0e10cSrcweir **************************************************************************
29cdf0e10cSrcweir
30cdf0e10cSrcweir *************************************************************************/
31cdf0e10cSrcweir
32cdf0e10cSrcweir #include <memory>
33cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
34cdf0e10cSrcweir #include <com/sun/star/ucb/OpenMode.hpp>
35cdf0e10cSrcweir #include <string.h>
36cdf0e10cSrcweir #include <rtl/uri.hxx>
37cdf0e10cSrcweir
38cdf0e10cSrcweir #include "ftpstrcont.hxx"
39cdf0e10cSrcweir #include "ftpurl.hxx"
40cdf0e10cSrcweir #include "ftphandleprovider.hxx"
41cdf0e10cSrcweir #include "ftpinpstr.hxx"
42cdf0e10cSrcweir #include "ftpcfunc.hxx"
43cdf0e10cSrcweir #include "ftpcontainer.hxx"
44cdf0e10cSrcweir
45cdf0e10cSrcweir using namespace ftp;
46cdf0e10cSrcweir using namespace com::sun::star::ucb;
47cdf0e10cSrcweir using namespace com::sun::star::uno;
48cdf0e10cSrcweir using namespace com::sun::star::io;
49cdf0e10cSrcweir
50cdf0e10cSrcweir namespace {
51cdf0e10cSrcweir
encodePathSegment(rtl::OUString const & decoded)52cdf0e10cSrcweir rtl::OUString encodePathSegment(rtl::OUString const & decoded) {
53cdf0e10cSrcweir return rtl::Uri::encode(
54cdf0e10cSrcweir decoded, rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes,
55cdf0e10cSrcweir RTL_TEXTENCODING_UTF8);
56cdf0e10cSrcweir }
57cdf0e10cSrcweir
decodePathSegment(rtl::OUString const & encoded)58cdf0e10cSrcweir rtl::OUString decodePathSegment(rtl::OUString const & encoded) {
59cdf0e10cSrcweir return rtl::Uri::decode(
60cdf0e10cSrcweir encoded, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
61cdf0e10cSrcweir }
62cdf0e10cSrcweir
63cdf0e10cSrcweir }
64cdf0e10cSrcweir
MemoryContainer()65cdf0e10cSrcweir MemoryContainer::MemoryContainer()
66cdf0e10cSrcweir : m_nLen(0),
67cdf0e10cSrcweir m_nWritePos(0),
68cdf0e10cSrcweir m_pBuffer(0)
69cdf0e10cSrcweir {
70cdf0e10cSrcweir }
71cdf0e10cSrcweir
~MemoryContainer()72cdf0e10cSrcweir MemoryContainer::~MemoryContainer()
73cdf0e10cSrcweir {
74cdf0e10cSrcweir rtl_freeMemory(m_pBuffer);
75cdf0e10cSrcweir }
76cdf0e10cSrcweir
77cdf0e10cSrcweir
append(const void * pBuffer,size_t size,size_t nmemb)78cdf0e10cSrcweir int MemoryContainer::append(
79cdf0e10cSrcweir const void* pBuffer,
80cdf0e10cSrcweir size_t size,
81cdf0e10cSrcweir size_t nmemb
82cdf0e10cSrcweir ) throw()
83cdf0e10cSrcweir {
84cdf0e10cSrcweir sal_uInt32 nLen = size*nmemb;
85cdf0e10cSrcweir sal_uInt32 tmp(nLen + m_nWritePos);
86cdf0e10cSrcweir
87cdf0e10cSrcweir if(m_nLen < tmp) { // enlarge in steps of multiples of 1K
88cdf0e10cSrcweir do {
89cdf0e10cSrcweir m_nLen+=1024;
90cdf0e10cSrcweir } while(m_nLen < tmp);
91cdf0e10cSrcweir
92cdf0e10cSrcweir m_pBuffer = rtl_reallocateMemory(m_pBuffer,m_nLen);
93cdf0e10cSrcweir }
94cdf0e10cSrcweir
95cdf0e10cSrcweir rtl_copyMemory(static_cast<sal_Int8*>(m_pBuffer)+m_nWritePos,
96cdf0e10cSrcweir pBuffer,nLen);
97cdf0e10cSrcweir m_nWritePos = tmp;
98cdf0e10cSrcweir return nLen;
99cdf0e10cSrcweir }
100cdf0e10cSrcweir
101cdf0e10cSrcweir
102cdf0e10cSrcweir extern "C" {
103cdf0e10cSrcweir
memory_write(void * buffer,size_t size,size_t nmemb,void * stream)104cdf0e10cSrcweir int memory_write(void *buffer,size_t size,size_t nmemb,void *stream)
105cdf0e10cSrcweir {
106cdf0e10cSrcweir MemoryContainer *_stream =
107cdf0e10cSrcweir reinterpret_cast<MemoryContainer*>(stream);
108cdf0e10cSrcweir
109cdf0e10cSrcweir if(!_stream)
110cdf0e10cSrcweir return 0;
111cdf0e10cSrcweir
112cdf0e10cSrcweir return _stream->append(buffer,size,nmemb);
113cdf0e10cSrcweir }
114cdf0e10cSrcweir
115cdf0e10cSrcweir }
116cdf0e10cSrcweir
117cdf0e10cSrcweir
FTPURL(const FTPURL & r)118cdf0e10cSrcweir FTPURL::FTPURL(const FTPURL& r)
119cdf0e10cSrcweir : m_mutex(),
120cdf0e10cSrcweir m_pFCP(r.m_pFCP),
121cdf0e10cSrcweir m_aUsername(r.m_aUsername),
122cdf0e10cSrcweir m_bShowPassword(r.m_bShowPassword),
123cdf0e10cSrcweir m_aHost(r.m_aHost),
124cdf0e10cSrcweir m_aPort(r.m_aPort),
125cdf0e10cSrcweir m_aPathSegmentVec(r.m_aPathSegmentVec)
126cdf0e10cSrcweir
127cdf0e10cSrcweir {
128cdf0e10cSrcweir }
129cdf0e10cSrcweir
130cdf0e10cSrcweir
FTPURL(const rtl::OUString & url,FTPHandleProvider * pFCP)131cdf0e10cSrcweir FTPURL::FTPURL(const rtl::OUString& url,
132cdf0e10cSrcweir FTPHandleProvider* pFCP)
133cdf0e10cSrcweir throw(
134cdf0e10cSrcweir malformed_exception
135cdf0e10cSrcweir )
136cdf0e10cSrcweir : m_pFCP(pFCP),
137cdf0e10cSrcweir m_aUsername(rtl::OUString::createFromAscii("anonymous")),
138cdf0e10cSrcweir m_bShowPassword(false),
139cdf0e10cSrcweir m_aPort(rtl::OUString::createFromAscii("21"))
140cdf0e10cSrcweir {
141cdf0e10cSrcweir parse(url); // can reset m_bShowPassword
142cdf0e10cSrcweir }
143cdf0e10cSrcweir
144cdf0e10cSrcweir
~FTPURL()145cdf0e10cSrcweir FTPURL::~FTPURL()
146cdf0e10cSrcweir {
147cdf0e10cSrcweir }
148cdf0e10cSrcweir
149cdf0e10cSrcweir
parse(const rtl::OUString & url)150cdf0e10cSrcweir void FTPURL::parse(const rtl::OUString& url)
151cdf0e10cSrcweir throw(
152cdf0e10cSrcweir malformed_exception
153cdf0e10cSrcweir )
154cdf0e10cSrcweir {
155cdf0e10cSrcweir rtl::OUString aPassword,aAccount;
156cdf0e10cSrcweir rtl::OString aIdent(url.getStr(),
157cdf0e10cSrcweir url.getLength(),
158cdf0e10cSrcweir RTL_TEXTENCODING_UTF8);
159cdf0e10cSrcweir
160cdf0e10cSrcweir rtl::OString lower = aIdent.toAsciiLowerCase();
161cdf0e10cSrcweir if(lower.getLength() < 6 ||
162cdf0e10cSrcweir strncmp("ftp://",lower.getStr(),6))
163cdf0e10cSrcweir throw malformed_exception();
164cdf0e10cSrcweir
165cdf0e10cSrcweir char *buffer = new char[1+aIdent.getLength()];
166cdf0e10cSrcweir const char* p2 = aIdent.getStr();
167cdf0e10cSrcweir p2 += 6;
168cdf0e10cSrcweir
169cdf0e10cSrcweir char ch;
170cdf0e10cSrcweir char *p1 = buffer; // determine "username:password@host:port"
171cdf0e10cSrcweir while((ch = *p2++) != '/' && ch)
172cdf0e10cSrcweir *p1++ = ch;
173cdf0e10cSrcweir *p1 = 0;
174cdf0e10cSrcweir
175cdf0e10cSrcweir rtl::OUString aExpr(rtl::OUString(buffer,strlen(buffer),
176cdf0e10cSrcweir RTL_TEXTENCODING_UTF8));
177cdf0e10cSrcweir
178cdf0e10cSrcweir sal_Int32 l = aExpr.indexOf(sal_Unicode('@'));
179cdf0e10cSrcweir m_aHost = aExpr.copy(1+l);
180cdf0e10cSrcweir
181cdf0e10cSrcweir if(l != -1) {
182cdf0e10cSrcweir // Now username and password.
183cdf0e10cSrcweir aExpr = aExpr.copy(0,l);
184cdf0e10cSrcweir l = aExpr.indexOf(sal_Unicode(':'));
185cdf0e10cSrcweir if(l != -1) {
186cdf0e10cSrcweir aPassword = aExpr.copy(1+l);
187cdf0e10cSrcweir if(aPassword.getLength())
188cdf0e10cSrcweir m_bShowPassword = true;
189cdf0e10cSrcweir }
190cdf0e10cSrcweir if(l > 0)
191cdf0e10cSrcweir // Overwritte only if the username is not empty.
192cdf0e10cSrcweir m_aUsername = aExpr.copy(0,l);
193cdf0e10cSrcweir else if(aExpr.getLength())
194cdf0e10cSrcweir m_aUsername = aExpr;
195cdf0e10cSrcweir }
196cdf0e10cSrcweir
197cdf0e10cSrcweir l = m_aHost.lastIndexOf(sal_Unicode(':'));
198cdf0e10cSrcweir sal_Int32 ipv6Back = m_aHost.lastIndexOf(sal_Unicode(']'));
199cdf0e10cSrcweir if((ipv6Back == -1 && l != -1) // not ipv6, but a port
200cdf0e10cSrcweir ||
201cdf0e10cSrcweir (ipv6Back != -1 && 1+ipv6Back == l) // ipv6, and a port
202cdf0e10cSrcweir )
203cdf0e10cSrcweir {
204cdf0e10cSrcweir if(1+l<m_aHost.getLength())
205cdf0e10cSrcweir m_aPort = m_aHost.copy(1+l);
206cdf0e10cSrcweir m_aHost = m_aHost.copy(0,l);
207cdf0e10cSrcweir }
208cdf0e10cSrcweir
209cdf0e10cSrcweir while(ch) { // now determine the pathsegments ...
210cdf0e10cSrcweir p1 = buffer;
211cdf0e10cSrcweir while((ch = *p2++) != '/' && ch)
212cdf0e10cSrcweir *p1++ = ch;
213cdf0e10cSrcweir *p1 = 0;
214cdf0e10cSrcweir
215cdf0e10cSrcweir if(buffer[0]) {
216cdf0e10cSrcweir if(strcmp(buffer,"..") == 0 &&
217cdf0e10cSrcweir m_aPathSegmentVec.size() &&
218cdf0e10cSrcweir ! m_aPathSegmentVec.back().equalsAscii(".."))
219cdf0e10cSrcweir m_aPathSegmentVec.pop_back();
220cdf0e10cSrcweir else if(strcmp(buffer,".") == 0)
221cdf0e10cSrcweir ; // Ignore
222cdf0e10cSrcweir else
223cdf0e10cSrcweir // This is a legal name.
224cdf0e10cSrcweir m_aPathSegmentVec.push_back(
225cdf0e10cSrcweir rtl::OUString(buffer,
226cdf0e10cSrcweir strlen(buffer),
227cdf0e10cSrcweir RTL_TEXTENCODING_UTF8));
228cdf0e10cSrcweir }
229cdf0e10cSrcweir }
230cdf0e10cSrcweir
231cdf0e10cSrcweir delete[] buffer;
232cdf0e10cSrcweir
233cdf0e10cSrcweir if(m_bShowPassword)
234cdf0e10cSrcweir m_pFCP->setHost(m_aHost,
235cdf0e10cSrcweir m_aPort,
236cdf0e10cSrcweir m_aUsername,
237cdf0e10cSrcweir aPassword,
238cdf0e10cSrcweir aAccount);
239cdf0e10cSrcweir
240cdf0e10cSrcweir // now check for something like ";type=i" at end of url
241cdf0e10cSrcweir if(m_aPathSegmentVec.size() &&
242cdf0e10cSrcweir (l = m_aPathSegmentVec.back().indexOf(sal_Unicode(';'))) != -1) {
243cdf0e10cSrcweir m_aType = m_aPathSegmentVec.back().copy(l);
244cdf0e10cSrcweir m_aPathSegmentVec.back() = m_aPathSegmentVec.back().copy(0,l);
245cdf0e10cSrcweir }
246cdf0e10cSrcweir }
247cdf0e10cSrcweir
248cdf0e10cSrcweir
ident(bool withslash,bool internal) const249cdf0e10cSrcweir rtl::OUString FTPURL::ident(bool withslash,bool internal) const
250cdf0e10cSrcweir {
251cdf0e10cSrcweir // rebuild the url as one without ellipses,
252cdf0e10cSrcweir // and more important, as one without username and
253cdf0e10cSrcweir // password. ( These are set together with the command. )
254cdf0e10cSrcweir
255cdf0e10cSrcweir rtl::OUStringBuffer bff;
256cdf0e10cSrcweir bff.appendAscii("ftp://");
257cdf0e10cSrcweir
258cdf0e10cSrcweir if(!m_aUsername.equalsAscii("anonymous")) {
259cdf0e10cSrcweir bff.append(m_aUsername);
260cdf0e10cSrcweir
261cdf0e10cSrcweir rtl::OUString aPassword,aAccount;
262cdf0e10cSrcweir m_pFCP->forHost(m_aHost,
263cdf0e10cSrcweir m_aPort,
264cdf0e10cSrcweir m_aUsername,
265cdf0e10cSrcweir aPassword,
266cdf0e10cSrcweir aAccount);
267cdf0e10cSrcweir
268cdf0e10cSrcweir if((m_bShowPassword || internal) &&
269cdf0e10cSrcweir aPassword.getLength() )
270cdf0e10cSrcweir bff.append(sal_Unicode(':'))
271cdf0e10cSrcweir .append(aPassword);
272cdf0e10cSrcweir
273cdf0e10cSrcweir bff.append(sal_Unicode('@'));
274cdf0e10cSrcweir }
275cdf0e10cSrcweir bff.append(m_aHost);
276cdf0e10cSrcweir
277cdf0e10cSrcweir if(!m_aPort.equalsAscii("21"))
278cdf0e10cSrcweir bff.append(sal_Unicode(':'))
279cdf0e10cSrcweir .append(m_aPort)
280cdf0e10cSrcweir .append(sal_Unicode('/'));
281cdf0e10cSrcweir else
282cdf0e10cSrcweir bff.append(sal_Unicode('/'));
283cdf0e10cSrcweir
284cdf0e10cSrcweir for(unsigned i = 0; i < m_aPathSegmentVec.size(); ++i)
285cdf0e10cSrcweir if(i == 0)
286cdf0e10cSrcweir bff.append(m_aPathSegmentVec[i]);
287cdf0e10cSrcweir else
288cdf0e10cSrcweir bff.append(sal_Unicode('/')).append(m_aPathSegmentVec[i]);
289cdf0e10cSrcweir if(withslash)
290cdf0e10cSrcweir if(bff.getLength() && bff[bff.getLength()-1] != sal_Unicode('/'))
291cdf0e10cSrcweir bff.append(sal_Unicode('/'));
292cdf0e10cSrcweir
293cdf0e10cSrcweir bff.append(m_aType);
294cdf0e10cSrcweir return bff.makeStringAndClear();
295cdf0e10cSrcweir }
296cdf0e10cSrcweir
297cdf0e10cSrcweir
parent(bool internal) const298cdf0e10cSrcweir rtl::OUString FTPURL::parent(bool internal) const
299cdf0e10cSrcweir {
300cdf0e10cSrcweir rtl::OUStringBuffer bff;
301cdf0e10cSrcweir
302cdf0e10cSrcweir bff.appendAscii("ftp://");
303cdf0e10cSrcweir
304cdf0e10cSrcweir if(!m_aUsername.equalsAscii("anonymous")) {
305cdf0e10cSrcweir bff.append(m_aUsername);
306cdf0e10cSrcweir
307cdf0e10cSrcweir rtl::OUString aPassword,aAccount;
308cdf0e10cSrcweir m_pFCP->forHost(m_aHost,
309cdf0e10cSrcweir m_aPort,
310cdf0e10cSrcweir m_aUsername,
311cdf0e10cSrcweir aPassword,
312cdf0e10cSrcweir aAccount);
313cdf0e10cSrcweir
314cdf0e10cSrcweir if((internal || m_bShowPassword) && aPassword.getLength())
315cdf0e10cSrcweir bff.append(sal_Unicode(':'))
316cdf0e10cSrcweir .append(aPassword);
317cdf0e10cSrcweir
318cdf0e10cSrcweir bff.append(sal_Unicode('@'));
319cdf0e10cSrcweir }
320cdf0e10cSrcweir
321cdf0e10cSrcweir bff.append(m_aHost);
322cdf0e10cSrcweir
323cdf0e10cSrcweir if(!m_aPort.equalsAscii("21"))
324cdf0e10cSrcweir bff.append(sal_Unicode(':'))
325cdf0e10cSrcweir .append(m_aPort)
326cdf0e10cSrcweir .append(sal_Unicode('/'));
327cdf0e10cSrcweir else
328cdf0e10cSrcweir bff.append(sal_Unicode('/'));
329cdf0e10cSrcweir
330cdf0e10cSrcweir rtl::OUString last;
331cdf0e10cSrcweir
332cdf0e10cSrcweir for(unsigned int i = 0; i < m_aPathSegmentVec.size(); ++i)
333cdf0e10cSrcweir if(1+i == m_aPathSegmentVec.size())
334cdf0e10cSrcweir last = m_aPathSegmentVec[i];
335cdf0e10cSrcweir else if(i == 0)
336cdf0e10cSrcweir bff.append(m_aPathSegmentVec[i]);
337cdf0e10cSrcweir else
338cdf0e10cSrcweir bff.append(sal_Unicode('/')).append(m_aPathSegmentVec[i]);
339cdf0e10cSrcweir
340cdf0e10cSrcweir if(!last.getLength())
341cdf0e10cSrcweir bff.appendAscii("..");
342cdf0e10cSrcweir else if(last.equalsAscii(".."))
343cdf0e10cSrcweir bff.append(last).appendAscii("/..");
344cdf0e10cSrcweir
345cdf0e10cSrcweir bff.append(m_aType);
346cdf0e10cSrcweir return bff.makeStringAndClear();
347cdf0e10cSrcweir }
348cdf0e10cSrcweir
349cdf0e10cSrcweir
child(const rtl::OUString & title)350cdf0e10cSrcweir void FTPURL::child(const rtl::OUString& title)
351cdf0e10cSrcweir {
352cdf0e10cSrcweir m_aPathSegmentVec.push_back(encodePathSegment(title));
353cdf0e10cSrcweir }
354cdf0e10cSrcweir
355cdf0e10cSrcweir
child() const356cdf0e10cSrcweir rtl::OUString FTPURL::child() const
357cdf0e10cSrcweir {
358cdf0e10cSrcweir return
359cdf0e10cSrcweir m_aPathSegmentVec.size() ?
360cdf0e10cSrcweir decodePathSegment(m_aPathSegmentVec.back()) : rtl::OUString();
361cdf0e10cSrcweir }
362cdf0e10cSrcweir
363cdf0e10cSrcweir
364cdf0e10cSrcweir
365cdf0e10cSrcweir /** Listing of a directory.
366cdf0e10cSrcweir */
367cdf0e10cSrcweir
368cdf0e10cSrcweir namespace ftp {
369cdf0e10cSrcweir
370cdf0e10cSrcweir enum OS {
371cdf0e10cSrcweir FTP_DOS,FTP_UNIX,FTP_VMS,FTP_UNKNOWN
372cdf0e10cSrcweir };
373cdf0e10cSrcweir
374cdf0e10cSrcweir }
375cdf0e10cSrcweir
376cdf0e10cSrcweir
377cdf0e10cSrcweir #define SET_CONTROL_CONTAINER \
378cdf0e10cSrcweir MemoryContainer control; \
379cdf0e10cSrcweir curl_easy_setopt(curl, \
380cdf0e10cSrcweir CURLOPT_HEADERFUNCTION, \
381cdf0e10cSrcweir memory_write); \
382cdf0e10cSrcweir curl_easy_setopt(curl, \
383cdf0e10cSrcweir CURLOPT_WRITEHEADER, \
384cdf0e10cSrcweir &control)
385cdf0e10cSrcweir
386cdf0e10cSrcweir
387cdf0e10cSrcweir #define SET_DATA_CONTAINER \
388cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_NOBODY,false); \
389cdf0e10cSrcweir MemoryContainer data; \
390cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,memory_write); \
391cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_WRITEDATA,&data)
392cdf0e10cSrcweir
393cdf0e10cSrcweir #define SET_URL(url) \
394cdf0e10cSrcweir rtl::OString urlParAscii(url.getStr(), \
395cdf0e10cSrcweir url.getLength(), \
396cdf0e10cSrcweir RTL_TEXTENCODING_UTF8); \
397cdf0e10cSrcweir curl_easy_setopt(curl, \
398cdf0e10cSrcweir CURLOPT_URL, \
399cdf0e10cSrcweir urlParAscii.getStr());
400cdf0e10cSrcweir
401cdf0e10cSrcweir // Setting username:password
402cdf0e10cSrcweir #define SET_USER_PASSWORD(username,password) \
403cdf0e10cSrcweir rtl::OUString combi(username + \
404cdf0e10cSrcweir rtl::OUString::createFromAscii(":") + \
405cdf0e10cSrcweir password); \
406cdf0e10cSrcweir rtl::OString aUserPsswd(combi.getStr(), \
407cdf0e10cSrcweir combi.getLength(), \
408cdf0e10cSrcweir RTL_TEXTENCODING_UTF8); \
409cdf0e10cSrcweir curl_easy_setopt(curl, \
410cdf0e10cSrcweir CURLOPT_USERPWD, \
411cdf0e10cSrcweir aUserPsswd.getStr())
412cdf0e10cSrcweir
413cdf0e10cSrcweir
414cdf0e10cSrcweir
open()415*72cd26ddSAriel Constenla-Haile oslFileHandle FTPURL::open()
416cdf0e10cSrcweir throw(curl_exception)
417cdf0e10cSrcweir {
418cdf0e10cSrcweir if(!m_aPathSegmentVec.size())
419cdf0e10cSrcweir throw curl_exception(CURLE_FTP_COULDNT_RETR_FILE);
420cdf0e10cSrcweir
421cdf0e10cSrcweir CURL *curl = m_pFCP->handle();
422cdf0e10cSrcweir
423cdf0e10cSrcweir SET_CONTROL_CONTAINER;
424cdf0e10cSrcweir rtl::OUString url(ident(false,true));
425cdf0e10cSrcweir SET_URL(url);
426*72cd26ddSAriel Constenla-Haile
427*72cd26ddSAriel Constenla-Haile oslFileHandle res( NULL );
428*72cd26ddSAriel Constenla-Haile if ( osl_createTempFile( NULL, &res, NULL ) == osl_File_E_None )
429*72cd26ddSAriel Constenla-Haile {
430*72cd26ddSAriel Constenla-Haile curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,file_write);
431*72cd26ddSAriel Constenla-Haile curl_easy_setopt(curl,CURLOPT_WRITEDATA,res);
432*72cd26ddSAriel Constenla-Haile
433*72cd26ddSAriel Constenla-Haile curl_easy_setopt(curl,CURLOPT_POSTQUOTE,0);
434*72cd26ddSAriel Constenla-Haile CURLcode err = curl_easy_perform(curl);
435*72cd26ddSAriel Constenla-Haile
436*72cd26ddSAriel Constenla-Haile if(err == CURLE_OK)
437*72cd26ddSAriel Constenla-Haile osl_setFilePos( res, osl_Pos_Absolut, 0 );
438*72cd26ddSAriel Constenla-Haile else {
439*72cd26ddSAriel Constenla-Haile osl_closeFile(res),res = 0;
440*72cd26ddSAriel Constenla-Haile throw curl_exception(err);
441*72cd26ddSAriel Constenla-Haile }
442cdf0e10cSrcweir }
443cdf0e10cSrcweir
444cdf0e10cSrcweir return res;
445cdf0e10cSrcweir }
446cdf0e10cSrcweir
447cdf0e10cSrcweir
list(sal_Int16 nMode) const448cdf0e10cSrcweir std::vector<FTPDirentry> FTPURL::list(
449cdf0e10cSrcweir sal_Int16 nMode
450cdf0e10cSrcweir ) const
451cdf0e10cSrcweir throw(
452cdf0e10cSrcweir curl_exception
453cdf0e10cSrcweir )
454cdf0e10cSrcweir {
455cdf0e10cSrcweir CURL *curl = m_pFCP->handle();
456cdf0e10cSrcweir
457cdf0e10cSrcweir SET_CONTROL_CONTAINER;
458cdf0e10cSrcweir SET_DATA_CONTAINER;
459cdf0e10cSrcweir rtl::OUString url(ident(true,true));
460cdf0e10cSrcweir SET_URL(url);
461cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_POSTQUOTE,0);
462cdf0e10cSrcweir
463cdf0e10cSrcweir CURLcode err = curl_easy_perform(curl);
464cdf0e10cSrcweir if(err != CURLE_OK)
465cdf0e10cSrcweir throw curl_exception(err);
466cdf0e10cSrcweir
467cdf0e10cSrcweir // now evaluate the error messages
468cdf0e10cSrcweir
469cdf0e10cSrcweir sal_uInt32 len = data.m_nWritePos;
470cdf0e10cSrcweir char* fwd = (char*) data.m_pBuffer;
471cdf0e10cSrcweir rtl::OString str(fwd,len);
472cdf0e10cSrcweir char *p1, *p2;
473cdf0e10cSrcweir p1 = p2 = fwd;
474cdf0e10cSrcweir
475cdf0e10cSrcweir OS osKind(FTP_UNKNOWN);
476cdf0e10cSrcweir std::vector<FTPDirentry> resvec;
477cdf0e10cSrcweir FTPDirentry aDirEntry;
478cdf0e10cSrcweir // ensure slash at the end
479cdf0e10cSrcweir rtl::OUString viewurl(ident(true,false));
480cdf0e10cSrcweir
481cdf0e10cSrcweir while(true) {
482cdf0e10cSrcweir while(p2-fwd < int(len) && *p2 != '\n') ++p2;
483cdf0e10cSrcweir if(p2-fwd == int(len)) break;
484cdf0e10cSrcweir
485cdf0e10cSrcweir *p2 = 0;
486cdf0e10cSrcweir switch(osKind) {
487cdf0e10cSrcweir // While FTP knows the 'system'-command,
488cdf0e10cSrcweir // which returns the operating system type,
489cdf0e10cSrcweir // this is not usable here: There are Windows-server
490cdf0e10cSrcweir // formatting the output like UNIX-ls command.
491cdf0e10cSrcweir case FTP_DOS:
492cdf0e10cSrcweir FTPDirectoryParser::parseDOS(aDirEntry,p1);
493cdf0e10cSrcweir break;
494cdf0e10cSrcweir case FTP_UNIX:
495cdf0e10cSrcweir FTPDirectoryParser::parseUNIX(aDirEntry,p1);
496cdf0e10cSrcweir break;
497cdf0e10cSrcweir case FTP_VMS:
498cdf0e10cSrcweir FTPDirectoryParser::parseVMS(aDirEntry,p1);
499cdf0e10cSrcweir break;
500cdf0e10cSrcweir default:
501cdf0e10cSrcweir if(FTPDirectoryParser::parseUNIX(aDirEntry,p1))
502cdf0e10cSrcweir osKind = FTP_UNIX;
503cdf0e10cSrcweir else if(FTPDirectoryParser::parseDOS(aDirEntry,p1))
504cdf0e10cSrcweir osKind = FTP_DOS;
505cdf0e10cSrcweir else if(FTPDirectoryParser::parseVMS(aDirEntry,p1))
506cdf0e10cSrcweir osKind = FTP_VMS;
507cdf0e10cSrcweir }
508cdf0e10cSrcweir aDirEntry.m_aName = aDirEntry.m_aName.trim();
509cdf0e10cSrcweir if(osKind != int(FTP_UNKNOWN) &&
510cdf0e10cSrcweir !aDirEntry.m_aName.equalsAscii("..") &&
511cdf0e10cSrcweir !aDirEntry.m_aName.equalsAscii(".")) {
512cdf0e10cSrcweir aDirEntry.m_aURL = viewurl + encodePathSegment(aDirEntry.m_aName);
513cdf0e10cSrcweir
514cdf0e10cSrcweir sal_Bool isDir =
515cdf0e10cSrcweir sal_Bool(aDirEntry.m_nMode&INETCOREFTP_FILEMODE_ISDIR);
516cdf0e10cSrcweir switch(nMode) {
517cdf0e10cSrcweir case OpenMode::DOCUMENTS:
518cdf0e10cSrcweir if(!isDir)
519cdf0e10cSrcweir resvec.push_back(aDirEntry);
520cdf0e10cSrcweir break;
521cdf0e10cSrcweir case OpenMode::FOLDERS:
522cdf0e10cSrcweir if(isDir)
523cdf0e10cSrcweir resvec.push_back(aDirEntry);
524cdf0e10cSrcweir break;
525cdf0e10cSrcweir default:
526cdf0e10cSrcweir resvec.push_back(aDirEntry);
527cdf0e10cSrcweir };
528cdf0e10cSrcweir }
529cdf0e10cSrcweir aDirEntry.clear();
530cdf0e10cSrcweir p1 = p2 + 1;
531cdf0e10cSrcweir }
532cdf0e10cSrcweir
533cdf0e10cSrcweir return resvec;
534cdf0e10cSrcweir }
535cdf0e10cSrcweir
536cdf0e10cSrcweir
net_title() const537cdf0e10cSrcweir rtl::OUString FTPURL::net_title() const
538cdf0e10cSrcweir throw(curl_exception)
539cdf0e10cSrcweir {
540cdf0e10cSrcweir CURL *curl = m_pFCP->handle();
541cdf0e10cSrcweir
542cdf0e10cSrcweir SET_CONTROL_CONTAINER;
543cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
544cdf0e10cSrcweir struct curl_slist *slist = 0;
545cdf0e10cSrcweir // post request
546cdf0e10cSrcweir slist = curl_slist_append(slist,"PWD");
547cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
548cdf0e10cSrcweir
549cdf0e10cSrcweir bool try_more(true);
550cdf0e10cSrcweir CURLcode err;
551cdf0e10cSrcweir rtl::OUString aNetTitle;
552cdf0e10cSrcweir
553cdf0e10cSrcweir while(true) {
554cdf0e10cSrcweir rtl::OUString url(ident(false,true));
555cdf0e10cSrcweir
556cdf0e10cSrcweir if(try_more &&
557cdf0e10cSrcweir 1+url.lastIndexOf(sal_Unicode('/')) != url.getLength())
558cdf0e10cSrcweir url += rtl::OUString::createFromAscii("/"); // add end-slash
559cdf0e10cSrcweir else if(!try_more &&
560cdf0e10cSrcweir 1+url.lastIndexOf(sal_Unicode('/')) == url.getLength())
561cdf0e10cSrcweir url = url.copy(0,url.getLength()-1); // remove end-slash
562cdf0e10cSrcweir
563cdf0e10cSrcweir SET_URL(url);
564cdf0e10cSrcweir err = curl_easy_perform(curl);
565cdf0e10cSrcweir
566cdf0e10cSrcweir if(err == CURLE_OK) { // get the title from the server
567cdf0e10cSrcweir char* fwd = (char*) control.m_pBuffer;
568cdf0e10cSrcweir sal_uInt32 len = (sal_uInt32) control.m_nWritePos;
569cdf0e10cSrcweir
570cdf0e10cSrcweir aNetTitle = rtl::OUString(fwd,len,RTL_TEXTENCODING_UTF8);
571cdf0e10cSrcweir // the buffer now contains the name of the file;
572cdf0e10cSrcweir // analyze the output:
573cdf0e10cSrcweir // Format of current working directory:
574cdf0e10cSrcweir // 257 "/bla/bla" is current directory
575cdf0e10cSrcweir sal_Int32 index1 = aNetTitle.lastIndexOf(
576cdf0e10cSrcweir rtl::OUString::createFromAscii("257"));
577cdf0e10cSrcweir index1 = 1+aNetTitle.indexOf(sal_Unicode('"'),index1);
578cdf0e10cSrcweir sal_Int32 index2 = aNetTitle.indexOf(sal_Unicode('"'),index1);
579cdf0e10cSrcweir aNetTitle = aNetTitle.copy(index1,index2-index1);
580cdf0e10cSrcweir if(!aNetTitle.equalsAscii("/")) {
581cdf0e10cSrcweir index1 = aNetTitle.lastIndexOf(sal_Unicode('/'));
582cdf0e10cSrcweir aNetTitle = aNetTitle.copy(1+index1);
583cdf0e10cSrcweir }
584cdf0e10cSrcweir try_more = false;
585cdf0e10cSrcweir } else if(err == CURLE_BAD_PASSWORD_ENTERED)
586cdf0e10cSrcweir // the client should retry after getting the correct
587cdf0e10cSrcweir // username + password
588cdf0e10cSrcweir throw curl_exception(err);
589cdf0e10cSrcweir #if LIBCURL_VERSION_NUM>=0x070d01 /* 7.13.1 */
590cdf0e10cSrcweir else if(err == CURLE_LOGIN_DENIED)
591cdf0e10cSrcweir // the client should retry after getting the correct
592cdf0e10cSrcweir // username + password
593cdf0e10cSrcweir throw curl_exception(err);
594cdf0e10cSrcweir #endif
595cdf0e10cSrcweir else if(try_more && err == CURLE_FTP_ACCESS_DENIED) {
596cdf0e10cSrcweir // We were either denied access when trying to login to
597cdf0e10cSrcweir // an FTP server or when trying to change working directory
598cdf0e10cSrcweir // to the one given in the URL.
599cdf0e10cSrcweir if(m_aPathSegmentVec.size())
600cdf0e10cSrcweir // determine title form url
601cdf0e10cSrcweir aNetTitle = decodePathSegment(m_aPathSegmentVec.back());
602cdf0e10cSrcweir else
603cdf0e10cSrcweir // must be root
604cdf0e10cSrcweir aNetTitle = rtl::OUString::createFromAscii("/");
605cdf0e10cSrcweir try_more = false;
606cdf0e10cSrcweir }
607cdf0e10cSrcweir
608cdf0e10cSrcweir if(try_more)
609cdf0e10cSrcweir try_more = false;
610cdf0e10cSrcweir else
611cdf0e10cSrcweir break;
612cdf0e10cSrcweir }
613cdf0e10cSrcweir
614cdf0e10cSrcweir curl_slist_free_all(slist);
615cdf0e10cSrcweir return aNetTitle;
616cdf0e10cSrcweir }
617cdf0e10cSrcweir
618cdf0e10cSrcweir
direntry() const619cdf0e10cSrcweir FTPDirentry FTPURL::direntry() const
620cdf0e10cSrcweir throw(curl_exception)
621cdf0e10cSrcweir {
622cdf0e10cSrcweir rtl::OUString nettitle = net_title();
623cdf0e10cSrcweir FTPDirentry aDirentry;
624cdf0e10cSrcweir
625cdf0e10cSrcweir aDirentry.m_aName = nettitle; // init aDirentry
626cdf0e10cSrcweir if(nettitle.equalsAscii("/") ||
627cdf0e10cSrcweir nettitle.equalsAscii(".."))
628cdf0e10cSrcweir aDirentry.m_nMode = INETCOREFTP_FILEMODE_ISDIR;
629cdf0e10cSrcweir else
630cdf0e10cSrcweir aDirentry.m_nMode = INETCOREFTP_FILEMODE_UNKNOWN;
631cdf0e10cSrcweir
632cdf0e10cSrcweir aDirentry.m_nSize = 0;
633cdf0e10cSrcweir
634cdf0e10cSrcweir if(!nettitle.equalsAscii("/")) {
635cdf0e10cSrcweir // try to open the parent directory
636cdf0e10cSrcweir FTPURL aURL(parent(),m_pFCP);
637cdf0e10cSrcweir
638cdf0e10cSrcweir std::vector<FTPDirentry> aList = aURL.list(OpenMode::ALL);
639cdf0e10cSrcweir
640cdf0e10cSrcweir for(unsigned i = 0; i < aList.size(); ++i) {
641cdf0e10cSrcweir if(aList[i].m_aName == nettitle) { // the relevant file is found
642cdf0e10cSrcweir aDirentry = aList[i];
643cdf0e10cSrcweir break;
644cdf0e10cSrcweir }
645cdf0e10cSrcweir }
646cdf0e10cSrcweir }
647cdf0e10cSrcweir return aDirentry;
648cdf0e10cSrcweir }
649cdf0e10cSrcweir
650cdf0e10cSrcweir
651cdf0e10cSrcweir extern "C" {
652cdf0e10cSrcweir
memory_read(void * ptr,size_t size,size_t nmemb,void * stream)653cdf0e10cSrcweir size_t memory_read(void *ptr,size_t size,size_t nmemb,void *stream)
654cdf0e10cSrcweir {
655cdf0e10cSrcweir sal_Int32 nRequested = sal_Int32(size*nmemb);
656cdf0e10cSrcweir CurlInput *curlInput = static_cast<CurlInput*>(stream);
657cdf0e10cSrcweir if(curlInput)
658cdf0e10cSrcweir return size_t(curlInput->read(((sal_Int8*)ptr),nRequested));
659cdf0e10cSrcweir else
660cdf0e10cSrcweir return 0;
661cdf0e10cSrcweir }
662cdf0e10cSrcweir
663cdf0e10cSrcweir }
664cdf0e10cSrcweir
665cdf0e10cSrcweir
insert(bool replaceExisting,void * stream) const666cdf0e10cSrcweir void FTPURL::insert(bool replaceExisting,void* stream) const
667cdf0e10cSrcweir throw(curl_exception)
668cdf0e10cSrcweir {
669cdf0e10cSrcweir if(!replaceExisting) {
670cdf0e10cSrcweir // FTPDirentry aDirentry(direntry());
671cdf0e10cSrcweir // if(aDirentry.m_nMode == INETCOREFTP_FILEMODE_UNKNOWN)
672cdf0e10cSrcweir // throw curl_exception(FILE_EXIST_DURING_INSERT);
673cdf0e10cSrcweir throw curl_exception(FILE_MIGHT_EXIST_DURING_INSERT);
674cdf0e10cSrcweir } // else
675cdf0e10cSrcweir // overwrite is default in libcurl
676cdf0e10cSrcweir
677cdf0e10cSrcweir CURL *curl = m_pFCP->handle();
678cdf0e10cSrcweir
679cdf0e10cSrcweir SET_CONTROL_CONTAINER;
680cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_NOBODY,false); // no data => no transfer
681cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_POSTQUOTE,0);
682cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_QUOTE,0);
683cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_READFUNCTION,memory_read);
684cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_READDATA,stream);
685cdf0e10cSrcweir curl_easy_setopt(curl, CURLOPT_UPLOAD,1);
686cdf0e10cSrcweir
687cdf0e10cSrcweir rtl::OUString url(ident(false,true));
688cdf0e10cSrcweir SET_URL(url);
689cdf0e10cSrcweir
690cdf0e10cSrcweir CURLcode err = curl_easy_perform(curl);
691cdf0e10cSrcweir curl_easy_setopt(curl, CURLOPT_UPLOAD,false);
692cdf0e10cSrcweir
693cdf0e10cSrcweir if(err != CURLE_OK)
694cdf0e10cSrcweir throw curl_exception(err);
695cdf0e10cSrcweir }
696cdf0e10cSrcweir
697cdf0e10cSrcweir
698cdf0e10cSrcweir
mkdir(bool ReplaceExisting) const699cdf0e10cSrcweir void FTPURL::mkdir(bool ReplaceExisting) const
700cdf0e10cSrcweir throw(curl_exception)
701cdf0e10cSrcweir {
702cdf0e10cSrcweir rtl::OString title;
703cdf0e10cSrcweir if(m_aPathSegmentVec.size()) {
704cdf0e10cSrcweir rtl::OUString titleOU = m_aPathSegmentVec.back();
705cdf0e10cSrcweir titleOU = decodePathSegment(titleOU);
706cdf0e10cSrcweir title = rtl::OString(titleOU.getStr(),
707cdf0e10cSrcweir titleOU.getLength(),
708cdf0e10cSrcweir RTL_TEXTENCODING_UTF8);
709cdf0e10cSrcweir }
710cdf0e10cSrcweir else
711cdf0e10cSrcweir // will give an error
712cdf0e10cSrcweir title = rtl::OString("/");
713cdf0e10cSrcweir
714cdf0e10cSrcweir rtl::OString aDel("del "); aDel += title;
715cdf0e10cSrcweir rtl::OString mkd("mkd "); mkd += title;
716cdf0e10cSrcweir
717cdf0e10cSrcweir struct curl_slist *slist = 0;
718cdf0e10cSrcweir
719cdf0e10cSrcweir FTPDirentry aDirentry(direntry());
720cdf0e10cSrcweir if(!ReplaceExisting) {
721cdf0e10cSrcweir // if(aDirentry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN)
722cdf0e10cSrcweir // throw curl_exception(FOLDER_EXIST_DURING_INSERT);
723cdf0e10cSrcweir throw curl_exception(FOLDER_MIGHT_EXIST_DURING_INSERT);
724cdf0e10cSrcweir } else if(aDirentry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN)
725cdf0e10cSrcweir slist = curl_slist_append(slist,aDel.getStr());
726cdf0e10cSrcweir
727cdf0e10cSrcweir slist = curl_slist_append(slist,mkd.getStr());
728cdf0e10cSrcweir
729cdf0e10cSrcweir CURL *curl = m_pFCP->handle();
730cdf0e10cSrcweir SET_CONTROL_CONTAINER;
731cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
732cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_QUOTE,0);
733cdf0e10cSrcweir
734cdf0e10cSrcweir // post request
735cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
736cdf0e10cSrcweir
737cdf0e10cSrcweir rtl::OUString url(parent(true));
738cdf0e10cSrcweir if(1+url.lastIndexOf(sal_Unicode('/')) != url.getLength())
739cdf0e10cSrcweir url += rtl::OUString::createFromAscii("/");
740cdf0e10cSrcweir SET_URL(url);
741cdf0e10cSrcweir
742cdf0e10cSrcweir CURLcode err = curl_easy_perform(curl);
743cdf0e10cSrcweir curl_slist_free_all(slist);
744cdf0e10cSrcweir if(err != CURLE_OK)
745cdf0e10cSrcweir throw curl_exception(err);
746cdf0e10cSrcweir }
747cdf0e10cSrcweir
748cdf0e10cSrcweir
ren(const rtl::OUString & NewTitle)749cdf0e10cSrcweir rtl::OUString FTPURL::ren(const rtl::OUString& NewTitle)
750cdf0e10cSrcweir throw(curl_exception)
751cdf0e10cSrcweir {
752cdf0e10cSrcweir CURL *curl = m_pFCP->handle();
753cdf0e10cSrcweir
754cdf0e10cSrcweir // post request
755cdf0e10cSrcweir rtl::OString renamefrom("RNFR ");
756cdf0e10cSrcweir rtl::OUString OldTitle = net_title();
757cdf0e10cSrcweir renamefrom +=
758cdf0e10cSrcweir rtl::OString(OldTitle.getStr(),
759cdf0e10cSrcweir OldTitle.getLength(),
760cdf0e10cSrcweir RTL_TEXTENCODING_UTF8);
761cdf0e10cSrcweir
762cdf0e10cSrcweir rtl::OString renameto("RNTO ");
763cdf0e10cSrcweir renameto +=
764cdf0e10cSrcweir rtl::OString(NewTitle.getStr(),
765cdf0e10cSrcweir NewTitle.getLength(),
766cdf0e10cSrcweir RTL_TEXTENCODING_UTF8);
767cdf0e10cSrcweir
768cdf0e10cSrcweir struct curl_slist *slist = 0;
769cdf0e10cSrcweir slist = curl_slist_append(slist,renamefrom.getStr());
770cdf0e10cSrcweir slist = curl_slist_append(slist,renameto.getStr());
771cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
772cdf0e10cSrcweir
773cdf0e10cSrcweir SET_CONTROL_CONTAINER;
774cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
775cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_QUOTE,0);
776cdf0e10cSrcweir
777cdf0e10cSrcweir rtl::OUString url(parent(true));
778cdf0e10cSrcweir if(1+url.lastIndexOf(sal_Unicode('/')) != url.getLength())
779cdf0e10cSrcweir url += rtl::OUString::createFromAscii("/");
780cdf0e10cSrcweir SET_URL(url);
781cdf0e10cSrcweir
782cdf0e10cSrcweir CURLcode err = curl_easy_perform(curl);
783cdf0e10cSrcweir curl_slist_free_all(slist);
784cdf0e10cSrcweir if(err != CURLE_OK)
785cdf0e10cSrcweir throw curl_exception(err);
786cdf0e10cSrcweir else if(m_aPathSegmentVec.size() &&
787cdf0e10cSrcweir !m_aPathSegmentVec.back().equalsAscii(".."))
788cdf0e10cSrcweir m_aPathSegmentVec.back() = encodePathSegment(NewTitle);
789cdf0e10cSrcweir return OldTitle;
790cdf0e10cSrcweir }
791cdf0e10cSrcweir
792cdf0e10cSrcweir
793cdf0e10cSrcweir
del() const794cdf0e10cSrcweir void FTPURL::del() const
795cdf0e10cSrcweir throw(curl_exception)
796cdf0e10cSrcweir {
797cdf0e10cSrcweir FTPDirentry aDirentry(direntry());
798cdf0e10cSrcweir
799cdf0e10cSrcweir rtl::OString dele(aDirentry.m_aName.getStr(),
800cdf0e10cSrcweir aDirentry.m_aName.getLength(),
801cdf0e10cSrcweir RTL_TEXTENCODING_UTF8);
802cdf0e10cSrcweir
803cdf0e10cSrcweir if(aDirentry.m_nMode & INETCOREFTP_FILEMODE_ISDIR) {
804cdf0e10cSrcweir std::vector<FTPDirentry> vec = list(sal_Int16(OpenMode::ALL));
805cdf0e10cSrcweir for( unsigned int i = 0; i < vec.size(); ++i )
806cdf0e10cSrcweir try {
807cdf0e10cSrcweir FTPURL url(vec[i].m_aURL,m_pFCP);
808cdf0e10cSrcweir url.del();
809cdf0e10cSrcweir } catch(const curl_exception&) {
810cdf0e10cSrcweir }
811cdf0e10cSrcweir dele = rtl::OString("RMD ") + dele;
812cdf0e10cSrcweir }
813cdf0e10cSrcweir else if(aDirentry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN)
814cdf0e10cSrcweir dele = rtl::OString("DELE ") + dele;
815cdf0e10cSrcweir else
816cdf0e10cSrcweir return;
817cdf0e10cSrcweir
818cdf0e10cSrcweir // post request
819cdf0e10cSrcweir CURL *curl = m_pFCP->handle();
820cdf0e10cSrcweir struct curl_slist *slist = 0;
821cdf0e10cSrcweir slist = curl_slist_append(slist,dele.getStr());
822cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
823cdf0e10cSrcweir
824cdf0e10cSrcweir SET_CONTROL_CONTAINER;
825cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
826cdf0e10cSrcweir curl_easy_setopt(curl,CURLOPT_QUOTE,0);
827cdf0e10cSrcweir
828cdf0e10cSrcweir rtl::OUString url(parent(true));
829cdf0e10cSrcweir if(1+url.lastIndexOf(sal_Unicode('/')) != url.getLength())
830cdf0e10cSrcweir url += rtl::OUString::createFromAscii("/");
831cdf0e10cSrcweir SET_URL(url);
832cdf0e10cSrcweir
833cdf0e10cSrcweir CURLcode err = curl_easy_perform(curl);
834cdf0e10cSrcweir curl_slist_free_all(slist);
835cdf0e10cSrcweir if(err != CURLE_OK)
836cdf0e10cSrcweir throw curl_exception(err);
837cdf0e10cSrcweir }
838cdf0e10cSrcweir
839