LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/ucb/source/ucp/ftp - ftpcontent.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 34 356 9.6 %
Date: 2013-07-09 Functions: 7 34 20.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : /**************************************************************************
      22             :                                 TODO
      23             :  **************************************************************************
      24             : 
      25             :  *************************************************************************/
      26             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      27             : 
      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 "ftpcfunc.hxx"
      36             : #include "ftpstrcont.hxx"
      37             : #include "ftpintreq.hxx"
      38             : 
      39             : #include <memory>
      40             : #include <vector>
      41             : #include <string.h>
      42             : #include "curl.hxx"
      43             : #include <curl/easy.h>
      44             : #include <comphelper/processfactory.hxx>
      45             : #include <ucbhelper/cancelcommandexecution.hxx>
      46             : #include <ucbhelper/contentidentifier.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/ucb/ContentInfoAttribute.hpp>
      52             : #include <com/sun/star/beans/UnknownPropertyException.hpp>
      53             : #include <com/sun/star/beans/Property.hpp>
      54             : #include <com/sun/star/beans/PropertyValue.hpp>
      55             : #include <com/sun/star/ucb/XCommandInfo.hpp>
      56             : #include <com/sun/star/io/XActiveDataSink.hpp>
      57             : #include <com/sun/star/io/XOutputStream.hpp>
      58             : #include <com/sun/star/io/XActiveDataStreamer.hpp>
      59             : #include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
      60             : #include <com/sun/star/ucb/OpenCommandArgument2.hpp>
      61             : #include <com/sun/star/ucb/UnsupportedOpenModeException.hpp>
      62             : #include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
      63             : #include <com/sun/star/ucb/InteractiveNetworkResolveNameException.hpp>
      64             : #include <com/sun/star/ucb/InteractiveIOException.hpp>
      65             : #include <com/sun/star/ucb/MissingPropertiesException.hpp>
      66             : #include <com/sun/star/ucb/MissingInputStreamException.hpp>
      67             : #include <com/sun/star/ucb/UnsupportedNameClashException.hpp>
      68             : #include <com/sun/star/ucb/NameClashException.hpp>
      69             : #include <com/sun/star/ucb/OpenMode.hpp>
      70             : #include <com/sun/star/ucb/IOErrorCode.hpp>
      71             : 
      72             : using namespace ftp;
      73             : using namespace com::sun::star::task;
      74             : using namespace com::sun::star::container;
      75             : using namespace com::sun::star::lang;
      76             : using namespace com::sun::star::uno;
      77             : using namespace com::sun::star::ucb;
      78             : using namespace com::sun::star::beans;
      79             : using namespace com::sun::star::io;
      80             : using namespace com::sun::star::sdbc;
      81             : 
      82             : 
      83             : 
      84             : //=========================================================================
      85             : //=========================================================================
      86             : //
      87             : // Content Implementation.
      88             : //
      89             : //=========================================================================
      90             : //=========================================================================
      91             : 
      92           2 : FTPContent::FTPContent( const Reference< XComponentContext >& rxContext,
      93             :                         FTPContentProvider* pProvider,
      94             :                         const Reference< XContentIdentifier >& Identifier,
      95             :                         const FTPURL& aFTPURL)
      96             :     : ContentImplHelper(rxContext,pProvider,Identifier),
      97             :       m_pFCP(pProvider),
      98             :       m_aFTPURL(aFTPURL),
      99             :       m_bInserted(false),
     100           2 :       m_bTitleSet(false)
     101             : {
     102           2 : }
     103             : 
     104             : 
     105             : 
     106           0 : FTPContent::FTPContent( const Reference< XComponentContext >& rxContext,
     107             :                         FTPContentProvider* pProvider,
     108             :                         const Reference< XContentIdentifier >& Identifier,
     109             :                         const ContentInfo& Info)
     110             :     : ContentImplHelper(rxContext,pProvider,Identifier),
     111             :       m_pFCP(pProvider),
     112           0 :       m_aFTPURL(Identifier->getContentIdentifier(),
     113             :                 pProvider),
     114             :       m_bInserted(true),
     115             :       m_bTitleSet(false),
     116           0 :       m_aInfo(Info)
     117             : {
     118           0 : }
     119             : 
     120             : 
     121             : 
     122             : //=========================================================================
     123             : 
     124           4 : FTPContent::~FTPContent()
     125             : {
     126           4 : }
     127             : 
     128             : 
     129             : //=========================================================================
     130             : //
     131             : // XInterface methods.
     132             : //
     133             : //=========================================================================
     134             : 
     135          40 : XINTERFACE_IMPL_6( FTPContent,
     136             :                    XTypeProvider,
     137             :                    XServiceInfo,
     138             :                    XContent,
     139             :                    XCommandProcessor,
     140             :                    XContentCreator,
     141             :                    XChild);
     142             : 
     143             : //=========================================================================
     144             : //
     145             : // XTypeProvider methods.
     146             : //
     147             : //=========================================================================
     148             : 
     149           0 : XTYPEPROVIDER_IMPL_6( FTPContent,
     150             :                           XTypeProvider,
     151             :                           XServiceInfo,
     152             :                           XContent,
     153             :                       XCommandProcessor,
     154             :                       XContentCreator,
     155             :                       XChild);
     156             : 
     157             : //=========================================================================
     158             : //
     159             : // XServiceInfo methods.
     160             : //
     161             : //=========================================================================
     162             : 
     163             : // needed, because the service shall not be creatable!!
     164             : #undef XSERVICEINFO_CREATE_INSTANCE_IMPL
     165             : #define XSERVICEINFO_CREATE_INSTANCE_IMPL( Class )
     166             : 
     167           0 : XSERVICEINFO_IMPL_1( FTPContent,
     168             :                      OUString( "com.sun.star.comp.FTPContent"),
     169             :                      OUString( "com.sun.star.ucb.FTPContent"));
     170             : 
     171             : 
     172             : 
     173             : //=========================================================================
     174             : //
     175             : // XContent methods.
     176             : //
     177             : //=========================================================================
     178             : 
     179             : // virtual
     180           0 : OUString SAL_CALL FTPContent::getContentType()
     181             :     throw( RuntimeException )
     182             : {
     183           0 :     return OUString(FTP_CONTENT_TYPE);
     184             : }
     185             : 
     186             : 
     187             : //=========================================================================
     188             : //
     189             : // XCommandProcessor methods.
     190             : //
     191             : //=========================================================================
     192             : 
     193             : 
     194             : //virtual
     195           0 : void SAL_CALL FTPContent::abort( sal_Int32 /*CommandId*/ )
     196             :     throw( RuntimeException )
     197             : {
     198           0 : }
     199             : 
     200             : 
     201             : 
     202             : /***************************************************************************/
     203             : /*                                                                         */
     204             : /*                     Internal implementation class.                      */
     205             : /*                                                                         */
     206             : /***************************************************************************/
     207             : 
     208             : 
     209           0 : class ResultSetFactoryI
     210             :     : public ResultSetFactory
     211             : {
     212             : public:
     213             : 
     214           0 :     ResultSetFactoryI(const Reference<XComponentContext >&  rxContext,
     215             :                       const Reference<XContentProvider >&  xProvider,
     216             :                       sal_Int32 nOpenMode,
     217             :                       const Sequence<Property>& seq,
     218             :                       const Sequence<NumberedSortingInfo>& seqSort,
     219             :                       const std::vector<FTPDirentry>& dirvec)
     220             :         : m_xContext(rxContext),
     221             :           m_xProvider(xProvider),
     222             :           m_nOpenMode(nOpenMode),
     223             :           m_seq(seq),
     224             :           m_seqSort(seqSort),
     225           0 :           m_dirvec(dirvec)
     226             :     {
     227           0 :     }
     228             : 
     229           0 :     virtual ResultSetBase* createResultSet()
     230             :     {
     231             :         return new ResultSetI(m_xContext,
     232             :                               m_xProvider,
     233             :                               m_nOpenMode,
     234             :                               m_seq,
     235             :                               m_seqSort,
     236           0 :                               m_dirvec);
     237             :     }
     238             : 
     239             : public:
     240             : 
     241             :     Reference< XComponentContext >                  m_xContext;
     242             :     Reference< XContentProvider >                   m_xProvider;
     243             :     sal_Int32                                       m_nOpenMode;
     244             :     Sequence< Property >                            m_seq;
     245             :     Sequence< NumberedSortingInfo >                 m_seqSort;
     246             :     std::vector<FTPDirentry>                        m_dirvec;
     247             : };
     248             : 
     249             : 
     250             : 
     251             : //=========================================================================
     252             : //
     253             : // XCommandProcessor methods.
     254             : //
     255             : //=========================================================================
     256             : 
     257             : enum ACTION { NOACTION,
     258             :               THROWAUTHENTICATIONREQUEST,
     259             :               THROWACCESSDENIED,
     260             :               THROWINTERACTIVECONNECT,
     261             :               THROWRESOLVENAME,
     262             :               THROWQUOTE,
     263             :               THROWNOFILE,
     264             :               THROWGENERAL };
     265             : 
     266             : 
     267             : // virtual
     268           1 : Any SAL_CALL FTPContent::execute(
     269             :     const Command& aCommand,
     270             :     sal_Int32 /*CommandId*/,
     271             :     const Reference<
     272             :     XCommandEnvironment >& Environment
     273             : )
     274             :     throw(
     275             :         Exception,
     276             :         CommandAbortedException,
     277             :         RuntimeException
     278             :     )
     279             : {
     280           1 :     ACTION action(NOACTION);
     281           1 :     Any aRet;
     282             : 
     283             :     while(true)
     284             :         try {
     285           2 :             if(action == THROWAUTHENTICATIONREQUEST) {
     286             :                 // try to get a continuation first
     287           0 :                 OUString aRealm,aPassword,aAccount;
     288             :                 m_pFCP->forHost(m_aFTPURL.host(),
     289             :                                 m_aFTPURL.port(),
     290             :                                 m_aFTPURL.username(),
     291             :                                 aPassword,
     292           0 :                                 aAccount);
     293             :                 rtl::Reference<ucbhelper::SimpleAuthenticationRequest>
     294             :                     p( new ucbhelper::SimpleAuthenticationRequest(
     295             :                         m_aFTPURL.ident(false, false),
     296             :                         m_aFTPURL.host(),      // ServerName
     297             :                         ucbhelper::SimpleAuthenticationRequest::ENTITY_NA,
     298             :                         aRealm,
     299             :                         ucbhelper::SimpleAuthenticationRequest
     300             :                         ::ENTITY_FIXED,
     301             :                         m_aFTPURL.username(),
     302             :                         ucbhelper::SimpleAuthenticationRequest
     303             :                         ::ENTITY_MODIFY,
     304           0 :                         aPassword));
     305             : 
     306           0 :                 Reference<XInteractionHandler> xInteractionHandler;
     307           0 :                 if(Environment.is())
     308           0 :                     xInteractionHandler =
     309           0 :                         Environment->getInteractionHandler();
     310             : 
     311           0 :                 if( xInteractionHandler.is()) {
     312           0 :                     xInteractionHandler->handle(p.get());
     313             : 
     314             :                     Reference<XInterface> xSelection(
     315           0 :                         p->getSelection().get());
     316             : 
     317           0 :                     if(Reference<XInteractionRetry>(
     318           0 :                         xSelection,UNO_QUERY).is())
     319           0 :                         action = NOACTION;
     320           0 :                     else if(Reference<XInteractionSupplyAuthentication>(
     321           0 :                         xSelection,UNO_QUERY).is()) {
     322             :                         m_pFCP->setHost(
     323             :                             m_aFTPURL.host(),
     324             :                             m_aFTPURL.port(),
     325             :                             m_aFTPURL.username(),
     326           0 :                             p->getAuthenticationSupplier()->getPassword(),
     327           0 :                             aAccount);
     328           0 :                         action = NOACTION;
     329           0 :                     }
     330             :                 }
     331           0 :                 aRet = p->getRequest();
     332             :             }
     333             : 
     334             : //              if(aCommand.Name.compareToAscii(
     335             : //                  "getPropertyValues") == 0 &&
     336             : //                 action != NOACTION) {
     337             : //                  // It is not allowed to throw if
     338             : //                  // command is getPropertyValues
     339             : //                  rtl::Reference<ucbhelper::PropertyValueSet> xRow =
     340             : //                      new ucbhelper::PropertyValueSet(m_xSMgr);
     341             : //                  Sequence<Property> Properties;
     342             : //                  aCommand.Argument >>= Properties;
     343             : //                  for(int i = 0; i < Properties.getLength(); ++i)
     344             : //                      xRow->appendVoid(Properties[i]);
     345             : //                  aRet <<= Reference<XRow>(xRow.get());
     346             : //                  return aRet;
     347             : //              }
     348             : 
     349           2 :             switch (action)
     350             :             {
     351             :             case NOACTION:
     352           1 :                 break;
     353             : 
     354             :             case THROWAUTHENTICATIONREQUEST:
     355             :                 ucbhelper::cancelCommandExecution(
     356             :                     aRet,
     357           0 :                     Reference<XCommandEnvironment>(0));
     358           0 :                 break;
     359             : 
     360             :             case THROWACCESSDENIED:
     361             :                 {
     362           0 :                     Sequence<Any> seq(1);
     363           0 :                     PropertyValue value;
     364           0 :                     value.Name = OUString("Uri");
     365           0 :                     value.Handle = -1;
     366           0 :                     value.Value <<= m_aFTPURL.ident(false,false);
     367           0 :                     value.State = PropertyState_DIRECT_VALUE;
     368           0 :                     seq[0] <<= value;
     369             :                     ucbhelper::cancelCommandExecution(
     370             :                         IOErrorCode_ACCESS_DENIED,
     371             :                         seq,
     372           0 :                         Environment);
     373           0 :                     break;
     374             :                 }
     375             :             case THROWINTERACTIVECONNECT:
     376             :                 {
     377           0 :                     InteractiveNetworkConnectException excep;
     378           0 :                     excep.Server = m_aFTPURL.host();
     379           0 :                     aRet <<= excep;
     380             :                     ucbhelper::cancelCommandExecution(
     381             :                         aRet,
     382           0 :                         Environment);
     383           0 :                     break;
     384             :                 }
     385             :             case THROWRESOLVENAME:
     386             :                 {
     387           1 :                     InteractiveNetworkResolveNameException excep;
     388           1 :                     excep.Server = m_aFTPURL.host();
     389           1 :                     aRet <<= excep;
     390             :                     ucbhelper::cancelCommandExecution(
     391             :                         aRet,
     392           1 :                         Environment);
     393           1 :                     break;
     394             :                 }
     395             :             case THROWNOFILE:
     396             :                 {
     397           0 :                     Sequence<Any> seq(1);
     398           0 :                     PropertyValue value;
     399           0 :                     value.Name = OUString("Uri");
     400           0 :                     value.Handle = -1;
     401           0 :                     value.Value <<= m_aFTPURL.ident(false,false);
     402           0 :                     value.State = PropertyState_DIRECT_VALUE;
     403           0 :                     seq[0] <<= value;
     404             :                     ucbhelper::cancelCommandExecution(
     405             :                         IOErrorCode_NO_FILE,
     406             :                         seq,
     407           0 :                         Environment);
     408           0 :                     break;
     409             :                 }
     410             :             case THROWQUOTE:
     411             :             case THROWGENERAL:
     412             :                 ucbhelper::cancelCommandExecution(
     413             :                     IOErrorCode_GENERAL,
     414             :                     Sequence<Any>(0),
     415           0 :                     Environment);
     416           0 :                 break;
     417             :             }
     418             : 
     419           1 :             if(aCommand.Name.compareToAscii("getPropertyValues") == 0) {
     420           0 :                 Sequence<Property> Properties;
     421           0 :                 if(!(aCommand.Argument >>= Properties))
     422             :                 {
     423           0 :                     aRet <<= IllegalArgumentException(
     424             :                                 OUString( "Wrong argument type!" ),
     425             :                                 static_cast< cppu::OWeakObject * >(this),
     426           0 :                                 -1);
     427           0 :                     ucbhelper::cancelCommandExecution(aRet,Environment);
     428             :                 }
     429             : 
     430           0 :                 aRet <<= getPropertyValues(Properties,Environment);
     431             :             }
     432           1 :             else if(aCommand.Name.compareToAscii("setPropertyValues") == 0)
     433             :             {
     434           0 :                 Sequence<PropertyValue> propertyValues;
     435             : 
     436           0 :                 if( ! ( aCommand.Argument >>= propertyValues ) ) {
     437           0 :                     aRet <<= IllegalArgumentException(
     438             :                                 OUString( "Wrong argument type!" ),
     439             :                                 static_cast< cppu::OWeakObject * >(this),
     440           0 :                                 -1);
     441           0 :                     ucbhelper::cancelCommandExecution(aRet,Environment);
     442             :                 }
     443             : 
     444           0 :                 aRet <<= setPropertyValues(propertyValues);
     445             :             }
     446           1 :             else if(aCommand.Name.compareToAscii("getCommandInfo") == 0) {
     447             :                 // Note: Implemented by base class.
     448           0 :                 aRet <<= getCommandInfo(Environment);
     449             :             }
     450           1 :             else if(aCommand.Name.compareToAscii("getPropertySetInfo") == 0) {
     451             :                 // Note: Implemented by base class.
     452           0 :                 aRet <<= getPropertySetInfo(Environment);
     453             :             }
     454           1 :             else if(aCommand.Name.compareToAscii( "insert" ) == 0)
     455             :             {
     456           0 :                 InsertCommandArgument aInsertArgument;
     457           0 :                 if ( ! ( aCommand.Argument >>= aInsertArgument ) ) {
     458           0 :                     aRet <<= IllegalArgumentException(
     459             :                                 OUString( "Wrong argument type!" ),
     460             :                                 static_cast< cppu::OWeakObject * >(this),
     461           0 :                                 -1);
     462           0 :                     ucbhelper::cancelCommandExecution(aRet,Environment);
     463             :                 }
     464           0 :                 insert(aInsertArgument,Environment);
     465             :             }
     466           1 :             else if(aCommand.Name.compareToAscii("delete") == 0) {
     467           0 :                 m_aFTPURL.del();
     468           0 :                 deleted();
     469             :             }
     470           1 :             else if(aCommand.Name.compareToAscii( "open" ) == 0) {
     471           1 :                 OpenCommandArgument2 aOpenCommand;
     472           1 :                 if ( !( aCommand.Argument >>= aOpenCommand ) ) {
     473           0 :                     aRet <<= IllegalArgumentException(
     474             :                                 OUString( "Wrong argument type!" ),
     475             :                                 static_cast< cppu::OWeakObject * >(this),
     476           0 :                                 -1);
     477             : 
     478           0 :                     ucbhelper::cancelCommandExecution(aRet,Environment);
     479             :                 }
     480             : 
     481           1 :                 if(aOpenCommand.Mode == OpenMode::DOCUMENT) {
     482             :                     // Open as a document
     483             :                     Reference<XActiveDataSink>
     484           0 :                         xActiveDataSink(aOpenCommand.Sink,UNO_QUERY);
     485             :                     Reference< XOutputStream >
     486           0 :                         xOutputStream(aOpenCommand.Sink,UNO_QUERY);
     487             : 
     488           0 :                     if(xActiveDataSink.is()) {
     489           0 :                         xActiveDataSink->setInputStream(
     490           0 :                             new ucbhelper::FdInputStream(m_aFTPURL.open()));
     491             :                     }
     492           0 :                     else if(xOutputStream.is()) {
     493             :                         Reference<XInputStream> xStream(
     494           0 :                             new ucbhelper::FdInputStream(m_aFTPURL.open()));
     495           0 :                         Sequence<sal_Int8> byte_seq(4096);
     496           0 :                         sal_Int32 n = 1000; // value does not matter here
     497             :                         for (;;) {
     498           0 :                             n = xStream->readBytes(byte_seq,4096);
     499           0 :                             if (n == 0) {
     500           0 :                                 break;
     501             :                             }
     502             :                             try {
     503           0 :                                 if(byte_seq.getLength() != n)
     504           0 :                                     byte_seq.realloc(n);
     505           0 :                                 xOutputStream->writeBytes(byte_seq);
     506           0 :                             } catch(const NotConnectedException&) {
     507             : 
     508           0 :                             } catch(const BufferSizeExceededException&) {
     509             : 
     510           0 :                             } catch(const IOException&) {
     511             : 
     512             :                             }
     513           0 :                         }
     514           0 :                         if(n) {
     515           0 :                             Sequence<Any> seq(1);
     516           0 :                             PropertyValue value;
     517           0 :                             value.Name = OUString("Uri");
     518           0 :                             value.Handle = -1;
     519           0 :                             value.Value <<= m_aFTPURL.ident(false,false);
     520           0 :                             value.State = PropertyState_DIRECT_VALUE;
     521           0 :                             seq[0] <<= value;
     522             :                             ucbhelper::cancelCommandExecution(
     523             :                                 IOErrorCode_UNKNOWN,
     524             :                                 seq,
     525           0 :                                 Environment);
     526           0 :                         }
     527             :                     }
     528             :                     else {
     529           0 :                         aRet <<= UnsupportedDataSinkException(
     530             :                             OUString(),
     531             :                             static_cast< cppu::OWeakObject * >(this),
     532           0 :                             aOpenCommand.Sink);
     533           0 :                         ucbhelper::cancelCommandExecution(aRet,Environment);
     534           0 :                     }
     535             :                 }
     536           1 :                 else if(aOpenCommand.Mode == OpenMode::ALL ||
     537           0 :                         aOpenCommand.Mode == OpenMode::DOCUMENTS ||
     538           0 :                         aOpenCommand.Mode == OpenMode::FOLDERS ) {
     539             :                     std::vector<FTPDirentry> resvec =
     540           1 :                         m_aFTPURL.list(sal_Int16(aOpenCommand.Mode));
     541             :                     Reference< XDynamicResultSet > xSet
     542             :                         = new DynamicResultSet(
     543             :                             m_xContext,
     544             :                             this,
     545             :                             aOpenCommand,
     546             :                             Environment,
     547             :                             new ResultSetFactoryI(m_xContext,
     548           0 :                                                   m_xProvider.get(),
     549             :                                                   aOpenCommand.Mode,
     550             :                                                   aOpenCommand.Properties,
     551             :                                                   aOpenCommand.SortingInfo,
     552           0 :                                                   resvec));
     553           0 :                     aRet <<= xSet;
     554             :                 }
     555           0 :                 else if(aOpenCommand.Mode ==
     556           0 :                         OpenMode::DOCUMENT_SHARE_DENY_NONE ||
     557           0 :                         aOpenCommand.Mode ==
     558             :                         OpenMode::DOCUMENT_SHARE_DENY_WRITE) {
     559             :                     // Unsupported OpenMode
     560           0 :                     aRet <<= UnsupportedOpenModeException(
     561             :                         OUString(),
     562             :                         static_cast< cppu::OWeakObject * >(this),
     563           0 :                         static_cast< sal_Int16 >(aOpenCommand.Mode));
     564           0 :                     ucbhelper::cancelCommandExecution(aRet,Environment);
     565             :                 }
     566             :                 else {
     567           0 :                     aRet <<= IllegalArgumentException(
     568             :                                 OUString( "Unexpected OpenMode!" ),
     569             :                                 static_cast< cppu::OWeakObject * >(this),
     570           0 :                                 -1);
     571             : 
     572           0 :                     ucbhelper::cancelCommandExecution(aRet,Environment);
     573           1 :                 }
     574           0 :             } else if(aCommand.Name.compareToAscii("createNewContent") == 0) {
     575           0 :                 ContentInfo aArg;
     576           0 :                 if (!(aCommand.Argument >>= aArg)) {
     577             :                     ucbhelper::cancelCommandExecution(
     578             :                         makeAny(
     579             :                             IllegalArgumentException(
     580             :                                 OUString( "Wrong argument type!" ),
     581             :                                 static_cast< cppu::OWeakObject * >(this),
     582             :                                 -1)),
     583           0 :                         Environment);
     584             :                     // Unreachable
     585             :                 }
     586           0 :                 aRet <<= createNewContent(aArg);
     587             :             } else {
     588           0 :                 aRet <<= UnsupportedCommandException(
     589             :                     aCommand.Name,
     590           0 :                     static_cast< cppu::OWeakObject * >(this));
     591           0 :                 ucbhelper::cancelCommandExecution(aRet,Environment);
     592             :             }
     593             : 
     594           0 :             return aRet;
     595           2 :         } catch(const curl_exception& e) {
     596           1 :             if(e.code() == CURLE_COULDNT_CONNECT)
     597           0 :                 action = THROWINTERACTIVECONNECT;
     598           1 :             else if(e.code() == CURLE_COULDNT_RESOLVE_HOST )
     599           1 :                 action = THROWRESOLVENAME;
     600           0 :             else if(e.code() == CURLE_FTP_USER_PASSWORD_INCORRECT ||
     601           0 :                     e.code() == CURLE_LOGIN_DENIED ||
     602           0 :                     e.code() == CURLE_BAD_PASSWORD_ENTERED ||
     603           0 :                     e.code() == CURLE_FTP_WEIRD_PASS_REPLY)
     604           0 :                 action = THROWAUTHENTICATIONREQUEST;
     605           0 :             else if(e.code() == CURLE_FTP_ACCESS_DENIED)
     606           0 :                 action = THROWACCESSDENIED;
     607           0 :             else if(e.code() == CURLE_FTP_QUOTE_ERROR)
     608           0 :                 action = THROWQUOTE;
     609           0 :             else if(e.code() == CURLE_FTP_COULDNT_RETR_FILE)
     610           0 :                 action = THROWNOFILE;
     611             :             else
     612             :                 // nothing known about the cause of the error
     613           0 :                 action = THROWGENERAL;
     614             :         }
     615             : }
     616             : 
     617             : #define FTP_FILE OUString( "application/vnd.sun.staroffice.ftp-file")
     618             : 
     619             : #define FTP_FOLDER OUString( "application/vnd.sun.staroffice.ftp-folder")
     620             : 
     621             : Sequence<ContentInfo > SAL_CALL
     622           0 : FTPContent::queryCreatableContentsInfo(  )
     623             :     throw (RuntimeException)
     624             : {
     625           0 :     return queryCreatableContentsInfo_Static();
     626             : }
     627             : 
     628             : // static
     629             : Sequence<ContentInfo >
     630           0 : FTPContent::queryCreatableContentsInfo_Static(  )
     631             :     throw (RuntimeException)
     632             : {
     633           0 :     Sequence< ContentInfo > seq(2);
     634             : 
     635           0 :     seq[0].Type = FTP_FILE;
     636           0 :     seq[0].Attributes = ContentInfoAttribute::INSERT_WITH_INPUTSTREAM
     637           0 :         | ContentInfoAttribute::KIND_DOCUMENT;
     638           0 :     Sequence< Property > props( 1 );
     639           0 :     props[0] = Property(
     640             :         OUString("Title"),
     641             :         -1,
     642           0 :         getCppuType( static_cast< OUString* >( 0 ) ),
     643             :         PropertyAttribute::MAYBEVOID
     644           0 :         | PropertyAttribute::BOUND );
     645           0 :     seq[0].Properties = props;
     646             : 
     647             :     // folder
     648           0 :     seq[1].Type       = FTP_FOLDER;
     649           0 :     seq[1].Attributes = ContentInfoAttribute::KIND_FOLDER;
     650           0 :     seq[1].Properties = props;
     651             : 
     652           0 :     return seq;
     653             : }
     654             : 
     655             : Reference<XContent > SAL_CALL
     656           0 : FTPContent::createNewContent( const ContentInfo& Info )
     657             :     throw (RuntimeException)
     658             : {
     659           0 :     if( Info.Type =="application/vnd.sun.staroffice.ftp-file" || Info.Type == "application/vnd.sun.staroffice.ftp-folder" )
     660             :         return new FTPContent(m_xContext,
     661             :                               m_pFCP,
     662           0 :                               m_xIdentifier,Info);
     663             :     else
     664           0 :         return Reference<XContent>(0);
     665             : }
     666             : 
     667             : 
     668             : 
     669             : 
     670             : Reference<XInterface > SAL_CALL
     671           0 : FTPContent::getParent(  )
     672             :     throw (RuntimeException)
     673             : {
     674             :     Reference<XContentIdentifier>
     675           0 :         xIdent(new FTPContentIdentifier(m_aFTPURL.parent(false)));
     676           0 :     return m_xProvider->queryContent(xIdent);
     677             : }
     678             : 
     679             : 
     680             : void SAL_CALL
     681           0 : FTPContent::setParent(const Reference<XInterface >& /*Parent*/ )
     682             :     throw (NoSupportException,
     683             :            RuntimeException)
     684             : {
     685           0 :     throw NoSupportException();
     686             : }
     687             : 
     688             : 
     689             : 
     690           0 : OUString FTPContent::getParentURL()
     691             : {
     692           0 :     return m_aFTPURL.parent();
     693             : }
     694             : 
     695             : 
     696             : class InsertData
     697             :     : public CurlInput {
     698             : 
     699             : public:
     700             : 
     701           0 :     InsertData(const Reference<XInputStream>& xInputStream)
     702           0 :         : m_xInputStream(xInputStream) { }
     703           0 :     virtual ~InsertData() {}
     704             : 
     705             :     // returns the number of bytes actually read
     706             :     virtual sal_Int32 read(sal_Int8 *dest,sal_Int32 nBytesRequested);
     707             : 
     708             : private:
     709             : 
     710             :     Reference<XInputStream> m_xInputStream;
     711             : };
     712             : 
     713             : 
     714             : 
     715           0 : sal_Int32 InsertData::read(sal_Int8 *dest,sal_Int32 nBytesRequested)
     716             : {
     717           0 :     sal_Int32 m = 0;
     718             : 
     719           0 :     if(m_xInputStream.is()) {
     720           0 :             Sequence<sal_Int8> seq(nBytesRequested);
     721           0 :         m = m_xInputStream->readBytes(seq,nBytesRequested);
     722           0 :         memcpy(dest,seq.getConstArray(),m);
     723             :     }
     724           0 :     return m;
     725             : }
     726             : 
     727             : 
     728           0 : void FTPContent::insert(const InsertCommandArgument& aInsertCommand,
     729             :                         const Reference<XCommandEnvironment>& Env)
     730             : {
     731           0 :     osl::MutexGuard aGuard(m_aMutex);
     732             : 
     733           0 :     if(m_bInserted && !m_bTitleSet) {
     734           0 :         MissingPropertiesException excep;
     735           0 :         excep.Properties.realloc(1);
     736           0 :         excep.Properties[0] = OUString("Title");
     737           0 :         Any aAny; aAny <<= excep;
     738           0 :         ucbhelper::cancelCommandExecution(aAny,Env);
     739             :     }
     740             : 
     741           0 :     if(m_bInserted &&
     742           0 :        m_aInfo.Type == FTP_FILE &&
     743           0 :        !aInsertCommand.Data.is())
     744             :     {
     745           0 :         MissingInputStreamException excep;
     746           0 :         Any aAny; aAny <<= excep;
     747           0 :         ucbhelper::cancelCommandExecution(aAny,Env);
     748             :     }
     749             : 
     750           0 :     bool bReplace(aInsertCommand.ReplaceExisting);
     751             : 
     752             :  retry:
     753             :     try {
     754           0 :         if(m_aInfo.Type == FTP_FILE) {
     755           0 :             InsertData data(aInsertCommand.Data);
     756           0 :             m_aFTPURL.insert(bReplace,&data);
     757           0 :         } else if(m_aInfo.Type == FTP_FOLDER)
     758           0 :             m_aFTPURL.mkdir(bReplace);
     759           0 :     } catch(const curl_exception& e) {
     760           0 :         if(e.code() == FILE_EXIST_DURING_INSERT ||
     761           0 :            e.code() == FOLDER_EXIST_DURING_INSERT) {
     762             :             // Deprecated, not used anymore:
     763           0 :             NameClashException excep;
     764           0 :             excep.Name = m_aFTPURL.child();
     765           0 :             Any aAny;
     766           0 :             aAny <<= excep;
     767           0 :             ucbhelper::cancelCommandExecution(aAny,Env);
     768           0 :         } else if(e.code() == FOLDER_MIGHT_EXIST_DURING_INSERT ||
     769           0 :                   e.code() == FILE_MIGHT_EXIST_DURING_INSERT) {
     770             :             // Interact
     771           0 :             Reference<XInteractionHandler> xInt;
     772           0 :             if(Env.is())
     773           0 :                 xInt = Env->getInteractionHandler();
     774             : 
     775           0 :             UnsupportedNameClashException excep;
     776           0 :             excep.NameClash = 0; //NameClash::ERROR;
     777             : 
     778           0 :             if(!xInt.is()) {
     779           0 :                 Any aAny;
     780           0 :                 aAny <<= excep;
     781           0 :                 ucbhelper::cancelCommandExecution(aAny,Env);
     782             :             }
     783             : 
     784             :             XInteractionRequestImpl* p =
     785           0 :                 new XInteractionRequestImpl(m_aFTPURL.child());
     786           0 :             Reference<XInteractionRequest> req(p);
     787           0 :             xInt->handle(req);
     788           0 :             if(p->approved()) {
     789           0 :                 bReplace = true;
     790           0 :                 goto retry;
     791             :             }
     792             :             else
     793           0 :                 throw excep;
     794             :         }
     795             :         else
     796           0 :             throw;
     797           0 :     }
     798             : 
     799             :     // May not be reached, because both mkdir and insert can throw curl-
     800             :     // exceptions
     801           0 :     m_bInserted = false;
     802           0 :     inserted();
     803           0 : }
     804             : 
     805             : 
     806             : 
     807           0 : Reference< XRow > FTPContent::getPropertyValues(
     808             :     const Sequence< Property >& seqProp,
     809             :     const Reference<XCommandEnvironment>& /*environment*/
     810             : )
     811             : {
     812             :     rtl::Reference<ucbhelper::PropertyValueSet> xRow =
     813           0 :         new ucbhelper::PropertyValueSet(m_xContext);
     814             : 
     815           0 :     FTPDirentry aDirEntry = m_aFTPURL.direntry();
     816             : 
     817           0 :     for(sal_Int32 i = 0; i < seqProp.getLength(); ++i) {
     818           0 :         const OUString& Name = seqProp[i].Name;
     819           0 :         if(Name.compareToAscii("Title") == 0)
     820           0 :             xRow->appendString(seqProp[i],aDirEntry.m_aName);
     821           0 :         else if(Name.compareToAscii("CreatableContentsInfo") == 0)
     822           0 :             xRow->appendObject(seqProp[i],
     823           0 :                                makeAny(queryCreatableContentsInfo()));
     824           0 :         else if(aDirEntry.m_nMode != INETCOREFTP_FILEMODE_UNKNOWN) {
     825           0 :             if(Name.compareToAscii("ContentType") == 0)
     826           0 :                 xRow->appendString(seqProp[i],
     827           0 :                                    aDirEntry.m_nMode&INETCOREFTP_FILEMODE_ISDIR
     828             :                                    ? FTP_FOLDER
     829           0 :                                    : FTP_FILE );
     830           0 :             else if(Name.compareToAscii("IsReadOnly") == 0)
     831           0 :                 xRow->appendBoolean(seqProp[i],
     832             :                                     aDirEntry.m_nMode
     833           0 :                                     & INETCOREFTP_FILEMODE_WRITE
     834             :                                     ? 0
     835           0 :                                     : 1 );
     836           0 :             else if(Name.compareToAscii("IsDocument") == 0)
     837           0 :                 xRow->appendBoolean(seqProp[i],
     838             :                                     ! sal_Bool(aDirEntry.m_nMode &
     839           0 :                                                INETCOREFTP_FILEMODE_ISDIR));
     840           0 :             else if(Name.compareToAscii("IsFolder") == 0)
     841           0 :                 xRow->appendBoolean(seqProp[i],
     842             :                                     sal_Bool(aDirEntry.m_nMode &
     843           0 :                                              INETCOREFTP_FILEMODE_ISDIR));
     844           0 :             else if(Name.compareToAscii("Size") == 0)
     845           0 :                 xRow->appendLong(seqProp[i],
     846           0 :                                  aDirEntry.m_nSize);
     847           0 :             else if(Name.compareToAscii("DateCreated") == 0)
     848           0 :                 xRow->appendTimestamp(seqProp[i],
     849           0 :                                       aDirEntry.m_aDate);
     850             :             else
     851           0 :                 xRow->appendVoid(seqProp[i]);
     852             :         } else
     853           0 :             xRow->appendVoid(seqProp[i]);
     854             :     }
     855             : 
     856           0 :     return Reference<XRow>(xRow.get());
     857             : }
     858             : 
     859             : 
     860             : 
     861           0 : Sequence<Any> FTPContent::setPropertyValues(
     862             :     const Sequence<PropertyValue>& seqPropVal)
     863             : {
     864           0 :     Sequence<Any> ret(seqPropVal.getLength());
     865           0 :     Sequence<PropertyChangeEvent > evt;
     866             : 
     867           0 :     osl::MutexGuard aGuard(m_aMutex);
     868           0 :     for(sal_Int32 i = 0; i < ret.getLength(); ++i) {
     869           0 :         if ( seqPropVal[i].Name == "Title" ) {
     870           0 :             OUString Title;
     871           0 :             if(!(seqPropVal[i].Value >>= Title)) {
     872           0 :                 ret[i] <<= IllegalTypeException();
     873           0 :                 continue;
     874           0 :             } else if(Title.isEmpty()) {
     875           0 :                 ret[i] <<= IllegalArgumentException();
     876           0 :                 continue;
     877             :             }
     878             : 
     879           0 :             if(m_bInserted) {
     880           0 :                 m_aFTPURL.child(Title);
     881           0 :                 m_xIdentifier =
     882           0 :                     new FTPContentIdentifier(m_aFTPURL.ident(false,false));
     883           0 :                 m_bTitleSet = true;
     884             :             } else
     885             :                 try {
     886           0 :                     OUString OldTitle = m_aFTPURL.ren(Title);
     887           0 :                     evt.realloc(1);
     888           0 :                     evt[0].PropertyName =
     889           0 :                         OUString("Title");
     890           0 :                     evt[0].Further = false;
     891           0 :                     evt[0].PropertyHandle = -1;
     892           0 :                     evt[0].OldValue <<= OldTitle;
     893           0 :                     evt[0].NewValue <<= Title;
     894           0 :                 } catch(const curl_exception&) {
     895           0 :                     InteractiveIOException excep;
     896             :                     // any better possibility here?
     897             :                     // ( the error code is always CURLE_FTP_QUOTE_ERROR )
     898           0 :                     excep.Code = IOErrorCode_ACCESS_DENIED;
     899           0 :                     ret[i] <<= excep;
     900           0 :                 }
     901             :         } else {
     902             :             Sequence<Property> props =
     903           0 :                 getProperties(Reference<XCommandEnvironment>(0));
     904             : 
     905             :             // either unknown or read-only
     906           0 :             ret[i] <<= UnknownPropertyException();
     907           0 :             for(sal_Int32 j = 0; j < props.getLength(); ++j)
     908           0 :                 if(props[j].Name == seqPropVal[i].Name) {
     909           0 :                     ret[i] <<= IllegalAccessException(
     910             :                         OUString( "Property is read-only!"),
     911             :                             //props[j].Attributes & PropertyAttribute::READONLY
     912             :                             //    ? "Property is read-only!"
     913             :                             //    : "Access denied!"),
     914           0 :                         static_cast< cppu::OWeakObject * >( this ));
     915           0 :                     break;
     916           0 :                 }
     917             :         }
     918             :     }
     919             : 
     920           0 :     if(evt.getLength()) {
     921             :         // title has changed
     922           0 :         notifyPropertiesChange(evt);
     923           0 :         exchange(new FTPContentIdentifier(m_aFTPURL.ident(false,false)));
     924             :     }
     925             : 
     926           0 :     return ret;
     927             : }
     928             : 
     929             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10