/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #ifndef _WIN32 #include #else #if !defined WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN #endif #include #endif #include #include #include #include #include #include #include using namespace ::osl; using namespace ::utl; static OString impl_getHostname() { OString aHost; #ifdef _WIN32 /* prevent windows from connecting to the net to get its own hostname by using the netbios name */ DWORD sz = MAX_COMPUTERNAME_LENGTH + 1; TCHAR szHost[MAX_COMPUTERNAME_LENGTH + 1]; if (GetComputerNameA(szHost, &sz)) aHost = OString(szHost); else aHost = OString("UNKNOWN"); #else /* Don't do dns lookup on Linux either */ char pHostName[1024]; if ( gethostname( pHostName, sizeof( pHostName ) - 1 ) == 0 ) { pHostName[sizeof( pHostName ) - 1] = '\0'; aHost = OString( pHostName ); } else aHost = "UNKNOWN"_ostr; #endif return aHost; } namespace desktop { Lockfile::Lockfile( bool bIPCserver ) :m_bIPCserver(bIPCserver) ,m_bRemove(false) ,m_bIsLocked(false) { // build the file-url to use for the lock OUString aUserPath; utl::Bootstrap::locateUserInstallation( aUserPath ); m_aLockname = aUserPath + "/.lock"; // generate ID const int nIdBytes = 16; char tmpId[nIdBytes*2+1]; time_t t = time(nullptr); for (int i = 0; i 0) m_aDate = m_aDate.copy(0, i); } // try to create file File aFile(m_aLockname); if (aFile.open( osl_File_OpenFlag_Create ) == File::E_EXIST) { m_bIsLocked = true; } else { // new lock created aFile.close( ); syncToFile( ); m_bRemove = true; } } bool Lockfile::check( fpExecWarning execWarning ) { if (m_bIsLocked) { // lock existed, ask user what to do if (isStale() || (execWarning != nullptr && (*execWarning)( this ))) { // remove file and create new File::remove( m_aLockname ); File aFile(m_aLockname); (void)aFile.open( osl_File_OpenFlag_Create ); aFile.close( ); syncToFile( ); m_bRemove = true; return true; } else { //leave alone and return false m_bRemove = false; return false; } } else { // lock was created by us return true; } } bool Lockfile::isStale() const { // this checks whether the lockfile was created on the same // host by the same user. Should this be the case it is safe // to assume that it is a stale lockfile which can be overwritten OUString aLockname = m_aLockname; Config aConfig(aLockname); aConfig.SetGroup(LOCKFILE_GROUP ""_ostr); OString aIPCserver = aConfig.ReadKey( LOCKFILE_IPCKEY ""_ostr ); if (!aIPCserver.equalsIgnoreAsciiCase("true")) return false; OString aHost = aConfig.ReadKey( LOCKFILE_HOSTKEY ""_ostr ); OString aUser = aConfig.ReadKey( LOCKFILE_USERKEY ""_ostr ); // lockfile from same host? OString myHost( impl_getHostname() ); if (aHost == myHost) { // lockfile by same UID OUString myUserName; Security aSecurity; aSecurity.getUserName( myUserName ); OString myUser(OUStringToOString(myUserName, RTL_TEXTENCODING_ASCII_US)); if (aUser == myUser) return true; } return false; } void Lockfile::syncToFile() const { OUString aLockname = m_aLockname; Config aConfig(aLockname); aConfig.SetGroup(LOCKFILE_GROUP ""_ostr); // get information OString aHost( impl_getHostname() ); OUString aUserName; Security aSecurity; aSecurity.getUserName( aUserName ); OString aUser = OUStringToOString( aUserName, RTL_TEXTENCODING_ASCII_US ); OString aTime = OUStringToOString( m_aDate, RTL_TEXTENCODING_ASCII_US ); OString aStamp = OUStringToOString( m_aId, RTL_TEXTENCODING_ASCII_US ); // write information aConfig.WriteKey( LOCKFILE_USERKEY ""_ostr, aUser ); aConfig.WriteKey( LOCKFILE_HOSTKEY ""_ostr, aHost ); aConfig.WriteKey( LOCKFILE_STAMPKEY ""_ostr, aStamp ); aConfig.WriteKey( LOCKFILE_TIMEKEY ""_ostr, aTime ); aConfig.WriteKey( LOCKFILE_IPCKEY ""_ostr, m_bIPCserver ? "true"_ostr : "false"_ostr ); aConfig.Flush( ); } Lockfile::~Lockfile() { // unlock userdata by removing file if ( m_bRemove ) File::remove( m_aLockname ); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */