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