1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_svtools.hxx"
37 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
38 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
39 #include <com/sun/star/ucb/InsertCommandArgument.hpp>
40 #include <com/sun/star/ucb/NameClashException.hpp>
41 #include <com/sun/star/io/WrongFormatException.hpp>
44 #include <osl/security.hxx>
45 #include <osl/socket.hxx>
46 #include <osl/file.hxx>
48 #include <rtl/string.hxx>
49 #include <rtl/ustring.hxx>
50 #include <rtl/strbuf.hxx>
51 #include <rtl/ustrbuf.hxx>
53 #include <comphelper/processfactory.hxx>
55 #include <tools/urlobj.hxx>
56 #include <unotools/bootstrap.hxx>
58 #include <ucbhelper/content.hxx>
60 #include <svtools/useroptions.hxx>
62 #include <svtools/lockfilecommon.hxx>
64 using namespace ::com::sun::star
;
68 // ----------------------------------------------------------------------
69 LockFileCommon::LockFileCommon( const ::rtl::OUString
& aOrigURL
, const uno::Reference
< lang::XMultiServiceFactory
>& xFactory
, const ::rtl::OUString
& aPrefix
)
70 : m_xFactory( xFactory
)
72 if ( !m_xFactory
.is() )
73 m_xFactory
= ::comphelper::getProcessServiceFactory();
75 INetURLObject aDocURL
= ResolveLinks( INetURLObject( aOrigURL
) );
77 ::rtl::OUString aShareURLString
= aDocURL
.GetPartBeforeLastName();
78 aShareURLString
+= aPrefix
;
79 aShareURLString
+= aDocURL
.GetName();
80 aShareURLString
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "#" ) );
81 m_aURL
= INetURLObject( aShareURLString
).GetMainURL( INetURLObject::NO_DECODE
);
84 // ----------------------------------------------------------------------
85 LockFileCommon::~LockFileCommon()
89 // ----------------------------------------------------------------------
90 INetURLObject
LockFileCommon::ResolveLinks( const INetURLObject
& aDocURL
)
92 if ( aDocURL
.HasError() )
93 throw lang::IllegalArgumentException();
95 ::rtl::OUString aURLToCheck
= aDocURL
.GetMainURL( INetURLObject::NO_DECODE
);
97 sal_Bool bNeedsChecking
= sal_True
;
98 sal_Int32 nMaxLinkCount
= 128;
101 while( bNeedsChecking
)
103 bNeedsChecking
= sal_False
;
105 // do not allow too deep links
106 if ( nCount
++ >= nMaxLinkCount
)
107 throw io::IOException();
109 // there is currently no UCB functionality to resolve the symbolic links;
110 // since the lock files are used only for local file systems the osl functionality is used directly
112 ::osl::FileStatus
aStatus( FileStatusMask_Type
| FileStatusMask_LinkTargetURL
);
113 ::osl::DirectoryItem aItem
;
114 if ( ::osl::FileBase::E_None
== ::osl::DirectoryItem::get( aURLToCheck
, aItem
)
115 && aItem
.is() && ::osl::FileBase::E_None
== aItem
.getFileStatus( aStatus
) )
117 if ( aStatus
.isValid( FileStatusMask_Type
)
118 && aStatus
.isValid( FileStatusMask_LinkTargetURL
)
119 && aStatus
.getFileType() == ::osl::FileStatus::Link
)
121 aURLToCheck
= aStatus
.getLinkTargetURL();
122 bNeedsChecking
= sal_True
;
127 return INetURLObject( aURLToCheck
);
130 // ----------------------------------------------------------------------
131 uno::Sequence
< uno::Sequence
< ::rtl::OUString
> > LockFileCommon::ParseList( const uno::Sequence
< sal_Int8
>& aBuffer
)
133 sal_Int32 nCurPos
= 0;
134 sal_Int32 nCurEntry
= 0;
135 uno::Sequence
< uno::Sequence
< ::rtl::OUString
> > aResult( 10 );
137 while ( nCurPos
< aBuffer
.getLength() )
139 if ( nCurEntry
>= aResult
.getLength() )
140 aResult
.realloc( nCurEntry
+ 10 );
141 aResult
[nCurEntry
] = ParseEntry( aBuffer
, nCurPos
);
145 aResult
.realloc( nCurEntry
);
149 // ----------------------------------------------------------------------
150 uno::Sequence
< ::rtl::OUString
> LockFileCommon::ParseEntry( const uno::Sequence
< sal_Int8
>& aBuffer
, sal_Int32
& io_nCurPos
)
152 uno::Sequence
< ::rtl::OUString
> aResult( LOCKFILE_ENTRYSIZE
);
154 for ( int nInd
= 0; nInd
< LOCKFILE_ENTRYSIZE
; nInd
++ )
156 aResult
[nInd
] = ParseName( aBuffer
, io_nCurPos
);
157 if ( io_nCurPos
>= aBuffer
.getLength()
158 || ( nInd
< LOCKFILE_ENTRYSIZE
- 1 && aBuffer
[io_nCurPos
++] != ',' )
159 || ( nInd
== LOCKFILE_ENTRYSIZE
- 1 && aBuffer
[io_nCurPos
++] != ';' ) )
160 throw io::WrongFormatException();
166 // ----------------------------------------------------------------------
167 ::rtl::OUString
LockFileCommon::ParseName( const uno::Sequence
< sal_Int8
>& aBuffer
, sal_Int32
& io_nCurPos
)
169 ::rtl::OStringBuffer aResult
;
170 sal_Bool bHaveName
= sal_False
;
171 sal_Bool bEscape
= sal_False
;
175 if ( io_nCurPos
>= aBuffer
.getLength() )
176 throw io::WrongFormatException();
180 if ( aBuffer
[io_nCurPos
] == ',' || aBuffer
[io_nCurPos
] == ';' || aBuffer
[io_nCurPos
] == '\\' )
181 aResult
.append( (sal_Char
)aBuffer
[io_nCurPos
] );
183 throw io::WrongFormatException();
188 else if ( aBuffer
[io_nCurPos
] == ',' || aBuffer
[io_nCurPos
] == ';' )
189 bHaveName
= sal_True
;
192 if ( aBuffer
[io_nCurPos
] == '\\' )
195 aResult
.append( (sal_Char
)aBuffer
[io_nCurPos
] );
201 return ::rtl::OStringToOUString( aResult
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
);
204 // ----------------------------------------------------------------------
205 ::rtl::OUString
LockFileCommon::EscapeCharacters( const ::rtl::OUString
& aSource
)
207 ::rtl::OUStringBuffer aBuffer
;
208 const sal_Unicode
* pStr
= aSource
.getStr();
209 for ( sal_Int32 nInd
= 0; nInd
< aSource
.getLength() && pStr
[nInd
] != 0; nInd
++ )
211 if ( pStr
[nInd
] == '\\' || pStr
[nInd
] == ';' || pStr
[nInd
] == ',' )
212 aBuffer
.append( (sal_Unicode
)'\\' );
213 aBuffer
.append( pStr
[nInd
] );
216 return aBuffer
.makeStringAndClear();
219 // ----------------------------------------------------------------------
220 ::rtl::OUString
LockFileCommon::GetOOOUserName()
222 SvtUserOptions aUserOpt
;
223 ::rtl::OUString aName
= aUserOpt
.GetFirstName();
224 if ( aName
.getLength() )
225 aName
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ) );
226 aName
+= aUserOpt
.GetLastName();
231 // ----------------------------------------------------------------------
232 ::rtl::OUString
LockFileCommon::GetCurrentLocalTime()
234 ::rtl::OUString aTime
;
237 if ( osl_getSystemTime( &aSysTime
) )
240 if ( osl_getLocalTimeFromSystemTime( &aSysTime
, &aLocTime
) )
242 oslDateTime aDateTime
;
243 if ( osl_getDateTimeFromTimeValue( &aLocTime
, &aDateTime
) )
246 sprintf( pDateTime
, "%02d.%02d.%4d %02d:%02d", aDateTime
.Day
, aDateTime
.Month
, aDateTime
.Year
, aDateTime
.Hours
, aDateTime
.Minutes
);
247 aTime
= ::rtl::OUString::createFromAscii( pDateTime
);
255 // ----------------------------------------------------------------------
256 uno::Sequence
< ::rtl::OUString
> LockFileCommon::GenerateOwnEntry()
258 uno::Sequence
< ::rtl::OUString
> aResult( LOCKFILE_ENTRYSIZE
);
260 aResult
[LOCKFILE_OOOUSERNAME_ID
] = GetOOOUserName();
262 ::osl::Security aSecurity
;
263 aSecurity
.getUserName( aResult
[LOCKFILE_SYSUSERNAME_ID
] );
265 aResult
[LOCKFILE_LOCALHOST_ID
] = ::osl::SocketAddr::getLocalHostname();
267 aResult
[LOCKFILE_EDITTIME_ID
] = GetCurrentLocalTime();
269 ::utl::Bootstrap::locateUserInstallation( aResult
[LOCKFILE_USERURL_ID
] );