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