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 .
23 #include <com/sun/star/lang/IllegalArgumentException.hpp>
24 #include <com/sun/star/io/WrongFormatException.hpp>
27 #include <osl/security.hxx>
28 #include <osl/socket.hxx>
29 #include <osl/file.hxx>
30 #include <o3tl/enumrange.hxx>
32 #include <rtl/ustring.hxx>
33 #include <rtl/strbuf.hxx>
34 #include <rtl/ustrbuf.hxx>
36 #include <tools/urlobj.hxx>
37 #include <unotools/bootstrap.hxx>
39 #include <unotools/useroptions.hxx>
41 #include <salhelper/linkhelper.hxx>
43 #include <svl/lockfilecommon.hxx>
45 using namespace ::com::sun::star
;
50 LockFileCommon::LockFileCommon(const OUString
& aLockFileURL
)
51 : m_aURL(aLockFileURL
)
55 LockFileCommon::~LockFileCommon()
60 const OUString
& LockFileCommon::GetURL() const
66 void LockFileCommon::SetURL(const OUString
& aURL
)
72 OUString
LockFileCommon::GenerateOwnLockFileURL(const OUString
& aOrigURL
, const OUString
& aPrefix
)
74 INetURLObject aURL
= ResolveLinks(INetURLObject(aOrigURL
));
75 aURL
.setName(aPrefix
+ aURL
.GetLastName() + "%23" /*'#'*/);
76 return aURL
.GetMainURL(INetURLObject::DecodeMechanism::NONE
);
80 INetURLObject
LockFileCommon::ResolveLinks( const INetURLObject
& aDocURL
)
82 if ( aDocURL
.HasError() )
83 throw lang::IllegalArgumentException();
85 OUString aURLToCheck
= aDocURL
.GetMainURL(INetURLObject::DecodeMechanism::NONE
);
87 // there is currently no UCB functionality to resolve the symbolic links;
88 // since the lock files are used only for local file systems the osl
89 // functionality is used directly
90 salhelper::LinkResolver
aResolver(osl_FileStatus_Mask_FileName
);
91 osl::FileBase::RC eStatus
= aResolver
.fetchFileStatus(aURLToCheck
);
92 if (eStatus
== osl::FileBase::E_None
)
93 aURLToCheck
= aResolver
.m_aStatus
.getFileURL();
94 else if (eStatus
== osl::FileBase::E_MULTIHOP
)
96 // do not allow too deep links
97 throw io::IOException();
100 return INetURLObject( aURLToCheck
);
104 void LockFileCommon::ParseList( const uno::Sequence
< sal_Int8
>& aBuffer
, std::vector
< LockFileEntry
> & aResult
)
106 sal_Int32 nCurPos
= 0;
107 while ( nCurPos
< aBuffer
.getLength() )
109 aResult
.push_back( ParseEntry( aBuffer
, nCurPos
) );
114 LockFileEntry
LockFileCommon::ParseEntry( const uno::Sequence
< sal_Int8
>& aBuffer
, sal_Int32
& io_nCurPos
)
116 LockFileEntry aResult
;
118 for ( LockFileComponent nInd
: o3tl::enumrange
<LockFileComponent
>() )
120 aResult
[nInd
] = ParseName( aBuffer
, io_nCurPos
);
121 if ( io_nCurPos
>= aBuffer
.getLength()
122 || ( nInd
< LockFileComponent::LAST
&& aBuffer
[io_nCurPos
++] != ',' )
123 || ( nInd
== LockFileComponent::LAST
&& aBuffer
[io_nCurPos
++] != ';' ) )
124 throw io::WrongFormatException();
131 OUString
LockFileCommon::ParseName( const uno::Sequence
< sal_Int8
>& aBuffer
, sal_Int32
& io_nCurPos
)
133 OStringBuffer
aResult(128);
134 bool bHaveName
= false;
135 bool bEscape
= false;
139 if ( io_nCurPos
>= aBuffer
.getLength() )
140 throw io::WrongFormatException();
144 if ( aBuffer
[io_nCurPos
] != ',' && aBuffer
[io_nCurPos
] != ';' && aBuffer
[io_nCurPos
] != '\\' )
145 throw io::WrongFormatException();
147 aResult
.append( static_cast<char>(aBuffer
[io_nCurPos
]) );
152 else if ( aBuffer
[io_nCurPos
] == ',' || aBuffer
[io_nCurPos
] == ';' )
156 if ( aBuffer
[io_nCurPos
] == '\\' )
159 aResult
.append( static_cast<char>(aBuffer
[io_nCurPos
]) );
165 return OStringToOUString( aResult
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
);
169 OUString
LockFileCommon::EscapeCharacters( const OUString
& aSource
)
171 OUStringBuffer
aBuffer(aSource
.getLength()*2);
172 const sal_Unicode
* pStr
= aSource
.getStr();
173 for ( sal_Int32 nInd
= 0; nInd
< aSource
.getLength() && pStr
[nInd
] != 0; nInd
++ )
175 if ( pStr
[nInd
] == '\\' || pStr
[nInd
] == ';' || pStr
[nInd
] == ',' )
176 aBuffer
.append( '\\' );
177 aBuffer
.append( pStr
[nInd
] );
180 return aBuffer
.makeStringAndClear();
184 OUString
LockFileCommon::GetOOOUserName()
186 SvtUserOptions aUserOpt
;
187 OUString aName
= aUserOpt
.GetFirstName();
188 if ( !aName
.isEmpty() )
190 aName
+= aUserOpt
.GetLastName();
196 OUString
LockFileCommon::GetCurrentLocalTime()
201 if ( osl_getSystemTime( &aSysTime
) )
204 if ( osl_getLocalTimeFromSystemTime( &aSysTime
, &aLocTime
) )
206 oslDateTime aDateTime
;
207 if ( osl_getDateTimeFromTimeValue( &aLocTime
, &aDateTime
) )
209 char pDateTime
[sizeof("65535.65535.-32768 65535:65535")];
210 // reserve enough space for hypothetical max length
211 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
) );
212 aTime
= OUString::createFromAscii( pDateTime
);
221 LockFileEntry
LockFileCommon::GenerateOwnEntry()
223 LockFileEntry aResult
;
225 aResult
[LockFileComponent::OOOUSERNAME
] = GetOOOUserName();
227 ::osl::Security aSecurity
;
228 aSecurity
.getUserName( aResult
[LockFileComponent::SYSUSERNAME
] );
230 aResult
[LockFileComponent::LOCALHOST
] = ::osl::SocketAddr::getLocalHostname();
232 aResult
[LockFileComponent::EDITTIME
] = GetCurrentLocalTime();
234 ::utl::Bootstrap::locateUserInstallation( aResult
[LockFileComponent::USERURL
] );
242 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */