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