LCOV - code coverage report
Current view: top level - svl/source/misc - documentlockfile.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 78 89 87.6 %
Date: 2012-08-25 Functions: 8 8 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 96 220 43.6 %

           Branch data     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                 :            : #include <stdio.h>
      22                 :            : 
      23                 :            : #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
      24                 :            : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
      25                 :            : #include <com/sun/star/ucb/InsertCommandArgument.hpp>
      26                 :            : #include <com/sun/star/ucb/NameClashException.hpp>
      27                 :            : #include <com/sun/star/io/WrongFormatException.hpp>
      28                 :            : 
      29                 :            : #include <osl/time.h>
      30                 :            : #include <osl/security.hxx>
      31                 :            : #include <osl/socket.hxx>
      32                 :            : 
      33                 :            : #include <rtl/string.hxx>
      34                 :            : #include <rtl/ustring.hxx>
      35                 :            : #include <rtl/strbuf.hxx>
      36                 :            : #include <rtl/ustrbuf.hxx>
      37                 :            : 
      38                 :            : #include <comphelper/processfactory.hxx>
      39                 :            : 
      40                 :            : #include <unotools/bootstrap.hxx>
      41                 :            : 
      42                 :            : #include <ucbhelper/content.hxx>
      43                 :            : 
      44                 :            : #include <unotools/useroptions.hxx>
      45                 :            : 
      46                 :            : #include <svl/documentlockfile.hxx>
      47                 :            : 
      48                 :            : using namespace ::com::sun::star;
      49                 :            : 
      50                 :            : namespace svt {
      51                 :            : 
      52                 :            : sal_Bool DocumentLockFile::m_bAllowInteraction = sal_True;
      53                 :            : 
      54                 :            : // ----------------------------------------------------------------------
      55                 :        182 : DocumentLockFile::DocumentLockFile( const ::rtl::OUString& aOrigURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
      56         [ +  - ]:        182 : : LockFileCommon( aOrigURL, xFactory, ::rtl::OUString( ".~lock."  ) )
      57                 :            : {
      58                 :        182 : }
      59                 :            : 
      60                 :            : // ----------------------------------------------------------------------
      61                 :        182 : DocumentLockFile::~DocumentLockFile()
      62                 :            : {
      63                 :        182 : }
      64                 :            : 
      65                 :            : // ----------------------------------------------------------------------
      66                 :         88 : void DocumentLockFile::WriteEntryToStream( uno::Sequence< ::rtl::OUString > aEntry, uno::Reference< io::XOutputStream > xOutput )
      67                 :            : {
      68         [ +  - ]:         88 :     ::osl::MutexGuard aGuard( m_aMutex );
      69                 :            : 
      70                 :         88 :     ::rtl::OUStringBuffer aBuffer;
      71                 :            : 
      72         [ +  + ]:        528 :     for ( sal_Int32 nEntryInd = 0; nEntryInd < aEntry.getLength(); nEntryInd++ )
      73                 :            :     {
      74 [ +  - ][ +  - ]:        440 :         aBuffer.append( EscapeCharacters( aEntry[nEntryInd] ) );
                 [ +  - ]
      75         [ +  + ]:        440 :         if ( nEntryInd < aEntry.getLength() - 1 )
      76         [ +  - ]:        352 :             aBuffer.append( (sal_Unicode)',' );
      77                 :            :         else
      78         [ +  - ]:         88 :             aBuffer.append( (sal_Unicode)';' );
      79                 :            :     }
      80                 :            : 
      81 [ +  - ][ +  - ]:         88 :     ::rtl::OString aStringData( ::rtl::OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ) );
      82         [ +  - ]:         88 :     uno::Sequence< sal_Int8 > aData( (sal_Int8*)aStringData.getStr(), aStringData.getLength() );
      83 [ +  - ][ +  - ]:         88 :     xOutput->writeBytes( aData );
         [ +  - ][ +  - ]
      84                 :         88 : }
      85                 :            : 
      86                 :            : // ----------------------------------------------------------------------
      87                 :         91 : sal_Bool DocumentLockFile::CreateOwnLockFile()
      88                 :            : {
      89         [ +  - ]:         91 :     ::osl::MutexGuard aGuard( m_aMutex );
      90                 :            : 
      91                 :            :     try
      92                 :            :     {
      93                 :            :         uno::Reference< io::XStream > xTempFile(
      94         [ +  - ]:         91 :             m_xFactory->createInstance( ::rtl::OUString("com.sun.star.io.TempFile") ),
      95 [ +  - ][ +  + ]:         91 :             uno::UNO_QUERY_THROW );
      96         [ +  - ]:         88 :         uno::Reference< io::XSeekable > xSeekable( xTempFile, uno::UNO_QUERY_THROW );
      97                 :            : 
      98 [ +  - ][ +  - ]:         88 :         uno::Reference< io::XInputStream > xInput = xTempFile->getInputStream();
      99 [ +  - ][ +  - ]:         88 :         uno::Reference< io::XOutputStream > xOutput = xTempFile->getOutputStream();
     100                 :            : 
     101 [ +  - ][ -  + ]:         88 :         if ( !xInput.is() || !xOutput.is() )
                 [ -  + ]
     102         [ #  # ]:          0 :             throw uno::RuntimeException();
     103                 :            : 
     104         [ +  - ]:         88 :         uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry();
     105 [ +  - ][ +  - ]:         88 :         WriteEntryToStream( aNewEntry, xOutput );
                 [ +  - ]
     106 [ +  - ][ +  - ]:         88 :         xOutput->closeOutput();
     107                 :            : 
     108 [ +  - ][ +  - ]:         88 :         xSeekable->seek( 0 );
     109                 :            : 
     110                 :         88 :         uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
     111         [ +  - ]:         88 :         ::ucbhelper::Content aTargetContent( m_aURL, xEnv );
     112                 :            : 
     113         [ +  - ]:         88 :         ucb::InsertCommandArgument aInsertArg;
     114         [ +  - ]:         88 :         aInsertArg.Data = xInput;
     115                 :         88 :         aInsertArg.ReplaceExisting = sal_False;
     116                 :         88 :         uno::Any aCmdArg;
     117         [ +  - ]:         88 :         aCmdArg <<= aInsertArg;
     118         [ +  - ]:         88 :         aTargetContent.executeCommand( ::rtl::OUString( "insert"  ), aCmdArg );
     119                 :            : 
     120                 :            :         // try to let the file be hidden if possible
     121                 :            :         try {
     122 [ +  - ][ #  # ]:         88 :             aTargetContent.setPropertyValue( ::rtl::OUString( "IsHidden"  ), uno::makeAny( sal_True ) );
                 [ +  - ]
     123 [ +  - ][ +  - ]:         91 :         } catch( uno::Exception& ) {}
         [ +  - ][ #  # ]
                 [ +  - ]
     124                 :            :     }
     125         [ #  # ]:          0 :     catch( ucb::NameClashException& )
     126                 :            :     {
     127                 :          0 :         return sal_False;
     128                 :            :     }
     129                 :            : 
     130         [ +  - ]:         91 :     return sal_True;
     131                 :            : }
     132                 :            : 
     133                 :            : // ----------------------------------------------------------------------
     134                 :         91 : uno::Sequence< ::rtl::OUString > DocumentLockFile::GetLockData()
     135                 :            : {
     136         [ +  - ]:         91 :     ::osl::MutexGuard aGuard( m_aMutex );
     137                 :            : 
     138         [ +  + ]:         91 :     uno::Reference< io::XInputStream > xInput = OpenStream();
     139         [ -  + ]:         88 :     if ( !xInput.is() )
     140         [ #  # ]:          0 :         throw uno::RuntimeException();
     141                 :            : 
     142                 :         88 :     const sal_Int32 nBufLen = 32000;
     143         [ +  - ]:         88 :     uno::Sequence< sal_Int8 > aBuffer( nBufLen );
     144                 :            : 
     145                 :         88 :     sal_Int32 nRead = 0;
     146                 :            : 
     147 [ +  - ][ +  - ]:         88 :     nRead = xInput->readBytes( aBuffer, nBufLen );
     148 [ +  - ][ +  - ]:         88 :     xInput->closeInput();
     149                 :            : 
     150         [ -  + ]:         88 :     if ( nRead == nBufLen )
     151         [ #  # ]:          0 :         throw io::WrongFormatException();
     152                 :            : 
     153                 :         88 :     sal_Int32 nCurPos = 0;
     154 [ +  - ][ +  - ]:         91 :     return ParseEntry( aBuffer, nCurPos );
                 [ +  - ]
     155                 :            : }
     156                 :            : 
     157                 :            : // ----------------------------------------------------------------------
     158                 :         91 : uno::Reference< io::XInputStream > DocumentLockFile::OpenStream()
     159                 :            : {
     160         [ +  - ]:         91 :     ::osl::MutexGuard aGuard( m_aMutex );
     161                 :            : 
     162                 :         91 :     uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
     163         [ +  - ]:         91 :     ::ucbhelper::Content aSourceContent( m_aURL, xEnv );
     164                 :            : 
     165                 :            :     // the file can be opened readonly, no locking will be done
     166 [ +  + ][ +  - ]:         91 :     return aSourceContent.openStream();
                 [ +  - ]
     167                 :            : }
     168                 :            : 
     169                 :            : // ----------------------------------------------------------------------
     170                 :          3 : sal_Bool DocumentLockFile::OverwriteOwnLockFile()
     171                 :            : {
     172                 :            :     // allows to overwrite the lock file with the current data
     173                 :            :     try
     174                 :            :     {
     175                 :          3 :         uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
     176         [ +  - ]:          3 :         ::ucbhelper::Content aTargetContent( m_aURL, xEnv );
     177                 :            : 
     178         [ +  - ]:          3 :         uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry();
     179                 :            : 
     180         [ -  + ]:          3 :         uno::Reference< io::XStream > xStream = aTargetContent.openWriteableStreamNoLock();
     181 [ #  # ][ #  # ]:          0 :         uno::Reference< io::XOutputStream > xOutput = xStream->getOutputStream();
     182         [ #  # ]:          0 :         uno::Reference< io::XTruncate > xTruncate( xOutput, uno::UNO_QUERY_THROW );
     183                 :            : 
     184 [ #  # ][ #  # ]:          0 :         xTruncate->truncate();
     185 [ #  # ][ #  # ]:          0 :         WriteEntryToStream( aNewEntry, xOutput );
                 [ #  # ]
     186 [ #  # ][ #  # ]:          3 :         xOutput->closeOutput();
         [ #  # ][ -  + ]
                 [ #  # ]
     187                 :            :     }
     188                 :          3 :     catch( uno::Exception& )
     189                 :            :     {
     190                 :          3 :         return sal_False;
     191                 :            :     }
     192                 :            : 
     193                 :          3 :     return sal_True;
     194                 :            : }
     195                 :            : 
     196                 :            : // ----------------------------------------------------------------------
     197                 :         91 : void DocumentLockFile::RemoveFile()
     198                 :            : {
     199         [ +  - ]:         91 :     ::osl::MutexGuard aGuard( m_aMutex );
     200                 :            : 
     201                 :            :     // TODO/LATER: the removing is not atomar, is it possible in general to make it atomar?
     202         [ +  - ]:         91 :     uno::Sequence< ::rtl::OUString > aNewEntry = GenerateOwnEntry();
     203         [ +  + ]:         91 :     uno::Sequence< ::rtl::OUString > aFileData = GetLockData();
     204                 :            : 
     205         [ -  + ]:         88 :     if ( aFileData.getLength() < LOCKFILE_ENTRYSIZE )
     206         [ #  # ]:          0 :         throw io::WrongFormatException();
     207                 :            : 
     208 [ +  - ][ +  - ]:        264 :     if ( !aFileData[LOCKFILE_SYSUSERNAME_ID].equals( aNewEntry[LOCKFILE_SYSUSERNAME_ID] )
           [ +  -  +  -  
           -  + ][ -  + ]
     209 [ +  - ][ +  - ]:         88 :       || !aFileData[LOCKFILE_LOCALHOST_ID].equals( aNewEntry[LOCKFILE_LOCALHOST_ID] )
     210 [ +  - ][ +  - ]:         88 :       || !aFileData[LOCKFILE_USERURL_ID].equals( aNewEntry[LOCKFILE_USERURL_ID] ) )
     211         [ #  # ]:          0 :         throw io::IOException(); // not the owner, access denied
     212                 :            : 
     213                 :         88 :     uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
     214         [ +  - ]:         88 :     ::ucbhelper::Content aCnt(m_aURL, xEnv);
     215                 :            :     aCnt.executeCommand(rtl::OUString("delete"),
     216 [ +  - ][ +  - ]:         91 :         uno::makeAny(sal_Bool(sal_True)));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     217                 :         88 : }
     218                 :            : 
     219                 :            : } // namespace svt
     220                 :            : 
     221                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10