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  (l = m_aPathSegmentVec.back().indexOf(';')) != -1) {
231  m_aType = m_aPathSegmentVec.back().copy(l);
232  m_aPathSegmentVec.back() = m_aPathSegmentVec.back().copy(0,l);
233  }
234 }
235 
236 
237 OUString FTPURL::ident(bool withslash,bool internal) const
238 {
239  // rebuild the url as one without ellipses,
240  // and more important, as one without username and
241  // password. ( These are set together with the command. )
242 
243  OUStringBuffer bff;
244  bff.append("ftp://");
245 
246  if( m_aUsername != "anonymous" ) {
247  bff.append(m_aUsername);
248 
249  OUString aPassword,aAccount;
251  m_aPort,
252  m_aUsername,
253  aPassword,
254  aAccount);
255 
256  if((m_bShowPassword || internal) &&
257  !aPassword.isEmpty() )
258  bff.append(':')
259  .append(aPassword);
260 
261  bff.append('@');
262  }
263  bff.append(m_aHost);
264 
265  if( m_aPort != "21" )
266  bff.append(':')
267  .append(m_aPort)
268  .append('/');
269  else
270  bff.append('/');
271 
272  for(size_t i = 0; i < m_aPathSegmentVec.size(); ++i)
273  if(i == 0)
274  bff.append(m_aPathSegmentVec[i]);
275  else
276  bff.append('/').append(m_aPathSegmentVec[i]);
277  if(withslash)
278  if(!bff.isEmpty() && bff[bff.getLength()-1] != '/')
279  bff.append('/');
280 
281  bff.append(m_aType);
282  return bff.makeStringAndClear();
283 }
284 
285 
286 OUString FTPURL::parent(bool internal) const
287 {
288  OUStringBuffer bff;
289 
290  bff.append("ftp://");
291 
292  if( m_aUsername != "anonymous" ) {
293  bff.append(m_aUsername);
294 
295  OUString aPassword,aAccount;
297  m_aPort,
298  m_aUsername,
299  aPassword,
300  aAccount);
301 
302  if((internal || m_bShowPassword) && !aPassword.isEmpty())
303  bff.append(':')
304  .append(aPassword);
305 
306  bff.append('@');
307  }
308 
309  bff.append(m_aHost);
310 
311  if( m_aPort != "21" )
312  bff.append(':')
313  .append(m_aPort)
314  .append('/');
315  else
316  bff.append('/');
317 
318  OUString last;
319 
320  for(size_t i = 0; i < m_aPathSegmentVec.size(); ++i)
321  if(1+i == m_aPathSegmentVec.size())
322  last = m_aPathSegmentVec[i];
323  else if(i == 0)
324  bff.append(m_aPathSegmentVec[i]);
325  else
326  bff.append('/').append(m_aPathSegmentVec[i]);
327 
328  if(last.isEmpty())
329  bff.append("..");
330  else if ( last == ".." )
331  bff.append(last).append("/..");
332 
333  bff.append(m_aType);
334  return bff.makeStringAndClear();
335 }
336 
337 
338 void FTPURL::child(const OUString& title)
339 {
340  m_aPathSegmentVec.push_back(encodePathSegment(title));
341 }
342 
343 
344 OUString FTPURL::child() const
345 {
346  return
347  !m_aPathSegmentVec.empty() ?
348  decodePathSegment(m_aPathSegmentVec.back()) : OUString();
349 }
350 
351 
355 namespace ftp {
356 
357  namespace {
358 
359  enum OS {
360  FTP_DOS,FTP_UNIX,FTP_VMS,FTP_UNKNOWN
361  };
362 
363  }
364 
365 }
366 
367 
368 #define SET_CONTROL_CONTAINER \
369  MemoryContainer control; \
370  curl_easy_setopt(curl, \
371  CURLOPT_HEADERFUNCTION, \
372  memory_write); \
373  curl_easy_setopt(curl, \
374  CURLOPT_WRITEHEADER, \
375  &control)
376 
377 
378 static void setCurlUrl(CURL* curl, OUString const & url)
379 {
380  OString urlParAscii(url.getStr(),
381  url.getLength(),
382  RTL_TEXTENCODING_UTF8);
383  curl_easy_setopt(curl,
384  CURLOPT_URL,
385  urlParAscii.getStr());
386 };
387 
388 oslFileHandle FTPURL::open()
389 {
390  if(m_aPathSegmentVec.empty())
391  throw curl_exception(CURLE_FTP_COULDNT_RETR_FILE);
392 
393  CURL *curl = m_pFCP->handle();
394 
396  OUString url(ident(false,true));
397  setCurlUrl(curl, url);
398 
399  oslFileHandle res( nullptr );
400  if ( osl_createTempFile( nullptr, &res, nullptr ) == osl_File_E_None )
401  {
402  curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,file_write);
403  curl_easy_setopt(curl,CURLOPT_WRITEDATA,res);
404 
405  curl_easy_setopt(curl,CURLOPT_POSTQUOTE,0);
406  CURLcode err = curl_easy_perform(curl);
407 
408  if(err == CURLE_OK)
409  {
410  oslFileError rc = osl_setFilePos( res, osl_Pos_Absolut, 0 );
411  SAL_WARN_IF(rc != osl_File_E_None, "ucb.ucp.ftp",
412  "osl_setFilePos failed");
413  }
414  else {
415  osl_closeFile(res);
416  res = nullptr;
417  throw curl_exception(err);
418  }
419  }
420 
421  return res;
422 }
423 
424 
425 std::vector<FTPDirentry> FTPURL::list(
426  sal_Int16 nMode
427 ) const
428 {
429  CURL *curl = m_pFCP->handle();
430 
432  curl_easy_setopt(curl,CURLOPT_NOBODY,false);
433  MemoryContainer data;
434  curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,memory_write);
435  curl_easy_setopt(curl,CURLOPT_WRITEDATA,&data);
436 
437  OUString url(ident(true,true));
438  setCurlUrl(curl, url);
439  curl_easy_setopt(curl,CURLOPT_POSTQUOTE,0);
440 
441  CURLcode err = curl_easy_perform(curl);
442  if(err != CURLE_OK)
443  throw curl_exception(err);
444 
445  // now evaluate the error messages
446 
447  sal_uInt32 len = data.m_nWritePos;
448  char* fwd = static_cast<char*>(data.m_pBuffer);
449  char *p1, *p2;
450  p1 = p2 = fwd;
451 
452  OS osKind(FTP_UNKNOWN);
453  std::vector<FTPDirentry> resvec;
454  FTPDirentry aDirEntry;
455  // ensure slash at the end
456  OUString viewurl(ident(true,false));
457 
458  while(true) {
459  while(p2-fwd < int(len) && *p2 != '\n') ++p2;
460  if(p2-fwd == int(len)) break;
461 
462  *p2 = 0;
463  switch(osKind) {
464  // While FTP knows the 'system'-command,
465  // which returns the operating system type,
466  // this is not usable here: There are Windows-server
467  // formatting the output like UNIX-ls command.
468  case FTP_DOS:
469  FTPDirectoryParser::parseDOS(aDirEntry,p1);
470  break;
471  case FTP_UNIX:
472  FTPDirectoryParser::parseUNIX(aDirEntry,p1);
473  break;
474  case FTP_VMS:
475  FTPDirectoryParser::parseVMS(aDirEntry,p1);
476  break;
477  default:
478  if(FTPDirectoryParser::parseUNIX(aDirEntry,p1))
479  osKind = FTP_UNIX;
480  else if(FTPDirectoryParser::parseDOS(aDirEntry,p1))
481  osKind = FTP_DOS;
482  else if(FTPDirectoryParser::parseVMS(aDirEntry,p1))
483  osKind = FTP_VMS;
484  }
485  aDirEntry.m_aName = aDirEntry.m_aName.trim();
486  if( osKind != int(FTP_UNKNOWN) && aDirEntry.m_aName != ".." && aDirEntry.m_aName != "." ) {
487  aDirEntry.m_aURL = viewurl + encodePathSegment(aDirEntry.m_aName);
488 
489  bool isDir = (aDirEntry.m_nMode & INETCOREFTP_FILEMODE_ISDIR) == INETCOREFTP_FILEMODE_ISDIR;
490  switch(nMode) {
491  case OpenMode::DOCUMENTS:
492  if(!isDir)
493  resvec.push_back(aDirEntry);
494  break;
495  case OpenMode::FOLDERS:
496  if(isDir)
497  resvec.push_back(aDirEntry);
498  break;
499  default:
500  resvec.push_back(aDirEntry);
501  };
502  }
503  aDirEntry.clear();
504  p1 = p2 + 1;
505  }
506 
507  return resvec;
508 }
509 
510 
511 OUString FTPURL::net_title() const
512 {
513  CURL *curl = m_pFCP->handle();
514 
516  curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
517  struct curl_slist *slist = nullptr;
518  // post request
519  slist = curl_slist_append(slist,"PWD");
520  curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
521 
522  bool try_more(true);
523  CURLcode err;
524  OUString aNetTitle;
525 
526  while(true) {
527  OUString url(ident(false,true));
528 
529  if(try_more && !url.endsWith("/"))
530  url += "/"; // add end-slash
531  else if(!try_more && url.endsWith("/"))
532  url = url.copy(0,url.getLength()-1); // remove end-slash
533 
534  setCurlUrl(curl, url);
535  err = curl_easy_perform(curl);
536 
537  if(err == CURLE_OK) { // get the title from the server
538  char* fwd = static_cast<char*>(control.m_pBuffer);
539  sal_uInt32 len = control.m_nWritePos;
540 
541  aNetTitle = OUString(fwd,len,RTL_TEXTENCODING_UTF8);
542  // the buffer now contains the name of the file;
543  // analyze the output:
544  // Format of current working directory:
545  // 257 "/bla/bla" is current directory
546  sal_Int32 index1 = aNetTitle.lastIndexOf("257");
547  index1 = aNetTitle.indexOf('"', index1 + std::strlen("257")) + 1;
548  sal_Int32 index2 = aNetTitle.indexOf('"', index1);
549  aNetTitle = index2 > index1
550  ? aNetTitle.copy(index1, index2 - index1) : OUString();
551  if( aNetTitle != "/" ) {
552  index1 = aNetTitle.lastIndexOf('/');
553  aNetTitle = aNetTitle.copy(1+index1);
554  }
555  try_more = false;
556  } else if(err == CURLE_BAD_PASSWORD_ENTERED)
557  // the client should retry after getting the correct
558  // username + password
559  throw curl_exception(err);
560 #if LIBCURL_VERSION_NUM>=0x070d01 /* 7.13.1 */
561  else if(err == CURLE_LOGIN_DENIED)
562  // the client should retry after getting the correct
563  // username + password
564  throw curl_exception(err);
565 #endif
566  else if(try_more && err == CURLE_FTP_ACCESS_DENIED) {
567  // We were either denied access when trying to login to
568  // an FTP server or when trying to change working directory
569  // to the one given in the URL.
570  if(!m_aPathSegmentVec.empty())
571  // determine title from URL
572  aNetTitle = decodePathSegment(m_aPathSegmentVec.back());
573  else
574  // must be root
575  aNetTitle = "/";
576  try_more = false;
577  }
578 
579  if(try_more)
580  try_more = false;
581  else
582  break;
583  }
584 
585  curl_slist_free_all(slist);
586  return aNetTitle;
587 }
588 
589 
591 {
592  OUString nettitle = net_title();
593  FTPDirentry aDirentry;
594 
595  aDirentry.m_aName = nettitle; // init aDirentry
596  if( nettitle == "/" || nettitle == ".." )
598  else
600 
601  aDirentry.m_nSize = 0;
602 
603  if( nettitle != "/" ) {
604  // try to open the parent directory
606 
607  std::vector<FTPDirentry> aList = aURL.list(OpenMode::ALL);
608 
609  for(const FTPDirentry & d : aList) {
610  if(d.m_aName == nettitle) { // the relevant file is found
611  aDirentry = d;
612  break;
613  }
614  }
615  }
616  return aDirentry;
617 }
618 
619 
620 extern "C" {
621 
622  static size_t memory_read(void *ptr,size_t size,size_t nmemb,void *stream)
623  {
624  sal_Int32 nRequested = sal_Int32(size*nmemb);
625  CurlInput *curlInput = static_cast<CurlInput*>(stream);
626  if(curlInput)
627  return size_t(curlInput->read(static_cast<sal_Int8*>(ptr),nRequested));
628  else
629  return 0;
630  }
631 
632 }
633 
634 
635 void FTPURL::insert(bool replaceExisting,void* stream) const
636 {
637  if(!replaceExisting) {
638 // FTPDirentry aDirentry(direntry());
639 // if(aDirentry.m_nMode == INETCOREFTP_FILEMODE_UNKNOWN)
640  // throw curl_exception(FILE_EXIST_DURING_INSERT);
642  } // else
643  // overwrite is default in libcurl
644 
645  CURL *curl = m_pFCP->handle();
646 
648  curl_easy_setopt(curl,CURLOPT_NOBODY,false); // no data => no transfer
649  curl_easy_setopt(curl,CURLOPT_POSTQUOTE,0);
650  curl_easy_setopt(curl,CURLOPT_QUOTE,0);
651  curl_easy_setopt(curl,CURLOPT_READFUNCTION,memory_read);
652  curl_easy_setopt(curl,CURLOPT_READDATA,stream);
653  curl_easy_setopt(curl, CURLOPT_UPLOAD,1);
654 
655  OUString url(ident(false,true));
656  setCurlUrl(curl, url);
657 
658  CURLcode err = curl_easy_perform(curl);
659  curl_easy_setopt(curl, CURLOPT_UPLOAD,false);
660 
661  if(err != CURLE_OK)
662  throw curl_exception(err);
663 }
664 
665 
666 void FTPURL::mkdir(bool ReplaceExisting) const
667 {
668  OString title;
669  if(!m_aPathSegmentVec.empty()) {
670  OUString titleOU = m_aPathSegmentVec.back();
671  titleOU = decodePathSegment(titleOU);
672  title = OString(titleOU.getStr(),
673  titleOU.getLength(),
674  RTL_TEXTENCODING_UTF8);
675  }
676  else
677  // will give an error
678  title = OString("/");
679 
680  OString aDel = "del " + title;
681  OString mkd = "mkd " + title;
682 
683  struct curl_slist *slist = nullptr;
684 
685  FTPDirentry aDirentry(direntry());
686  if(!ReplaceExisting) {
687 // if(aDirentry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN)
688 // throw curl_exception(FOLDER_EXIST_DURING_INSERT);
690  } else if(aDirentry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN)
691  slist = curl_slist_append(slist,aDel.getStr());
692 
693  slist = curl_slist_append(slist,mkd.getStr());
694 
695  CURL *curl = m_pFCP->handle();
697  curl_easy_setopt(curl,CURLOPT_NOBODY,true); // no data => no transfer
698  curl_easy_setopt(curl,CURLOPT_QUOTE,0);
699 
700  // post request
701  curl_easy_setopt(curl,CURLOPT_POSTQUOTE,slist);
702 
703  OUString url(parent(true));
704  if(!url.endsWith("/"))
705  url += "/";
706  setCurlUrl(curl, url);
707 
708  CURLcode err = curl_easy_perform(curl);
709  curl_slist_free_all(slist);
710  if(err != CURLE_OK)
711  throw curl_exception(err);
712 }
713 
714 
715 OUString FTPURL::ren(const OUString& NewTitle)
716 {
717  CURL *curl = m_pFCP->handle();
718 
719  // post request
720  OUString OldTitle = net_title();
721  OString renamefrom = "RNFR " +
722  OString(OldTitle.getStr(),
723  OldTitle.getLength(),
724  RTL_TEXTENCODING_UTF8);
725 
726  OString renameto = "RNTO " +
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:103
void parse(const OUString &url)
Definition: ftpurl.cxx:145
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]
OUString net_title() const
Definition: ftpurl.cxx:511
OUString child() const
returns the unencoded title
Definition: ftpurl.cxx:344
static bool parseUNIX(FTPDirentry &rEntry, const sal_Char *pBuffer)
Definition: ftpdirp.cxx:843
void mkdir(bool ReplaceExisting) const
Definition: ftpurl.cxx:666
static void setCurlUrl(CURL *curl, OUString const &url)
Definition: ftpurl.cxx:378
OUString parent(bool internal=false) const
returns the parent url.
Definition: ftpurl.cxx:286
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:425
sal_uInt32 m_nMode
Definition: ftpdirp.hxx:76
FTPContentProvider * m_pFCP
Definition: ftpurl.hxx:140
FTPDirentry direntry() const
Definition: ftpurl.cxx:590
double d
OUString m_aHost
Definition: ftpurl.hxx:144
err
OUString ren(const OUString &NewTitle)
Definition: ftpurl.cxx:715
void del() const
Definition: ftpurl.cxx:755
void insert(bool ReplaceExisting, void *stream) const
Definition: ftpurl.cxx:635
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:622
OUString const aURL
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:388
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:237
OUString m_aName
Definition: ftpdirp.hxx:74
#define SET_CONTROL_CONTAINER
Definition: ftpurl.cxx:368
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
void SAL_CALL last(const css::awt::SpinEvent &rEvent) override
static bool parseVMS(FTPDirentry &rEntry, const sal_Char *pBuffer)
Definition: ftpdirp.cxx:556