bump product version to 5.0.4.1
[LibreOffice.git] / svl / source / misc / documentlockfile.cxx
blobba55fcb612721a66f67e32d41a32fd7993451f7d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
22 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
23 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
24 #include <com/sun/star/ucb/NameClashException.hpp>
25 #include <com/sun/star/io/WrongFormatException.hpp>
26 #include <com/sun/star/io/TempFile.hpp>
28 #include <osl/time.h>
29 #include <osl/security.hxx>
30 #include <osl/socket.hxx>
31 #include <o3tl/enumrange.hxx>
33 #include <rtl/string.hxx>
34 #include <rtl/ustring.hxx>
35 #include <rtl/strbuf.hxx>
36 #include <rtl/ustrbuf.hxx>
38 #include <comphelper/processfactory.hxx>
40 #include <unotools/bootstrap.hxx>
42 #include <ucbhelper/content.hxx>
44 #include <unotools/useroptions.hxx>
46 #include <svl/documentlockfile.hxx>
48 using namespace ::com::sun::star;
50 namespace svt {
52 bool DocumentLockFile::m_bAllowInteraction = true;
55 DocumentLockFile::DocumentLockFile( const OUString& aOrigURL )
56 : LockFileCommon( aOrigURL, OUString( ".~lock." ) )
61 DocumentLockFile::~DocumentLockFile()
66 void DocumentLockFile::WriteEntryToStream( const LockFileEntry& aEntry, uno::Reference< io::XOutputStream > xOutput )
68 ::osl::MutexGuard aGuard( m_aMutex );
70 OUStringBuffer aBuffer;
72 for ( LockFileComponent lft : o3tl::enumrange<LockFileComponent>() )
74 aBuffer.append( EscapeCharacters( aEntry[lft] ) );
75 if ( lft < LockFileComponent::LAST )
76 aBuffer.append( ',' );
77 else
78 aBuffer.append( ';' );
81 OString aStringData( OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ) );
82 uno::Sequence< sal_Int8 > aData( reinterpret_cast<sal_Int8 const *>(aStringData.getStr()), aStringData.getLength() );
83 xOutput->writeBytes( aData );
87 bool DocumentLockFile::CreateOwnLockFile()
89 ::osl::MutexGuard aGuard( m_aMutex );
91 try
93 uno::Reference< io::XStream > xTempFile(
94 io::TempFile::create( comphelper::getProcessComponentContext() ),
95 uno::UNO_QUERY_THROW );
96 uno::Reference< io::XSeekable > xSeekable( xTempFile, uno::UNO_QUERY_THROW );
98 uno::Reference< io::XInputStream > xInput = xTempFile->getInputStream();
99 uno::Reference< io::XOutputStream > xOutput = xTempFile->getOutputStream();
101 if ( !xInput.is() || !xOutput.is() )
102 throw uno::RuntimeException();
104 LockFileEntry aNewEntry = GenerateOwnEntry();
105 WriteEntryToStream( aNewEntry, xOutput );
106 xOutput->closeOutput();
108 xSeekable->seek( 0 );
110 uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
111 ::ucbhelper::Content aTargetContent( m_aURL, xEnv, comphelper::getProcessComponentContext() );
113 ucb::InsertCommandArgument aInsertArg;
114 aInsertArg.Data = xInput;
115 aInsertArg.ReplaceExisting = sal_False;
116 uno::Any aCmdArg;
117 aCmdArg <<= aInsertArg;
118 aTargetContent.executeCommand( OUString( "insert" ), aCmdArg );
120 // try to let the file be hidden if possible
121 try {
122 aTargetContent.setPropertyValue("IsHidden", uno::makeAny( sal_True ) );
123 } catch( uno::Exception& ) {}
125 catch( ucb::NameClashException& )
127 return false;
130 return true;
134 LockFileEntry DocumentLockFile::GetLockData()
136 ::osl::MutexGuard aGuard( m_aMutex );
138 uno::Reference< io::XInputStream > xInput = OpenStream();
139 if ( !xInput.is() )
140 throw uno::RuntimeException();
142 const sal_Int32 nBufLen = 32000;
143 uno::Sequence< sal_Int8 > aBuffer( nBufLen );
145 sal_Int32 nRead = 0;
147 nRead = xInput->readBytes( aBuffer, nBufLen );
148 xInput->closeInput();
150 if ( nRead == nBufLen )
151 throw io::WrongFormatException();
153 sal_Int32 nCurPos = 0;
154 return ParseEntry( aBuffer, nCurPos );
158 uno::Reference< io::XInputStream > DocumentLockFile::OpenStream()
160 ::osl::MutexGuard aGuard( m_aMutex );
162 uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
163 ::ucbhelper::Content aSourceContent( m_aURL, xEnv, comphelper::getProcessComponentContext() );
165 // the file can be opened readonly, no locking will be done
166 return aSourceContent.openStream();
170 bool DocumentLockFile::OverwriteOwnLockFile()
172 // allows to overwrite the lock file with the current data
175 uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
176 ::ucbhelper::Content aTargetContent( m_aURL, xEnv, comphelper::getProcessComponentContext() );
178 LockFileEntry aNewEntry = GenerateOwnEntry();
180 uno::Reference< io::XStream > xStream = aTargetContent.openWriteableStreamNoLock();
181 uno::Reference< io::XOutputStream > xOutput = xStream->getOutputStream();
182 uno::Reference< io::XTruncate > xTruncate( xOutput, uno::UNO_QUERY_THROW );
184 xTruncate->truncate();
185 WriteEntryToStream( aNewEntry, xOutput );
186 xOutput->closeOutput();
188 catch( uno::Exception& )
190 return false;
193 return true;
197 void DocumentLockFile::RemoveFile()
199 ::osl::MutexGuard aGuard( m_aMutex );
201 // TODO/LATER: the removing is not atomic, is it possible in general to make it atomic?
202 LockFileEntry aNewEntry = GenerateOwnEntry();
203 LockFileEntry aFileData = GetLockData();
205 if ( !aFileData[LockFileComponent::SYSUSERNAME].equals( aNewEntry[LockFileComponent::SYSUSERNAME] )
206 || !aFileData[LockFileComponent::LOCALHOST].equals( aNewEntry[LockFileComponent::LOCALHOST] )
207 || !aFileData[LockFileComponent::USERURL].equals( aNewEntry[LockFileComponent::USERURL] ) )
208 throw io::IOException(); // not the owner, access denied
210 uno::Reference < ::com::sun::star::ucb::XCommandEnvironment > xEnv;
211 ::ucbhelper::Content aCnt(m_aURL, xEnv, comphelper::getProcessComponentContext());
212 aCnt.executeCommand(OUString("delete"),
213 uno::makeAny(true));
216 } // namespace svt
218 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */