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