From 929b57a7e098afa7e7647ccf888c59e5b4e0ff68 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Wed, 28 Jul 2010 22:38:23 +0000 Subject: [PATCH] 2010-07-29 00:36 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * src/rtl/Makefile * include/hbapifs.h * include/hbextern.ch + src/rtl/fslink.c + tests/flink.prg + Added new C level functions to create file links: HB_BOOL hb_fsLink( const char * pszExisting, const char * pszNewFile ); HB_BOOL hb_fsLinkSym( const char * pszTarget, const char * pszNewFile ); + Added new Harbour level functions to create file links: HB_FLINK( , ) -> HB_FLINKSYM( , ) -> ; They work on POSIX and Windows Vista/7 systems. * src/rtl/fserr.c + Mapped Windows error ERROR_PRIVILEGE_NOT_HELD to DOS error 5. --- harbour/ChangeLog | 21 ++++ harbour/include/hbapifs.h | 4 +- harbour/include/hbextern.ch | 2 + harbour/src/rtl/Makefile | 1 + harbour/src/rtl/fserr.c | 20 ++-- harbour/src/rtl/fslink.c | 210 ++++++++++++++++++++++++++++++++++++ harbour/tests/flink.prg | 33 ++++++ 7 files changed, 280 insertions(+), 11 deletions(-) create mode 100644 harbour/src/rtl/fslink.c create mode 100644 harbour/tests/flink.prg diff --git a/harbour/ChangeLog b/harbour/ChangeLog index faa8c042dc..b5f63ead3b 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,27 @@ The license applies to all entries newer than 2009-04-28. */ +2010-07-29 00:36 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) + * src/rtl/Makefile + * include/hbapifs.h + * include/hbextern.ch + + src/rtl/fslink.c + + tests/flink.prg + + Added new C level functions to create file links: + + HB_BOOL hb_fsLink( const char * pszExisting, const char * pszNewFile ); + HB_BOOL hb_fsLinkSym( const char * pszTarget, const char * pszNewFile ); + + + Added new Harbour level functions to create file links: + + HB_FLINK( , ) -> + HB_FLINKSYM( , ) -> + + ; They work on POSIX and Windows Vista/7 systems. + + * src/rtl/fserr.c + + Mapped Windows error ERROR_PRIVILEGE_NOT_HELD to DOS error 5. + 2010-07-28 23:08 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * external/sqlite3/sqlite3.c * external/sqlite3/sqlite3.dif diff --git a/harbour/include/hbapifs.h b/harbour/include/hbapifs.h index 41dae3cf24..26cd114fd3 100644 --- a/harbour/include/hbapifs.h +++ b/harbour/include/hbapifs.h @@ -215,7 +215,9 @@ extern HB_EXPORT void hb_fsSetFError ( HB_ERRCODE uiError ); /* set FERR extern HB_EXPORT HB_BOOL hb_fsNameExists ( const char * pszFileName ); /* check if a name exists in the filesystem (wildcard chars not accepted). */ extern HB_EXPORT HB_BOOL hb_fsFileExists ( const char * pszFileName ); /* check if a file exists (wildcard chars not accepted). */ extern HB_EXPORT HB_BOOL hb_fsDirExists ( const char * pszDirName ); /* check if a directory exists (wildcard chars not accepted). */ -extern HB_EXPORT HB_BOOL hb_fsCopy ( const char * pSource, const char * pDest ); +extern HB_EXPORT HB_BOOL hb_fsCopy ( const char * pszSource, const char * pszDest ); /* copy file */ +extern HB_EXPORT HB_BOOL hb_fsLink ( const char * pszExisting, const char * pszNewFile ); /* create hard link */ +extern HB_EXPORT HB_BOOL hb_fsLinkSym ( const char * pszTarget, const char * pszNewFile ); /* create symbolic (soft) link */ #define hb_fsFLock( h, s, l ) hb_fsLock( h, s, l, FL_LOCK ) #define hb_fsFUnlock( h, s, l ) hb_fsLock( h, s, l, FL_UNLOCK ) diff --git a/harbour/include/hbextern.ch b/harbour/include/hbextern.ch index d7f7c82e28..2f5330776d 100644 --- a/harbour/include/hbextern.ch +++ b/harbour/include/hbextern.ch @@ -903,6 +903,8 @@ EXTERNAL HB_FUNLOCK EXTERNAL HB_FTEMPCREATE EXTERNAL HB_FTEMPCREATEEX EXTERNAL HB_FCOPY +EXTERNAL HB_FLINK +EXTERNAL HB_FLINKSYM EXTERNAL HB_FSETATTR EXTERNAL HB_FGETATTR EXTERNAL HB_FSETDATETIME diff --git a/harbour/src/rtl/Makefile b/harbour/src/rtl/Makefile index d4918725f6..c41c3036bf 100644 --- a/harbour/src/rtl/Makefile +++ b/harbour/src/rtl/Makefile @@ -54,6 +54,7 @@ C_SOURCES := \ fnsplit.c \ fscopy.c \ fserr.c \ + fslink.c \ fssize.c \ fstemp.c \ gete.c \ diff --git a/harbour/src/rtl/fserr.c b/harbour/src/rtl/fserr.c index 59db709b89..ec0a702f0a 100644 --- a/harbour/src/rtl/fserr.c +++ b/harbour/src/rtl/fserr.c @@ -126,18 +126,18 @@ static HB_ERRCODE hb_errnoToDosError( int ErrCode ) static HB_ERRCODE hb_WinToDosError( DWORD dwError ) { + #ifndef ERROR_PRIVILEGE_NOT_HELD + #define ERROR_PRIVILEGE_NOT_HELD 1314L + #endif + switch( dwError ) { - case ERROR_ALREADY_EXISTS: - return 5; - case ERROR_FILE_NOT_FOUND: - return 2; - case ERROR_PATH_NOT_FOUND: - return 3; - case ERROR_TOO_MANY_OPEN_FILES: - return 4; - case ERROR_INVALID_HANDLE: - return 6; + case ERROR_PRIVILEGE_NOT_HELD: + case ERROR_ALREADY_EXISTS: return 5; + case ERROR_FILE_NOT_FOUND: return 2; + case ERROR_PATH_NOT_FOUND: return 3; + case ERROR_TOO_MANY_OPEN_FILES: return 4; + case ERROR_INVALID_HANDLE: return 6; } return ( HB_ERRCODE ) dwError; diff --git a/harbour/src/rtl/fslink.c b/harbour/src/rtl/fslink.c new file mode 100644 index 0000000000..5e5247ea65 --- /dev/null +++ b/harbour/src/rtl/fslink.c @@ -0,0 +1,210 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * hb_fsLink(), hb_fsLinkSym(), HB_FLINK, HB_FLINKSYM() functions + * + * Copyright 2010 Viktor Szakats (harbour.01 syenar.hu) + * www - http://harbour-project.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#include "hbapi.h" +#include "hbapifs.h" + +#if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) + #include +#elif defined( HB_OS_UNIX ) + #include +#endif + +HB_BOOL hb_fsLink( const char * pszExisting, const char * pszNewFile ) +{ + HB_BOOL fResult; + + if( pszExisting && pszNewFile ) + { +#if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) + { + typedef BOOL ( WINAPI * _HB_CREATEHARDLINK )( LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES ); + + static _HB_CREATEHARDLINK s_pCreateHardLink = NULL; + + if( ! s_pCreateHardLink ) + s_pCreateHardLink = ( _HB_CREATEHARDLINK ) GetProcAddress( GetModuleHandle( TEXT( "kernel32.dll" ) ), +#if defined( UNICODE ) + "CreateHardLinkW" ); +#else + "CreateHardLinkA" ); +#endif + + if( s_pCreateHardLink ) + { + LPTSTR lpFileName = HB_TCHAR_CONVTO( pszNewFile ); + LPTSTR lpExistingFileName = HB_TCHAR_CONVTO( pszExisting ); + + fResult = s_pCreateHardLink( lpFileName, lpExistingFileName, NULL ) != 0; + hb_fsSetIOError( fResult, 0 ); + hb_fsSetFError( hb_fsError() ); + + HB_TCHAR_FREE( lpFileName ); + HB_TCHAR_FREE( lpExistingFileName ); + } + else + { + hb_fsSetFError( 1 ); + fResult = HB_FALSE; + } + } +#elif defined( HB_OS_UNIX ) + { + fResult = ( link( pszExisting, pszNewFile ) == 0 ); + hb_fsSetIOError( fResult, 0 ); + hb_fsSetFError( hb_fsError() ); + } +#else + { + hb_fsSetFError( 1 ); + fResult = HB_FALSE; + } +#endif + } + else + { + hb_fsSetFError( 2 ); + fResult = HB_FALSE; + } + + return fResult; +} + +HB_BOOL hb_fsLinkSym( const char * pszTarget, const char * pszNewFile ) +{ + HB_BOOL fResult; + + if( pszTarget && pszNewFile ) + { +#if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) + { + typedef BOOL ( WINAPI * _HB_CREATESYMBOLICLINK )( LPCTSTR, LPCTSTR, DWORD ); + + static _HB_CREATESYMBOLICLINK s_pCreateSymbolicLink = NULL; + + #ifndef SYMBOLIC_LINK_FLAG_DIRECTORY + #define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1 + #endif + + if( ! s_pCreateSymbolicLink ) + s_pCreateSymbolicLink = ( _HB_CREATESYMBOLICLINK ) GetProcAddress( GetModuleHandle( TEXT( "kernel32.dll" ) ), +#if defined( UNICODE ) + "CreateSymbolicLinkW" ); +#else + "CreateSymbolicLinkA" ); +#endif + + if( s_pCreateSymbolicLink ) + { + LPTSTR lpSymlinkFileName = HB_TCHAR_CONVTO( pszNewFile ); + LPTSTR lpTargetFileName = HB_TCHAR_CONVTO( pszTarget ); + + fResult = s_pCreateSymbolicLink( lpSymlinkFileName, lpTargetFileName, hb_fsIsDirectory( pszTarget ) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ) != 0; + hb_fsSetIOError( fResult, 0 ); + hb_fsSetFError( hb_fsError() ); + + HB_TCHAR_FREE( lpSymlinkFileName ); + HB_TCHAR_FREE( lpTargetFileName ); + } + else + { + hb_fsSetFError( 1 ); + fResult = HB_FALSE; + } + } +#elif defined( HB_OS_UNIX ) + { + fResult = ( symlink( pszTarget, pszNewFile ) == 0 ); + hb_fsSetIOError( fResult, 0 ); + hb_fsSetFError( hb_fsError() ); + } +#else + { + hb_fsSetFError( 1 ); + fResult = HB_FALSE; + } +#endif + } + else + { + hb_fsSetFError( 2 ); + fResult = HB_FALSE; + } + + return fResult; +} + +HB_FUNC( HB_FLINK ) +{ + const char * pszExisting = hb_parc( 1 ), * pszNewFile = hb_parc( 2 ); + + if( pszExisting && pszNewFile ) + hb_retni( hb_fsLink( pszExisting, pszNewFile ) ? 0 : F_ERROR ); + else + { + hb_fsSetFError( 2 ); + hb_retni( F_ERROR ); + } +} + +HB_FUNC( HB_FLINKSYM ) +{ + const char * pszTarget = hb_parc( 1 ), * pszNewFile = hb_parc( 2 ); + + if( pszTarget && pszNewFile ) + hb_retni( hb_fsLinkSym( pszTarget, pszNewFile ) ? 0 : F_ERROR ); + else + { + hb_fsSetFError( 2 ); + hb_retni( F_ERROR ); + } +} diff --git a/harbour/tests/flink.prg b/harbour/tests/flink.prg new file mode 100644 index 0000000000..9356fd8ac3 --- /dev/null +++ b/harbour/tests/flink.prg @@ -0,0 +1,33 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * + * Copyright 2010 Viktor Szakats (harbour.01 syenar.hu) + * www - http://harbour-project.org + * + */ + +#include "simpleio.ch" + +PROCEDURE Main() + + hb_MemoWrit( "_hb_h.txt", ">h.txt<" ) + + ? HB_FLINK() + ? FERROR(), DOSERROR() + + ? HB_FLINK( "_hb_h.txt", "_hb_hlnk.txt" ) + ? FERROR(), DOSERROR() + + hb_MemoWrit( "_hb_s.txt", ">s.txt<" ) + + ? HB_FLINKSYM() + ? FERROR(), DOSERROR() + + ? HB_FLINKSYM( "_hb_s.txt", "_hb_slnk.txt" ) + ? FERROR(), DOSERROR() + + RETURN