xref: /aoo42x/main/sal/osl/unx/file_misc.cxx (revision fc633f11)
187d2adbcSAndrew Rist /**************************************************************
2*fc633f11Smseidel  *
387d2adbcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
487d2adbcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
587d2adbcSAndrew Rist  * distributed with this work for additional information
687d2adbcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
787d2adbcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
887d2adbcSAndrew Rist  * "License"); you may not use this file except in compliance
987d2adbcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*fc633f11Smseidel  *
1187d2adbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*fc633f11Smseidel  *
1387d2adbcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
1487d2adbcSAndrew Rist  * software distributed under the License is distributed on an
1587d2adbcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1687d2adbcSAndrew Rist  * KIND, either express or implied.  See the License for the
1787d2adbcSAndrew Rist  * specific language governing permissions and limitations
1887d2adbcSAndrew Rist  * under the License.
19*fc633f11Smseidel  *
2087d2adbcSAndrew Rist  *************************************************************/
2187d2adbcSAndrew Rist 
2287d2adbcSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "osl/file.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include "osl/diagnose.h"
27cdf0e10cSrcweir #include "osl/thread.h"
28cdf0e10cSrcweir #include <osl/signal.h>
29cdf0e10cSrcweir #include "rtl/alloc.h"
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "system.h"
32cdf0e10cSrcweir #include "file_impl.hxx"
33cdf0e10cSrcweir #include "file_error_transl.h"
34cdf0e10cSrcweir #include "file_path_helper.hxx"
35cdf0e10cSrcweir #include "file_url.h"
36cdf0e10cSrcweir #include "uunxapi.hxx"
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #include <sys/types.h>
39cdf0e10cSrcweir #include <errno.h>
40cdf0e10cSrcweir #include <dirent.h>
41cdf0e10cSrcweir #include <limits.h>
42cdf0e10cSrcweir #include <stdio.h>
43cdf0e10cSrcweir #include <string.h>
44cdf0e10cSrcweir #include <unistd.h>
45cdf0e10cSrcweir #include <sys/stat.h>
46cdf0e10cSrcweir #include <sys/mman.h>
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #include <algorithm>
49cdf0e10cSrcweir 
50cdf0e10cSrcweir /************************************************************************
51cdf0e10cSrcweir  *   ToDo
52cdf0e10cSrcweir  *
53cdf0e10cSrcweir  *   - Fix: check for corresponding struct sizes in exported functions
54cdf0e10cSrcweir  *   - check size/use of oslDirectory
55cdf0e10cSrcweir  *   - check size/use of oslDirectoryItem
56cdf0e10cSrcweir  ***********************************************************************/
57cdf0e10cSrcweir /******************************************************************************
58*fc633f11Smseidel  * Data Type Definition
59cdf0e10cSrcweir  ******************************************************************************/
60cdf0e10cSrcweir 
61cdf0e10cSrcweir typedef struct
62cdf0e10cSrcweir {
63*fc633f11Smseidel 	rtl_uString* ustrPath; /* holds native directory path */
64*fc633f11Smseidel 	DIR*         pDirStruct;
65cdf0e10cSrcweir } oslDirectoryImpl;
66cdf0e10cSrcweir 
67cdf0e10cSrcweir #if 0
68cdf0e10cSrcweir /* FIXME: reintroducing this may save some extra bytes per Item */
69cdf0e10cSrcweir typedef struct
70cdf0e10cSrcweir {
71*fc633f11Smseidel 	rtl_uString* ustrFileName; /* holds native file name */
72*fc633f11Smseidel 	rtl_uString* ustrDirPath; /* holds native dir path */
73*fc633f11Smseidel 	sal_uInt32   RefCount;
74cdf0e10cSrcweir } oslDirectoryItemImpl;
75cdf0e10cSrcweir #endif
76cdf0e10cSrcweir 
DirectoryItem_Impl(rtl_uString * ustrFilePath,unsigned char DType)77cdf0e10cSrcweir DirectoryItem_Impl::DirectoryItem_Impl(
78cdf0e10cSrcweir 	rtl_uString * ustrFilePath, unsigned char DType)
79cdf0e10cSrcweir 	: m_RefCount     (1),
80cdf0e10cSrcweir 	  m_ustrFilePath (ustrFilePath),
81cdf0e10cSrcweir 	  m_DType        (DType)
82cdf0e10cSrcweir {
83cdf0e10cSrcweir 	if (m_ustrFilePath != 0)
84cdf0e10cSrcweir 		rtl_uString_acquire(m_ustrFilePath);
85cdf0e10cSrcweir }
~DirectoryItem_Impl()86cdf0e10cSrcweir DirectoryItem_Impl::~DirectoryItem_Impl()
87cdf0e10cSrcweir {
88cdf0e10cSrcweir 	if (m_ustrFilePath != 0)
89cdf0e10cSrcweir 		rtl_uString_release(m_ustrFilePath);
90cdf0e10cSrcweir }
91cdf0e10cSrcweir 
operator new(size_t n)92cdf0e10cSrcweir void * DirectoryItem_Impl::operator new(size_t n)
93cdf0e10cSrcweir {
94cdf0e10cSrcweir 	return rtl_allocateMemory(n);
95cdf0e10cSrcweir }
operator delete(void * p,size_t)96cdf0e10cSrcweir void DirectoryItem_Impl::operator delete(void * p, size_t)
97cdf0e10cSrcweir {
98cdf0e10cSrcweir 	rtl_freeMemory(p);
99cdf0e10cSrcweir }
100cdf0e10cSrcweir 
acquire()101cdf0e10cSrcweir void DirectoryItem_Impl::acquire()
102cdf0e10cSrcweir {
103cdf0e10cSrcweir 	++m_RefCount;
104cdf0e10cSrcweir }
release()105cdf0e10cSrcweir void DirectoryItem_Impl::release()
106cdf0e10cSrcweir {
107cdf0e10cSrcweir 	if (0 == --m_RefCount)
108cdf0e10cSrcweir 		delete this;
109cdf0e10cSrcweir }
110cdf0e10cSrcweir 
getFileType() const111cdf0e10cSrcweir oslFileType DirectoryItem_Impl::getFileType() const
112cdf0e10cSrcweir {
113cdf0e10cSrcweir 	switch (m_DType)
114cdf0e10cSrcweir 	{
115cdf0e10cSrcweir #ifdef _DIRENT_HAVE_D_TYPE
116cdf0e10cSrcweir 		case DT_LNK:
117cdf0e10cSrcweir 			return osl_File_Type_Link;
118cdf0e10cSrcweir 		case DT_DIR:
119cdf0e10cSrcweir 			return osl_File_Type_Directory;
120cdf0e10cSrcweir 		case DT_REG:
121cdf0e10cSrcweir 			return osl_File_Type_Regular;
122cdf0e10cSrcweir 		case DT_FIFO:
123cdf0e10cSrcweir 			return osl_File_Type_Fifo;
124cdf0e10cSrcweir 		case DT_SOCK:
125cdf0e10cSrcweir 			return osl_File_Type_Socket;
126cdf0e10cSrcweir 		case DT_CHR:
127cdf0e10cSrcweir 		case DT_BLK:
128cdf0e10cSrcweir 			return osl_File_Type_Special;
129cdf0e10cSrcweir #endif /* _DIRENT_HAVE_D_TYPE */
130cdf0e10cSrcweir 		default:
131cdf0e10cSrcweir 			break;
132cdf0e10cSrcweir 	}
133cdf0e10cSrcweir 	return osl_File_Type_Unknown;
134cdf0e10cSrcweir }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir /******************************************************************************
137*fc633f11Smseidel  * C-String Function Declarations
138cdf0e10cSrcweir  *****************************************************************************/
139cdf0e10cSrcweir 
140cdf0e10cSrcweir static oslFileError osl_psz_createDirectory(const sal_Char* pszPath);
141cdf0e10cSrcweir static oslFileError osl_psz_removeDirectory(const sal_Char* pszPath);
142cdf0e10cSrcweir 
143cdf0e10cSrcweir /*******************************************************************
144*fc633f11Smseidel  * osl_openDirectory
145cdf0e10cSrcweir  ******************************************************************/
146cdf0e10cSrcweir 
osl_openDirectory(rtl_uString * ustrDirectoryURL,oslDirectory * pDirectory)147cdf0e10cSrcweir oslFileError SAL_CALL osl_openDirectory(rtl_uString* ustrDirectoryURL, oslDirectory* pDirectory)
148cdf0e10cSrcweir {
149*fc633f11Smseidel 	rtl_uString* ustrSystemPath = NULL;
150*fc633f11Smseidel 	oslFileError eRet;
151cdf0e10cSrcweir 
152*fc633f11Smseidel 	char path[PATH_MAX];
153cdf0e10cSrcweir 
154*fc633f11Smseidel 	if ((0 == ustrDirectoryURL) || (0 == ustrDirectoryURL->length) || (0 == pDirectory))
155*fc633f11Smseidel 		return osl_File_E_INVAL;
156cdf0e10cSrcweir 
157*fc633f11Smseidel 	/* convert file URL to system path */
158*fc633f11Smseidel 	eRet = osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL, &ustrSystemPath, sal_False);
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 	if( osl_File_E_None != eRet )
161*fc633f11Smseidel 		return eRet;
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 	osl_systemPathRemoveSeparator(ustrSystemPath);
164cdf0e10cSrcweir 
165*fc633f11Smseidel 	/* convert unicode path to text */
166*fc633f11Smseidel 	if ( UnicodeToText( path, PATH_MAX, ustrSystemPath->buffer, ustrSystemPath->length )
167*fc633f11Smseidel #ifdef MACOSX
168*fc633f11Smseidel 	 && macxp_resolveAlias( path, PATH_MAX ) == 0
169cdf0e10cSrcweir #endif /* MACOSX */
170cdf0e10cSrcweir 	 )
171*fc633f11Smseidel 	{
172*fc633f11Smseidel 		/* open directory */
173*fc633f11Smseidel 		DIR *pdir = opendir( path );
174*fc633f11Smseidel 
175*fc633f11Smseidel 		if( pdir )
176*fc633f11Smseidel 		{
177*fc633f11Smseidel 			/* create and initialize impl structure */
178*fc633f11Smseidel 			oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*) rtl_allocateMemory( sizeof(oslDirectoryImpl) );
179*fc633f11Smseidel 
180*fc633f11Smseidel 			if( pDirImpl )
181*fc633f11Smseidel 			{
182*fc633f11Smseidel 				pDirImpl->pDirStruct = pdir;
183*fc633f11Smseidel 				pDirImpl->ustrPath = ustrSystemPath;
184*fc633f11Smseidel 
185*fc633f11Smseidel 				*pDirectory = (oslDirectory) pDirImpl;
186*fc633f11Smseidel 				return osl_File_E_None;
187*fc633f11Smseidel 			}
188*fc633f11Smseidel 			else
189*fc633f11Smseidel 			{
190*fc633f11Smseidel 				errno = ENOMEM;
191*fc633f11Smseidel 				closedir( pdir );
192*fc633f11Smseidel 			}
193*fc633f11Smseidel 		}
194*fc633f11Smseidel 		else
195*fc633f11Smseidel 		{
196cdf0e10cSrcweir #ifdef DEBUG_OSL_FILE
197*fc633f11Smseidel 			perror ("osl_openDirectory"); fprintf (stderr, path);
198cdf0e10cSrcweir #endif
199*fc633f11Smseidel 		}
200*fc633f11Smseidel 	}
201cdf0e10cSrcweir 
202*fc633f11Smseidel 	rtl_uString_release( ustrSystemPath );
203cdf0e10cSrcweir 
204*fc633f11Smseidel 	return oslTranslateFileError(OSL_FET_ERROR, errno);
205cdf0e10cSrcweir }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir /****************************************************************************/
208*fc633f11Smseidel /* osl_closeDirectory */
209cdf0e10cSrcweir /****************************************************************************/
210cdf0e10cSrcweir 
osl_closeDirectory(oslDirectory Directory)211cdf0e10cSrcweir oslFileError SAL_CALL osl_closeDirectory( oslDirectory Directory )
212cdf0e10cSrcweir {
213*fc633f11Smseidel 	oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*) Directory;
214*fc633f11Smseidel 	oslFileError err = osl_File_E_None;
215cdf0e10cSrcweir 
216*fc633f11Smseidel 	OSL_ASSERT( Directory );
217cdf0e10cSrcweir 
218*fc633f11Smseidel 	if( NULL == pDirImpl )
219*fc633f11Smseidel 		return osl_File_E_INVAL;
220cdf0e10cSrcweir 
221*fc633f11Smseidel 	/* close directory */
222*fc633f11Smseidel 	if( closedir( pDirImpl->pDirStruct ) )
223*fc633f11Smseidel 	{
224*fc633f11Smseidel 		err = oslTranslateFileError(OSL_FET_ERROR, errno);
225*fc633f11Smseidel 	}
226cdf0e10cSrcweir 
227*fc633f11Smseidel 	/* cleanup members */
228*fc633f11Smseidel 	rtl_uString_release( pDirImpl->ustrPath );
229cdf0e10cSrcweir 
230*fc633f11Smseidel 	rtl_freeMemory( pDirImpl );
231cdf0e10cSrcweir 
232*fc633f11Smseidel 	return err;
233cdf0e10cSrcweir }
234cdf0e10cSrcweir 
235cdf0e10cSrcweir /**********************************************
236cdf0e10cSrcweir  * osl_readdir_impl_
237cdf0e10cSrcweir  *
238cdf0e10cSrcweir  * readdir wrapper, filters out "." and ".."
239cdf0e10cSrcweir  * on request
240cdf0e10cSrcweir  *********************************************/
241cdf0e10cSrcweir 
osl_readdir_impl_(DIR * pdir,sal_Bool bFilterLocalAndParentDir)242cdf0e10cSrcweir static struct dirent* osl_readdir_impl_(DIR* pdir, sal_Bool bFilterLocalAndParentDir)
243cdf0e10cSrcweir {
244cdf0e10cSrcweir 	struct dirent* pdirent;
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 	while ((pdirent = readdir(pdir)) != NULL)
247cdf0e10cSrcweir 	{
248cdf0e10cSrcweir 		if (bFilterLocalAndParentDir &&
249cdf0e10cSrcweir 			((0 == strcmp(pdirent->d_name, ".")) || (0 == strcmp(pdirent->d_name, ".."))))
250cdf0e10cSrcweir 			continue;
251cdf0e10cSrcweir 		else
252cdf0e10cSrcweir 			break;
253cdf0e10cSrcweir 	}
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 	return pdirent;
256cdf0e10cSrcweir }
257cdf0e10cSrcweir 
258cdf0e10cSrcweir /****************************************************************************
259*fc633f11Smseidel  * osl_getNextDirectoryItem
260cdf0e10cSrcweir  ***************************************************************************/
261cdf0e10cSrcweir 
osl_getNextDirectoryItem(oslDirectory Directory,oslDirectoryItem * pItem,sal_uInt32)262cdf0e10cSrcweir oslFileError SAL_CALL osl_getNextDirectoryItem(oslDirectory Directory, oslDirectoryItem* pItem, sal_uInt32 /*uHint*/)
263cdf0e10cSrcweir {
264*fc633f11Smseidel 	oslDirectoryImpl* pDirImpl     = (oslDirectoryImpl*)Directory;
265*fc633f11Smseidel 	rtl_uString*      ustrFileName = NULL;
266*fc633f11Smseidel 	rtl_uString*      ustrFilePath = NULL;
267*fc633f11Smseidel 	struct dirent*    pEntry;
268cdf0e10cSrcweir 
269*fc633f11Smseidel 	OSL_ASSERT(Directory);
270*fc633f11Smseidel 	OSL_ASSERT(pItem);
271cdf0e10cSrcweir 
272*fc633f11Smseidel 	if ((NULL == Directory) || (NULL == pItem))
273*fc633f11Smseidel 		return osl_File_E_INVAL;
274cdf0e10cSrcweir 
275*fc633f11Smseidel 	pEntry = osl_readdir_impl_(pDirImpl->pDirStruct, sal_True);
276cdf0e10cSrcweir 
277*fc633f11Smseidel 	if (NULL == pEntry)
278*fc633f11Smseidel 		return osl_File_E_NOENT;
279cdf0e10cSrcweir 
280cdf0e10cSrcweir 
281cdf0e10cSrcweir #if defined(MACOSX)
282cdf0e10cSrcweir 
283*fc633f11Smseidel 	// convert decomposed filename to precomposed unicode
284*fc633f11Smseidel 	char composed_name[BUFSIZ];
285*fc633f11Smseidel 	CFMutableStringRef strRef = CFStringCreateMutable (NULL, 0 );
286*fc633f11Smseidel 	CFStringAppendCString( strRef, pEntry->d_name, kCFStringEncodingUTF8 ); //UTF8 is default on Mac OSX
287*fc633f11Smseidel 	CFStringNormalize( strRef, kCFStringNormalizationFormC );
288*fc633f11Smseidel 	CFStringGetCString( strRef, composed_name, BUFSIZ, kCFStringEncodingUTF8 );
289*fc633f11Smseidel 	CFRelease( strRef );
290*fc633f11Smseidel 	rtl_string2UString( &ustrFileName, composed_name, strlen( composed_name),
291cdf0e10cSrcweir 	osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
292cdf0e10cSrcweir 
293*fc633f11Smseidel #else // not MACOSX
294*fc633f11Smseidel 	/* convert file name to unicode */
295*fc633f11Smseidel 	rtl_string2UString( &ustrFileName, pEntry->d_name, strlen( pEntry->d_name ),
296*fc633f11Smseidel 		osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
297*fc633f11Smseidel 	OSL_ASSERT(ustrFileName != 0);
298cdf0e10cSrcweir 
299cdf0e10cSrcweir #endif
300cdf0e10cSrcweir 
301cdf0e10cSrcweir 	osl_systemPathMakeAbsolutePath(pDirImpl->ustrPath, ustrFileName, &ustrFilePath);
302*fc633f11Smseidel 	rtl_uString_release( ustrFileName );
303cdf0e10cSrcweir 
304cdf0e10cSrcweir 	DirectoryItem_Impl * pImpl = static_cast< DirectoryItem_Impl* >(*pItem);
305cdf0e10cSrcweir 	if (0 != pImpl)
306cdf0e10cSrcweir 	{
307cdf0e10cSrcweir 		pImpl->release(), pImpl = 0;
308cdf0e10cSrcweir 	}
309cdf0e10cSrcweir #ifdef _DIRENT_HAVE_D_TYPE
310cdf0e10cSrcweir 	pImpl = new DirectoryItem_Impl(ustrFilePath, pEntry->d_type);
311cdf0e10cSrcweir #else
312cdf0e10cSrcweir 	pImpl = new DirectoryItem_Impl(ustrFilePath);
313cdf0e10cSrcweir #endif /* _DIRENT_HAVE_D_TYPE */
314cdf0e10cSrcweir 	*pItem = pImpl;
315cdf0e10cSrcweir 	rtl_uString_release( ustrFilePath );
316cdf0e10cSrcweir 
317*fc633f11Smseidel 	return osl_File_E_None;
318cdf0e10cSrcweir }
319cdf0e10cSrcweir 
320cdf0e10cSrcweir /****************************************************************************/
321*fc633f11Smseidel /* osl_getDirectoryItem */
322cdf0e10cSrcweir /****************************************************************************/
323cdf0e10cSrcweir 
osl_getDirectoryItem(rtl_uString * ustrFileURL,oslDirectoryItem * pItem)324cdf0e10cSrcweir oslFileError SAL_CALL osl_getDirectoryItem( rtl_uString* ustrFileURL, oslDirectoryItem* pItem )
325cdf0e10cSrcweir {
326*fc633f11Smseidel 	rtl_uString* ustrSystemPath = NULL;
327*fc633f11Smseidel 	oslFileError osl_error      = osl_File_E_INVAL;
328cdf0e10cSrcweir 
329*fc633f11Smseidel 	OSL_ASSERT((0 != ustrFileURL) && (0 != pItem));
330*fc633f11Smseidel 	if ((0 == ustrFileURL) || (0 == ustrFileURL->length) || (0 == pItem))
331*fc633f11Smseidel 		return osl_File_E_INVAL;
332cdf0e10cSrcweir 
333*fc633f11Smseidel 	osl_error = osl_getSystemPathFromFileURL_Ex(ustrFileURL, &ustrSystemPath, sal_False);
334*fc633f11Smseidel 	if (osl_File_E_None != osl_error)
335*fc633f11Smseidel 		return osl_error;
336cdf0e10cSrcweir 
337cdf0e10cSrcweir 	osl_systemPathRemoveSeparator(ustrSystemPath);
338cdf0e10cSrcweir 
339cdf0e10cSrcweir 	if (-1 == access_u(ustrSystemPath, F_OK))
340cdf0e10cSrcweir 	{
341cdf0e10cSrcweir 		osl_error = oslTranslateFileError(OSL_FET_ERROR, errno);
342cdf0e10cSrcweir 	}
343cdf0e10cSrcweir 	else
344cdf0e10cSrcweir 	{
345cdf0e10cSrcweir 		*pItem = new DirectoryItem_Impl(ustrSystemPath);
346cdf0e10cSrcweir 	}
347cdf0e10cSrcweir 	rtl_uString_release(ustrSystemPath);
348cdf0e10cSrcweir 
349cdf0e10cSrcweir 	return osl_error;
350cdf0e10cSrcweir }
351cdf0e10cSrcweir 
352cdf0e10cSrcweir 
353cdf0e10cSrcweir /****************************************************************************/
354*fc633f11Smseidel /* osl_acquireDirectoryItem */
355cdf0e10cSrcweir /****************************************************************************/
356cdf0e10cSrcweir 
osl_acquireDirectoryItem(oslDirectoryItem Item)357cdf0e10cSrcweir oslFileError SAL_CALL osl_acquireDirectoryItem( oslDirectoryItem Item )
358cdf0e10cSrcweir {
359cdf0e10cSrcweir 	DirectoryItem_Impl * pImpl = static_cast< DirectoryItem_Impl* >(Item);
360cdf0e10cSrcweir 	if (0 == pImpl)
361cdf0e10cSrcweir 		return osl_File_E_INVAL;
362cdf0e10cSrcweir 
363cdf0e10cSrcweir 	pImpl->acquire();
364*fc633f11Smseidel 	return osl_File_E_None;
365cdf0e10cSrcweir }
366cdf0e10cSrcweir 
367cdf0e10cSrcweir /****************************************************************************/
368*fc633f11Smseidel /* osl_releaseDirectoryItem */
369cdf0e10cSrcweir /****************************************************************************/
370cdf0e10cSrcweir 
osl_releaseDirectoryItem(oslDirectoryItem Item)371cdf0e10cSrcweir oslFileError SAL_CALL osl_releaseDirectoryItem( oslDirectoryItem Item )
372cdf0e10cSrcweir {
373cdf0e10cSrcweir 	DirectoryItem_Impl * pImpl = static_cast< DirectoryItem_Impl* >(Item);
374cdf0e10cSrcweir 	if (0 == pImpl)
375cdf0e10cSrcweir 		return osl_File_E_INVAL;
376cdf0e10cSrcweir 
377cdf0e10cSrcweir 	pImpl->release();
378*fc633f11Smseidel 	return osl_File_E_None;
379cdf0e10cSrcweir }
380cdf0e10cSrcweir 
381cdf0e10cSrcweir /****************************************************************************/
382*fc633f11Smseidel /* osl_createDirectory */
383cdf0e10cSrcweir /****************************************************************************/
384cdf0e10cSrcweir 
osl_createDirectory(rtl_uString * ustrDirectoryURL)385cdf0e10cSrcweir oslFileError SAL_CALL osl_createDirectory( rtl_uString* ustrDirectoryURL )
386cdf0e10cSrcweir {
387*fc633f11Smseidel 	char path[PATH_MAX];
388*fc633f11Smseidel 	oslFileError eRet;
389cdf0e10cSrcweir 
390*fc633f11Smseidel 	OSL_ASSERT( ustrDirectoryURL );
391cdf0e10cSrcweir 
392*fc633f11Smseidel 	/* convert directory url to system path */
393*fc633f11Smseidel 	eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
394*fc633f11Smseidel 	if( eRet != osl_File_E_None )
395*fc633f11Smseidel 		return eRet;
396cdf0e10cSrcweir 
397cdf0e10cSrcweir #ifdef MACOSX
398*fc633f11Smseidel 	if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
399*fc633f11Smseidel 		return oslTranslateFileError( OSL_FET_ERROR, errno );
400cdf0e10cSrcweir #endif/* MACOSX */
401cdf0e10cSrcweir 
402*fc633f11Smseidel 	return osl_psz_createDirectory( path );
403cdf0e10cSrcweir }
404cdf0e10cSrcweir 
405cdf0e10cSrcweir /****************************************************************************/
406*fc633f11Smseidel /* osl_removeDirectory */
407cdf0e10cSrcweir /****************************************************************************/
408cdf0e10cSrcweir 
osl_removeDirectory(rtl_uString * ustrDirectoryURL)409cdf0e10cSrcweir oslFileError SAL_CALL osl_removeDirectory( rtl_uString* ustrDirectoryURL )
410cdf0e10cSrcweir {
411*fc633f11Smseidel 	char path[PATH_MAX];
412*fc633f11Smseidel 	oslFileError eRet;
413cdf0e10cSrcweir 
414*fc633f11Smseidel 	OSL_ASSERT( ustrDirectoryURL );
415cdf0e10cSrcweir 
416*fc633f11Smseidel 	/* convert directory url to system path */
417*fc633f11Smseidel 	eRet = FileURLToPath( path, PATH_MAX, ustrDirectoryURL );
418*fc633f11Smseidel 	if( eRet != osl_File_E_None )
419*fc633f11Smseidel 		return eRet;
420cdf0e10cSrcweir 
421cdf0e10cSrcweir #ifdef MACOSX
422*fc633f11Smseidel 	if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
423*fc633f11Smseidel 		return oslTranslateFileError( OSL_FET_ERROR, errno );
424cdf0e10cSrcweir #endif/* MACOSX */
425cdf0e10cSrcweir 
426*fc633f11Smseidel 	return osl_psz_removeDirectory( path );
427cdf0e10cSrcweir }
428cdf0e10cSrcweir 
429cdf0e10cSrcweir /*****************************************
430cdf0e10cSrcweir  * osl_psz_createDirectory
431cdf0e10cSrcweir  ****************************************/
432cdf0e10cSrcweir 
osl_psz_createDirectory(const sal_Char * pszPath)433cdf0e10cSrcweir static oslFileError osl_psz_createDirectory( const sal_Char* pszPath )
434cdf0e10cSrcweir {
435*fc633f11Smseidel 	int nRet=0;
436*fc633f11Smseidel 	int mode = S_IRWXU | S_IRWXG | S_IRWXO;
437cdf0e10cSrcweir 
438*fc633f11Smseidel 	nRet = mkdir(pszPath,mode);
439cdf0e10cSrcweir 
440*fc633f11Smseidel 	if ( nRet < 0 )
441*fc633f11Smseidel 	{
442*fc633f11Smseidel 		nRet=errno;
443*fc633f11Smseidel 		return oslTranslateFileError(OSL_FET_ERROR, nRet);
444*fc633f11Smseidel 	}
445cdf0e10cSrcweir 
446*fc633f11Smseidel 	return osl_File_E_None;
447cdf0e10cSrcweir }
448cdf0e10cSrcweir 
449cdf0e10cSrcweir /*****************************************
450cdf0e10cSrcweir  * osl_psz_removeDirectory
451cdf0e10cSrcweir  ****************************************/
452cdf0e10cSrcweir 
osl_psz_removeDirectory(const sal_Char * pszPath)453cdf0e10cSrcweir static oslFileError osl_psz_removeDirectory( const sal_Char* pszPath )
454cdf0e10cSrcweir {
455*fc633f11Smseidel 	int nRet=0;
456cdf0e10cSrcweir 
457*fc633f11Smseidel 	nRet = rmdir(pszPath);
458cdf0e10cSrcweir 
459*fc633f11Smseidel 	if ( nRet < 0 )
460*fc633f11Smseidel 	{
461*fc633f11Smseidel 		nRet=errno;
462*fc633f11Smseidel 		return oslTranslateFileError(OSL_FET_ERROR, nRet);
463*fc633f11Smseidel 	}
464cdf0e10cSrcweir 
465*fc633f11Smseidel 	return osl_File_E_None;
466cdf0e10cSrcweir }
467cdf0e10cSrcweir 
468cdf0e10cSrcweir /****************************************************************************/
469*fc633f11Smseidel /* osl_createDirectoryPath */
470cdf0e10cSrcweir /****************************************************************************/
471cdf0e10cSrcweir 
path_make_parent(sal_Unicode * path)472cdf0e10cSrcweir static int path_make_parent(sal_Unicode* path)
473cdf0e10cSrcweir {
474cdf0e10cSrcweir 	int i = rtl_ustr_lastIndexOfChar(path, '/');
475*fc633f11Smseidel 
476cdf0e10cSrcweir 	if (i > 0)
477cdf0e10cSrcweir 	{
478cdf0e10cSrcweir 		*(path + i) = 0;
479cdf0e10cSrcweir 		return i;
480cdf0e10cSrcweir 	}
481cdf0e10cSrcweir 	else
482cdf0e10cSrcweir 		return 0;
483cdf0e10cSrcweir }
484cdf0e10cSrcweir 
create_dir_with_callback(sal_Unicode * directory_path,oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,void * pData)485cdf0e10cSrcweir static int create_dir_with_callback(
486cdf0e10cSrcweir 	sal_Unicode* directory_path,
487*fc633f11Smseidel 	oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
488*fc633f11Smseidel 	void* pData)
489cdf0e10cSrcweir {
490cdf0e10cSrcweir 	int mode = S_IRWXU | S_IRWXG | S_IRWXO;
491*fc633f11Smseidel 
492cdf0e10cSrcweir 	if (osl::mkdir(directory_path, mode) == 0)
493*fc633f11Smseidel 	{
494*fc633f11Smseidel 		if (aDirectoryCreationCallbackFunc)
495*fc633f11Smseidel 		{
496*fc633f11Smseidel 			rtl::OUString url;
497*fc633f11Smseidel 			osl::FileBase::getFileURLFromSystemPath(directory_path, url);
498*fc633f11Smseidel 			aDirectoryCreationCallbackFunc(pData, url.pData);
499*fc633f11Smseidel 		}
500*fc633f11Smseidel 		return 0;
501*fc633f11Smseidel 	}
502*fc633f11Smseidel 	return errno;
503cdf0e10cSrcweir }
504cdf0e10cSrcweir 
create_dir_recursively_(sal_Unicode * dir_path,oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,void * pData)505cdf0e10cSrcweir static oslFileError create_dir_recursively_(
506cdf0e10cSrcweir 	sal_Unicode* dir_path,
507*fc633f11Smseidel 	oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
508*fc633f11Smseidel 	void* pData)
509*fc633f11Smseidel {
510cdf0e10cSrcweir 	OSL_PRECOND((rtl_ustr_getLength(dir_path) > 0) && ((dir_path + (rtl_ustr_getLength(dir_path) - 1)) != (dir_path + rtl_ustr_lastIndexOfChar(dir_path, '/'))), \
511cdf0e10cSrcweir 	"Path must not end with a slash");
512*fc633f11Smseidel 
513cdf0e10cSrcweir 	int native_err = create_dir_with_callback(
514*fc633f11Smseidel 		dir_path, aDirectoryCreationCallbackFunc, pData);
515*fc633f11Smseidel 
516*fc633f11Smseidel 	if (native_err == 0)
517*fc633f11Smseidel 		return osl_File_E_None;
518*fc633f11Smseidel 
519*fc633f11Smseidel 	if (native_err != ENOENT)
520*fc633f11Smseidel 		return oslTranslateFileError(OSL_FET_ERROR, native_err);
521*fc633f11Smseidel 
522cdf0e10cSrcweir 	// we step back until '/a_dir' at maximum because
523cdf0e10cSrcweir 	// we should get an error unequal ENOENT when
524*fc633f11Smseidel 	// we try to create 'a_dir' at '/' and would so
525*fc633f11Smseidel 	// return before
526cdf0e10cSrcweir 	int pos = path_make_parent(dir_path);
527*fc633f11Smseidel 
528*fc633f11Smseidel 	oslFileError osl_error = create_dir_recursively_(
529*fc633f11Smseidel 		dir_path, aDirectoryCreationCallbackFunc, pData);
530*fc633f11Smseidel 
531*fc633f11Smseidel 	if (osl_File_E_None != osl_error)
532*fc633f11Smseidel 		return osl_error;
533*fc633f11Smseidel 
534*fc633f11Smseidel 	dir_path[pos] = '/';
535*fc633f11Smseidel 
536*fc633f11Smseidel 	return create_dir_recursively_(dir_path, aDirectoryCreationCallbackFunc, pData);
537cdf0e10cSrcweir }
538cdf0e10cSrcweir 
osl_createDirectoryPath(rtl_uString * aDirectoryUrl,oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,void * pData)539cdf0e10cSrcweir oslFileError SAL_CALL osl_createDirectoryPath(
540*fc633f11Smseidel 	rtl_uString* aDirectoryUrl,
541*fc633f11Smseidel 	oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
542*fc633f11Smseidel 	void* pData)
543cdf0e10cSrcweir {
544*fc633f11Smseidel 	if (aDirectoryUrl == NULL)
545*fc633f11Smseidel 		return osl_File_E_INVAL;
546*fc633f11Smseidel 
547*fc633f11Smseidel 	rtl::OUString sys_path;
548*fc633f11Smseidel 	oslFileError osl_error = osl_getSystemPathFromFileURL_Ex(
549*fc633f11Smseidel 		aDirectoryUrl, &sys_path.pData, sal_False);
550*fc633f11Smseidel 
551*fc633f11Smseidel 	if (osl_error != osl_File_E_None)
552*fc633f11Smseidel 		return osl_error;
553*fc633f11Smseidel 
554*fc633f11Smseidel 	osl::systemPathRemoveSeparator(sys_path);
555*fc633f11Smseidel 
556*fc633f11Smseidel 	// const_cast because sys_path is a local copy which we want to modify inplace instead of
557*fc633f11Smseidel 	// copy it into another buffer on the heap again
558*fc633f11Smseidel 	return create_dir_recursively_(sys_path.pData->buffer, aDirectoryCreationCallbackFunc, pData);
559cdf0e10cSrcweir }
560cdf0e10cSrcweir 
561cdf0e10cSrcweir /******************************************************************************
562*fc633f11Smseidel  * C-String Function Declarations
563cdf0e10cSrcweir  *****************************************************************************/
564cdf0e10cSrcweir 
565cdf0e10cSrcweir static oslFileError osl_psz_removeFile(const sal_Char* pszPath);
566cdf0e10cSrcweir static oslFileError osl_psz_copyFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
567cdf0e10cSrcweir static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
568cdf0e10cSrcweir 
569cdf0e10cSrcweir 
570cdf0e10cSrcweir /******************************************************************************
571*fc633f11Smseidel  * Static Module Utility Function Declarations
572cdf0e10cSrcweir  *****************************************************************************/
573cdf0e10cSrcweir 
574cdf0e10cSrcweir static oslFileError  oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists);
575cdf0e10cSrcweir static oslFileError  oslChangeFileModes(const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID);
576cdf0e10cSrcweir static int           oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName);
577cdf0e10cSrcweir static int           oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode);
578cdf0e10cSrcweir static oslFileError  oslDoMoveFile(const sal_Char* pszPath, const sal_Char* pszDestPath);
579cdf0e10cSrcweir 
580cdf0e10cSrcweir /****************************************************************************/
581*fc633f11Smseidel /* osl_moveFile */
582cdf0e10cSrcweir /****************************************************************************/
583cdf0e10cSrcweir 
osl_moveFile(rtl_uString * ustrFileURL,rtl_uString * ustrDestURL)584cdf0e10cSrcweir oslFileError SAL_CALL osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
585cdf0e10cSrcweir {
586*fc633f11Smseidel 	char srcPath[PATH_MAX];
587*fc633f11Smseidel 	char destPath[PATH_MAX];
588*fc633f11Smseidel 	oslFileError eRet;
589cdf0e10cSrcweir 
590*fc633f11Smseidel 	OSL_ASSERT( ustrFileURL );
591*fc633f11Smseidel 	OSL_ASSERT( ustrDestURL );
592cdf0e10cSrcweir 
593*fc633f11Smseidel 	/* convert source url to system path */
594*fc633f11Smseidel 	eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
595*fc633f11Smseidel 	if( eRet != osl_File_E_None )
596*fc633f11Smseidel 		return eRet;
597cdf0e10cSrcweir 
598*fc633f11Smseidel 	/* convert destination url to system path */
599*fc633f11Smseidel 	eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
600*fc633f11Smseidel 	if( eRet != osl_File_E_None )
601*fc633f11Smseidel 		return eRet;
602cdf0e10cSrcweir 
603cdf0e10cSrcweir #ifdef MACOSX
604*fc633f11Smseidel 	if ( macxp_resolveAlias( srcPath, PATH_MAX ) != 0 || macxp_resolveAlias( destPath, PATH_MAX ) != 0 )
605*fc633f11Smseidel 		return oslTranslateFileError( OSL_FET_ERROR, errno );
606cdf0e10cSrcweir #endif/* MACOSX */
607cdf0e10cSrcweir 
608*fc633f11Smseidel 	return oslDoMoveFile( srcPath, destPath );
609cdf0e10cSrcweir }
610cdf0e10cSrcweir 
611cdf0e10cSrcweir /****************************************************************************/
612*fc633f11Smseidel /* osl_copyFile */
613cdf0e10cSrcweir /****************************************************************************/
614cdf0e10cSrcweir 
osl_copyFile(rtl_uString * ustrFileURL,rtl_uString * ustrDestURL)615cdf0e10cSrcweir oslFileError SAL_CALL osl_copyFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
616cdf0e10cSrcweir {
617*fc633f11Smseidel 	char srcPath[PATH_MAX];
618*fc633f11Smseidel 	char destPath[PATH_MAX];
619*fc633f11Smseidel 	oslFileError eRet;
620cdf0e10cSrcweir 
621*fc633f11Smseidel 	OSL_ASSERT( ustrFileURL );
622*fc633f11Smseidel 	OSL_ASSERT( ustrDestURL );
623cdf0e10cSrcweir 
624*fc633f11Smseidel 	/* convert source url to system path */
625*fc633f11Smseidel 	eRet = FileURLToPath( srcPath, PATH_MAX, ustrFileURL );
626*fc633f11Smseidel 	if( eRet != osl_File_E_None )
627*fc633f11Smseidel 		return eRet;
628cdf0e10cSrcweir 
629*fc633f11Smseidel 	/* convert destination url to system path */
630*fc633f11Smseidel 	eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
631*fc633f11Smseidel 	if( eRet != osl_File_E_None )
632*fc633f11Smseidel 		return eRet;
633cdf0e10cSrcweir 
634cdf0e10cSrcweir #ifdef MACOSX
635*fc633f11Smseidel 	if ( macxp_resolveAlias( srcPath, PATH_MAX ) != 0 || macxp_resolveAlias( destPath, PATH_MAX ) != 0 )
636*fc633f11Smseidel 		return oslTranslateFileError( OSL_FET_ERROR, errno );
637cdf0e10cSrcweir #endif/* MACOSX */
638cdf0e10cSrcweir 
639*fc633f11Smseidel 	return osl_psz_copyFile( srcPath, destPath );
640cdf0e10cSrcweir }
641cdf0e10cSrcweir 
642cdf0e10cSrcweir /****************************************************************************/
643*fc633f11Smseidel /* osl_removeFile */
644cdf0e10cSrcweir /****************************************************************************/
645cdf0e10cSrcweir 
osl_removeFile(rtl_uString * ustrFileURL)646cdf0e10cSrcweir oslFileError SAL_CALL osl_removeFile( rtl_uString* ustrFileURL )
647cdf0e10cSrcweir {
648*fc633f11Smseidel 	char path[PATH_MAX];
649*fc633f11Smseidel 	oslFileError eRet;
650cdf0e10cSrcweir 
651*fc633f11Smseidel 	OSL_ASSERT( ustrFileURL );
652cdf0e10cSrcweir 
653*fc633f11Smseidel 	/* convert file url to system path */
654*fc633f11Smseidel 	eRet = FileURLToPath( path, PATH_MAX, ustrFileURL );
655*fc633f11Smseidel 	if( eRet != osl_File_E_None )
656*fc633f11Smseidel 		return eRet;
657cdf0e10cSrcweir 
658cdf0e10cSrcweir #ifdef MACOSX
659*fc633f11Smseidel 	if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
660*fc633f11Smseidel 		return oslTranslateFileError( OSL_FET_ERROR, errno );
661cdf0e10cSrcweir #endif/* MACOSX */
662cdf0e10cSrcweir 
663*fc633f11Smseidel 	return osl_psz_removeFile( path );
664cdf0e10cSrcweir }
665cdf0e10cSrcweir 
666cdf0e10cSrcweir /******************************************************************************
667*fc633f11Smseidel  * Utility Functions
668cdf0e10cSrcweir  *****************************************************************************/
669cdf0e10cSrcweir 
670cdf0e10cSrcweir /*****************************************
671cdf0e10cSrcweir  * oslDoMoveFile
672cdf0e10cSrcweir  ****************************************/
673cdf0e10cSrcweir 
oslDoMoveFile(const sal_Char * pszPath,const sal_Char * pszDestPath)674cdf0e10cSrcweir static oslFileError oslDoMoveFile( const sal_Char* pszPath, const sal_Char* pszDestPath)
675cdf0e10cSrcweir {
676*fc633f11Smseidel 	oslFileError tErr=osl_File_E_invalidError;
677cdf0e10cSrcweir 
678*fc633f11Smseidel 	tErr = osl_psz_moveFile(pszPath,pszDestPath);
679*fc633f11Smseidel 	if ( tErr == osl_File_E_None )
680*fc633f11Smseidel 	{
681*fc633f11Smseidel 		return tErr;
682*fc633f11Smseidel 	}
683cdf0e10cSrcweir 
684*fc633f11Smseidel 	if ( tErr != osl_File_E_XDEV )
685*fc633f11Smseidel 	{
686*fc633f11Smseidel 		return tErr;
687*fc633f11Smseidel 	}
688cdf0e10cSrcweir 
689*fc633f11Smseidel 	tErr=osl_psz_copyFile(pszPath,pszDestPath);
690cdf0e10cSrcweir 
691*fc633f11Smseidel 	if ( tErr != osl_File_E_None )
692*fc633f11Smseidel 	{
693*fc633f11Smseidel 		oslFileError tErrRemove;
694*fc633f11Smseidel 		tErrRemove=osl_psz_removeFile(pszDestPath);
695*fc633f11Smseidel 		return tErr;
696*fc633f11Smseidel 	}
697cdf0e10cSrcweir 
698*fc633f11Smseidel 	tErr=osl_psz_removeFile(pszPath);
699cdf0e10cSrcweir 
700*fc633f11Smseidel 	return tErr;
701cdf0e10cSrcweir }
702cdf0e10cSrcweir 
703cdf0e10cSrcweir /*****************************************
704cdf0e10cSrcweir  * osl_psz_removeFile
705cdf0e10cSrcweir  ****************************************/
osl_psz_removeFile(const sal_Char * pszPath)706cdf0e10cSrcweir static oslFileError osl_psz_removeFile( const sal_Char* pszPath )
707cdf0e10cSrcweir {
708*fc633f11Smseidel 	int nRet=0;
709*fc633f11Smseidel 	struct stat aStat;
710*fc633f11Smseidel 
711*fc633f11Smseidel 	nRet = lstat(pszPath,&aStat);
712*fc633f11Smseidel 	if ( nRet < 0 )
713*fc633f11Smseidel 	{
714*fc633f11Smseidel 		nRet=errno;
715*fc633f11Smseidel 		return oslTranslateFileError(OSL_FET_ERROR, nRet);
716*fc633f11Smseidel 	}
717*fc633f11Smseidel 
718*fc633f11Smseidel 	if ( S_ISDIR(aStat.st_mode) )
719*fc633f11Smseidel 	{
720*fc633f11Smseidel 		return osl_File_E_ISDIR;
721*fc633f11Smseidel 	}
722*fc633f11Smseidel 
723*fc633f11Smseidel 	nRet = unlink(pszPath);
724*fc633f11Smseidel 	if ( nRet < 0 )
725*fc633f11Smseidel 	{
726*fc633f11Smseidel 		nRet=errno;
727*fc633f11Smseidel 		return oslTranslateFileError(OSL_FET_ERROR, nRet);
728*fc633f11Smseidel 	}
729*fc633f11Smseidel 
730*fc633f11Smseidel 	return osl_File_E_None;
731cdf0e10cSrcweir }
732cdf0e10cSrcweir 
733cdf0e10cSrcweir /*****************************************
734cdf0e10cSrcweir  * osl_psz_moveFile
735cdf0e10cSrcweir  ****************************************/
736cdf0e10cSrcweir 
osl_psz_moveFile(const sal_Char * pszPath,const sal_Char * pszDestPath)737cdf0e10cSrcweir static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath)
738cdf0e10cSrcweir {
739cdf0e10cSrcweir 
740*fc633f11Smseidel 	int nRet = 0;
741cdf0e10cSrcweir 
742*fc633f11Smseidel 	nRet = rename(pszPath,pszDestPath);
743cdf0e10cSrcweir 
744*fc633f11Smseidel 	if ( nRet < 0 )
745*fc633f11Smseidel 	{
746*fc633f11Smseidel 		nRet=errno;
747*fc633f11Smseidel 		return oslTranslateFileError(OSL_FET_ERROR, nRet);
748*fc633f11Smseidel 	}
749cdf0e10cSrcweir 
750*fc633f11Smseidel 	return osl_File_E_None;
751cdf0e10cSrcweir }
752cdf0e10cSrcweir 
753cdf0e10cSrcweir /*****************************************
754cdf0e10cSrcweir  * osl_psz_copyFile
755cdf0e10cSrcweir  ****************************************/
756cdf0e10cSrcweir 
osl_psz_copyFile(const sal_Char * pszPath,const sal_Char * pszDestPath)757cdf0e10cSrcweir static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
758cdf0e10cSrcweir {
759*fc633f11Smseidel 	time_t nAcTime=0;
760*fc633f11Smseidel 	time_t nModTime=0;
761*fc633f11Smseidel 	uid_t nUID=0;
762*fc633f11Smseidel 	gid_t nGID=0;
763*fc633f11Smseidel 	int nRet=0;
764*fc633f11Smseidel 	mode_t nMode=0;
765*fc633f11Smseidel 	struct stat aFileStat;
766*fc633f11Smseidel 	oslFileError tErr=osl_File_E_invalidError;
767*fc633f11Smseidel 	size_t nSourceSize=0;
768*fc633f11Smseidel 	int DestFileExists=1;
769*fc633f11Smseidel 
770*fc633f11Smseidel 	/* mfe: does the source file really exists? */
771*fc633f11Smseidel 	nRet = lstat(pszPath,&aFileStat);
772*fc633f11Smseidel 
773*fc633f11Smseidel 	if ( nRet < 0 )
774*fc633f11Smseidel 	{
775*fc633f11Smseidel 		nRet=errno;
776*fc633f11Smseidel 		return oslTranslateFileError(OSL_FET_ERROR, nRet);
777*fc633f11Smseidel 	}
778*fc633f11Smseidel 
779*fc633f11Smseidel 	/* mfe: we do only copy files here! */
780*fc633f11Smseidel 	if ( S_ISDIR(aFileStat.st_mode) )
781*fc633f11Smseidel 	{
782*fc633f11Smseidel 		return osl_File_E_ISDIR;
783*fc633f11Smseidel 	}
784*fc633f11Smseidel 
785*fc633f11Smseidel 	nSourceSize=(size_t)aFileStat.st_size;
786*fc633f11Smseidel 	nMode=aFileStat.st_mode;
787*fc633f11Smseidel 	nAcTime=aFileStat.st_atime;
788*fc633f11Smseidel 	nModTime=aFileStat.st_mtime;
789*fc633f11Smseidel 	nUID=aFileStat.st_uid;
790*fc633f11Smseidel 	nGID=aFileStat.st_gid;
791*fc633f11Smseidel 
792*fc633f11Smseidel 	nRet = stat(pszDestPath,&aFileStat);
793*fc633f11Smseidel 	if ( nRet < 0 )
794*fc633f11Smseidel 	{
795*fc633f11Smseidel 		nRet=errno;
796*fc633f11Smseidel 
797*fc633f11Smseidel 		if ( nRet == ENOENT )
798*fc633f11Smseidel 		{
799*fc633f11Smseidel 			DestFileExists=0;
800*fc633f11Smseidel 		}
801*fc633f11Smseidel /*		return oslTranslateFileError(nRet);*/
802*fc633f11Smseidel 	}
803*fc633f11Smseidel 
804*fc633f11Smseidel 	/* mfe: the destination file must not be a directory! */
805*fc633f11Smseidel 	if ( nRet == 0 && S_ISDIR(aFileStat.st_mode) )
806*fc633f11Smseidel 	{
807*fc633f11Smseidel 		return osl_File_E_ISDIR;
808*fc633f11Smseidel 	}
809*fc633f11Smseidel 	else
810*fc633f11Smseidel 	{
811*fc633f11Smseidel 		/* mfe: file does not exists or is no dir */
812*fc633f11Smseidel 	}
813*fc633f11Smseidel 
814*fc633f11Smseidel 	tErr = oslDoCopy(pszPath,pszDestPath,nMode,nSourceSize,DestFileExists);
815*fc633f11Smseidel 
816*fc633f11Smseidel 	if ( tErr != osl_File_E_None )
817*fc633f11Smseidel 	{
818*fc633f11Smseidel 		return tErr;
819*fc633f11Smseidel 	}
820*fc633f11Smseidel 
821*fc633f11Smseidel 	/*
822*fc633f11Smseidel 	 *   mfe: ignore return code
823*fc633f11Smseidel 	 *        since only the success of the copy is
824*fc633f11Smseidel 	 *        important
825*fc633f11Smseidel 	 */
826*fc633f11Smseidel 	oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
827*fc633f11Smseidel 
828*fc633f11Smseidel 	return tErr;
829cdf0e10cSrcweir }
830cdf0e10cSrcweir 
831cdf0e10cSrcweir 
832cdf0e10cSrcweir /******************************************************************************
833*fc633f11Smseidel  * Utility Functions
834cdf0e10cSrcweir  *****************************************************************************/
835cdf0e10cSrcweir 
836cdf0e10cSrcweir /*****************************************
837cdf0e10cSrcweir  * oslDoCopy
838cdf0e10cSrcweir  ****************************************/
839cdf0e10cSrcweir 
840cdf0e10cSrcweir #define TMP_DEST_FILE_EXTENSION ".osl-tmp"
841cdf0e10cSrcweir 
oslDoCopy(const sal_Char * pszSourceFileName,const sal_Char * pszDestFileName,mode_t nMode,size_t nSourceSize,int DestFileExists)842cdf0e10cSrcweir static oslFileError oslDoCopy(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, mode_t nMode, size_t nSourceSize, int DestFileExists)
843cdf0e10cSrcweir {
844*fc633f11Smseidel 	int      nRet=0;
845*fc633f11Smseidel 	sal_Char pszTmpDestFile[PATH_MAX];
846cdf0e10cSrcweir 	size_t   size_tmp_dest_buff = sizeof(pszTmpDestFile);
847cdf0e10cSrcweir 
848cdf0e10cSrcweir 	/* Quick fix for #106048, the whole copy file function seems
849cdf0e10cSrcweir 	   to be erroneous anyway and needs to be rewritten.
850*fc633f11Smseidel 	   Besides osl_copyFile	is currently not used from AOO code.
851cdf0e10cSrcweir 	*/
852cdf0e10cSrcweir 	memset(pszTmpDestFile, 0, size_tmp_dest_buff);
853cdf0e10cSrcweir 
854*fc633f11Smseidel 	if ( DestFileExists )
855*fc633f11Smseidel 	{
856cdf0e10cSrcweir 		strncpy(pszTmpDestFile, pszDestFileName, size_tmp_dest_buff - 1);
857cdf0e10cSrcweir 
858cdf0e10cSrcweir 		if ((strlen(pszTmpDestFile) + strlen(TMP_DEST_FILE_EXTENSION)) >= size_tmp_dest_buff)
859cdf0e10cSrcweir 			return osl_File_E_NAMETOOLONG;
860cdf0e10cSrcweir 
861cdf0e10cSrcweir 		strncat(pszTmpDestFile, TMP_DEST_FILE_EXTENSION, strlen(TMP_DEST_FILE_EXTENSION));
862cdf0e10cSrcweir 
863*fc633f11Smseidel 		/* FIXME: what if pszTmpDestFile already exists? */
864*fc633f11Smseidel 		/*        with getcanonical??? */
865*fc633f11Smseidel 		nRet=rename(pszDestFileName,pszTmpDestFile);
866*fc633f11Smseidel 	}
867*fc633f11Smseidel 
868*fc633f11Smseidel 	/* mfe: should be S_ISREG */
869*fc633f11Smseidel 	if ( !S_ISLNK(nMode) )
870*fc633f11Smseidel 	{
871*fc633f11Smseidel 		/* copy SourceFile to DestFile */
872*fc633f11Smseidel 		nRet = oslDoCopyFile(pszSourceFileName,pszDestFileName,nSourceSize, nMode);
873*fc633f11Smseidel 	}
874*fc633f11Smseidel 	/* mfe: OK redundant at the moment */
875*fc633f11Smseidel 	else if ( S_ISLNK(nMode) )
876*fc633f11Smseidel 	{
877*fc633f11Smseidel 		nRet = oslDoCopyLink(pszSourceFileName,pszDestFileName);
878*fc633f11Smseidel 	}
879*fc633f11Smseidel 	else
880*fc633f11Smseidel 	{
881*fc633f11Smseidel 		/* mfe: what to do here? */
882*fc633f11Smseidel 		nRet=ENOSYS;
883*fc633f11Smseidel 	}
884*fc633f11Smseidel 
885*fc633f11Smseidel 	if ( nRet > 0 && DestFileExists == 1 )
886*fc633f11Smseidel 	{
887*fc633f11Smseidel 		unlink(pszDestFileName);
888*fc633f11Smseidel 		rename(pszTmpDestFile,pszDestFileName);
889*fc633f11Smseidel 	}
890*fc633f11Smseidel 
891*fc633f11Smseidel 	if ( nRet > 0 )
892*fc633f11Smseidel 	{
893*fc633f11Smseidel 		return oslTranslateFileError(OSL_FET_ERROR, nRet);
894*fc633f11Smseidel 	}
895*fc633f11Smseidel 
896*fc633f11Smseidel 	if ( DestFileExists == 1 )
897*fc633f11Smseidel 	{
898*fc633f11Smseidel 		unlink(pszTmpDestFile);
899*fc633f11Smseidel 	}
900*fc633f11Smseidel 
901*fc633f11Smseidel 	return osl_File_E_None;
902cdf0e10cSrcweir }
903cdf0e10cSrcweir 
904cdf0e10cSrcweir /*****************************************
905cdf0e10cSrcweir  * oslChangeFileModes
906cdf0e10cSrcweir  ****************************************/
907cdf0e10cSrcweir 
oslChangeFileModes(const sal_Char * pszFileName,mode_t nMode,time_t nAcTime,time_t nModTime,uid_t nUID,gid_t nGID)908cdf0e10cSrcweir static oslFileError oslChangeFileModes( const sal_Char* pszFileName, mode_t nMode, time_t nAcTime, time_t nModTime, uid_t nUID, gid_t nGID)
909cdf0e10cSrcweir {
910*fc633f11Smseidel 	int nRet=0;
911*fc633f11Smseidel 	struct utimbuf aTimeBuffer;
912*fc633f11Smseidel 
913*fc633f11Smseidel 	nRet = chmod(pszFileName,nMode);
914*fc633f11Smseidel 	if ( nRet < 0 )
915*fc633f11Smseidel 	{
916*fc633f11Smseidel 		nRet=errno;
917*fc633f11Smseidel 		return oslTranslateFileError(OSL_FET_ERROR, nRet);
918*fc633f11Smseidel 	}
919*fc633f11Smseidel 
920*fc633f11Smseidel 	aTimeBuffer.actime=nAcTime;
921*fc633f11Smseidel 	aTimeBuffer.modtime=nModTime;
922*fc633f11Smseidel 	nRet=utime(pszFileName,&aTimeBuffer);
923*fc633f11Smseidel 	if ( nRet < 0 )
924*fc633f11Smseidel 	{
925*fc633f11Smseidel 		nRet=errno;
926*fc633f11Smseidel 		return oslTranslateFileError(OSL_FET_ERROR, nRet);
927*fc633f11Smseidel 	}
928*fc633f11Smseidel 
929*fc633f11Smseidel 	if ( nUID != getuid() )
930*fc633f11Smseidel 	{
931*fc633f11Smseidel 		nUID=getuid();
932*fc633f11Smseidel 	}
933*fc633f11Smseidel 
934*fc633f11Smseidel 	nRet=chown(pszFileName,nUID,nGID);
935*fc633f11Smseidel 	if ( nRet < 0 )
936*fc633f11Smseidel 	{
937*fc633f11Smseidel 		nRet=errno;
938*fc633f11Smseidel 
939*fc633f11Smseidel 		/* mfe: do not return an error here! */
940*fc633f11Smseidel 		/* return oslTranslateFileError(nRet);*/
941*fc633f11Smseidel 	}
942*fc633f11Smseidel 
943*fc633f11Smseidel 	return osl_File_E_None;
944cdf0e10cSrcweir }
945cdf0e10cSrcweir 
946cdf0e10cSrcweir /*****************************************
947cdf0e10cSrcweir  * oslDoCopyLink
948cdf0e10cSrcweir  ****************************************/
949cdf0e10cSrcweir 
oslDoCopyLink(const sal_Char * pszSourceFileName,const sal_Char * pszDestFileName)950cdf0e10cSrcweir static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName)
951cdf0e10cSrcweir {
952*fc633f11Smseidel 	int nRet=0;
953cdf0e10cSrcweir 
954*fc633f11Smseidel 	/* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
955*fc633f11Smseidel 	/* mfe: if source is a link copy the link and not the file it points to (hro says so) */
956*fc633f11Smseidel 	sal_Char pszLinkContent[PATH_MAX];
957cdf0e10cSrcweir 
958*fc633f11Smseidel 	pszLinkContent[0] = '\0';
959cdf0e10cSrcweir 
960*fc633f11Smseidel 	nRet = readlink(pszSourceFileName,pszLinkContent,PATH_MAX-1);
961cdf0e10cSrcweir 
962*fc633f11Smseidel 	if ( nRet < 0 )
963*fc633f11Smseidel 	{
964*fc633f11Smseidel 		nRet=errno;
965*fc633f11Smseidel 		return nRet;
966*fc633f11Smseidel 	}
967cdf0e10cSrcweir 	else
968cdf0e10cSrcweir 		pszLinkContent[ nRet ] = 0;
969cdf0e10cSrcweir 
970*fc633f11Smseidel 	nRet = symlink(pszLinkContent,pszDestFileName);
971cdf0e10cSrcweir 
972*fc633f11Smseidel 	if ( nRet < 0 )
973*fc633f11Smseidel 	{
974*fc633f11Smseidel 		nRet=errno;
975*fc633f11Smseidel 		return nRet;
976*fc633f11Smseidel 	}
977cdf0e10cSrcweir 
978*fc633f11Smseidel 	return 0;
979cdf0e10cSrcweir }
980cdf0e10cSrcweir 
981cdf0e10cSrcweir /*****************************************
982cdf0e10cSrcweir  * oslDoCopyFile
983cdf0e10cSrcweir  ****************************************/
984cdf0e10cSrcweir 
oslDoCopyFile(const sal_Char * pszSourceFileName,const sal_Char * pszDestFileName,size_t nSourceSize,mode_t mode)985cdf0e10cSrcweir static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode)
986*fc633f11Smseidel {
987*fc633f11Smseidel 	int SourceFileFD=0;
988*fc633f11Smseidel 	int DestFileFD=0;
989*fc633f11Smseidel 	int nRet=0;
990*fc633f11Smseidel 
991*fc633f11Smseidel 	SourceFileFD=open(pszSourceFileName,O_RDONLY);
992*fc633f11Smseidel 	if ( SourceFileFD < 0 )
993*fc633f11Smseidel 	{
994*fc633f11Smseidel 		nRet=errno;
995*fc633f11Smseidel 		return nRet;
996*fc633f11Smseidel 	}
997*fc633f11Smseidel 
998*fc633f11Smseidel 	DestFileFD=open(pszDestFileName, O_WRONLY | O_CREAT, mode);
999*fc633f11Smseidel 
1000*fc633f11Smseidel 	if ( DestFileFD < 0 )
1001*fc633f11Smseidel 	{
1002*fc633f11Smseidel 		nRet=errno;
1003*fc633f11Smseidel 		close(SourceFileFD);
1004*fc633f11Smseidel 		return nRet;
1005*fc633f11Smseidel 	}
1006*fc633f11Smseidel 
1007*fc633f11Smseidel 	size_t nWritten = 0;
1008*fc633f11Smseidel 	size_t nRemains = nSourceSize;
1009*fc633f11Smseidel 
1010*fc633f11Smseidel 	if ( nRemains )
1011*fc633f11Smseidel 	{
1012*fc633f11Smseidel 		/* mmap has problems, try the direct streaming */
1013*fc633f11Smseidel 		char pBuffer[0x8000];
1014*fc633f11Smseidel 		size_t nRead = 0;
1015*fc633f11Smseidel 
1016*fc633f11Smseidel 		nRemains = nSourceSize;
1017*fc633f11Smseidel 
1018*fc633f11Smseidel 		do
1019*fc633f11Smseidel 		{
1020*fc633f11Smseidel 			nRead = 0;
1021*fc633f11Smseidel 			nWritten = 0;
1022*fc633f11Smseidel 
1023*fc633f11Smseidel 			size_t nToRead = std::min( (size_t)0x8000, nRemains );
1024*fc633f11Smseidel 			nRead = read( SourceFileFD, pBuffer, nToRead );
1025*fc633f11Smseidel 			if ( (size_t)-1 != nRead )
1026*fc633f11Smseidel 				nWritten = write( DestFileFD, pBuffer, nRead );
1027*fc633f11Smseidel 
1028*fc633f11Smseidel 			if ( (size_t)-1 != nWritten )
1029*fc633f11Smseidel 				nRemains -= nWritten;
1030*fc633f11Smseidel 		}
1031*fc633f11Smseidel 		while( nRemains && (size_t)-1 != nRead && nRead == nWritten );
1032*fc633f11Smseidel 	}
1033*fc633f11Smseidel 
1034*fc633f11Smseidel 	if ( nRemains )
1035*fc633f11Smseidel 	{
1036*fc633f11Smseidel 		if ( errno )
1037*fc633f11Smseidel 			nRet = errno;
1038*fc633f11Smseidel 		else
1039*fc633f11Smseidel 			nRet = ENOSPC;
1040*fc633f11Smseidel 	}
1041*fc633f11Smseidel 
1042*fc633f11Smseidel 	close( SourceFileFD );
1043*fc633f11Smseidel 	if ( close( DestFileFD ) == -1 && nRet == 0 )
1044*fc633f11Smseidel 		nRet = errno;
1045*fc633f11Smseidel 
1046*fc633f11Smseidel 	return nRet;
1047cdf0e10cSrcweir }
1048cdf0e10cSrcweir 
1049