2008-07-26 16:25 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)

* harbour/contrib/hbmzip/zip.c
    ! fixed access to uninitialized member of z_stream by simple
      initialization. Anyhow it's minor bug in MINIZIP code exploited
      HB_ZipDeleteFile() which causes that TEXT flag is not set after
      raw binary file updating. There is also no API call to make it
      manually.
      
  * harbour/contrib/hbmzip/hbmzip.c
  * harbour/contrib/hbmzip/readme.txt
    + added HB_ZipDeleteFile( cZipFile, cFileMask ) --> nError

  * harbour/common.mak
  * harbour/source/rtl/Makefile
  + harbour/source/rtl/dirscan.prg
    + added HB_DirScan( cPath, cFileMask, cAttr )

  * harbour/source/rtl/strmatch.c
    + added HB_FileMatch( cFile, cPattern )

  * harbour/include/hbextern.ch
    + added HB_DirScan(), HB_FileMatch()

  * harbour/contrib/xhb/dirrec.prg
    * changed to use HB_DirScan()
This commit is contained in:
Przemyslaw Czerpak
2008-07-26 14:26:11 +00:00
parent 3c36339459
commit 6bfbdc7bd6
10 changed files with 374 additions and 47 deletions

View File

@@ -8,6 +8,32 @@
2008-12-31 13:59 UTC+0100 Foo Bar <foo.bar@foobar.org>
*/
2008-07-26 16:25 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/contrib/hbmzip/zip.c
! fixed access to uninitialized member of z_stream by simple
initialization. Anyhow it's minor bug in MINIZIP code exploited
HB_ZipDeleteFile() which causes that TEXT flag is not set after
raw binary file updating. There is also no API call to make it
manually.
* harbour/contrib/hbmzip/hbmzip.c
* harbour/contrib/hbmzip/readme.txt
+ added HB_ZipDeleteFile( cZipFile, cFileMask ) --> nError
* harbour/common.mak
* harbour/source/rtl/Makefile
+ harbour/source/rtl/dirscan.prg
+ added HB_DirScan( cPath, cFileMask, cAttr )
* harbour/source/rtl/strmatch.c
+ added HB_FileMatch( cFile, cPattern )
* harbour/include/hbextern.ch
+ added HB_DirScan(), HB_FileMatch()
* harbour/contrib/xhb/dirrec.prg
* changed to use HB_DirScan()
2008-07-26 12:22 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
* TODO
* Updated.

View File

@@ -600,6 +600,7 @@ RTL_LIB_OBJS = \
$(OBJ_DIR)\dbedit$(OBJEXT) \
$(OBJ_DIR)\devoutp$(OBJEXT) \
$(OBJ_DIR)\dircmd$(OBJEXT) \
$(OBJ_DIR)\dirscan$(OBJEXT) \
$(OBJ_DIR)\einstv52$(OBJEXT) \
$(OBJ_DIR)\einstvar$(OBJEXT) \
$(OBJ_DIR)\einstvau$(OBJEXT) \

View File

@@ -80,6 +80,7 @@
#endif
#endif
#define HB_Z_IOBUF_SIZE ( 1024 * 16 )
static HB_GARBAGE_FUNC( hb_zipfile_destructor )
{
@@ -133,7 +134,7 @@ static gzFile hb_unzipfileParam( int iParam )
/* HB_ZipOpen( cFileName, [ iMode = HB_ZIP_CREATE ], [ @cGlobalComment ] ) --> hZip */
HB_FUNC( HB_ZIPOPEN )
{
char* szFileName = hb_parc( 1 );
const char* szFileName = hb_parc( 1 );
if( szFileName )
{
@@ -179,7 +180,7 @@ HB_FUNC( HB_ZIPCLOSE )
[ cPassword ], [ cComment ] ) --> nError */
HB_FUNC( HB_ZIPFILECREATE )
{
char* szZipName = hb_parc( 2 );
const char* szZipName = hb_parc( 2 );
if( szZipName )
{
@@ -220,7 +221,7 @@ HB_FUNC( HB_ZIPFILECREATE )
/* HB_ZipFileWrite( hZip, cData [, nLen ] ) --> nError */
HB_FUNC( HB_ZIPFILEWRITE )
{
char* pData = hb_parc( 2 );
const char* pData = hb_parc( 2 );
if( pData )
{
@@ -251,7 +252,7 @@ HB_FUNC( HB_ZIPFILECLOSE )
/* HB_UnzipOpen( cFileName ) --> hUnzip */
HB_FUNC( HB_UNZIPOPEN )
{
char* szFileName = hb_parc( 1 );
const char* szFileName = hb_parc( 1 );
if( szFileName )
{
@@ -508,7 +509,7 @@ HB_FUNC( HB_UNZIPFILECLOSE )
*
*/
static int hb_zipStoreFile( zipFile hZip, char* szFileName, char* szName, char* szPassword, char* szComment )
static int hb_zipStoreFile( zipFile hZip, const char* szFileName, const char* szName, const char* szPassword, const char* szComment )
{
char * szZipName, * pString;
FHANDLE hFile;
@@ -788,8 +789,8 @@ static int hb_zipStoreFile( zipFile hZip, char* szFileName, char* szName, char*
szPassword, 0 );
if( iResult == 0 )
{
pString = (char*) hb_xgrab( 1024 * 16 );
while ( ( ulLen = hb_fsReadLarge( hFile, (BYTE*) pString, 1024 * 16 ) ) > 0 )
pString = ( char* ) hb_xgrab( HB_Z_IOBUF_SIZE );
while( ( ulLen = hb_fsReadLarge( hFile, (BYTE*) pString, HB_Z_IOBUF_SIZE ) ) > 0 )
{
zipWriteInFileInZip( hZip, pString, ulLen );
}
@@ -812,7 +813,7 @@ static int hb_zipStoreFile( zipFile hZip, char* szFileName, char* szName, char*
/* HB_ZipStoreFile( hZip, cFileName, [ cZipName ], [ cPassword ], [ cComment ] ) --> nError */
HB_FUNC( HB_ZIPSTOREFILE )
{
char* szFileName = hb_parc( 2 );
const char* szFileName = hb_parc( 2 );
if( szFileName )
{
@@ -826,7 +827,7 @@ HB_FUNC( HB_ZIPSTOREFILE )
}
static int hb_unzipExtractCurrentFile( unzFile hUnzip, char* szFileName, char* szPassword )
static int hb_unzipExtractCurrentFile( unzFile hUnzip, const char* szFileName, const char* szPassword )
{
char szName[ _POSIX_PATH_MAX + 1 ];
ULONG ulPos, ulLen;
@@ -881,9 +882,9 @@ static int hb_unzipExtractCurrentFile( unzFile hUnzip, char* szFileName, char* s
if( hFile != FS_ERROR )
{
pString = (char*) hb_xgrab( 1024 * 16 );
pString = (char*) hb_xgrab( HB_Z_IOBUF_SIZE );
while ( ( iResult = unzReadCurrentFile( hUnzip, pString, 16 * 1024 ) ) > 0 )
while( ( iResult = unzReadCurrentFile( hUnzip, pString, HB_Z_IOBUF_SIZE ) ) > 0 )
{
hb_fsWriteLarge( hFile, (BYTE*) pString, (ULONG) iResult );
}
@@ -1025,3 +1026,215 @@ HB_FUNC( HB_UNZIPEXTRACTCURRENTFILE )
if( hUnzip )
hb_retni( hb_unzipExtractCurrentFile( hUnzip, hb_parc( 2 ), hb_parc( 3 ) ) );
}
static int hb_zipDeleteFile( const char* szZipFile, const char* szFileMask )
{
char szTempFile[ _POSIX_PATH_MAX + 1 ];
char szCurrFile[ _POSIX_PATH_MAX + 1 ];
PHB_FNAME pFileName;
FHANDLE hFile;
unzFile hUnzip;
zipFile hZip;
unz_global_info ugi;
unz_file_info ufi;
zip_fileinfo zfi;
char* pszGlobalComment = NULL;
char* pszFileComment = NULL;
void* pExtraField = NULL;
void* pLocalExtraField = NULL;
int iFilesLeft = 0;
int iFilesDel = 0;
int iExtraFieldLen;
int method;
int level;
int iResult;
/* open source file */
hUnzip = unzOpen( szZipFile );
if( hUnzip == NULL )
return UNZ_ERRNO;
pFileName = hb_fsFNameSplit( szZipFile );
hFile = hb_fsCreateTemp( ( BYTE * ) pFileName->szPath, NULL, FC_NORMAL, ( BYTE * ) szTempFile );
hZip = NULL;
if( hFile != FS_ERROR )
{
hb_fsClose( hFile );
hZip = zipOpen( szTempFile, APPEND_STATUS_CREATE );
}
hb_xfree( pFileName );
if( hZip == NULL )
{
unzClose( hUnzip );
return UNZ_ERRNO;
}
iResult = unzGetGlobalInfo( hUnzip, &ugi );
if( iResult == UNZ_OK )
{
if( ugi.size_comment > 0 )
{
pszGlobalComment = ( char * ) hb_xgrab( ugi.size_comment + 1 );
if( ( uLong ) unzGetGlobalComment( hUnzip, pszGlobalComment,
ugi.size_comment ) != ugi.size_comment )
iResult = UNZ_ERRNO;
pszGlobalComment[ ugi.size_comment ] = '\0';
}
if( iResult == UNZ_OK )
iResult = unzGoToFirstFile( hUnzip );
}
while( iResult == UNZ_OK )
{
iResult = unzGetCurrentFileInfo( hUnzip, &ufi, szCurrFile, _POSIX_PATH_MAX, NULL, 0, NULL, 0 );
if( iResult != UNZ_OK )
break;
if( hb_strMatchFile( szCurrFile, szFileMask ) )
iFilesDel++;
else
{
if( ufi.size_file_extra )
pExtraField = ( char * ) hb_xgrab( ufi.size_file_extra );
if( ufi.size_file_comment )
pszFileComment = ( char * ) hb_xgrab( ufi.size_file_comment + 1 );
iResult = unzGetCurrentFileInfo( hUnzip, NULL, NULL, 0,
pExtraField, ufi.size_file_extra,
pszFileComment, ufi.size_file_comment );
pszFileComment[ ufi.size_file_comment ] = '\0';
if( iResult != UNZ_OK )
break;
iResult = unzOpenCurrentFile2( hUnzip, &method, &level, 1 );
if( iResult != UNZ_OK )
break;
iExtraFieldLen = unzGetLocalExtrafield( hUnzip, NULL, 0 );
if( iExtraFieldLen < 0 )
{
iResult = UNZ_ERRNO;
break;
}
else if( iExtraFieldLen > 0 )
{
pLocalExtraField = hb_xgrab( iExtraFieldLen );
if( unzGetLocalExtrafield( hUnzip, pLocalExtraField, iExtraFieldLen ) != iExtraFieldLen )
{
iResult = UNZ_ERRNO;
break;
}
}
memset( &zfi, 0, sizeof( zfi ) );
memcpy( &zfi.tmz_date, &ufi.tmu_date, sizeof( tm_unz ) );
zfi.dosDate = ufi.dosDate;
zfi.internal_fa = ufi.internal_fa;
zfi.external_fa = ufi.external_fa;
iResult = zipOpenNewFileInZip2( hZip, szCurrFile, &zfi, pLocalExtraField, iExtraFieldLen, pExtraField, ufi.size_file_extra, pszFileComment, method, level, 1 );
if( iResult != UNZ_OK )
break;
if( ufi.compressed_size )
{
BYTE * buffer = ( BYTE * ) hb_xgrab( HB_Z_IOBUF_SIZE );
uLong ulLeft = ufi.compressed_size;
while( ulLeft > 0 )
{
int iRead = HB_MIN( ulLeft, HB_Z_IOBUF_SIZE );
iResult = unzReadCurrentFile( hUnzip, ( voidp ) buffer, iRead );
if( iResult < 0 )
break;
if( iResult != iRead )
{
iResult = UNZ_ERRNO;
break;
}
iResult = zipWriteInFileInZip( hZip, ( voidp ) buffer, iRead );
if( iResult != UNZ_OK )
break;
ulLeft -= iRead;
}
hb_xfree( buffer );
if( iResult != UNZ_OK )
break;
}
iResult = zipCloseFileInZipRaw( hZip, ufi.uncompressed_size, ufi.crc );
if( iResult != UNZ_OK )
break;
iResult = unzCloseCurrentFile( hUnzip );
if( iResult != UNZ_OK )
break;
if( pExtraField )
{
hb_xfree( pExtraField );
pExtraField = NULL;
}
if( pszFileComment )
{
hb_xfree( pszFileComment );
pszFileComment = NULL;
}
if( pLocalExtraField )
{
hb_xfree( pLocalExtraField );
pLocalExtraField = NULL;
}
iFilesLeft++;
}
iResult = unzGoToNextFile( hUnzip );
}
if( pExtraField )
hb_xfree( pExtraField );
if( pszFileComment )
hb_xfree( pszFileComment );
if( pLocalExtraField )
hb_xfree( pLocalExtraField );
if( iFilesDel == 0 )
iResult = UNZ_ERRNO;
else if( iResult == UNZ_END_OF_LIST_OF_FILE )
iResult = UNZ_OK;
if( iResult != UNZ_OK )
zipClose( hZip, NULL );
else
iResult = zipClose( hZip, pszGlobalComment );
unzClose( hUnzip );
if( pszGlobalComment )
hb_xfree( pszGlobalComment );
if( iResult != UNZ_OK )
hb_fsDelete( ( BYTE * ) szTempFile );
else
{
hb_fsDelete( ( BYTE * ) szZipFile );
if( iFilesLeft == 0 )
hb_fsDelete( ( BYTE * ) szTempFile );
else if( !hb_fsRename( ( BYTE * ) szTempFile, ( BYTE * ) szZipFile ) )
iResult = UNZ_ERRNO;
}
return iResult;
}
/* HB_ZipDeleteFile( cZipFile, cFileMask ) --> nError */
HB_FUNC( HB_ZIPDELETEFILE )
{
char * szZipFile = hb_parc( 1 );
char * szFileMask = hb_parc( 2 );
if( szZipFile && szFileMask )
hb_retni( hb_zipDeleteFile( szZipFile, szFileMask ) );
else
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

View File

@@ -50,7 +50,7 @@ HB_ZipFileCreate( hZip, cZipName, dDate, cTime,
nInternalAttr, nExternalAttr,
[ nMethod = HB_ZLIB_METHOD_DEFLATE ],
[ nLevel = HB_ZLIB_COMPRESSION_DEFAULT ],
[ cPassword ], [ cComment ] ) --> nError */
[ cPassword ], [ cComment ] ) --> nError
HB_ZipFileWrite( hZip, cData [, nLen ] ) --> nError
HB_ZipFileClose( hZip ) --> nError
HB_ZipStoreFile( hZip, cFileName, [ cZipName ], ;
@@ -67,8 +67,11 @@ HB_UnzipFileGoto( hUnzip, nPosition ) --> nError
HB_UnzipFileInfo( hUnzip, @cZipName, @dDate, @cTime,
@nInternalAttr, @nExternalAttr,
@nMethod, @nSize, @nCompressedSize,
@cComment ) --> nError */
@cComment ) --> nError
HB_UnzipFileOpen( hUnzip, [ cPassword ] ) --> nError
HB_UnzipFileRead( hUnzip, @cBuf [, nLen ] ) --> nRead
HB_UnzipFileClose( hUnzip ) --> nError
HB_UnzipExtractCurrentFile( hZip, [ cFileName ], [ cPassword ] ) --> nError
HB_ZipDeleteFile( cZipFile, cFileMask ) --> nError

View File

@@ -544,6 +544,7 @@ extern zipFile ZEXPORT zipOpen2 (
ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
ziinit.in_opened_file_inzip = 0;
ziinit.ci.stream_initialised = 0;
ziinit.ci.stream.data_type = 0;
ziinit.number_entry = 0;
ziinit.add_position_when_writting_offset = 0;
init_linkedlist(&(ziinit.central_dir));

View File

@@ -72,41 +72,19 @@
FUNCTION DirectoryRecurse( cPath, cAttr )
LOCAL aResult := {}, aDir, aFile, cExt, cMask, cPathSep
LOCAL aResult
LOCAL cFilePath, cExt, cMask
IF Empty( cPath )
cPath := ""
cMask := hb_osFileMask()
ELSE
hb_FNameSplit( cPath, @cPath, @cMask, @cExt )
cMask += cExt
IF cMask == ""
cMask := hb_osFileMask()
ENDIF
ENDIF
hb_FNameSplit( cPath, @cFilePath, @cMask, @cExt )
cMask += cExt
IF ! ValType( cAttr ) $ "CM"
cAttr := ""
ENDIF
/* The trick with StrTran() below if for strict xHarbour
* compatibility though it should be reverted when it will
* be fixed in xHarbour
*/
aResult := HB_DirScan( cFilePath, cMask + cExt, ;
StrTran( Upper( cAttr ), "D" ) )
cPathSep := hb_osPathSeparator()
/* xHarbour does not add "D" to attribute list */
aDir := Directory( cPath + cMask, cAttr + "D" )
FOR EACH aFile IN aDir
IF "D" $ aFile[ 5 ]
/* xHarbour does not respect "D" in attribute list */
IF "D" $ cAttr
AAdd( aResult, aFile )
ENDIF
IF !( aFile[ 1 ] == "." .OR. aFile[ 1 ] == ".." )
AEval( DirectoryRecurse( cPath + aFile[ 1 ] + cPathSep + cMask, cAttr ), ;
{ |x| x[ 1 ] := aFile[ 1 ] + cPathSep + x[ 1 ], ;
AAdd( aResult, x ) } )
ENDIF
ELSE
AAdd( aResult, aFile )
ENDIF
NEXT
AEval( aResult, { |x| x[ 1 ] := cFilePath + x[ 1 ] } )
RETURN aResult

View File

@@ -795,6 +795,7 @@ EXTERNAL HB_FILEEXISTS
EXTERNAL HB_DIREXISTS
EXTERNAL HB_FNAMEMERGE
EXTERNAL HB_FNAMESPLIT
EXTERNAL HB_DIRSCAN
EXTERNAL HB_LANGNAME
EXTERNAL HB_LANGSELECT
EXTERNAL HB_LANGERRMSG
@@ -837,7 +838,6 @@ EXTERNAL HB_IDLESTATE
EXTERNAL HB_RELEASECPU
EXTERNAL HB_OSNEWLINE
EXTERNAL HB_OSFILEMASK
EXTERNAL HB_APARAMS
EXTERNAL HB_PVALUE
EXTERNAL HB_FORNEXT
@@ -846,6 +846,7 @@ EXTERNAL HB_METHODNAME
EXTERNAL HB_SETMACRO
EXTERNAL HB_STOD
EXTERNAL HB_WILDMATCH
EXTERNAL HB_FILEMATCH
EXTERNAL HB_CLOCKS2SECS
EXTERNAL HB_MATHERMODE
EXTERNAL HB_MATHERBLOCK
@@ -1053,6 +1054,7 @@ EXTERNAL HB_OSDRIVESEPARATOR
EXTERNAL HB_OSPATHDELIMITERS
EXTERNAL HB_OSPATHLISTSEPARATOR
EXTERNAL HB_OSPATHSEPARATOR
EXTERNAL HB_OSFILEMASK
EXTERNAL HB_SETKEYARRAY
EXTERNAL HB_SETKEYCHECK
EXTERNAL HB_SETKEYGET

View File

@@ -170,6 +170,7 @@ PRG_SOURCES=\
dbedit.prg \
devoutp.prg \
dircmd.prg \
dirscan.prg \
einstv52.prg \
einstvar.prg \
einstvau.prg \

View File

@@ -0,0 +1,96 @@
/*
* $Id$
*/
/*
* Harbour Project source code:
* HB_DirScan()
*
* Copyright 2008 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
* www - http://www.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.
*
*/
STATIC FUNCTION HB_doScan( cPath, cMask, cAttr, cPathSep )
LOCAL aResult, aFile
LOCAL lMatch
aResult := {}
FOR EACH aFile IN Directory( cPath + hb_osFileMask(), cAttr + "D" )
lMatch = HB_FileMatch( aFile[ 1 ], cMask )
IF "D" $ aFile[ 5 ]
IF lMatch .AND. "D" $ cAttr
AAdd( aResult, aFile )
ENDIF
IF !( aFile[ 1 ] == "." .OR. aFile[ 1 ] == ".." .OR. aFile[ 1 ] == "" )
AEval( HB_DoScan( cPath + aFile[ 1 ] + cPathSep, cMask, cAttr, cPathSep ), ;
{ |x| x[ 1 ] := aFile[ 1 ] + cPathSep + x[ 1 ], ;
AAdd( aResult, x ) } )
ENDIF
ELSEIF lMatch
AAdd( aResult, aFile )
ENDIF
NEXT
RETURN aResult
FUNCTION HB_DirScan( cPath, cFileMask, cAttr )
LOCAL cFilePath, cPathSep
cPathSep := hb_osPathSeparator()
IF Empty( cPath )
cFilePath := ""
ELSE
cFilePath := cPath
IF !Right( cPath, 1 ) $ hb_osPathDelimiters()
cFilePath += cPathSep
ENDIF
ENDIF
RETURN HB_DoScan( cFilePath, ;
IIF( Empty( cFileMask ), hb_osFileMask(), cFileMask ), ;
IIF( ValType( cAttr ) $ "CM", cAttr, "" ), ;
cPathSep )

View File

@@ -320,3 +320,9 @@ HB_FUNC( HB_WILDMATCH )
hb_parl( 3 ) ? hb_strMatchWildExact( hb_parc( 2 ), hb_parc( 1 ) ) :
hb_strMatchWild( hb_parc( 2 ), hb_parc( 1 ) ) );
}
HB_FUNC( HB_FILEMATCH )
{
hb_retl( ( ! ISCHAR( 1 ) || ! ISCHAR( 2 ) ) ? FALSE :
hb_strMatchFile( hb_parc( 1 ), hb_parc( 2 ) ) );
}