Commit 87b7eb4ff7782f9b6d060376907798f86afc4bf9

Authored by Megan Watson
1 parent cf08213f

Replaced the zip binary with peclzip. Updated storage function (uploadTmpFile) t…

…o take an options array.
PT: 1660589
Jira: KTS-4501

Committed by: Megan Watson
Reviewed by: Prince Mbekwa
lib/import/zipimportstorage.inc.php
... ... @@ -8,31 +8,31 @@
8 8 * Document Management Made Simple
9 9 * Copyright (C) 2008, 2009 KnowledgeTree Inc.
10 10 * Portions copyright The Jam Warehouse Software (Pty) Limited
11   - *
  11 + *
12 12 * This program is free software; you can redistribute it and/or modify it under
13 13 * the terms of the GNU General Public License version 3 as published by the
14 14 * Free Software Foundation.
15   - *
  15 + *
16 16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 18 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 19 * details.
20   - *
  20 + *
21 21 * You should have received a copy of the GNU General Public License
22 22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23   - *
24   - * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
  23 + *
  24 + * You can contact KnowledgeTree Inc., PO Box 7775 #87847, San Francisco,
25 25 * California 94120-7775, or email info@knowledgetree.com.
26   - *
  26 + *
27 27 * The interactive user interfaces in modified source and object code versions
28 28 * of this program must display Appropriate Legal Notices, as required under
29 29 * Section 5 of the GNU General Public License version 3.
30   - *
  30 + *
31 31 * In accordance with Section 7(b) of the GNU General Public License version 3,
32 32 * these Appropriate Legal Notices must retain the display of the "Powered by
33   - * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  33 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
34 34 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
35   - * must display the words "Powered by KnowledgeTree" and retain the original
  35 + * must display the words "Powered by KnowledgeTree" and retain the original
36 36 * copyright notice.
37 37 * Contributor( s): ______________________________________
38 38 */
... ... @@ -40,8 +40,10 @@
40 40 require_once(KT_LIB_DIR . '/filelike/fsfilelike.inc.php');
41 41 require_once(KT_LIB_DIR . '/import/fsimportstorage.inc.php');
42 42  
  43 +require_once(KT_DIR.'/thirdparty/peclzip/pclzip.lib.php');
43 44 require_once('File/Archive.php');
44 45  
  46 +
45 47 class KTZipImportStorage extends KTFSImportStorage {
46 48  
47 49 /**
... ... @@ -56,10 +58,17 @@ class KTZipImportStorage extends KTFSImportStorage {
56 58  
57 59 var $aFile = array();
58 60  
  61 + var $sFileName = 'file';
  62 +
59 63 var $allowed_extensions = array('tgz', 'tar', 'gz', 'zip', 'deb', 'ar');
60 64  
61   - function KTZipImportStorage($sFilesName) {
62   - $this->aFile = $_FILES[$sFilesName];
  65 + function KTZipImportStorage($fileName, $fileData = null) {
  66 + $this->sFileName = $fileName;
  67 + if(empty($fileData)){
  68 + $this->aFile = $_FILES[$fileName];
  69 + }else{
  70 + $this->aFile = $fileData;
  71 + }
63 72 $this->sZipPath = $this->aFile['tmp_name'];
64 73  
65 74 // Check the bzip2 lib functions are available
... ... @@ -114,7 +123,7 @@ class KTZipImportStorage extends KTFSImportStorage {
114 123 return PEAR::raiseError(_kt("Archive file given does not exist"));
115 124 }
116 125 unlink($sTmpPath);
117   - mkdir($sTmpPath, 0700);
  126 + mkdir($sTmpPath, 0777);
118 127 $this->sBasePath = $sTmpPath;
119 128  
120 129 // Set environment language to output character encoding
... ... @@ -124,9 +133,17 @@ class KTZipImportStorage extends KTFSImportStorage {
124 133 putenv("LANGUAGE=$loc");
125 134 $loc = setlocale(LC_ALL, $loc);
126 135  
127   - // File Archive doesn't unzip properly so sticking to the original unzip functionality
  136 + // File Archive doesn't unzip properly - using peclzip for zip files
  137 + // todo: replace file archive for tar, etc
128 138 if($this->sExtension == 'zip'){
129   - // ** Original zip functionality
  139 +
  140 + $archive = new PclZip($this->sZipPath);
  141 +
  142 + if ($archive->extract(PCLZIP_OPT_PATH, $sTmpPath) == 0){
  143 + die("<font color='red'>Error : Unable to unzip archive</font>");
  144 + }
  145 +
  146 + /* ** Original zip functionality using the unzip binary ** *
130 147 $sUnzipCommand = KTUtil::findCommand("import/unzip", "unzip");
131 148 if (empty($sUnzipCommand)) {
132 149 return PEAR::raiseError(_kt("unzip command not found on system"));
... ... @@ -142,10 +159,11 @@ class KTZipImportStorage extends KTFSImportStorage {
142 159 if ($aRes['ret'] !== 0) {
143 160 return PEAR::raiseError(_kt("Could not retrieve contents from zip storage"));
144 161 }
  162 + /* ** End original zip functionality ** */
145 163 }else{
146 164 File_Archive::extract(
147 165 File_Archive::readArchive(
148   - $this->sExtension, File_Archive::readUploadedFile('file')
  166 + $this->sExtension, File_Archive::readUploadedFile($this->sFileName)
149 167 ),
150 168 $dst = $sTmpPath
151 169 );
... ... @@ -157,6 +175,10 @@ class KTZipImportStorage extends KTFSImportStorage {
157 175 KTUtil::deleteDirectory($this->sBasePath);
158 176 $this->sBasePath = null;
159 177 }
  178 + if ($this->sZipPath && file_exists($this->sZipPath)) {
  179 + KTUtil::deleteDirectory($this->sZipPath);
  180 + $this->sZipPath = null;
  181 + }
160 182 }
161 183 }
162 184  
... ...
lib/storage/ondiskhashedstoragemanager.inc.php
... ... @@ -92,13 +92,13 @@ class KTOnDiskHashedStorageManager extends KTStorageManager {
92 92 * @param unknown_type $sTmpFilePath
93 93 * @return unknown
94 94 */
95   - function uploadTmpFile($sUploadedFile, $sTmpFilePath) {
  95 + function uploadTmpFile($sUploadedFile, $sTmpFilePath, $aOptions = null) {
96 96  
97 97 //copy the file accross
98 98 if (OS_WINDOWS) {
99 99 $sTmpFilePath = str_replace('\\','/',$sTmpFilePath);
100 100 }
101   - if ($this->writeToFile($sUploadedFile, $sTmpFilePath)) {
  101 + if ($this->writeToFile($sUploadedFile, $sTmpFilePath, $aOptions)) {
102 102 if (file_exists($sTmpFilePath)) {
103 103 return true;
104 104 } else {
... ...
lib/storage/ondiskpathstoragemanager.inc.php
... ... @@ -90,7 +90,7 @@ class KTOnDiskPathStorageManager extends KTStorageManager {
90 90 * @param unknown_type $sTmpFilePath
91 91 * @return unknown
92 92 */
93   - function uploadTmpFile($sUploadedFile, $sTmpFilePath) {
  93 + function uploadTmpFile($sUploadedFile, $sTmpFilePath, $aOptions = null) {
94 94  
95 95 //copy the file accross
96 96 if (OS_WINDOWS) {
... ...
lib/storage/storagemanager.inc.php
... ... @@ -59,10 +59,14 @@ class KTStorageManager {
59 59 * @param unknown_type $sTmpFilePath
60 60 * @return unknown
61 61 */
62   - function uploadTmpFile($sUploadedFile, $sTmpFilePath) {
  62 + function uploadTmpFile($sUploadedFile, $sTmpFilePath, $aOptions = null) {
63 63 return PEAR::raiseError(_kt('Not implemented'));
64 64 }
65 65  
  66 + function writeToFile($sTmpFilePath, $sDocumentFileSystemPath, $aOptions = null) {
  67 + return PEAR::raiseError(_kt("Not implemented"));
  68 + }
  69 +
66 70 /**
67 71 * Gets the latest verison of a document's contents from storage and
68 72 * writes it to the standard content with HTTP headers as an
... ...
plugins/multiselect/BulkUpload.php
... ... @@ -68,12 +68,12 @@ class InetBulkUploadFolderAction extends KTFolderAction {
68 68 {
69 69 $aJavascript[] = 'thirdpartyjs/jquery/jquery-1.3.2.js';
70 70 $aJavascript[] = 'thirdpartyjs/jquery/jquery_noconflict.js';
71   -
72   - $oPage =& $GLOBALS['main'];
  71 +
  72 + $oPage =& $GLOBALS['main'];
73 73 if (method_exists($oPage, 'requireJSResources')) {
74 74 $oPage->requireJSResources($aJavascript);
75 75 }
76   -
  76 +
77 77 $js = "<script src='resources/js/kt_hidelink.js' type='text/javascript'></script>";
78 78 return $js._kt('Bulk Upload');
79 79 }
... ... @@ -116,37 +116,37 @@ class InetBulkUploadFolderAction extends KTFolderAction {
116 116 function do_main() {
117 117 $bulkUploadForm = $this->getBulkUploadForm();
118 118 return $bulkUploadForm->render();
119   - }
  119 + }
120 120  
121 121  
122 122 /**
123 123 * Returns the main Bulk Upload Form
124   - * @return KTForm
  124 + * @return KTForm
125 125 *
126 126 */
127 127  
128 128 function getBulkUploadForm() {
129 129 $this->oPage->setBreadcrumbDetails(_kt("bulk upload"));
130   -
  130 +
131 131 //Adding the required Bulk Upload javascript includes
132 132 $aJavascript[] = 'resources/js/taillog.js';
133 133 $aJavascript[] = 'resources/js/conditional_usage.js';
134 134 $aJavascript[] = 'resources/js/kt_bulkupload.js';
135   -
  135 +
136 136 //Loading the widget js libraries to support dynamic "Ajax Loaded" widget rendering
137 137 //FIXME: The widgets can support this via dynamic call to place libs in the head if they aren't loaded
138 138 // jQuery can do this but need time to implement/test.
139   -
  139 +
140 140 $aJavascript[] = 'thirdpartyjs/jquery/jquery-1.3.2.js';
141 141 $aJavascript[] = 'thirdpartyjs/tinymce/jscripts/tiny_mce/tiny_mce.js';
142 142 $aJavascript[] = 'resources/js/kt_tinymce_init.js';
143 143 $aJavascript[] = 'thirdpartyjs/tinymce/jscripts/tiny_mce/jquery.tinymce.js';
144   -
  144 +
145 145 $this->oPage->requireJSResources($aJavascript);
146   -
  146 +
147 147 //FIXME: Might really not need to load these styles, will check l8r
148 148 //$this->oPage->requireCSSResource('resources/css/kt-treewidget.css')}
149   -
  149 +
150 150 //Creating the form
151 151 $oForm = new KTForm;
152 152 $oForm->setOptions(array(
... ... @@ -156,19 +156,20 @@ class InetBulkUploadFolderAction extends KTFolderAction {
156 156 'action' => 'upload',
157 157 'fail_action' => 'main',
158 158 'encoding' => 'multipart/form-data',
  159 + 'file_upload' => true,
159 160 // 'cancel_url' => KTBrowseUtil::getUrlForDocument($this->oDocument),
160 161 'context' => &$this,
161 162 'extraargs' => $this->meldPersistQuery("","",true),
162   - 'description' => _kt('The bulk upload facility allows for a number of documents to be added to the document management system. Provide an archive (ZIP) file from your local computer, and all documents and folders within that archive will be added to the document management system.')
  163 + 'description' => _kt('The bulk upload facility allows for a number of documents to be added to the document management system. Provide an archive (ZIP) file from your local computer, and all documents and folders within that archive will be added to the document management system.')
163 164 ));
164   -
  165 +
165 166 $oWF =& KTWidgetFactory::getSingleton();
166   -
  167 +
167 168 $widgets = array();
168 169 $validators = array();
169   -
  170 +
170 171 // Adding the File Upload Widget
171   -
  172 +
172 173 //Legacy kt3 widgets don't conform to ktcore type widgets by virtue of the 'name' attribute.
173 174 //$widgets[] = new KTFileUploadWidget(_kt('Archive file'), , 'file', "", $this->oPage, true, "file");
174 175  
... ... @@ -180,14 +181,14 @@ class InetBulkUploadFolderAction extends KTFolderAction {
180 181 'value' => '',
181 182 'description' => _kt('The archive file containing the documents you wish to add to the document management system.'),
182 183 ));
183   -
  184 +
184 185 $aVocab = array('' => _kt('- Please select a document type -'));
185 186 foreach (DocumentType::getListForUserAndFolder($this->oUser, $this->oFolder) as $oDocumentType) {
186 187 if(!$oDocumentType->getDisabled()) {
187 188 $aVocab[$oDocumentType->getId()] = $oDocumentType->getName();
188 189 }
189 190 }
190   -
  191 +
191 192 //Adding document type lookup widget
192 193 $widgets[] = $oWF->get('ktcore.widgets.selection',array(
193 194 'label' => _kt('Document Type'),
... ... @@ -200,32 +201,32 @@ class InetBulkUploadFolderAction extends KTFolderAction {
200 201 'label_method' => 'getName',
201 202 'simple_select' => false,
202 203 ));
203   -
  204 +
204 205 //Adding the quick "add" button for when no meta data needs to be added.
205 206 //FIXME: This widget should only display if there are any "required" fields for the given document type
206 207 // Default/general document field type must also be taken into consideration
207   -
  208 +
208 209 $widgets[] = $oWF->get('ktcore.widgets.button',array(
209 210 'value' => _kt('Add'),
210 211 'id' => 'quick_add',
211 212 'description' => _kt('If you do not need to modify any the metadata for this document (see below), then you can simply click "Add" here to finish the process and add the document.'),
212 213 'name' => 'btn_quick_submit',
213 214 ));
214   -
  215 +
215 216 $oFReg =& KTFieldsetRegistry::getSingleton();
216   -
  217 +
217 218 $activesets = KTFieldset::getGenericFieldsets();
218 219 foreach ($activesets as $oFieldset) {
219 220 $widgets = kt_array_merge($widgets, $oFReg->widgetsForFieldset($oFieldset, 'fieldset_' . $oFieldset->getId(), $this->oDocument));
220 221 $validators = kt_array_merge($validators, $oFReg->validatorsForFieldset($oFieldset, 'fieldset_' . $oFieldset->getId(), $this->oDocument));
221 222 }
222   -
  223 +
223 224 //Adding the type_metadata_fields layer to be updated via ajax for non generic metadata fieldsets
224 225 $widgets[] = $oWF->get('ktcore.widgets.layer',array(
225 226 'value' => '',
226 227 'id' => 'type_metadata_fields',
227 228 ));
228   -
  229 +
229 230 $oForm->setWidgets($widgets);
230 231 $oForm->setValidators($validators);
231 232  
... ... @@ -253,6 +254,7 @@ class InetBulkUploadFolderAction extends KTFolderAction {
253 254 */
254 255 function do_upload() {
255 256 set_time_limit(0);
  257 + global $default;
256 258 $aErrorOptions = array(
257 259 'redirect_to' => array('main', sprintf('fFolderId=%d', $this->oFolder->getId())),
258 260 );
... ... @@ -268,19 +270,37 @@ class InetBulkUploadFolderAction extends KTFolderAction {
268 270 $oDocumentType = $this->oValidator->validateDocumentType($requestDocumentType, $aErrorOptions);
269 271  
270 272 unset($aErrorOptions['message']);
271   - $fileName = $_FILES['file'];
272   - if ($fileName == '' || $fileName == NULL){
273   - $fileName = $_FILES['_kt_attempt_unique_file'];//$_FILES['_kt_attempt_unique_file'];
  273 + $fileData = $_FILES['file'];
  274 + $fileName = 'file';
  275 + if ($fileData == '' || $fileData == NULL){
  276 + $fileData = $_FILES['_kt_attempt_unique_file'];//$_FILES['_kt_attempt_unique_file'];
  277 + $fileName = '_kt_attempt_unique_file';
274 278 }
275 279  
276   - $aFile = $this->oValidator->validateFile($fileName, $aErrorOptions);
  280 + $aFile = $this->oValidator->validateFile($fileData, $aErrorOptions);
  281 +
  282 + // Lets move the file from the windows temp directory into our own directory
  283 + $oKTConfig =& KTConfig::getSingleton();
  284 + $sBasedir = $oKTConfig->get("urls/tmpDirectory");
  285 + $tmpFilename = tempnam($sBasedir, 'kt_storebulk');
  286 +
  287 + $oStorage =& KTStorageManagerUtil::getSingleton();
  288 + $res = $oStorage->uploadTmpFile($fileData['tmp_name'], $tmpFilename, array('copy_upload' => 'true'));
  289 +
  290 + // Save the new temp filename in the file data array
  291 + $fileData['tmp_name'] = $tmpFilename;
  292 +
  293 + if($res === false){
  294 + $default->log->error('File could not be copied from the system temp directory.');
  295 + exit('File could not be copied from the system temp directory.');
  296 + }
277 297  
278 298 $matches = array();
279 299 $aFields = array();
280 300  
281 301 // author: Charl Mert
282 302 // Older kt3 form field submission used name='metadata_9 etc and the aFields array contained them.'
283   - // Should keep open here for backwards compatibility but will close it to "discover" the other
  303 + // Should keep open here for backwards compatibility but will close it to "discover" the other
284 304 // old interfaces.
285 305 /*
286 306 foreach ($_REQUEST as $k => $v) {
... ... @@ -302,9 +322,9 @@ class InetBulkUploadFolderAction extends KTFolderAction {
302 322  
303 323 //Newer metadata form field catcher that works with ktcore form array type fields named like
304 324 //name='metadata[fieldset][metadata_9]'
305   -
  325 +
306 326 $aData = $_REQUEST['data'];
307   -
  327 +
308 328 /* //This validation breaks with ajax loaded form items e.g. a non generic fieldset that submits
309 329 * //values doesn't pass the check below.
310 330 $oForm = $this->getBulkUploadForm();
... ... @@ -315,9 +335,9 @@ class InetBulkUploadFolderAction extends KTFolderAction {
315 335 $data = $res['results'];
316 336 var_dump($data);
317 337 */
318   -
  338 +
319 339 $data = $aData;
320   -
  340 +
321 341 $doctypeid = $requestDocumentType;
322 342 $aGenericFieldsetIds = KTFieldset::getGenericFieldsets(array('ids' => false));
323 343 $aSpecificFieldsetIds = KTFieldset::getForDocumentType($doctypeid, array('ids' => false));
... ... @@ -359,21 +379,21 @@ class InetBulkUploadFolderAction extends KTFolderAction {
359 379 }
360 380  
361 381 }
362   - }
  382 + }
363 383  
364 384 $aOptions = array(
365 385 'documenttype' => $oDocumentType,
366 386 'metadata' => $MDPack,
367 387 );
368   -
369   - $fs =& new KTZipImportStorage('_kt_attempt_unique_file');
  388 +
  389 + $fs =& new KTZipImportStorage($fileName, $fileData);
370 390 if(!$fs->CheckFormat()){
371 391 $sFormats = $fs->getFormats();
372 392 $this->addErrorMessage(sprintf(_kt("Bulk Upload failed. Archive is not an accepted format. Accepted formats are: .%s") , $sFormats));
373 393 controllerRedirect("browse", 'fFolderId=' . $this->oFolder->getID());
374 394 exit;
375 395 }
376   -
  396 +
377 397 if(KTPluginUtil::pluginIsActive('inet.foldermetadata.plugin'))
378 398 {
379 399 require_once(KT_DIR . "/plugins/foldermetadata/import/bulkimport.inc.php");
... ...
thirdparty/peclzip/pclzip.lib.php 0 → 100755
Changes suppressed. Click to show
  1 +<?php
  2 +// --------------------------------------------------------------------------------
  3 +// PhpConcept Library - Zip Module 2.5
  4 +// --------------------------------------------------------------------------------
  5 +// License GNU/LGPL - Vincent Blavet - March 2006
  6 +// http://www.phpconcept.net
  7 +// --------------------------------------------------------------------------------
  8 +//
  9 +// Presentation :
  10 +// PclZip is a PHP library that manage ZIP archives.
  11 +// So far tests show that archives generated by PclZip are readable by
  12 +// WinZip application and other tools.
  13 +//
  14 +// Description :
  15 +// See readme.txt and http://www.phpconcept.net
  16 +//
  17 +// Warning :
  18 +// This library and the associated files are non commercial, non professional
  19 +// work.
  20 +// It should not have unexpected results. However if any damage is caused by
  21 +// this software the author can not be responsible.
  22 +// The use of this software is at the risk of the user.
  23 +//
  24 +// --------------------------------------------------------------------------------
  25 +// $Id: pclzip.lib.php,v 1.44 2006/03/08 21:23:59 vblavet Exp $
  26 +// --------------------------------------------------------------------------------
  27 +
  28 + // ----- Constants
  29 + define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
  30 +
  31 + // ----- File list separator
  32 + // In version 1.x of PclZip, the separator for file list is a space
  33 + // (which is not a very smart choice, specifically for windows paths !).
  34 + // A better separator should be a comma (,). This constant gives you the
  35 + // abilty to change that.
  36 + // However notice that changing this value, may have impact on existing
  37 + // scripts, using space separated filenames.
  38 + // Recommanded values for compatibility with older versions :
  39 + //define( 'PCLZIP_SEPARATOR', ' ' );
  40 + // Recommanded values for smart separation of filenames.
  41 + define( 'PCLZIP_SEPARATOR', ',' );
  42 +
  43 + // ----- Error configuration
  44 + // 0 : PclZip Class integrated error handling
  45 + // 1 : PclError external library error handling. By enabling this
  46 + // you must ensure that you have included PclError library.
  47 + // [2,...] : reserved for futur use
  48 + define( 'PCLZIP_ERROR_EXTERNAL', 0 );
  49 +
  50 + // ----- Optional static temporary directory
  51 + // By default temporary files are generated in the script current
  52 + // path.
  53 + // If defined :
  54 + // - MUST BE terminated by a '/'.
  55 + // - MUST be a valid, already created directory
  56 + // Samples :
  57 + // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
  58 + // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
  59 + define( 'PCLZIP_TEMPORARY_DIR', '' );
  60 +
  61 +// --------------------------------------------------------------------------------
  62 +// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
  63 +// --------------------------------------------------------------------------------
  64 +
  65 + // ----- Global variables
  66 + $g_pclzip_version = "2.5";
  67 +
  68 + // ----- Error codes
  69 + // -1 : Unable to open file in binary write mode
  70 + // -2 : Unable to open file in binary read mode
  71 + // -3 : Invalid parameters
  72 + // -4 : File does not exist
  73 + // -5 : Filename is too long (max. 255)
  74 + // -6 : Not a valid zip file
  75 + // -7 : Invalid extracted file size
  76 + // -8 : Unable to create directory
  77 + // -9 : Invalid archive extension
  78 + // -10 : Invalid archive format
  79 + // -11 : Unable to delete file (unlink)
  80 + // -12 : Unable to rename file (rename)
  81 + // -13 : Invalid header checksum
  82 + // -14 : Invalid archive size
  83 + define( 'PCLZIP_ERR_USER_ABORTED', 2 );
  84 + define( 'PCLZIP_ERR_NO_ERROR', 0 );
  85 + define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
  86 + define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
  87 + define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
  88 + define( 'PCLZIP_ERR_MISSING_FILE', -4 );
  89 + define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
  90 + define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
  91 + define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
  92 + define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
  93 + define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
  94 + define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
  95 + define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
  96 + define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
  97 + define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
  98 + define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
  99 + define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
  100 + define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
  101 + define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
  102 + define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
  103 + define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
  104 + define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
  105 + define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
  106 +
  107 + // ----- Options values
  108 + define( 'PCLZIP_OPT_PATH', 77001 );
  109 + define( 'PCLZIP_OPT_ADD_PATH', 77002 );
  110 + define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
  111 + define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
  112 + define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
  113 + define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
  114 + define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
  115 + define( 'PCLZIP_OPT_BY_NAME', 77008 );
  116 + define( 'PCLZIP_OPT_BY_INDEX', 77009 );
  117 + define( 'PCLZIP_OPT_BY_EREG', 77010 );
  118 + define( 'PCLZIP_OPT_BY_PREG', 77011 );
  119 + define( 'PCLZIP_OPT_COMMENT', 77012 );
  120 + define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
  121 + define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
  122 + define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
  123 + define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
  124 + define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
  125 + // Having big trouble with crypt. Need to multiply 2 long int
  126 + // which is not correctly supported by PHP ...
  127 + //define( 'PCLZIP_OPT_CRYPT', 77018 );
  128 + define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
  129 +
  130 + // ----- File description attributes
  131 + define( 'PCLZIP_ATT_FILE_NAME', 79001 );
  132 + define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
  133 + define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
  134 +
  135 + // ----- Call backs values
  136 + define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
  137 + define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
  138 + define( 'PCLZIP_CB_PRE_ADD', 78003 );
  139 + define( 'PCLZIP_CB_POST_ADD', 78004 );
  140 + /* For futur use
  141 + define( 'PCLZIP_CB_PRE_LIST', 78005 );
  142 + define( 'PCLZIP_CB_POST_LIST', 78006 );
  143 + define( 'PCLZIP_CB_PRE_DELETE', 78007 );
  144 + define( 'PCLZIP_CB_POST_DELETE', 78008 );
  145 + */
  146 +
  147 + // --------------------------------------------------------------------------------
  148 + // Class : PclZip
  149 + // Description :
  150 + // PclZip is the class that represent a Zip archive.
  151 + // The public methods allow the manipulation of the archive.
  152 + // Attributes :
  153 + // Attributes must not be accessed directly.
  154 + // Methods :
  155 + // PclZip() : Object creator
  156 + // create() : Creates the Zip archive
  157 + // listContent() : List the content of the Zip archive
  158 + // extract() : Extract the content of the archive
  159 + // properties() : List the properties of the archive
  160 + // --------------------------------------------------------------------------------
  161 + class PclZip
  162 + {
  163 + // ----- Filename of the zip file
  164 + var $zipname = '';
  165 +
  166 + // ----- File descriptor of the zip file
  167 + var $zip_fd = 0;
  168 +
  169 + // ----- Internal error handling
  170 + var $error_code = 1;
  171 + var $error_string = '';
  172 +
  173 + // ----- Current status of the magic_quotes_runtime
  174 + // This value store the php configuration for magic_quotes
  175 + // The class can then disable the magic_quotes and reset it after
  176 + var $magic_quotes_status;
  177 +
  178 + // --------------------------------------------------------------------------------
  179 + // Function : PclZip()
  180 + // Description :
  181 + // Creates a PclZip object and set the name of the associated Zip archive
  182 + // filename.
  183 + // Note that no real action is taken, if the archive does not exist it is not
  184 + // created. Use create() for that.
  185 + // --------------------------------------------------------------------------------
  186 + function PclZip($p_zipname)
  187 + {
  188 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::PclZip', "zipname=$p_zipname");
  189 +
  190 + // ----- Tests the zlib
  191 + if (!function_exists('gzopen'))
  192 + {
  193 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 1, "zlib extension seems to be missing");
  194 + die('Abort '.basename(__FILE__).' : Missing zlib extensions');
  195 + }
  196 +
  197 + // ----- Set the attributes
  198 + $this->zipname = $p_zipname;
  199 + $this->zip_fd = 0;
  200 + $this->magic_quotes_status = -1;
  201 +
  202 + // ----- Return
  203 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 1);
  204 + return;
  205 + }
  206 + // --------------------------------------------------------------------------------
  207 +
  208 + // --------------------------------------------------------------------------------
  209 + // Function :
  210 + // create($p_filelist, $p_add_dir="", $p_remove_dir="")
  211 + // create($p_filelist, $p_option, $p_option_value, ...)
  212 + // Description :
  213 + // This method supports two different synopsis. The first one is historical.
  214 + // This method creates a Zip Archive. The Zip file is created in the
  215 + // filesystem. The files and directories indicated in $p_filelist
  216 + // are added in the archive. See the parameters description for the
  217 + // supported format of $p_filelist.
  218 + // When a directory is in the list, the directory and its content is added
  219 + // in the archive.
  220 + // In this synopsis, the function takes an optional variable list of
  221 + // options. See bellow the supported options.
  222 + // Parameters :
  223 + // $p_filelist : An array containing file or directory names, or
  224 + // a string containing one filename or one directory name, or
  225 + // a string containing a list of filenames and/or directory
  226 + // names separated by spaces.
  227 + // $p_add_dir : A path to add before the real path of the archived file,
  228 + // in order to have it memorized in the archive.
  229 + // $p_remove_dir : A path to remove from the real path of the file to archive,
  230 + // in order to have a shorter path memorized in the archive.
  231 + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
  232 + // is removed first, before $p_add_dir is added.
  233 + // Options :
  234 + // PCLZIP_OPT_ADD_PATH :
  235 + // PCLZIP_OPT_REMOVE_PATH :
  236 + // PCLZIP_OPT_REMOVE_ALL_PATH :
  237 + // PCLZIP_OPT_COMMENT :
  238 + // PCLZIP_CB_PRE_ADD :
  239 + // PCLZIP_CB_POST_ADD :
  240 + // Return Values :
  241 + // 0 on failure,
  242 + // The list of the added files, with a status of the add action.
  243 + // (see PclZip::listContent() for list entry format)
  244 + // --------------------------------------------------------------------------------
  245 + function create($p_filelist)
  246 + {
  247 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::create', "filelist='$p_filelist', ...");
  248 + $v_result=1;
  249 +
  250 + // ----- Reset the error handler
  251 + $this->privErrorReset();
  252 +
  253 + // ----- Set default values
  254 + $v_options = array();
  255 + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
  256 +
  257 + // ----- Look for variable options arguments
  258 + $v_size = func_num_args();
  259 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
  260 +
  261 + // ----- Look for arguments
  262 + if ($v_size > 1) {
  263 + // ----- Get the arguments
  264 + $v_arg_list = func_get_args();
  265 +
  266 + // ----- Remove from the options list the first argument
  267 + array_shift($v_arg_list);
  268 + $v_size--;
  269 +
  270 + // ----- Look for first arg
  271 + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  272 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");
  273 +
  274 + // ----- Parse the options
  275 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  276 + array (PCLZIP_OPT_REMOVE_PATH => 'optional',
  277 + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  278 + PCLZIP_OPT_ADD_PATH => 'optional',
  279 + PCLZIP_CB_PRE_ADD => 'optional',
  280 + PCLZIP_CB_POST_ADD => 'optional',
  281 + PCLZIP_OPT_NO_COMPRESSION => 'optional',
  282 + PCLZIP_OPT_COMMENT => 'optional'
  283 + //, PCLZIP_OPT_CRYPT => 'optional'
  284 + ));
  285 + if ($v_result != 1) {
  286 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  287 + return 0;
  288 + }
  289 + }
  290 +
  291 + // ----- Look for 2 args
  292 + // Here we need to support the first historic synopsis of the
  293 + // method.
  294 + else {
  295 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
  296 +
  297 + // ----- Get the first argument
  298 + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
  299 +
  300 + // ----- Look for the optional second argument
  301 + if ($v_size == 2) {
  302 + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
  303 + }
  304 + else if ($v_size > 2) {
  305 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
  306 + "Invalid number / type of arguments");
  307 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  308 + return 0;
  309 + }
  310 + }
  311 + }
  312 +
  313 + // ----- Init
  314 + $v_string_list = array();
  315 + $v_att_list = array();
  316 + $v_filedescr_list = array();
  317 + $p_result_list = array();
  318 +
  319 + // ----- Look if the $p_filelist is really an array
  320 + if (is_array($p_filelist)) {
  321 +
  322 + // ----- Look if the first element is also an array
  323 + // This will mean that this is a file description entry
  324 + if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
  325 + $v_att_list = $p_filelist;
  326 + }
  327 +
  328 + // ----- The list is a list of string names
  329 + else {
  330 + $v_string_list = $p_filelist;
  331 + }
  332 + }
  333 +
  334 + // ----- Look if the $p_filelist is a string
  335 + else if (is_string($p_filelist)) {
  336 + // ----- Create a list from the string
  337 + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
  338 + }
  339 +
  340 + // ----- Invalid variable type for $p_filelist
  341 + else {
  342 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
  343 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  344 + return 0;
  345 + }
  346 +
  347 + // ----- Reformat the string list
  348 + if (sizeof($v_string_list) != 0) {
  349 + foreach ($v_string_list as $v_string) {
  350 + if ($v_string != '') {
  351 + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
  352 + }
  353 + else {
  354 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Ignore an empty filename");
  355 + }
  356 + }
  357 + }
  358 +
  359 + // ----- For each file in the list check the attributes
  360 + $v_supported_attributes
  361 + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
  362 + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
  363 + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
  364 + );
  365 + foreach ($v_att_list as $v_entry) {
  366 + $v_result = $this->privFileDescrParseAtt($v_entry,
  367 + $v_filedescr_list[],
  368 + $v_options,
  369 + $v_supported_attributes);
  370 + if ($v_result != 1) {
  371 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  372 + return 0;
  373 + }
  374 + }
  375 +
  376 + // ----- Expand the filelist (expand directories)
  377 + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
  378 + if ($v_result != 1) {
  379 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  380 + return 0;
  381 + }
  382 +
  383 + // ----- Call the create fct
  384 + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
  385 + if ($v_result != 1) {
  386 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  387 + return 0;
  388 + }
  389 +
  390 + // ----- Return
  391 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);
  392 + return $p_result_list;
  393 + }
  394 + // --------------------------------------------------------------------------------
  395 +
  396 + // --------------------------------------------------------------------------------
  397 + // Function :
  398 + // add($p_filelist, $p_add_dir="", $p_remove_dir="")
  399 + // add($p_filelist, $p_option, $p_option_value, ...)
  400 + // Description :
  401 + // This method supports two synopsis. The first one is historical.
  402 + // This methods add the list of files in an existing archive.
  403 + // If a file with the same name already exists, it is added at the end of the
  404 + // archive, the first one is still present.
  405 + // If the archive does not exist, it is created.
  406 + // Parameters :
  407 + // $p_filelist : An array containing file or directory names, or
  408 + // a string containing one filename or one directory name, or
  409 + // a string containing a list of filenames and/or directory
  410 + // names separated by spaces.
  411 + // $p_add_dir : A path to add before the real path of the archived file,
  412 + // in order to have it memorized in the archive.
  413 + // $p_remove_dir : A path to remove from the real path of the file to archive,
  414 + // in order to have a shorter path memorized in the archive.
  415 + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
  416 + // is removed first, before $p_add_dir is added.
  417 + // Options :
  418 + // PCLZIP_OPT_ADD_PATH :
  419 + // PCLZIP_OPT_REMOVE_PATH :
  420 + // PCLZIP_OPT_REMOVE_ALL_PATH :
  421 + // PCLZIP_OPT_COMMENT :
  422 + // PCLZIP_OPT_ADD_COMMENT :
  423 + // PCLZIP_OPT_PREPEND_COMMENT :
  424 + // PCLZIP_CB_PRE_ADD :
  425 + // PCLZIP_CB_POST_ADD :
  426 + // Return Values :
  427 + // 0 on failure,
  428 + // The list of the added files, with a status of the add action.
  429 + // (see PclZip::listContent() for list entry format)
  430 + // --------------------------------------------------------------------------------
  431 + function add($p_filelist)
  432 + {
  433 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::add', "filelist='$p_filelist', ...");
  434 + $v_result=1;
  435 +
  436 + // ----- Reset the error handler
  437 + $this->privErrorReset();
  438 +
  439 + // ----- Set default values
  440 + $v_options = array();
  441 + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
  442 +
  443 + // ----- Look for variable options arguments
  444 + $v_size = func_num_args();
  445 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
  446 +
  447 + // ----- Look for arguments
  448 + if ($v_size > 1) {
  449 + // ----- Get the arguments
  450 + $v_arg_list = func_get_args();
  451 +
  452 + // ----- Remove form the options list the first argument
  453 + array_shift($v_arg_list);
  454 + $v_size--;
  455 +
  456 + // ----- Look for first arg
  457 + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  458 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");
  459 +
  460 + // ----- Parse the options
  461 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  462 + array (PCLZIP_OPT_REMOVE_PATH => 'optional',
  463 + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  464 + PCLZIP_OPT_ADD_PATH => 'optional',
  465 + PCLZIP_CB_PRE_ADD => 'optional',
  466 + PCLZIP_CB_POST_ADD => 'optional',
  467 + PCLZIP_OPT_NO_COMPRESSION => 'optional',
  468 + PCLZIP_OPT_COMMENT => 'optional',
  469 + PCLZIP_OPT_ADD_COMMENT => 'optional',
  470 + PCLZIP_OPT_PREPEND_COMMENT => 'optional'
  471 + //, PCLZIP_OPT_CRYPT => 'optional'
  472 + ));
  473 + if ($v_result != 1) {
  474 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  475 + return 0;
  476 + }
  477 + }
  478 +
  479 + // ----- Look for 2 args
  480 + // Here we need to support the first historic synopsis of the
  481 + // method.
  482 + else {
  483 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
  484 +
  485 + // ----- Get the first argument
  486 + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
  487 +
  488 + // ----- Look for the optional second argument
  489 + if ($v_size == 2) {
  490 + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
  491 + }
  492 + else if ($v_size > 2) {
  493 + // ----- Error log
  494 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  495 +
  496 + // ----- Return
  497 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  498 + return 0;
  499 + }
  500 + }
  501 + }
  502 +
  503 + // ----- Init
  504 + $v_string_list = array();
  505 + $v_att_list = array();
  506 + $v_filedescr_list = array();
  507 + $p_result_list = array();
  508 +
  509 + // ----- Look if the $p_filelist is really an array
  510 + if (is_array($p_filelist)) {
  511 +
  512 + // ----- Look if the first element is also an array
  513 + // This will mean that this is a file description entry
  514 + if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
  515 + $v_att_list = $p_filelist;
  516 + }
  517 +
  518 + // ----- The list is a list of string names
  519 + else {
  520 + $v_string_list = $p_filelist;
  521 + }
  522 + }
  523 +
  524 + // ----- Look if the $p_filelist is a string
  525 + else if (is_string($p_filelist)) {
  526 + // ----- Create a list from the string
  527 + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
  528 + }
  529 +
  530 + // ----- Invalid variable type for $p_filelist
  531 + else {
  532 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
  533 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  534 + return 0;
  535 + }
  536 +
  537 + // ----- Reformat the string list
  538 + if (sizeof($v_string_list) != 0) {
  539 + foreach ($v_string_list as $v_string) {
  540 + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
  541 + }
  542 + }
  543 +
  544 + // ----- For each file in the list check the attributes
  545 + $v_supported_attributes
  546 + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
  547 + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
  548 + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
  549 + );
  550 + foreach ($v_att_list as $v_entry) {
  551 + $v_result = $this->privFileDescrParseAtt($v_entry,
  552 + $v_filedescr_list[],
  553 + $v_options,
  554 + $v_supported_attributes);
  555 + if ($v_result != 1) {
  556 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  557 + return 0;
  558 + }
  559 + }
  560 +
  561 + // ----- Expand the filelist (expand directories)
  562 + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
  563 + if ($v_result != 1) {
  564 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  565 + return 0;
  566 + }
  567 +
  568 + // ----- Call the create fct
  569 + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
  570 + if ($v_result != 1) {
  571 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  572 + return 0;
  573 + }
  574 +
  575 + // ----- Return
  576 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);
  577 + return $p_result_list;
  578 + }
  579 + // --------------------------------------------------------------------------------
  580 +
  581 + // --------------------------------------------------------------------------------
  582 + // Function : listContent()
  583 + // Description :
  584 + // This public method, gives the list of the files and directories, with their
  585 + // properties.
  586 + // The properties of each entries in the list are (used also in other functions) :
  587 + // filename : Name of the file. For a create or add action it is the filename
  588 + // given by the user. For an extract function it is the filename
  589 + // of the extracted file.
  590 + // stored_filename : Name of the file / directory stored in the archive.
  591 + // size : Size of the stored file.
  592 + // compressed_size : Size of the file's data compressed in the archive
  593 + // (without the headers overhead)
  594 + // mtime : Last known modification date of the file (UNIX timestamp)
  595 + // comment : Comment associated with the file
  596 + // folder : true | false
  597 + // index : index of the file in the archive
  598 + // status : status of the action (depending of the action) :
  599 + // Values are :
  600 + // ok : OK !
  601 + // filtered : the file / dir is not extracted (filtered by user)
  602 + // already_a_directory : the file can not be extracted because a
  603 + // directory with the same name already exists
  604 + // write_protected : the file can not be extracted because a file
  605 + // with the same name already exists and is
  606 + // write protected
  607 + // newer_exist : the file was not extracted because a newer file exists
  608 + // path_creation_fail : the file is not extracted because the folder
  609 + // does not exists and can not be created
  610 + // write_error : the file was not extracted because there was a
  611 + // error while writing the file
  612 + // read_error : the file was not extracted because there was a error
  613 + // while reading the file
  614 + // invalid_header : the file was not extracted because of an archive
  615 + // format error (bad file header)
  616 + // Note that each time a method can continue operating when there
  617 + // is an action error on a file, the error is only logged in the file status.
  618 + // Return Values :
  619 + // 0 on an unrecoverable failure,
  620 + // The list of the files in the archive.
  621 + // --------------------------------------------------------------------------------
  622 + function listContent()
  623 + {
  624 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::listContent', "");
  625 + $v_result=1;
  626 +
  627 + // ----- Reset the error handler
  628 + $this->privErrorReset();
  629 +
  630 + // ----- Check archive
  631 + if (!$this->privCheckFormat()) {
  632 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  633 + return(0);
  634 + }
  635 +
  636 + // ----- Call the extracting fct
  637 + $p_list = array();
  638 + if (($v_result = $this->privList($p_list)) != 1)
  639 + {
  640 + unset($p_list);
  641 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
  642 + return(0);
  643 + }
  644 +
  645 + // ----- Return
  646 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
  647 + return $p_list;
  648 + }
  649 + // --------------------------------------------------------------------------------
  650 +
  651 + // --------------------------------------------------------------------------------
  652 + // Function :
  653 + // extract($p_path="./", $p_remove_path="")
  654 + // extract([$p_option, $p_option_value, ...])
  655 + // Description :
  656 + // This method supports two synopsis. The first one is historical.
  657 + // This method extract all the files / directories from the archive to the
  658 + // folder indicated in $p_path.
  659 + // If you want to ignore the 'root' part of path of the memorized files
  660 + // you can indicate this in the optional $p_remove_path parameter.
  661 + // By default, if a newer file with the same name already exists, the
  662 + // file is not extracted.
  663 + //
  664 + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
  665 + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
  666 + // at the end of the path value of PCLZIP_OPT_PATH.
  667 + // Parameters :
  668 + // $p_path : Path where the files and directories are to be extracted
  669 + // $p_remove_path : First part ('root' part) of the memorized path
  670 + // (if any similar) to remove while extracting.
  671 + // Options :
  672 + // PCLZIP_OPT_PATH :
  673 + // PCLZIP_OPT_ADD_PATH :
  674 + // PCLZIP_OPT_REMOVE_PATH :
  675 + // PCLZIP_OPT_REMOVE_ALL_PATH :
  676 + // PCLZIP_CB_PRE_EXTRACT :
  677 + // PCLZIP_CB_POST_EXTRACT :
  678 + // Return Values :
  679 + // 0 or a negative value on failure,
  680 + // The list of the extracted files, with a status of the action.
  681 + // (see PclZip::listContent() for list entry format)
  682 + // --------------------------------------------------------------------------------
  683 + function extract()
  684 + {
  685 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extract", "");
  686 + $v_result=1;
  687 +
  688 + // ----- Reset the error handler
  689 + $this->privErrorReset();
  690 +
  691 + // ----- Check archive
  692 + if (!$this->privCheckFormat()) {
  693 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  694 + return(0);
  695 + }
  696 +
  697 + // ----- Set default values
  698 + $v_options = array();
  699 +// $v_path = "./";
  700 + $v_path = '';
  701 + $v_remove_path = "";
  702 + $v_remove_all_path = false;
  703 +
  704 + // ----- Look for variable options arguments
  705 + $v_size = func_num_args();
  706 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
  707 +
  708 + // ----- Default values for option
  709 + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
  710 +
  711 + // ----- Look for arguments
  712 + if ($v_size > 0) {
  713 + // ----- Get the arguments
  714 + $v_arg_list = func_get_args();
  715 +
  716 + // ----- Look for first arg
  717 + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  718 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");
  719 +
  720 + // ----- Parse the options
  721 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  722 + array (PCLZIP_OPT_PATH => 'optional',
  723 + PCLZIP_OPT_REMOVE_PATH => 'optional',
  724 + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  725 + PCLZIP_OPT_ADD_PATH => 'optional',
  726 + PCLZIP_CB_PRE_EXTRACT => 'optional',
  727 + PCLZIP_CB_POST_EXTRACT => 'optional',
  728 + PCLZIP_OPT_SET_CHMOD => 'optional',
  729 + PCLZIP_OPT_BY_NAME => 'optional',
  730 + PCLZIP_OPT_BY_EREG => 'optional',
  731 + PCLZIP_OPT_BY_PREG => 'optional',
  732 + PCLZIP_OPT_BY_INDEX => 'optional',
  733 + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
  734 + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
  735 + PCLZIP_OPT_REPLACE_NEWER => 'optional'
  736 + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
  737 + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional'
  738 + ));
  739 + if ($v_result != 1) {
  740 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  741 + return 0;
  742 + }
  743 +
  744 + // ----- Set the arguments
  745 + if (isset($v_options[PCLZIP_OPT_PATH])) {
  746 + $v_path = $v_options[PCLZIP_OPT_PATH];
  747 + }
  748 + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
  749 + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
  750 + }
  751 + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  752 + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  753 + }
  754 + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
  755 + // ----- Check for '/' in last path char
  756 + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
  757 + $v_path .= '/';
  758 + }
  759 + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
  760 + }
  761 + }
  762 +
  763 + // ----- Look for 2 args
  764 + // Here we need to support the first historic synopsis of the
  765 + // method.
  766 + else {
  767 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
  768 +
  769 + // ----- Get the first argument
  770 + $v_path = $v_arg_list[0];
  771 +
  772 + // ----- Look for the optional second argument
  773 + if ($v_size == 2) {
  774 + $v_remove_path = $v_arg_list[1];
  775 + }
  776 + else if ($v_size > 2) {
  777 + // ----- Error log
  778 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  779 +
  780 + // ----- Return
  781 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
  782 + return 0;
  783 + }
  784 + }
  785 + }
  786 +
  787 + // ----- Trace
  788 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");
  789 +
  790 + // ----- Call the extracting fct
  791 + $p_list = array();
  792 + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
  793 + $v_remove_all_path, $v_options);
  794 + if ($v_result < 1) {
  795 + unset($p_list);
  796 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
  797 + return(0);
  798 + }
  799 +
  800 + // ----- Return
  801 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
  802 + return $p_list;
  803 + }
  804 + // --------------------------------------------------------------------------------
  805 +
  806 +
  807 + // --------------------------------------------------------------------------------
  808 + // Function :
  809 + // extractByIndex($p_index, $p_path="./", $p_remove_path="")
  810 + // extractByIndex($p_index, [$p_option, $p_option_value, ...])
  811 + // Description :
  812 + // This method supports two synopsis. The first one is historical.
  813 + // This method is doing a partial extract of the archive.
  814 + // The extracted files or folders are identified by their index in the
  815 + // archive (from 0 to n).
  816 + // Note that if the index identify a folder, only the folder entry is
  817 + // extracted, not all the files included in the archive.
  818 + // Parameters :
  819 + // $p_index : A single index (integer) or a string of indexes of files to
  820 + // extract. The form of the string is "0,4-6,8-12" with only numbers
  821 + // and '-' for range or ',' to separate ranges. No spaces or ';'
  822 + // are allowed.
  823 + // $p_path : Path where the files and directories are to be extracted
  824 + // $p_remove_path : First part ('root' part) of the memorized path
  825 + // (if any similar) to remove while extracting.
  826 + // Options :
  827 + // PCLZIP_OPT_PATH :
  828 + // PCLZIP_OPT_ADD_PATH :
  829 + // PCLZIP_OPT_REMOVE_PATH :
  830 + // PCLZIP_OPT_REMOVE_ALL_PATH :
  831 + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
  832 + // not as files.
  833 + // The resulting content is in a new field 'content' in the file
  834 + // structure.
  835 + // This option must be used alone (any other options are ignored).
  836 + // PCLZIP_CB_PRE_EXTRACT :
  837 + // PCLZIP_CB_POST_EXTRACT :
  838 + // Return Values :
  839 + // 0 on failure,
  840 + // The list of the extracted files, with a status of the action.
  841 + // (see PclZip::listContent() for list entry format)
  842 + // --------------------------------------------------------------------------------
  843 + //function extractByIndex($p_index, options...)
  844 + function extractByIndex($p_index)
  845 + {
  846 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extractByIndex", "index='$p_index', ...");
  847 + $v_result=1;
  848 +
  849 + // ----- Reset the error handler
  850 + $this->privErrorReset();
  851 +
  852 + // ----- Check archive
  853 + if (!$this->privCheckFormat()) {
  854 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  855 + return(0);
  856 + }
  857 +
  858 + // ----- Set default values
  859 + $v_options = array();
  860 +// $v_path = "./";
  861 + $v_path = '';
  862 + $v_remove_path = "";
  863 + $v_remove_all_path = false;
  864 +
  865 + // ----- Look for variable options arguments
  866 + $v_size = func_num_args();
  867 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
  868 +
  869 + // ----- Default values for option
  870 + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
  871 +
  872 + // ----- Look for arguments
  873 + if ($v_size > 1) {
  874 + // ----- Get the arguments
  875 + $v_arg_list = func_get_args();
  876 +
  877 + // ----- Remove form the options list the first argument
  878 + array_shift($v_arg_list);
  879 + $v_size--;
  880 +
  881 + // ----- Look for first arg
  882 + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  883 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");
  884 +
  885 + // ----- Parse the options
  886 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  887 + array (PCLZIP_OPT_PATH => 'optional',
  888 + PCLZIP_OPT_REMOVE_PATH => 'optional',
  889 + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  890 + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
  891 + PCLZIP_OPT_ADD_PATH => 'optional',
  892 + PCLZIP_CB_PRE_EXTRACT => 'optional',
  893 + PCLZIP_CB_POST_EXTRACT => 'optional',
  894 + PCLZIP_OPT_SET_CHMOD => 'optional',
  895 + PCLZIP_OPT_REPLACE_NEWER => 'optional'
  896 + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
  897 + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional'
  898 + ));
  899 + if ($v_result != 1) {
  900 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  901 + return 0;
  902 + }
  903 +
  904 + // ----- Set the arguments
  905 + if (isset($v_options[PCLZIP_OPT_PATH])) {
  906 + $v_path = $v_options[PCLZIP_OPT_PATH];
  907 + }
  908 + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
  909 + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
  910 + }
  911 + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  912 + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  913 + }
  914 + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
  915 + // ----- Check for '/' in last path char
  916 + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
  917 + $v_path .= '/';
  918 + }
  919 + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
  920 + }
  921 + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
  922 + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
  923 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING not set.");
  924 + }
  925 + else {
  926 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING set.");
  927 + }
  928 + }
  929 +
  930 + // ----- Look for 2 args
  931 + // Here we need to support the first historic synopsis of the
  932 + // method.
  933 + else {
  934 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
  935 +
  936 + // ----- Get the first argument
  937 + $v_path = $v_arg_list[0];
  938 +
  939 + // ----- Look for the optional second argument
  940 + if ($v_size == 2) {
  941 + $v_remove_path = $v_arg_list[1];
  942 + }
  943 + else if ($v_size > 2) {
  944 + // ----- Error log
  945 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  946 +
  947 + // ----- Return
  948 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  949 + return 0;
  950 + }
  951 + }
  952 + }
  953 +
  954 + // ----- Trace
  955 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "index='$p_index', path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");
  956 +
  957 + // ----- Trick
  958 + // Here I want to reuse extractByRule(), so I need to parse the $p_index
  959 + // with privParseOptions()
  960 + $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
  961 + $v_options_trick = array();
  962 + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
  963 + array (PCLZIP_OPT_BY_INDEX => 'optional' ));
  964 + if ($v_result != 1) {
  965 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  966 + return 0;
  967 + }
  968 + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
  969 +
  970 + // ----- Call the extracting fct
  971 + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
  972 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
  973 + return(0);
  974 + }
  975 +
  976 + // ----- Return
  977 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
  978 + return $p_list;
  979 + }
  980 + // --------------------------------------------------------------------------------
  981 +
  982 + // --------------------------------------------------------------------------------
  983 + // Function :
  984 + // delete([$p_option, $p_option_value, ...])
  985 + // Description :
  986 + // This method removes files from the archive.
  987 + // If no parameters are given, then all the archive is emptied.
  988 + // Parameters :
  989 + // None or optional arguments.
  990 + // Options :
  991 + // PCLZIP_OPT_BY_INDEX :
  992 + // PCLZIP_OPT_BY_NAME :
  993 + // PCLZIP_OPT_BY_EREG :
  994 + // PCLZIP_OPT_BY_PREG :
  995 + // Return Values :
  996 + // 0 on failure,
  997 + // The list of the files which are still present in the archive.
  998 + // (see PclZip::listContent() for list entry format)
  999 + // --------------------------------------------------------------------------------
  1000 + function delete()
  1001 + {
  1002 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::delete", "");
  1003 + $v_result=1;
  1004 +
  1005 + // ----- Reset the error handler
  1006 + $this->privErrorReset();
  1007 +
  1008 + // ----- Check archive
  1009 + if (!$this->privCheckFormat()) {
  1010 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  1011 + return(0);
  1012 + }
  1013 +
  1014 + // ----- Set default values
  1015 + $v_options = array();
  1016 +
  1017 + // ----- Look for variable options arguments
  1018 + $v_size = func_num_args();
  1019 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
  1020 +
  1021 + // ----- Look for arguments
  1022 + if ($v_size > 0) {
  1023 + // ----- Get the arguments
  1024 + $v_arg_list = func_get_args();
  1025 +
  1026 + // ----- Parse the options
  1027 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  1028 + array (PCLZIP_OPT_BY_NAME => 'optional',
  1029 + PCLZIP_OPT_BY_EREG => 'optional',
  1030 + PCLZIP_OPT_BY_PREG => 'optional',
  1031 + PCLZIP_OPT_BY_INDEX => 'optional' ));
  1032 + if ($v_result != 1) {
  1033 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  1034 + return 0;
  1035 + }
  1036 + }
  1037 +
  1038 + // ----- Magic quotes trick
  1039 + $this->privDisableMagicQuotes();
  1040 +
  1041 + // ----- Call the delete fct
  1042 + $v_list = array();
  1043 + if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
  1044 + $this->privSwapBackMagicQuotes();
  1045 + unset($v_list);
  1046 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
  1047 + return(0);
  1048 + }
  1049 +
  1050 + // ----- Magic quotes trick
  1051 + $this->privSwapBackMagicQuotes();
  1052 +
  1053 + // ----- Return
  1054 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_list);
  1055 + return $v_list;
  1056 + }
  1057 + // --------------------------------------------------------------------------------
  1058 +
  1059 + // --------------------------------------------------------------------------------
  1060 + // Function : deleteByIndex()
  1061 + // Description :
  1062 + // ***** Deprecated *****
  1063 + // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
  1064 + // --------------------------------------------------------------------------------
  1065 + function deleteByIndex($p_index)
  1066 + {
  1067 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'");
  1068 +
  1069 + $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
  1070 +
  1071 + // ----- Return
  1072 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
  1073 + return $p_list;
  1074 + }
  1075 + // --------------------------------------------------------------------------------
  1076 +
  1077 + // --------------------------------------------------------------------------------
  1078 + // Function : properties()
  1079 + // Description :
  1080 + // This method gives the properties of the archive.
  1081 + // The properties are :
  1082 + // nb : Number of files in the archive
  1083 + // comment : Comment associated with the archive file
  1084 + // status : not_exist, ok
  1085 + // Parameters :
  1086 + // None
  1087 + // Return Values :
  1088 + // 0 on failure,
  1089 + // An array with the archive properties.
  1090 + // --------------------------------------------------------------------------------
  1091 + function properties()
  1092 + {
  1093 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::properties", "");
  1094 +
  1095 + // ----- Reset the error handler
  1096 + $this->privErrorReset();
  1097 +
  1098 + // ----- Magic quotes trick
  1099 + $this->privDisableMagicQuotes();
  1100 +
  1101 + // ----- Check archive
  1102 + if (!$this->privCheckFormat()) {
  1103 + $this->privSwapBackMagicQuotes();
  1104 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  1105 + return(0);
  1106 + }
  1107 +
  1108 + // ----- Default properties
  1109 + $v_prop = array();
  1110 + $v_prop['comment'] = '';
  1111 + $v_prop['nb'] = 0;
  1112 + $v_prop['status'] = 'not_exist';
  1113 +
  1114 + // ----- Look if file exists
  1115 + if (@is_file($this->zipname))
  1116 + {
  1117 + // ----- Open the zip file
  1118 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  1119 + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
  1120 + {
  1121 + $this->privSwapBackMagicQuotes();
  1122 +
  1123 + // ----- Error log
  1124 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
  1125 +
  1126 + // ----- Return
  1127 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), 0);
  1128 + return 0;
  1129 + }
  1130 +
  1131 + // ----- Read the central directory informations
  1132 + $v_central_dir = array();
  1133 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  1134 + {
  1135 + $this->privSwapBackMagicQuotes();
  1136 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  1137 + return 0;
  1138 + }
  1139 +
  1140 + // ----- Close the zip file
  1141 + $this->privCloseFd();
  1142 +
  1143 + // ----- Set the user attributes
  1144 + $v_prop['comment'] = $v_central_dir['comment'];
  1145 + $v_prop['nb'] = $v_central_dir['entries'];
  1146 + $v_prop['status'] = 'ok';
  1147 + }
  1148 +
  1149 + // ----- Magic quotes trick
  1150 + $this->privSwapBackMagicQuotes();
  1151 +
  1152 + // ----- Return
  1153 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_prop);
  1154 + return $v_prop;
  1155 + }
  1156 + // --------------------------------------------------------------------------------
  1157 +
  1158 + // --------------------------------------------------------------------------------
  1159 + // Function : duplicate()
  1160 + // Description :
  1161 + // This method creates an archive by copying the content of an other one. If
  1162 + // the archive already exist, it is replaced by the new one without any warning.
  1163 + // Parameters :
  1164 + // $p_archive : The filename of a valid archive, or
  1165 + // a valid PclZip object.
  1166 + // Return Values :
  1167 + // 1 on success.
  1168 + // 0 or a negative value on error (error code).
  1169 + // --------------------------------------------------------------------------------
  1170 + function duplicate($p_archive)
  1171 + {
  1172 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::duplicate", "");
  1173 + $v_result = 1;
  1174 +
  1175 + // ----- Reset the error handler
  1176 + $this->privErrorReset();
  1177 +
  1178 + // ----- Look if the $p_archive is a PclZip object
  1179 + if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
  1180 + {
  1181 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is valid PclZip object '".$p_archive->zipname."'");
  1182 +
  1183 + // ----- Duplicate the archive
  1184 + $v_result = $this->privDuplicate($p_archive->zipname);
  1185 + }
  1186 +
  1187 + // ----- Look if the $p_archive is a string (so a filename)
  1188 + else if (is_string($p_archive))
  1189 + {
  1190 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is a filename '$p_archive'");
  1191 +
  1192 + // ----- Check that $p_archive is a valid zip file
  1193 + // TBC : Should also check the archive format
  1194 + if (!is_file($p_archive)) {
  1195 + // ----- Error log
  1196 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
  1197 + $v_result = PCLZIP_ERR_MISSING_FILE;
  1198 + }
  1199 + else {
  1200 + // ----- Duplicate the archive
  1201 + $v_result = $this->privDuplicate($p_archive);
  1202 + }
  1203 + }
  1204 +
  1205 + // ----- Invalid variable
  1206 + else
  1207 + {
  1208 + // ----- Error log
  1209 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
  1210 + $v_result = PCLZIP_ERR_INVALID_PARAMETER;
  1211 + }
  1212 +
  1213 + // ----- Return
  1214 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1215 + return $v_result;
  1216 + }
  1217 + // --------------------------------------------------------------------------------
  1218 +
  1219 + // --------------------------------------------------------------------------------
  1220 + // Function : merge()
  1221 + // Description :
  1222 + // This method merge the $p_archive_to_add archive at the end of the current
  1223 + // one ($this).
  1224 + // If the archive ($this) does not exist, the merge becomes a duplicate.
  1225 + // If the $p_archive_to_add archive does not exist, the merge is a success.
  1226 + // Parameters :
  1227 + // $p_archive_to_add : It can be directly the filename of a valid zip archive,
  1228 + // or a PclZip object archive.
  1229 + // Return Values :
  1230 + // 1 on success,
  1231 + // 0 or negative values on error (see below).
  1232 + // --------------------------------------------------------------------------------
  1233 + function merge($p_archive_to_add)
  1234 + {
  1235 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::merge", "");
  1236 + $v_result = 1;
  1237 +
  1238 + // ----- Reset the error handler
  1239 + $this->privErrorReset();
  1240 +
  1241 + // ----- Check archive
  1242 + if (!$this->privCheckFormat()) {
  1243 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  1244 + return(0);
  1245 + }
  1246 +
  1247 + // ----- Look if the $p_archive_to_add is a PclZip object
  1248 + if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
  1249 + {
  1250 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is valid PclZip object");
  1251 +
  1252 + // ----- Merge the archive
  1253 + $v_result = $this->privMerge($p_archive_to_add);
  1254 + }
  1255 +
  1256 + // ----- Look if the $p_archive_to_add is a string (so a filename)
  1257 + else if (is_string($p_archive_to_add))
  1258 + {
  1259 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is a filename");
  1260 +
  1261 + // ----- Create a temporary archive
  1262 + $v_object_archive = new PclZip($p_archive_to_add);
  1263 +
  1264 + // ----- Merge the archive
  1265 + $v_result = $this->privMerge($v_object_archive);
  1266 + }
  1267 +
  1268 + // ----- Invalid variable
  1269 + else
  1270 + {
  1271 + // ----- Error log
  1272 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
  1273 + $v_result = PCLZIP_ERR_INVALID_PARAMETER;
  1274 + }
  1275 +
  1276 + // ----- Return
  1277 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1278 + return $v_result;
  1279 + }
  1280 + // --------------------------------------------------------------------------------
  1281 +
  1282 +
  1283 +
  1284 + // --------------------------------------------------------------------------------
  1285 + // Function : errorCode()
  1286 + // Description :
  1287 + // Parameters :
  1288 + // --------------------------------------------------------------------------------
  1289 + function errorCode()
  1290 + {
  1291 + if (PCLZIP_ERROR_EXTERNAL == 1) {
  1292 + return(PclErrorCode());
  1293 + }
  1294 + else {
  1295 + return($this->error_code);
  1296 + }
  1297 + }
  1298 + // --------------------------------------------------------------------------------
  1299 +
  1300 + // --------------------------------------------------------------------------------
  1301 + // Function : errorName()
  1302 + // Description :
  1303 + // Parameters :
  1304 + // --------------------------------------------------------------------------------
  1305 + function errorName($p_with_code=false)
  1306 + {
  1307 + $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
  1308 + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
  1309 + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
  1310 + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
  1311 + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
  1312 + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
  1313 + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
  1314 + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
  1315 + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
  1316 + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
  1317 + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
  1318 + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
  1319 + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
  1320 + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
  1321 + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
  1322 + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
  1323 + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
  1324 + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
  1325 + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
  1326 + ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
  1327 + ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
  1328 + );
  1329 +
  1330 + if (isset($v_name[$this->error_code])) {
  1331 + $v_value = $v_name[$this->error_code];
  1332 + }
  1333 + else {
  1334 + $v_value = 'NoName';
  1335 + }
  1336 +
  1337 + if ($p_with_code) {
  1338 + return($v_value.' ('.$this->error_code.')');
  1339 + }
  1340 + else {
  1341 + return($v_value);
  1342 + }
  1343 + }
  1344 + // --------------------------------------------------------------------------------
  1345 +
  1346 + // --------------------------------------------------------------------------------
  1347 + // Function : errorInfo()
  1348 + // Description :
  1349 + // Parameters :
  1350 + // --------------------------------------------------------------------------------
  1351 + function errorInfo($p_full=false)
  1352 + {
  1353 + if (PCLZIP_ERROR_EXTERNAL == 1) {
  1354 + return(PclErrorString());
  1355 + }
  1356 + else {
  1357 + if ($p_full) {
  1358 + return($this->errorName(true)." : ".$this->error_string);
  1359 + }
  1360 + else {
  1361 + return($this->error_string." [code ".$this->error_code."]");
  1362 + }
  1363 + }
  1364 + }
  1365 + // --------------------------------------------------------------------------------
  1366 +
  1367 +
  1368 +// --------------------------------------------------------------------------------
  1369 +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
  1370 +// ***** *****
  1371 +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
  1372 +// --------------------------------------------------------------------------------
  1373 +
  1374 +
  1375 +
  1376 + // --------------------------------------------------------------------------------
  1377 + // Function : privCheckFormat()
  1378 + // Description :
  1379 + // This method check that the archive exists and is a valid zip archive.
  1380 + // Several level of check exists. (futur)
  1381 + // Parameters :
  1382 + // $p_level : Level of check. Default 0.
  1383 + // 0 : Check the first bytes (magic codes) (default value))
  1384 + // 1 : 0 + Check the central directory (futur)
  1385 + // 2 : 1 + Check each file header (futur)
  1386 + // Return Values :
  1387 + // true on success,
  1388 + // false on error, the error code is set.
  1389 + // --------------------------------------------------------------------------------
  1390 + function privCheckFormat($p_level=0)
  1391 + {
  1392 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFormat", "");
  1393 + $v_result = true;
  1394 +
  1395 + // ----- Reset the file system cache
  1396 + clearstatcache();
  1397 +
  1398 + // ----- Reset the error handler
  1399 + $this->privErrorReset();
  1400 +
  1401 + // ----- Look if the file exits
  1402 + if (!is_file($this->zipname)) {
  1403 + // ----- Error log
  1404 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
  1405 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());
  1406 + return(false);
  1407 + }
  1408 +
  1409 + // ----- Check that the file is readeable
  1410 + if (!is_readable($this->zipname)) {
  1411 + // ----- Error log
  1412 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
  1413 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());
  1414 + return(false);
  1415 + }
  1416 +
  1417 + // ----- Check the magic code
  1418 + // TBC
  1419 +
  1420 + // ----- Check the central header
  1421 + // TBC
  1422 +
  1423 + // ----- Check each file header
  1424 + // TBC
  1425 +
  1426 + // ----- Return
  1427 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1428 + return $v_result;
  1429 + }
  1430 + // --------------------------------------------------------------------------------
  1431 +
  1432 + // --------------------------------------------------------------------------------
  1433 + // Function : privParseOptions()
  1434 + // Description :
  1435 + // This internal methods reads the variable list of arguments ($p_options_list,
  1436 + // $p_size) and generate an array with the options and values ($v_result_list).
  1437 + // $v_requested_options contains the options that can be present and those that
  1438 + // must be present.
  1439 + // $v_requested_options is an array, with the option value as key, and 'optional',
  1440 + // or 'mandatory' as value.
  1441 + // Parameters :
  1442 + // See above.
  1443 + // Return Values :
  1444 + // 1 on success.
  1445 + // 0 on failure.
  1446 + // --------------------------------------------------------------------------------
  1447 + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
  1448 + {
  1449 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privParseOptions", "");
  1450 + $v_result=1;
  1451 +
  1452 + // ----- Read the options
  1453 + $i=0;
  1454 + while ($i<$p_size) {
  1455 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Looking for table index $i, option = '".PclZipUtilOptionText($p_options_list[$i])."(".$p_options_list[$i].")'");
  1456 +
  1457 + // ----- Check if the option is supported
  1458 + if (!isset($v_requested_options[$p_options_list[$i]])) {
  1459 + // ----- Error log
  1460 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
  1461 +
  1462 + // ----- Return
  1463 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1464 + return PclZip::errorCode();
  1465 + }
  1466 +
  1467 + // ----- Look for next option
  1468 + switch ($p_options_list[$i]) {
  1469 + // ----- Look for options that request a path value
  1470 + case PCLZIP_OPT_PATH :
  1471 + case PCLZIP_OPT_REMOVE_PATH :
  1472 + case PCLZIP_OPT_ADD_PATH :
  1473 + // ----- Check the number of parameters
  1474 + if (($i+1) >= $p_size) {
  1475 + // ----- Error log
  1476 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1477 +
  1478 + // ----- Return
  1479 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1480 + return PclZip::errorCode();
  1481 + }
  1482 +
  1483 + // ----- Get the value
  1484 + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false);
  1485 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
  1486 + $i++;
  1487 + break;
  1488 +
  1489 + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
  1490 + // ----- Check the number of parameters
  1491 + if (($i+1) >= $p_size) {
  1492 + // ----- Error log
  1493 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1494 +
  1495 + // ----- Return
  1496 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1497 + return PclZip::errorCode();
  1498 + }
  1499 +
  1500 + // ----- Get the value
  1501 + if ( is_string($p_options_list[$i+1])
  1502 + && ($p_options_list[$i+1] != '')) {
  1503 + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false);
  1504 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
  1505 + $i++;
  1506 + }
  1507 + else {
  1508 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." set with an empty value is ignored.");
  1509 + }
  1510 + break;
  1511 +
  1512 + // ----- Look for options that request an array of string for value
  1513 + case PCLZIP_OPT_BY_NAME :
  1514 + // ----- Check the number of parameters
  1515 + if (($i+1) >= $p_size) {
  1516 + // ----- Error log
  1517 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1518 +
  1519 + // ----- Return
  1520 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1521 + return PclZip::errorCode();
  1522 + }
  1523 +
  1524 + // ----- Get the value
  1525 + if (is_string($p_options_list[$i+1])) {
  1526 + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
  1527 + }
  1528 + else if (is_array($p_options_list[$i+1])) {
  1529 + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1530 + }
  1531 + else {
  1532 + // ----- Error log
  1533 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1534 +
  1535 + // ----- Return
  1536 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1537 + return PclZip::errorCode();
  1538 + }
  1539 + ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
  1540 + $i++;
  1541 + break;
  1542 +
  1543 + // ----- Look for options that request an EREG or PREG expression
  1544 + case PCLZIP_OPT_BY_EREG :
  1545 + case PCLZIP_OPT_BY_PREG :
  1546 + //case PCLZIP_OPT_CRYPT :
  1547 + // ----- Check the number of parameters
  1548 + if (($i+1) >= $p_size) {
  1549 + // ----- Error log
  1550 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1551 +
  1552 + // ----- Return
  1553 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1554 + return PclZip::errorCode();
  1555 + }
  1556 +
  1557 + // ----- Get the value
  1558 + if (is_string($p_options_list[$i+1])) {
  1559 + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1560 + }
  1561 + else {
  1562 + // ----- Error log
  1563 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1564 +
  1565 + // ----- Return
  1566 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1567 + return PclZip::errorCode();
  1568 + }
  1569 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
  1570 + $i++;
  1571 + break;
  1572 +
  1573 + // ----- Look for options that takes a string
  1574 + case PCLZIP_OPT_COMMENT :
  1575 + case PCLZIP_OPT_ADD_COMMENT :
  1576 + case PCLZIP_OPT_PREPEND_COMMENT :
  1577 + // ----- Check the number of parameters
  1578 + if (($i+1) >= $p_size) {
  1579 + // ----- Error log
  1580 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
  1581 + "Missing parameter value for option '"
  1582 + .PclZipUtilOptionText($p_options_list[$i])
  1583 + ."'");
  1584 +
  1585 + // ----- Return
  1586 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1587 + return PclZip::errorCode();
  1588 + }
  1589 +
  1590 + // ----- Get the value
  1591 + if (is_string($p_options_list[$i+1])) {
  1592 + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1593 + }
  1594 + else {
  1595 + // ----- Error log
  1596 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
  1597 + "Wrong parameter value for option '"
  1598 + .PclZipUtilOptionText($p_options_list[$i])
  1599 + ."'");
  1600 +
  1601 + // ----- Return
  1602 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1603 + return PclZip::errorCode();
  1604 + }
  1605 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
  1606 + $i++;
  1607 + break;
  1608 +
  1609 + // ----- Look for options that request an array of index
  1610 + case PCLZIP_OPT_BY_INDEX :
  1611 + // ----- Check the number of parameters
  1612 + if (($i+1) >= $p_size) {
  1613 + // ----- Error log
  1614 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1615 +
  1616 + // ----- Return
  1617 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1618 + return PclZip::errorCode();
  1619 + }
  1620 +
  1621 + // ----- Get the value
  1622 + $v_work_list = array();
  1623 + if (is_string($p_options_list[$i+1])) {
  1624 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is a string '".$p_options_list[$i+1]."'");
  1625 +
  1626 + // ----- Remove spaces
  1627 + $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
  1628 +
  1629 + // ----- Parse items
  1630 + $v_work_list = explode(",", $p_options_list[$i+1]);
  1631 + }
  1632 + else if (is_integer($p_options_list[$i+1])) {
  1633 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an integer '".$p_options_list[$i+1]."'");
  1634 + $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
  1635 + }
  1636 + else if (is_array($p_options_list[$i+1])) {
  1637 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an array");
  1638 + $v_work_list = $p_options_list[$i+1];
  1639 + }
  1640 + else {
  1641 + // ----- Error log
  1642 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1643 +
  1644 + // ----- Return
  1645 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1646 + return PclZip::errorCode();
  1647 + }
  1648 +
  1649 + // ----- Reduce the index list
  1650 + // each index item in the list must be a couple with a start and
  1651 + // an end value : [0,3], [5-5], [8-10], ...
  1652 + // ----- Check the format of each item
  1653 + $v_sort_flag=false;
  1654 + $v_sort_value=0;
  1655 + for ($j=0; $j<sizeof($v_work_list); $j++) {
  1656 + // ----- Explode the item
  1657 + $v_item_list = explode("-", $v_work_list[$j]);
  1658 + $v_size_item_list = sizeof($v_item_list);
  1659 +
  1660 + // ----- TBC : Here we might check that each item is a
  1661 + // real integer ...
  1662 +
  1663 + // ----- Look for single value
  1664 + if ($v_size_item_list == 1) {
  1665 + // ----- Set the option value
  1666 + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
  1667 + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
  1668 + }
  1669 + elseif ($v_size_item_list == 2) {
  1670 + // ----- Set the option value
  1671 + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
  1672 + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
  1673 + }
  1674 + else {
  1675 + // ----- Error log
  1676 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1677 +
  1678 + // ----- Return
  1679 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1680 + return PclZip::errorCode();
  1681 + }
  1682 +
  1683 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extracted index item = [".$v_result_list[$p_options_list[$i]][$j]['start'].",".$v_result_list[$p_options_list[$i]][$j]['end']."]");
  1684 +
  1685 + // ----- Look for list sort
  1686 + if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
  1687 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The list should be sorted ...");
  1688 + $v_sort_flag=true;
  1689 +
  1690 + // ----- TBC : An automatic sort should be writen ...
  1691 + // ----- Error log
  1692 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1693 +
  1694 + // ----- Return
  1695 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1696 + return PclZip::errorCode();
  1697 + }
  1698 + $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
  1699 + }
  1700 +
  1701 + // ----- Sort the items
  1702 + if ($v_sort_flag) {
  1703 + // TBC : To Be Completed
  1704 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "List sorting is not yet write ...");
  1705 + }
  1706 +
  1707 + // ----- Next option
  1708 + $i++;
  1709 + break;
  1710 +
  1711 + // ----- Look for options that request no value
  1712 + case PCLZIP_OPT_REMOVE_ALL_PATH :
  1713 + case PCLZIP_OPT_EXTRACT_AS_STRING :
  1714 + case PCLZIP_OPT_NO_COMPRESSION :
  1715 + case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
  1716 + case PCLZIP_OPT_REPLACE_NEWER :
  1717 + case PCLZIP_OPT_STOP_ON_ERROR :
  1718 + $v_result_list[$p_options_list[$i]] = true;
  1719 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
  1720 + break;
  1721 +
  1722 + // ----- Look for options that request an octal value
  1723 + case PCLZIP_OPT_SET_CHMOD :
  1724 + // ----- Check the number of parameters
  1725 + if (($i+1) >= $p_size) {
  1726 + // ----- Error log
  1727 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1728 +
  1729 + // ----- Return
  1730 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1731 + return PclZip::errorCode();
  1732 + }
  1733 +
  1734 + // ----- Get the value
  1735 + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1736 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
  1737 + $i++;
  1738 + break;
  1739 +
  1740 + // ----- Look for options that request a call-back
  1741 + case PCLZIP_CB_PRE_EXTRACT :
  1742 + case PCLZIP_CB_POST_EXTRACT :
  1743 + case PCLZIP_CB_PRE_ADD :
  1744 + case PCLZIP_CB_POST_ADD :
  1745 + /* for futur use
  1746 + case PCLZIP_CB_PRE_DELETE :
  1747 + case PCLZIP_CB_POST_DELETE :
  1748 + case PCLZIP_CB_PRE_LIST :
  1749 + case PCLZIP_CB_POST_LIST :
  1750 + */
  1751 + // ----- Check the number of parameters
  1752 + if (($i+1) >= $p_size) {
  1753 + // ----- Error log
  1754 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1755 +
  1756 + // ----- Return
  1757 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1758 + return PclZip::errorCode();
  1759 + }
  1760 +
  1761 + // ----- Get the value
  1762 + $v_function_name = $p_options_list[$i+1];
  1763 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "call-back ".PclZipUtilOptionText($p_options_list[$i])." = '".$v_function_name."'");
  1764 +
  1765 + // ----- Check that the value is a valid existing function
  1766 + if (!function_exists($v_function_name)) {
  1767 + // ----- Error log
  1768 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1769 +
  1770 + // ----- Return
  1771 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1772 + return PclZip::errorCode();
  1773 + }
  1774 +
  1775 + // ----- Set the attribute
  1776 + $v_result_list[$p_options_list[$i]] = $v_function_name;
  1777 + $i++;
  1778 + break;
  1779 +
  1780 + default :
  1781 + // ----- Error log
  1782 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
  1783 + "Unknown parameter '"
  1784 + .$p_options_list[$i]."'");
  1785 +
  1786 + // ----- Return
  1787 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1788 + return PclZip::errorCode();
  1789 + }
  1790 +
  1791 + // ----- Next options
  1792 + $i++;
  1793 + }
  1794 +
  1795 + // ----- Look for mandatory options
  1796 + if ($v_requested_options !== false) {
  1797 + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
  1798 + // ----- Look for mandatory option
  1799 + if ($v_requested_options[$key] == 'mandatory') {
  1800 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")");
  1801 + // ----- Look if present
  1802 + if (!isset($v_result_list[$key])) {
  1803 + // ----- Error log
  1804 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
  1805 +
  1806 + // ----- Return
  1807 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1808 + return PclZip::errorCode();
  1809 + }
  1810 + }
  1811 + }
  1812 + }
  1813 +
  1814 + // ----- Return
  1815 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1816 + return $v_result;
  1817 + }
  1818 + // --------------------------------------------------------------------------------
  1819 +
  1820 + // --------------------------------------------------------------------------------
  1821 + // Function : privFileDescrParseAtt()
  1822 + // Description :
  1823 + // Parameters :
  1824 + // Return Values :
  1825 + // 1 on success.
  1826 + // 0 on failure.
  1827 + // --------------------------------------------------------------------------------
  1828 + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
  1829 + {
  1830 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrParseAtt", "");
  1831 + $v_result=1;
  1832 +
  1833 + // ----- For each file in the list check the attributes
  1834 + foreach ($p_file_list as $v_key => $v_value) {
  1835 +
  1836 + // ----- Check if the option is supported
  1837 + if (!isset($v_requested_options[$v_key])) {
  1838 + // ----- Error log
  1839 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
  1840 +
  1841 + // ----- Return
  1842 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1843 + return PclZip::errorCode();
  1844 + }
  1845 +
  1846 + // ----- Look for attribute
  1847 + switch ($v_key) {
  1848 + case PCLZIP_ATT_FILE_NAME :
  1849 + if (!is_string($v_value)) {
  1850 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1851 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1852 + return PclZip::errorCode();
  1853 + }
  1854 +
  1855 + $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
  1856 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");
  1857 +
  1858 + if ($p_filedescr['filename'] == '') {
  1859 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
  1860 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1861 + return PclZip::errorCode();
  1862 + }
  1863 +
  1864 + break;
  1865 +
  1866 + case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
  1867 + if (!is_string($v_value)) {
  1868 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1869 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1870 + return PclZip::errorCode();
  1871 + }
  1872 +
  1873 + $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
  1874 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");
  1875 +
  1876 + if ($p_filedescr['new_short_name'] == '') {
  1877 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
  1878 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1879 + return PclZip::errorCode();
  1880 + }
  1881 + break;
  1882 +
  1883 + case PCLZIP_ATT_FILE_NEW_FULL_NAME :
  1884 + if (!is_string($v_value)) {
  1885 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1886 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1887 + return PclZip::errorCode();
  1888 + }
  1889 +
  1890 + $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
  1891 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");
  1892 +
  1893 + if ($p_filedescr['new_full_name'] == '') {
  1894 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
  1895 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1896 + return PclZip::errorCode();
  1897 + }
  1898 + break;
  1899 +
  1900 + default :
  1901 + // ----- Error log
  1902 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
  1903 + "Unknown parameter '".$v_key."'");
  1904 +
  1905 + // ----- Return
  1906 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1907 + return PclZip::errorCode();
  1908 + }
  1909 +
  1910 + // ----- Look for mandatory options
  1911 + if ($v_requested_options !== false) {
  1912 + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
  1913 + // ----- Look for mandatory option
  1914 + if ($v_requested_options[$key] == 'mandatory') {
  1915 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")");
  1916 + // ----- Look if present
  1917 + if (!isset($p_file_list[$key])) {
  1918 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
  1919 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1920 + return PclZip::errorCode();
  1921 + }
  1922 + }
  1923 + }
  1924 + }
  1925 +
  1926 + // end foreach
  1927 + }
  1928 +
  1929 + // ----- Return
  1930 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1931 + return $v_result;
  1932 + }
  1933 + // --------------------------------------------------------------------------------
  1934 +
  1935 + // --------------------------------------------------------------------------------
  1936 + // Function : privFileDescrExpand()
  1937 + // Description :
  1938 + // Parameters :
  1939 + // Return Values :
  1940 + // 1 on success.
  1941 + // 0 on failure.
  1942 + // --------------------------------------------------------------------------------
  1943 + function privFileDescrExpand(&$p_filedescr_list, &$p_options)
  1944 + {
  1945 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrExpand", "");
  1946 + $v_result=1;
  1947 +
  1948 + // ----- Create a result list
  1949 + $v_result_list = array();
  1950 +
  1951 + // ----- Look each entry
  1952 + for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
  1953 + // ----- Get filedescr
  1954 + $v_descr = $p_filedescr_list[$i];
  1955 +
  1956 + // ----- Reduce the filename
  1957 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr before reduction :'".$v_descr['filename']."'");
  1958 + $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename']);
  1959 + $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
  1960 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr after reduction :'".$v_descr['filename']."'");
  1961 +
  1962 + // ----- Get type of descr
  1963 + if (!file_exists($v_descr['filename'])) {
  1964 + // ----- Error log
  1965 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_descr['filename']."' does not exists");
  1966 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exists");
  1967 +
  1968 + // ----- Return
  1969 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1970 + return PclZip::errorCode();
  1971 + }
  1972 + if (@is_file($v_descr['filename'])) {
  1973 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a file");
  1974 + $v_descr['type'] = 'file';
  1975 + }
  1976 + else if (@is_dir($v_descr['filename'])) {
  1977 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a folder");
  1978 + $v_descr['type'] = 'folder';
  1979 + }
  1980 + else if (@is_link($v_descr['filename'])) {
  1981 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : link");
  1982 + // skip
  1983 + continue;
  1984 + }
  1985 + else {
  1986 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : unknown type");
  1987 + // skip
  1988 + continue;
  1989 + }
  1990 +
  1991 + // ----- Calculate the stored filename
  1992 + $this->privCalculateStoredFilename($v_descr, $p_options);
  1993 +
  1994 + // ----- Add the descriptor in result list
  1995 + $v_result_list[sizeof($v_result_list)] = $v_descr;
  1996 +
  1997 + // ----- Look for folder
  1998 + if ($v_descr['type'] == 'folder') {
  1999 + // ----- List of items in folder
  2000 + $v_dirlist_descr = array();
  2001 + $v_dirlist_nb = 0;
  2002 + if ($v_folder_handler = @opendir($v_descr['filename'])) {
  2003 + while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
  2004 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for '".$v_item_handler."' in the directory");
  2005 +
  2006 + // ----- Skip '.' and '..'
  2007 + if (($v_item_handler == '.') || ($v_item_handler == '..')) {
  2008 + continue;
  2009 + }
  2010 +
  2011 + // ----- Compose the full filename
  2012 + $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
  2013 +
  2014 + // ----- Look for different stored filename
  2015 + // Because the name of the folder was changed, the name of the
  2016 + // files/sub-folders also change
  2017 + if ($v_descr['stored_filename'] != $v_descr['filename']) {
  2018 + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
  2019 + }
  2020 +
  2021 + $v_dirlist_nb++;
  2022 + }
  2023 + }
  2024 + else {
  2025 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to open dir '".$v_descr['filename']."' in read mode. Skipped.");
  2026 + // TBC : unable to open folder in read mode
  2027 + }
  2028 +
  2029 + // ----- Expand each element of the list
  2030 + if ($v_dirlist_nb != 0) {
  2031 + // ----- Expand
  2032 + if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
  2033 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2034 + return $v_result;
  2035 + }
  2036 +
  2037 + // ----- Concat the resulting list
  2038 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Merging result list (size '".sizeof($v_result_list)."') with dirlist (size '".sizeof($v_dirlist_descr)."')");
  2039 + $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
  2040 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "merged result list is size '".sizeof($v_result_list)."'");
  2041 + }
  2042 + else {
  2043 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Nothing in this folder to expand.");
  2044 + }
  2045 +
  2046 + // ----- Free local array
  2047 + unset($v_dirlist_descr);
  2048 + }
  2049 + }
  2050 +
  2051 + // ----- Get the result list
  2052 + $p_filedescr_list = $v_result_list;
  2053 +
  2054 + // ----- Return
  2055 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2056 + return $v_result;
  2057 + }
  2058 + // --------------------------------------------------------------------------------
  2059 +
  2060 + // --------------------------------------------------------------------------------
  2061 + // Function : privCreate()
  2062 + // Description :
  2063 + // Parameters :
  2064 + // Return Values :
  2065 + // --------------------------------------------------------------------------------
  2066 + function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
  2067 + {
  2068 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCreate", "list");
  2069 + $v_result=1;
  2070 + $v_list_detail = array();
  2071 +
  2072 + // ----- Magic quotes trick
  2073 + $this->privDisableMagicQuotes();
  2074 +
  2075 + // ----- Open the file in write mode
  2076 + if (($v_result = $this->privOpenFd('wb')) != 1)
  2077 + {
  2078 + // ----- Return
  2079 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2080 + return $v_result;
  2081 + }
  2082 +
  2083 + // ----- Add the list of files
  2084 + $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
  2085 +
  2086 + // ----- Close
  2087 + $this->privCloseFd();
  2088 +
  2089 + // ----- Magic quotes trick
  2090 + $this->privSwapBackMagicQuotes();
  2091 +
  2092 + // ----- Return
  2093 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2094 + return $v_result;
  2095 + }
  2096 + // --------------------------------------------------------------------------------
  2097 +
  2098 + // --------------------------------------------------------------------------------
  2099 + // Function : privAdd()
  2100 + // Description :
  2101 + // Parameters :
  2102 + // Return Values :
  2103 + // --------------------------------------------------------------------------------
  2104 + function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
  2105 + {
  2106 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAdd", "list");
  2107 + $v_result=1;
  2108 + $v_list_detail = array();
  2109 +
  2110 + // ----- Look if the archive exists or is empty
  2111 + if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
  2112 + {
  2113 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, or is empty, create it.");
  2114 +
  2115 + // ----- Do a create
  2116 + $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
  2117 +
  2118 + // ----- Return
  2119 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2120 + return $v_result;
  2121 + }
  2122 + // ----- Magic quotes trick
  2123 + $this->privDisableMagicQuotes();
  2124 +
  2125 + // ----- Open the zip file
  2126 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  2127 + if (($v_result=$this->privOpenFd('rb')) != 1)
  2128 + {
  2129 + // ----- Magic quotes trick
  2130 + $this->privSwapBackMagicQuotes();
  2131 +
  2132 + // ----- Return
  2133 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2134 + return $v_result;
  2135 + }
  2136 +
  2137 + // ----- Read the central directory informations
  2138 + $v_central_dir = array();
  2139 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  2140 + {
  2141 + $this->privCloseFd();
  2142 + $this->privSwapBackMagicQuotes();
  2143 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2144 + return $v_result;
  2145 + }
  2146 +
  2147 + // ----- Go to beginning of File
  2148 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
  2149 + @rewind($this->zip_fd);
  2150 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
  2151 +
  2152 + // ----- Creates a temporay file
  2153 + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  2154 +
  2155 + // ----- Open the temporary file in write mode
  2156 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  2157 + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
  2158 + {
  2159 + $this->privCloseFd();
  2160 + $this->privSwapBackMagicQuotes();
  2161 +
  2162 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
  2163 +
  2164 + // ----- Return
  2165 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2166 + return PclZip::errorCode();
  2167 + }
  2168 +
  2169 + // ----- Copy the files from the archive to the temporary file
  2170 + // TBC : Here I should better append the file and go back to erase the central dir
  2171 + $v_size = $v_central_dir['offset'];
  2172 + while ($v_size != 0)
  2173 + {
  2174 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  2175 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  2176 + $v_buffer = fread($this->zip_fd, $v_read_size);
  2177 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  2178 + $v_size -= $v_read_size;
  2179 + }
  2180 +
  2181 + // ----- Swap the file descriptor
  2182 + // Here is a trick : I swap the temporary fd with the zip fd, in order to use
  2183 + // the following methods on the temporary fil and not the real archive
  2184 + $v_swap = $this->zip_fd;
  2185 + $this->zip_fd = $v_zip_temp_fd;
  2186 + $v_zip_temp_fd = $v_swap;
  2187 +
  2188 + // ----- Add the files
  2189 + $v_header_list = array();
  2190 + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
  2191 + {
  2192 + fclose($v_zip_temp_fd);
  2193 + $this->privCloseFd();
  2194 + @unlink($v_zip_temp_name);
  2195 + $this->privSwapBackMagicQuotes();
  2196 +
  2197 + // ----- Return
  2198 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2199 + return $v_result;
  2200 + }
  2201 +
  2202 + // ----- Store the offset of the central dir
  2203 + $v_offset = @ftell($this->zip_fd);
  2204 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
  2205 +
  2206 + // ----- Copy the block of file headers from the old archive
  2207 + $v_size = $v_central_dir['size'];
  2208 + while ($v_size != 0)
  2209 + {
  2210 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  2211 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  2212 + $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
  2213 + @fwrite($this->zip_fd, $v_buffer, $v_read_size);
  2214 + $v_size -= $v_read_size;
  2215 + }
  2216 +
  2217 + // ----- Create the Central Dir files header
  2218 + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
  2219 + {
  2220 + // ----- Create the file header
  2221 + if ($v_header_list[$i]['status'] == 'ok') {
  2222 + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  2223 + fclose($v_zip_temp_fd);
  2224 + $this->privCloseFd();
  2225 + @unlink($v_zip_temp_name);
  2226 + $this->privSwapBackMagicQuotes();
  2227 +
  2228 + // ----- Return
  2229 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2230 + return $v_result;
  2231 + }
  2232 + $v_count++;
  2233 + }
  2234 +
  2235 + // ----- Transform the header to a 'usable' info
  2236 + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  2237 + }
  2238 +
  2239 + // ----- Zip file comment
  2240 + $v_comment = $v_central_dir['comment'];
  2241 + if (isset($p_options[PCLZIP_OPT_COMMENT])) {
  2242 + $v_comment = $p_options[PCLZIP_OPT_COMMENT];
  2243 + }
  2244 + if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
  2245 + $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
  2246 + }
  2247 + if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
  2248 + $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
  2249 + }
  2250 +
  2251 + // ----- Calculate the size of the central header
  2252 + $v_size = @ftell($this->zip_fd)-$v_offset;
  2253 +
  2254 + // ----- Create the central dir footer
  2255 + if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
  2256 + {
  2257 + // ----- Reset the file list
  2258 + unset($v_header_list);
  2259 + $this->privSwapBackMagicQuotes();
  2260 +
  2261 + // ----- Return
  2262 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2263 + return $v_result;
  2264 + }
  2265 +
  2266 + // ----- Swap back the file descriptor
  2267 + $v_swap = $this->zip_fd;
  2268 + $this->zip_fd = $v_zip_temp_fd;
  2269 + $v_zip_temp_fd = $v_swap;
  2270 +
  2271 + // ----- Close
  2272 + $this->privCloseFd();
  2273 +
  2274 + // ----- Close the temporary file
  2275 + @fclose($v_zip_temp_fd);
  2276 +
  2277 + // ----- Magic quotes trick
  2278 + $this->privSwapBackMagicQuotes();
  2279 +
  2280 + // ----- Delete the zip file
  2281 + // TBC : I should test the result ...
  2282 + @unlink($this->zipname);
  2283 +
  2284 + // ----- Rename the temporary file
  2285 + // TBC : I should test the result ...
  2286 + //@rename($v_zip_temp_name, $this->zipname);
  2287 + PclZipUtilRename($v_zip_temp_name, $this->zipname);
  2288 +
  2289 + // ----- Return
  2290 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2291 + return $v_result;
  2292 + }
  2293 + // --------------------------------------------------------------------------------
  2294 +
  2295 + // --------------------------------------------------------------------------------
  2296 + // Function : privOpenFd()
  2297 + // Description :
  2298 + // Parameters :
  2299 + // --------------------------------------------------------------------------------
  2300 + function privOpenFd($p_mode)
  2301 + {
  2302 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privOpenFd", 'mode='.$p_mode);
  2303 + $v_result=1;
  2304 +
  2305 + // ----- Look if already open
  2306 + if ($this->zip_fd != 0)
  2307 + {
  2308 + // ----- Error log
  2309 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
  2310 +
  2311 + // ----- Return
  2312 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2313 + return PclZip::errorCode();
  2314 + }
  2315 +
  2316 + // ----- Open the zip file
  2317 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Open file in '.$p_mode.' mode');
  2318 + if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
  2319 + {
  2320 + // ----- Error log
  2321 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
  2322 +
  2323 + // ----- Return
  2324 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2325 + return PclZip::errorCode();
  2326 + }
  2327 +
  2328 + // ----- Return
  2329 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2330 + return $v_result;
  2331 + }
  2332 + // --------------------------------------------------------------------------------
  2333 +
  2334 + // --------------------------------------------------------------------------------
  2335 + // Function : privCloseFd()
  2336 + // Description :
  2337 + // Parameters :
  2338 + // --------------------------------------------------------------------------------
  2339 + function privCloseFd()
  2340 + {
  2341 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCloseFd", "");
  2342 + $v_result=1;
  2343 +
  2344 + if ($this->zip_fd != 0)
  2345 + @fclose($this->zip_fd);
  2346 + $this->zip_fd = 0;
  2347 +
  2348 + // ----- Return
  2349 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2350 + return $v_result;
  2351 + }
  2352 + // --------------------------------------------------------------------------------
  2353 +
  2354 + // --------------------------------------------------------------------------------
  2355 + // Function : privAddList()
  2356 + // Description :
  2357 + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
  2358 + // different from the real path of the file. This is usefull if you want to have PclTar
  2359 + // running in any directory, and memorize relative path from an other directory.
  2360 + // Parameters :
  2361 + // $p_list : An array containing the file or directory names to add in the tar
  2362 + // $p_result_list : list of added files with their properties (specially the status field)
  2363 + // $p_add_dir : Path to add in the filename path archived
  2364 + // $p_remove_dir : Path to remove in the filename path archived
  2365 + // Return Values :
  2366 + // --------------------------------------------------------------------------------
  2367 +// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
  2368 + function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
  2369 + {
  2370 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddList", "list");
  2371 + $v_result=1;
  2372 +
  2373 + // ----- Add the files
  2374 + $v_header_list = array();
  2375 + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
  2376 + {
  2377 + // ----- Return
  2378 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2379 + return $v_result;
  2380 + }
  2381 +
  2382 + // ----- Store the offset of the central dir
  2383 + $v_offset = @ftell($this->zip_fd);
  2384 +
  2385 + // ----- Create the Central Dir files header
  2386 + for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
  2387 + {
  2388 + // ----- Create the file header
  2389 + if ($v_header_list[$i]['status'] == 'ok') {
  2390 + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  2391 + // ----- Return
  2392 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2393 + return $v_result;
  2394 + }
  2395 + $v_count++;
  2396 + }
  2397 +
  2398 + // ----- Transform the header to a 'usable' info
  2399 + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  2400 + }
  2401 +
  2402 + // ----- Zip file comment
  2403 + $v_comment = '';
  2404 + if (isset($p_options[PCLZIP_OPT_COMMENT])) {
  2405 + $v_comment = $p_options[PCLZIP_OPT_COMMENT];
  2406 + }
  2407 +
  2408 + // ----- Calculate the size of the central header
  2409 + $v_size = @ftell($this->zip_fd)-$v_offset;
  2410 +
  2411 + // ----- Create the central dir footer
  2412 + if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
  2413 + {
  2414 + // ----- Reset the file list
  2415 + unset($v_header_list);
  2416 +
  2417 + // ----- Return
  2418 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2419 + return $v_result;
  2420 + }
  2421 +
  2422 + // ----- Return
  2423 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2424 + return $v_result;
  2425 + }
  2426 + // --------------------------------------------------------------------------------
  2427 +
  2428 + // --------------------------------------------------------------------------------
  2429 + // Function : privAddFileList()
  2430 + // Description :
  2431 + // Parameters :
  2432 + // $p_filedescr_list : An array containing the file description
  2433 + // or directory names to add in the zip
  2434 + // $p_result_list : list of added files with their properties (specially the status field)
  2435 + // Return Values :
  2436 + // --------------------------------------------------------------------------------
  2437 + function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
  2438 + {
  2439 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFileList", "filedescr_list");
  2440 + $v_result=1;
  2441 + $v_header = array();
  2442 +
  2443 + // ----- Recuperate the current number of elt in list
  2444 + $v_nb = sizeof($p_result_list);
  2445 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Before add, list have ".$v_nb." elements");
  2446 +
  2447 + // ----- Loop on the files
  2448 + for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
  2449 + // ----- Format the filename
  2450 + $p_filedescr_list[$j]['filename']
  2451 + = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
  2452 +
  2453 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for file '".$p_filedescr_list[$j]['filename']."'");
  2454 +
  2455 + // ----- Skip empty file names
  2456 + // TBC : Can this be possible ? not checked in DescrParseAtt ?
  2457 + if ($p_filedescr_list[$j]['filename'] == "") {
  2458 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Skip empty filename");
  2459 + continue;
  2460 + }
  2461 +
  2462 + // ----- Check the filename
  2463 + if (!file_exists($p_filedescr_list[$j]['filename'])) {
  2464 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_filedescr_list[$j]['filename']."' does not exists");
  2465 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exists");
  2466 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2467 + return PclZip::errorCode();
  2468 + }
  2469 +
  2470 + // ----- Look if it is a file or a dir with no all path remove option
  2471 + if ( (is_file($p_filedescr_list[$j]['filename']))
  2472 + || ( is_dir($p_filedescr_list[$j]['filename'])
  2473 + && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
  2474 + || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
  2475 +
  2476 + // ----- Add the file
  2477 + $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
  2478 + $p_options);
  2479 + if ($v_result != 1) {
  2480 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2481 + return $v_result;
  2482 + }
  2483 +
  2484 + // ----- Store the file infos
  2485 + $p_result_list[$v_nb++] = $v_header;
  2486 + }
  2487 + }
  2488 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "After add, list have ".$v_nb." elements");
  2489 +
  2490 + // ----- Return
  2491 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2492 + return $v_result;
  2493 + }
  2494 + // --------------------------------------------------------------------------------
  2495 +
  2496 + // --------------------------------------------------------------------------------
  2497 + // Function : privAddFile()
  2498 + // Description :
  2499 + // Parameters :
  2500 + // Return Values :
  2501 + // --------------------------------------------------------------------------------
  2502 + function privAddFile($p_filedescr, &$p_header, &$p_options)
  2503 + {
  2504 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFile", "filename='".$p_filedescr['filename']."'");
  2505 + $v_result=1;
  2506 +
  2507 + // ----- Working variable
  2508 + $p_filename = $p_filedescr['filename'];
  2509 +
  2510 + // TBC : Already done in the fileAtt check ... ?
  2511 + if ($p_filename == "") {
  2512 + // ----- Error log
  2513 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
  2514 +
  2515 + // ----- Return
  2516 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2517 + return PclZip::errorCode();
  2518 + }
  2519 +
  2520 + // ----- Look for a stored different filename
  2521 + if (isset($p_filedescr['stored_filename'])) {
  2522 + $v_stored_filename = $p_filedescr['stored_filename'];
  2523 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is NOT the same "'.$v_stored_filename.'"');
  2524 + }
  2525 + else {
  2526 + $v_stored_filename = $p_filedescr['stored_filename'];
  2527 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is the same');
  2528 + }
  2529 +
  2530 + // ----- Set the file properties
  2531 + clearstatcache();
  2532 + $p_header['version'] = 20;
  2533 + $p_header['version_extracted'] = 10;
  2534 + $p_header['flag'] = 0;
  2535 + $p_header['compression'] = 0;
  2536 + $p_header['mtime'] = filemtime($p_filename);
  2537 + $p_header['crc'] = 0;
  2538 + $p_header['compressed_size'] = 0;
  2539 + $p_header['size'] = filesize($p_filename);
  2540 + $p_header['filename_len'] = strlen($p_filename);
  2541 + $p_header['extra_len'] = 0;
  2542 + $p_header['comment_len'] = 0;
  2543 + $p_header['disk'] = 0;
  2544 + $p_header['internal'] = 0;
  2545 +// $p_header['external'] = (is_file($p_filename)?0xFE49FFE0:0x41FF0010);
  2546 + $p_header['external'] = (is_file($p_filename)?0x00000000:0x00000010);
  2547 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header external extension '".sprintf("0x%X",$p_header['external'])."'");
  2548 + $p_header['offset'] = 0;
  2549 + $p_header['filename'] = $p_filename;
  2550 + $p_header['stored_filename'] = $v_stored_filename;
  2551 + $p_header['extra'] = '';
  2552 + $p_header['comment'] = '';
  2553 + $p_header['status'] = 'ok';
  2554 + $p_header['index'] = -1;
  2555 +
  2556 + // ----- Look for pre-add callback
  2557 + if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
  2558 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_ADD]."()') is defined for the extraction");
  2559 +
  2560 + // ----- Generate a local information
  2561 + $v_local_header = array();
  2562 + $this->privConvertHeader2FileInfo($p_header, $v_local_header);
  2563 +
  2564 + // ----- Call the callback
  2565 + // Here I do not use call_user_func() because I need to send a reference to the
  2566 + // header.
  2567 + eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
  2568 + if ($v_result == 0) {
  2569 + // ----- Change the file status
  2570 + $p_header['status'] = "skipped";
  2571 + $v_result = 1;
  2572 + }
  2573 +
  2574 + // ----- Update the informations
  2575 + // Only some fields can be modified
  2576 + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
  2577 + $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
  2578 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New stored filename is '".$p_header['stored_filename']."'");
  2579 + }
  2580 + }
  2581 +
  2582 + // ----- Look for empty stored filename
  2583 + if ($p_header['stored_filename'] == "") {
  2584 + $p_header['status'] = "filtered";
  2585 + }
  2586 +
  2587 + // ----- Check the path length
  2588 + if (strlen($p_header['stored_filename']) > 0xFF) {
  2589 + $p_header['status'] = 'filename_too_long';
  2590 + }
  2591 +
  2592 + // ----- Look if no error, or file not skipped
  2593 + if ($p_header['status'] == 'ok') {
  2594 +
  2595 + // ----- Look for a file
  2596 + if (is_file($p_filename))
  2597 + {
  2598 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a file");
  2599 + // ----- Open the source file
  2600 + if (($v_file = @fopen($p_filename, "rb")) == 0) {
  2601 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
  2602 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2603 + return PclZip::errorCode();
  2604 + }
  2605 +
  2606 + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
  2607 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be compressed");
  2608 + // ----- Read the file content
  2609 + $v_content_compressed = @fread($v_file, $p_header['size']);
  2610 +
  2611 + // ----- Calculate the CRC
  2612 + $p_header['crc'] = @crc32($v_content_compressed);
  2613 +
  2614 + // ----- Set header parameters
  2615 + $p_header['compressed_size'] = $p_header['size'];
  2616 + $p_header['compression'] = 0;
  2617 + }
  2618 + else {
  2619 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will be compressed");
  2620 + // ----- Read the file content
  2621 + $v_content = @fread($v_file, $p_header['size']);
  2622 +
  2623 + // ----- Calculate the CRC
  2624 + $p_header['crc'] = @crc32($v_content);
  2625 +
  2626 + // ----- Compress the file
  2627 + $v_content_compressed = @gzdeflate($v_content);
  2628 +
  2629 + // ----- Set header parameters
  2630 + $p_header['compressed_size'] = strlen($v_content_compressed);
  2631 + $p_header['compression'] = 8;
  2632 + }
  2633 +
  2634 + // ----- Look for encryption
  2635 + /*
  2636 + if ((isset($p_options[PCLZIP_OPT_CRYPT]))
  2637 + && ($p_options[PCLZIP_OPT_CRYPT] != "")) {
  2638 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File need to be crypted ....");
  2639 +
  2640 + // Should be a random header
  2641 + $v_header = 'xxxxxxxxxxxx';
  2642 + $v_content_compressed = PclZipUtilZipEncrypt($v_content_compressed,
  2643 + $p_header['compressed_size'],
  2644 + $v_header,
  2645 + $p_header['crc'],
  2646 + "test");
  2647 +
  2648 + $p_header['compressed_size'] += 12;
  2649 + $p_header['flag'] = 1;
  2650 +
  2651 + // ----- Add the header to the data
  2652 + $v_content_compressed = $v_header.$v_content_compressed;
  2653 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size after header : ".strlen($v_content_compressed)."");
  2654 + }
  2655 + */
  2656 +
  2657 + // ----- Call the header generation
  2658 + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
  2659 + @fclose($v_file);
  2660 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2661 + return $v_result;
  2662 + }
  2663 +
  2664 + // ----- Write the compressed (or not) content
  2665 + @fwrite($this->zip_fd,
  2666 + $v_content_compressed, $p_header['compressed_size']);
  2667 +
  2668 + // ----- Close the file
  2669 + @fclose($v_file);
  2670 + }
  2671 +
  2672 + // ----- Look for a directory
  2673 + else {
  2674 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a folder");
  2675 + // ----- Look for directory last '/'
  2676 + if (@substr($p_header['stored_filename'], -1) != '/') {
  2677 + $p_header['stored_filename'] .= '/';
  2678 + }
  2679 +
  2680 + // ----- Set the file properties
  2681 + $p_header['size'] = 0;
  2682 + //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
  2683 + $p_header['external'] = 0x00000010; // Value for a folder : to be checked
  2684 +
  2685 + // ----- Call the header generation
  2686 + if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
  2687 + {
  2688 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2689 + return $v_result;
  2690 + }
  2691 + }
  2692 + }
  2693 +
  2694 + // ----- Look for post-add callback
  2695 + if (isset($p_options[PCLZIP_CB_POST_ADD])) {
  2696 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_ADD]."()') is defined for the extraction");
  2697 +
  2698 + // ----- Generate a local information
  2699 + $v_local_header = array();
  2700 + $this->privConvertHeader2FileInfo($p_header, $v_local_header);
  2701 +
  2702 + // ----- Call the callback
  2703 + // Here I do not use call_user_func() because I need to send a reference to the
  2704 + // header.
  2705 + eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
  2706 + if ($v_result == 0) {
  2707 + // ----- Ignored
  2708 + $v_result = 1;
  2709 + }
  2710 +
  2711 + // ----- Update the informations
  2712 + // Nothing can be modified
  2713 + }
  2714 +
  2715 + // ----- Return
  2716 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2717 + return $v_result;
  2718 + }
  2719 + // --------------------------------------------------------------------------------
  2720 +
  2721 + // --------------------------------------------------------------------------------
  2722 + // Function : privCalculateStoredFilename()
  2723 + // Description :
  2724 + // Based on file descriptor properties and global options, this method
  2725 + // calculate the filename that will be stored in the archive.
  2726 + // Parameters :
  2727 + // Return Values :
  2728 + // --------------------------------------------------------------------------------
  2729 + function privCalculateStoredFilename(&$p_filedescr, &$p_options)
  2730 + {
  2731 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCalculateStoredFilename", "filename='".$p_filedescr['filename']."'");
  2732 + $v_result=1;
  2733 +
  2734 + // ----- Working variables
  2735 + $p_filename = $p_filedescr['filename'];
  2736 + if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
  2737 + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
  2738 + }
  2739 + else {
  2740 + $p_add_dir = '';
  2741 + }
  2742 + if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
  2743 + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
  2744 + }
  2745 + else {
  2746 + $p_remove_dir = '';
  2747 + }
  2748 + if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  2749 + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  2750 + }
  2751 + else {
  2752 + $p_remove_all_dir = 0;
  2753 + }
  2754 +
  2755 + // ----- Look for full name change
  2756 + if (isset($p_filedescr['new_full_name'])) {
  2757 + $v_stored_filename = $p_filedescr['new_full_name'];
  2758 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Changing full name of '".$p_filename."' for '".$v_stored_filename."'");
  2759 + }
  2760 +
  2761 + // ----- Look for path and/or short name change
  2762 + else {
  2763 +
  2764 + // ----- Look for short name change
  2765 + if (isset($p_filedescr['new_short_name'])) {
  2766 + $v_path_info = pathinfo($p_filename);
  2767 + $v_dir = '';
  2768 + if ($v_path_info['dirname'] != '') {
  2769 + $v_dir = $v_path_info['dirname'].'/';
  2770 + }
  2771 + $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
  2772 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Changing short name of '".$p_filename."' for '".$v_stored_filename."'");
  2773 + }
  2774 + else {
  2775 + // ----- Calculate the stored filename
  2776 + $v_stored_filename = $p_filename;
  2777 + }
  2778 +
  2779 + // ----- Look for all path to remove
  2780 + if ($p_remove_all_dir) {
  2781 + $v_stored_filename = basename($p_filename);
  2782 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove all path selected change '".$p_filename."' for '".$v_stored_filename."'");
  2783 + }
  2784 + // ----- Look for partial path remove
  2785 + else if ($p_remove_dir != "") {
  2786 + if (substr($p_remove_dir, -1) != '/')
  2787 + $p_remove_dir .= "/";
  2788 +
  2789 + if ( (substr($p_filename, 0, 2) == "./")
  2790 + || (substr($p_remove_dir, 0, 2) == "./")) {
  2791 +
  2792 + if ( (substr($p_filename, 0, 2) == "./")
  2793 + && (substr($p_remove_dir, 0, 2) != "./")) {
  2794 + $p_remove_dir = "./".$p_remove_dir;
  2795 + }
  2796 + if ( (substr($p_filename, 0, 2) != "./")
  2797 + && (substr($p_remove_dir, 0, 2) == "./")) {
  2798 + $p_remove_dir = substr($p_remove_dir, 2);
  2799 + }
  2800 + }
  2801 +
  2802 + $v_compare = PclZipUtilPathInclusion($p_remove_dir,
  2803 + $v_stored_filename);
  2804 + if ($v_compare > 0) {
  2805 + if ($v_compare == 2) {
  2806 + $v_stored_filename = "";
  2807 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Path to remove is the current folder");
  2808 + }
  2809 + else {
  2810 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove path '$p_remove_dir' in file '$v_stored_filename'");
  2811 + $v_stored_filename = substr($v_stored_filename,
  2812 + strlen($p_remove_dir));
  2813 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Result is '$v_stored_filename'");
  2814 + }
  2815 + }
  2816 + }
  2817 + // ----- Look for path to add
  2818 + if ($p_add_dir != "") {
  2819 + if (substr($p_add_dir, -1) == "/")
  2820 + $v_stored_filename = $p_add_dir.$v_stored_filename;
  2821 + else
  2822 + $v_stored_filename = $p_add_dir."/".$v_stored_filename;
  2823 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'");
  2824 + }
  2825 + }
  2826 +
  2827 + // ----- Filename (reduce the path of stored name)
  2828 + $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
  2829 + $p_filedescr['stored_filename'] = $v_stored_filename;
  2830 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Stored filename will be '".$p_filedescr['stored_filename']."', strlen ".strlen($p_filedescr['stored_filename']));
  2831 +
  2832 + // ----- Return
  2833 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2834 + return $v_result;
  2835 + }
  2836 + // --------------------------------------------------------------------------------
  2837 +
  2838 + // --------------------------------------------------------------------------------
  2839 + // Function : privWriteFileHeader()
  2840 + // Description :
  2841 + // Parameters :
  2842 + // Return Values :
  2843 + // --------------------------------------------------------------------------------
  2844 + function privWriteFileHeader(&$p_header)
  2845 + {
  2846 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
  2847 + $v_result=1;
  2848 +
  2849 + // ----- Store the offset position of the file
  2850 + $p_header['offset'] = ftell($this->zip_fd);
  2851 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'File offset of the header :'.$p_header['offset']);
  2852 +
  2853 + // ----- Transform UNIX mtime to DOS format mdate/mtime
  2854 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
  2855 + $v_date = getdate($p_header['mtime']);
  2856 + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
  2857 + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
  2858 +
  2859 + // ----- Packed data
  2860 + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
  2861 + $p_header['version_extracted'], $p_header['flag'],
  2862 + $p_header['compression'], $v_mtime, $v_mdate,
  2863 + $p_header['crc'], $p_header['compressed_size'],
  2864 + $p_header['size'],
  2865 + strlen($p_header['stored_filename']),
  2866 + $p_header['extra_len']);
  2867 +
  2868 + // ----- Write the first 148 bytes of the header in the archive
  2869 + fputs($this->zip_fd, $v_binary_data, 30);
  2870 +
  2871 + // ----- Write the variable fields
  2872 + if (strlen($p_header['stored_filename']) != 0)
  2873 + {
  2874 + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
  2875 + }
  2876 + if ($p_header['extra_len'] != 0)
  2877 + {
  2878 + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
  2879 + }
  2880 +
  2881 + // ----- Return
  2882 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2883 + return $v_result;
  2884 + }
  2885 + // --------------------------------------------------------------------------------
  2886 +
  2887 + // --------------------------------------------------------------------------------
  2888 + // Function : privWriteCentralFileHeader()
  2889 + // Description :
  2890 + // Parameters :
  2891 + // Return Values :
  2892 + // --------------------------------------------------------------------------------
  2893 + function privWriteCentralFileHeader(&$p_header)
  2894 + {
  2895 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
  2896 + $v_result=1;
  2897 +
  2898 + // TBC
  2899 + //for(reset($p_header); $key = key($p_header); next($p_header)) {
  2900 + // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]);
  2901 + //}
  2902 +
  2903 + // ----- Transform UNIX mtime to DOS format mdate/mtime
  2904 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
  2905 + $v_date = getdate($p_header['mtime']);
  2906 + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
  2907 + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
  2908 +
  2909 + // ----- Packed data
  2910 + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
  2911 + $p_header['version'], $p_header['version_extracted'],
  2912 + $p_header['flag'], $p_header['compression'],
  2913 + $v_mtime, $v_mdate, $p_header['crc'],
  2914 + $p_header['compressed_size'], $p_header['size'],
  2915 + strlen($p_header['stored_filename']),
  2916 + $p_header['extra_len'], $p_header['comment_len'],
  2917 + $p_header['disk'], $p_header['internal'],
  2918 + $p_header['external'], $p_header['offset']);
  2919 +
  2920 + // ----- Write the 42 bytes of the header in the zip file
  2921 + fputs($this->zip_fd, $v_binary_data, 46);
  2922 +
  2923 + // ----- Write the variable fields
  2924 + if (strlen($p_header['stored_filename']) != 0)
  2925 + {
  2926 + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
  2927 + }
  2928 + if ($p_header['extra_len'] != 0)
  2929 + {
  2930 + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
  2931 + }
  2932 + if ($p_header['comment_len'] != 0)
  2933 + {
  2934 + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
  2935 + }
  2936 +
  2937 + // ----- Return
  2938 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2939 + return $v_result;
  2940 + }
  2941 + // --------------------------------------------------------------------------------
  2942 +
  2943 + // --------------------------------------------------------------------------------
  2944 + // Function : privWriteCentralHeader()
  2945 + // Description :
  2946 + // Parameters :
  2947 + // Return Values :
  2948 + // --------------------------------------------------------------------------------
  2949 + function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
  2950 + {
  2951 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralHeader", 'nb_entries='.$p_nb_entries.', size='.$p_size.', offset='.$p_offset.', comment="'.$p_comment.'"');
  2952 + $v_result=1;
  2953 +
  2954 + // ----- Packed data
  2955 + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
  2956 + $p_nb_entries, $p_size,
  2957 + $p_offset, strlen($p_comment));
  2958 +
  2959 + // ----- Write the 22 bytes of the header in the zip file
  2960 + fputs($this->zip_fd, $v_binary_data, 22);
  2961 +
  2962 + // ----- Write the variable fields
  2963 + if (strlen($p_comment) != 0)
  2964 + {
  2965 + fputs($this->zip_fd, $p_comment, strlen($p_comment));
  2966 + }
  2967 +
  2968 + // ----- Return
  2969 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2970 + return $v_result;
  2971 + }
  2972 + // --------------------------------------------------------------------------------
  2973 +
  2974 + // --------------------------------------------------------------------------------
  2975 + // Function : privList()
  2976 + // Description :
  2977 + // Parameters :
  2978 + // Return Values :
  2979 + // --------------------------------------------------------------------------------
  2980 + function privList(&$p_list)
  2981 + {
  2982 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privList", "list");
  2983 + $v_result=1;
  2984 +
  2985 + // ----- Magic quotes trick
  2986 + $this->privDisableMagicQuotes();
  2987 +
  2988 + // ----- Open the zip file
  2989 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  2990 + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
  2991 + {
  2992 + // ----- Magic quotes trick
  2993 + $this->privSwapBackMagicQuotes();
  2994 +
  2995 + // ----- Error log
  2996 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
  2997 +
  2998 + // ----- Return
  2999 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3000 + return PclZip::errorCode();
  3001 + }
  3002 +
  3003 + // ----- Read the central directory informations
  3004 + $v_central_dir = array();
  3005 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  3006 + {
  3007 + $this->privSwapBackMagicQuotes();
  3008 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3009 + return $v_result;
  3010 + }
  3011 +
  3012 + // ----- Go to beginning of Central Dir
  3013 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Offset : ".$v_central_dir['offset']."'");
  3014 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
  3015 + @rewind($this->zip_fd);
  3016 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
  3017 + if (@fseek($this->zip_fd, $v_central_dir['offset']))
  3018 + {
  3019 + $this->privSwapBackMagicQuotes();
  3020 +
  3021 + // ----- Error log
  3022 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  3023 +
  3024 + // ----- Return
  3025 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3026 + return PclZip::errorCode();
  3027 + }
  3028 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
  3029 +
  3030 + // ----- Read each entry
  3031 + for ($i=0; $i<$v_central_dir['entries']; $i++)
  3032 + {
  3033 + // ----- Read the file header
  3034 + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
  3035 + {
  3036 + $this->privSwapBackMagicQuotes();
  3037 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3038 + return $v_result;
  3039 + }
  3040 + $v_header['index'] = $i;
  3041 +
  3042 + // ----- Get the only interesting attributes
  3043 + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
  3044 + unset($v_header);
  3045 + }
  3046 +
  3047 + // ----- Close the zip file
  3048 + $this->privCloseFd();
  3049 +
  3050 + // ----- Magic quotes trick
  3051 + $this->privSwapBackMagicQuotes();
  3052 +
  3053 + // ----- Return
  3054 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3055 + return $v_result;
  3056 + }
  3057 + // --------------------------------------------------------------------------------
  3058 +
  3059 + // --------------------------------------------------------------------------------
  3060 + // Function : privConvertHeader2FileInfo()
  3061 + // Description :
  3062 + // This function takes the file informations from the central directory
  3063 + // entries and extract the interesting parameters that will be given back.
  3064 + // The resulting file infos are set in the array $p_info
  3065 + // $p_info['filename'] : Filename with full path. Given by user (add),
  3066 + // extracted in the filesystem (extract).
  3067 + // $p_info['stored_filename'] : Stored filename in the archive.
  3068 + // $p_info['size'] = Size of the file.
  3069 + // $p_info['compressed_size'] = Compressed size of the file.
  3070 + // $p_info['mtime'] = Last modification date of the file.
  3071 + // $p_info['comment'] = Comment associated with the file.
  3072 + // $p_info['folder'] = true/false : indicates if the entry is a folder or not.
  3073 + // $p_info['status'] = status of the action on the file.
  3074 + // Parameters :
  3075 + // Return Values :
  3076 + // --------------------------------------------------------------------------------
  3077 + function privConvertHeader2FileInfo($p_header, &$p_info)
  3078 + {
  3079 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privConvertHeader2FileInfo", "Filename='".$p_header['filename']."'");
  3080 + $v_result=1;
  3081 +
  3082 + // ----- Get the interesting attributes
  3083 + $p_info['filename'] = $p_header['filename'];
  3084 + $p_info['stored_filename'] = $p_header['stored_filename'];
  3085 + $p_info['size'] = $p_header['size'];
  3086 + $p_info['compressed_size'] = $p_header['compressed_size'];
  3087 + $p_info['mtime'] = $p_header['mtime'];
  3088 + $p_info['comment'] = $p_header['comment'];
  3089 + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
  3090 + $p_info['index'] = $p_header['index'];
  3091 + $p_info['status'] = $p_header['status'];
  3092 +
  3093 + // ----- Return
  3094 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3095 + return $v_result;
  3096 + }
  3097 + // --------------------------------------------------------------------------------
  3098 +
  3099 + // --------------------------------------------------------------------------------
  3100 + // Function : privExtractByRule()
  3101 + // Description :
  3102 + // Extract a file or directory depending of rules (by index, by name, ...)
  3103 + // Parameters :
  3104 + // $p_file_list : An array where will be placed the properties of each
  3105 + // extracted file
  3106 + // $p_path : Path to add while writing the extracted files
  3107 + // $p_remove_path : Path to remove (from the file memorized path) while writing the
  3108 + // extracted files. If the path does not match the file path,
  3109 + // the file is extracted with its memorized path.
  3110 + // $p_remove_path does not apply to 'list' mode.
  3111 + // $p_path and $p_remove_path are commulative.
  3112 + // Return Values :
  3113 + // 1 on success,0 or less on error (see error code list)
  3114 + // --------------------------------------------------------------------------------
  3115 + function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
  3116 + {
  3117 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByRule", "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
  3118 + $v_result=1;
  3119 +
  3120 + // ----- Magic quotes trick
  3121 + $this->privDisableMagicQuotes();
  3122 +
  3123 + // ----- Check the path
  3124 + if ( ($p_path == "")
  3125 + || ( (substr($p_path, 0, 1) != "/")
  3126 + && (substr($p_path, 0, 3) != "../")
  3127 + && (substr($p_path,1,2)!=":/")))
  3128 + $p_path = "./".$p_path;
  3129 +
  3130 + // ----- Reduce the path last (and duplicated) '/'
  3131 + if (($p_path != "./") && ($p_path != "/"))
  3132 + {
  3133 + // ----- Look for the path end '/'
  3134 + while (substr($p_path, -1) == "/")
  3135 + {
  3136 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'");
  3137 + $p_path = substr($p_path, 0, strlen($p_path)-1);
  3138 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]");
  3139 + }
  3140 + }
  3141 +
  3142 + // ----- Look for path to remove format (should end by /)
  3143 + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
  3144 + {
  3145 + $p_remove_path .= '/';
  3146 + }
  3147 + $p_remove_path_size = strlen($p_remove_path);
  3148 +
  3149 + // ----- Open the zip file
  3150 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  3151 + if (($v_result = $this->privOpenFd('rb')) != 1)
  3152 + {
  3153 + $this->privSwapBackMagicQuotes();
  3154 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3155 + return $v_result;
  3156 + }
  3157 +
  3158 + // ----- Read the central directory informations
  3159 + $v_central_dir = array();
  3160 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  3161 + {
  3162 + // ----- Close the zip file
  3163 + $this->privCloseFd();
  3164 + $this->privSwapBackMagicQuotes();
  3165 +
  3166 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3167 + return $v_result;
  3168 + }
  3169 +
  3170 + // ----- Start at beginning of Central Dir
  3171 + $v_pos_entry = $v_central_dir['offset'];
  3172 +
  3173 + // ----- Read each entry
  3174 + $j_start = 0;
  3175 + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
  3176 + {
  3177 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : '$i'");
  3178 +
  3179 + // ----- Read next Central dir entry
  3180 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position before rewind : ".ftell($this->zip_fd)."'");
  3181 + @rewind($this->zip_fd);
  3182 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position after rewind : ".ftell($this->zip_fd)."'");
  3183 + if (@fseek($this->zip_fd, $v_pos_entry))
  3184 + {
  3185 + // ----- Close the zip file
  3186 + $this->privCloseFd();
  3187 + $this->privSwapBackMagicQuotes();
  3188 +
  3189 + // ----- Error log
  3190 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  3191 +
  3192 + // ----- Return
  3193 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3194 + return PclZip::errorCode();
  3195 + }
  3196 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");
  3197 +
  3198 + // ----- Read the file header
  3199 + $v_header = array();
  3200 + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
  3201 + {
  3202 + // ----- Close the zip file
  3203 + $this->privCloseFd();
  3204 + $this->privSwapBackMagicQuotes();
  3205 +
  3206 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3207 + return $v_result;
  3208 + }
  3209 +
  3210 + // ----- Store the index
  3211 + $v_header['index'] = $i;
  3212 +
  3213 + // ----- Store the file position
  3214 + $v_pos_entry = ftell($this->zip_fd);
  3215 +
  3216 + // ----- Look for the specific extract rules
  3217 + $v_extract = false;
  3218 +
  3219 + // ----- Look for extract by name rule
  3220 + if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
  3221 + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
  3222 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
  3223 +
  3224 + // ----- Look if the filename is in the list
  3225 + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
  3226 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
  3227 +
  3228 + // ----- Look for a directory
  3229 + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
  3230 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
  3231 +
  3232 + // ----- Look if the directory is in the filename path
  3233 + if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
  3234 + && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  3235 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
  3236 + $v_extract = true;
  3237 + }
  3238 + }
  3239 + // ----- Look for a filename
  3240 + elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
  3241 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
  3242 + $v_extract = true;
  3243 + }
  3244 + }
  3245 + }
  3246 +
  3247 + // ----- Look for extract by ereg rule
  3248 + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
  3249 + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
  3250 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
  3251 +
  3252 + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
  3253 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
  3254 + $v_extract = true;
  3255 + }
  3256 + }
  3257 +
  3258 + // ----- Look for extract by preg rule
  3259 + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
  3260 + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
  3261 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
  3262 +
  3263 + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
  3264 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
  3265 + $v_extract = true;
  3266 + }
  3267 + }
  3268 +
  3269 + // ----- Look for extract by index rule
  3270 + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
  3271 + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
  3272 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
  3273 +
  3274 + // ----- Look if the index is in the list
  3275 + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
  3276 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]");
  3277 +
  3278 + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
  3279 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
  3280 + $v_extract = true;
  3281 + }
  3282 + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
  3283 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
  3284 + $j_start = $j+1;
  3285 + }
  3286 +
  3287 + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
  3288 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
  3289 + break;
  3290 + }
  3291 + }
  3292 + }
  3293 +
  3294 + // ----- Look for no rule, which means extract all the archive
  3295 + else {
  3296 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with no rule (extract all)");
  3297 + $v_extract = true;
  3298 + }
  3299 +
  3300 + // ----- Check compression method
  3301 + if ( ($v_extract)
  3302 + && ( ($v_header['compression'] != 8)
  3303 + && ($v_header['compression'] != 0))) {
  3304 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported compression method (".$v_header['compression'].")");
  3305 + $v_header['status'] = 'unsupported_compression';
  3306 +
  3307 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3308 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3309 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3310 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
  3311 +
  3312 + $this->privSwapBackMagicQuotes();
  3313 +
  3314 + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
  3315 + "Filename '".$v_header['stored_filename']."' is "
  3316 + ."compressed by an unsupported compression "
  3317 + ."method (".$v_header['compression'].") ");
  3318 +
  3319 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3320 + return PclZip::errorCode();
  3321 + }
  3322 + }
  3323 +
  3324 + // ----- Check encrypted files
  3325 + if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
  3326 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported file encryption");
  3327 + $v_header['status'] = 'unsupported_encryption';
  3328 +
  3329 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3330 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3331 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3332 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
  3333 +
  3334 + $this->privSwapBackMagicQuotes();
  3335 +
  3336 + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
  3337 + "Unsupported encryption for "
  3338 + ." filename '".$v_header['stored_filename']
  3339 + ."'");
  3340 +
  3341 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3342 + return PclZip::errorCode();
  3343 + }
  3344 + }
  3345 +
  3346 + // ----- Look for real extraction
  3347 + if (($v_extract) && ($v_header['status'] != 'ok')) {
  3348 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "No need for extract");
  3349 + $v_result = $this->privConvertHeader2FileInfo($v_header,
  3350 + $p_file_list[$v_nb_extracted++]);
  3351 + if ($v_result != 1) {
  3352 + $this->privCloseFd();
  3353 + $this->privSwapBackMagicQuotes();
  3354 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3355 + return $v_result;
  3356 + }
  3357 +
  3358 + $v_extract = false;
  3359 + }
  3360 +
  3361 + // ----- Look for real extraction
  3362 + if ($v_extract)
  3363 + {
  3364 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file '".$v_header['filename']."', index '$i'");
  3365 +
  3366 + // ----- Go to the file position
  3367 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
  3368 + @rewind($this->zip_fd);
  3369 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
  3370 + if (@fseek($this->zip_fd, $v_header['offset']))
  3371 + {
  3372 + // ----- Close the zip file
  3373 + $this->privCloseFd();
  3374 +
  3375 + $this->privSwapBackMagicQuotes();
  3376 +
  3377 + // ----- Error log
  3378 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  3379 +
  3380 + // ----- Return
  3381 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3382 + return PclZip::errorCode();
  3383 + }
  3384 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
  3385 +
  3386 + // ----- Look for extraction as string
  3387 + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
  3388 +
  3389 + // ----- Extracting the file
  3390 + $v_result1 = $this->privExtractFileAsString($v_header, $v_string);
  3391 + if ($v_result1 < 1) {
  3392 + $this->privCloseFd();
  3393 + $this->privSwapBackMagicQuotes();
  3394 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
  3395 + return $v_result1;
  3396 + }
  3397 +
  3398 + // ----- Get the only interesting attributes
  3399 + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
  3400 + {
  3401 + // ----- Close the zip file
  3402 + $this->privCloseFd();
  3403 + $this->privSwapBackMagicQuotes();
  3404 +
  3405 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3406 + return $v_result;
  3407 + }
  3408 +
  3409 + // ----- Set the file content
  3410 + $p_file_list[$v_nb_extracted]['content'] = $v_string;
  3411 +
  3412 + // ----- Next extracted file
  3413 + $v_nb_extracted++;
  3414 +
  3415 + // ----- Look for user callback abort
  3416 + if ($v_result1 == 2) {
  3417 + break;
  3418 + }
  3419 + }
  3420 + // ----- Look for extraction in standard output
  3421 + elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
  3422 + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
  3423 + // ----- Extracting the file in standard output
  3424 + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
  3425 + if ($v_result1 < 1) {
  3426 + $this->privCloseFd();
  3427 + $this->privSwapBackMagicQuotes();
  3428 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
  3429 + return $v_result1;
  3430 + }
  3431 +
  3432 + // ----- Get the only interesting attributes
  3433 + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
  3434 + $this->privCloseFd();
  3435 + $this->privSwapBackMagicQuotes();
  3436 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3437 + return $v_result;
  3438 + }
  3439 +
  3440 + // ----- Look for user callback abort
  3441 + if ($v_result1 == 2) {
  3442 + break;
  3443 + }
  3444 + }
  3445 + // ----- Look for normal extraction
  3446 + else {
  3447 + // ----- Extracting the file
  3448 + $v_result1 = $this->privExtractFile($v_header,
  3449 + $p_path, $p_remove_path,
  3450 + $p_remove_all_path,
  3451 + $p_options);
  3452 + if ($v_result1 < 1) {
  3453 + $this->privCloseFd();
  3454 + $this->privSwapBackMagicQuotes();
  3455 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
  3456 + return $v_result1;
  3457 + }
  3458 +
  3459 + // ----- Get the only interesting attributes
  3460 + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
  3461 + {
  3462 + // ----- Close the zip file
  3463 + $this->privCloseFd();
  3464 + $this->privSwapBackMagicQuotes();
  3465 +
  3466 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3467 + return $v_result;
  3468 + }
  3469 +
  3470 + // ----- Look for user callback abort
  3471 + if ($v_result1 == 2) {
  3472 + break;
  3473 + }
  3474 + }
  3475 + }
  3476 + }
  3477 +
  3478 + // ----- Close the zip file
  3479 + $this->privCloseFd();
  3480 + $this->privSwapBackMagicQuotes();
  3481 +
  3482 + // ----- Return
  3483 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3484 + return $v_result;
  3485 + }
  3486 + // --------------------------------------------------------------------------------
  3487 +
  3488 + // --------------------------------------------------------------------------------
  3489 + // Function : privExtractFile()
  3490 + // Description :
  3491 + // Parameters :
  3492 + // Return Values :
  3493 + //
  3494 + // 1 : ... ?
  3495 + // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
  3496 + // --------------------------------------------------------------------------------
  3497 + function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
  3498 + {
  3499 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFile', "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
  3500 + $v_result=1;
  3501 +
  3502 + // ----- Read the file header
  3503 + if (($v_result = $this->privReadFileHeader($v_header)) != 1)
  3504 + {
  3505 + // ----- Return
  3506 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3507 + return $v_result;
  3508 + }
  3509 +
  3510 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
  3511 +
  3512 + // ----- Check that the file header is coherent with $p_entry info
  3513 + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
  3514 + // TBC
  3515 + }
  3516 +
  3517 + // ----- Look for all path to remove
  3518 + if ($p_remove_all_path == true) {
  3519 + // ----- Look for folder entry that not need to be extracted
  3520 + if (($p_entry['external']&0x00000010)==0x00000010) {
  3521 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The entry is a folder : need to be filtered");
  3522 +
  3523 + $p_entry['status'] = "filtered";
  3524 +
  3525 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3526 + return $v_result;
  3527 + }
  3528 +
  3529 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "All path is removed");
  3530 + // ----- Get the basename of the path
  3531 + $p_entry['filename'] = basename($p_entry['filename']);
  3532 + }
  3533 +
  3534 + // ----- Look for path to remove
  3535 + else if ($p_remove_path != "")
  3536 + {
  3537 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look for some path to remove");
  3538 + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
  3539 + {
  3540 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The folder is the same as the removed path '".$p_entry['filename']."'");
  3541 +
  3542 + // ----- Change the file status
  3543 + $p_entry['status'] = "filtered";
  3544 +
  3545 + // ----- Return
  3546 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3547 + return $v_result;
  3548 + }
  3549 +
  3550 + $p_remove_path_size = strlen($p_remove_path);
  3551 + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
  3552 + {
  3553 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '".$p_entry['filename']."'");
  3554 +
  3555 + // ----- Remove the path
  3556 + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
  3557 +
  3558 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Resulting file is '".$p_entry['filename']."'");
  3559 + }
  3560 + }
  3561 +
  3562 + // ----- Add the path
  3563 + if ($p_path != '') {
  3564 + $p_entry['filename'] = $p_path."/".$p_entry['filename'];
  3565 + }
  3566 +
  3567 + // ----- Check a base_dir_restriction
  3568 + if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
  3569 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Check the extract directory restriction");
  3570 + $v_inclusion
  3571 + = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
  3572 + $p_entry['filename']);
  3573 + if ($v_inclusion == 0) {
  3574 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_EXTRACT_DIR_RESTRICTION is selected, file is outside restriction");
  3575 +
  3576 + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
  3577 + "Filename '".$p_entry['filename']."' is "
  3578 + ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
  3579 +
  3580 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3581 + return PclZip::errorCode();
  3582 + }
  3583 + }
  3584 +
  3585 + // ----- Look for pre-extract callback
  3586 + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
  3587 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction");
  3588 +
  3589 + // ----- Generate a local information
  3590 + $v_local_header = array();
  3591 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  3592 +
  3593 + // ----- Call the callback
  3594 + // Here I do not use call_user_func() because I need to send a reference to the
  3595 + // header.
  3596 + eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
  3597 + if ($v_result == 0) {
  3598 + // ----- Change the file status
  3599 + $p_entry['status'] = "skipped";
  3600 + $v_result = 1;
  3601 + }
  3602 +
  3603 + // ----- Look for abort result
  3604 + if ($v_result == 2) {
  3605 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
  3606 + // ----- This status is internal and will be changed in 'skipped'
  3607 + $p_entry['status'] = "aborted";
  3608 + $v_result = PCLZIP_ERR_USER_ABORTED;
  3609 + }
  3610 +
  3611 + // ----- Update the informations
  3612 + // Only some fields can be modified
  3613 + $p_entry['filename'] = $v_local_header['filename'];
  3614 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'");
  3615 + }
  3616 +
  3617 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'");
  3618 +
  3619 + // ----- Look if extraction should be done
  3620 + if ($p_entry['status'] == 'ok') {
  3621 +
  3622 + // ----- Look for specific actions while the file exist
  3623 + if (file_exists($p_entry['filename']))
  3624 + {
  3625 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_entry['filename']."' already exists");
  3626 +
  3627 + // ----- Look if file is a directory
  3628 + if (is_dir($p_entry['filename']))
  3629 + {
  3630 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is a directory");
  3631 +
  3632 + // ----- Change the file status
  3633 + $p_entry['status'] = "already_a_directory";
  3634 +
  3635 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3636 + // For historical reason first PclZip implementation does not stop
  3637 + // when this kind of error occurs.
  3638 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3639 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3640 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
  3641 +
  3642 + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
  3643 + "Filename '".$p_entry['filename']."' is "
  3644 + ."already used by an existing directory");
  3645 +
  3646 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3647 + return PclZip::errorCode();
  3648 + }
  3649 + }
  3650 + // ----- Look if file is write protected
  3651 + else if (!is_writeable($p_entry['filename']))
  3652 + {
  3653 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is write protected");
  3654 +
  3655 + // ----- Change the file status
  3656 + $p_entry['status'] = "write_protected";
  3657 +
  3658 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3659 + // For historical reason first PclZip implementation does not stop
  3660 + // when this kind of error occurs.
  3661 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3662 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3663 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
  3664 +
  3665 + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
  3666 + "Filename '".$p_entry['filename']."' exists "
  3667 + ."and is write protected");
  3668 +
  3669 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3670 + return PclZip::errorCode();
  3671 + }
  3672 + }
  3673 +
  3674 + // ----- Look if the extracted file is older
  3675 + else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
  3676 + {
  3677 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is newer (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")");
  3678 + // ----- Change the file status
  3679 + if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
  3680 + && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
  3681 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_REPLACE_NEWER is selected, file will be replaced");
  3682 + }
  3683 + else {
  3684 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be replaced");
  3685 + $p_entry['status'] = "newer_exist";
  3686 +
  3687 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3688 + // For historical reason first PclZip implementation does not stop
  3689 + // when this kind of error occurs.
  3690 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3691 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3692 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
  3693 +
  3694 + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
  3695 + "Newer version of '".$p_entry['filename']."' exists "
  3696 + ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
  3697 +
  3698 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3699 + return PclZip::errorCode();
  3700 + }
  3701 + }
  3702 + }
  3703 + else {
  3704 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is older than the extrated one - will be replaced by the extracted one (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")");
  3705 + }
  3706 + }
  3707 +
  3708 + // ----- Check the directory availability and create it if necessary
  3709 + else {
  3710 + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
  3711 + $v_dir_to_check = $p_entry['filename'];
  3712 + else if (!strstr($p_entry['filename'], "/"))
  3713 + $v_dir_to_check = "";
  3714 + else
  3715 + $v_dir_to_check = dirname($p_entry['filename']);
  3716 +
  3717 + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
  3718 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '".$p_entry['filename']."'");
  3719 +
  3720 + // ----- Change the file status
  3721 + $p_entry['status'] = "path_creation_fail";
  3722 +
  3723 + // ----- Return
  3724 + ////--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3725 + //return $v_result;
  3726 + $v_result = 1;
  3727 + }
  3728 + }
  3729 + }
  3730 +
  3731 + // ----- Look if extraction should be done
  3732 + if ($p_entry['status'] == 'ok') {
  3733 +
  3734 + // ----- Do the extraction (if not a folder)
  3735 + if (!(($p_entry['external']&0x00000010)==0x00000010))
  3736 + {
  3737 + // ----- Look for not compressed file
  3738 + if ($p_entry['compression'] == 0) {
  3739 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
  3740 +
  3741 + // ----- Opening destination file
  3742 + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
  3743 + {
  3744 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode");
  3745 +
  3746 + // ----- Change the file status
  3747 + $p_entry['status'] = "write_error";
  3748 +
  3749 + // ----- Return
  3750 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3751 + return $v_result;
  3752 + }
  3753 +
  3754 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read '".$p_entry['size']."' bytes");
  3755 +
  3756 + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  3757 + $v_size = $p_entry['compressed_size'];
  3758 + while ($v_size != 0)
  3759 + {
  3760 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  3761 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read $v_read_size bytes");
  3762 + $v_buffer = @fread($this->zip_fd, $v_read_size);
  3763 + /* Try to speed up the code
  3764 + $v_binary_data = pack('a'.$v_read_size, $v_buffer);
  3765 + @fwrite($v_dest_file, $v_binary_data, $v_read_size);
  3766 + */
  3767 + @fwrite($v_dest_file, $v_buffer, $v_read_size);
  3768 + $v_size -= $v_read_size;
  3769 + }
  3770 +
  3771 + // ----- Closing the destination file
  3772 + fclose($v_dest_file);
  3773 +
  3774 + // ----- Change the file mtime
  3775 + touch($p_entry['filename'], $p_entry['mtime']);
  3776 +
  3777 +
  3778 + }
  3779 + else {
  3780 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (Compression method ".$p_entry['compression'].")");
  3781 + // ----- TBC
  3782 + // Need to be finished
  3783 + if (($p_entry['flag'] & 1) == 1) {
  3784 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File is encrypted");
  3785 + /*
  3786 + // ----- Read the encryption header
  3787 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read 12 encryption header bytes");
  3788 + $v_encryption_header = @fread($this->zip_fd, 12);
  3789 +
  3790 + // ----- Read the encrypted & compressed file in a buffer
  3791 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".($p_entry['compressed_size']-12)."' compressed & encrypted bytes");
  3792 + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']-12);
  3793 +
  3794 + // ----- Decrypt the buffer
  3795 + $this->privDecrypt($v_encryption_header, $v_buffer,
  3796 + $p_entry['compressed_size']-12, $p_entry['crc']);
  3797 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Buffer is '".$v_buffer."'");
  3798 + */
  3799 + }
  3800 + else {
  3801 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".$p_entry['compressed_size']."' compressed bytes");
  3802 + // ----- Read the compressed file in a buffer (one shot)
  3803 + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  3804 + }
  3805 +
  3806 + // ----- Decompress the file
  3807 + $v_file_content = @gzinflate($v_buffer);
  3808 + unset($v_buffer);
  3809 + if ($v_file_content === FALSE) {
  3810 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to inflate compressed file");
  3811 +
  3812 + // ----- Change the file status
  3813 + // TBC
  3814 + $p_entry['status'] = "error";
  3815 +
  3816 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3817 + return $v_result;
  3818 + }
  3819 +
  3820 + // ----- Opening destination file
  3821 + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
  3822 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode");
  3823 +
  3824 + // ----- Change the file status
  3825 + $p_entry['status'] = "write_error";
  3826 +
  3827 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3828 + return $v_result;
  3829 + }
  3830 +
  3831 + // ----- Write the uncompressed data
  3832 + @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
  3833 + unset($v_file_content);
  3834 +
  3835 + // ----- Closing the destination file
  3836 + @fclose($v_dest_file);
  3837 +
  3838 + // ----- Change the file mtime
  3839 + @touch($p_entry['filename'], $p_entry['mtime']);
  3840 + }
  3841 +
  3842 + // ----- Look for chmod option
  3843 + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
  3844 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "chmod option activated '".$p_options[PCLZIP_OPT_SET_CHMOD]."'");
  3845 +
  3846 + // ----- Change the mode of the file
  3847 + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
  3848 + }
  3849 +
  3850 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
  3851 + }
  3852 + }
  3853 +
  3854 + // ----- Change abort status
  3855 + if ($p_entry['status'] == "aborted") {
  3856 + $p_entry['status'] = "skipped";
  3857 + }
  3858 +
  3859 + // ----- Look for post-extract callback
  3860 + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
  3861 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction");
  3862 +
  3863 + // ----- Generate a local information
  3864 + $v_local_header = array();
  3865 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  3866 +
  3867 + // ----- Call the callback
  3868 + // Here I do not use call_user_func() because I need to send a reference to the
  3869 + // header.
  3870 + eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
  3871 +
  3872 + // ----- Look for abort result
  3873 + if ($v_result == 2) {
  3874 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
  3875 + $v_result = PCLZIP_ERR_USER_ABORTED;
  3876 + }
  3877 + }
  3878 +
  3879 + // ----- Return
  3880 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3881 + return $v_result;
  3882 + }
  3883 + // --------------------------------------------------------------------------------
  3884 +
  3885 + // --------------------------------------------------------------------------------
  3886 + // Function : privExtractFileInOutput()
  3887 + // Description :
  3888 + // Parameters :
  3889 + // Return Values :
  3890 + // --------------------------------------------------------------------------------
  3891 + function privExtractFileInOutput(&$p_entry, &$p_options)
  3892 + {
  3893 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileInOutput', "");
  3894 + $v_result=1;
  3895 +
  3896 + // ----- Read the file header
  3897 + if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
  3898 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3899 + return $v_result;
  3900 + }
  3901 +
  3902 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
  3903 +
  3904 + // ----- Check that the file header is coherent with $p_entry info
  3905 + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
  3906 + // TBC
  3907 + }
  3908 +
  3909 + // ----- Look for pre-extract callback
  3910 + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
  3911 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction");
  3912 +
  3913 + // ----- Generate a local information
  3914 + $v_local_header = array();
  3915 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  3916 +
  3917 + // ----- Call the callback
  3918 + // Here I do not use call_user_func() because I need to send a reference to the
  3919 + // header.
  3920 + eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
  3921 + if ($v_result == 0) {
  3922 + // ----- Change the file status
  3923 + $p_entry['status'] = "skipped";
  3924 + $v_result = 1;
  3925 + }
  3926 +
  3927 + // ----- Look for abort result
  3928 + if ($v_result == 2) {
  3929 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
  3930 + // ----- This status is internal and will be changed in 'skipped'
  3931 + $p_entry['status'] = "aborted";
  3932 + $v_result = PCLZIP_ERR_USER_ABORTED;
  3933 + }
  3934 +
  3935 + // ----- Update the informations
  3936 + // Only some fields can be modified
  3937 + $p_entry['filename'] = $v_local_header['filename'];
  3938 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'");
  3939 + }
  3940 +
  3941 + // ----- Trace
  3942 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'");
  3943 +
  3944 + // ----- Look if extraction should be done
  3945 + if ($p_entry['status'] == 'ok') {
  3946 +
  3947 + // ----- Do the extraction (if not a folder)
  3948 + if (!(($p_entry['external']&0x00000010)==0x00000010)) {
  3949 + // ----- Look for not compressed file
  3950 + if ($p_entry['compressed_size'] == $p_entry['size']) {
  3951 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
  3952 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes");
  3953 +
  3954 + // ----- Read the file in a buffer (one shot)
  3955 + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  3956 +
  3957 + // ----- Send the file to the output
  3958 + echo $v_buffer;
  3959 + unset($v_buffer);
  3960 + }
  3961 + else {
  3962 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file");
  3963 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Reading '".$p_entry['size']."' bytes");
  3964 +
  3965 + // ----- Read the compressed file in a buffer (one shot)
  3966 + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  3967 +
  3968 + // ----- Decompress the file
  3969 + $v_file_content = gzinflate($v_buffer);
  3970 + unset($v_buffer);
  3971 +
  3972 + // ----- Send the file to the output
  3973 + echo $v_file_content;
  3974 + unset($v_file_content);
  3975 + }
  3976 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
  3977 + }
  3978 + }
  3979 +
  3980 + // ----- Change abort status
  3981 + if ($p_entry['status'] == "aborted") {
  3982 + $p_entry['status'] = "skipped";
  3983 + }
  3984 +
  3985 + // ----- Look for post-extract callback
  3986 + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
  3987 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction");
  3988 +
  3989 + // ----- Generate a local information
  3990 + $v_local_header = array();
  3991 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  3992 +
  3993 + // ----- Call the callback
  3994 + // Here I do not use call_user_func() because I need to send a reference to the
  3995 + // header.
  3996 + eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
  3997 +
  3998 + // ----- Look for abort result
  3999 + if ($v_result == 2) {
  4000 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
  4001 + $v_result = PCLZIP_ERR_USER_ABORTED;
  4002 + }
  4003 + }
  4004 +
  4005 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4006 + return $v_result;
  4007 + }
  4008 + // --------------------------------------------------------------------------------
  4009 +
  4010 + // --------------------------------------------------------------------------------
  4011 + // Function : privExtractFileAsString()
  4012 + // Description :
  4013 + // Parameters :
  4014 + // Return Values :
  4015 + // --------------------------------------------------------------------------------
  4016 + function privExtractFileAsString(&$p_entry, &$p_string)
  4017 + {
  4018 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileAsString', "p_entry['filename']='".$p_entry['filename']."'");
  4019 + $v_result=1;
  4020 +
  4021 + // ----- Read the file header
  4022 + $v_header = array();
  4023 + if (($v_result = $this->privReadFileHeader($v_header)) != 1)
  4024 + {
  4025 + // ----- Return
  4026 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4027 + return $v_result;
  4028 + }
  4029 +
  4030 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
  4031 +
  4032 + // ----- Check that the file header is coherent with $p_entry info
  4033 + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
  4034 + // TBC
  4035 + }
  4036 +
  4037 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file in string (with path) '".$p_entry['filename']."', size '$v_header[size]'");
  4038 +
  4039 + // ----- Do the extraction (if not a folder)
  4040 + if (!(($p_entry['external']&0x00000010)==0x00000010))
  4041 + {
  4042 + // ----- Look for not compressed file
  4043 +// if ($p_entry['compressed_size'] == $p_entry['size'])
  4044 + if ($p_entry['compression'] == 0) {
  4045 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
  4046 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes");
  4047 +
  4048 + // ----- Reading the file
  4049 + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
  4050 + }
  4051 + else {
  4052 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (compression method '".$p_entry['compression']."')");
  4053 +
  4054 + // ----- Reading the file
  4055 + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
  4056 +
  4057 + // ----- Decompress the file
  4058 + if (($p_string = @gzinflate($v_data)) === FALSE) {
  4059 + // TBC
  4060 + }
  4061 + }
  4062 +
  4063 + // ----- Trace
  4064 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
  4065 + }
  4066 + else {
  4067 + // TBC : error : can not extract a folder in a string
  4068 + }
  4069 +
  4070 + // ----- Return
  4071 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4072 + return $v_result;
  4073 + }
  4074 + // --------------------------------------------------------------------------------
  4075 +
  4076 + // --------------------------------------------------------------------------------
  4077 + // Function : privReadFileHeader()
  4078 + // Description :
  4079 + // Parameters :
  4080 + // Return Values :
  4081 + // --------------------------------------------------------------------------------
  4082 + function privReadFileHeader(&$p_header)
  4083 + {
  4084 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadFileHeader", "");
  4085 + $v_result=1;
  4086 +
  4087 + // ----- Read the 4 bytes signature
  4088 + $v_binary_data = @fread($this->zip_fd, 4);
  4089 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
  4090 + $v_data = unpack('Vid', $v_binary_data);
  4091 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
  4092 +
  4093 + // ----- Check signature
  4094 + if ($v_data['id'] != 0x04034b50)
  4095 + {
  4096 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid File header");
  4097 +
  4098 + // ----- Error log
  4099 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
  4100 +
  4101 + // ----- Return
  4102 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4103 + return PclZip::errorCode();
  4104 + }
  4105 +
  4106 + // ----- Read the first 42 bytes of the header
  4107 + $v_binary_data = fread($this->zip_fd, 26);
  4108 +
  4109 + // ----- Look for invalid block size
  4110 + if (strlen($v_binary_data) != 26)
  4111 + {
  4112 + $p_header['filename'] = "";
  4113 + $p_header['status'] = "invalid_header";
  4114 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
  4115 +
  4116 + // ----- Error log
  4117 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
  4118 +
  4119 + // ----- Return
  4120 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4121 + return PclZip::errorCode();
  4122 + }
  4123 +
  4124 + // ----- Extract the values
  4125 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header : '".$v_binary_data."'");
  4126 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header (Hex) : '".bin2hex($v_binary_data)."'");
  4127 + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
  4128 +
  4129 + // ----- Get filename
  4130 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "File name length : ".$v_data['filename_len']);
  4131 + $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
  4132 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename : \''.$p_header['filename'].'\'');
  4133 +
  4134 + // ----- Get extra_fields
  4135 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extra field length : ".$v_data['extra_len']);
  4136 + if ($v_data['extra_len'] != 0) {
  4137 + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
  4138 + }
  4139 + else {
  4140 + $p_header['extra'] = '';
  4141 + }
  4142 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Extra field : \''.bin2hex($p_header['extra']).'\'');
  4143 +
  4144 + // ----- Extract properties
  4145 + $p_header['version_extracted'] = $v_data['version'];
  4146 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : ('.$p_header['version_extracted'].') \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\'');
  4147 + $p_header['compression'] = $v_data['compression'];
  4148 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compression method : \''.$p_header['compression'].'\'');
  4149 + $p_header['size'] = $v_data['size'];
  4150 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_header['size'].'\'');
  4151 + $p_header['compressed_size'] = $v_data['compressed_size'];
  4152 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_header['compressed_size'].'\'');
  4153 + $p_header['crc'] = $v_data['crc'];
  4154 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.sprintf("0x%X", $p_header['crc']).'\'');
  4155 + $p_header['flag'] = $v_data['flag'];
  4156 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Flag : \''.$p_header['flag'].'\'');
  4157 + $p_header['filename_len'] = $v_data['filename_len'];
  4158 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename_len : \''.$p_header['filename_len'].'\'');
  4159 +
  4160 + // ----- Recuperate date in UNIX format
  4161 + $p_header['mdate'] = $v_data['mdate'];
  4162 + $p_header['mtime'] = $v_data['mtime'];
  4163 + if ($p_header['mdate'] && $p_header['mtime'])
  4164 + {
  4165 + // ----- Extract time
  4166 + $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
  4167 + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
  4168 + $v_seconde = ($p_header['mtime'] & 0x001F)*2;
  4169 +
  4170 + // ----- Extract date
  4171 + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
  4172 + $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
  4173 + $v_day = $p_header['mdate'] & 0x001F;
  4174 +
  4175 + // ----- Get UNIX date format
  4176 + $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
  4177 +
  4178 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
  4179 + }
  4180 + else
  4181 + {
  4182 + $p_header['mtime'] = time();
  4183 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
  4184 + }
  4185 +
  4186 + // TBC
  4187 + //for(reset($v_data); $key = key($v_data); next($v_data)) {
  4188 + // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Attribut[$key] = ".$v_data[$key]);
  4189 + //}
  4190 +
  4191 + // ----- Set the stored filename
  4192 + $p_header['stored_filename'] = $p_header['filename'];
  4193 +
  4194 + // ----- Set the status field
  4195 + $p_header['status'] = "ok";
  4196 +
  4197 + // ----- Return
  4198 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4199 + return $v_result;
  4200 + }
  4201 + // --------------------------------------------------------------------------------
  4202 +
  4203 + // --------------------------------------------------------------------------------
  4204 + // Function : privReadCentralFileHeader()
  4205 + // Description :
  4206 + // Parameters :
  4207 + // Return Values :
  4208 + // --------------------------------------------------------------------------------
  4209 + function privReadCentralFileHeader(&$p_header)
  4210 + {
  4211 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadCentralFileHeader", "");
  4212 + $v_result=1;
  4213 +
  4214 + // ----- Read the 4 bytes signature
  4215 + $v_binary_data = @fread($this->zip_fd, 4);
  4216 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
  4217 + $v_data = unpack('Vid', $v_binary_data);
  4218 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
  4219 +
  4220 + // ----- Check signature
  4221 + if ($v_data['id'] != 0x02014b50)
  4222 + {
  4223 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid Central Dir File signature");
  4224 +
  4225 + // ----- Error log
  4226 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
  4227 +
  4228 + // ----- Return
  4229 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4230 + return PclZip::errorCode();
  4231 + }
  4232 +
  4233 + // ----- Read the first 42 bytes of the header
  4234 + $v_binary_data = fread($this->zip_fd, 42);
  4235 +
  4236 + // ----- Look for invalid block size
  4237 + if (strlen($v_binary_data) != 42)
  4238 + {
  4239 + $p_header['filename'] = "";
  4240 + $p_header['status'] = "invalid_header";
  4241 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
  4242 +
  4243 + // ----- Error log
  4244 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
  4245 +
  4246 + // ----- Return
  4247 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4248 + return PclZip::errorCode();
  4249 + }
  4250 +
  4251 + // ----- Extract the values
  4252 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header : '".$v_binary_data."'");
  4253 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header (Hex) : '".bin2hex($v_binary_data)."'");
  4254 + $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
  4255 +
  4256 + // ----- Get filename
  4257 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "File name length : ".$p_header['filename_len']);
  4258 + if ($p_header['filename_len'] != 0)
  4259 + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
  4260 + else
  4261 + $p_header['filename'] = '';
  4262 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Filename : \''.$p_header['filename'].'\'');
  4263 +
  4264 + // ----- Get extra
  4265 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Extra length : ".$p_header['extra_len']);
  4266 + if ($p_header['extra_len'] != 0)
  4267 + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
  4268 + else
  4269 + $p_header['extra'] = '';
  4270 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Extra : \''.$p_header['extra'].'\'');
  4271 +
  4272 + // ----- Get comment
  4273 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Comment length : ".$p_header['comment_len']);
  4274 + if ($p_header['comment_len'] != 0)
  4275 + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
  4276 + else
  4277 + $p_header['comment'] = '';
  4278 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Comment : \''.$p_header['comment'].'\'');
  4279 +
  4280 + // ----- Extract properties
  4281 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version : \''.($p_header['version']/10).'.'.($p_header['version']%10).'\'');
  4282 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\'');
  4283 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Size : \''.$p_header['size'].'\'');
  4284 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Compressed Size : \''.$p_header['compressed_size'].'\'');
  4285 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'CRC : \''.sprintf("0x%X", $p_header['crc']).'\'');
  4286 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Flag : \''.$p_header['flag'].'\'');
  4287 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Offset : \''.$p_header['offset'].'\'');
  4288 +
  4289 + // ----- Recuperate date in UNIX format
  4290 + if ($p_header['mdate'] && $p_header['mtime'])
  4291 + {
  4292 + // ----- Extract time
  4293 + $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
  4294 + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
  4295 + $v_seconde = ($p_header['mtime'] & 0x001F)*2;
  4296 +
  4297 + // ----- Extract date
  4298 + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
  4299 + $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
  4300 + $v_day = $p_header['mdate'] & 0x001F;
  4301 +
  4302 + // ----- Get UNIX date format
  4303 + $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
  4304 +
  4305 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
  4306 + }
  4307 + else
  4308 + {
  4309 + $p_header['mtime'] = time();
  4310 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
  4311 + }
  4312 +
  4313 + // ----- Set the stored filename
  4314 + $p_header['stored_filename'] = $p_header['filename'];
  4315 +
  4316 + // ----- Set default status to ok
  4317 + $p_header['status'] = 'ok';
  4318 +
  4319 + // ----- Look if it is a directory
  4320 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Internal (Hex) : '".sprintf("Ox%04X", $p_header['internal'])."'");
  4321 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "External (Hex) : '".sprintf("Ox%04X", $p_header['external'])."' (".(($p_header['external']&0x00000010)==0x00000010?'is a folder':'is a file').')');
  4322 + if (substr($p_header['filename'], -1) == '/') {
  4323 + //$p_header['external'] = 0x41FF0010;
  4324 + $p_header['external'] = 0x00000010;
  4325 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Force folder external : \''.sprintf("Ox%04X", $p_header['external']).'\'');
  4326 + }
  4327 +
  4328 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Header of filename : \''.$p_header['filename'].'\'');
  4329 +
  4330 + // ----- Return
  4331 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4332 + return $v_result;
  4333 + }
  4334 + // --------------------------------------------------------------------------------
  4335 +
  4336 + // --------------------------------------------------------------------------------
  4337 + // Function : privCheckFileHeaders()
  4338 + // Description :
  4339 + // Parameters :
  4340 + // Return Values :
  4341 + // 1 on success,
  4342 + // 0 on error;
  4343 + // --------------------------------------------------------------------------------
  4344 + function privCheckFileHeaders(&$p_local_header, &$p_central_header)
  4345 + {
  4346 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFileHeaders", "");
  4347 + $v_result=1;
  4348 +
  4349 + // ----- Check the static values
  4350 + // TBC
  4351 + if ($p_local_header['filename'] != $p_central_header['filename']) {
  4352 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename" : TBC To Be Completed');
  4353 + }
  4354 + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
  4355 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "version_extracted" : TBC To Be Completed');
  4356 + }
  4357 + if ($p_local_header['flag'] != $p_central_header['flag']) {
  4358 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "flag" : TBC To Be Completed');
  4359 + }
  4360 + if ($p_local_header['compression'] != $p_central_header['compression']) {
  4361 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "compression" : TBC To Be Completed');
  4362 + }
  4363 + if ($p_local_header['mtime'] != $p_central_header['mtime']) {
  4364 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "mtime" : TBC To Be Completed');
  4365 + }
  4366 + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
  4367 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename_len" : TBC To Be Completed');
  4368 + }
  4369 +
  4370 + // ----- Look for flag bit 3
  4371 + if (($p_local_header['flag'] & 8) == 8) {
  4372 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Purpose bit flag bit 3 set !');
  4373 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'File size, compression size and crc found in central header');
  4374 + $p_local_header['size'] = $p_central_header['size'];
  4375 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_local_header['size'].'\'');
  4376 + $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
  4377 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_local_header['compressed_size'].'\'');
  4378 + $p_local_header['crc'] = $p_central_header['crc'];
  4379 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.sprintf("0x%X", $p_local_header['crc']).'\'');
  4380 + }
  4381 +
  4382 + // ----- Return
  4383 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4384 + return $v_result;
  4385 + }
  4386 + // --------------------------------------------------------------------------------
  4387 +
  4388 + // --------------------------------------------------------------------------------
  4389 + // Function : privReadEndCentralDir()
  4390 + // Description :
  4391 + // Parameters :
  4392 + // Return Values :
  4393 + // --------------------------------------------------------------------------------
  4394 + function privReadEndCentralDir(&$p_central_dir)
  4395 + {
  4396 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadEndCentralDir", "");
  4397 + $v_result=1;
  4398 +
  4399 + // ----- Go to the end of the zip file
  4400 + $v_size = filesize($this->zipname);
  4401 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size of the file :$v_size");
  4402 + @fseek($this->zip_fd, $v_size);
  4403 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position at end of zip file : \''.ftell($this->zip_fd).'\'');
  4404 + if (@ftell($this->zip_fd) != $v_size)
  4405 + {
  4406 + // ----- Error log
  4407 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
  4408 +
  4409 + // ----- Return
  4410 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4411 + return PclZip::errorCode();
  4412 + }
  4413 +
  4414 + // ----- First try : look if this is an archive with no commentaries (most of the time)
  4415 + // in this case the end of central dir is at 22 bytes of the file end
  4416 + $v_found = 0;
  4417 + if ($v_size > 26) {
  4418 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Look for central dir with no comment');
  4419 + @fseek($this->zip_fd, $v_size-22);
  4420 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after min central position : \''.ftell($this->zip_fd).'\'');
  4421 + if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
  4422 + {
  4423 + // ----- Error log
  4424 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
  4425 +
  4426 + // ----- Return
  4427 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4428 + return PclZip::errorCode();
  4429 + }
  4430 +
  4431 + // ----- Read for bytes
  4432 + $v_binary_data = @fread($this->zip_fd, 4);
  4433 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
  4434 + $v_data = @unpack('Vid', $v_binary_data);
  4435 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
  4436 +
  4437 + // ----- Check signature
  4438 + if ($v_data['id'] == 0x06054b50) {
  4439 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found central dir at the default position.");
  4440 + $v_found = 1;
  4441 + }
  4442 +
  4443 + $v_pos = ftell($this->zip_fd);
  4444 + }
  4445 +
  4446 + // ----- Go back to the maximum possible size of the Central Dir End Record
  4447 + if (!$v_found) {
  4448 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Start extended search of end central dir');
  4449 + $v_maximum_size = 65557; // 0xFFFF + 22;
  4450 + if ($v_maximum_size > $v_size)
  4451 + $v_maximum_size = $v_size;
  4452 + @fseek($this->zip_fd, $v_size-$v_maximum_size);
  4453 + if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
  4454 + {
  4455 + // ----- Error log
  4456 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
  4457 +
  4458 + // ----- Return
  4459 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4460 + return PclZip::errorCode();
  4461 + }
  4462 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after max central position : \''.ftell($this->zip_fd).'\'');
  4463 +
  4464 + // ----- Read byte per byte in order to find the signature
  4465 + $v_pos = ftell($this->zip_fd);
  4466 + $v_bytes = 0x00000000;
  4467 + while ($v_pos < $v_size)
  4468 + {
  4469 + // ----- Read a byte
  4470 + $v_byte = @fread($this->zip_fd, 1);
  4471 +
  4472 + // ----- Add the byte
  4473 + $v_bytes = ($v_bytes << 8) | Ord($v_byte);
  4474 +
  4475 + // ----- Compare the bytes
  4476 + if ($v_bytes == 0x504b0506)
  4477 + {
  4478 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Found End Central Dir signature at position : \''.ftell($this->zip_fd).'\'');
  4479 + $v_pos++;
  4480 + break;
  4481 + }
  4482 +
  4483 + $v_pos++;
  4484 + }
  4485 +
  4486 + // ----- Look if not found end of central dir
  4487 + if ($v_pos == $v_size)
  4488 + {
  4489 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to find End of Central Dir Record signature");
  4490 +
  4491 + // ----- Error log
  4492 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
  4493 +
  4494 + // ----- Return
  4495 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4496 + return PclZip::errorCode();
  4497 + }
  4498 + }
  4499 +
  4500 + // ----- Read the first 18 bytes of the header
  4501 + $v_binary_data = fread($this->zip_fd, 18);
  4502 +
  4503 + // ----- Look for invalid block size
  4504 + if (strlen($v_binary_data) != 18)
  4505 + {
  4506 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
  4507 +
  4508 + // ----- Error log
  4509 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
  4510 +
  4511 + // ----- Return
  4512 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4513 + return PclZip::errorCode();
  4514 + }
  4515 +
  4516 + // ----- Extract the values
  4517 + ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record : '".$v_binary_data."'");
  4518 + ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record (Hex) : '".bin2hex($v_binary_data)."'");
  4519 + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
  4520 +
  4521 + // ----- Check the global size
  4522 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Comment length : ".$v_data['comment_size']);
  4523 + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
  4524 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The central dir is not at the end of the archive. Some trailing bytes exists after the archive.");
  4525 +
  4526 + // ----- Removed in release 2.2 see readme file
  4527 + // The check of the file size is a little too strict.
  4528 + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
  4529 + // While decrypted, zip has training 0 bytes
  4530 + if (0) {
  4531 + // ----- Error log
  4532 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
  4533 + 'The central dir is not at the end of the archive.'
  4534 + .' Some trailing bytes exists after the archive.');
  4535 +
  4536 + // ----- Return
  4537 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4538 + return PclZip::errorCode();
  4539 + }
  4540 + }
  4541 +
  4542 + // ----- Get comment
  4543 + if ($v_data['comment_size'] != 0)
  4544 + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
  4545 + else
  4546 + $p_central_dir['comment'] = '';
  4547 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment : \''.$p_central_dir['comment'].'\'');
  4548 +
  4549 + $p_central_dir['entries'] = $v_data['entries'];
  4550 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries : \''.$p_central_dir['entries'].'\'');
  4551 + $p_central_dir['disk_entries'] = $v_data['disk_entries'];
  4552 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries for this disk : \''.$p_central_dir['disk_entries'].'\'');
  4553 + $p_central_dir['offset'] = $v_data['offset'];
  4554 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Offset of Central Dir : \''.$p_central_dir['offset'].'\'');
  4555 + $p_central_dir['size'] = $v_data['size'];
  4556 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size of Central Dir : \''.$p_central_dir['size'].'\'');
  4557 + $p_central_dir['disk'] = $v_data['disk'];
  4558 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Disk number : \''.$p_central_dir['disk'].'\'');
  4559 + $p_central_dir['disk_start'] = $v_data['disk_start'];
  4560 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Start disk number : \''.$p_central_dir['disk_start'].'\'');
  4561 +
  4562 + // TBC
  4563 + //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
  4564 + // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "central_dir[$key] = ".$p_central_dir[$key]);
  4565 + //}
  4566 +
  4567 + // ----- Return
  4568 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4569 + return $v_result;
  4570 + }
  4571 + // --------------------------------------------------------------------------------
  4572 +
  4573 + // --------------------------------------------------------------------------------
  4574 + // Function : privDeleteByRule()
  4575 + // Description :
  4576 + // Parameters :
  4577 + // Return Values :
  4578 + // --------------------------------------------------------------------------------
  4579 + function privDeleteByRule(&$p_result_list, &$p_options)
  4580 + {
  4581 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDeleteByRule", "");
  4582 + $v_result=1;
  4583 + $v_list_detail = array();
  4584 +
  4585 + // ----- Open the zip file
  4586 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  4587 + if (($v_result=$this->privOpenFd('rb')) != 1)
  4588 + {
  4589 + // ----- Return
  4590 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4591 + return $v_result;
  4592 + }
  4593 +
  4594 + // ----- Read the central directory informations
  4595 + $v_central_dir = array();
  4596 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  4597 + {
  4598 + $this->privCloseFd();
  4599 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4600 + return $v_result;
  4601 + }
  4602 +
  4603 + // ----- Go to beginning of File
  4604 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
  4605 + @rewind($this->zip_fd);
  4606 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
  4607 +
  4608 + // ----- Scan all the files
  4609 + // ----- Start at beginning of Central Dir
  4610 + $v_pos_entry = $v_central_dir['offset'];
  4611 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
  4612 + @rewind($this->zip_fd);
  4613 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
  4614 + if (@fseek($this->zip_fd, $v_pos_entry))
  4615 + {
  4616 + // ----- Close the zip file
  4617 + $this->privCloseFd();
  4618 +
  4619 + // ----- Error log
  4620 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  4621 +
  4622 + // ----- Return
  4623 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4624 + return PclZip::errorCode();
  4625 + }
  4626 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
  4627 +
  4628 + // ----- Read each entry
  4629 + $v_header_list = array();
  4630 + $j_start = 0;
  4631 + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
  4632 + {
  4633 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry (index '$i')");
  4634 +
  4635 + // ----- Read the file header
  4636 + $v_header_list[$v_nb_extracted] = array();
  4637 + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
  4638 + {
  4639 + // ----- Close the zip file
  4640 + $this->privCloseFd();
  4641 +
  4642 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4643 + return $v_result;
  4644 + }
  4645 +
  4646 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename (index '$i') : '".$v_header_list[$v_nb_extracted]['stored_filename']."'");
  4647 +
  4648 + // ----- Store the index
  4649 + $v_header_list[$v_nb_extracted]['index'] = $i;
  4650 +
  4651 + // ----- Look for the specific extract rules
  4652 + $v_found = false;
  4653 +
  4654 + // ----- Look for extract by name rule
  4655 + if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
  4656 + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
  4657 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
  4658 +
  4659 + // ----- Look if the filename is in the list
  4660 + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
  4661 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
  4662 +
  4663 + // ----- Look for a directory
  4664 + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
  4665 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
  4666 +
  4667 + // ----- Look if the directory is in the filename path
  4668 + if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
  4669 + && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  4670 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
  4671 + $v_found = true;
  4672 + }
  4673 + elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
  4674 + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  4675 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The entry is the searched directory");
  4676 + $v_found = true;
  4677 + }
  4678 + }
  4679 + // ----- Look for a filename
  4680 + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
  4681 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
  4682 + $v_found = true;
  4683 + }
  4684 + }
  4685 + }
  4686 +
  4687 + // ----- Look for extract by ereg rule
  4688 + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
  4689 + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
  4690 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
  4691 +
  4692 + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
  4693 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
  4694 + $v_found = true;
  4695 + }
  4696 + }
  4697 +
  4698 + // ----- Look for extract by preg rule
  4699 + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
  4700 + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
  4701 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
  4702 +
  4703 + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
  4704 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
  4705 + $v_found = true;
  4706 + }
  4707 + }
  4708 +
  4709 + // ----- Look for extract by index rule
  4710 + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
  4711 + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
  4712 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
  4713 +
  4714 + // ----- Look if the index is in the list
  4715 + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
  4716 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]");
  4717 +
  4718 + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
  4719 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
  4720 + $v_found = true;
  4721 + }
  4722 + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
  4723 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
  4724 + $j_start = $j+1;
  4725 + }
  4726 +
  4727 + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
  4728 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
  4729 + break;
  4730 + }
  4731 + }
  4732 + }
  4733 + else {
  4734 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "No argument mean remove all file");
  4735 + $v_found = true;
  4736 + }
  4737 +
  4738 + // ----- Look for deletion
  4739 + if ($v_found)
  4740 + {
  4741 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' need to be deleted");
  4742 + unset($v_header_list[$v_nb_extracted]);
  4743 + }
  4744 + else
  4745 + {
  4746 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' will not be deleted");
  4747 + $v_nb_extracted++;
  4748 + }
  4749 + }
  4750 +
  4751 + // ----- Look if something need to be deleted
  4752 + if ($v_nb_extracted > 0) {
  4753 +
  4754 + // ----- Creates a temporay file
  4755 + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  4756 +
  4757 + // ----- Creates a temporary zip archive
  4758 + $v_temp_zip = new PclZip($v_zip_temp_name);
  4759 +
  4760 + // ----- Open the temporary zip file in write mode
  4761 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary write mode");
  4762 + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
  4763 + $this->privCloseFd();
  4764 +
  4765 + // ----- Return
  4766 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4767 + return $v_result;
  4768 + }
  4769 +
  4770 + // ----- Look which file need to be kept
  4771 + for ($i=0; $i<sizeof($v_header_list); $i++) {
  4772 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Keep entry index '$i' : '".$v_header_list[$i]['filename']."'");
  4773 +
  4774 + // ----- Calculate the position of the header
  4775 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset='". $v_header_list[$i]['offset']."'");
  4776 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
  4777 + @rewind($this->zip_fd);
  4778 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
  4779 + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
  4780 + // ----- Close the zip file
  4781 + $this->privCloseFd();
  4782 + $v_temp_zip->privCloseFd();
  4783 + @unlink($v_zip_temp_name);
  4784 +
  4785 + // ----- Error log
  4786 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  4787 +
  4788 + // ----- Return
  4789 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4790 + return PclZip::errorCode();
  4791 + }
  4792 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
  4793 +
  4794 + // ----- Read the file header
  4795 + $v_local_header = array();
  4796 + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
  4797 + // ----- Close the zip file
  4798 + $this->privCloseFd();
  4799 + $v_temp_zip->privCloseFd();
  4800 + @unlink($v_zip_temp_name);
  4801 +
  4802 + // ----- Return
  4803 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4804 + return $v_result;
  4805 + }
  4806 +
  4807 + // ----- Check that local file header is same as central file header
  4808 + if ($this->privCheckFileHeaders($v_local_header,
  4809 + $v_header_list[$i]) != 1) {
  4810 + // TBC
  4811 + }
  4812 + unset($v_local_header);
  4813 +
  4814 + // ----- Write the file header
  4815 + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
  4816 + // ----- Close the zip file
  4817 + $this->privCloseFd();
  4818 + $v_temp_zip->privCloseFd();
  4819 + @unlink($v_zip_temp_name);
  4820 +
  4821 + // ----- Return
  4822 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4823 + return $v_result;
  4824 + }
  4825 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset for this file is '".$v_header_list[$i]['offset']."'");
  4826 +
  4827 + // ----- Read/write the data block
  4828 + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
  4829 + // ----- Close the zip file
  4830 + $this->privCloseFd();
  4831 + $v_temp_zip->privCloseFd();
  4832 + @unlink($v_zip_temp_name);
  4833 +
  4834 + // ----- Return
  4835 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4836 + return $v_result;
  4837 + }
  4838 + }
  4839 +
  4840 + // ----- Store the offset of the central dir
  4841 + $v_offset = @ftell($v_temp_zip->zip_fd);
  4842 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "New offset of central dir : $v_offset");
  4843 +
  4844 + // ----- Re-Create the Central Dir files header
  4845 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the new central directory");
  4846 + for ($i=0; $i<sizeof($v_header_list); $i++) {
  4847 + // ----- Create the file header
  4848 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset of file : ".$v_header_list[$i]['offset']);
  4849 + if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  4850 + $v_temp_zip->privCloseFd();
  4851 + $this->privCloseFd();
  4852 + @unlink($v_zip_temp_name);
  4853 +
  4854 + // ----- Return
  4855 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4856 + return $v_result;
  4857 + }
  4858 +
  4859 + // ----- Transform the header to a 'usable' info
  4860 + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  4861 + }
  4862 +
  4863 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the central directory footer");
  4864 +
  4865 + // ----- Zip file comment
  4866 + $v_comment = '';
  4867 + if (isset($p_options[PCLZIP_OPT_COMMENT])) {
  4868 + $v_comment = $p_options[PCLZIP_OPT_COMMENT];
  4869 + }
  4870 +
  4871 + // ----- Calculate the size of the central header
  4872 + $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
  4873 +
  4874 + // ----- Create the central dir footer
  4875 + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
  4876 + // ----- Reset the file list
  4877 + unset($v_header_list);
  4878 + $v_temp_zip->privCloseFd();
  4879 + $this->privCloseFd();
  4880 + @unlink($v_zip_temp_name);
  4881 +
  4882 + // ----- Return
  4883 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4884 + return $v_result;
  4885 + }
  4886 +
  4887 + // ----- Close
  4888 + $v_temp_zip->privCloseFd();
  4889 + $this->privCloseFd();
  4890 +
  4891 + // ----- Delete the zip file
  4892 + // TBC : I should test the result ...
  4893 + @unlink($this->zipname);
  4894 +
  4895 + // ----- Rename the temporary file
  4896 + // TBC : I should test the result ...
  4897 + //@rename($v_zip_temp_name, $this->zipname);
  4898 + PclZipUtilRename($v_zip_temp_name, $this->zipname);
  4899 +
  4900 + // ----- Destroy the temporary archive
  4901 + unset($v_temp_zip);
  4902 + }
  4903 +
  4904 + // ----- Remove every files : reset the file
  4905 + else if ($v_central_dir['entries'] != 0) {
  4906 + $this->privCloseFd();
  4907 +
  4908 + if (($v_result = $this->privOpenFd('wb')) != 1) {
  4909 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4910 + return $v_result;
  4911 + }
  4912 +
  4913 + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
  4914 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4915 + return $v_result;
  4916 + }
  4917 +
  4918 + $this->privCloseFd();
  4919 + }
  4920 +
  4921 + // ----- Return
  4922 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4923 + return $v_result;
  4924 + }
  4925 + // --------------------------------------------------------------------------------
  4926 +
  4927 + // --------------------------------------------------------------------------------
  4928 + // Function : privDirCheck()
  4929 + // Description :
  4930 + // Check if a directory exists, if not it creates it and all the parents directory
  4931 + // which may be useful.
  4932 + // Parameters :
  4933 + // $p_dir : Directory path to check.
  4934 + // Return Values :
  4935 + // 1 : OK
  4936 + // -1 : Unable to create directory
  4937 + // --------------------------------------------------------------------------------
  4938 + function privDirCheck($p_dir, $p_is_dir=false)
  4939 + {
  4940 + $v_result = 1;
  4941 +
  4942 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDirCheck", "entry='$p_dir', is_dir='".($p_is_dir?"true":"false")."'");
  4943 +
  4944 + // ----- Remove the final '/'
  4945 + if (($p_is_dir) && (substr($p_dir, -1)=='/'))
  4946 + {
  4947 + $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
  4948 + }
  4949 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Looking for entry '$p_dir'");
  4950 +
  4951 + // ----- Check the directory availability
  4952 + if ((is_dir($p_dir)) || ($p_dir == ""))
  4953 + {
  4954 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, "'$p_dir' is a directory");
  4955 + return 1;
  4956 + }
  4957 +
  4958 + // ----- Extract parent directory
  4959 + $p_parent_dir = dirname($p_dir);
  4960 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Parent directory is '$p_parent_dir'");
  4961 +
  4962 + // ----- Just a check
  4963 + if ($p_parent_dir != $p_dir)
  4964 + {
  4965 + // ----- Look for parent directory
  4966 + if ($p_parent_dir != "")
  4967 + {
  4968 + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
  4969 + {
  4970 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4971 + return $v_result;
  4972 + }
  4973 + }
  4974 + }
  4975 +
  4976 + // ----- Create the directory
  4977 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Create directory '$p_dir'");
  4978 + if (!@mkdir($p_dir, 0777))
  4979 + {
  4980 + // ----- Error log
  4981 + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
  4982 +
  4983 + // ----- Return
  4984 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4985 + return PclZip::errorCode();
  4986 + }
  4987 +
  4988 + // ----- Return
  4989 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result, "Directory '$p_dir' created");
  4990 + return $v_result;
  4991 + }
  4992 + // --------------------------------------------------------------------------------
  4993 +
  4994 + // --------------------------------------------------------------------------------
  4995 + // Function : privMerge()
  4996 + // Description :
  4997 + // If $p_archive_to_add does not exist, the function exit with a success result.
  4998 + // Parameters :
  4999 + // Return Values :
  5000 + // --------------------------------------------------------------------------------
  5001 + function privMerge(&$p_archive_to_add)
  5002 + {
  5003 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privMerge", "archive='".$p_archive_to_add->zipname."'");
  5004 + $v_result=1;
  5005 +
  5006 + // ----- Look if the archive_to_add exists
  5007 + if (!is_file($p_archive_to_add->zipname))
  5008 + {
  5009 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to add does not exist. End of merge.");
  5010 +
  5011 + // ----- Nothing to merge, so merge is a success
  5012 + $v_result = 1;
  5013 +
  5014 + // ----- Return
  5015 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5016 + return $v_result;
  5017 + }
  5018 +
  5019 + // ----- Look if the archive exists
  5020 + if (!is_file($this->zipname))
  5021 + {
  5022 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, duplicate the archive_to_add.");
  5023 +
  5024 + // ----- Do a duplicate
  5025 + $v_result = $this->privDuplicate($p_archive_to_add->zipname);
  5026 +
  5027 + // ----- Return
  5028 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5029 + return $v_result;
  5030 + }
  5031 +
  5032 + // ----- Open the zip file
  5033 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  5034 + if (($v_result=$this->privOpenFd('rb')) != 1)
  5035 + {
  5036 + // ----- Return
  5037 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5038 + return $v_result;
  5039 + }
  5040 +
  5041 + // ----- Read the central directory informations
  5042 + $v_central_dir = array();
  5043 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  5044 + {
  5045 + $this->privCloseFd();
  5046 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5047 + return $v_result;
  5048 + }
  5049 +
  5050 + // ----- Go to beginning of File
  5051 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
  5052 + @rewind($this->zip_fd);
  5053 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
  5054 +
  5055 + // ----- Open the archive_to_add file
  5056 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open archive_to_add in binary read mode");
  5057 + if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
  5058 + {
  5059 + $this->privCloseFd();
  5060 +
  5061 + // ----- Return
  5062 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5063 + return $v_result;
  5064 + }
  5065 +
  5066 + // ----- Read the central directory informations
  5067 + $v_central_dir_to_add = array();
  5068 + if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
  5069 + {
  5070 + $this->privCloseFd();
  5071 + $p_archive_to_add->privCloseFd();
  5072 +
  5073 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5074 + return $v_result;
  5075 + }
  5076 +
  5077 + // ----- Go to beginning of File
  5078 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
  5079 + @rewind($p_archive_to_add->zip_fd);
  5080 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
  5081 +
  5082 + // ----- Creates a temporay file
  5083 + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  5084 +
  5085 + // ----- Open the temporary file in write mode
  5086 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  5087 + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
  5088 + {
  5089 + $this->privCloseFd();
  5090 + $p_archive_to_add->privCloseFd();
  5091 +
  5092 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
  5093 +
  5094 + // ----- Return
  5095 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  5096 + return PclZip::errorCode();
  5097 + }
  5098 +
  5099 + // ----- Copy the files from the archive to the temporary file
  5100 + // TBC : Here I should better append the file and go back to erase the central dir
  5101 + $v_size = $v_central_dir['offset'];
  5102 + while ($v_size != 0)
  5103 + {
  5104 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5105 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  5106 + $v_buffer = fread($this->zip_fd, $v_read_size);
  5107 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  5108 + $v_size -= $v_read_size;
  5109 + }
  5110 +
  5111 + // ----- Copy the files from the archive_to_add into the temporary file
  5112 + $v_size = $v_central_dir_to_add['offset'];
  5113 + while ($v_size != 0)
  5114 + {
  5115 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5116 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  5117 + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
  5118 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  5119 + $v_size -= $v_read_size;
  5120 + }
  5121 +
  5122 + // ----- Store the offset of the central dir
  5123 + $v_offset = @ftell($v_zip_temp_fd);
  5124 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
  5125 +
  5126 + // ----- Copy the block of file headers from the old archive
  5127 + $v_size = $v_central_dir['size'];
  5128 + while ($v_size != 0)
  5129 + {
  5130 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5131 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  5132 + $v_buffer = @fread($this->zip_fd, $v_read_size);
  5133 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  5134 + $v_size -= $v_read_size;
  5135 + }
  5136 +
  5137 + // ----- Copy the block of file headers from the archive_to_add
  5138 + $v_size = $v_central_dir_to_add['size'];
  5139 + while ($v_size != 0)
  5140 + {
  5141 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5142 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  5143 + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
  5144 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  5145 + $v_size -= $v_read_size;
  5146 + }
  5147 +
  5148 + // ----- Merge the file comments
  5149 + $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
  5150 +
  5151 + // ----- Calculate the size of the (new) central header
  5152 + $v_size = @ftell($v_zip_temp_fd)-$v_offset;
  5153 +
  5154 + // ----- Swap the file descriptor
  5155 + // Here is a trick : I swap the temporary fd with the zip fd, in order to use
  5156 + // the following methods on the temporary fil and not the real archive fd
  5157 + $v_swap = $this->zip_fd;
  5158 + $this->zip_fd = $v_zip_temp_fd;
  5159 + $v_zip_temp_fd = $v_swap;
  5160 +
  5161 + // ----- Create the central dir footer
  5162 + if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
  5163 + {
  5164 + $this->privCloseFd();
  5165 + $p_archive_to_add->privCloseFd();
  5166 + @fclose($v_zip_temp_fd);
  5167 + $this->zip_fd = null;
  5168 +
  5169 + // ----- Reset the file list
  5170 + unset($v_header_list);
  5171 +
  5172 + // ----- Return
  5173 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5174 + return $v_result;
  5175 + }
  5176 +
  5177 + // ----- Swap back the file descriptor
  5178 + $v_swap = $this->zip_fd;
  5179 + $this->zip_fd = $v_zip_temp_fd;
  5180 + $v_zip_temp_fd = $v_swap;
  5181 +
  5182 + // ----- Close
  5183 + $this->privCloseFd();
  5184 + $p_archive_to_add->privCloseFd();
  5185 +
  5186 + // ----- Close the temporary file
  5187 + @fclose($v_zip_temp_fd);
  5188 +
  5189 + // ----- Delete the zip file
  5190 + // TBC : I should test the result ...
  5191 + @unlink($this->zipname);
  5192 +
  5193 + // ----- Rename the temporary file
  5194 + // TBC : I should test the result ...
  5195 + //@rename($v_zip_temp_name, $this->zipname);
  5196 + PclZipUtilRename($v_zip_temp_name, $this->zipname);
  5197 +
  5198 + // ----- Return
  5199 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5200 + return $v_result;
  5201 + }
  5202 + // --------------------------------------------------------------------------------
  5203 +
  5204 + // --------------------------------------------------------------------------------
  5205 + // Function : privDuplicate()
  5206 + // Description :
  5207 + // Parameters :
  5208 + // Return Values :
  5209 + // --------------------------------------------------------------------------------
  5210 + function privDuplicate($p_archive_filename)
  5211 + {
  5212 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDuplicate", "archive_filename='$p_archive_filename'");
  5213 + $v_result=1;
  5214 +
  5215 + // ----- Look if the $p_archive_filename exists
  5216 + if (!is_file($p_archive_filename))
  5217 + {
  5218 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to duplicate does not exist. End of duplicate.");
  5219 +
  5220 + // ----- Nothing to duplicate, so duplicate is a success.
  5221 + $v_result = 1;
  5222 +
  5223 + // ----- Return
  5224 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5225 + return $v_result;
  5226 + }
  5227 +
  5228 + // ----- Open the zip file
  5229 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  5230 + if (($v_result=$this->privOpenFd('wb')) != 1)
  5231 + {
  5232 + // ----- Return
  5233 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5234 + return $v_result;
  5235 + }
  5236 +
  5237 + // ----- Open the temporary file in write mode
  5238 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  5239 + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
  5240 + {
  5241 + $this->privCloseFd();
  5242 +
  5243 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
  5244 +
  5245 + // ----- Return
  5246 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  5247 + return PclZip::errorCode();
  5248 + }
  5249 +
  5250 + // ----- Copy the files from the archive to the temporary file
  5251 + // TBC : Here I should better append the file and go back to erase the central dir
  5252 + $v_size = filesize($p_archive_filename);
  5253 + while ($v_size != 0)
  5254 + {
  5255 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5256 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read $v_read_size bytes");
  5257 + $v_buffer = fread($v_zip_temp_fd, $v_read_size);
  5258 + @fwrite($this->zip_fd, $v_buffer, $v_read_size);
  5259 + $v_size -= $v_read_size;
  5260 + }
  5261 +
  5262 + // ----- Close
  5263 + $this->privCloseFd();
  5264 +
  5265 + // ----- Close the temporary file
  5266 + @fclose($v_zip_temp_fd);
  5267 +
  5268 + // ----- Return
  5269 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5270 + return $v_result;
  5271 + }
  5272 + // --------------------------------------------------------------------------------
  5273 +
  5274 + // --------------------------------------------------------------------------------
  5275 + // Function : privErrorLog()
  5276 + // Description :
  5277 + // Parameters :
  5278 + // --------------------------------------------------------------------------------
  5279 + function privErrorLog($p_error_code=0, $p_error_string='')
  5280 + {
  5281 + if (PCLZIP_ERROR_EXTERNAL == 1) {
  5282 + PclError($p_error_code, $p_error_string);
  5283 + }
  5284 + else {
  5285 + $this->error_code = $p_error_code;
  5286 + $this->error_string = $p_error_string;
  5287 + }
  5288 + }
  5289 + // --------------------------------------------------------------------------------
  5290 +
  5291 + // --------------------------------------------------------------------------------
  5292 + // Function : privErrorReset()
  5293 + // Description :
  5294 + // Parameters :
  5295 + // --------------------------------------------------------------------------------
  5296 + function privErrorReset()
  5297 + {
  5298 + if (PCLZIP_ERROR_EXTERNAL == 1) {
  5299 + PclErrorReset();
  5300 + }
  5301 + else {
  5302 + $this->error_code = 0;
  5303 + $this->error_string = '';
  5304 + }
  5305 + }
  5306 + // --------------------------------------------------------------------------------
  5307 +
  5308 + // --------------------------------------------------------------------------------
  5309 + // Function : privDecrypt()
  5310 + // Description :
  5311 + // Parameters :
  5312 + // Return Values :
  5313 + // --------------------------------------------------------------------------------
  5314 + function privDecrypt($p_encryption_header, &$p_buffer, $p_size, $p_crc)
  5315 + {
  5316 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDecrypt', "size=".$p_size."");
  5317 + $v_result=1;
  5318 +
  5319 + // ----- To Be Modified ;-)
  5320 + $v_pwd = "test";
  5321 +
  5322 + $p_buffer = PclZipUtilZipDecrypt($p_buffer, $p_size, $p_encryption_header,
  5323 + $p_crc, $v_pwd);
  5324 +
  5325 + // ----- Return
  5326 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5327 + return $v_result;
  5328 + }
  5329 + // --------------------------------------------------------------------------------
  5330 +
  5331 + // --------------------------------------------------------------------------------
  5332 + // Function : privDisableMagicQuotes()
  5333 + // Description :
  5334 + // Parameters :
  5335 + // Return Values :
  5336 + // --------------------------------------------------------------------------------
  5337 + function privDisableMagicQuotes()
  5338 + {
  5339 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDisableMagicQuotes', "");
  5340 + $v_result=1;
  5341 +
  5342 + // ----- Look if function exists
  5343 + if ( (!function_exists("get_magic_quotes_runtime"))
  5344 + || (!function_exists("set_magic_quotes_runtime"))) {
  5345 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported");
  5346 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5347 + return $v_result;
  5348 + }
  5349 +
  5350 + // ----- Look if already done
  5351 + if ($this->magic_quotes_status != -1) {
  5352 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote already disabled");
  5353 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5354 + return $v_result;
  5355 + }
  5356 +
  5357 + // ----- Get and memorize the magic_quote value
  5358 + $this->magic_quotes_status = @get_magic_quotes_runtime();
  5359 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Current magic_quotes_runtime status is '".($this->magic_quotes_status==0?'disable':'enable')."'");
  5360 +
  5361 + // ----- Disable magic_quotes
  5362 + if ($this->magic_quotes_status == 1) {
  5363 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Disable magic_quotes");
  5364 + @set_magic_quotes_runtime(0);
  5365 + }
  5366 +
  5367 + // ----- Return
  5368 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5369 + return $v_result;
  5370 + }
  5371 + // --------------------------------------------------------------------------------
  5372 +
  5373 + // --------------------------------------------------------------------------------
  5374 + // Function : privSwapBackMagicQuotes()
  5375 + // Description :
  5376 + // Parameters :
  5377 + // Return Values :
  5378 + // --------------------------------------------------------------------------------
  5379 + function privSwapBackMagicQuotes()
  5380 + {
  5381 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privSwapBackMagicQuotes', "");
  5382 + $v_result=1;
  5383 +
  5384 + // ----- Look if function exists
  5385 + if ( (!function_exists("get_magic_quotes_runtime"))
  5386 + || (!function_exists("set_magic_quotes_runtime"))) {
  5387 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported");
  5388 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5389 + return $v_result;
  5390 + }
  5391 +
  5392 + // ----- Look if something to do
  5393 + if ($this->magic_quotes_status != -1) {
  5394 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote not modified");
  5395 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5396 + return $v_result;
  5397 + }
  5398 +
  5399 + // ----- Swap back magic_quotes
  5400 + if ($this->magic_quotes_status == 1) {
  5401 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Enable back magic_quotes");
  5402 + @set_magic_quotes_runtime($this->magic_quotes_status);
  5403 + }
  5404 +
  5405 + // ----- Return
  5406 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5407 + return $v_result;
  5408 + }
  5409 + // --------------------------------------------------------------------------------
  5410 +
  5411 + }
  5412 + // End of class
  5413 + // --------------------------------------------------------------------------------
  5414 +
  5415 + // --------------------------------------------------------------------------------
  5416 + // Function : PclZipUtilPathReduction()
  5417 + // Description :
  5418 + // Parameters :
  5419 + // Return Values :
  5420 + // --------------------------------------------------------------------------------
  5421 + function PclZipUtilPathReduction($p_dir)
  5422 + {
  5423 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathReduction", "dir='$p_dir'");
  5424 + $v_result = "";
  5425 +
  5426 + // ----- Look for not empty path
  5427 + if ($p_dir != "") {
  5428 + // ----- Explode path by directory names
  5429 + $v_list = explode("/", $p_dir);
  5430 +
  5431 + // ----- Study directories from last to first
  5432 + $v_skip = 0;
  5433 + for ($i=sizeof($v_list)-1; $i>=0; $i--) {
  5434 + // ----- Look for current path
  5435 + if ($v_list[$i] == ".") {
  5436 + // ----- Ignore this directory
  5437 + // Should be the first $i=0, but no check is done
  5438 + }
  5439 + else if ($v_list[$i] == "..") {
  5440 + $v_skip++;
  5441 + }
  5442 + else if ($v_list[$i] == "") {
  5443 + // ----- First '/' i.e. root slash
  5444 + if ($i == 0) {
  5445 + $v_result = "/".$v_result;
  5446 + if ($v_skip > 0) {
  5447 + // ----- It is an invalid path, so the path is not modified
  5448 + // TBC
  5449 + $v_result = $p_dir;
  5450 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid path is unchanged");
  5451 + $v_skip = 0;
  5452 + }
  5453 + }
  5454 + // ----- Last '/' i.e. indicates a directory
  5455 + else if ($i == (sizeof($v_list)-1)) {
  5456 + $v_result = $v_list[$i];
  5457 + }
  5458 + // ----- Double '/' inside the path
  5459 + else {
  5460 + // ----- Ignore only the double '//' in path,
  5461 + // but not the first and last '/'
  5462 + }
  5463 + }
  5464 + else {
  5465 + // ----- Look for item to skip
  5466 + if ($v_skip > 0) {
  5467 + $v_skip--;
  5468 + }
  5469 + else {
  5470 + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
  5471 + }
  5472 + }
  5473 + }
  5474 +
  5475 + // ----- Look for skip
  5476 + if ($v_skip > 0) {
  5477 + while ($v_skip > 0) {
  5478 + $v_result = '../'.$v_result;
  5479 + $v_skip--;
  5480 + }
  5481 + }
  5482 + }
  5483 +
  5484 + // ----- Return
  5485 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5486 + return $v_result;
  5487 + }
  5488 + // --------------------------------------------------------------------------------
  5489 +
  5490 + // --------------------------------------------------------------------------------
  5491 + // Function : PclZipUtilPathInclusion()
  5492 + // Description :
  5493 + // This function indicates if the path $p_path is under the $p_dir tree. Or,
  5494 + // said in an other way, if the file or sub-dir $p_path is inside the dir
  5495 + // $p_dir.
  5496 + // The function indicates also if the path is exactly the same as the dir.
  5497 + // This function supports path with duplicated '/' like '//', but does not
  5498 + // support '.' or '..' statements.
  5499 + // Parameters :
  5500 + // Return Values :
  5501 + // 0 if $p_path is not inside directory $p_dir
  5502 + // 1 if $p_path is inside directory $p_dir
  5503 + // 2 if $p_path is exactly the same as $p_dir
  5504 + // --------------------------------------------------------------------------------
  5505 + function PclZipUtilPathInclusion($p_dir, $p_path)
  5506 + {
  5507 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathInclusion", "dir='$p_dir', path='$p_path'");
  5508 + $v_result = 1;
  5509 +
  5510 + // ----- Look for path beginning by ./
  5511 + if ( ($p_dir == '.')
  5512 + || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
  5513 + $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
  5514 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Replacing ./ by full path in p_dir '".$p_dir."'");
  5515 + }
  5516 + if ( ($p_path == '.')
  5517 + || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
  5518 + $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
  5519 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Replacing ./ by full path in p_path '".$p_path."'");
  5520 + }
  5521 +
  5522 + // ----- Explode dir and path by directory separator
  5523 + $v_list_dir = explode("/", $p_dir);
  5524 + $v_list_dir_size = sizeof($v_list_dir);
  5525 + $v_list_path = explode("/", $p_path);
  5526 + $v_list_path_size = sizeof($v_list_path);
  5527 +
  5528 + // ----- Study directories paths
  5529 + $i = 0;
  5530 + $j = 0;
  5531 + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
  5532 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Working on dir($i)='".$v_list_dir[$i]."' and path($j)='".$v_list_path[$j]."'");
  5533 +
  5534 + // ----- Look for empty dir (path reduction)
  5535 + if ($v_list_dir[$i] == '') {
  5536 + $i++;
  5537 + continue;
  5538 + }
  5539 + if ($v_list_path[$j] == '') {
  5540 + $j++;
  5541 + continue;
  5542 + }
  5543 +
  5544 + // ----- Compare the items
  5545 + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {
  5546 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Items ($i,$j) are different");
  5547 + $v_result = 0;
  5548 + }
  5549 +
  5550 + // ----- Next items
  5551 + $i++;
  5552 + $j++;
  5553 + }
  5554 +
  5555 + // ----- Look if everything seems to be the same
  5556 + if ($v_result) {
  5557 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Look for tie break");
  5558 + // ----- Skip all the empty items
  5559 + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
  5560 + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
  5561 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Looking on dir($i)='".($i < $v_list_dir_size?$v_list_dir[$i]:'')."' and path($j)='".($j < $v_list_path_size?$v_list_path[$j]:'')."'");
  5562 +
  5563 + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
  5564 + // ----- There are exactly the same
  5565 + $v_result = 2;
  5566 + }
  5567 + else if ($i < $v_list_dir_size) {
  5568 + // ----- The path is shorter than the dir
  5569 + $v_result = 0;
  5570 + }
  5571 + }
  5572 +
  5573 + // ----- Return
  5574 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5575 + return $v_result;
  5576 + }
  5577 + // --------------------------------------------------------------------------------
  5578 +
  5579 + // --------------------------------------------------------------------------------
  5580 + // Function : PclZipUtilCopyBlock()
  5581 + // Description :
  5582 + // Parameters :
  5583 + // $p_mode : read/write compression mode
  5584 + // 0 : src & dest normal
  5585 + // 1 : src gzip, dest normal
  5586 + // 2 : src normal, dest gzip
  5587 + // 3 : src & dest gzip
  5588 + // Return Values :
  5589 + // --------------------------------------------------------------------------------
  5590 + function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
  5591 + {
  5592 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilCopyBlock", "size=$p_size, mode=$p_mode");
  5593 + $v_result = 1;
  5594 +
  5595 + if ($p_mode==0)
  5596 + {
  5597 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset before read :".(@ftell($p_src)));
  5598 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset before write :".(@ftell($p_dest)));
  5599 + while ($p_size != 0)
  5600 + {
  5601 + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  5602 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  5603 + $v_buffer = @fread($p_src, $v_read_size);
  5604 + @fwrite($p_dest, $v_buffer, $v_read_size);
  5605 + $p_size -= $v_read_size;
  5606 + }
  5607 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset after read :".(@ftell($p_src)));
  5608 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset after write :".(@ftell($p_dest)));
  5609 + }
  5610 + else if ($p_mode==1)
  5611 + {
  5612 + while ($p_size != 0)
  5613 + {
  5614 + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  5615 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  5616 + $v_buffer = @gzread($p_src, $v_read_size);
  5617 + @fwrite($p_dest, $v_buffer, $v_read_size);
  5618 + $p_size -= $v_read_size;
  5619 + }
  5620 + }
  5621 + else if ($p_mode==2)
  5622 + {
  5623 + while ($p_size != 0)
  5624 + {
  5625 + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  5626 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  5627 + $v_buffer = @fread($p_src, $v_read_size);
  5628 + @gzwrite($p_dest, $v_buffer, $v_read_size);
  5629 + $p_size -= $v_read_size;
  5630 + }
  5631 + }
  5632 + else if ($p_mode==3)
  5633 + {
  5634 + while ($p_size != 0)
  5635 + {
  5636 + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  5637 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  5638 + $v_buffer = @gzread($p_src, $v_read_size);
  5639 + @gzwrite($p_dest, $v_buffer, $v_read_size);
  5640 + $p_size -= $v_read_size;
  5641 + }
  5642 + }
  5643 +
  5644 + // ----- Return
  5645 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5646 + return $v_result;
  5647 + }
  5648 + // --------------------------------------------------------------------------------
  5649 +
  5650 + // --------------------------------------------------------------------------------
  5651 + // Function : PclZipUtilRename()
  5652 + // Description :
  5653 + // This function tries to do a simple rename() function. If it fails, it
  5654 + // tries to copy the $p_src file in a new $p_dest file and then unlink the
  5655 + // first one.
  5656 + // Parameters :
  5657 + // $p_src : Old filename
  5658 + // $p_dest : New filename
  5659 + // Return Values :
  5660 + // 1 on success, 0 on failure.
  5661 + // --------------------------------------------------------------------------------
  5662 + function PclZipUtilRename($p_src, $p_dest)
  5663 + {
  5664 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilRename", "source=$p_src, destination=$p_dest");
  5665 + $v_result = 1;
  5666 +
  5667 + // ----- Try to rename the files
  5668 + if (!@rename($p_src, $p_dest)) {
  5669 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to rename file, try copy+unlink");
  5670 +
  5671 + // ----- Try to copy & unlink the src
  5672 + if (!@copy($p_src, $p_dest)) {
  5673 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to copy file");
  5674 + $v_result = 0;
  5675 + }
  5676 + else if (!@unlink($p_src)) {
  5677 + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to unlink old filename");
  5678 + $v_result = 0;
  5679 + }
  5680 + }
  5681 +
  5682 + // ----- Return
  5683 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5684 + return $v_result;
  5685 + }
  5686 + // --------------------------------------------------------------------------------
  5687 +
  5688 + // --------------------------------------------------------------------------------
  5689 + // Function : PclZipUtilOptionText()
  5690 + // Description :
  5691 + // Translate option value in text. Mainly for debug purpose.
  5692 + // Parameters :
  5693 + // $p_option : the option value.
  5694 + // Return Values :
  5695 + // The option text value.
  5696 + // --------------------------------------------------------------------------------
  5697 + function PclZipUtilOptionText($p_option)
  5698 + {
  5699 + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilOptionText", "option='".$p_option."'");
  5700 +
  5701 + $v_list = get_defined_constants();
  5702 + for (reset($v_list); $v_key = key($v_list); next($v_list)) {
  5703 + $v_prefix = substr($v_key, 0, 10);
  5704 + if (( ($v_prefix == 'PCLZIP_OPT')
  5705 + || ($v_prefix == 'PCLZIP_CB_')
  5706 + || ($v_prefix == 'PCLZIP_ATT'))
  5707 + && ($v_list[$v_key] == $p_option)) {
  5708 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_key);
  5709 + return $v_key;
  5710 + }
  5711 + }
  5712 +
  5713 + $v_result = 'Unknown';
  5714 +
  5715 + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  5716 + return $v_result;
  5717 + }
  5718 + // --------------------------------------------------------------------------------
  5719 +
  5720 + // --------------------------------------------------------------------------------
  5721 + // Function : PclZipUtilTranslateWinPath()
  5722 + // Description :
  5723 + // Translate windows path by replacing '\' by '/' and optionally removing
  5724 + // drive letter.
  5725 + // Parameters :
  5726 + // $p_path : path to translate.
  5727 + // $p_remove_disk_letter : true | false
  5728 + // Return Values :
  5729 + // The path translated.
  5730 + // --------------------------------------------------------------------------------
  5731 + function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
  5732 + {
  5733 + if (stristr(php_uname(), 'windows')) {
  5734 + // ----- Look for potential disk letter
  5735 + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
  5736 + $p_path = substr($p_path, $v_position+1);
  5737 + }
  5738 + // ----- Change potential windows directory separator
  5739 + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
  5740 + $p_path = strtr($p_path, '\\', '/');
  5741 + }
  5742 + }
  5743 + return $p_path;
  5744 + }
  5745 + // --------------------------------------------------------------------------------
  5746 +
  5747 +
  5748 +?>
... ...