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 : : #include <osl/file.hxx>
33 : :
34 : : #include <rtl/string.hxx>
35 : : #include <rtl/ustring.hxx>
36 : : #include <rtl/strbuf.hxx>
37 : : #include <rtl/ustrbuf.hxx>
38 : :
39 : : #include <comphelper/processfactory.hxx>
40 : :
41 : : #include <tools/urlobj.hxx>
42 : : #include <unotools/bootstrap.hxx>
43 : :
44 : : #include <ucbhelper/content.hxx>
45 : :
46 : : #include <unotools/useroptions.hxx>
47 : :
48 : : #include <salhelper/linkhelper.hxx>
49 : :
50 : : #include <svl/lockfilecommon.hxx>
51 : :
52 : : using namespace ::com::sun::star;
53 : :
54 : : namespace svt {
55 : :
56 : : // ----------------------------------------------------------------------
57 : 182 : LockFileCommon::LockFileCommon( const ::rtl::OUString& aOrigURL, const uno::Reference< lang::XMultiServiceFactory >& xFactory, const ::rtl::OUString& aPrefix )
58 : 182 : : m_xFactory( xFactory )
59 : : {
60 [ + - ]: 182 : if ( !m_xFactory.is() )
61 [ + - ][ + - ]: 182 : m_xFactory = ::comphelper::getProcessServiceFactory();
62 : :
63 [ + - ][ + - ]: 182 : INetURLObject aDocURL = ResolveLinks( INetURLObject( aOrigURL ) );
[ + - ]
64 : :
65 [ + - ]: 182 : ::rtl::OUString aShareURLString = aDocURL.GetPartBeforeLastName();
66 : 182 : aShareURLString += aPrefix;
67 [ + - ]: 182 : aShareURLString += aDocURL.GetName();
68 : 182 : aShareURLString += "%23"; // '#'
69 [ + - ][ + - ]: 182 : m_aURL = INetURLObject( aShareURLString ).GetMainURL( INetURLObject::NO_DECODE );
[ + - ][ + - ]
70 : 182 : }
71 : :
72 : : // ----------------------------------------------------------------------
73 : 182 : LockFileCommon::~LockFileCommon()
74 : : {
75 : 182 : }
76 : :
77 : : // ----------------------------------------------------------------------
78 : 182 : INetURLObject LockFileCommon::ResolveLinks( const INetURLObject& aDocURL )
79 : : {
80 [ - + ]: 182 : if ( aDocURL.HasError() )
81 [ # # ]: 0 : throw lang::IllegalArgumentException();
82 : :
83 [ + - ]: 182 : ::rtl::OUString aURLToCheck = aDocURL.GetMainURL(INetURLObject::NO_DECODE);
84 : :
85 : : // there is currently no UCB functionality to resolve the symbolic links;
86 : : // since the lock files are used only for local file systems the osl
87 : : // functionality is used directly
88 : 182 : salhelper::LinkResolver aResolver(osl_FileStatus_Mask_FileName);
89 [ + - ]: 182 : osl::FileBase::RC eStatus = aResolver.fetchFileStatus(aURLToCheck);
90 [ + + ]: 182 : if (eStatus == osl::FileBase::E_None)
91 [ + - ]: 152 : aURLToCheck = aResolver.m_aStatus.getFileURL();
92 [ - + ]: 30 : else if (eStatus == osl::FileBase::E_MULTIHOP)
93 : : {
94 : : // do not allow too deep links
95 [ # # ]: 0 : throw io::IOException();
96 : : }
97 : :
98 [ + - ]: 182 : return INetURLObject( aURLToCheck );
99 : : }
100 : :
101 : : // ----------------------------------------------------------------------
102 : 0 : uno::Sequence< uno::Sequence< ::rtl::OUString > > LockFileCommon::ParseList( const uno::Sequence< sal_Int8 >& aBuffer )
103 : : {
104 : 0 : sal_Int32 nCurPos = 0;
105 : 0 : sal_Int32 nCurEntry = 0;
106 [ # # ]: 0 : uno::Sequence< uno::Sequence< ::rtl::OUString > > aResult( 10 );
107 : :
108 [ # # ]: 0 : while ( nCurPos < aBuffer.getLength() )
109 : : {
110 [ # # ]: 0 : if ( nCurEntry >= aResult.getLength() )
111 [ # # ]: 0 : aResult.realloc( nCurEntry + 10 );
112 [ # # ][ # # ]: 0 : aResult[nCurEntry] = ParseEntry( aBuffer, nCurPos );
[ # # ][ # # ]
113 : 0 : nCurEntry++;
114 : : }
115 : :
116 [ # # ]: 0 : aResult.realloc( nCurEntry );
117 : 0 : return aResult;
118 : : }
119 : :
120 : : // ----------------------------------------------------------------------
121 : 88 : uno::Sequence< ::rtl::OUString > LockFileCommon::ParseEntry( const uno::Sequence< sal_Int8 >& aBuffer, sal_Int32& io_nCurPos )
122 : : {
123 : 88 : uno::Sequence< ::rtl::OUString > aResult( LOCKFILE_ENTRYSIZE );
124 : :
125 [ + + ]: 528 : for ( int nInd = 0; nInd < LOCKFILE_ENTRYSIZE; nInd++ )
126 : : {
127 [ + - ][ + - ]: 440 : aResult[nInd] = ParseName( aBuffer, io_nCurPos );
128 [ + + + - ]: 880 : if ( io_nCurPos >= aBuffer.getLength()
[ + + - + ]
[ - + ][ + - ]
129 : 352 : || ( nInd < LOCKFILE_ENTRYSIZE - 1 && aBuffer[io_nCurPos++] != ',' )
130 : 88 : || ( nInd == LOCKFILE_ENTRYSIZE - 1 && aBuffer[io_nCurPos++] != ';' ) )
131 [ # # ]: 0 : throw io::WrongFormatException();
132 : : }
133 : :
134 : 88 : return aResult;
135 : : }
136 : :
137 : : // ----------------------------------------------------------------------
138 : 440 : ::rtl::OUString LockFileCommon::ParseName( const uno::Sequence< sal_Int8 >& aBuffer, sal_Int32& io_nCurPos )
139 : : {
140 : 440 : ::rtl::OStringBuffer aResult;
141 : 440 : sal_Bool bHaveName = sal_False;
142 : 440 : sal_Bool bEscape = sal_False;
143 : :
144 [ + + ]: 11416 : while( !bHaveName )
145 : : {
146 [ - + ]: 10976 : if ( io_nCurPos >= aBuffer.getLength() )
147 [ # # ]: 0 : throw io::WrongFormatException();
148 : :
149 [ - + ]: 10976 : if ( bEscape )
150 : : {
151 [ # # ][ # # ]: 0 : if ( aBuffer[io_nCurPos] == ',' || aBuffer[io_nCurPos] == ';' || aBuffer[io_nCurPos] == '\\' )
[ # # ][ # # ]
152 [ # # ]: 0 : aResult.append( (sal_Char)aBuffer[io_nCurPos] );
153 : : else
154 [ # # ]: 0 : throw io::WrongFormatException();
155 : :
156 : 0 : bEscape = sal_False;
157 : 0 : io_nCurPos++;
158 : : }
159 [ + + ][ + + ]: 10976 : else if ( aBuffer[io_nCurPos] == ',' || aBuffer[io_nCurPos] == ';' )
[ + + ]
160 : 440 : bHaveName = sal_True;
161 : : else
162 : : {
163 [ - + ]: 10536 : if ( aBuffer[io_nCurPos] == '\\' )
164 : 0 : bEscape = sal_True;
165 : : else
166 [ + - ]: 10536 : aResult.append( (sal_Char)aBuffer[io_nCurPos] );
167 : :
168 : 10536 : io_nCurPos++;
169 : : }
170 : : }
171 : :
172 [ + - ]: 440 : return ::rtl::OStringToOUString( aResult.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
173 : : }
174 : :
175 : : // ----------------------------------------------------------------------
176 : 440 : ::rtl::OUString LockFileCommon::EscapeCharacters( const ::rtl::OUString& aSource )
177 : : {
178 : 440 : ::rtl::OUStringBuffer aBuffer;
179 : 440 : const sal_Unicode* pStr = aSource.getStr();
180 [ + + ][ + - ]: 10976 : for ( sal_Int32 nInd = 0; nInd < aSource.getLength() && pStr[nInd] != 0; nInd++ )
[ + + ]
181 : : {
182 [ + - ][ + - ]: 10536 : if ( pStr[nInd] == '\\' || pStr[nInd] == ';' || pStr[nInd] == ',' )
[ - + ]
183 [ # # ]: 0 : aBuffer.append( (sal_Unicode)'\\' );
184 [ + - ]: 10536 : aBuffer.append( pStr[nInd] );
185 : : }
186 : :
187 [ + - ]: 440 : return aBuffer.makeStringAndClear();
188 : : }
189 : :
190 : : // ----------------------------------------------------------------------
191 : 182 : ::rtl::OUString LockFileCommon::GetOOOUserName()
192 : : {
193 [ + - ]: 182 : SvtUserOptions aUserOpt;
194 [ + - ]: 182 : ::rtl::OUString aName = aUserOpt.GetFirstName();
195 [ - + ]: 182 : if ( !aName.isEmpty() )
196 : 0 : aName += " ";
197 [ + - ]: 182 : aName += aUserOpt.GetLastName();
198 : :
199 [ + - ]: 182 : return aName;
200 : : }
201 : :
202 : : // ----------------------------------------------------------------------
203 : 182 : ::rtl::OUString LockFileCommon::GetCurrentLocalTime()
204 : : {
205 : 182 : ::rtl::OUString aTime;
206 : :
207 : : TimeValue aSysTime;
208 [ + - ][ + - ]: 182 : if ( osl_getSystemTime( &aSysTime ) )
209 : : {
210 : : TimeValue aLocTime;
211 [ + - ][ + - ]: 182 : if ( osl_getLocalTimeFromSystemTime( &aSysTime, &aLocTime ) )
212 : : {
213 : : oslDateTime aDateTime;
214 [ + - ][ + - ]: 182 : if ( osl_getDateTimeFromTimeValue( &aLocTime, &aDateTime ) )
215 : : {
216 : : char pDateTime[20];
217 : 182 : sprintf( pDateTime, "%02d.%02d.%4d %02d:%02d", aDateTime.Day, aDateTime.Month, aDateTime.Year, aDateTime.Hours, aDateTime.Minutes );
218 : 182 : aTime = ::rtl::OUString::createFromAscii( pDateTime );
219 : : }
220 : : }
221 : : }
222 : :
223 : 182 : return aTime;
224 : : }
225 : :
226 : : // ----------------------------------------------------------------------
227 : 182 : uno::Sequence< ::rtl::OUString > LockFileCommon::GenerateOwnEntry()
228 : : {
229 [ + - ]: 182 : uno::Sequence< ::rtl::OUString > aResult( LOCKFILE_ENTRYSIZE );
230 : :
231 [ + - ][ + - ]: 182 : aResult[LOCKFILE_OOOUSERNAME_ID] = GetOOOUserName();
232 : :
233 [ + - ]: 182 : ::osl::Security aSecurity;
234 [ + - ][ + - ]: 182 : aSecurity.getUserName( aResult[LOCKFILE_SYSUSERNAME_ID] );
235 : :
236 [ + - ][ + - ]: 182 : aResult[LOCKFILE_LOCALHOST_ID] = ::osl::SocketAddr::getLocalHostname();
237 : :
238 [ + - ][ + - ]: 182 : aResult[LOCKFILE_EDITTIME_ID] = GetCurrentLocalTime();
239 : :
240 [ + - ][ + - ]: 182 : ::utl::Bootstrap::locateUserInstallation( aResult[LOCKFILE_USERURL_ID] );
241 : :
242 : :
243 [ + - ]: 182 : return aResult;
244 : : }
245 : :
246 : : } // namespace svt
247 : :
248 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|