1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/lang/IllegalArgumentException.hpp>
22 #include <com/sun/star/io/WrongFormatException.hpp>
25 #include <osl/security.hxx>
26 #include <osl/socket.hxx>
27 #include <osl/file.hxx>
28 #include <o3tl/enumrange.hxx>
29 #include <o3tl/sprintf.hxx>
31 #include <rtl/ustring.hxx>
32 #include <rtl/strbuf.hxx>
33 #include <rtl/ustrbuf.hxx>
35 #include <tools/urlobj.hxx>
36 #include <unotools/bootstrap.hxx>
38 #include <unotools/useroptions.hxx>
40 #include <salhelper/linkhelper.hxx>
42 #include <svl/lockfilecommon.hxx>
45 using namespace ::com::sun::star
;
50 LockFileCommon::LockFileCommon(OUString aLockFileURL
)
51 : m_aURL(std::move(aLockFileURL
))
55 LockFileCommon::~LockFileCommon()
60 const OUString
& LockFileCommon::GetURL() const
66 void LockFileCommon::SetURL(const OUString
& aURL
)
72 OUString
LockFileCommon::GenerateOwnLockFileURL(
73 std::u16string_view aOrigURL
, std::u16string_view aPrefix
)
75 INetURLObject aURL
= ResolveLinks(INetURLObject(aOrigURL
));
76 aURL
.setName(Concat2View(aPrefix
+ aURL
.GetLastName() + "%23" /*'#'*/));
77 return aURL
.GetMainURL(INetURLObject::DecodeMechanism::NONE
);
81 INetURLObject
LockFileCommon::ResolveLinks( const INetURLObject
& aDocURL
)
83 if ( aDocURL
.HasError() )
84 throw lang::IllegalArgumentException();
86 OUString aURLToCheck
= aDocURL
.GetMainURL(INetURLObject::DecodeMechanism::NONE
);
88 // there is currently no UCB functionality to resolve the symbolic links;
89 // since the lock files are used only for local file systems the osl
90 // functionality is used directly
91 salhelper::LinkResolver
aResolver(osl_FileStatus_Mask_FileName
);
92 osl::FileBase::RC eStatus
= aResolver
.fetchFileStatus(aURLToCheck
);
93 if (eStatus
== osl::FileBase::E_None
)
94 aURLToCheck
= aResolver
.m_aStatus
.getFileURL();
95 else if (eStatus
== osl::FileBase::E_MULTIHOP
)
97 // do not allow too deep links
98 throw io::IOException();
101 return INetURLObject( aURLToCheck
);
105 void LockFileCommon::ParseList( const uno::Sequence
< sal_Int8
>& aBuffer
, std::vector
< LockFileEntry
> & aResult
)
107 sal_Int32 nCurPos
= 0;
108 while ( nCurPos
< aBuffer
.getLength() )
110 aResult
.push_back( ParseEntry( aBuffer
, nCurPos
) );
115 LockFileEntry
LockFileCommon::ParseEntry( const uno::Sequence
< sal_Int8
>& aBuffer
, sal_Int32
& io_nCurPos
)
117 LockFileEntry aResult
;
119 for ( LockFileComponent nInd
: o3tl::enumrange
<LockFileComponent
>() )
121 aResult
[nInd
] = ParseName( aBuffer
, io_nCurPos
);
122 if ( io_nCurPos
>= aBuffer
.getLength()
123 || ( nInd
< LockFileComponent::LAST
&& aBuffer
[io_nCurPos
++] != ',' )
124 || ( nInd
== LockFileComponent::LAST
&& aBuffer
[io_nCurPos
++] != ';' ) )
125 throw io::WrongFormatException();
132 OUString
LockFileCommon::ParseName( const uno::Sequence
< sal_Int8
>& aBuffer
, sal_Int32
& io_nCurPos
)
134 OStringBuffer
aResult(128);
135 bool bHaveName
= false;
136 bool bEscape
= false;
140 if ( io_nCurPos
>= aBuffer
.getLength() )
141 throw io::WrongFormatException();
145 if ( aBuffer
[io_nCurPos
] != ',' && aBuffer
[io_nCurPos
] != ';' && aBuffer
[io_nCurPos
] != '\\' )
146 throw io::WrongFormatException();
148 aResult
.append( static_cast<char>(aBuffer
[io_nCurPos
]) );
153 else if ( aBuffer
[io_nCurPos
] == ',' || aBuffer
[io_nCurPos
] == ';' )
157 if ( aBuffer
[io_nCurPos
] == '\\' )
160 aResult
.append( static_cast<char>(aBuffer
[io_nCurPos
]) );
166 return OStringToOUString( aResult
, RTL_TEXTENCODING_UTF8
);
170 OUString
LockFileCommon::EscapeCharacters( const OUString
& aSource
)
172 OUStringBuffer
aBuffer(aSource
.getLength()*2);
173 const sal_Unicode
* pStr
= aSource
.getStr();
174 for ( sal_Int32 nInd
= 0; nInd
< aSource
.getLength() && pStr
[nInd
] != 0; nInd
++ )
176 if ( pStr
[nInd
] == '\\' || pStr
[nInd
] == ';' || pStr
[nInd
] == ',' )
177 aBuffer
.append( '\\' );
178 aBuffer
.append( pStr
[nInd
] );
181 return aBuffer
.makeStringAndClear();
185 OUString
LockFileCommon::GetOOOUserName()
187 SvtUserOptions aUserOpt
;
188 OUString aName
= aUserOpt
.GetFirstName();
189 if ( !aName
.isEmpty() )
191 aName
+= aUserOpt
.GetLastName();
197 OUString
LockFileCommon::GetCurrentLocalTime()
202 if ( osl_getSystemTime( &aSysTime
) )
205 if ( osl_getLocalTimeFromSystemTime( &aSysTime
, &aLocTime
) )
207 oslDateTime aDateTime
;
208 if ( osl_getDateTimeFromTimeValue( &aLocTime
, &aDateTime
) )
210 char pDateTime
[sizeof("65535.65535.-32768 65535:65535")];
211 // reserve enough space for hypothetical max length
212 o3tl::sprintf( pDateTime
, "%02" SAL_PRIuUINT32
".%02" SAL_PRIuUINT32
".%4" SAL_PRIdINT32
" %02" SAL_PRIuUINT32
":%02" SAL_PRIuUINT32
, sal_uInt32(aDateTime
.Day
), sal_uInt32(aDateTime
.Month
), sal_Int32(aDateTime
.Year
), sal_uInt32(aDateTime
.Hours
), sal_uInt32(aDateTime
.Minutes
) );
213 aTime
= OUString::createFromAscii( pDateTime
);
222 LockFileEntry
LockFileCommon::GenerateOwnEntry()
224 LockFileEntry aResult
;
226 aResult
[LockFileComponent::OOOUSERNAME
] = GetOOOUserName();
228 ::osl::Security aSecurity
;
229 aSecurity
.getUserName( aResult
[LockFileComponent::SYSUSERNAME
] );
231 aResult
[LockFileComponent::LOCALHOST
] = ::osl::SocketAddr::getLocalHostname();
233 aResult
[LockFileComponent::EDITTIME
] = GetCurrentLocalTime();
235 ::utl::Bootstrap::locateUserInstallation( aResult
[LockFileComponent::USERURL
] );
243 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */