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