1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "osl/file.hxx"
21 #include "osl/detail/file.h"
23 #include "osl/diagnose.h"
24 #include "osl/thread.h"
25 #include <osl/signal.h>
26 #include "rtl/alloc.h"
29 #include "file_impl.hxx"
30 #include "file_error_transl.h"
31 #include "file_path_helper.hxx"
33 #include "uunxapi.hxx"
34 #include "readwrite_helper.h"
36 #include <sys/types.h>
49 #include <osl/detail/android-bootstrap.h>
52 /************************************************************************
55 * - Fix: check for corresponding struct sizes in exported functions
56 * - check size/use of oslDirectory
57 * - check size/use of oslDirectoryItem
58 ***********************************************************************/
59 /******************************************************************************
61 * Data Type Definition
63 ******************************************************************************/
67 rtl_uString
* ustrPath
; /* holds native directory path */
76 lo_apk_dir
* pApkDirStruct
;
80 DirectoryItem_Impl::DirectoryItem_Impl(
81 rtl_uString
* ustrFilePath
, unsigned char DType
)
83 m_ustrFilePath (ustrFilePath
),
86 if (m_ustrFilePath
!= 0)
87 rtl_uString_acquire(m_ustrFilePath
);
89 DirectoryItem_Impl::~DirectoryItem_Impl()
91 if (m_ustrFilePath
!= 0)
92 rtl_uString_release(m_ustrFilePath
);
95 void * DirectoryItem_Impl::operator new(size_t n
)
97 return rtl_allocateMemory(n
);
99 void DirectoryItem_Impl::operator delete(void * p
)
104 void DirectoryItem_Impl::acquire()
108 void DirectoryItem_Impl::release()
110 if (0 == --m_RefCount
)
114 oslFileType
DirectoryItem_Impl::getFileType() const
118 #ifdef _DIRENT_HAVE_D_TYPE
120 return osl_File_Type_Link
;
122 return osl_File_Type_Directory
;
124 return osl_File_Type_Regular
;
126 return osl_File_Type_Fifo
;
128 return osl_File_Type_Socket
;
131 return osl_File_Type_Special
;
132 #endif /* _DIRENT_HAVE_D_TYPE */
136 return osl_File_Type_Unknown
;
139 /******************************************************************************
141 * C-String Function Declarations
143 *****************************************************************************/
145 static oslFileError
osl_psz_createDirectory(const sal_Char
* pszPath
);
146 static oslFileError
osl_psz_removeDirectory(const sal_Char
* pszPath
);
148 /*******************************************************************
150 ******************************************************************/
152 oslFileError SAL_CALL
osl_openDirectory(rtl_uString
* ustrDirectoryURL
, oslDirectory
* pDirectory
)
154 rtl_uString
* ustrSystemPath
= NULL
;
159 if ((0 == ustrDirectoryURL
) || (0 == ustrDirectoryURL
->length
) || (0 == pDirectory
))
160 return osl_File_E_INVAL
;
162 /* convert file URL to system path */
163 eRet
= osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL
, &ustrSystemPath
, sal_False
);
165 if( osl_File_E_None
!= eRet
)
168 osl_systemPathRemoveSeparator(ustrSystemPath
);
170 /* convert unicode path to text */
171 if ( UnicodeToText( path
, PATH_MAX
, ustrSystemPath
->buffer
, ustrSystemPath
->length
)
173 && macxp_resolveAlias( path
, PATH_MAX
) == 0
178 if( strncmp( path
, "/assets/", sizeof( "/assets/" ) - 1) == 0 )
180 lo_apk_dir
*pdir
= lo_apk_opendir( path
);
184 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*) rtl_allocateMemory( sizeof(oslDirectoryImpl
) );
188 pDirImpl
->eKind
= oslDirectoryImpl::KIND_ASSETS
;
189 pDirImpl
->pApkDirStruct
= pdir
;
190 pDirImpl
->ustrPath
= ustrSystemPath
;
192 *pDirectory
= (oslDirectory
) pDirImpl
;
193 return osl_File_E_None
;
198 lo_apk_closedir( pdir
);
206 DIR *pdir
= opendir( path
);
210 /* create and initialize impl structure */
211 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*) rtl_allocateMemory( sizeof(oslDirectoryImpl
) );
215 pDirImpl
->pDirStruct
= pdir
;
216 pDirImpl
->ustrPath
= ustrSystemPath
;
218 pDirImpl
->eKind
= oslDirectoryImpl::KIND_DIRENT
;
220 *pDirectory
= (oslDirectory
) pDirImpl
;
221 return osl_File_E_None
;
231 #ifdef DEBUG_OSL_FILE
232 perror ("osl_openDirectory"); fprintf (stderr
, path
);
238 rtl_uString_release( ustrSystemPath
);
240 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
243 /****************************************************************************/
244 /* osl_closeDirectory */
245 /****************************************************************************/
247 oslFileError SAL_CALL
osl_closeDirectory( oslDirectory Directory
)
249 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*) Directory
;
250 oslFileError err
= osl_File_E_None
;
252 OSL_ASSERT( Directory
);
254 if( NULL
== pDirImpl
)
255 return osl_File_E_INVAL
;
258 if( pDirImpl
->eKind
== oslDirectoryImpl::KIND_ASSETS
)
260 if (lo_apk_closedir( pDirImpl
->pApkDirStruct
))
266 if( closedir( pDirImpl
->pDirStruct
) )
267 err
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
270 /* cleanup members */
271 rtl_uString_release( pDirImpl
->ustrPath
);
273 rtl_freeMemory( pDirImpl
);
278 /**********************************************
281 * readdir wrapper, filters out "." and ".."
283 *********************************************/
285 static struct dirent
* osl_readdir_impl_(DIR* pdir
, sal_Bool bFilterLocalAndParentDir
)
287 struct dirent
* pdirent
;
289 while ((pdirent
= readdir(pdir
)) != NULL
)
291 if (bFilterLocalAndParentDir
&&
292 ((0 == strcmp(pdirent
->d_name
, ".")) || (0 == strcmp(pdirent
->d_name
, ".."))))
301 /****************************************************************************
302 * osl_getNextDirectoryItem
303 ***************************************************************************/
305 oslFileError SAL_CALL
osl_getNextDirectoryItem(oslDirectory Directory
, oslDirectoryItem
* pItem
, SAL_UNUSED_PARAMETER sal_uInt32
/*uHint*/)
307 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*)Directory
;
308 rtl_uString
* ustrFileName
= NULL
;
309 rtl_uString
* ustrFilePath
= NULL
;
310 struct dirent
* pEntry
;
312 OSL_ASSERT(Directory
);
315 if ((NULL
== Directory
) || (NULL
== pItem
))
316 return osl_File_E_INVAL
;
319 if( pDirImpl
->eKind
== oslDirectoryImpl::KIND_ASSETS
)
321 pEntry
= lo_apk_readdir(pDirImpl
->pApkDirStruct
);
326 pEntry
= osl_readdir_impl_(pDirImpl
->pDirStruct
, sal_True
);
330 return osl_File_E_NOENT
;
335 // convert decomposed filename to precomposed unicode
336 char composed_name
[BUFSIZ
];
337 CFMutableStringRef strRef
= CFStringCreateMutable (NULL
, 0 );
338 CFStringAppendCString( strRef
, pEntry
->d_name
, kCFStringEncodingUTF8
); //UTF8 is default on Mac OSX
339 CFStringNormalize( strRef
, kCFStringNormalizationFormC
);
340 CFStringGetCString( strRef
, composed_name
, BUFSIZ
, kCFStringEncodingUTF8
);
342 rtl_string2UString( &ustrFileName
, composed_name
, strlen( composed_name
),
343 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
346 /* convert file name to unicode */
347 rtl_string2UString( &ustrFileName
, pEntry
->d_name
, strlen( pEntry
->d_name
),
348 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
349 OSL_ASSERT(ustrFileName
!= 0);
353 osl_systemPathMakeAbsolutePath(pDirImpl
->ustrPath
, ustrFileName
, &ustrFilePath
);
354 rtl_uString_release( ustrFileName
);
356 DirectoryItem_Impl
* pImpl
= static_cast< DirectoryItem_Impl
* >(*pItem
);
359 pImpl
->release(), pImpl
= 0;
361 #ifdef _DIRENT_HAVE_D_TYPE
362 pImpl
= new DirectoryItem_Impl(ustrFilePath
, pEntry
->d_type
);
364 pImpl
= new DirectoryItem_Impl(ustrFilePath
);
365 #endif /* _DIRENT_HAVE_D_TYPE */
367 rtl_uString_release( ustrFilePath
);
369 return osl_File_E_None
;
372 /****************************************************************************/
373 /* osl_getDirectoryItem */
374 /****************************************************************************/
376 oslFileError SAL_CALL
osl_getDirectoryItem( rtl_uString
* ustrFileURL
, oslDirectoryItem
* pItem
)
378 rtl_uString
* ustrSystemPath
= NULL
;
379 oslFileError osl_error
= osl_File_E_INVAL
;
381 OSL_ASSERT((0 != ustrFileURL
) && (0 != pItem
));
382 if ((0 == ustrFileURL
) || (0 == ustrFileURL
->length
) || (0 == pItem
))
383 return osl_File_E_INVAL
;
385 osl_error
= osl_getSystemPathFromFileURL_Ex(ustrFileURL
, &ustrSystemPath
, sal_False
);
386 if (osl_File_E_None
!= osl_error
)
389 osl_systemPathRemoveSeparator(ustrSystemPath
);
391 if (-1 == access_u(ustrSystemPath
, F_OK
))
393 osl_error
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
397 *pItem
= new DirectoryItem_Impl(ustrSystemPath
);
399 rtl_uString_release(ustrSystemPath
);
405 /****************************************************************************/
406 /* osl_acquireDirectoryItem */
407 /****************************************************************************/
409 oslFileError SAL_CALL
osl_acquireDirectoryItem( oslDirectoryItem Item
)
411 DirectoryItem_Impl
* pImpl
= static_cast< DirectoryItem_Impl
* >(Item
);
413 return osl_File_E_INVAL
;
416 return osl_File_E_None
;
419 /****************************************************************************/
420 /* osl_releaseDirectoryItem */
421 /****************************************************************************/
423 oslFileError SAL_CALL
osl_releaseDirectoryItem( oslDirectoryItem Item
)
425 DirectoryItem_Impl
* pImpl
= static_cast< DirectoryItem_Impl
* >(Item
);
427 return osl_File_E_INVAL
;
430 return osl_File_E_None
;
433 /****************************************************************************/
434 /* osl_createDirectory */
435 /****************************************************************************/
437 oslFileError SAL_CALL
osl_createDirectory( rtl_uString
* ustrDirectoryURL
)
442 OSL_ASSERT( ustrDirectoryURL
);
444 /* convert directory url to system path */
445 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
446 if( eRet
!= osl_File_E_None
)
450 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
451 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
454 return osl_psz_createDirectory( path
);
457 /****************************************************************************/
458 /* osl_removeDirectory */
459 /****************************************************************************/
461 oslFileError SAL_CALL
osl_removeDirectory( rtl_uString
* ustrDirectoryURL
)
466 OSL_ASSERT( ustrDirectoryURL
);
468 /* convert directory url to system path */
469 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
470 if( eRet
!= osl_File_E_None
)
474 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
475 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
478 return osl_psz_removeDirectory( path
);
481 /*****************************************
482 * osl_psz_createDirectory
483 ****************************************/
485 static oslFileError
osl_psz_createDirectory( const sal_Char
* pszPath
)
488 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
490 nRet
= mkdir(pszPath
,mode
);
495 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
498 return osl_File_E_None
;
501 /*****************************************
502 * osl_psz_removeDirectory
503 ****************************************/
505 static oslFileError
osl_psz_removeDirectory( const sal_Char
* pszPath
)
509 nRet
= rmdir(pszPath
);
514 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
517 return osl_File_E_None
;
520 /****************************************************************************/
521 /* osl_createDirectoryPath */
522 /****************************************************************************/
524 static int path_make_parent(sal_Unicode
* path
)
526 int i
= rtl_ustr_lastIndexOfChar(path
, '/');
537 static int create_dir_with_callback(
538 sal_Unicode
* directory_path
,
539 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
542 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
544 if (osl::mkdir(directory_path
, mode
) == 0)
546 if (aDirectoryCreationCallbackFunc
)
549 osl::FileBase::getFileURLFromSystemPath(directory_path
, url
);
550 aDirectoryCreationCallbackFunc(pData
, url
.pData
);
557 static oslFileError
create_dir_recursively_(
558 sal_Unicode
* dir_path
,
559 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
562 OSL_PRECOND((rtl_ustr_getLength(dir_path
) > 0) && ((dir_path
+ (rtl_ustr_getLength(dir_path
) - 1)) != (dir_path
+ rtl_ustr_lastIndexOfChar(dir_path
, '/'))), \
563 "Path must not end with a slash");
565 int native_err
= create_dir_with_callback(
566 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
569 return osl_File_E_None
;
571 if (native_err
!= ENOENT
)
572 return oslTranslateFileError(OSL_FET_ERROR
, native_err
);
574 // we step back until '/a_dir' at maximum because
575 // we should get an error unequal ENOENT when
576 // we try to create 'a_dir' at '/' and would so
578 int pos
= path_make_parent(dir_path
);
580 oslFileError osl_error
= create_dir_recursively_(
581 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
583 if (osl_File_E_None
!= osl_error
)
588 return create_dir_recursively_(dir_path
, aDirectoryCreationCallbackFunc
, pData
);
591 oslFileError SAL_CALL
osl_createDirectoryPath(
592 rtl_uString
* aDirectoryUrl
,
593 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
596 if (aDirectoryUrl
== NULL
)
597 return osl_File_E_INVAL
;
599 rtl::OUString sys_path
;
600 oslFileError osl_error
= osl_getSystemPathFromFileURL_Ex(
601 aDirectoryUrl
, &sys_path
.pData
, sal_False
);
603 if (osl_error
!= osl_File_E_None
)
606 osl::systemPathRemoveSeparator(sys_path
);
608 // const_cast because sys_path is a local copy which we want to modify inplace instead of
609 // coyp it into another buffer on the heap again
610 return create_dir_recursively_(sys_path
.pData
->buffer
, aDirectoryCreationCallbackFunc
, pData
);
613 /******************************************************************************
615 * C-String Function Declarations
617 *****************************************************************************/
619 static oslFileError
osl_psz_removeFile(const sal_Char
* pszPath
);
620 static oslFileError
osl_psz_copyFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
621 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
624 /******************************************************************************
626 * Static Module Utility Function Declarations
628 *****************************************************************************/
630 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
);
631 static oslFileError
oslChangeFileModes(const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
);
632 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
);
633 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
);
634 static oslFileError
oslDoMoveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
636 /****************************************************************************/
638 /****************************************************************************/
640 oslFileError SAL_CALL
osl_moveFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
642 char srcPath
[PATH_MAX
];
643 char destPath
[PATH_MAX
];
646 OSL_ASSERT( ustrFileURL
);
647 OSL_ASSERT( ustrDestURL
);
649 /* convert source url to system path */
650 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
651 if( eRet
!= osl_File_E_None
)
654 /* convert destination url to system path */
655 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
656 if( eRet
!= osl_File_E_None
)
660 if ( macxp_resolveAlias( srcPath
, PATH_MAX
) != 0 || macxp_resolveAlias( destPath
, PATH_MAX
) != 0 )
661 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
664 return oslDoMoveFile( srcPath
, destPath
);
667 /****************************************************************************/
669 /****************************************************************************/
671 oslFileError SAL_CALL
osl_copyFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
673 char srcPath
[PATH_MAX
];
674 char destPath
[PATH_MAX
];
677 OSL_ASSERT( ustrFileURL
);
678 OSL_ASSERT( ustrDestURL
);
680 /* convert source url to system path */
681 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
682 if( eRet
!= osl_File_E_None
)
685 /* convert destination url to system path */
686 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
687 if( eRet
!= osl_File_E_None
)
691 if ( macxp_resolveAlias( srcPath
, PATH_MAX
) != 0 || macxp_resolveAlias( destPath
, PATH_MAX
) != 0 )
692 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
695 return osl_psz_copyFile( srcPath
, destPath
);
698 /****************************************************************************/
700 /****************************************************************************/
702 oslFileError SAL_CALL
osl_removeFile( rtl_uString
* ustrFileURL
)
707 OSL_ASSERT( ustrFileURL
);
709 /* convert file url to system path */
710 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
711 if( eRet
!= osl_File_E_None
)
715 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
716 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
719 return osl_psz_removeFile( path
);
722 /******************************************************************************
726 *****************************************************************************/
728 /*****************************************
730 ****************************************/
732 static oslFileError
oslDoMoveFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
734 oslFileError tErr
= osl_psz_moveFile(pszPath
,pszDestPath
);
735 if ( tErr
== osl_File_E_None
)
740 if ( tErr
!= osl_File_E_XDEV
)
745 tErr
=osl_psz_copyFile(pszPath
,pszDestPath
);
747 if ( tErr
!= osl_File_E_None
)
749 osl_psz_removeFile(pszDestPath
);
753 tErr
=osl_psz_removeFile(pszPath
);
758 /*****************************************
760 ****************************************/
761 static oslFileError
osl_psz_removeFile( const sal_Char
* pszPath
)
766 nRet
= lstat_c(pszPath
,&aStat
);
770 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
773 if ( S_ISDIR(aStat
.st_mode
) )
775 return osl_File_E_ISDIR
;
778 nRet
= unlink(pszPath
);
782 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
785 return osl_File_E_None
;
788 /*****************************************
790 ****************************************/
792 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
797 nRet
= rename(pszPath
,pszDestPath
);
802 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
805 return osl_File_E_None
;
808 /*****************************************
810 ****************************************/
812 static oslFileError
osl_psz_copyFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
820 struct stat aFileStat
;
821 oslFileError tErr
=osl_File_E_invalidError
;
822 size_t nSourceSize
=0;
823 int DestFileExists
=1;
825 /* mfe: does the source file really exists? */
826 nRet
= lstat_c(pszPath
,&aFileStat
);
831 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
834 /* mfe: we do only copy files here! */
835 if ( S_ISDIR(aFileStat
.st_mode
) )
837 return osl_File_E_ISDIR
;
840 nSourceSize
=(size_t)aFileStat
.st_size
;
841 nMode
=aFileStat
.st_mode
;
842 nAcTime
=aFileStat
.st_atime
;
843 nModTime
=aFileStat
.st_mtime
;
844 nUID
=aFileStat
.st_uid
;
845 nGID
=aFileStat
.st_gid
;
847 nRet
= stat(pszDestPath
,&aFileStat
);
852 if ( nRet
== ENOENT
)
856 /* return oslTranslateFileError(nRet);*/
859 /* mfe: the destination file must not be a directory! */
860 if ( nRet
== 0 && S_ISDIR(aFileStat
.st_mode
) )
862 return osl_File_E_ISDIR
;
866 /* mfe: file does not exists or is no dir */
869 tErr
= oslDoCopy(pszPath
,pszDestPath
,nMode
,nSourceSize
,DestFileExists
);
871 if ( tErr
!= osl_File_E_None
)
877 * mfe: ignore return code
878 * since only the success of the copy is
881 oslChangeFileModes(pszDestPath
,nMode
,nAcTime
,nModTime
,nUID
,nGID
);
887 /******************************************************************************
891 *****************************************************************************/
893 /*****************************************
895 ****************************************/
897 #define TMP_DEST_FILE_EXTENSION ".osl-tmp"
899 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
)
902 sal_Char pszTmpDestFile
[PATH_MAX
];
903 size_t size_tmp_dest_buff
= sizeof(pszTmpDestFile
);
905 /* Quick fix for #106048, the whole copy file function seems
906 to be erroneous anyway and needs to be rewritten.
908 memset(pszTmpDestFile
, 0, size_tmp_dest_buff
);
910 if ( DestFileExists
)
912 strncpy(pszTmpDestFile
, pszDestFileName
, size_tmp_dest_buff
- 1);
914 if ((strlen(pszTmpDestFile
) + strlen(TMP_DEST_FILE_EXTENSION
)) >= size_tmp_dest_buff
)
915 return osl_File_E_NAMETOOLONG
;
917 strncat(pszTmpDestFile
, TMP_DEST_FILE_EXTENSION
, strlen(TMP_DEST_FILE_EXTENSION
));
919 /* FIXME: what if pszTmpDestFile already exists? */
920 /* with getcanonical??? */
921 nRet
=rename(pszDestFileName
,pszTmpDestFile
);
924 /* mfe: should be S_ISREG */
925 if ( !S_ISLNK(nMode
) )
927 /* copy SourceFile to DestFile */
928 nRet
= oslDoCopyFile(pszSourceFileName
,pszDestFileName
,nSourceSize
, nMode
);
930 /* mfe: OK redundant at the moment */
931 else if ( S_ISLNK(nMode
) )
933 nRet
= oslDoCopyLink(pszSourceFileName
,pszDestFileName
);
937 /* mfe: what to do here? */
941 if ( nRet
> 0 && DestFileExists
== 1 )
943 unlink(pszDestFileName
);
944 rename(pszTmpDestFile
,pszDestFileName
);
949 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
952 if ( DestFileExists
== 1 )
954 unlink(pszTmpDestFile
);
957 return osl_File_E_None
;
960 /*****************************************
962 ****************************************/
964 static oslFileError
oslChangeFileModes( const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
)
967 struct utimbuf aTimeBuffer
;
969 nRet
= chmod(pszFileName
,nMode
);
973 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
976 aTimeBuffer
.actime
=nAcTime
;
977 aTimeBuffer
.modtime
=nModTime
;
978 nRet
=utime(pszFileName
,&aTimeBuffer
);
982 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
985 if ( nUID
!= getuid() )
990 nRet
=chown(pszFileName
,nUID
,nGID
);
995 /* mfe: do not return an error here! */
996 /* return oslTranslateFileError(nRet);*/
999 return osl_File_E_None
;
1002 /*****************************************
1004 ****************************************/
1006 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
)
1010 /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
1011 /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
1012 sal_Char pszLinkContent
[PATH_MAX
+1];
1014 pszLinkContent
[0] = '\0';
1016 nRet
= readlink(pszSourceFileName
,pszLinkContent
,PATH_MAX
);
1024 pszLinkContent
[ nRet
] = 0;
1026 nRet
= symlink(pszLinkContent
,pszDestFileName
);
1037 /*****************************************
1039 ****************************************/
1041 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
)
1043 oslFileHandle SourceFileFH
=0;
1047 if (osl_openFilePath(pszSourceFileName
,
1049 osl_File_OpenFlag_Read
|osl_File_OpenFlag_NoLock
|osl_File_OpenFlag_NoExcl
) != osl_File_E_None
)
1051 // Let's hope errno is still set relevantly after osl_openFilePath...
1056 DestFileFD
=open(pszDestFileName
, O_WRONLY
| O_CREAT
, mode
);
1058 if ( DestFileFD
< 0 )
1061 osl_closeFile(SourceFileFH
);
1065 size_t nRemains
= nSourceSize
;
1069 /* mmap has problems, try the direct streaming */
1070 char pBuffer
[0x7FFF];
1074 size_t nToRead
= std::min( sizeof(pBuffer
), nRemains
);
1077 if ( osl_readFile( SourceFileFH
, pBuffer
, nToRead
, &nRead
) != osl_File_E_None
|| nRead
> nToRead
|| nRead
== 0 )
1080 succeeded
= safeWrite( DestFileFD
, pBuffer
, nRead
);
1084 // We know nRead <= nToRead, so it must fit in a size_t
1085 nRemains
-= (size_t) nRead
;
1098 osl_closeFile( SourceFileFH
);
1099 if ( close( DestFileFD
) == -1 && nRet
== 0 )
1105 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */