summaryrefslogtreecommitdiff
path: root/tools/source
diff options
context:
space:
mode:
authorAndras Timar <atimar@suse.com>2013-04-04 18:53:04 +0200
committerAndras Timar <atimar@suse.com>2013-04-04 19:31:20 +0200
commitc8f8f36027656e42707d782655187fce3229e0f3 (patch)
tree79a79ebff52798ec2ed1ea12183c05f0f91635c0 /tools/source
parent7dce1c9fd2d26c9c2c53f0d307aa281972d2e82d (diff)
fdo#44994 write out tools' FileCopier class
Change-Id: Ie3d04f0b2ed35099d5682d165e17c10a6d736f99
Diffstat (limited to 'tools/source')
-rw-r--r--tools/source/fsys/comdep.hxx27
-rw-r--r--tools/source/fsys/dirent.cxx165
-rw-r--r--tools/source/fsys/filecopy.cxx291
3 files changed, 1 insertions, 482 deletions
diff --git a/tools/source/fsys/comdep.hxx b/tools/source/fsys/comdep.hxx
index 80cd3a06c556..2b1e135f394b 100644
--- a/tools/source/fsys/comdep.hxx
+++ b/tools/source/fsys/comdep.hxx
@@ -19,7 +19,7 @@
#ifndef _COMDEP_HXX
#define _COMDEP_HXX
-#include "tools-internal.hxx"
+#include <tools/fsys.hxx>
#define ACCESSDELIM(e) ( ( e == FSYS_STYLE_NTFS ) ? "\\" : "/" )
#define ACCESSDELIM_C(e)(char)\
@@ -87,31 +87,6 @@ struct DirReader_Impl
};
-struct FileCopier_Impl
-{
- FSysAction nActions; ///< action command (Copy/Move/recur)
- Link aErrorLink; ///< link to call upon errors
- ErrCode eErr; ///< current errorcode in the handler
- const DirEntry* pErrSource; ///< for Error-Handler in case of Source error
- const DirEntry* pErrTarget; ///< for Error-Handler in case of Target error
-
- FileCopier_Impl()
- : nActions( 0 ), eErr( 0 ),
- pErrSource( 0 ), pErrTarget( 0 )
- {}
- FileCopier_Impl( const FileCopier_Impl &rOrig )
- : nActions( rOrig.nActions ), eErr( 0 ),
- pErrSource( 0 ), pErrTarget( 0 )
- {}
-
- FileCopier_Impl& operator=( const FileCopier_Impl &rOrig )
- {
- nActions = rOrig.nActions;
- eErr = 0; pErrSource = 0; pErrTarget = 0;
- return *this;
- }
-};
-
#if defined WNT
sal_Bool IsRedirectable_Impl( const rtl::OString &rPath );
#else
diff --git a/tools/source/fsys/dirent.cxx b/tools/source/fsys/dirent.cxx
index be2899512e4e..4c42f478fb17 100644
--- a/tools/source/fsys/dirent.cxx
+++ b/tools/source/fsys/dirent.cxx
@@ -1463,171 +1463,6 @@ sal_Bool DirEntry::MakeDir( sal_Bool bSloppy ) const
return sal_True;
}
-FSysError DirEntry::CopyTo( const DirEntry& rDest, FSysAction nActions ) const
-{
- DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
-
- if ( FSYS_ACTION_COPYFILE != (nActions & FSYS_ACTION_COPYFILE) )
-#ifdef UNX
- {
- // create hardlink
- // redirection missing
- rtl::OString aThis(rtl::OUStringToOString(GetFull(), osl_getThreadTextEncoding()));
- rtl::OString aDest(rtl::OUStringToOString(rDest.GetFull(), osl_getThreadTextEncoding()));
- if (link(aThis.getStr(), aDest.getStr()) == -1)
- return Sys2SolarError_Impl( errno );
- else
- return FSYS_ERR_OK;
- }
-#else
- return FSYS_ERR_NOTSUPPORTED;
-#endif
-
- FileCopier fc(*this, rDest);
- return fc.Execute(nActions);
-}
-
-#if defined WNT || defined UNX
-FSysError DirEntry::MoveTo( const DirEntry& rNewName ) const
-{
- DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
-
- DirEntry aDest(rNewName);
- FileStat aDestStat(rNewName);
- if ( aDestStat.IsKind(FSYS_KIND_DIR ) )
- {
- aDest += DirEntry(rtl::OStringToOUString(aName, osl_getThreadTextEncoding()));
- }
- if ( aDest.Exists() )
- {
- return FSYS_ERR_ALREADYEXISTS;
- }
-
- String aFrom( GetFull() );
-
- String aTo( aDest.GetFull() );
-
- rtl::OString bFrom(rtl::OUStringToOString(aFrom, osl_getThreadTextEncoding()));
- rtl::OString bTo(rtl::OUStringToOString(aTo, osl_getThreadTextEncoding()));
-
-#ifdef WNT
- // MoveTo nun atomar
- SetLastError(0);
-
- DirEntry aFromDevice(rtl::OStringToOUString(bFrom, osl_getThreadTextEncoding()));
- DirEntry aToDevice(rtl::OStringToOUString(bTo,osl_getThreadTextEncoding()));
- aFromDevice.ToAbs();
- aToDevice.ToAbs();
- aFromDevice=aFromDevice.GetDevice();
- aToDevice=aToDevice.GetDevice();
-
- if (aFromDevice==aToDevice)
- {
- // same device, use intra-device-move with MoveFile
- MoveFile( bFrom.getStr(), bTo.getStr() );
- // Note: MoveFile is buggy for cross-device operations.
- // Return value is TRUE, even if the operation was only partially successful.
- // MoveFile has varying behavior between differing NT-versions.
- return Sys2SolarError_Impl( GetLastError() );
- }
- else
- {
- // Not the same device, use inter-device-move with copy/delete
- FSysError nCopyError = CopyTo(rNewName, FSYS_ACTION_COPYFILE);
-
- DirEntry aKill(rtl::OStringToOUString(bTo, osl_getThreadTextEncoding()));
- FileStat aKillStat(String(rtl::OStringToOUString(bTo, osl_getThreadTextEncoding())));
- if ( aKillStat.IsKind(FSYS_KIND_DIR ) )
- {
- aKill += String(rtl::OStringToOUString(aName, osl_getThreadTextEncoding()));
- }
-
- if (nCopyError==FSYS_ERR_OK)
- {
- if (Kill()==FSYS_ERR_OK)
- {
- return FSYS_ERR_OK;
- }
- else
- {
- aKill.Kill();
- return FSYS_ERR_ACCESSDENIED;
- }
- }
- else
- {
- aKill.Kill();
- return nCopyError;
- }
- }
-#else
- // #68639#
- // on some nfs connections rename with from == to
- // leads to destruction of file
- if ( ( aFrom != aTo ) && ( 0 != rename( bFrom.getStr(), bTo.getStr() ) ) )
-#if !defined(UNX)
- return Sys2SolarError_Impl( GetLastError() );
-#else
- {
- if( errno == EXDEV )
- // simple rename does not work cross device
- {
- FILE *fpIN = fopen( bFrom.getStr(), "r" );
- FILE *fpOUT = fopen( bTo.getStr(), "w" );
- if( fpIN && fpOUT )
- {
- char pBuf[ 16384 ];
- int nBytes, nWritten, nErr = 0;
- errno = 0;
- while( ( nBytes = fread( pBuf, 1, sizeof(pBuf), fpIN ) ) && ! nErr )
- {
- nWritten = fwrite( pBuf, 1, nBytes, fpOUT );
- // Error in fwrite ?
- if( nWritten < nBytes )
- {
- nErr = errno;
- break;
- }
- }
- fclose( fpIN );
- fclose( fpOUT );
- if ( nErr )
- {
- unlink( bTo.getStr() );
- return Sys2SolarError_Impl( nErr );
- }
- else
- {
- unlink( bFrom.getStr() );
- }
- }
- else
- {
- if ( fpIN )
- fclose( fpIN );
- if ( fpOUT )
- fclose( fpOUT );
- return Sys2SolarError_Impl( EXDEV );
- }
- }
- else
- {
- return Sys2SolarError_Impl( errno );
- }
- }
-#endif
-#endif
-
-// For the WNT case we always return already above, so avoid warning
-// C4702: unreachable code. Possibly also in non-WNT cases we always
-// return already above, but gcc apparently doesn't mind.
-#ifndef WNT
- return ERRCODE_NONE;
-#endif
-}
-
-#endif
-
FSysError DirEntry::Kill( FSysAction nActions ) const
{
DBG_CHKTHIS( DirEntry, ImpCheckDirEntry );
diff --git a/tools/source/fsys/filecopy.cxx b/tools/source/fsys/filecopy.cxx
deleted file mode 100644
index e0a0c7128181..000000000000
--- a/tools/source/fsys/filecopy.cxx
+++ /dev/null
@@ -1,291 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#if defined WNT
-#include <windows.h>
-#include <io.h>
-#elif defined UNX
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#endif
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <stdio.h>
-#include "comdep.hxx"
-#include <tools/stream.hxx>
-#include <osl/file.hxx>
-
-using namespace ::osl;
-
-FileCopier::FileCopier( const DirEntry& rSource, const DirEntry& rTarget ) :
- aSource ( rSource ),
- aTarget ( rTarget ),
- nBytesTotal ( 0 ),
- nBytesCopied( 0 ),
- nBlockSize ( 4096 ),
- pImp ( new FileCopier_Impl )
-{
-}
-
-FileCopier::FileCopier( const FileCopier& rCopier ) :
- aSource ( rCopier.aSource ),
- aTarget ( rCopier.aTarget ),
- nBytesTotal ( 0 ),
- nBytesCopied ( 0 ),
- aProgressLink ( rCopier.aProgressLink ),
- nBlockSize ( 4096 ),
- pImp ( new FileCopier_Impl )
-{
-}
-
-FileCopier::~FileCopier()
-{
- delete pImp;
-}
-
-FileCopier& FileCopier::operator = ( const FileCopier &rCopier )
-{
- aSource = rCopier.aSource;
- aTarget = rCopier.aTarget;
- nBytesTotal = rCopier.nBytesTotal;
- nBytesCopied = rCopier.nBytesCopied;
- nBytesCopied = rCopier.nBytesCopied;
- nBlockSize = rCopier.nBlockSize;
- aProgressLink = rCopier.aProgressLink;
- *pImp = *(rCopier.pImp);
- return *this;
-}
-
-sal_Bool FileCopier::Progress()
-{
- if ( !aProgressLink )
- return sal_True;
- else
- {
- if ( aProgressLink.Call( this ) )
- return sal_True;
- return ( 0 == Error( ERRCODE_ABORT, 0, 0 ) );
- }
-}
-
-ErrCode FileCopier::Error( ErrCode eErr, const DirEntry* pSource, const DirEntry* pTarget )
-{
- // No error or no error handler?
- if ( !eErr || !pImp->aErrorLink )
- // => keep error
- return eErr;
-
- // otherwise request from ErrorHandler
- pImp->pErrSource = pSource;
- pImp->pErrTarget = pTarget;
- pImp->eErr = eErr;
- ErrCode eRet = (ErrCode) pImp->aErrorLink.Call( this );
- pImp->pErrSource = 0;
- pImp->pErrTarget = 0;
- return eRet;
-}
-
-FSysError FileCopier::DoCopy_Impl( const DirEntry &rSource, const DirEntry &rTarget )
-{
- FSysError eRet = FSYS_ERR_OK;
- ErrCode eWarn = FSYS_ERR_OK;
-
- // shorten target name if necessary
- DirEntry aTgt;
- aTgt = rTarget;
-
- // source is directory?
- FileStat aSourceFileStat( rSource );
- if ( aSourceFileStat.IsKind( FSYS_KIND_DIR ) )
- {
- // recursive copy
- eRet = Error( aTgt.MakeDir() ? FSYS_ERR_OK : FSYS_ERR_UNKNOWN, 0, &aTgt );
- Dir aSourceDir( rSource, FSYS_KIND_DIR|FSYS_KIND_FILE );
- for ( sal_uInt16 n = 0; ERRCODE_TOERROR(eRet) == FSYS_ERR_OK && n < aSourceDir.Count(); ++n )
- {
- const DirEntry &rSubSource = aSourceDir[n];
- DirEntryFlag eFlag = rSubSource.GetFlag();
- if ( eFlag != FSYS_FLAG_CURRENT && eFlag != FSYS_FLAG_PARENT )
- {
- DirEntry aSubTarget( aTgt );
- aSubTarget += rSubSource.GetName();
- eRet = DoCopy_Impl( rSubSource, aSubTarget );
- if ( eRet && !eWarn )
- eWarn = eRet;
- }
- }
- }
- else if ( aSourceFileStat.IsKind(FSYS_KIND_FILE) )
- {
- if ( ( FSYS_ACTION_KEEP_EXISTING == ( pImp->nActions & FSYS_ACTION_KEEP_EXISTING ) ) &&
- aTgt.Exists() )
- {
- // Do not overwrite existing file in target folder.
- return ERRCODE_NONE;
- }
-
- // copy file
- nBytesCopied = 0;
- nBytesTotal = FileStat( rSource ).GetSize();
-
- ::rtl::OUString aFileName;
- FileBase::getFileURLFromSystemPath( ::rtl::OUString(rSource.GetFull()), aFileName );
- SvFileStream aSrc( aFileName, STREAM_READ|STREAM_NOCREATE|STREAM_SHARE_DENYNONE );
-
- if ( !aSrc.GetError() )
- {
-#ifdef UNX
- struct stat buf;
- if ( fstat( aSrc.GetFileHandle(), &buf ) == -1 )
- eRet = Error( FSYS_ERR_ACCESSDENIED, 0, &aTgt );
-#endif
- ::rtl::OUString aTargetFileName;
- FileBase::getFileURLFromSystemPath( ::rtl::OUString(aTgt.GetFull()), aTargetFileName );
-
- SvFileStream aTargetStream( aTargetFileName, STREAM_WRITE | STREAM_TRUNC | STREAM_SHARE_DENYWRITE );
- if ( !aTargetStream.GetError() )
- {
-#ifdef UNX
- if ( fchmod( aTargetStream.GetFileHandle(), buf.st_mode ) == -1 )
- eRet = Error( FSYS_ERR_ACCESSDENIED, 0, &aTgt );
-#endif
- size_t nAllocSize = 0, nSize = 0;
- char *pBuf = 0;
- while ( Progress() && nSize == nAllocSize && eRet == FSYS_ERR_OK )
- {
- // adjust the block-size
- if ( nBlockSize > nAllocSize )
- {
- delete[] pBuf;
- nAllocSize = nBlockSize;
- pBuf = new char[nAllocSize];
- }
-
- // copy one block
- nSize = aSrc.Read( pBuf, nBlockSize );
- aTargetStream.Write( pBuf, nSize );
- if ( aTargetStream.GetError() )
- eRet = Error( aTargetStream.GetError(), 0, &aTgt );
-
- // adjust counters
- nBytesCopied += nSize;
- if ( nBytesCopied > nBytesTotal )
- nBytesTotal = nBytesCopied;
- }
- delete[] pBuf;
- }
- else
- eRet = Error( aTargetStream.GetError(), 0, &aTgt );
-
- aTargetStream.Close();
-
- // remove incomplete file
- if ( nBytesCopied != nBytesTotal )
- {
- aTgt.Kill();
- }
- }
- else
- eRet = Error( aSrc.GetError(), &rSource, 0 );
- }
- else if ( aSourceFileStat.IsKind(FSYS_KIND_NONE) )
- eRet = Error( ERRCODE_IO_NOTEXISTS, &rSource, 0 );
- else
- eRet = Error( ERRCODE_IO_NOTSUPPORTED, &rSource, 0 );
-
-#ifdef WNT
- // Set LastWriteTime and Attributes of the target identical with the source
-
- if ( FSYS_ERR_OK == ERRCODE_TOERROR(eRet) )
- {
- WIN32_FIND_DATA fdSource;
- rtl::OString aFullSource(rtl::OUStringToOString(aSource.GetFull(), osl_getThreadTextEncoding()));
- rtl::OString aFullTarget(rtl::OUStringToOString(aTgt.GetFull(), osl_getThreadTextEncoding()));
- HANDLE hFind = FindFirstFile( aFullSource.getStr() , &fdSource );
- if ( hFind != INVALID_HANDLE_VALUE )
- {
- FindClose( hFind );
-
- HANDLE hFile = CreateFile( aFullTarget.getStr(), GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
-
- if ( hFile != INVALID_HANDLE_VALUE )
- {
- SetFileTime( hFile, NULL, NULL, &fdSource.ftLastWriteTime );
- CloseHandle( hFile );
- }
-
- SetFileAttributes( aFullTarget.getStr(), fdSource.dwFileAttributes );
- }
- }
-#endif
- // Remove File/Dir upon Move if necessary
- if ( FSYS_ERR_OK == ERRCODE_TOERROR(eRet) && ( pImp->nActions & FSYS_ACTION_MOVE ) )
- {
- ErrCode eKillErr = Error( rSource.Kill() | ERRCODE_WARNING_MASK, &rSource, 0 );
- if ( eKillErr != ERRCODE_WARNING_MASK )
- {
- if ( rSource.Exists() )
- // Removal failed => remove copy
- aTgt.Kill( pImp->nActions );
- if ( !eWarn )
- eWarn = eKillErr;
- }
- }
-
- return !eRet ? eWarn : eRet;
-}
-
-FSysError FileCopier::Execute( FSysAction nActions )
-{
- return ExecuteExact( nActions );
-}
-
-FSysError FileCopier::ExecuteExact( FSysAction nActions, FSysExact eExact )
-{
- DirEntry aAbsSource = DirEntry( aSource);
- DirEntry aAbsTarget = DirEntry( aTarget );
- pImp->nActions = nActions;
-
- // check if both paths are accessible and source and target are different
- if ( !aAbsTarget.ToAbs() || !aAbsSource.ToAbs() || aAbsTarget == aAbsSource )
- return FSYS_ERR_ACCESSDENIED;
-
- // check if copy would be endless recursive into itself
- if ( FSYS_ACTION_RECURSIVE == ( nActions & FSYS_ACTION_RECURSIVE ) &&
- aAbsSource.Contains( aAbsTarget ) )
- return ERRCODE_IO_RECURSIVE;
-
- // target is directory?
- if ( eExact == FSYS_NOTEXACT &&
- FileStat( aAbsTarget ).IsKind(FSYS_KIND_DIR) && FileStat( aAbsSource ).IsKind(FSYS_KIND_FILE) )
- // append name of source
- aAbsTarget += aSource.GetName();
-
- // recursive copy
- return DoCopy_Impl( aAbsSource, aAbsTarget );
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */