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