LibreOffice Module desktop (master) 1
lockfile.cxx
Go to the documentation of this file.
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#include <sal/config.h>
21
22#include <memory>
23
24#include <time.h>
25#ifndef _WIN32
26#include <unistd.h>
27#else
28#if !defined WIN32_LEAN_AND_MEAN
29# define WIN32_LEAN_AND_MEAN
30#endif
31#include <windows.h>
32#endif
33#include <comphelper/random.hxx>
34#include <sal/types.h>
35#include <osl/file.hxx>
36#include <osl/security.hxx>
38#include <tools/config.hxx>
39
40#include <lockfile.hxx>
41
42using namespace ::osl;
43using namespace ::utl;
44
45
46static OString impl_getHostname()
47{
48 OString aHost;
49#ifdef _WIN32
50 /*
51 prevent windows from connecting to the net to get its own
52 hostname by using the netbios name
53 */
54 DWORD sz = MAX_COMPUTERNAME_LENGTH + 1;
55 TCHAR szHost[MAX_COMPUTERNAME_LENGTH + 1];
56 if (GetComputerNameA(szHost, &sz))
57 aHost = OString(szHost);
58 else
59 aHost = OString("UNKNOWN");
60#else
61 /* Don't do dns lookup on Linux either */
62 char pHostName[1024];
63
64 if ( gethostname( pHostName, sizeof( pHostName ) - 1 ) == 0 )
65 {
66 pHostName[sizeof( pHostName ) - 1] = '\0';
67 aHost = OString( pHostName );
68 }
69 else
70 aHost = OString("UNKNOWN");
71#endif
72
73 return aHost;
74}
75
76namespace desktop {
77
78 Lockfile::Lockfile( bool bIPCserver )
79 :m_bIPCserver(bIPCserver)
80 ,m_bRemove(false)
81 ,m_bIsLocked(false)
82 {
83 // build the file-url to use for the lock
84 OUString aUserPath;
86 m_aLockname = aUserPath + "/.lock";
87
88 // generate ID
89 const int nIdBytes = 16;
90 char tmpId[nIdBytes*2+1];
91 time_t t = time(nullptr);
92 for (int i = 0; i<nIdBytes; i++) {
93 int tmpByte = comphelper::rng::uniform_int_distribution(0, 0xFF);
94 SAL_WNODEPRECATED_DECLARATIONS_PUSH // sprintf (macOS 13 SDK)
95 sprintf( tmpId+i*2, "%02X", tmpByte );
97 }
98 tmpId[nIdBytes*2]=0x00;
99 m_aId = OUString::createFromAscii( tmpId );
100
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');
106 if (i > 0)
107 m_aDate = m_aDate.copy(0, i);
108 }
109
110
111 // try to create file
112 File aFile(m_aLockname);
113 if (aFile.open( osl_File_OpenFlag_Create ) == File::E_EXIST) {
114 m_bIsLocked = true;
115 } else {
116 // new lock created
117 aFile.close( );
118 syncToFile( );
119 m_bRemove = true;
120 }
121 }
122
123 bool Lockfile::check( fpExecWarning execWarning )
124 {
125
126 if (m_bIsLocked) {
127 // lock existed, ask user what to do
128 if (isStale() ||
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 );
134 aFile.close( );
135 syncToFile( );
136 m_bRemove = true;
137 return true;
138 } else {
139 //leave alone and return false
140 m_bRemove = false;
141 return false;
142 }
143 } else {
144 // lock was created by us
145 return true;
146 }
147 }
148
149 bool Lockfile::isStale() const
150 {
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"))
159 return false;
160
161 OString aHost = aConfig.ReadKey( LOCKFILE_HOSTKEY );
162 OString aUser = aConfig.ReadKey( LOCKFILE_USERKEY );
163
164 // lockfile from same host?
165 OString myHost( impl_getHostname() );
166 if (aHost == myHost) {
167 // lockfile by same UID
168 OUString myUserName;
169 Security aSecurity;
170 aSecurity.getUserName( myUserName );
171 OString myUser(OUStringToOString(myUserName, RTL_TEXTENCODING_ASCII_US));
172 if (aUser == myUser)
173 return true;
174 }
175 return false;
176 }
177
179 {
180 OUString aLockname = m_aLockname;
181 Config aConfig(aLockname);
182 aConfig.SetGroup(LOCKFILE_GROUP);
183
184 // get information
185 OString aHost( impl_getHostname() );
186 OUString aUserName;
187 Security aSecurity;
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 );
192
193 // write information
194 aConfig.WriteKey( LOCKFILE_USERKEY, aUser );
195 aConfig.WriteKey( LOCKFILE_HOSTKEY, aHost );
196 aConfig.WriteKey( LOCKFILE_STAMPKEY, aStamp );
197 aConfig.WriteKey( LOCKFILE_TIMEKEY, aTime );
198 aConfig.WriteKey(
200 m_bIPCserver ? OString("true") : OString("false") );
201 aConfig.Flush( );
202 }
203
205 {
206 // unlock userdata by removing file
207 if ( m_bRemove )
208 File::remove( m_aLockname );
209 }
210}
211
212
213/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
void SetGroup(const OString &rGroup)
void Flush()
OString ReadKey(const OString &rKey) const
void WriteKey(const OString &rKey, const OString &rValue)
OUString m_aLockname
Definition: lockfile.hxx:73
bool check(fpExecWarning execWarning)
Definition: lockfile.cxx:123
Lockfile(bool bIPCserver=true)
Definition: lockfile.cxx:78
OUString m_aId
Definition: lockfile.hxx:78
OUString m_aDate
Definition: lockfile.hxx:79
void syncToFile() const
Definition: lockfile.cxx:178
bool isStale() const
Definition: lockfile.cxx:149
static PathStatus locateUserInstallation(OUString &_rURL)
static OString impl_getHostname()
Definition: lockfile.cxx:46
#define LOCKFILE_GROUP
Definition: lockfile.hxx:41
#define LOCKFILE_STAMPKEY
Definition: lockfile.hxx:44
#define LOCKFILE_HOSTKEY
Definition: lockfile.hxx:43
#define LOCKFILE_TIMEKEY
Definition: lockfile.hxx:45
#define LOCKFILE_USERKEY
Definition: lockfile.hxx:42
#define LOCKFILE_IPCKEY
Definition: lockfile.hxx:46
int uniform_int_distribution(int a, int b)
Definition: app.cxx:167
int i
int sprintf(char(&s)[N], char const *format, T &&... arguments)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
#define SAL_WNODEPRECATED_DECLARATIONS_POP
#define SAL_WNODEPRECATED_DECLARATIONS_PUSH