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