1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "osl/file.hxx"
30 #include "osl/detail/file.h"
32 #include "osl/diagnose.h"
33 #include "osl/thread.h"
34 #include <osl/signal.h>
35 #include "rtl/alloc.h"
38 #include "file_impl.hxx"
39 #include "file_error_transl.h"
40 #include "file_path_helper.hxx"
42 #include "uunxapi.hxx"
43 #include "readwrite_helper.h"
45 #include <sys/types.h>
58 #include <osl/detail/android-bootstrap.h>
61 /************************************************************************
64 * - Fix: check for corresponding struct sizes in exported functions
65 * - check size/use of oslDirectory
66 * - check size/use of oslDirectoryItem
67 ***********************************************************************/
68 /******************************************************************************
70 * Data Type Definition
72 ******************************************************************************/
76 rtl_uString
* ustrPath
; /* holds native directory path */
85 lo_apk_dir
* pApkDirStruct
;
89 DirectoryItem_Impl::DirectoryItem_Impl(
90 rtl_uString
* ustrFilePath
, unsigned char DType
)
92 m_ustrFilePath (ustrFilePath
),
95 if (m_ustrFilePath
!= 0)
96 rtl_uString_acquire(m_ustrFilePath
);
98 DirectoryItem_Impl::~DirectoryItem_Impl()
100 if (m_ustrFilePath
!= 0)
101 rtl_uString_release(m_ustrFilePath
);
104 void * DirectoryItem_Impl::operator new(size_t n
)
106 return rtl_allocateMemory(n
);
108 void DirectoryItem_Impl::operator delete(void * p
)
113 void DirectoryItem_Impl::acquire()
117 void DirectoryItem_Impl::release()
119 if (0 == --m_RefCount
)
123 oslFileType
DirectoryItem_Impl::getFileType() const
127 #ifdef _DIRENT_HAVE_D_TYPE
129 return osl_File_Type_Link
;
131 return osl_File_Type_Directory
;
133 return osl_File_Type_Regular
;
135 return osl_File_Type_Fifo
;
137 return osl_File_Type_Socket
;
140 return osl_File_Type_Special
;
141 #endif /* _DIRENT_HAVE_D_TYPE */
145 return osl_File_Type_Unknown
;
148 /******************************************************************************
150 * C-String Function Declarations
152 *****************************************************************************/
154 static oslFileError
osl_psz_createDirectory(const sal_Char
* pszPath
);
155 static oslFileError
osl_psz_removeDirectory(const sal_Char
* pszPath
);
157 /*******************************************************************
159 ******************************************************************/
161 oslFileError SAL_CALL
osl_openDirectory(rtl_uString
* ustrDirectoryURL
, oslDirectory
* pDirectory
)
163 rtl_uString
* ustrSystemPath
= NULL
;
168 if ((0 == ustrDirectoryURL
) || (0 == ustrDirectoryURL
->length
) || (0 == pDirectory
))
169 return osl_File_E_INVAL
;
171 /* convert file URL to system path */
172 eRet
= osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL
, &ustrSystemPath
, sal_False
);
174 if( osl_File_E_None
!= eRet
)
177 osl_systemPathRemoveSeparator(ustrSystemPath
);
179 /* convert unicode path to text */
180 if ( UnicodeToText( path
, PATH_MAX
, ustrSystemPath
->buffer
, ustrSystemPath
->length
)
182 && macxp_resolveAlias( path
, PATH_MAX
) == 0
187 if( strncmp( path
, "/assets/", sizeof( "/assets/" ) - 1) == 0 )
189 lo_apk_dir
*pdir
= lo_apk_opendir( path
);
193 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*) rtl_allocateMemory( sizeof(oslDirectoryImpl
) );
197 pDirImpl
->eKind
= oslDirectoryImpl::KIND_ASSETS
;
198 pDirImpl
->pApkDirStruct
= pdir
;
199 pDirImpl
->ustrPath
= ustrSystemPath
;
201 *pDirectory
= (oslDirectory
) pDirImpl
;
202 return osl_File_E_None
;
207 lo_apk_closedir( pdir
);
215 DIR *pdir
= opendir( path
);
219 /* create and initialize impl structure */
220 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*) rtl_allocateMemory( sizeof(oslDirectoryImpl
) );
224 pDirImpl
->pDirStruct
= pdir
;
225 pDirImpl
->ustrPath
= ustrSystemPath
;
227 pDirImpl
->eKind
= oslDirectoryImpl::KIND_DIRENT
;
229 *pDirectory
= (oslDirectory
) pDirImpl
;
230 return osl_File_E_None
;
240 #ifdef DEBUG_OSL_FILE
241 perror ("osl_openDirectory"); fprintf (stderr
, path
);
247 rtl_uString_release( ustrSystemPath
);
249 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
252 /****************************************************************************/
253 /* osl_closeDirectory */
254 /****************************************************************************/
256 oslFileError SAL_CALL
osl_closeDirectory( oslDirectory Directory
)
258 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*) Directory
;
259 oslFileError err
= osl_File_E_None
;
261 OSL_ASSERT( Directory
);
263 if( NULL
== pDirImpl
)
264 return osl_File_E_INVAL
;
267 if( pDirImpl
->eKind
== oslDirectoryImpl::KIND_ASSETS
)
269 if (lo_apk_closedir( pDirImpl
->pApkDirStruct
))
275 if( closedir( pDirImpl
->pDirStruct
) )
276 err
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
279 /* cleanup members */
280 rtl_uString_release( pDirImpl
->ustrPath
);
282 rtl_freeMemory( pDirImpl
);
287 /**********************************************
290 * readdir wrapper, filters out "." and ".."
292 *********************************************/
294 static struct dirent
* osl_readdir_impl_(DIR* pdir
, sal_Bool bFilterLocalAndParentDir
)
296 struct dirent
* pdirent
;
298 while ((pdirent
= readdir(pdir
)) != NULL
)
300 if (bFilterLocalAndParentDir
&&
301 ((0 == strcmp(pdirent
->d_name
, ".")) || (0 == strcmp(pdirent
->d_name
, ".."))))
310 /****************************************************************************
311 * osl_getNextDirectoryItem
312 ***************************************************************************/
314 oslFileError SAL_CALL
osl_getNextDirectoryItem(oslDirectory Directory
, oslDirectoryItem
* pItem
, SAL_UNUSED_PARAMETER sal_uInt32
/*uHint*/)
316 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*)Directory
;
317 rtl_uString
* ustrFileName
= NULL
;
318 rtl_uString
* ustrFilePath
= NULL
;
319 struct dirent
* pEntry
;
321 OSL_ASSERT(Directory
);
324 if ((NULL
== Directory
) || (NULL
== pItem
))
325 return osl_File_E_INVAL
;
328 if( pDirImpl
->eKind
== oslDirectoryImpl::KIND_ASSETS
)
330 pEntry
= lo_apk_readdir(pDirImpl
->pApkDirStruct
);
335 pEntry
= osl_readdir_impl_(pDirImpl
->pDirStruct
, sal_True
);
339 return osl_File_E_NOENT
;
344 // convert decomposed filename to precomposed unicode
345 char composed_name
[BUFSIZ
];
346 CFMutableStringRef strRef
= CFStringCreateMutable (NULL
, 0 );
347 CFStringAppendCString( strRef
, pEntry
->d_name
, kCFStringEncodingUTF8
); //UTF8 is default on Mac OSX
348 CFStringNormalize( strRef
, kCFStringNormalizationFormC
);
349 CFStringGetCString( strRef
, composed_name
, BUFSIZ
, kCFStringEncodingUTF8
);
351 rtl_string2UString( &ustrFileName
, composed_name
, strlen( composed_name
),
352 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
355 /* convert file name to unicode */
356 rtl_string2UString( &ustrFileName
, pEntry
->d_name
, strlen( pEntry
->d_name
),
357 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
358 OSL_ASSERT(ustrFileName
!= 0);
362 osl_systemPathMakeAbsolutePath(pDirImpl
->ustrPath
, ustrFileName
, &ustrFilePath
);
363 rtl_uString_release( ustrFileName
);
365 DirectoryItem_Impl
* pImpl
= static_cast< DirectoryItem_Impl
* >(*pItem
);
368 pImpl
->release(), pImpl
= 0;
370 #ifdef _DIRENT_HAVE_D_TYPE
371 pImpl
= new DirectoryItem_Impl(ustrFilePath
, pEntry
->d_type
);
373 pImpl
= new DirectoryItem_Impl(ustrFilePath
);
374 #endif /* _DIRENT_HAVE_D_TYPE */
376 rtl_uString_release( ustrFilePath
);
378 return osl_File_E_None
;
381 /****************************************************************************/
382 /* osl_getDirectoryItem */
383 /****************************************************************************/
385 oslFileError SAL_CALL
osl_getDirectoryItem( rtl_uString
* ustrFileURL
, oslDirectoryItem
* pItem
)
387 rtl_uString
* ustrSystemPath
= NULL
;
388 oslFileError osl_error
= osl_File_E_INVAL
;
390 OSL_ASSERT((0 != ustrFileURL
) && (0 != pItem
));
391 if ((0 == ustrFileURL
) || (0 == ustrFileURL
->length
) || (0 == pItem
))
392 return osl_File_E_INVAL
;
394 osl_error
= osl_getSystemPathFromFileURL_Ex(ustrFileURL
, &ustrSystemPath
, sal_False
);
395 if (osl_File_E_None
!= osl_error
)
398 osl_systemPathRemoveSeparator(ustrSystemPath
);
400 if (-1 == access_u(ustrSystemPath
, F_OK
))
402 osl_error
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
406 *pItem
= new DirectoryItem_Impl(ustrSystemPath
);
408 rtl_uString_release(ustrSystemPath
);
414 /****************************************************************************/
415 /* osl_acquireDirectoryItem */
416 /****************************************************************************/
418 oslFileError SAL_CALL
osl_acquireDirectoryItem( oslDirectoryItem Item
)
420 DirectoryItem_Impl
* pImpl
= static_cast< DirectoryItem_Impl
* >(Item
);
422 return osl_File_E_INVAL
;
425 return osl_File_E_None
;
428 /****************************************************************************/
429 /* osl_releaseDirectoryItem */
430 /****************************************************************************/
432 oslFileError SAL_CALL
osl_releaseDirectoryItem( oslDirectoryItem Item
)
434 DirectoryItem_Impl
* pImpl
= static_cast< DirectoryItem_Impl
* >(Item
);
436 return osl_File_E_INVAL
;
439 return osl_File_E_None
;
442 /****************************************************************************/
443 /* osl_createDirectory */
444 /****************************************************************************/
446 oslFileError SAL_CALL
osl_createDirectory( rtl_uString
* ustrDirectoryURL
)
451 OSL_ASSERT( ustrDirectoryURL
);
453 /* convert directory url to system path */
454 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
455 if( eRet
!= osl_File_E_None
)
459 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
460 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
463 return osl_psz_createDirectory( path
);
466 /****************************************************************************/
467 /* osl_removeDirectory */
468 /****************************************************************************/
470 oslFileError SAL_CALL
osl_removeDirectory( rtl_uString
* ustrDirectoryURL
)
475 OSL_ASSERT( ustrDirectoryURL
);
477 /* convert directory url to system path */
478 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
479 if( eRet
!= osl_File_E_None
)
483 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
484 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
487 return osl_psz_removeDirectory( path
);
490 /*****************************************
491 * osl_psz_createDirectory
492 ****************************************/
494 static oslFileError
osl_psz_createDirectory( const sal_Char
* pszPath
)
497 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
499 nRet
= mkdir(pszPath
,mode
);
504 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
507 return osl_File_E_None
;
510 /*****************************************
511 * osl_psz_removeDirectory
512 ****************************************/
514 static oslFileError
osl_psz_removeDirectory( const sal_Char
* pszPath
)
518 nRet
= rmdir(pszPath
);
523 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
526 return osl_File_E_None
;
529 /****************************************************************************/
530 /* osl_createDirectoryPath */
531 /****************************************************************************/
533 static int path_make_parent(sal_Unicode
* path
)
535 int i
= rtl_ustr_lastIndexOfChar(path
, '/');
546 static int create_dir_with_callback(
547 sal_Unicode
* directory_path
,
548 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
551 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
553 if (osl::mkdir(directory_path
, mode
) == 0)
555 if (aDirectoryCreationCallbackFunc
)
558 osl::FileBase::getFileURLFromSystemPath(directory_path
, url
);
559 aDirectoryCreationCallbackFunc(pData
, url
.pData
);
566 static oslFileError
create_dir_recursively_(
567 sal_Unicode
* dir_path
,
568 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
571 OSL_PRECOND((rtl_ustr_getLength(dir_path
) > 0) && ((dir_path
+ (rtl_ustr_getLength(dir_path
) - 1)) != (dir_path
+ rtl_ustr_lastIndexOfChar(dir_path
, '/'))), \
572 "Path must not end with a slash");
574 int native_err
= create_dir_with_callback(
575 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
578 return osl_File_E_None
;
580 if (native_err
!= ENOENT
)
581 return oslTranslateFileError(OSL_FET_ERROR
, native_err
);
583 // we step back until '/a_dir' at maximum because
584 // we should get an error unequal ENOENT when
585 // we try to create 'a_dir' at '/' and would so
587 int pos
= path_make_parent(dir_path
);
589 oslFileError osl_error
= create_dir_recursively_(
590 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
592 if (osl_File_E_None
!= osl_error
)
597 return create_dir_recursively_(dir_path
, aDirectoryCreationCallbackFunc
, pData
);
600 oslFileError SAL_CALL
osl_createDirectoryPath(
601 rtl_uString
* aDirectoryUrl
,
602 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
605 if (aDirectoryUrl
== NULL
)
606 return osl_File_E_INVAL
;
608 rtl::OUString sys_path
;
609 oslFileError osl_error
= osl_getSystemPathFromFileURL_Ex(
610 aDirectoryUrl
, &sys_path
.pData
, sal_False
);
612 if (osl_error
!= osl_File_E_None
)
615 osl::systemPathRemoveSeparator(sys_path
);
617 // const_cast because sys_path is a local copy which we want to modify inplace instead of
618 // coyp it into another buffer on the heap again
619 return create_dir_recursively_(sys_path
.pData
->buffer
, aDirectoryCreationCallbackFunc
, pData
);
622 /******************************************************************************
624 * C-String Function Declarations
626 *****************************************************************************/
628 static oslFileError
osl_psz_removeFile(const sal_Char
* pszPath
);
629 static oslFileError
osl_psz_copyFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
630 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
633 /******************************************************************************
635 * Static Module Utility Function Declarations
637 *****************************************************************************/
639 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
);
640 static oslFileError
oslChangeFileModes(const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
);
641 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
);
642 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
);
643 static oslFileError
oslDoMoveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
645 /****************************************************************************/
647 /****************************************************************************/
649 oslFileError SAL_CALL
osl_moveFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
651 char srcPath
[PATH_MAX
];
652 char destPath
[PATH_MAX
];
655 OSL_ASSERT( ustrFileURL
);
656 OSL_ASSERT( ustrDestURL
);
658 /* convert source url to system path */
659 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
660 if( eRet
!= osl_File_E_None
)
663 /* convert destination url to system path */
664 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
665 if( eRet
!= osl_File_E_None
)
669 if ( macxp_resolveAlias( srcPath
, PATH_MAX
) != 0 || macxp_resolveAlias( destPath
, PATH_MAX
) != 0 )
670 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
673 return oslDoMoveFile( srcPath
, destPath
);
676 /****************************************************************************/
678 /****************************************************************************/
680 oslFileError SAL_CALL
osl_copyFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
682 char srcPath
[PATH_MAX
];
683 char destPath
[PATH_MAX
];
686 OSL_ASSERT( ustrFileURL
);
687 OSL_ASSERT( ustrDestURL
);
689 /* convert source url to system path */
690 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
691 if( eRet
!= osl_File_E_None
)
694 /* convert destination url to system path */
695 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
696 if( eRet
!= osl_File_E_None
)
700 if ( macxp_resolveAlias( srcPath
, PATH_MAX
) != 0 || macxp_resolveAlias( destPath
, PATH_MAX
) != 0 )
701 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
704 return osl_psz_copyFile( srcPath
, destPath
);
707 /****************************************************************************/
709 /****************************************************************************/
711 oslFileError SAL_CALL
osl_removeFile( rtl_uString
* ustrFileURL
)
716 OSL_ASSERT( ustrFileURL
);
718 /* convert file url to system path */
719 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
720 if( eRet
!= osl_File_E_None
)
724 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
725 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
728 return osl_psz_removeFile( path
);
731 /******************************************************************************
735 *****************************************************************************/
737 /*****************************************
739 ****************************************/
741 static oslFileError
oslDoMoveFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
743 oslFileError tErr
=osl_File_E_invalidError
;
745 tErr
= osl_psz_moveFile(pszPath
,pszDestPath
);
746 if ( tErr
== osl_File_E_None
)
751 if ( tErr
!= osl_File_E_XDEV
)
756 tErr
=osl_psz_copyFile(pszPath
,pszDestPath
);
758 if ( tErr
!= osl_File_E_None
)
760 osl_psz_removeFile(pszDestPath
);
764 tErr
=osl_psz_removeFile(pszPath
);
769 /*****************************************
771 ****************************************/
772 static oslFileError
osl_psz_removeFile( const sal_Char
* pszPath
)
777 nRet
= lstat_c(pszPath
,&aStat
);
781 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
784 if ( S_ISDIR(aStat
.st_mode
) )
786 return osl_File_E_ISDIR
;
789 nRet
= unlink(pszPath
);
793 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
796 return osl_File_E_None
;
799 /*****************************************
801 ****************************************/
803 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
808 nRet
= rename(pszPath
,pszDestPath
);
813 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
816 return osl_File_E_None
;
819 /*****************************************
821 ****************************************/
823 static oslFileError
osl_psz_copyFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
831 struct stat aFileStat
;
832 oslFileError tErr
=osl_File_E_invalidError
;
833 size_t nSourceSize
=0;
834 int DestFileExists
=1;
836 /* mfe: does the source file really exists? */
837 nRet
= lstat_c(pszPath
,&aFileStat
);
842 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
845 /* mfe: we do only copy files here! */
846 if ( S_ISDIR(aFileStat
.st_mode
) )
848 return osl_File_E_ISDIR
;
851 nSourceSize
=(size_t)aFileStat
.st_size
;
852 nMode
=aFileStat
.st_mode
;
853 nAcTime
=aFileStat
.st_atime
;
854 nModTime
=aFileStat
.st_mtime
;
855 nUID
=aFileStat
.st_uid
;
856 nGID
=aFileStat
.st_gid
;
858 nRet
= stat(pszDestPath
,&aFileStat
);
863 if ( nRet
== ENOENT
)
867 /* return oslTranslateFileError(nRet);*/
870 /* mfe: the destination file must not be a directory! */
871 if ( nRet
== 0 && S_ISDIR(aFileStat
.st_mode
) )
873 return osl_File_E_ISDIR
;
877 /* mfe: file does not exists or is no dir */
880 tErr
= oslDoCopy(pszPath
,pszDestPath
,nMode
,nSourceSize
,DestFileExists
);
882 if ( tErr
!= osl_File_E_None
)
888 * mfe: ignore return code
889 * since only the success of the copy is
892 oslChangeFileModes(pszDestPath
,nMode
,nAcTime
,nModTime
,nUID
,nGID
);
898 /******************************************************************************
902 *****************************************************************************/
904 /*****************************************
906 ****************************************/
908 #define TMP_DEST_FILE_EXTENSION ".osl-tmp"
910 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
)
913 sal_Char pszTmpDestFile
[PATH_MAX
];
914 size_t size_tmp_dest_buff
= sizeof(pszTmpDestFile
);
916 /* Quick fix for #106048, the whole copy file function seems
917 to be erroneous anyway and needs to be rewritten.
919 memset(pszTmpDestFile
, 0, size_tmp_dest_buff
);
921 if ( DestFileExists
)
923 strncpy(pszTmpDestFile
, pszDestFileName
, size_tmp_dest_buff
- 1);
925 if ((strlen(pszTmpDestFile
) + strlen(TMP_DEST_FILE_EXTENSION
)) >= size_tmp_dest_buff
)
926 return osl_File_E_NAMETOOLONG
;
928 strncat(pszTmpDestFile
, TMP_DEST_FILE_EXTENSION
, strlen(TMP_DEST_FILE_EXTENSION
));
930 /* FIXME: what if pszTmpDestFile already exists? */
931 /* with getcanonical??? */
932 nRet
=rename(pszDestFileName
,pszTmpDestFile
);
935 /* mfe: should be S_ISREG */
936 if ( !S_ISLNK(nMode
) )
938 /* copy SourceFile to DestFile */
939 nRet
= oslDoCopyFile(pszSourceFileName
,pszDestFileName
,nSourceSize
, nMode
);
941 /* mfe: OK redundant at the moment */
942 else if ( S_ISLNK(nMode
) )
944 nRet
= oslDoCopyLink(pszSourceFileName
,pszDestFileName
);
948 /* mfe: what to do here? */
952 if ( nRet
> 0 && DestFileExists
== 1 )
954 unlink(pszDestFileName
);
955 rename(pszTmpDestFile
,pszDestFileName
);
960 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
963 if ( DestFileExists
== 1 )
965 unlink(pszTmpDestFile
);
968 return osl_File_E_None
;
971 /*****************************************
973 ****************************************/
975 static oslFileError
oslChangeFileModes( const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
)
978 struct utimbuf aTimeBuffer
;
980 nRet
= chmod(pszFileName
,nMode
);
984 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
987 aTimeBuffer
.actime
=nAcTime
;
988 aTimeBuffer
.modtime
=nModTime
;
989 nRet
=utime(pszFileName
,&aTimeBuffer
);
993 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
996 if ( nUID
!= getuid() )
1001 nRet
=chown(pszFileName
,nUID
,nGID
);
1006 /* mfe: do not return an error here! */
1007 /* return oslTranslateFileError(nRet);*/
1010 return osl_File_E_None
;
1013 /*****************************************
1015 ****************************************/
1017 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
)
1021 /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
1022 /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
1023 sal_Char pszLinkContent
[PATH_MAX
];
1025 pszLinkContent
[0] = '\0';
1027 nRet
= readlink(pszSourceFileName
,pszLinkContent
,PATH_MAX
);
1035 pszLinkContent
[ nRet
] = 0;
1037 nRet
= symlink(pszLinkContent
,pszDestFileName
);
1048 /*****************************************
1050 ****************************************/
1052 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
)
1054 oslFileHandle SourceFileFH
=0;
1058 if (osl_openFilePath(pszSourceFileName
,
1060 osl_File_OpenFlag_Read
|osl_File_OpenFlag_NoLock
|osl_File_OpenFlag_NoExcl
) != osl_File_E_None
)
1062 // Let's hope errno is still set relevantly after osl_openFilePath...
1067 DestFileFD
=open(pszDestFileName
, O_WRONLY
| O_CREAT
, mode
);
1069 if ( DestFileFD
< 0 )
1072 osl_closeFile(SourceFileFH
);
1076 size_t nRemains
= nSourceSize
;
1080 /* mmap has problems, try the direct streaming */
1081 char pBuffer
[0x7FFF];
1085 size_t nToRead
= std::min( sizeof(pBuffer
), nRemains
);
1088 if ( osl_readFile( SourceFileFH
, pBuffer
, nToRead
, &nRead
) != osl_File_E_None
|| nRead
> nToRead
|| nRead
== 0 )
1091 succeeded
= safeWrite( DestFileFD
, pBuffer
, nRead
);
1095 // We know nRead <= nToRead, so it must fit in a size_t
1096 nRemains
-= (size_t) nRead
;
1109 osl_closeFile( SourceFileFH
);
1110 if ( close( DestFileFD
) == -1 && nRet
== 0 )
1116 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */