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 .
20 #include <sal/config.h>
29 #if !defined WIN32_LEAN_AND_MEAN
30 # define WIN32_LEAN_AND_MEAN
34 #include <comphelper/random.hxx>
35 #include <sal/types.h>
36 #include <osl/file.hxx>
37 #include <osl/socket.hxx>
38 #include <osl/security.hxx>
39 #include <unotools/bootstrap.hxx>
40 #include <tools/config.hxx>
42 #include <lockfile.hxx>
44 using namespace ::osl
;
45 using namespace ::utl
;
48 static OString
impl_getHostname()
53 prevent windows from connecting to the net to get its own
54 hostname by using the netbios name
56 DWORD sz
= MAX_COMPUTERNAME_LENGTH
+ 1;
57 auto szHost
= std::make_unique
<char[]>(sz
);
58 if (GetComputerNameA(szHost
.get(), &sz
))
59 aHost
= OString(szHost
.get());
61 aHost
= OString("UNKNOWN");
63 /* Don't do dns lookup on Linux either */
64 sal_Char pHostName
[1024];
66 if ( gethostname( pHostName
, sizeof( pHostName
) - 1 ) == 0 )
68 pHostName
[sizeof( pHostName
) - 1] = '\0';
69 aHost
= OString( pHostName
);
72 aHost
= OString("UNKNOWN");
80 Lockfile::Lockfile( bool bIPCserver
)
81 :m_bIPCserver(bIPCserver
)
85 // build the file-url to use for the lock
87 utl::Bootstrap::locateUserInstallation( aUserPath
);
88 m_aLockname
= aUserPath
+ "/.lock";
91 const int nIdBytes
= 16;
92 char tmpId
[nIdBytes
*2+1];
93 time_t t
= time(nullptr);
94 for (int i
= 0; i
<nIdBytes
; i
++) {
95 int tmpByte
= comphelper::rng::uniform_int_distribution(0, 0xFF);
96 sprintf( tmpId
+i
*2, "%02X", tmpByte
);
98 tmpId
[nIdBytes
*2]=0x00;
99 m_aId
= OUString::createFromAscii( tmpId
);
101 // generate date string
102 char *tmpTime
= ctime( &t
);
103 if (tmpTime
!= nullptr) {
104 m_aDate
= OUString::createFromAscii( tmpTime
);
105 sal_Int32 i
= m_aDate
.indexOf('\n');
107 m_aDate
= m_aDate
.copy(0, i
);
111 // try to create file
112 File
aFile(m_aLockname
);
113 if (aFile
.open( osl_File_OpenFlag_Create
) == File::E_EXIST
) {
123 bool Lockfile::check( fpExecWarning execWarning
)
127 // lock existed, ask user what to do
129 (execWarning
!= nullptr && (*execWarning
)( this ))) {
130 // remove file and create new
131 File::remove( m_aLockname
);
132 File
aFile(m_aLockname
);
133 (void)aFile
.open( osl_File_OpenFlag_Create
);
139 //leave alone and return false
144 // lock was created by us
149 bool Lockfile::isStale() const
151 // this checks whether the lockfile was created on the same
152 // host by the same user. Should this be the case it is safe
153 // to assume that it is a stale lockfile which can be overwritten
154 OUString aLockname
= m_aLockname
;
155 Config
aConfig(aLockname
);
156 aConfig
.SetGroup(LOCKFILE_GROUP
);
157 OString aIPCserver
= aConfig
.ReadKey( LOCKFILE_IPCKEY
);
158 if (!aIPCserver
.equalsIgnoreAsciiCase("true"))
161 OString aHost
= aConfig
.ReadKey( LOCKFILE_HOSTKEY
);
162 OString aUser
= aConfig
.ReadKey( LOCKFILE_USERKEY
);
164 // lockfile from same host?
165 OString
myHost( impl_getHostname() );
166 if (aHost
== myHost
) {
167 // lockfile by same UID
170 aSecurity
.getUserName( myUserName
);
171 OString
myUser(OUStringToOString(myUserName
, RTL_TEXTENCODING_ASCII_US
));
178 void Lockfile::syncToFile() const
180 OUString aLockname
= m_aLockname
;
181 Config
aConfig(aLockname
);
182 aConfig
.SetGroup(LOCKFILE_GROUP
);
185 OString
aHost( impl_getHostname() );
188 aSecurity
.getUserName( aUserName
);
189 OString aUser
= OUStringToOString( aUserName
, RTL_TEXTENCODING_ASCII_US
);
190 OString aTime
= OUStringToOString( m_aDate
, RTL_TEXTENCODING_ASCII_US
);
191 OString aStamp
= OUStringToOString( m_aId
, RTL_TEXTENCODING_ASCII_US
);
194 aConfig
.WriteKey( LOCKFILE_USERKEY
, aUser
);
195 aConfig
.WriteKey( LOCKFILE_HOSTKEY
, aHost
);
196 aConfig
.WriteKey( LOCKFILE_STAMPKEY
, aStamp
);
197 aConfig
.WriteKey( LOCKFILE_TIMEKEY
, aTime
);
200 m_bIPCserver
? OString("true") : OString("false") );
204 Lockfile::~Lockfile()
206 // unlock userdata by removing file
208 File::remove( m_aLockname
);
213 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */