Files
Przemysław Czerpak 3bb0f06ec9 2017-11-14 19:44 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* contrib/hbmzip/mzip.c
    * use 'char *' instead of 'zipcharpc' to compile with minizip versions
      which do not define 'zipcharpc' type
2017-11-14 19:44:22 +01:00

1731 lines
49 KiB
C

/*
* Wrapper functions for minizip library
* Some higher-level ZIP archive functions
*
* Copyright 2008 Mindaugas Kavaliauskas <dbtopas.at.dbtopas.lt>
* Copyright 2011-2013 Viktor Szakats (vszakats.net/harbour) (codepage/unicode)
*
* 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 program; see the file LICENSE.txt. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA (or visit https://www.gnu.org/licenses/).
*
* 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.
*
*/
#if ! defined( _LARGEFILE64_SOURCE )
# define _LARGEFILE64_SOURCE 1
#endif
#include "hbapi.h"
#include "hbapiitm.h"
#include "hbapierr.h"
#include "hbapistr.h"
#include "hbdate.h"
#include "hbset.h"
#if ! defined( HB_OS_UNIX )
# undef _LARGEFILE64_SOURCE
#endif
#include "zip.h"
#include "unzip.h"
#if defined( HB_OS_UNIX )
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <utime.h>
#elif defined( HB_OS_DOS )
#if defined( __DJGPP__ ) || defined( __RSX32__ ) || defined( __GNUC__ )
#include "hb_io.h"
#include <sys/param.h>
#if defined( HB_OS_DOS )
#include <time.h>
#include <utime.h>
#endif
#endif
#elif defined( HB_OS_WIN )
#include <windows.h>
#if ! defined( INVALID_FILE_ATTRIBUTES )
#define INVALID_FILE_ATTRIBUTES ( ( DWORD ) -1 )
#endif
#include "hbwinuni.h"
#elif defined( HB_OS_OS2 )
#define INCL_DOSFILEMGR
#define INCL_ERRORS
#include <os2.h>
#endif
#if ! defined( HB_USE_LARGEFILE64 ) && defined( HB_OS_UNIX )
#if defined( __USE_LARGEFILE64 )
/*
* The macro: __USE_LARGEFILE64 is set when _LARGEFILE64_SOURCE is
* defined and effectively enables lseek64()/flock64()/ftruncate64()
* functions on 32-bit machines.
*/
#define HB_USE_LARGEFILE64
#elif defined( HB_OS_UNIX ) && defined( O_LARGEFILE )
#define HB_USE_LARGEFILE64
#endif
#endif
#define _ZIP_FLAG_UNICODE ( 1 << 11 ) /* Language encoding flag (EFS) */
#if defined( HB_OS_UNIX )
#define _VER_PLATFORM 0x03 /* it's necessary for file attributes in unzip */
#else
#define _VER_PLATFORM 0x00
#endif
static int _version_made_by( HB_BOOL fUnicode )
{
return ( fUnicode ? 0x3F /* 6.3.x */ : 0x14 /* 2.0.x */ ) | ( _VER_PLATFORM << 8 );
}
#define HB_Z_IOBUF_SIZE ( 1024 * 16 )
static HB_GARBAGE_FUNC( hb_zipfile_destructor )
{
zipFile * phZip = ( zipFile * ) Cargo;
if( *phZip )
{
zipClose( *phZip, NULL );
*phZip = NULL;
}
}
static const HB_GC_FUNCS s_gcZipFileFuncs =
{
hb_zipfile_destructor,
hb_gcDummyMark
};
static zipFile hb_zipfileParam( int iParam )
{
zipFile * phZip = ( zipFile * ) hb_parptrGC( &s_gcZipFileFuncs, iParam );
if( phZip && *phZip )
return *phZip;
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
return NULL;
}
static HB_GARBAGE_FUNC( hb_unzipfile_destructor )
{
unzFile * phUnzip = ( unzFile * ) Cargo;
if( *phUnzip )
{
unzClose( *phUnzip );
*phUnzip = NULL;
}
}
static const HB_GC_FUNCS s_gcUnZipFileFuncs =
{
hb_unzipfile_destructor,
hb_gcDummyMark
};
static unzFile hb_unzipfileParam( int iParam )
{
unzFile * phUnzip = ( unzFile * ) hb_parptrGC( &s_gcUnZipFileFuncs, iParam );
if( phUnzip && *phUnzip )
return *phUnzip;
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
return NULL;
}
static PHB_FILE hb_fileHandleParam( int iParam, HB_BOOL * pfFree )
{
PHB_FILE pFile = NULL;
* pfFree = HB_FALSE;
if( HB_ISNUM( iParam ) )
{
HB_FHANDLE hFile = hb_numToHandle( hb_parnint( iParam ) );
if( hFile != FS_ERROR )
{
pFile = hb_fileFromHandle( hFile );
* pfFree = HB_TRUE;
}
}
else
pFile = hb_fileParam( iParam );
if( pFile != NULL )
return pFile;
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
return NULL;
}
static HB_FATTR hb_translateExtAttr( const char * szFileName, HB_FATTR ulExtAttr )
{
int iLen;
iLen = ( int ) strlen( szFileName );
if( ( iLen > 4 && ( hb_stricmp( szFileName + iLen - 4, ".exe" ) == 0 ||
hb_stricmp( szFileName + iLen - 4, ".com" ) == 0 ||
hb_stricmp( szFileName + iLen - 4, ".bat" ) == 0 ||
hb_stricmp( szFileName + iLen - 4, ".cmd" ) == 0 ) ) ||
( iLen > 3 && hb_stricmp( szFileName + iLen - 3, ".sh" ) == 0 ) )
{
ulExtAttr |= 0x00490000; /* --x--x--x */
}
if( ulExtAttr & HB_FA_READONLY )
ulExtAttr |= 0x01240000; /* r--r--r-- */
else
ulExtAttr |= 0x01B60000; /* rw-rw-rw- */
if( ulExtAttr & HB_FA_DIRECTORY )
ulExtAttr |= 0x40000000;
else
ulExtAttr |= 0x80000000;
return ulExtAttr;
}
/* hb_zipOpen( cFileName, [ iMode = HB_ZIP_CREATE ], [ @cGlobalComment ] ) --> hZip */
HB_FUNC( HB_ZIPOPEN )
{
const char * szFileName = hb_parc( 1 );
if( szFileName )
{
const char * pszGlobalComment = NULL;
char * pszFree;
zipFile hZip = zipOpen2( hb_fsNameConv( szFileName, &pszFree ), hb_parnidef( 2, APPEND_STATUS_CREATE ),
&pszGlobalComment, NULL );
if( pszFree )
hb_xfree( pszFree );
if( hZip )
{
zipFile * phZip = ( zipFile * ) hb_gcAllocate( sizeof( zipFile ), &s_gcZipFileFuncs );
*phZip = hZip;
hb_retptrGC( phZip );
if( pszGlobalComment )
hb_storc( pszGlobalComment, 3 );
}
}
else
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* hb_zipClose( hZip, [ cGlobalComment ] ) --> nError */
HB_FUNC( HB_ZIPCLOSE )
{
zipFile * phZip = ( zipFile * ) hb_parptrGC( &s_gcZipFileFuncs, 1 );
if( phZip && *phZip )
{
zipFile hZip = *phZip;
*phZip = NULL;
hb_retni( zipClose( hZip, hb_parc( 2 ) ) );
}
else
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* hb_zipFileCreate( hZip, cZipName, dDate, cTime, nInternalAttr, nExternalAttr,
[ nMethod = HB_ZLIB_METHOD_DEFLATE ],
[ nLevel = HB_ZLIB_COMPRESSION_DEFAULT ],
[ cPassword, ulFileCRC32 ], [ cComment ], [ lUnicode ] ) --> nError */
HB_FUNC( HB_ZIPFILECREATE )
{
const char * szZipName = hb_parc( 2 );
if( szZipName )
{
zipFile hZip = hb_zipfileParam( 1 );
if( hZip )
{
int iMethod = hb_parnidef( 7, Z_DEFLATED );
int iLevel = hb_parnidef( 8, Z_DEFAULT_COMPRESSION );
long lJulian, lMillisec;
int iYear, iMonth, iDay, iHour, iMinute, iSecond, iMSec;
uLong flags = 0;
HB_BOOL fUnicode = hb_parl( 12 );
void * hZipName = NULL;
void * hComment = NULL;
const char * szComment;
zip_fileinfo zfi;
memset( &zfi, 0, sizeof( zfi ) );
if( HB_ISTIMESTAMP( 3 ) )
{
hb_partdt( &lJulian, &lMillisec, 3 );
hb_dateDecode( lJulian, &iYear, &iMonth, &iDay );
hb_timeDecode( lMillisec, &iHour, &iMinute, &iSecond, &iMSec );
}
else
{
hb_dateDecode( hb_pardl( 3 ), &iYear, &iMonth, &iDay );
hb_timeStrGet( hb_parc( 4 ), &iHour, &iMinute, &iSecond, &iMSec );
}
zfi.tmz_date.tm_hour = iHour;
zfi.tmz_date.tm_min = iMinute;
zfi.tmz_date.tm_sec = iSecond;
zfi.tmz_date.tm_year = iYear;
zfi.tmz_date.tm_mon = iMonth - 1;
zfi.tmz_date.tm_mday = iDay;
zfi.internal_fa = hb_parnl( 5 );
zfi.external_fa = hb_parnl( 6 );
#if ! defined( HB_OS_UNIX )
if( ( zfi.external_fa & 0xFFFF0000 ) == 0 )
zfi.external_fa = hb_translateExtAttr( szZipName, zfi.external_fa );
#endif
if( fUnicode )
{
szZipName = hb_parstr_utf8( 2, &hZipName, NULL );
szComment = hb_parstr_utf8( 11, &hComment, NULL );
flags |= _ZIP_FLAG_UNICODE;
}
else
szComment = hb_parc( 11 );
hb_retni( zipOpenNewFileInZip4( hZip, szZipName, &zfi,
NULL, 0, NULL, 0,
szComment, iMethod, iLevel, 0,
-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
hb_parc( 9 ), hb_parnl( 10 ), _version_made_by( fUnicode ), flags ) );
if( fUnicode )
{
hb_strfree( hZipName );
hb_strfree( hComment );
}
}
}
else
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* hb_zipFileWrite( hZip, cData [, nLen ] ) --> nError */
HB_FUNC( HB_ZIPFILEWRITE )
{
const char * pData = hb_parc( 2 );
if( pData )
{
zipFile hZip = hb_zipfileParam( 1 );
if( hZip )
{
HB_SIZE nLen = hb_parclen( 2 );
if( HB_ISNUM( 3 ) )
{
HB_SIZE nWrite = hb_parns( 3 );
if( nWrite < nLen )
nLen = nWrite;
}
hb_retni( zipWriteInFileInZip( hZip, pData, ( unsigned ) nLen ) );
}
}
else
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* hb_zipFileClose( hZip ) --> nError */
HB_FUNC( HB_ZIPFILECLOSE )
{
zipFile hZip = hb_zipfileParam( 1 );
if( hZip )
hb_retni( zipCloseFileInZip( hZip ) );
}
/* hb_unzipOpen( cFileName ) --> hUnzip */
HB_FUNC( HB_UNZIPOPEN )
{
const char * szFileName = hb_parc( 1 );
if( szFileName )
{
char * pszFree;
unzFile hUnzip = unzOpen( hb_fsNameConv( szFileName, &pszFree ) );
if( pszFree )
hb_xfree( pszFree );
if( hUnzip )
{
unzFile * phUnzip = ( unzFile * ) hb_gcAllocate( sizeof( unzFile ), &s_gcUnZipFileFuncs );
*phUnzip = hUnzip;
hb_retptrGC( phUnzip );
}
}
else
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* hb_unzipClose( hUnzip ) --> nError */
HB_FUNC( HB_UNZIPCLOSE )
{
unzFile * phUnzip = ( unzFile * ) hb_parptrGC( &s_gcUnZipFileFuncs, 1 );
if( phUnzip && *phUnzip )
{
unzFile hUnzip = *phUnzip;
*phUnzip = NULL;
hb_retni( unzClose( hUnzip ) );
}
else
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* hb_unzipGlobalInfo( hUnzip, @nEntries, @cGlobalComment ) --> nError */
HB_FUNC( HB_UNZIPGLOBALINFO )
{
unzFile hUnzip = hb_unzipfileParam( 1 );
if( hUnzip )
{
unz_global_info ugi;
int iResult;
iResult = unzGetGlobalInfo( hUnzip, &ugi );
hb_retni( iResult );
if( iResult == UNZ_OK )
{
hb_storni( ugi.number_entry, 2 );
if( HB_ISBYREF( 3 ) )
{
if( ugi.size_comment > 0 )
{
char * pszComment = ( char * ) hb_xgrab( ugi.size_comment + 1 );
iResult = unzGetGlobalComment( hUnzip, pszComment, ugi.size_comment );
if( iResult < 0 )
{
hb_xfree( pszComment );
hb_storc( NULL, 3 );
hb_retni( iResult );
}
else
{
pszComment[ iResult ] = '\0';
if( ! hb_storclen_buffer( pszComment, ugi.size_comment, 3 ) )
hb_xfree( pszComment );
}
}
}
}
else
{
hb_storni( 0, 2 );
hb_storc( NULL, 3 );
}
}
}
/* hb_unzipFileFirst( hUnzip ) --> nError */
HB_FUNC( HB_UNZIPFILEFIRST )
{
unzFile hUnzip = hb_unzipfileParam( 1 );
if( hUnzip )
hb_retni( unzGoToFirstFile( hUnzip ) );
}
/* hb_unzipFileNext( hUnzip ) --> nError */
HB_FUNC( HB_UNZIPFILENEXT )
{
unzFile hUnzip = hb_unzipfileParam( 1 );
if( hUnzip )
hb_retni( unzGoToNextFile( hUnzip ) );
}
/* hb_unzipFilePos( hUnzip ) --> nPosition */
HB_FUNC( HB_UNZIPFILEPOS )
{
unzFile hUnzip = hb_unzipfileParam( 1 );
if( hUnzip )
hb_retnint( unzGetOffset( hUnzip ) );
}
/* hb_unzipFileGoto( hUnzip, nPosition ) --> nError */
HB_FUNC( HB_UNZIPFILEGOTO )
{
unzFile hUnzip = hb_unzipfileParam( 1 );
if( hUnzip )
hb_retni( unzSetOffset( hUnzip, ( uLong ) hb_parnint( 2 ) ) );
}
/* hb_unzipFileInfo( hUnzip, @cZipName, @dDate, @cTime,
@nInternalAttr, @nExternalAttr,
@nMethod, @nSize, @nCompressedSize,
@lCrypted, @cComment, @nCRC ) --> nError */
HB_FUNC( HB_UNZIPFILEINFO )
{
unzFile hUnzip = hb_unzipfileParam( 1 );
if( hUnzip )
{
char szFileName[ HB_PATH_MAX * 3 ];
unz_file_info ufi;
int iResult;
iResult = unzGetCurrentFileInfo( hUnzip, &ufi, szFileName, sizeof( szFileName ) - 1,
NULL, 0, NULL, 0 );
hb_retni( iResult );
if( iResult == UNZ_OK )
{
HB_BOOL fUnicode = ( ufi.flag & _ZIP_FLAG_UNICODE ) != 0;
long lJulian, lMillisec;
szFileName[ sizeof( szFileName ) - 1 ] = '\0';
if( fUnicode )
hb_storstr_utf8( szFileName, 2 );
else
hb_storc( szFileName, 2 );
lJulian = hb_dateEncode( ufi.tmu_date.tm_year, ufi.tmu_date.tm_mon + 1,
ufi.tmu_date.tm_mday );
lMillisec = hb_timeEncode( ufi.tmu_date.tm_hour, ufi.tmu_date.tm_min,
ufi.tmu_date.tm_sec, 0 );
hb_stortdt( lJulian, lMillisec, 3 );
if( HB_ISBYREF( 4 ) )
{
char buf[ 16 ];
hb_snprintf( buf, sizeof( buf ), "%02d:%02d:%02d",
ufi.tmu_date.tm_hour, ufi.tmu_date.tm_min,
ufi.tmu_date.tm_sec );
hb_storc( buf, 4 );
}
hb_stornl( ufi.internal_fa, 5 );
hb_stornl( ufi.external_fa, 6 );
hb_stornl( ufi.compression_method, 7 );
hb_storns( ufi.uncompressed_size, 8 );
hb_storns( ufi.compressed_size, 9 );
hb_storl( ( ufi.flag & 1 ) != 0, 10 );
hb_stornint( ufi.crc, 12 );
if( ufi.size_file_comment > 0 && HB_ISBYREF( 11 ) )
{
char * pszComment = ( char * ) hb_xgrab( ufi.size_file_comment + 1 );
iResult = unzGetCurrentFileInfo( hUnzip, &ufi, NULL, 0, NULL, 0,
pszComment, ufi.size_file_comment );
pszComment[ ufi.size_file_comment ] = '\0';
if( iResult != UNZ_OK )
{
hb_xfree( pszComment );
hb_storc( NULL, 11 );
}
else if( fUnicode )
{
hb_storstrlen_utf8( pszComment, ufi.size_file_comment, 11 );
hb_xfree( pszComment );
}
else if( ! hb_storclen_buffer( pszComment, ufi.size_file_comment, 11 ) )
hb_xfree( pszComment );
}
}
else
{
hb_storc( NULL, 2 );
hb_stortdt( 0, 0, 3 );
hb_storc( NULL, 4 );
hb_stornl( 0, 5 );
hb_stornl( 0, 6 );
hb_stornl( 0, 7 );
hb_storns( 0, 8 );
hb_storns( 0, 9 );
hb_storl( HB_FALSE, 10 );
hb_storc( NULL, 11 );
}
}
}
/* hb_unzipFileOpen( hUnzip, [ cPassword ] ) --> nError */
HB_FUNC( HB_UNZIPFILEOPEN )
{
unzFile hUnzip = hb_unzipfileParam( 1 );
if( hUnzip )
hb_retni( unzOpenCurrentFilePassword( hUnzip, hb_parc( 2 ) ) );
}
/* hb_unzipFileRead( hUnzip, @cBuf [, nLen ] ) --> nRead */
HB_FUNC( HB_UNZIPFILEREAD )
{
PHB_ITEM pBuffer = hb_param( 2, HB_IT_STRING );
char * buffer;
HB_SIZE nSize;
if( pBuffer && HB_ISBYREF( 2 ) &&
hb_itemGetWriteCL( pBuffer, &buffer, &nSize ) )
{
unzFile hUnzip = hb_unzipfileParam( 1 );
if( hUnzip )
{
if( HB_ISNUM( 3 ) )
{
HB_SIZE nRead = hb_parns( 3 );
if( nRead < nSize )
nSize = nRead;
}
hb_retns( unzReadCurrentFile( hUnzip, buffer, ( unsigned ) nSize ) );
}
}
else
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
/* hb_unzipFileClose( hUnzip ) --> nError */
HB_FUNC( HB_UNZIPFILECLOSE )
{
unzFile hUnzip = hb_unzipfileParam( 1 );
if( hUnzip )
hb_retni( unzCloseCurrentFile( hUnzip ) );
}
/*
*
* Higher-level functions - not wrappers of minizip code
*
*/
static HB_BOOL hb_zipGetFileInfoFromHandle( PHB_FILE pFile, HB_U32 * pulCRC, HB_BOOL * pfText )
{
HB_BOOL fText = pfText != NULL, fResult = HB_FALSE;
HB_U32 ulCRC = 0;
if( pFile != NULL )
{
unsigned char * pString = ( unsigned char * ) hb_xgrab( HB_Z_IOBUF_SIZE );
HB_SIZE nRead;
do
{
nRead = hb_fileRead( pFile, pString, HB_Z_IOBUF_SIZE, -1 );
if( nRead > 0 && nRead != ( HB_SIZE ) FS_ERROR )
{
ulCRC = crc32( ulCRC, pString, ( uInt ) nRead );
if( fText )
{
HB_SIZE u;
for( u = 0; u < nRead; ++u )
{
if( pString[ u ] < 0x20 ?
( pString[ u ] != HB_CHAR_HT &&
pString[ u ] != HB_CHAR_LF &&
pString[ u ] != HB_CHAR_CR &&
pString[ u ] != HB_CHAR_EOF ) :
( pString[ u ] >= 0x7F && pString[ u ] < 0xA0 &&
pString[ u ] != ( unsigned char ) HB_CHAR_SOFT1 ) )
{
fText = HB_FALSE;
break;
}
}
}
}
}
while( nRead == HB_Z_IOBUF_SIZE );
fResult = ( hb_fsError() == 0 );
hb_xfree( pString );
}
if( pulCRC )
*pulCRC = ulCRC;
if( pfText )
*pfText = fText;
return fResult;
}
static HB_BOOL hb_zipGetFileInfo( const char * pszFileName, HB_U32 * pulCRC, HB_BOOL * pfText )
{
PHB_FILE pFile;
HB_BOOL fResult;
pFile = hb_fileExtOpen( pszFileName, NULL,
FO_READ | FO_SHARED | FO_PRIVATE | FXO_SHARELOCK,
NULL, NULL );
fResult = hb_zipGetFileInfoFromHandle( pFile, pulCRC, pfText );
if( pFile != NULL )
hb_fileClose( pFile );
return fResult;
}
/* hb_zipFileCRC32( cFileName ) --> nCRC */
HB_FUNC( HB_ZIPFILECRC32 )
{
const char * szFileName = hb_parc( 1 );
if( szFileName )
{
HB_U32 ulCRC = 0;
if( ! hb_zipGetFileInfo( szFileName, &ulCRC, NULL ) )
ulCRC = 0;
hb_retnint( ulCRC );
}
else
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
static int hb_zipStoreFile( zipFile hZip, int iParamFileName, int iParamZipName, const char * szPassword, int iParamComment, HB_BOOL fUnicode )
{
const char * szFileName = hb_parc( iParamFileName );
PHB_FILE pFile;
HB_SIZE nLen;
HB_FATTR ulExtAttr;
zip_fileinfo zfi;
int iResult;
HB_BOOL fError;
HB_BOOL fText;
HB_U32 ulCRC;
uLong flags = 0;
void * hZipName = NULL;
void * hComment = NULL;
char * szZipName;
const char * szComment;
memset( &zfi, 0, sizeof( zfi ) );
fError = HB_FALSE;
ulExtAttr = 0;
#if defined( HB_OS_WIN )
if( hb_fileIsLocalName( szFileName ) )
{
LPTSTR lpFileNameFree;
LPCTSTR lpFileName = HB_FSNAMECONV( szFileName, &lpFileNameFree );
DWORD attr = GetFileAttributes( lpFileName );
if( attr != INVALID_FILE_ATTRIBUTES )
{
ulExtAttr = attr & ( FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY |
FILE_ATTRIBUTE_ARCHIVE );
}
else
fError = HB_TRUE;
if( lpFileNameFree )
hb_xfree( lpFileNameFree );
}
else
#elif defined( HB_OS_OS2 )
if( hb_fileIsLocalName( szFileName ) )
{
FILESTATUS3 fs3;
APIRET ulrc;
char * pszFree;
ulrc = DosQueryPathInfo( ( PCSZ ) hb_fsNameConv( szFileName, &pszFree ), FIL_STANDARD, &fs3, sizeof( fs3 ) );
if( pszFree )
hb_xfree( pszFree );
if( ulrc == NO_ERROR )
{
if( fs3.attrFile & FILE_READONLY )
ulExtAttr |= HB_FA_READONLY;
if( fs3.attrFile & FILE_HIDDEN )
ulExtAttr |= HB_FA_HIDDEN;
if( fs3.attrFile & FILE_SYSTEM )
ulExtAttr |= HB_FA_SYSTEM;
if( fs3.attrFile & FILE_DIRECTORY )
ulExtAttr |= HB_FA_DIRECTORY;
if( fs3.attrFile & FILE_ARCHIVED )
ulExtAttr |= HB_FA_ARCHIVE;
zfi.tmz_date.tm_sec = fs3.ftimeLastWrite.twosecs * 2;
zfi.tmz_date.tm_min = fs3.ftimeLastWrite.minutes;
zfi.tmz_date.tm_hour = fs3.ftimeLastWrite.hours;
zfi.tmz_date.tm_mday = fs3.fdateLastWrite.day;
zfi.tmz_date.tm_mon = fs3.fdateLastWrite.month;
zfi.tmz_date.tm_year = fs3.fdateLastWrite.year + 1980;
}
else
fError = HB_TRUE;
}
else
#elif defined( HB_OS_UNIX )
if( hb_fileIsLocalName( szFileName ) )
{
struct tm st;
time_t ftime;
char * pszFree;
# if defined( HB_USE_LARGEFILE64 )
struct stat64 statbuf;
if( stat64( hb_fsNameConv( szFileName, &pszFree ), &statbuf ) == 0 )
# else
struct stat statbuf;
if( stat( hb_fsNameConv( szFileName, &pszFree ), &statbuf ) == 0 )
# endif
{
if( S_ISDIR( statbuf.st_mode ) )
{
ulExtAttr |= 0x40000000;
ulExtAttr |= 0x10; /* FILE_ATTRIBUTE_DIRECTORY */
}
else
{
ulExtAttr |= 0x80000000;
ulExtAttr |= 0x20; /* FILE_ATTRIBUTE_ARCHIVE */
}
ulExtAttr |= ( ( statbuf.st_mode & S_IXOTH ) ? 0x00010000 : 0 ) |
( ( statbuf.st_mode & S_IWOTH ) ? 0x00020000 : 0 ) |
( ( statbuf.st_mode & S_IROTH ) ? 0x00040000 : 0 ) |
( ( statbuf.st_mode & S_IXGRP ) ? 0x00080000 : 0 ) |
( ( statbuf.st_mode & S_IWGRP ) ? 0x00100000 : 0 ) |
( ( statbuf.st_mode & S_IRGRP ) ? 0x00200000 : 0 ) |
( ( statbuf.st_mode & S_IXUSR ) ? 0x00400000 : 0 ) |
( ( statbuf.st_mode & S_IWUSR ) ? 0x00800000 : 0 ) |
( ( statbuf.st_mode & S_IRUSR ) ? 0x01000000 : 0 );
ftime = statbuf.st_mtime;
# if defined( HB_HAS_LOCALTIME_R )
localtime_r( &ftime, &st );
# else
st = *localtime( &ftime );
# endif
zfi.tmz_date.tm_sec = st.tm_sec;
zfi.tmz_date.tm_min = st.tm_min;
zfi.tmz_date.tm_hour = st.tm_hour;
zfi.tmz_date.tm_mday = st.tm_mday;
zfi.tmz_date.tm_mon = st.tm_mon;
zfi.tmz_date.tm_year = st.tm_year;
}
else
fError = HB_TRUE;
if( pszFree )
hb_xfree( pszFree );
}
else
#endif
{
HB_FATTR attr;
long lJulian, lMillisec;
if( ! hb_fileAttrGet( szFileName, &attr ) )
ulExtAttr = 0x81B60020; /* HB_FA_ARCHIVE | rw-rw-rw- */
else
{
#if defined( HB_OS_UNIX )
if( attr & HB_FA_DIRECTORY )
ulExtAttr |= 0x40000000;
else
{
ulExtAttr |= 0x80000000;
ulExtAttr |= HB_FA_ARCHIVE;
}
/* Harbour uses the same binary values for unix access rights and
* DOS/WIN/OS2 attributes so we can use them directly
*/
ulExtAttr |= attr & ( HB_FA_RWXU | HB_FA_RWXG | HB_FA_RWXO );
#endif
ulExtAttr |= attr & ( HB_FA_READONLY | HB_FA_HIDDEN | HB_FA_SYSTEM |
HB_FA_DIRECTORY | HB_FA_ARCHIVE );
}
if( hb_fileTimeGet( szFileName, &lJulian, &lMillisec ) )
{
int iYear, iMonth, iDay;
int iHour, iMinute, iSecond, iMSec;
hb_dateDecode( lJulian, &iYear, &iMonth, &iDay );
hb_timeDecode( lMillisec, &iHour, &iMinute, &iSecond, &iMSec );
zfi.tmz_date.tm_sec = iSecond;
zfi.tmz_date.tm_min = iMinute;
zfi.tmz_date.tm_hour = iHour;
zfi.tmz_date.tm_mday = iDay;
zfi.tmz_date.tm_mon = iMonth - 1;
zfi.tmz_date.tm_year = iYear;
}
}
if( fError )
return -200;
#if ! defined( HB_OS_UNIX )
ulExtAttr = hb_translateExtAttr( szFileName, ulExtAttr );
#endif
if( ! HB_ISCHAR( iParamZipName ) )
iParamZipName = iParamFileName;
if( fUnicode )
{
szZipName = hb_strdup( hb_parstr_utf8( iParamZipName, &hZipName, NULL ) );
szComment = hb_parstr_utf8( iParamComment, &hComment, NULL );
flags |= _ZIP_FLAG_UNICODE;
}
else
{
szZipName = hb_strdup( hb_parc( iParamZipName ) );
szComment = hb_parc( iParamComment );
}
nLen = strlen( szZipName );
if( iParamZipName != iParamFileName )
{
/* change path separators to '/' */
while( nLen-- )
{
if( szZipName[ nLen ] == '\\' )
szZipName[ nLen ] = '/';
}
}
else
{
while( nLen-- )
{
if( szZipName[ nLen ] == '/' || szZipName[ nLen ] == '\\' )
{
memmove( szZipName, &szZipName[ nLen + 1 ], strlen( szZipName ) - nLen );
break;
}
}
}
fText = HB_FALSE;
ulCRC = 0;
zfi.external_fa = ulExtAttr;
/* TODO: zip.exe test: 0 for binary file, 1 for text. Does not depend on
extension. We should analyze content of file to determine this??? */
zfi.internal_fa = 0;
if( ulExtAttr & 0x40000000 )
{
iResult = zipOpenNewFileInZip4( hZip, szZipName, &zfi, NULL, 0, NULL, 0, szComment,
Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0,
-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
szPassword, ulCRC, _version_made_by( fUnicode ), flags );
if( iResult == 0 )
zipCloseFileInZip( hZip );
}
else
{
pFile = hb_fileExtOpen( szFileName, NULL,
FO_READ | FO_SHARED | FO_PRIVATE | FXO_SHARELOCK,
NULL, NULL );
if( pFile != NULL )
{
#if defined( HB_OS_WIN )
if( hb_fileIsLocal( pFile ) )
{
FILETIME ftutc, ft;
SYSTEMTIME st;
if( GetFileTime( ( HANDLE ) hb_fileHandle( pFile ), NULL, NULL, &ftutc ) &&
FileTimeToLocalFileTime( &ftutc, &ft ) &&
FileTimeToSystemTime( &ft, &st ) )
{
zfi.tmz_date.tm_sec = st.wSecond;
zfi.tmz_date.tm_min = st.wMinute;
zfi.tmz_date.tm_hour = st.wHour;
zfi.tmz_date.tm_mday = st.wDay;
zfi.tmz_date.tm_mon = st.wMonth - 1;
zfi.tmz_date.tm_year = st.wYear;
}
}
#endif
if( szPassword )
{
if( hb_zipGetFileInfo( szFileName, &ulCRC, &fText ) )
zfi.internal_fa = fText ? 1 : 0;
}
iResult = zipOpenNewFileInZip4( hZip, szZipName, &zfi, NULL, 0, NULL, 0, szComment,
Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0,
-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
szPassword, ulCRC, _version_made_by( fUnicode ), flags );
if( iResult == 0 )
{
char * pString = ( char * ) hb_xgrab( HB_Z_IOBUF_SIZE );
while( ( nLen = hb_fileRead( pFile, pString, HB_Z_IOBUF_SIZE, -1 ) ) > 0 &&
nLen != ( HB_SIZE ) FS_ERROR )
zipWriteInFileInZip( hZip, pString, ( unsigned ) nLen );
hb_xfree( pString );
zipCloseFileInZip( hZip );
}
hb_fileClose( pFile );
}
else
iResult = -200 - hb_fsError();
}
hb_xfree( szZipName );
if( fUnicode )
{
hb_strfree( hZipName );
hb_strfree( hComment );
}
return iResult;
}
/* hb_zipStoreFile( hZip, cFileName, [ cZipName ], [ cPassword ], [ cComment ], [ lUnicode ] ) --> nError */
HB_FUNC( HB_ZIPSTOREFILE )
{
if( hb_parc( 2 ) )
{
zipFile hZip = hb_zipfileParam( 1 );
if( hZip )
hb_retni( hb_zipStoreFile( hZip, 2, 3, hb_parc( 4 ), 5, hb_parl( 6 ) ) );
}
else
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
static int hb_zipStoreFileHandle( zipFile hZip, PHB_FILE pFile, int iParamZipName, const char * szPassword, int iParamComment, HB_BOOL fUnicode )
{
HB_SIZE nLen;
zip_fileinfo zfi;
int iResult;
HB_BOOL fText;
HB_U32 ulCRC;
uLong flags = 0;
void * hZipName = NULL;
void * hComment = NULL;
char * szZipName;
const char * szComment;
if( pFile == NULL )
return -200;
if( fUnicode )
{
szZipName = hb_strdup( hb_parstr_utf8( iParamZipName, &hZipName, NULL ) );
szComment = hb_parstr_utf8( iParamComment, &hComment, NULL );
flags |= _ZIP_FLAG_UNICODE;
}
else
{
szZipName = hb_strdup( hb_parc( iParamZipName ) );
szComment = hb_parc( iParamComment );
}
/* change path separators to '/' */
nLen = strlen( szZipName );
while( nLen-- )
{
if( szZipName[ nLen ] == '\\' )
szZipName[ nLen ] = '/';
}
memset( &zfi, 0, sizeof( zfi ) );
zfi.external_fa = 0x81B60020;
zfi.tmz_date.tm_sec = 0;
zfi.tmz_date.tm_min = 0;
zfi.tmz_date.tm_hour = 0;
zfi.tmz_date.tm_mday = 1;
zfi.tmz_date.tm_mon = 0;
zfi.tmz_date.tm_year = 0;
ulCRC = 0;
fText = HB_FALSE;
if( szPassword && hb_zipGetFileInfoFromHandle( pFile, &ulCRC, &fText ) )
zfi.internal_fa = fText ? 1 : 0;
else
/* TODO: zip.exe test: 0 for binary file, 1 for text. Does not depend on
extension. We should analyze content of file to determine this??? */
zfi.internal_fa = 0;
iResult = zipOpenNewFileInZip4( hZip, szZipName, &zfi, NULL, 0, NULL, 0, szComment,
Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0,
-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
szPassword, ulCRC, _version_made_by( fUnicode ), flags );
if( iResult == 0 )
{
char * pString = ( char * ) hb_xgrab( HB_Z_IOBUF_SIZE );
hb_fileSeek( pFile, 0, FS_SET );
while( ( nLen = hb_fileRead( pFile, pString, HB_Z_IOBUF_SIZE, -1 ) ) > 0 &&
nLen != ( HB_SIZE ) FS_ERROR )
zipWriteInFileInZip( hZip, pString, ( unsigned ) nLen );
hb_xfree( pString );
zipCloseFileInZip( hZip );
}
hb_xfree( szZipName );
if( fUnicode )
{
hb_strfree( hZipName );
hb_strfree( hComment );
}
return iResult;
}
/* hb_zipStoreFileHandle( hZip, fhnd, cZipName, [ cPassword ], [ cComment ], [ lUnicode ] ) --> nError */
HB_FUNC( HB_ZIPSTOREFILEHANDLE )
{
if( HB_ISCHAR( 3 ) )
{
zipFile hZip = hb_zipfileParam( 1 );
if( hZip )
{
HB_BOOL fFree;
PHB_FILE pFile = hb_fileHandleParam( 2, &fFree );
if( pFile != NULL )
{
hb_retni( hb_zipStoreFileHandle( hZip, pFile, 3, hb_parc( 4 ), 5, hb_parl( 6 ) ) );
if( fFree )
hb_fileDetach( pFile );
}
}
}
else
hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
static int hb_unzipExtractCurrentFile( unzFile hUnzip, const char * szFileName, const char * szPassword )
{
char szNameRaw[ HB_PATH_MAX * 3 ];
char * szName;
HB_SIZE nPos, nLen;
unz_file_info ufi;
int iResult;
PHB_FILE pFile;
iResult = unzGetCurrentFileInfo( hUnzip, &ufi, szNameRaw, sizeof( szNameRaw ) - 1,
NULL, 0, NULL, 0 );
if( iResult != UNZ_OK )
return iResult;
iResult = unzOpenCurrentFilePassword( hUnzip, szPassword );
if( iResult != UNZ_OK )
return iResult;
if( szFileName )
szName = hb_strdup( szFileName );
else
{
HB_BOOL fUnicode = ( ufi.flag & _ZIP_FLAG_UNICODE ) != 0;
if( fUnicode )
{
PHB_ITEM pTemp = hb_itemPutStrUTF8( NULL, szNameRaw );
szName = hb_strdup( hb_itemGetCPtr( pTemp ) );
hb_itemRelease( pTemp );
}
else
szName = hb_strdup( szNameRaw );
}
nLen = strlen( szName );
/* Test shows that files in subdirectories can be stored to zip file without
explicitly adding directory. So, let's create a required path */
nPos = 1;
while( nPos < nLen )
{
char cSep = szName[ nPos ];
/* allow both path separators, ignore terminating path separator */
if( ( cSep == '\\' || cSep == '/' ) && nPos < nLen - 1 )
{
szName[ nPos ] = '\0';
hb_fileDirMake( szName );
szName[ nPos ] = cSep;
}
nPos++;
}
if( ufi.external_fa & 0x40000000 ) /* DIRECTORY */
{
if( ! hb_fileDirMake( szName ) )
iResult = -200 - hb_fsError();
}
else
{
pFile = hb_fileExtOpen( szName, NULL,
FO_READWRITE | FO_EXCLUSIVE | FO_PRIVATE |
FXO_TRUNCATE | FXO_SHARELOCK, NULL, NULL );
if( pFile != NULL )
{
char * pString = ( char * ) hb_xgrab( HB_Z_IOBUF_SIZE );
while( ( iResult = unzReadCurrentFile( hUnzip, pString, HB_Z_IOBUF_SIZE ) ) > 0 )
if( hb_fileWrite( pFile, pString, ( HB_SIZE ) iResult, -1 ) != ( HB_SIZE ) iResult )
break;
hb_xfree( pString );
#if defined( HB_OS_WIN )
if( hb_fileIsLocal( pFile ) )
{
FILETIME ftutc, ft;
SYSTEMTIME st;
st.wSecond = ( WORD ) ufi.tmu_date.tm_sec;
st.wMinute = ( WORD ) ufi.tmu_date.tm_min;
st.wHour = ( WORD ) ufi.tmu_date.tm_hour;
st.wDay = ( WORD ) ufi.tmu_date.tm_mday;
st.wMonth = ( WORD ) ufi.tmu_date.tm_mon + 1;
st.wYear = ( WORD ) ufi.tmu_date.tm_year;
st.wMilliseconds = 0;
if( SystemTimeToFileTime( &st, &ft ) &&
LocalFileTimeToFileTime( &ft, &ftutc ) )
{
SetFileTime( ( HANDLE ) hb_fileHandle( pFile ), &ftutc, &ftutc, &ftutc );
}
}
#endif
hb_fileClose( pFile );
}
else
iResult = -200 - hb_fsError();
}
unzCloseCurrentFile( hUnzip );
#if defined( HB_OS_WIN )
if( hb_fileIsLocalName( szName ) )
{
LPTSTR lpFileNameFree;
LPCTSTR lpFileName = HB_FSNAMECONV( szName, &lpFileNameFree );
SetFileAttributes( ( LPCTSTR ) lpFileName, ufi.external_fa & 0xFF );
if( lpFileNameFree )
hb_xfree( lpFileNameFree );
}
else
#elif defined( HB_OS_OS2 )
if( hb_fileIsLocalName( szName ) )
{
FILESTATUS3 fs3;
APIRET ulrc;
HB_FATTR ulAttr = FILE_NORMAL;
int iAttr = ufi.external_fa & 0xFF;
char * pszFree;
const char * szNameOS = hb_fsNameConv( szName, &pszFree );
if( iAttr & HB_FA_READONLY )
ulAttr |= FILE_READONLY;
if( iAttr & HB_FA_HIDDEN )
ulAttr |= FILE_HIDDEN;
if( iAttr & HB_FA_SYSTEM )
ulAttr |= FILE_SYSTEM;
if( iAttr & HB_FA_ARCHIVE )
ulAttr |= FILE_ARCHIVED;
ulrc = DosQueryPathInfo( ( PCSZ ) szNameOS, FIL_STANDARD, &fs3, sizeof( fs3 ) );
if( ulrc == NO_ERROR )
{
FDATE fdate;
FTIME ftime;
fdate.year = ufi.tmu_date.tm_year - 1980;
fdate.month = ufi.tmu_date.tm_mon;
fdate.day = ufi.tmu_date.tm_mday;
ftime.hours = ufi.tmu_date.tm_hour;
ftime.minutes = ufi.tmu_date.tm_min;
ftime.twosecs = ufi.tmu_date.tm_sec / 2;
fs3.attrFile = ulAttr;
fs3.fdateCreation = fs3.fdateLastAccess = fs3.fdateLastWrite = fdate;
fs3.ftimeCreation = fs3.ftimeLastAccess = fs3.ftimeLastWrite = ftime;
ulrc = DosSetPathInfo( ( PCSZ ) szNameOS, FIL_STANDARD,
&fs3, sizeof( fs3 ), DSPI_WRTTHRU );
}
if( pszFree )
hb_xfree( pszFree );
}
else
#elif defined( HB_OS_UNIX )
if( hb_fileIsLocalName( szName ) )
{
struct utimbuf utim;
struct tm st;
char * pszFree;
const char * szNameOS = hb_fsNameConv( szName, &pszFree );
HB_FATTR ulAttr = ufi.external_fa;
if( ( ulAttr & 0xFFFF0000 ) == 0 )
ulAttr = hb_translateExtAttr( szName, ulAttr );
( void ) chmod( szNameOS,
( ( ulAttr & 0x00010000 ) ? S_IXOTH : 0 ) |
( ( ulAttr & 0x00020000 ) ? S_IWOTH : 0 ) |
( ( ulAttr & 0x00040000 ) ? S_IROTH : 0 ) |
( ( ulAttr & 0x00080000 ) ? S_IXGRP : 0 ) |
( ( ulAttr & 0x00100000 ) ? S_IWGRP : 0 ) |
( ( ulAttr & 0x00200000 ) ? S_IRGRP : 0 ) |
( ( ulAttr & 0x00400000 ) ? S_IXUSR : 0 ) |
( ( ulAttr & 0x00800000 ) ? S_IWUSR : 0 ) |
( ( ulAttr & 0x01000000 ) ? S_IRUSR : 0 ) );
memset( &st, 0, sizeof( st ) );
st.tm_sec = ufi.tmu_date.tm_sec;
st.tm_min = ufi.tmu_date.tm_min;
st.tm_hour = ufi.tmu_date.tm_hour;
st.tm_mday = ufi.tmu_date.tm_mday;
st.tm_mon = ufi.tmu_date.tm_mon;
st.tm_year = ufi.tmu_date.tm_year - 1900;
st.tm_isdst = -1;
utim.actime = utim.modtime = mktime( &st );
( void ) utime( szNameOS, &utim );
if( pszFree )
hb_xfree( pszFree );
}
else
#endif
{
long lJulian, lMillisec;
HB_FATTR ulAttr = ufi.external_fa;
lJulian = hb_dateEncode( ufi.tmu_date.tm_year, ufi.tmu_date.tm_mon + 1,
ufi.tmu_date.tm_mday );
lMillisec = hb_timeEncode( ufi.tmu_date.tm_hour, ufi.tmu_date.tm_min,
ufi.tmu_date.tm_sec, 0 );
hb_fileTimeSet( szName, lJulian, lMillisec );
#if defined( HB_OS_UNIX )
if( ( ulAttr & 0xFFFF0000 ) == 0 )
ulAttr = hb_translateExtAttr( szName, ulAttr );
ulAttr &= 0x01FF0000;
#else
ulAttr &= 0xFF;
#endif
hb_fileAttrSet( szName, ulAttr );
}
hb_xfree( szName );
return iResult;
}
/* hb_unzipExtractCurrentFile( hZip, [ cFileName ], [ cPassword ] ) --> nError */
HB_FUNC( HB_UNZIPEXTRACTCURRENTFILE )
{
unzFile hUnzip = hb_unzipfileParam( 1 );
if( hUnzip )
hb_retni( hb_unzipExtractCurrentFile( hUnzip, hb_parc( 2 ), hb_parc( 3 ) ) );
}
static int hb_unzipExtractCurrentFileToHandle( unzFile hUnzip, PHB_FILE pFile, const char * szPassword )
{
unz_file_info ufi;
int iResult;
if( pFile == NULL )
return -200;
iResult = unzGetCurrentFileInfo( hUnzip, &ufi, NULL, 0,
NULL, 0, NULL, 0 );
if( iResult != UNZ_OK )
return iResult;
iResult = unzOpenCurrentFilePassword( hUnzip, szPassword );
if( iResult != UNZ_OK )
return iResult;
if( ! ( ufi.external_fa & 0x40000000 ) ) /* DIRECTORY */
{
char * pString = ( char * ) hb_xgrab( HB_Z_IOBUF_SIZE );
while( ( iResult = unzReadCurrentFile( hUnzip, pString, HB_Z_IOBUF_SIZE ) ) > 0 )
if( hb_fileWrite( pFile, pString, ( HB_SIZE ) iResult, -1 ) != ( HB_SIZE ) iResult )
break;
hb_xfree( pString );
#if defined( HB_OS_WIN )
if( hb_fileIsLocal( pFile ) )
{
FILETIME ftutc, ft;
SYSTEMTIME st;
st.wSecond = ( WORD ) ufi.tmu_date.tm_sec;
st.wMinute = ( WORD ) ufi.tmu_date.tm_min;
st.wHour = ( WORD ) ufi.tmu_date.tm_hour;
st.wDay = ( WORD ) ufi.tmu_date.tm_mday;
st.wMonth = ( WORD ) ufi.tmu_date.tm_mon + 1;
st.wYear = ( WORD ) ufi.tmu_date.tm_year;
st.wMilliseconds = 0;
if( SystemTimeToFileTime( &st, &ft ) &&
LocalFileTimeToFileTime( &ft, &ftutc ) )
{
SetFileTime( ( HANDLE ) hb_fileHandle( pFile ), &ftutc, &ftutc, &ftutc );
}
}
#endif
}
unzCloseCurrentFile( hUnzip );
return iResult;
}
/* hb_unzipExtractCurrentFileToHandle( hZip, fhnd, [ cPassword ] ) --> nError */
HB_FUNC( HB_UNZIPEXTRACTCURRENTFILETOHANDLE )
{
unzFile hUnzip = hb_unzipfileParam( 1 );
if( hUnzip )
{
HB_BOOL fFree;
PHB_FILE pFile = hb_fileHandleParam( 2, &fFree );
if( pFile != NULL )
{
hb_retni( hb_unzipExtractCurrentFileToHandle( hUnzip, pFile, hb_parc( 3 ) ) );
if( fFree )
hb_fileDetach( pFile );
}
}
}
static int hb_zipDeleteFile( const char * szZipFile, const char * szFileMask )
{
char szTempFile[ HB_PATH_MAX ];
char szCurrFile[ HB_PATH_MAX * 3 ];
PHB_FNAME pFileName;
PHB_FILE pFile;
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;
char * pszFree;
/* open source file */
hUnzip = unzOpen( hb_fsNameConv( szZipFile, &pszFree ) );
if( pszFree )
hb_xfree( pszFree );
if( hUnzip == NULL )
return UNZ_ERRNO;
pFileName = hb_fsFNameSplit( szZipFile );
pFile = hb_fileCreateTemp( pFileName->szPath, NULL, FC_NORMAL, szTempFile );
hZip = NULL;
if( pFile != NULL )
{
hb_fileClose( pFile );
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, sizeof( szCurrFile ) - 1, NULL, 0, NULL, 0 );
if( iResult != UNZ_OK )
break;
if( hb_strMatchFile( szCurrFile, szFileMask ) )
iFilesDel++;
else
{
HB_BOOL fUnicode;
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, &ufi, NULL, 0,
pExtraField, ufi.size_file_extra,
pszFileComment, ufi.size_file_comment );
if( pszFileComment )
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;
}
}
fUnicode = ( ufi.flag & _ZIP_FLAG_UNICODE ) != 0;
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 = zipOpenNewFileInZip4( hZip, szCurrFile, &zfi, pLocalExtraField, iExtraFieldLen, pExtraField, ufi.size_file_extra, pszFileComment,
method, level, 1,
-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
NULL, 0, _version_made_by( fUnicode ), ufi.flag );
if( iResult != UNZ_OK )
break;
if( ufi.compressed_size )
{
void * buffer = 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_fileDelete( szTempFile );
else
{
hb_fileDelete( szZipFile );
if( iFilesLeft == 0 )
hb_fileDelete( szTempFile );
else if( ! hb_fileRename( szTempFile, szZipFile ) )
iResult = UNZ_ERRNO;
}
return iResult;
}
/* hb_zipDeleteFile( cZipFile, cFileMask ) --> nError */
HB_FUNC( HB_ZIPDELETEFILE )
{
const char * szZipFile = hb_parc( 1 );
const 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 );
}