xref: /aoo42x/main/ucb/source/ucp/ftp/ftpurl.cxx (revision 72cd26dd)
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 
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 
58cdf0e10cSrcweir rtl::OUString decodePathSegment(rtl::OUString const & encoded) {
59cdf0e10cSrcweir     return rtl::Uri::decode(
60cdf0e10cSrcweir         encoded, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
63cdf0e10cSrcweir }
64cdf0e10cSrcweir 
65cdf0e10cSrcweir MemoryContainer::MemoryContainer()
66cdf0e10cSrcweir     : m_nLen(0),
67cdf0e10cSrcweir       m_nWritePos(0),
68cdf0e10cSrcweir       m_pBuffer(0)
69cdf0e10cSrcweir {
70cdf0e10cSrcweir }
71cdf0e10cSrcweir 
72cdf0e10cSrcweir MemoryContainer::~MemoryContainer()
73cdf0e10cSrcweir {
74cdf0e10cSrcweir     rtl_freeMemory(m_pBuffer);
75cdf0e10cSrcweir }
76cdf0e10cSrcweir 
77cdf0e10cSrcweir 
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 
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 
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 
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 
145cdf0e10cSrcweir FTPURL::~FTPURL()
146cdf0e10cSrcweir {
147cdf0e10cSrcweir }
148cdf0e10cSrcweir 
149cdf0e10cSrcweir 
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 
249cdf0e10cSrcweir 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 
298cdf0e10cSrcweir 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 
350cdf0e10cSrcweir void FTPURL::child(const rtl::OUString& title)
351cdf0e10cSrcweir {
352cdf0e10cSrcweir     m_aPathSegmentVec.push_back(encodePathSegment(title));
353cdf0e10cSrcweir }
354cdf0e10cSrcweir 
355cdf0e10cSrcweir 
356cdf0e10cSrcweir 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 
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 
448cdf0e10cSrcweir 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 
537cdf0e10cSrcweir 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 
619cdf0e10cSrcweir 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 
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 
666cdf0e10cSrcweir 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 
699cdf0e10cSrcweir 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 
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 
794cdf0e10cSrcweir 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