1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_desktop.hxx" 30 #include <stdlib.h> 31 #include <time.h> 32 #ifdef WNT 33 #include <tools/prewin.h> 34 #include <windows.h> 35 #include <tools/postwin.h> 36 #endif 37 #include <sal/types.h> 38 #include <osl/file.hxx> 39 #include <osl/socket.hxx> 40 #include <osl/security.hxx> 41 #include <unotools/bootstrap.hxx> 42 #include <tools/string.hxx> 43 #include <tools/config.hxx> 44 45 #include "lockfile.hxx" 46 47 48 using namespace ::osl; 49 using namespace ::rtl; 50 using namespace ::utl; 51 52 53 namespace desktop { 54 55 // initialize static members... 56 // lock suffix 57 const OUString Lockfile::Suffix() 58 { return OUString::createFromAscii( "/.lock" ); } 59 // values for datafile 60 const ByteString Lockfile::Group() 61 { return ByteString( "Lockdata" ); } 62 const ByteString Lockfile::Userkey() 63 { return ByteString( "User" ); } 64 const ByteString Lockfile::Hostkey() 65 { return ByteString( "Host" ); } 66 const ByteString Lockfile::Stampkey() 67 { return ByteString( "Stamp" ); } 68 const ByteString Lockfile::Timekey() 69 { return ByteString( "Time" ); } 70 const ByteString Lockfile::IPCkey() 71 { return ByteString( "IPCServer" ); } 72 73 Lockfile::Lockfile( bool bIPCserver ) 74 :m_bIPCserver(bIPCserver) 75 ,m_bRemove(sal_False) 76 ,m_bIsLocked(sal_False) 77 { 78 // build the file-url to use for the lock 79 OUString aUserPath; 80 utl::Bootstrap::locateUserInstallation( aUserPath ); 81 m_aLockname = aUserPath + Suffix(); 82 83 // generate ID 84 const int nIdBytes = 16; 85 char tmpId[nIdBytes*2+1]; 86 time_t t; 87 srand( (unsigned)(t = time( NULL )) ); 88 int tmpByte = 0; 89 for (int i = 0; i<nIdBytes; i++) { 90 tmpByte = rand( ) % 0xFF; 91 sprintf( tmpId+i*2, "%02X", tmpByte ); // #100211# - checked 92 } 93 tmpId[nIdBytes*2]=0x00; 94 m_aId = OUString::createFromAscii( tmpId ); 95 96 // generate date string 97 char *tmpTime = ctime( &t ); 98 if (tmpTime != NULL) { 99 m_aDate = OUString::createFromAscii( tmpTime ); 100 sal_Int32 i = m_aDate.indexOf('\n'); 101 if (i > 0) 102 m_aDate = m_aDate.copy(0, i); 103 } 104 105 106 // try to create file 107 File aFile(m_aLockname); 108 if (aFile.open( OpenFlag_Create ) == File::E_EXIST) { 109 m_bIsLocked = sal_True; 110 } else { 111 // new lock created 112 aFile.close( ); 113 syncToFile( ); 114 m_bRemove = sal_True; 115 } 116 } 117 118 sal_Bool Lockfile::check( fpExecWarning execWarning ) 119 { 120 121 if (m_bIsLocked) { 122 // lock existed, ask user what to do 123 if (isStale() || 124 (execWarning != 0 && (*execWarning)( this ))) { 125 // remove file and create new 126 File::remove( m_aLockname ); 127 File aFile(m_aLockname); 128 aFile.open( OpenFlag_Create ); 129 aFile.close( ); 130 syncToFile( ); 131 m_bRemove = sal_True; 132 return sal_True; 133 } else { 134 //leave alone and return false 135 m_bRemove = sal_False; 136 return sal_False; 137 } 138 } else { 139 // lock was created by us 140 return sal_True; 141 } 142 } 143 144 sal_Bool Lockfile::isStale( void ) const 145 { 146 // this checks whether the lockfile was created on the same 147 // host by the same user. Should this be the case it is safe 148 // to assume that it is a stale lockfile which can be overwritten 149 String aLockname = m_aLockname; 150 Config aConfig(aLockname); 151 aConfig.SetGroup(Group()); 152 ByteString aIPCserver = aConfig.ReadKey( IPCkey() ); 153 if (! aIPCserver.EqualsIgnoreCaseAscii( "true" )) 154 return false; 155 156 ByteString aHost = aConfig.ReadKey( Hostkey() ); 157 ByteString aUser = aConfig.ReadKey( Userkey() ); 158 // lockfile from same host? 159 ByteString myHost; 160 #ifdef WNT 161 /* 162 prevent windows from connecting to the net to get it's own 163 hostname by using the netbios name 164 */ 165 sal_Int32 sz = MAX_COMPUTERNAME_LENGTH + 1; 166 char* szHost = new char[sz]; 167 if (GetComputerName(szHost, (LPDWORD)&sz)) 168 myHost = OString(szHost); 169 else 170 myHost = OString("UNKNOWN"); 171 delete[] szHost; 172 #else 173 oslSocketResult sRes; 174 myHost = OUStringToOString( 175 SocketAddr::getLocalHostname( &sRes ), RTL_TEXTENCODING_ASCII_US ); 176 #endif 177 if (aHost == myHost) { 178 // lockfile by same UID 179 OUString myUserName; 180 Security aSecurity; 181 aSecurity.getUserName( myUserName ); 182 ByteString myUser = OUStringToOString( myUserName, RTL_TEXTENCODING_ASCII_US ); 183 if (aUser == myUser) 184 return sal_True; 185 } 186 return sal_False; 187 } 188 189 void Lockfile::syncToFile( void ) const 190 { 191 String aLockname = m_aLockname; 192 Config aConfig(aLockname); 193 aConfig.SetGroup(Group()); 194 195 // get information 196 ByteString aHost; 197 #ifdef WNT 198 /* 199 prevent windows from connecting to the net to get it's own 200 hostname by using the netbios name 201 */ 202 sal_Int32 sz = MAX_COMPUTERNAME_LENGTH + 1; 203 char* szHost = new char[sz]; 204 if (GetComputerName(szHost, (LPDWORD)&sz)) 205 aHost = OString(szHost); 206 else 207 aHost = OString("UNKNOWN"); 208 delete[] szHost; 209 #else 210 oslSocketResult sRes; 211 aHost = OUStringToOString( 212 SocketAddr::getLocalHostname( &sRes ), RTL_TEXTENCODING_ASCII_US ); 213 #endif 214 OUString aUserName; 215 Security aSecurity; 216 aSecurity.getUserName( aUserName ); 217 ByteString aUser = OUStringToOString( aUserName, RTL_TEXTENCODING_ASCII_US ); 218 ByteString aTime = OUStringToOString( m_aDate, RTL_TEXTENCODING_ASCII_US ); 219 ByteString aStamp = OUStringToOString( m_aId, RTL_TEXTENCODING_ASCII_US ); 220 221 // write information 222 aConfig.WriteKey( Userkey(), aUser ); 223 aConfig.WriteKey( Hostkey(), aHost ); 224 aConfig.WriteKey( Stampkey(), aStamp ); 225 aConfig.WriteKey( Timekey(), aTime ); 226 aConfig.WriteKey( 227 IPCkey(), 228 m_bIPCserver ? ByteString("true") : ByteString("false") ); 229 aConfig.Flush( ); 230 } 231 232 void Lockfile::clean( void ) 233 { 234 if ( m_bRemove ) 235 { 236 File::remove( m_aLockname ); 237 m_bRemove = sal_False; 238 } 239 } 240 241 Lockfile::~Lockfile( void ) 242 { 243 // unlock userdata by removing file 244 if ( m_bRemove ) 245 File::remove( m_aLockname ); 246 } 247 } 248 249 250 251 252 253 254 255 256 257