/* * $Id$ */ /* * Harbour Project source code: * Wrapper functions for minizip library * Some higher level zip archive functions * * Copyright 2008 Mindaugas Kavaliauskas * 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 "hbapiitm.h" #include "hbapierr.h" #include "hbdate.h" #include "hbset.h" #include "zip.h" #include "unzip.h" #if defined( HB_OS_UNIX ) #include #include #include #include #include #elif defined( HB_OS_DOS ) #if defined( __DJGPP__ ) || defined( __RSX32__ ) || defined( __GNUC__ ) #include "hb_io.h" #include #if defined( HB_OS_DOS ) #include #include #endif #endif #elif defined( HB_OS_WIN ) #include #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 #endif #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 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 ) { zipcharpc 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( ( const char * ) 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 ] ) --> 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; 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 hb_retni( zipOpenNewFileInZip3( hZip, szZipName, &zfi, NULL, 0, NULL, 0, hb_parc( 11 ), iMethod, iLevel, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, hb_parc( 9 ), hb_parnl( 10 ) ) ); } } 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 ); HB_ISIZ nLen = hb_parclen( 2 ); if( HB_ISNUM( 3 ) && hb_parns( 3 ) < nLen ) nLen = hb_parns( 3 ); if( hZip ) 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 ]; unz_file_info ufi; int iResult; char buf[ 16 ]; long lJulian, lMillisec; iResult = unzGetCurrentFileInfo( hUnzip, &ufi, szFileName, HB_PATH_MAX - 1, NULL, 0, NULL, 0 ); hb_retni( iResult ); if( iResult == UNZ_OK ) { szFileName[ HB_PATH_MAX - 1 ] = '\0'; 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 ) ) { 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( !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_retnl( 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 a wrappers of minizip code * */ static HB_BOOL hb_zipGetFileInfoFromHandle( HB_FHANDLE hFile, HB_U32 * pulCRC, HB_BOOL * pfText ) { HB_BOOL fText = pfText != NULL, fResult = HB_FALSE; HB_U32 ulCRC = 0; if( hFile != FS_ERROR ) { unsigned char * pString = ( unsigned char * ) hb_xgrab( HB_Z_IOBUF_SIZE ); HB_SIZE nRead, u; do { nRead = hb_fsReadLarge( hFile, pString, HB_Z_IOBUF_SIZE ); if( nRead > 0 ) { ulCRC = crc32( ulCRC, pString, ( uInt ) nRead ); if( fText ) { 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 * szFileName, HB_U32 * pulCRC, HB_BOOL * pfText ) { HB_FHANDLE hFile; HB_BOOL fResult; hFile = hb_fsOpen( szFileName, FO_READ ); fResult = hb_zipGetFileInfoFromHandle( hFile, pulCRC, pfText ); if( hFile != FS_ERROR ) hb_fsClose( hFile ); return fResult; } /* HB_zipFileCRC32( cFileName ) --> nError */ 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, const char * szFileName, const char * szName, const char * szPassword, const char * szComment ) { char * szZipName, * pString; HB_FHANDLE hFile; HB_SIZE nLen; HB_FATTR ulExtAttr; zip_fileinfo zfi; int iResult; HB_BOOL fError; HB_BOOL fText; HB_U32 ulCRC; if( szName ) { /* change path separators to '/' */ szZipName = hb_strdup( szName ); nLen = strlen( szZipName ); pString = szZipName; while( nLen-- ) { if( pString[ nLen ] == '\\' ) pString[ nLen ] = '/'; } } else { /* get file name */ szZipName = hb_strdup( szFileName ); nLen = strlen( szZipName ); pString = szZipName; while( nLen-- ) { if( pString[ nLen ] == '/' || pString[ nLen ] == '\\' ) { memmove( szZipName, &pString[ nLen + 1 ], strlen( szZipName ) - nLen ); break; } } } memset( &zfi, 0, sizeof( zfi ) ); fError = HB_FALSE; ulExtAttr = 0; #if defined( HB_OS_WIN ) { LPTSTR lpFileNameFree; LPCTSTR lpFileName = HB_FSNAMECONV( szFileName, &lpFileNameFree ); DWORD attr = GetFileAttributes( lpFileName ); if( attr != INVALID_FILE_ATTRIBUTES ) { ulExtAttr = hb_translateExtAttr( szFileName, 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 ); } #elif defined( HB_OS_UNIX ) { struct stat statbuf; struct tm st; char * pszFree; if( stat( hb_fsNameConv( szFileName, &pszFree ), &statbuf ) == 0 ) { 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 ); # if defined( HB_HAS_LOCALTIME_R ) localtime_r( &statbuf.st_mtime, &st ); # else st = *localtime( &statbuf.st_mtime ); # 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 ); } #elif defined( HB_OS_DOS ) { # if defined( __DJGPP__ ) || defined( __RSX32__ ) || defined( __GNUC__ ) int attr; char * pszFree; attr = _chmod( hb_fsNameConv( szFileName, &pszFree ), 0, 0 ); if( pszFree ) hb_xfree( pszFree ); if( attr != -1 ) # else HB_FATTR attr; if( hb_fsGetAttr( szFileName, &attr ) ) # endif { ulExtAttr = attr & ( HB_FA_READONLY | HB_FA_HIDDEN | HB_FA_SYSTEM | HB_FA_DIRECTORY | HB_FA_ARCHIVE ); ulExtAttr = hb_translateExtAttr( szFileName, ulExtAttr ); } else fError = HB_TRUE; } #elif defined( HB_OS_OS2 ) { FILESTATUS3 fs3; APIRET ulrc; HB_FATTR ulAttr; char * pszFree; ulrc = DosQueryPathInfo( ( PCSZ ) hb_fsNameConv( szFileName, &pszFree ), FIL_STANDARD, &fs3, sizeof( fs3 ) ); if( pszFree ) hb_xfree( pszFree ); if( ulrc == NO_ERROR ) { ulAttr = 0; if( fs3.attrFile & FILE_READONLY ) ulAttr |= HB_FA_READONLY; if( fs3.attrFile & FILE_HIDDEN ) ulAttr |= HB_FA_HIDDEN; if( fs3.attrFile & FILE_SYSTEM ) ulAttr |= HB_FA_SYSTEM; if( fs3.attrFile & FILE_DIRECTORY ) ulAttr |= HB_FA_DIRECTORY; if( fs3.attrFile & FILE_ARCHIVED ) ulAttr |= HB_FA_ARCHIVE; ulExtAttr = hb_translateExtAttr( szFileName, ulAttr ); 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 { HB_FATTR attr; if( !hb_fsGetAttr( szFileName, &attr ) ) ulExtAttr = 0x81B60020; /* FILE_ATTRIBUTE_ARCHIVE | rw-rw-rw- */ else { ulExtAttr = attr & ( HB_FA_READONLY | HB_FA_HIDDEN | HB_FA_SYSTEM | HB_FA_DIRECTORY | HB_FA_ARCHIVE ); ulExtAttr = hb_translateExtAttr( szFileName, ulExtAttr ); } } #endif if( fError ) { hb_xfree( szZipName ); return -200; } 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 analyse content of file to determine this??? */ zfi.internal_fa = 0; if( ulExtAttr & 0x40000000 ) { iResult = zipOpenNewFileInZip3( hZip, szZipName, &zfi, NULL, 0, NULL, 0, szComment, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, szPassword, ulCRC ); if( iResult == 0 ) zipCloseFileInZip( hZip ); } else { hFile = hb_fsOpen( szFileName, FO_READ ); if( hFile != FS_ERROR ) { #if defined( HB_OS_WIN ) { FILETIME ftutc, ft; SYSTEMTIME st; if( GetFileTime( ( HANDLE ) hb_fsGetOsHandle( hFile ), 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 = zipOpenNewFileInZip3( hZip, szZipName, &zfi, NULL, 0, NULL, 0, szComment, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, szPassword, ulCRC ); if( iResult == 0 ) { pString = ( char * ) hb_xgrab( HB_Z_IOBUF_SIZE ); while( ( nLen = hb_fsReadLarge( hFile, pString, HB_Z_IOBUF_SIZE ) ) > 0 ) zipWriteInFileInZip( hZip, pString, ( unsigned ) nLen ); hb_xfree( pString ); zipCloseFileInZip( hZip ); } hb_fsClose( hFile ); } else iResult = -200 - hb_fsError(); } hb_xfree( szZipName ); return iResult; } /* HB_ZipStoreFile( hZip, cFileName, [ cZipName ], [ cPassword ], [ cComment ] ) --> nError */ HB_FUNC( HB_ZIPSTOREFILE ) { const char * szFileName = hb_parc( 2 ); if( szFileName ) { zipFile hZip = hb_zipfileParam( 1 ); if( hZip ) hb_retni( hb_zipStoreFile( hZip, szFileName, hb_parc( 3 ), hb_parc( 4 ), hb_parc( 5 ) ) ); } else hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } static int hb_zipStoreFileHandle( zipFile hZip, HB_FHANDLE hFile, const char * szName, const char * szPassword, const char * szComment ) { char * szZipName; HB_SIZE nLen; zip_fileinfo zfi; int iResult; HB_BOOL fText; HB_U32 ulCRC; if( hFile == FS_ERROR || szName == NULL ) return -200; /* change path separators to '/' */ szZipName = hb_strdup( szName ); 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( hFile, &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 analyse content of file to determine this??? */ zfi.internal_fa = 0; iResult = zipOpenNewFileInZip3( hZip, szZipName, &zfi, NULL, 0, NULL, 0, szComment, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, szPassword, ulCRC ); if( iResult == 0 ) { char * pString = ( char * ) hb_xgrab( HB_Z_IOBUF_SIZE ); hb_fsSeek( hFile, 0, FS_SET ); while( ( nLen = hb_fsReadLarge( hFile, pString, HB_Z_IOBUF_SIZE ) ) > 0 ) zipWriteInFileInZip( hZip, pString, ( unsigned ) nLen ); hb_xfree( pString ); zipCloseFileInZip( hZip ); } hb_xfree( szZipName ); return iResult; } /* HB_ZipStoreFileHandle( hZip, fhnd, [ cZipName ], [ cPassword ], [ cComment ] ) --> nError */ HB_FUNC( HB_ZIPSTOREFILEHANDLE ) { HB_FHANDLE hFile = hb_numToHandle( hb_parnint( 2 ) ); if( hFile != FS_ERROR && HB_ISCHAR( 3 ) ) { zipFile hZip = hb_zipfileParam( 1 ); if( hZip ) hb_retni( hb_zipStoreFileHandle( hZip, hFile, hb_parc( 3 ), hb_parc( 4 ), hb_parc( 5 ) ) ); } 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 szName[ HB_PATH_MAX ]; HB_SIZE nPos, nLen; char cSep, * pString; unz_file_info ufi; int iResult; HB_FHANDLE hFile; iResult = unzGetCurrentFileInfo( hUnzip, &ufi, szName, HB_PATH_MAX - 1, NULL, 0, NULL, 0 ); if( iResult != UNZ_OK ) return iResult; iResult = unzOpenCurrentFilePassword( hUnzip, szPassword ); if( iResult != UNZ_OK ) return iResult; if( szFileName ) hb_strncpy( szName, szFileName, sizeof( szName ) - 1 ); nLen = strlen( szName ); /* Test shows that files in subfolders can be stored to zip file without explicitly adding folder. So, let's create a required path */ nPos = 1; while( nPos < nLen ) { cSep = szName[ nPos ]; /* allow both path separators, ignore terminating path separator */ if( ( cSep == '\\' || cSep == '/' ) && nPos < nLen - 1 ) { szName[ nPos ] = '\0'; hb_fsMkDir( szName ); szName[ nPos ] = cSep; } nPos++; } if( ufi.external_fa & 0x40000000 ) /* DIRECTORY */ { hb_fsMkDir( szName ); iResult = UNZ_OK; } else { hFile = hb_fsCreate( szName, FC_NORMAL ); if( hFile != FS_ERROR ) { pString = ( char * ) hb_xgrab( HB_Z_IOBUF_SIZE ); while( ( iResult = unzReadCurrentFile( hUnzip, pString, HB_Z_IOBUF_SIZE ) ) > 0 ) hb_fsWriteLarge( hFile, pString, ( HB_SIZE ) iResult ); hb_xfree( pString ); #if defined( HB_OS_WIN ) { 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_fsGetOsHandle( hFile ), &ftutc, &ftutc, &ftutc ); } } #endif hb_fsClose( hFile ); } else iResult = -200 - hb_fsError(); } unzCloseCurrentFile( hUnzip ); #if defined( HB_OS_WIN ) { LPTSTR lpFileNameFree; LPCTSTR lpFileName = HB_FSNAMECONV( szName, &lpFileNameFree ); SetFileAttributes( ( LPCTSTR ) lpFileName, ufi.external_fa & 0xFF ); if( lpFileNameFree ) hb_xfree( lpFileNameFree ); } #elif defined( HB_OS_UNIX ) || defined( __DJGPP__ ) { struct utimbuf utim; struct tm st; time_t tim; char * pszFree; const char * szNameOS = hb_fsNameConv( szName, &pszFree ); # if defined( __DJGPP__ ) _chmod( szNameOS, 1, ufi.external_fa & 0xFF ); # else HB_FATTR ulAttr = ufi.external_fa; if( ( ulAttr & 0xFFFF0000 ) == 0 ) ulAttr = hb_translateExtAttr( szName, ulAttr ); 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 ) ); # endif 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; tim = mktime( &st ); # if defined( HB_HAS_LOCALTIME_R ) gmtime_r( &tim, &st ); # else st = *gmtime( &tim ); # endif utim.actime = utim.modtime = mktime( &st ); utime( szNameOS, &utim ); if( pszFree ) hb_xfree( pszFree ); } #elif defined( HB_OS_DOS ) { # if defined( __RSX32__ ) || defined( __GNUC__ ) char * pszFree; _chmod( hb_fsNameConv( szName, &pszFree ), 1, ufi.external_fa & 0xFF ); if( pszFree ) hb_xfree( pszFree ); # else hb_fsSetAttr( szName, ufi.external_fa & 0xFF ); # endif } #elif defined( HB_OS_OS2 ) { 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 { hb_fsSetAttr( szName, ufi.external_fa ); } #endif 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, HB_FHANDLE hFile, const char * szPassword ) { unz_file_info ufi; int iResult; if( hFile == FS_ERROR ) return -200; iResult = unzGetCurrentFileInfo( hUnzip, &ufi, NULL, HB_PATH_MAX - 1, 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 */ { if( hFile != FS_ERROR ) { char * pString = ( char * ) hb_xgrab( HB_Z_IOBUF_SIZE ); while( ( iResult = unzReadCurrentFile( hUnzip, pString, HB_Z_IOBUF_SIZE ) ) > 0 ) hb_fsWriteLarge( hFile, pString, ( HB_SIZE ) iResult ); hb_xfree( pString ); #if defined( HB_OS_WIN ) { 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_fsGetOsHandle( hFile ), &ftutc, &ftutc, &ftutc ); } } #endif } else iResult = -200 - hb_fsError(); } unzCloseCurrentFile( hUnzip ); return iResult; } /* HB_UnzipExtractCurrentFileToHandle( hZip, fhnd, [ cPassword ] ) --> nError */ HB_FUNC( HB_UNZIPEXTRACTCURRENTFILETOHANDLE ) { unzFile hUnzip = hb_unzipfileParam( 1 ); if( hUnzip ) hb_retni( hb_unzipExtractCurrentFileToHandle( hUnzip, hb_numToHandle( hb_parnint( 2 ) ), hb_parc( 3 ) ) ); } static int hb_zipDeleteFile( const char * szZipFile, const char * szFileMask ) { char szTempFile[ HB_PATH_MAX ]; char szCurrFile[ HB_PATH_MAX ]; PHB_FNAME pFileName; HB_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; 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 ); hFile = hb_fsCreateTemp( pFileName->szPath, NULL, FC_NORMAL, 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, HB_PATH_MAX - 1, 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, &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; } } 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 ) { 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_fsDelete( szTempFile ); else { hb_fsDelete( szZipFile ); if( iFilesLeft == 0 ) hb_fsDelete( szTempFile ); else if( !hb_fsRename( 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 ); }