merge the formfield patch from ooo-build
[ooovba.git] / ucb / source / ucp / ftp / ftpurl.cxx
blob06ea07b85567a2ba423b990235e00a29d4fb144d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ftpurl.cxx,v $
10 * $Revision: 1.25 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
33 /**************************************************************************
34 TODO
35 **************************************************************************
37 *************************************************************************/
39 #include <memory>
40 #include <rtl/ustrbuf.hxx>
41 #include <com/sun/star/ucb/OpenMode.hpp>
42 #include <string.h>
43 #include <rtl/uri.hxx>
45 #include "ftpstrcont.hxx"
46 #include "ftpurl.hxx"
47 #include "ftphandleprovider.hxx"
48 #include "ftpinpstr.hxx"
49 #include "ftpcfunc.hxx"
50 #include "ftpcontainer.hxx"
52 using namespace ftp;
53 using namespace com::sun::star::ucb;
54 using namespace com::sun::star::uno;
55 using namespace com::sun::star::io;
57 namespace {
59 rtl::OUString encodePathSegment(rtl::OUString const & decoded) {
60 return rtl::Uri::encode(
61 decoded, rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes,
62 RTL_TEXTENCODING_UTF8);
65 rtl::OUString decodePathSegment(rtl::OUString const & encoded) {
66 return rtl::Uri::decode(
67 encoded, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8);
72 MemoryContainer::MemoryContainer()
73 : m_nLen(0),
74 m_nWritePos(0),
75 m_pBuffer(0)
79 MemoryContainer::~MemoryContainer()
81 rtl_freeMemory(m_pBuffer);
85 int MemoryContainer::append(
86 const void* pBuffer,
87 size_t size,
88 size_t nmemb
89 ) throw()
91 sal_uInt32 nLen = size*nmemb;
92 sal_uInt32 tmp(nLen + m_nWritePos);
94 if(m_nLen < tmp) { // enlarge in steps of multiples of 1K
95 do {
96 m_nLen+=1024;
97 } while(m_nLen < tmp);
99 m_pBuffer = rtl_reallocateMemory(m_pBuffer,m_nLen);
102 rtl_copyMemory(static_cast<sal_Int8*>(m_pBuffer)+m_nWritePos,
103 pBuffer,nLen);
104 m_nWritePos = tmp;
105 return nLen;
109 extern "C" {
111 int memory_write(void *buffer,size_t size,size_t nmemb,void *stream)
113 MemoryContainer *_stream =
114 reinterpret_cast<MemoryContainer*>(stream);
116 if(!_stream)
117 return 0;
119 return _stream->append(buffer,size,nmemb);
125 FTPURL::FTPURL(const FTPURL& r)
126 : m_mutex(),
127 m_pFCP(r.m_pFCP),
128 m_aUsername(r.m_aUsername),
129 m_bShowPassword(r.m_bShowPassword),
130 m_aHost(r.m_aHost),
131 m_aPort(r.m_aPort),
132 m_aPathSegmentVec(r.m_aPathSegmentVec)
138 FTPURL::FTPURL(const rtl::OUString& url,
139 FTPHandleProvider* pFCP)
140 throw(
141 malformed_exception
143 : m_pFCP(pFCP),
144 m_aUsername(rtl::OUString::createFromAscii("anonymous")),
145 m_bShowPassword(false),
146 m_aPort(rtl::OUString::createFromAscii("21"))
148 parse(url); // can reset m_bShowPassword
152 FTPURL::~FTPURL()
157 void FTPURL::parse(const rtl::OUString& url)
158 throw(
159 malformed_exception
162 rtl::OUString aPassword,aAccount;
163 rtl::OString aIdent(url.getStr(),
164 url.getLength(),
165 RTL_TEXTENCODING_UTF8);
166 char *buffer = new char[1+aIdent.getLength()];
168 const char* p2 = aIdent.getStr();
170 rtl::OString lower = aIdent.toAsciiLowerCase();
171 if(lower.getLength() < 6 ||
172 strncmp("ftp://",lower.getStr(),6))
173 throw malformed_exception();
175 p2 += 6;
177 char ch;
178 char *p1 = buffer; // determine "username:password@host:port"
179 while((ch = *p2++) != '/' && ch)
180 *p1++ = ch;
181 *p1 = 0;
183 rtl::OUString aExpr(rtl::OUString(buffer,strlen(buffer),
184 RTL_TEXTENCODING_UTF8));
186 sal_Int32 l = aExpr.indexOf(sal_Unicode('@'));
187 m_aHost = aExpr.copy(1+l);
189 if(l != -1) {
190 // Now username and password.
191 aExpr = aExpr.copy(0,l);
192 l = aExpr.indexOf(sal_Unicode(':'));
193 if(l != -1) {
194 aPassword = aExpr.copy(1+l);
195 if(aPassword.getLength())
196 m_bShowPassword = true;
198 if(l > 0)
199 // Overwritte only if the username is not empty.
200 m_aUsername = aExpr.copy(0,l);
201 else if(aExpr.getLength())
202 m_aUsername = aExpr;
205 l = m_aHost.lastIndexOf(sal_Unicode(':'));
206 sal_Int32 ipv6Back = m_aHost.lastIndexOf(sal_Unicode(']'));
207 if((ipv6Back == -1 && l != -1) // not ipv6, but a port
209 (ipv6Back != -1 && 1+ipv6Back == l) // ipv6, and a port
212 if(1+l<m_aHost.getLength())
213 m_aPort = m_aHost.copy(1+l);
214 m_aHost = m_aHost.copy(0,l);
217 while(ch) { // now determine the pathsegments ...
218 p1 = buffer;
219 while((ch = *p2++) != '/' && ch)
220 *p1++ = ch;
221 *p1 = 0;
223 if(buffer[0]) {
224 if(strcmp(buffer,"..") == 0 &&
225 m_aPathSegmentVec.size() &&
226 ! m_aPathSegmentVec.back().equalsAscii(".."))
227 m_aPathSegmentVec.pop_back();
228 else if(strcmp(buffer,".") == 0)
229 ; // Ignore
230 else
231 // This is a legal name.
232 m_aPathSegmentVec.push_back(
233 rtl::OUString(buffer,
234 strlen(buffer),
235 RTL_TEXTENCODING_UTF8));
239 delete[] buffer;
241 if(m_bShowPassword)
242 m_pFCP->setHost(m_aHost,
243 m_aPort,
244 m_aUsername,
245 aPassword,
246 aAccount);
248 // now check for something like ";type=i" at end of url
249 if(m_aPathSegmentVec.size() &&
250 (l = m_aPathSegmentVec.back().indexOf(sal_Unicode(';'))) != -1) {
251 m_aType = m_aPathSegmentVec.back().copy(l);
252 m_aPathSegmentVec.back() = m_aPathSegmentVec.back().copy(0,l);
257 rtl::OUString FTPURL::ident(bool withslash,bool internal) const
259 // rebuild the url as one without ellipses,
260 // and more important, as one without username and
261 // password. ( These are set together with the command. )
263 rtl::OUStringBuffer bff;
264 bff.appendAscii("ftp://");
266 if(!m_aUsername.equalsAscii("anonymous")) {
267 bff.append(m_aUsername);
269 rtl::OUString aPassword,aAccount;
270 m_pFCP->forHost(m_aHost,
271 m_aPort,
272 m_aUsername,
273 aPassword,
274 aAccount);
276 if((m_bShowPassword || internal) &&
277 aPassword.getLength() )
278 bff.append(sal_Unicode(':'))
279 .append(aPassword);
281 bff.append(sal_Unicode('@'));
283 bff.append(m_aHost);
285 if(!m_aPort.equalsAscii("21"))
286 bff.append(sal_Unicode(':'))
287 .append(m_aPort)
288 .append(sal_Unicode('/'));
289 else
290 bff.append(sal_Unicode('/'));
292 for(unsigned i = 0; i < m_aPathSegmentVec.size(); ++i)
293 if(i == 0)
294 bff.append(m_aPathSegmentVec[i]);
295 else
296 bff.append(sal_Unicode('/')).append(m_aPathSegmentVec[i]);
297 if(withslash)
298 if(bff.getLength() && bff[bff.getLength()-1] != sal_Unicode('/'))
299 bff.append(sal_Unicode('/'));
301 bff.append(m_aType);
302 return bff.makeStringAndClear();
306 rtl::OUString FTPURL::parent(bool internal) const
308 rtl::OUStringBuffer bff;
310 bff.appendAscii("ftp://");
312 if(!m_aUsername.equalsAscii("anonymous")) {
313 bff.append(m_aUsername);
315 rtl::OUString aPassword,aAccount;
316 m_pFCP->forHost(m_aHost,
317 m_aPort,
318 m_aUsername,
319 aPassword,
320 aAccount);
322 if((internal || m_bShowPassword) && aPassword.getLength())
323 bff.append(sal_Unicode(':'))
324 .append(aPassword);
326 bff.append(sal_Unicode('@'));
329 bff.append(m_aHost);
331 if(!m_aPort.equalsAscii("21"))
332 bff.append(sal_Unicode(':'))
333 .append(m_aPort)
334 .append(sal_Unicode('/'));
335 else
336 bff.append(sal_Unicode('/'));
338 rtl::OUString last;
340 for(unsigned int i = 0; i < m_aPathSegmentVec.size(); ++i)
341 if(1+i == m_aPathSegmentVec.size())
342 last = m_aPathSegmentVec[i];
343 else if(i == 0)
344 bff.append(m_aPathSegmentVec[i]);
345 else
346 bff.append(sal_Unicode('/')).append(m_aPathSegmentVec[i]);
348 if(!last.getLength())
349 bff.appendAscii("..");
350 else if(last.equalsAscii(".."))
351 bff.append(last).appendAscii("/..");
353 bff.append(m_aType);
354 return bff.makeStringAndClear();
358 void FTPURL::child(const rtl::OUString& title)
360 m_aPathSegmentVec.push_back(encodePathSegment(title));
364 rtl::OUString FTPURL::child() const
366 return
367 m_aPathSegmentVec.size() ?
368 decodePathSegment(m_aPathSegmentVec.back()) : rtl::OUString();
373 /** Listing of a directory.
376 namespace ftp {
378 enum OS {
379 FTP_DOS,FTP_UNIX,FTP_VMS,FTP_UNKNOWN
385 #define SET_CONTROL_CONTAINER \
386 MemoryContainer control; \
387 curl_easy_setopt(curl, \
388 CURLOPT_HEADERFUNCTION, \
389 memory_write); \
390 curl_easy_setopt(curl, \
391 CURLOPT_WRITEHEADER, \
392 &control)
395 #define SET_DATA_CONTAINER \
396 curl_easy_setopt(curl,CURLOPT_NOBODY,false); \
397 MemoryContainer data; \
398 curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,memory_write); \
399 curl_easy_setopt(curl,CURLOPT_WRITEDATA,&data)
401 #define SET_URL(url) \
402 rtl::OString urlParAscii(url.getStr(), \
403 url.getLength(), \
404 RTL_TEXTENCODING_UTF8); \
405 curl_easy_setopt(curl, \
406 CURLOPT_URL, \
407 urlParAscii.getStr());
409 // Setting username:password
410 #define SET_USER_PASSWORD(username,password) \
411 rtl::OUString combi(username + \
412 rtl::OUString::createFromAscii(":") + \
413 password); \
414 rtl::OString aUserPsswd(combi.getStr(), \
415 combi.getLength(), \
416 RTL_TEXTENCODING_UTF8); \
417 curl_easy_setopt(curl, \
418 CURLOPT_USERPWD, \
419 aUserPsswd.getStr())
423 FILE* FTPURL::open()
424 throw(curl_exception)
426 if(!m_aPathSegmentVec.size())
427 throw curl_exception(CURLE_FTP_COULDNT_RETR_FILE);
429 CURL *curl = m_pFCP->handle();
431 SET_CONTROL_CONTAINER;
432 rtl::OUString url(ident(false,true));
433 SET_URL(url);
434 FILE *res = tmpfile();
435 curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,file_write);
436 curl_easy_setopt(curl,CURLOPT_WRITEDATA,res);
438 curl_easy_setopt(curl,CURLOPT_POSTQUOTE,0);
439 CURLcode err = curl_easy_perform(curl);
441 if(err == CURLE_OK)
442 rewind(res);
443 else {
444 fclose(res),res = 0;
445 throw curl_exception(err);
448 return res;
452 std::vector<FTPDirentry> FTPURL::list(
453 sal_Int16 nMode
454 ) const
455 throw(
456 curl_exception
459 CURL *curl = m_pFCP->handle();
461 SET_CONTROL_CONTAINER;
462 SET_DATA_CONTAINER;
463 rtl::OUString url(ident(true,true));
464 SET_URL(url);
465 curl_easy_setopt(curl,CURLOPT_POSTQUOTE,0);
467 CURLcode err = curl_easy_perform(curl);
468 if(err != CURLE_OK)
469 throw curl_exception(err);
471 // now evaluate the error messages
473 sal_uInt32 len = data.m_nWritePos;
474 char* fwd = (char*) data.m_pBuffer;
475 rtl::OString str(fwd,len);
476 char *p1, *p2;
477 p1 = p2 = fwd;
479 OS osKind(FTP_UNKNOWN);
480 std::vector<FTPDirentry> resvec;
481 FTPDirentry aDirEntry;
482 // ensure slash at the end
483 rtl::OUString viewurl(ident(true,false));
485 while(true) {
486 while(p2-fwd < int(len) && *p2 != '\n') ++p2;
487 if(p2-fwd == int(len)) break;
489 *p2 = 0;
490 switch(osKind) {
491 // While FTP knows the 'system'-command,
492 // which returns the operating system type,
493 // this is not usable here: There are Windows-server
494 // formatting the output like UNIX-ls command.
495 case FTP_DOS:
496 FTPDirectoryParser::parseDOS(aDirEntry,p1);
497 break;
498 case FTP_UNIX:
499 FTPDirectoryParser::parseUNIX(aDirEntry,p1);
500 break;
501 case FTP_VMS:
502 FTPDirectoryParser::parseVMS(aDirEntry,p1);
503 break;
504 default:
505 if(FTPDirectoryParser::parseUNIX(aDirEntry,p1))
506 osKind = FTP_UNIX;
507 else if(FTPDirectoryParser::parseDOS(aDirEntry,p1))
508 osKind = FTP_DOS;
509 else if(FTPDirectoryParser::parseVMS(aDirEntry,p1))
510 osKind = FTP_VMS;
512 aDirEntry.m_aName = aDirEntry.m_aName.trim();
513 if(osKind != int(FTP_UNKNOWN) &&
514 !aDirEntry.m_aName.equalsAscii("..") &&
515 !aDirEntry.m_aName.equalsAscii(".")) {
516 aDirEntry.m_aURL = viewurl + encodePathSegment(aDirEntry.m_aName);
518 sal_Bool isDir =
519 sal_Bool(aDirEntry.m_nMode&INETCOREFTP_FILEMODE_ISDIR);
520 switch(nMode) {
521 case OpenMode::DOCUMENTS:
522 if(!isDir)
523 resvec.push_back(aDirEntry);
524 break;
525 case OpenMode::FOLDERS:
526 if(isDir)
527 resvec.push_back(aDirEntry);
528 break;
529 default:
530 resvec.push_back(aDirEntry);
533 aDirEntry.clear();
534 p1 = p2 + 1;
537 return resvec;
541 rtl::OUString FTPURL::net_title() const
542 throw(curl_exception)
544 CURL *curl = m_pFCP->handle();
546 SET_CONTROL_CONTAINER;
547 curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
548 struct curl_slist *slist = 0;
549 // post request
550 slist = curl_slist_append(slist,"PWD");
551 curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
553 bool try_more(true);
554 CURLcode err;
555 rtl::OUString aNetTitle;
557 while(true) {
558 rtl::OUString url(ident(false,true));
560 if(try_more &&
561 1+url.lastIndexOf(sal_Unicode('/')) != url.getLength())
562 url += rtl::OUString::createFromAscii("/"); // add end-slash
563 else if(!try_more &&
564 1+url.lastIndexOf(sal_Unicode('/')) == url.getLength())
565 url = url.copy(0,url.getLength()-1); // remove end-slash
567 SET_URL(url);
568 err = curl_easy_perform(curl);
570 if(err == CURLE_OK) { // get the title from the server
571 char* fwd = (char*) control.m_pBuffer;
572 sal_uInt32 len = (sal_uInt32) control.m_nWritePos;
574 aNetTitle = rtl::OUString(fwd,len,RTL_TEXTENCODING_UTF8);
575 // the buffer now contains the name of the file;
576 // analyze the output:
577 // Format of current working directory:
578 // 257 "/bla/bla" is current directory
579 sal_Int32 index1 = aNetTitle.lastIndexOf(
580 rtl::OUString::createFromAscii("257"));
581 index1 = 1+aNetTitle.indexOf(sal_Unicode('"'),index1);
582 sal_Int32 index2 = aNetTitle.indexOf(sal_Unicode('"'),index1);
583 aNetTitle = aNetTitle.copy(index1,index2-index1);
584 if(!aNetTitle.equalsAscii("/")) {
585 index1 = aNetTitle.lastIndexOf(sal_Unicode('/'));
586 aNetTitle = aNetTitle.copy(1+index1);
588 try_more = false;
589 } else if(err == CURLE_BAD_PASSWORD_ENTERED)
590 // the client should retry after getting the correct
591 // username + password
592 throw curl_exception(err);
593 else if(try_more && err == CURLE_FTP_ACCESS_DENIED) {
594 // We were either denied access when trying to login to
595 // an FTP server or when trying to change working directory
596 // to the one given in the URL.
597 if(m_aPathSegmentVec.size())
598 // determine title form url
599 aNetTitle = decodePathSegment(m_aPathSegmentVec.back());
600 else
601 // must be root
602 aNetTitle = rtl::OUString::createFromAscii("/");
603 try_more = false;
606 if(try_more)
607 try_more = false;
608 else
609 break;
612 curl_slist_free_all(slist);
613 return aNetTitle;
617 FTPDirentry FTPURL::direntry() const
618 throw(curl_exception)
620 rtl::OUString nettitle = net_title();
621 FTPDirentry aDirentry;
623 aDirentry.m_aName = nettitle; // init aDirentry
624 if(nettitle.equalsAscii("/") ||
625 nettitle.equalsAscii(".."))
626 aDirentry.m_nMode = INETCOREFTP_FILEMODE_ISDIR;
627 else
628 aDirentry.m_nMode = INETCOREFTP_FILEMODE_UNKNOWN;
630 aDirentry.m_nSize = 0;
632 if(!nettitle.equalsAscii("/")) {
633 // try to open the parent directory
634 FTPURL aURL(parent(),m_pFCP);
636 std::vector<FTPDirentry> aList = aURL.list(OpenMode::ALL);
638 for(unsigned i = 0; i < aList.size(); ++i) {
639 if(aList[i].m_aName == nettitle) { // the relevant file is found
640 aDirentry = aList[i];
641 break;
645 return aDirentry;
649 extern "C" {
651 size_t memory_read(void *ptr,size_t size,size_t nmemb,void *stream)
653 sal_Int32 nRequested = sal_Int32(size*nmemb);
654 CurlInput *curlInput = static_cast<CurlInput*>(stream);
655 if(curlInput)
656 return size_t(curlInput->read(((sal_Int8*)ptr),nRequested));
657 else
658 return 0;
664 void FTPURL::insert(bool replaceExisting,void* stream) const
665 throw(curl_exception)
667 if(!replaceExisting) {
668 // FTPDirentry aDirentry(direntry());
669 // if(aDirentry.m_nMode == INETCOREFTP_FILEMODE_UNKNOWN)
670 // throw curl_exception(FILE_EXIST_DURING_INSERT);
671 throw curl_exception(FILE_MIGHT_EXIST_DURING_INSERT);
672 } // else
673 // overwrite is default in libcurl
675 CURL *curl = m_pFCP->handle();
677 SET_CONTROL_CONTAINER;
678 curl_easy_setopt(curl,CURLOPT_NOBODY,false); // no data => no transfer
679 curl_easy_setopt(curl,CURLOPT_POSTQUOTE,0);
680 curl_easy_setopt(curl,CURLOPT_QUOTE,0);
681 curl_easy_setopt(curl,CURLOPT_READFUNCTION,memory_read);
682 curl_easy_setopt(curl,CURLOPT_READDATA,stream);
683 curl_easy_setopt(curl, CURLOPT_UPLOAD,1);
685 rtl::OUString url(ident(false,true));
686 SET_URL(url);
688 CURLcode err = curl_easy_perform(curl);
689 curl_easy_setopt(curl, CURLOPT_UPLOAD,false);
691 if(err != CURLE_OK)
692 throw curl_exception(err);
697 void FTPURL::mkdir(bool ReplaceExisting) const
698 throw(curl_exception)
700 rtl::OString title;
701 if(m_aPathSegmentVec.size()) {
702 rtl::OUString titleOU = m_aPathSegmentVec.back();
703 titleOU = decodePathSegment(titleOU);
704 title = rtl::OString(titleOU.getStr(),
705 titleOU.getLength(),
706 RTL_TEXTENCODING_UTF8);
708 else
709 // will give an error
710 title = rtl::OString("/");
712 rtl::OString aDel("del "); aDel += title;
713 rtl::OString mkd("mkd "); mkd += title;
715 struct curl_slist *slist = 0;
717 FTPDirentry aDirentry(direntry());
718 if(!ReplaceExisting) {
719 // if(aDirentry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN)
720 // throw curl_exception(FOLDER_EXIST_DURING_INSERT);
721 throw curl_exception(FOLDER_MIGHT_EXIST_DURING_INSERT);
722 } else if(aDirentry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN)
723 slist = curl_slist_append(slist,aDel.getStr());
725 slist = curl_slist_append(slist,mkd.getStr());
727 CURL *curl = m_pFCP->handle();
728 SET_CONTROL_CONTAINER;
729 curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
730 curl_easy_setopt(curl,CURLOPT_QUOTE,0);
732 // post request
733 curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
735 rtl::OUString url(parent(true));
736 if(1+url.lastIndexOf(sal_Unicode('/')) != url.getLength())
737 url += rtl::OUString::createFromAscii("/");
738 SET_URL(url);
740 CURLcode err = curl_easy_perform(curl);
741 curl_slist_free_all(slist);
742 if(err != CURLE_OK)
743 throw curl_exception(err);
747 rtl::OUString FTPURL::ren(const rtl::OUString& NewTitle)
748 throw(curl_exception)
750 CURL *curl = m_pFCP->handle();
752 // post request
753 rtl::OString renamefrom("RNFR ");
754 rtl::OUString OldTitle = net_title();
755 renamefrom +=
756 rtl::OString(OldTitle.getStr(),
757 OldTitle.getLength(),
758 RTL_TEXTENCODING_UTF8);
760 rtl::OString renameto("RNTO ");
761 renameto +=
762 rtl::OString(NewTitle.getStr(),
763 NewTitle.getLength(),
764 RTL_TEXTENCODING_UTF8);
766 struct curl_slist *slist = 0;
767 slist = curl_slist_append(slist,renamefrom.getStr());
768 slist = curl_slist_append(slist,renameto.getStr());
769 curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
771 SET_CONTROL_CONTAINER;
772 curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
773 curl_easy_setopt(curl,CURLOPT_QUOTE,0);
775 rtl::OUString url(parent(true));
776 if(1+url.lastIndexOf(sal_Unicode('/')) != url.getLength())
777 url += rtl::OUString::createFromAscii("/");
778 SET_URL(url);
780 CURLcode err = curl_easy_perform(curl);
781 curl_slist_free_all(slist);
782 if(err != CURLE_OK)
783 throw curl_exception(err);
784 else if(m_aPathSegmentVec.size() &&
785 !m_aPathSegmentVec.back().equalsAscii(".."))
786 m_aPathSegmentVec.back() = encodePathSegment(NewTitle);
787 return OldTitle;
792 void FTPURL::del() const
793 throw(curl_exception)
795 FTPDirentry aDirentry(direntry());
797 rtl::OString dele(aDirentry.m_aName.getStr(),
798 aDirentry.m_aName.getLength(),
799 RTL_TEXTENCODING_UTF8);
801 if(aDirentry.m_nMode & INETCOREFTP_FILEMODE_ISDIR) {
802 std::vector<FTPDirentry> vec = list(sal_Int16(OpenMode::ALL));
803 for( unsigned int i = 0; i < vec.size(); ++i )
804 try {
805 FTPURL url(vec[i].m_aURL,m_pFCP);
806 url.del();
807 } catch(const curl_exception&) {
809 dele = rtl::OString("RMD ") + dele;
811 else if(aDirentry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN)
812 dele = rtl::OString("DELE ") + dele;
813 else
814 return;
816 // post request
817 CURL *curl = m_pFCP->handle();
818 struct curl_slist *slist = 0;
819 slist = curl_slist_append(slist,dele.getStr());
820 curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
822 SET_CONTROL_CONTAINER;
823 curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
824 curl_easy_setopt(curl,CURLOPT_QUOTE,0);
826 rtl::OUString url(parent(true));
827 if(1+url.lastIndexOf(sal_Unicode('/')) != url.getLength())
828 url += rtl::OUString::createFromAscii("/");
829 SET_URL(url);
831 CURLcode err = curl_easy_perform(curl);
832 curl_slist_free_all(slist);
833 if(err != CURLE_OK)
834 throw curl_exception(err);