1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 /**************************************************************************
23 **************************************************************************
25 *************************************************************************/
26 #include <com/sun/star/beans/PropertyAttribute.hpp>
28 #include "ftpdynresultset.hxx"
29 #include "ftpresultsetfactory.hxx"
30 #include "ftpresultsetI.hxx"
31 #include "ftpcontent.hxx"
32 #include "ftpcontentprovider.hxx"
33 #include "ftpdirp.hxx"
34 #include "ftpcontentidentifier.hxx"
35 #include "ftpintreq.hxx"
42 #include <comphelper/propertysequence.hxx>
43 #include <cppuhelper/queryinterface.hxx>
44 #include <cppuhelper/supportsservice.hxx>
45 #include <cppuhelper/typeprovider.hxx>
46 #include <ucbhelper/cancelcommandexecution.hxx>
47 #include <ucbhelper/fd_inputstream.hxx>
48 #include <ucbhelper/propertyvalueset.hxx>
49 #include <ucbhelper/simpleauthenticationrequest.hxx>
50 #include <com/sun/star/lang/IllegalAccessException.hpp>
51 #include <com/sun/star/lang/NoSupportException.hpp>
52 #include <com/sun/star/ucb/ContentInfoAttribute.hpp>
53 #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
54 #include <com/sun/star/beans/IllegalTypeException.hpp>
55 #include <com/sun/star/beans/UnknownPropertyException.hpp>
56 #include <com/sun/star/beans/Property.hpp>
57 #include <com/sun/star/ucb/XCommandInfo.hpp>
58 #include <com/sun/star/io/BufferSizeExceededException.hpp>
59 #include <com/sun/star/io/IOException.hpp>
60 #include <com/sun/star/io/NotConnectedException.hpp>
61 #include <com/sun/star/io/XActiveDataSink.hpp>
62 #include <com/sun/star/io/XOutputStream.hpp>
63 #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
64 #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
65 #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
66 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
67 #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
68 #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
69 #include <com/sun/star/ucb/InteractiveIOException.hpp>
70 #include <com/sun/star/ucb/MissingPropertiesException.hpp>
71 #include <com/sun/star/ucb/MissingInputStreamException.hpp>
72 #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
73 #include <com/sun/star/ucb/OpenMode.hpp>
74 #include <com/sun/star/ucb/IOErrorCode.hpp>
77 using namespace com::sun::star::task
;
78 using namespace com::sun::star::container
;
79 using namespace com::sun::star::lang
;
80 using namespace com::sun::star::uno
;
81 using namespace com::sun::star::ucb
;
82 using namespace com::sun::star::beans
;
83 using namespace com::sun::star::io
;
84 using namespace com::sun::star::sdbc
;
87 // Content Implementation.
89 FTPContent::FTPContent( const Reference
< XComponentContext
>& rxContext
,
90 FTPContentProvider
* pProvider
,
91 const Reference
< XContentIdentifier
>& Identifier
,
92 const FTPURL
& aFTPURL
)
93 : ContentImplHelper(rxContext
,pProvider
,Identifier
)
101 FTPContent::FTPContent( const Reference
< XComponentContext
>& rxContext
,
102 FTPContentProvider
* pProvider
,
103 const Reference
< XContentIdentifier
>& Identifier
,
105 : ContentImplHelper(rxContext
,pProvider
,Identifier
)
107 , m_aFTPURL(Identifier
->getContentIdentifier(), pProvider
)
110 , m_aInfo(std::move(Info
))
114 FTPContent::~FTPContent()
118 // XInterface methods.
120 void SAL_CALL
FTPContent::acquire()
123 OWeakObject::acquire();
126 void SAL_CALL
FTPContent::release()
129 OWeakObject::release();
132 css::uno::Any SAL_CALL
FTPContent::queryInterface( const css::uno::Type
& rType
)
134 css::uno::Any aRet
= cppu::queryInterface( rType
,
135 static_cast< XTypeProvider
* >(this),
136 static_cast< XServiceInfo
* >(this),
137 static_cast< XContent
* >(this),
138 static_cast< XCommandProcessor
* >(this),
139 static_cast< XContentCreator
* >(this),
140 static_cast< XChild
* >(this)
142 return aRet
.hasValue() ? aRet
: OWeakObject::queryInterface( rType
);
145 // XTypeProvider methods.
147 css::uno::Sequence
< sal_Int8
> SAL_CALL
FTPContent::getImplementationId()
149 return css::uno::Sequence
<sal_Int8
>();
152 css::uno::Sequence
< css::uno::Type
> SAL_CALL
FTPContent::getTypes()
154 static cppu::OTypeCollection
s_aCollection(
155 cppu::UnoType
<XTypeProvider
>::get(),
156 cppu::UnoType
<XServiceInfo
>::get(),
157 cppu::UnoType
<XContent
>::get(),
158 cppu::UnoType
<XCommandProcessor
>::get(),
159 cppu::UnoType
<XContentCreator
>::get(),
160 cppu::UnoType
<XChild
>::get()
163 return s_aCollection
.getTypes();
167 // XServiceInfo methods.
169 OUString SAL_CALL
FTPContent::getImplementationName()
171 return "com.sun.star.comp.FTPContent";
174 sal_Bool SAL_CALL
FTPContent::supportsService( const OUString
& ServiceName
)
176 return cppu::supportsService( this, ServiceName
);
179 css::uno::Sequence
< OUString
> SAL_CALL
FTPContent::getSupportedServiceNames()
181 return { "com.sun.star.ucb.FTPContent" };
188 OUString SAL_CALL
FTPContent::getContentType()
190 return FTP_CONTENT_TYPE
;
193 // XCommandProcessor methods.
196 void SAL_CALL
FTPContent::abort( sal_Int32
/*CommandId*/ )
201 ResultSetFactory::ResultSetFactory(const Reference
<XComponentContext
>& rxContext
,
202 const Reference
<XContentProvider
>& xProvider
,
203 const Sequence
<Property
>& seq
,
204 std::vector
<FTPDirentry
>&& dirvec
)
205 : m_xContext(rxContext
),
206 m_xProvider(xProvider
),
208 m_dirvec(std::move(dirvec
))
213 rtl::Reference
<ResultSetBase
> ResultSetFactory::createResultSet()
215 return new ResultSetI(m_xContext
,
222 // XCommandProcessor methods.
226 enum ACTION
{ NOACTION
,
227 THROWAUTHENTICATIONREQUEST
,
229 THROWINTERACTIVECONNECT
,
239 Any SAL_CALL
FTPContent::execute( const Command
& aCommand
,
240 sal_Int32
/*CommandId*/,
242 XCommandEnvironment
>& Environment
)
244 ACTION
action(NOACTION
);
251 if(action
== THROWAUTHENTICATIONREQUEST
)
253 // try to get a continuation first
254 OUString aPassword
,aAccount
;
255 m_pFCP
->forHost(m_aFTPURL
.host(),
257 m_aFTPURL
.username(),
260 rtl::Reference
<ucbhelper::SimpleAuthenticationRequest
>
261 p( new ucbhelper::SimpleAuthenticationRequest(
262 m_aFTPURL
.ident(false, false),
263 m_aFTPURL
.host(), // ServerName
264 ucbhelper::SimpleAuthenticationRequest::ENTITY_NA
,
266 ucbhelper::SimpleAuthenticationRequest
268 m_aFTPURL
.username(),
269 ucbhelper::SimpleAuthenticationRequest
273 Reference
<XInteractionHandler
> xInteractionHandler
;
275 xInteractionHandler
=
276 Environment
->getInteractionHandler();
278 if( xInteractionHandler
.is()) {
279 xInteractionHandler
->handle(p
);
281 Reference
<XInterface
> xSelection(
284 if(Reference
<XInteractionRetry
>(
285 xSelection
,UNO_QUERY
).is())
287 else if(Reference
<XInteractionSupplyAuthentication
>(
288 xSelection
,UNO_QUERY
).is()) {
292 m_aFTPURL
.username(),
293 p
->getAuthenticationSupplier()->getPassword(),
298 aRet
= p
->getRequest();
301 // if(aCommand.Name.equalsAscii(
302 // "getPropertyValues") &&
303 // action != NOACTION) {
304 // // It is not allowed to throw if
305 // // command is getPropertyValues
306 // rtl::Reference<ucbhelper::PropertyValueSet> xRow =
307 // new ucbhelper::PropertyValueSet(m_xSMgr);
308 // Sequence<Property> Properties;
309 // aCommand.Argument >>= Properties;
310 // for(int i = 0; i < Properties.getLength(); ++i)
311 // xRow->appendVoid(Properties[i]);
312 // aRet <<= Reference<XRow>(xRow.get());
321 case THROWAUTHENTICATIONREQUEST
:
322 ucbhelper::cancelCommandExecution(
324 Reference
<XCommandEnvironment
>(nullptr));
327 case THROWACCESSDENIED
:
329 Sequence
<Any
> seq(comphelper::InitAnyPropertySequence(
331 {"Uri", Any(m_aFTPURL
.ident(false,false))}
333 ucbhelper::cancelCommandExecution(
334 IOErrorCode_ACCESS_DENIED
,
339 case THROWINTERACTIVECONNECT
:
341 InteractiveNetworkConnectException excep
;
342 excep
.Server
= m_aFTPURL
.host();
344 ucbhelper::cancelCommandExecution(
351 IllegalIdentifierException ex
;
353 ucbhelper::cancelCommandExecution(
358 case THROWRESOLVENAME
:
360 InteractiveNetworkResolveNameException excep
;
361 excep
.Server
= m_aFTPURL
.host();
363 ucbhelper::cancelCommandExecution(
370 Sequence
<Any
> seq(comphelper::InitAnyPropertySequence(
372 {"Uri", Any(m_aFTPURL
.ident(false,false))}
374 ucbhelper::cancelCommandExecution(
382 ucbhelper::cancelCommandExecution(
389 if(aCommand
.Name
== "getPropertyValues") {
390 Sequence
<Property
> Properties
;
391 if(!(aCommand
.Argument
>>= Properties
))
393 aRet
<<= IllegalArgumentException(
394 "Wrong argument type!",
395 static_cast< cppu::OWeakObject
* >(this),
397 ucbhelper::cancelCommandExecution(aRet
,Environment
);
400 aRet
<<= getPropertyValues(Properties
);
402 else if(aCommand
.Name
== "setPropertyValues")
404 Sequence
<PropertyValue
> propertyValues
;
406 if( ! ( aCommand
.Argument
>>= propertyValues
) ) {
407 aRet
<<= IllegalArgumentException(
408 "Wrong argument type!",
409 static_cast< cppu::OWeakObject
* >(this),
411 ucbhelper::cancelCommandExecution(aRet
,Environment
);
414 aRet
<<= setPropertyValues(propertyValues
);
416 else if(aCommand
.Name
== "getCommandInfo") {
417 // Note: Implemented by base class.
418 aRet
<<= getCommandInfo(Environment
);
420 else if(aCommand
.Name
== "getPropertySetInfo") {
421 // Note: Implemented by base class.
422 aRet
<<= getPropertySetInfo(Environment
);
424 else if(aCommand
.Name
== "insert")
426 InsertCommandArgument aInsertArgument
;
427 if ( ! ( aCommand
.Argument
>>= aInsertArgument
) ) {
428 aRet
<<= IllegalArgumentException(
429 "Wrong argument type!",
430 static_cast< cppu::OWeakObject
* >(this),
432 ucbhelper::cancelCommandExecution(aRet
,Environment
);
434 insert(aInsertArgument
,Environment
);
436 else if(aCommand
.Name
== "delete") {
440 else if(aCommand
.Name
== "open") {
441 OpenCommandArgument2 aOpenCommand
;
442 if ( !( aCommand
.Argument
>>= aOpenCommand
) ) {
443 aRet
<<= IllegalArgumentException(
444 "Wrong argument type!",
445 static_cast< cppu::OWeakObject
* >(this),
448 ucbhelper::cancelCommandExecution(aRet
,Environment
);
451 if(aOpenCommand
.Mode
== OpenMode::DOCUMENT
) {
452 // Open as a document
453 Reference
<XActiveDataSink
>
454 xActiveDataSink(aOpenCommand
.Sink
,UNO_QUERY
);
455 Reference
< XOutputStream
>
456 xOutputStream(aOpenCommand
.Sink
,UNO_QUERY
);
458 if(xActiveDataSink
.is()) {
459 xActiveDataSink
->setInputStream(
460 new ucbhelper::FdInputStream(m_aFTPURL
.open()));
462 else if(xOutputStream
.is()) {
463 Reference
<XInputStream
> xStream(
464 new ucbhelper::FdInputStream(m_aFTPURL
.open()));
466 Sequence
<sal_Int8
> byte_seq(4096);
467 sal_Int32 n
= xStream
->readBytes(byte_seq
, 4096);
472 if(byte_seq
.getLength() != n
)
474 xOutputStream
->writeBytes(byte_seq
);
475 } catch(const NotConnectedException
&) {
477 } catch(const BufferSizeExceededException
&) {
479 } catch(const IOException
&) {
485 aRet
<<= UnsupportedDataSinkException(
487 static_cast< cppu::OWeakObject
* >(this),
489 ucbhelper::cancelCommandExecution(aRet
,Environment
);
492 else if(aOpenCommand
.Mode
== OpenMode::ALL
||
493 aOpenCommand
.Mode
== OpenMode::DOCUMENTS
||
494 aOpenCommand
.Mode
== OpenMode::FOLDERS
) {
495 std::vector
<FTPDirentry
> resvec
=
496 m_aFTPURL
.list(sal_Int16(aOpenCommand
.Mode
));
497 Reference
< XDynamicResultSet
> xSet
498 = new DynamicResultSet(
501 std::make_unique
<ResultSetFactory
>(m_xContext
,
503 aOpenCommand
.Properties
,
507 else if(aOpenCommand
.Mode
==
508 OpenMode::DOCUMENT_SHARE_DENY_NONE
||
510 OpenMode::DOCUMENT_SHARE_DENY_WRITE
) {
511 // Unsupported OpenMode
512 aRet
<<= UnsupportedOpenModeException(
514 static_cast< cppu::OWeakObject
* >(this),
515 static_cast< sal_Int16
>(aOpenCommand
.Mode
));
516 ucbhelper::cancelCommandExecution(aRet
,Environment
);
519 aRet
<<= IllegalArgumentException(
520 "Unexpected OpenMode!",
521 static_cast< cppu::OWeakObject
* >(this),
524 ucbhelper::cancelCommandExecution(aRet
,Environment
);
526 } else if(aCommand
.Name
== "createNewContent") {
528 if (!(aCommand
.Argument
>>= aArg
)) {
529 ucbhelper::cancelCommandExecution(
531 IllegalArgumentException(
532 "Wrong argument type!",
533 static_cast< cppu::OWeakObject
* >(this),
538 aRet
<<= createNewContent(aArg
);
540 aRet
<<= UnsupportedCommandException(
542 static_cast< cppu::OWeakObject
* >(this));
543 ucbhelper::cancelCommandExecution(aRet
,Environment
);
548 catch(const curl_exception
& e
)
550 if(e
.code() == CURLE_COULDNT_CONNECT
)
551 action
= THROWINTERACTIVECONNECT
;
552 else if (e
.code() == CURLE_URL_MALFORMAT
)
554 action
= THROWMALFORMED
;
556 else if(e
.code() == CURLE_COULDNT_RESOLVE_HOST
)
557 action
= THROWRESOLVENAME
;
558 else if(e
.code() == CURLE_FTP_USER_PASSWORD_INCORRECT
||
559 e
.code() == CURLE_LOGIN_DENIED
||
560 e
.code() == CURLE_BAD_PASSWORD_ENTERED
||
561 e
.code() == CURLE_FTP_WEIRD_PASS_REPLY
)
562 action
= THROWAUTHENTICATIONREQUEST
;
563 else if(e
.code() == CURLE_FTP_ACCESS_DENIED
)
564 action
= THROWACCESSDENIED
;
565 else if(e
.code() == CURLE_FTP_QUOTE_ERROR
)
567 else if(e
.code() == CURLE_FTP_COULDNT_RETR_FILE
)
568 action
= THROWNOFILE
;
570 // nothing known about the cause of the error
571 action
= THROWGENERAL
;
576 constexpr OUStringLiteral FTP_FILE
= u
"application/vnd.sun.staroffice.ftp-file";
578 constexpr OUStringLiteral FTP_FOLDER
= u
"application/vnd.sun.staroffice.ftp-folder";
580 Sequence
<ContentInfo
> SAL_CALL
581 FTPContent::queryCreatableContentsInfo( )
583 return queryCreatableContentsInfo_Static();
587 Sequence
<ContentInfo
>
588 FTPContent::queryCreatableContentsInfo_Static( )
590 Sequence
< Property
> props
{ Property(
593 cppu::UnoType
<OUString
>::get(),
594 PropertyAttribute::MAYBEVOID
595 | PropertyAttribute::BOUND
) };
598 { FTP_FILE
, ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
| ContentInfoAttribute::KIND_DOCUMENT
, props
},
599 { FTP_FOLDER
, ContentInfoAttribute::KIND_FOLDER
, props
}
603 Reference
<XContent
> SAL_CALL
604 FTPContent::createNewContent( const ContentInfo
& Info
)
606 if( Info
.Type
=="application/vnd.sun.staroffice.ftp-file" || Info
.Type
== "application/vnd.sun.staroffice.ftp-folder" )
607 return new FTPContent(m_xContext
,
611 return Reference
<XContent
>(nullptr);
615 Reference
<XInterface
> SAL_CALL
616 FTPContent::getParent( )
618 Reference
<XContentIdentifier
>
619 xIdent(new FTPContentIdentifier(m_aFTPURL
.parent()));
620 return Reference
<XInterface
>( m_xProvider
->queryContent(xIdent
), UNO_QUERY
);
625 FTPContent::setParent(const Reference
<XInterface
>& /*Parent*/ )
627 throw NoSupportException();
631 OUString
FTPContent::getParentURL()
633 return m_aFTPURL
.parent();
643 explicit InsertData(const Reference
<XInputStream
>& xInputStream
)
644 : m_xInputStream(xInputStream
) { }
645 virtual ~InsertData() {}
647 // returns the number of bytes actually read
648 virtual sal_Int32
read(sal_Int8
*dest
,sal_Int32 nBytesRequested
) override
;
652 Reference
<XInputStream
> m_xInputStream
;
657 sal_Int32
InsertData::read(sal_Int8
*dest
,sal_Int32 nBytesRequested
)
661 if(m_xInputStream
.is()) {
662 Sequence
<sal_Int8
> seq(nBytesRequested
);
663 m
= m_xInputStream
->readBytes(seq
,nBytesRequested
);
664 memcpy(dest
,seq
.getConstArray(),m
);
670 void FTPContent::insert(const InsertCommandArgument
& aInsertCommand
,
671 const Reference
<XCommandEnvironment
>& Env
)
673 osl::MutexGuard
aGuard(m_aMutex
);
675 if(m_bInserted
&& !m_bTitleSet
) {
676 MissingPropertiesException excep
;
677 excep
.Properties
= { "Title" };
678 ucbhelper::cancelCommandExecution(Any(excep
), Env
);
682 m_aInfo
.Type
== FTP_FILE
&&
683 !aInsertCommand
.Data
.is())
685 MissingInputStreamException excep
;
686 ucbhelper::cancelCommandExecution(Any(excep
), Env
);
689 bool bReplace(aInsertCommand
.ReplaceExisting
);
693 if(m_aInfo
.Type
== FTP_FILE
) {
694 InsertData
data(aInsertCommand
.Data
);
695 m_aFTPURL
.insert(bReplace
,&data
);
696 } else if(m_aInfo
.Type
== FTP_FOLDER
)
697 m_aFTPURL
.mkdir(bReplace
);
698 } catch(const curl_exception
& e
) {
699 if(e
.code() == FOLDER_MIGHT_EXIST_DURING_INSERT
||
700 e
.code() == FILE_MIGHT_EXIST_DURING_INSERT
) {
702 Reference
<XInteractionHandler
> xInt
;
704 xInt
= Env
->getInteractionHandler();
706 UnsupportedNameClashException excep
;
707 excep
.NameClash
= 0; //NameClash::ERROR;
710 ucbhelper::cancelCommandExecution(Any(excep
), Env
);
713 XInteractionRequestImpl request
;
714 const Reference
<XInteractionRequest
>& xReq(request
.getRequest());
716 if (request
.approved()) {
727 // May not be reached, because both mkdir and insert can throw curl-
734 Reference
< XRow
> FTPContent::getPropertyValues(
735 const Sequence
< Property
>& seqProp
738 rtl::Reference
<ucbhelper::PropertyValueSet
> xRow
=
739 new ucbhelper::PropertyValueSet(m_xContext
);
741 FTPDirentry aDirEntry
= m_aFTPURL
.direntry();
743 for(const auto& rProp
: seqProp
) {
744 const OUString
& Name
= rProp
.Name
;
746 xRow
->appendString(rProp
,aDirEntry
.m_aName
);
747 else if(Name
== "CreatableContentsInfo")
748 xRow
->appendObject(rProp
,
749 Any(queryCreatableContentsInfo()));
750 else if(aDirEntry
.m_nMode
!= INETCOREFTP_FILEMODE_UNKNOWN
) {
751 if(Name
== "ContentType")
752 xRow
->appendString(rProp
,
753 (aDirEntry
.m_nMode
& INETCOREFTP_FILEMODE_ISDIR
)
754 ? OUString(FTP_FOLDER
)
755 : OUString(FTP_FILE
) );
756 else if(Name
== "IsReadOnly")
757 xRow
->appendBoolean(rProp
,
759 & INETCOREFTP_FILEMODE_WRITE
) == 0 );
760 else if(Name
== "IsDocument")
761 xRow
->appendBoolean(rProp
,
763 INETCOREFTP_FILEMODE_ISDIR
) != INETCOREFTP_FILEMODE_ISDIR
);
764 else if(Name
== "IsFolder")
765 xRow
->appendBoolean(rProp
,
767 INETCOREFTP_FILEMODE_ISDIR
) == INETCOREFTP_FILEMODE_ISDIR
);
768 else if(Name
== "Size")
769 xRow
->appendLong(rProp
,
771 else if(Name
== "DateCreated")
772 xRow
->appendTimestamp(rProp
,
775 xRow
->appendVoid(rProp
);
777 xRow
->appendVoid(rProp
);
784 Sequence
<Any
> FTPContent::setPropertyValues(
785 const Sequence
<PropertyValue
>& seqPropVal
)
787 Sequence
<Any
> ret(seqPropVal
.getLength());
788 auto retRange
= asNonConstRange(ret
);
789 Sequence
<PropertyChangeEvent
> evt
;
791 osl::MutexGuard
aGuard(m_aMutex
);
792 for(sal_Int32 i
= 0; i
< ret
.getLength(); ++i
) {
793 if ( seqPropVal
[i
].Name
== "Title" ) {
795 if(!(seqPropVal
[i
].Value
>>= Title
)) {
796 retRange
[i
] <<= IllegalTypeException();
798 } else if(Title
.isEmpty()) {
799 retRange
[i
] <<= IllegalArgumentException();
804 m_aFTPURL
.child(Title
);
806 new FTPContentIdentifier(m_aFTPURL
.ident(false,false));
810 OUString OldTitle
= m_aFTPURL
.ren(Title
);
811 evt
= { { /* Source */ {},
812 /* PropertyName */ "Title",
814 /* PropertyHandle */ -1,
815 /* OldValue */ Any(OldTitle
),
816 /* NewValue */ Any(Title
) } };
817 } catch(const curl_exception
&) {
818 InteractiveIOException excep
;
819 // any better possibility here?
820 // ( the error code is always CURLE_FTP_QUOTE_ERROR )
821 excep
.Code
= IOErrorCode_ACCESS_DENIED
;
822 retRange
[i
] <<= excep
;
825 const Sequence
<Property
> props
=
826 getProperties(Reference
<XCommandEnvironment
>(nullptr));
828 // either unknown or read-only
829 retRange
[i
] <<= UnknownPropertyException();
830 const auto& rName
= seqPropVal
[i
].Name
;
831 auto pProp
= std::find_if(props
.begin(), props
.end(),
832 [&rName
](const Property
& rProp
) { return rProp
.Name
== rName
; });
833 if (pProp
!= props
.end()) {
834 retRange
[i
] <<= IllegalAccessException(
835 "Property is read-only!",
836 //props[j].Attributes & PropertyAttribute::READONLY
837 // ? "Property is read-only!"
838 // : "Access denied!"),
839 static_cast< cppu::OWeakObject
* >( this ));
844 if(evt
.hasElements()) {
846 notifyPropertiesChange(evt
);
847 (void)exchange(new FTPContentIdentifier(m_aFTPURL
.ident(false,false)));
853 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */