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