r68658 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r68657‎ | r68658 | r68659 >
Date:12:58, 28 June 2010
Author:jeroendedauw
Status:deferred (Comments)
Tags:
Comment:
Committing preliminary design for review purposes.
Modified paths:
  • /trunk/extensions/Deployment/README (modified) (history)
  • /trunk/extensions/Deployment/RELEASE-NOTES (modified) (history)
  • /trunk/extensions/Deployment/api (added) (history)
  • /trunk/extensions/Deployment/api/ApiExtensions.php (added) (history)
  • /trunk/extensions/Deployment/api/ApiQueryExtensions.php (added) (history)
  • /trunk/extensions/Deployment/includes (added) (history)
  • /trunk/extensions/Deployment/includes/Filesystem.php (added) (history)
  • /trunk/extensions/Deployment/includes/Installer.php (added) (history)
  • /trunk/extensions/Deployment/includes/filesystems (added) (history)
  • /trunk/extensions/Deployment/includes/filesystems/DirectFilesystem.php (added) (history)
  • /trunk/extensions/Deployment/includes/filesystems/FtpFilesystem.php (added) (history)
  • /trunk/extensions/Deployment/includes/installers (added) (history)
  • /trunk/extensions/Deployment/includes/installers/CoreInstaller.php (added) (history)
  • /trunk/extensions/Deployment/includes/installers/ExtensionInstaller.php (added) (history)
  • /trunk/extensions/Deployment/includes/pclzip.lib.php (added) (history)
  • /trunk/extensions/Deployment/maintenance (added) (history)
  • /trunk/extensions/Deployment/specials (added) (history)
  • /trunk/extensions/Deployment/specials/SpecialDashboard.php (added) (history)
  • /trunk/extensions/Deployment/specials/SpecialExtensions.php (added) (history)
  • /trunk/extensions/Deployment/specials/SpecialInstall.php (added) (history)
  • /trunk/extensions/Deployment/specials/SpecialUpdate.php (added) (history)
  • /trunk/extensions/Deployment/tests (added) (history)

Diff [purge]

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

Comments

#Comment by 😂 (talk | contribs)   13:14, 28 June 2010

Didn't look at this in detail, but class "Installer" will conflict with MediaWiki core.

#Comment by Jeroen De Dauw (talk | contribs)   13:17, 28 June 2010

I'll rename it to DeployInstaller or something similar for now then.

#Comment by Jeroen De Dauw (talk | contribs)   13:20, 28 June 2010

Done in 68659

Status & tagging log