| /************************************************************** |
| * |
| * 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 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_desktop.hxx" |
| #include <stdlib.h> |
| #include <time.h> |
| #ifdef WNT |
| #include <tools/prewin.h> |
| #include <windows.h> |
| #include <tools/postwin.h> |
| #endif |
| #include <sal/types.h> |
| #include <osl/file.hxx> |
| #include <osl/socket.hxx> |
| #include <osl/security.hxx> |
| #include <unotools/bootstrap.hxx> |
| #include <tools/string.hxx> |
| #include <tools/config.hxx> |
| |
| #include "lockfile.hxx" |
| |
| |
| using namespace ::osl; |
| using namespace ::rtl; |
| using namespace ::utl; |
| |
| |
| namespace desktop { |
| |
| // initialize static members... |
| // lock suffix |
| const OUString Lockfile::Suffix() |
| { return OUString::createFromAscii( "/.lock" ); } |
| // values for datafile |
| const ByteString Lockfile::Group() |
| { return ByteString( "Lockdata" ); } |
| const ByteString Lockfile::Userkey() |
| { return ByteString( "User" ); } |
| const ByteString Lockfile::Hostkey() |
| { return ByteString( "Host" ); } |
| const ByteString Lockfile::Stampkey() |
| { return ByteString( "Stamp" ); } |
| const ByteString Lockfile::Timekey() |
| { return ByteString( "Time" ); } |
| const ByteString Lockfile::IPCkey() |
| { return ByteString( "IPCServer" ); } |
| |
| Lockfile::Lockfile( bool bIPCserver ) |
| :m_bIPCserver(bIPCserver) |
| ,m_bRemove(sal_False) |
| ,m_bIsLocked(sal_False) |
| { |
| // build the file-url to use for the lock |
| OUString aUserPath; |
| utl::Bootstrap::locateUserInstallation( aUserPath ); |
| m_aLockname = aUserPath + Suffix(); |
| |
| // generate ID |
| const int nIdBytes = 16; |
| char tmpId[nIdBytes*2+1]; |
| time_t t; |
| srand( (unsigned)(t = time( NULL )) ); |
| int tmpByte = 0; |
| for (int i = 0; i<nIdBytes; i++) { |
| tmpByte = rand( ) % 0xFF; |
| sprintf( tmpId+i*2, "%02X", tmpByte ); // #100211# - checked |
| } |
| tmpId[nIdBytes*2]=0x00; |
| m_aId = OUString::createFromAscii( tmpId ); |
| |
| // generate date string |
| char *tmpTime = ctime( &t ); |
| if (tmpTime != NULL) { |
| m_aDate = OUString::createFromAscii( tmpTime ); |
| sal_Int32 i = m_aDate.indexOf('\n'); |
| if (i > 0) |
| m_aDate = m_aDate.copy(0, i); |
| } |
| |
| |
| // try to create file |
| File aFile(m_aLockname); |
| if (aFile.open( OpenFlag_Create ) == File::E_EXIST) { |
| m_bIsLocked = sal_True; |
| } else { |
| // new lock created |
| aFile.close( ); |
| syncToFile( ); |
| m_bRemove = sal_True; |
| } |
| } |
| |
| sal_Bool Lockfile::check( fpExecWarning execWarning ) |
| { |
| |
| if (m_bIsLocked) { |
| // lock existed, ask user what to do |
| if (isStale() || |
| (execWarning != 0 && (*execWarning)( this ))) { |
| // remove file and create new |
| File::remove( m_aLockname ); |
| File aFile(m_aLockname); |
| aFile.open( OpenFlag_Create ); |
| aFile.close( ); |
| syncToFile( ); |
| m_bRemove = sal_True; |
| return sal_True; |
| } else { |
| //leave alone and return false |
| m_bRemove = sal_False; |
| return sal_False; |
| } |
| } else { |
| // lock was created by us |
| return sal_True; |
| } |
| } |
| |
| sal_Bool Lockfile::isStale( void ) 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 |
| String aLockname = m_aLockname; |
| Config aConfig(aLockname); |
| aConfig.SetGroup(Group()); |
| ByteString aIPCserver = aConfig.ReadKey( IPCkey() ); |
| if (! aIPCserver.EqualsIgnoreCaseAscii( "true" )) |
| return false; |
| |
| ByteString aHost = aConfig.ReadKey( Hostkey() ); |
| ByteString aUser = aConfig.ReadKey( Userkey() ); |
| // lockfile from same host? |
| ByteString myHost; |
| #ifdef WNT |
| /* |
| prevent windows from connecting to the net to get it's own |
| hostname by using the netbios name |
| */ |
| sal_Int32 sz = MAX_COMPUTERNAME_LENGTH + 1; |
| char* szHost = new char[sz]; |
| if (GetComputerName(szHost, (LPDWORD)&sz)) |
| myHost = OString(szHost); |
| else |
| myHost = OString("UNKNOWN"); |
| delete[] szHost; |
| #else |
| oslSocketResult sRes; |
| myHost = OUStringToOString( |
| SocketAddr::getLocalHostname( &sRes ), RTL_TEXTENCODING_ASCII_US ); |
| #endif |
| if (aHost == myHost) { |
| // lockfile by same UID |
| OUString myUserName; |
| Security aSecurity; |
| aSecurity.getUserName( myUserName ); |
| ByteString myUser = OUStringToOString( myUserName, RTL_TEXTENCODING_ASCII_US ); |
| if (aUser == myUser) |
| return sal_True; |
| } |
| return sal_False; |
| } |
| |
| void Lockfile::syncToFile( void ) const |
| { |
| String aLockname = m_aLockname; |
| Config aConfig(aLockname); |
| aConfig.SetGroup(Group()); |
| |
| // get information |
| ByteString aHost; |
| #ifdef WNT |
| /* |
| prevent windows from connecting to the net to get it's own |
| hostname by using the netbios name |
| */ |
| sal_Int32 sz = MAX_COMPUTERNAME_LENGTH + 1; |
| char* szHost = new char[sz]; |
| if (GetComputerName(szHost, (LPDWORD)&sz)) |
| aHost = OString(szHost); |
| else |
| aHost = OString("UNKNOWN"); |
| delete[] szHost; |
| #else |
| oslSocketResult sRes; |
| aHost = OUStringToOString( |
| SocketAddr::getLocalHostname( &sRes ), RTL_TEXTENCODING_ASCII_US ); |
| #endif |
| OUString aUserName; |
| Security aSecurity; |
| aSecurity.getUserName( aUserName ); |
| ByteString aUser = OUStringToOString( aUserName, RTL_TEXTENCODING_ASCII_US ); |
| ByteString aTime = OUStringToOString( m_aDate, RTL_TEXTENCODING_ASCII_US ); |
| ByteString aStamp = OUStringToOString( m_aId, RTL_TEXTENCODING_ASCII_US ); |
| |
| // write information |
| aConfig.WriteKey( Userkey(), aUser ); |
| aConfig.WriteKey( Hostkey(), aHost ); |
| aConfig.WriteKey( Stampkey(), aStamp ); |
| aConfig.WriteKey( Timekey(), aTime ); |
| aConfig.WriteKey( |
| IPCkey(), |
| m_bIPCserver ? ByteString("true") : ByteString("false") ); |
| aConfig.Flush( ); |
| } |
| |
| void Lockfile::clean( void ) |
| { |
| if ( m_bRemove ) |
| { |
| File::remove( m_aLockname ); |
| m_bRemove = sal_False; |
| } |
| } |
| |
| Lockfile::~Lockfile( void ) |
| { |
| // unlock userdata by removing file |
| if ( m_bRemove ) |
| File::remove( m_aLockname ); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |