From 7006e76e11388a398f07adc6cb85d816a4eb2fec Mon Sep 17 00:00:00 2001 From: Megan Watson Date: Fri, 4 Jan 2008 11:30:20 +0000 Subject: [PATCH] KTS-2613 "Bulk import from archive file should support common compression systems such as rar, tar" Fixed. Added the pear library file archive to take care of additional compression formats. --- lib/import/zipimportstorage.inc.php | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- plugins/ktcore/folder/BulkUpload.php | 20 +++++++++----------- thirdparty/pear/File/Archive.php | 1403 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate.php | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/And.php | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/Current.php | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/Custom.php | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/Duplicate.php | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/Ereg.php | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/Eregi.php | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/Extension.php | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/False.php | 47 +++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/Index.php | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/MIME.php | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/MaxDepth.php | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/MinSize.php | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/MinTime.php | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/Not.php | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/Or.php | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Predicate/True.php | 45 +++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader.php | 416 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Ar.php | 387 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Archive.php | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Bzip2.php | 254 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Cache.php | 262 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/ChangeName.php | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Concat.php | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Directory.php | 220 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/File.php | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Filter.php | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Gzip.php | 276 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Memory.php | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/MimeList.php | 939 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Multi.php | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Relay.php | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Select.php | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Tar.php | 355 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Uncompress.php | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Reader/Zip.php | 493 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer.php | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/AddBaseName.php | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/Ar.php | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/Archive.php | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/Bzip2.php | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/Files.php | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/Gzip.php | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/Mail.php | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/Memory.php | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/MemoryArchive.php | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/Multi.php | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/Output.php | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/Tar.php | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/UniqueAppender.php | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/File/Archive/Writer/Zip.php | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/MIME/Type.php | 395 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ thirdparty/pear/MIME/Type/Parameter.php | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 56 files changed, 10970 insertions(+), 42 deletions(-) create mode 100644 thirdparty/pear/File/Archive.php create mode 100644 thirdparty/pear/File/Archive/Predicate.php create mode 100644 thirdparty/pear/File/Archive/Predicate/And.php create mode 100644 thirdparty/pear/File/Archive/Predicate/Current.php create mode 100644 thirdparty/pear/File/Archive/Predicate/Custom.php create mode 100644 thirdparty/pear/File/Archive/Predicate/Duplicate.php create mode 100644 thirdparty/pear/File/Archive/Predicate/Ereg.php create mode 100644 thirdparty/pear/File/Archive/Predicate/Eregi.php create mode 100644 thirdparty/pear/File/Archive/Predicate/Extension.php create mode 100644 thirdparty/pear/File/Archive/Predicate/False.php create mode 100644 thirdparty/pear/File/Archive/Predicate/Index.php create mode 100644 thirdparty/pear/File/Archive/Predicate/MIME.php create mode 100644 thirdparty/pear/File/Archive/Predicate/MaxDepth.php create mode 100644 thirdparty/pear/File/Archive/Predicate/MinSize.php create mode 100644 thirdparty/pear/File/Archive/Predicate/MinTime.php create mode 100644 thirdparty/pear/File/Archive/Predicate/Not.php create mode 100644 thirdparty/pear/File/Archive/Predicate/Or.php create mode 100644 thirdparty/pear/File/Archive/Predicate/True.php create mode 100644 thirdparty/pear/File/Archive/Reader.php create mode 100644 thirdparty/pear/File/Archive/Reader/Ar.php create mode 100644 thirdparty/pear/File/Archive/Reader/Archive.php create mode 100644 thirdparty/pear/File/Archive/Reader/Bzip2.php create mode 100644 thirdparty/pear/File/Archive/Reader/Cache.php create mode 100644 thirdparty/pear/File/Archive/Reader/ChangeName.php create mode 100644 thirdparty/pear/File/Archive/Reader/Concat.php create mode 100644 thirdparty/pear/File/Archive/Reader/Directory.php create mode 100644 thirdparty/pear/File/Archive/Reader/File.php create mode 100644 thirdparty/pear/File/Archive/Reader/Filter.php create mode 100644 thirdparty/pear/File/Archive/Reader/Gzip.php create mode 100644 thirdparty/pear/File/Archive/Reader/Memory.php create mode 100644 thirdparty/pear/File/Archive/Reader/MimeList.php create mode 100644 thirdparty/pear/File/Archive/Reader/Multi.php create mode 100644 thirdparty/pear/File/Archive/Reader/Relay.php create mode 100644 thirdparty/pear/File/Archive/Reader/Select.php create mode 100644 thirdparty/pear/File/Archive/Reader/Tar.php create mode 100644 thirdparty/pear/File/Archive/Reader/Uncompress.php create mode 100644 thirdparty/pear/File/Archive/Reader/Zip.php create mode 100644 thirdparty/pear/File/Archive/Writer.php create mode 100644 thirdparty/pear/File/Archive/Writer/AddBaseName.php create mode 100644 thirdparty/pear/File/Archive/Writer/Ar.php create mode 100644 thirdparty/pear/File/Archive/Writer/Archive.php create mode 100644 thirdparty/pear/File/Archive/Writer/Bzip2.php create mode 100644 thirdparty/pear/File/Archive/Writer/Files.php create mode 100644 thirdparty/pear/File/Archive/Writer/Gzip.php create mode 100644 thirdparty/pear/File/Archive/Writer/Mail.php create mode 100644 thirdparty/pear/File/Archive/Writer/Memory.php create mode 100644 thirdparty/pear/File/Archive/Writer/MemoryArchive.php create mode 100644 thirdparty/pear/File/Archive/Writer/Multi.php create mode 100644 thirdparty/pear/File/Archive/Writer/Output.php create mode 100644 thirdparty/pear/File/Archive/Writer/Tar.php create mode 100644 thirdparty/pear/File/Archive/Writer/UniqueAppender.php create mode 100644 thirdparty/pear/File/Archive/Writer/Zip.php create mode 100644 thirdparty/pear/MIME/Type.php create mode 100644 thirdparty/pear/MIME/Type/Parameter.php diff --git a/lib/import/zipimportstorage.inc.php b/lib/import/zipimportstorage.inc.php index 7844cc0..073f356 100644 --- a/lib/import/zipimportstorage.inc.php +++ b/lib/import/zipimportstorage.inc.php @@ -7,71 +7,140 @@ * KnowledgeTree Open Source Edition * Document Management Made Simple * Copyright (C) 2004 - 2007 The Jam Warehouse Software (Pty) Limited - * + * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3 as published by the * Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * + * * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com. - * + * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU General Public License version 3. - * + * * In accordance with Section 7(b) of the GNU General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by - * KnowledgeTree" logo and retain the original copyright notice. If the display of the + * KnowledgeTree" logo and retain the original copyright notice. If the display of the * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices - * must display the words "Powered by KnowledgeTree" and retain the original - * copyright notice. + * must display the words "Powered by KnowledgeTree" and retain the original + * copyright notice. * Contributor( s): ______________________________________ */ require_once(KT_LIB_DIR . '/filelike/fsfilelike.inc.php'); require_once(KT_LIB_DIR . '/import/fsimportstorage.inc.php'); +require_once('File/Archive.php'); + class KTZipImportStorage extends KTFSImportStorage { - function KTZipImportStorage($sZipPath) { - $this->sZipPath = $sZipPath; + + /** + * The archive extension. + * @var string + */ + var $sExtension = 'zip'; + + var $sZipPath = ''; + + var $sBasePath = ''; + + var $aFile = array(); + + var $allowed_extensions = array('tgz', 'tar', 'gz', 'gzip', 'zip', 'deb', 'ar'); + + function KTZipImportStorage($sFilesName) { + $this->aFile = $_FILES[$sFilesName]; + $this->sZipPath = $this->aFile['tmp_name']; + + // Check the bzip2 lib functions are available + if(function_exists('bzopen')){ + $this->allowed_extensions = array_merge($this->allowed_extensions, array('bz2', 'bzip2', 'tbz')); + } + } + + function CheckFormat(){ + // Get the file extension + $aFilename = explode('.', $this->aFile['name']); + $cnt = count($aFilename); + $sExtension = $aFilename[$cnt - 1]; + + // check if its in the list of supported extensions + if(!in_array($sExtension, $this->allowed_extensions)){ + return false; + } + + $this->sExtension = (!empty($sExtension)) ? $sExtension : 'zip'; + + // Check if the archive is a .tar.gz or .tar.bz, etc + if($cnt > 2){ + if($aFilename[$cnt-2] == 'tar'){ + switch($this->sExtension){ + case 'gz': + $this->sExtension = 'tgz'; + break; + case 'bz2': + $this->sExtension = 'tbz'; + break; + } + } + } + + return true; + } + + function getFormats(){ + return implode(', ', $this->allowed_extensions); } function init() { $oKTConfig =& KTConfig::getSingleton(); - $sBasedir = $oKTConfig->get("urls/tmpDirectory"); - - $sTmpPath = tempnam($sBasedir, 'zipimportstorage'); + $sBasedir = $oKTConfig->get("urls/tmpDirectory"); + + $sTmpPath = tempnam($sBasedir, 'archiveimportstorage'); if ($sTmpPath === false) { - return PEAR::raiseError(_kt("Could not create temporary directory for zip storage")); + return PEAR::raiseError(_kt("Could not create temporary directory for archive storage")); } if (!file_exists($this->sZipPath)) { - return PEAR::raiseError(_kt("Zip file given does not exist")); + return PEAR::raiseError(_kt("Archive file given does not exist")); } unlink($sTmpPath); mkdir($sTmpPath, 0700); $this->sBasePath = $sTmpPath; - $sUnzipCommand = KTUtil::findCommand("import/unzip", "unzip"); - if (empty($sUnzipCommand)) { - return PEAR::raiseError(_kt("unzip command not found on system")); - } - $aArgs = array( - $sUnzipCommand, - "-q", "-n", - "-d", $sTmpPath, - $this->sZipPath, - ); - $aRes = KTUtil::pexec($aArgs); - - if ($aRes['ret'] !== 0) { - return PEAR::raiseError(_kt("Could not retrieve contents from zip storage")); + + // File Archive doesn't unzip properly so sticking to the original unzip functionality + if($this->sExtension == 'zip'){ + // ** Original zip functionality + $sUnzipCommand = KTUtil::findCommand("import/unzip", "unzip"); + if (empty($sUnzipCommand)) { + return PEAR::raiseError(_kt("unzip command not found on system")); + } + $aArgs = array( + $sUnzipCommand, + "-q", "-n", + "-d", $sTmpPath, + $this->sZipPath, + ); + $aRes = KTUtil::pexec($aArgs); + + if ($aRes['ret'] !== 0) { + return PEAR::raiseError(_kt("Could not retrieve contents from zip storage")); + } + }else{ + File_Archive::extract( + File_Archive::readArchive( + $this->sExtension, File_Archive::readUploadedFile('file') + ), + $dst = $sTmpPath + ); } } @@ -83,4 +152,4 @@ class KTZipImportStorage extends KTFSImportStorage { } } -?> +?> \ No newline at end of file diff --git a/plugins/ktcore/folder/BulkUpload.php b/plugins/ktcore/folder/BulkUpload.php index 18839d5..e95dd6f 100644 --- a/plugins/ktcore/folder/BulkUpload.php +++ b/plugins/ktcore/folder/BulkUpload.php @@ -115,16 +115,6 @@ class KTBulkUploadFolderAction extends KTFolderAction { unset($aErrorOptions['message']); $aFile = $this->oValidator->validateFile($_FILES['file'], $aErrorOptions); - // Ensure file is a zip file - $sMime = $aFile['type']; - $pos = strpos($sMime, 'x-zip-compressed'); - $pos2 = strpos($sMime, 'application/zip'); - if($pos === false && $pos2 === false){ - $this->addErrorMessage(_kt("Bulk Upload failed: File is not a zip file.")); - controllerRedirect("browse", 'fFolderId=' . $this->oFolder->getID()); - exit(0); - } - $matches = array(); $aFields = array(); foreach ($_REQUEST as $k => $v) { @@ -138,7 +128,14 @@ class KTBulkUploadFolderAction extends KTFolderAction { 'metadata' => $aFields, ); - $fs =& new KTZipImportStorage($aFile['tmp_name']); + $fs =& new KTZipImportStorage('file'); + if(!$fs->CheckFormat()){ + $sFormats = $fs->getFormats(); + $this->addErrorMessage(_kt("Bulk Upload failed. Archive is not an accepted format. Accepted formats are: ".$sFormats)); + controllerRedirect("browse", 'fFolderId=' . $this->oFolder->getID()); + exit; + } + $bm =& new KTBulkImportManager($this->oFolder, $fs, $this->oUser, $aOptions); $this->startTransaction(); $res = $bm->import(); @@ -152,3 +149,4 @@ class KTBulkUploadFolderAction extends KTFolderAction { exit(0); } } +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive.php b/thirdparty/pear/File/Archive.php new file mode 100644 index 0000000..b3a5f95 --- /dev/null +++ b/thirdparty/pear/File/Archive.php @@ -0,0 +1,1403 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Archive.php,v 1.85 2005/08/16 08:48:59 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +/** + * To have access to PEAR::isError and PEAR::raiseError + * We should probably use lazy include and remove this inclusion... + */ +require_once "PEAR.php"; + +function File_Archive_cleanCache($file, $group) +{ + $file = split('_', $file); + if (count($file) != 3) { + return false; //not a File_Archive file, keep it + } + + $name = $file[2]; + $name = urldecode($name); + + $group = $file[1]; + + //clean the cache only for files in File_Archive groups + return substr($group, 0, 11) == 'FileArchive' && + !file_exists($name); //and only if the related file no longer exists +} + +/** + * Factory to access the most common File_Archive features + * It uses lazy include, so you dont have to include the files from + * File/Archive/* directories + */ +class File_Archive +{ + function& _option($name) + { + static $container = array( + 'zipCompressionLevel' => 9, + 'gzCompressionLevel' => 9, + 'tmpDirectory' => '.', + 'cache' => null, + 'appendRemoveDuplicates' => false, + 'blockSize' => 65536, + 'cacheCondition' => false + ); + return $container[$name]; + } + /** + * Sets an option that will be used by default by all readers or writers + * Option names are case sensitive + * Currently, the following options are used: + * + * "cache" + * Instance of a Cache_Lite object used to cache some compressed + * data to speed up future compressions of files + * Default: null (no cache used) + * + * "zipCompressionLevel" + * Value between 0 and 9 specifying the default compression level used + * by Zip writers (0 no compression, 9 highest compression) + * Default: 9 + * + * "gzCompressionLevel" + * Value between 0 and 9 specifying the default compression level used + * by Gz writers (0 no compression, 9 highest compression) + * Default: 9 + * + * "tmpDirectory" + * Directory where the temporary files generated by File_Archive will + * be created + * Default: '.' + * + * "appendRemoveDuplicates" + * If set to true, the appender created will by default remove the + * file present in the archive when adding a new one. This will slow the + * appending of files to archives + * Default: false + * + * "blockSize" + * To transfer data from a reader to a writer, some chunks a read from the + * source and written to the writer. This parameter controls the size of the + * chunks + * Default: 64kB + * + * "cacheCondition" + * This parameter specifies when a cache should be used. When the cache is + * used, the data of the reader is saved in a temporary file for future access. + * The cached reader will be read only once, even if you read it several times. + * This can be usefull to read compressed files or downloaded files (from http or ftp) + * The possible values for this option are + * - false: never use cache + * - a regexp: A cache will be used if the specified URL matches the regexp + * preg_match is used + * Default: false + * Example: '/^(http|ftp):\/\//' will cache all files downloaded via http or ftp + * + */ + function setOption($name, $value) + { + $option =& File_Archive::_option($name); + $option = $value; + if ($name == 'cache' && $value !== null) { + //TODO: ask to Cache_Lite to allow that + $value->_fileNameProtection = false; + } + } + + /** + * Retrieve the value of an option + */ + function getOption($name) + { + return File_Archive::_option($name); + } + + /** + * Create a reader to read the URL $URL. + * If the URL is a directory, it will recursively read that directory. + * If $uncompressionLevel is not null, the archives (files with extension + * tar, zip, gz or tgz) will be considered as directories (up to a depth of + * $uncompressionLevel if $uncompressionLevel > 0). The reader will only + * read files with a directory depth of $directoryDepth. It reader will + * replace the given URL ($URL) with $symbolic in the public filenames + * The default symbolic name is the last filename in the URL (or '' for + * directories) + * + * Examples: + * Considere the following file system + *
+     * a.txt
+     * b.tar (archive that contains the following files)
+     *     c.txt
+     *     d.tgz (archive that contains the following files)
+     *         e.txt
+     *         dir1/
+     *             f.txt
+     * dir2/
+     *     g.txt
+     *     dir3/
+     *         h.tar (archive that contains the following files)
+     *             i.txt
+     * 
+ * + * read('.') will return a reader that gives access to following + * files (recursively read current dir): + *
+     * a.txt
+     * b.tar
+     * dir2/g.txt
+     * dir2/dir3/h.tar
+     * 
+ * + * read('.', 'myBaseDir') will return the following reader: + *
+     * myBaseDir/a.txt
+     * myBaseDir/b.tar
+     * myBaseDir/dir2/g.txt
+     * myBaseDir/dir2/dir3/h.tar
+     * 
+ * + * read('.', '', -1) will return the following reader (uncompress + * everything) + *
+     * a.txt
+     * b.tar/c.txt
+     * b.tar/d.tgz/e.txt
+     * b.tar/d.tgz/dir1/f.txt
+     * dir2/g.txt
+     * dir2/dir3/h.tar/i.txt
+     * 
+ * + * read('.', '', 1) will uncompress only one level (so d.tgz will + * not be uncompressed): + *
+     * a.txt
+     * b.tar/c.txt
+     * b.tar/d.tgz
+     * dir2/g.txt
+     * dir2/dir3/h.tar/i.txt
+     * 
+ * + * read('.', '', 0, 0) will not recurse into subdirectories + *
+     * a.txt
+     * b.tar
+     * 
+ * + * read('.', '', 0, 1) will recurse only one level in + * subdirectories + *
+     * a.txt
+     * b.tar
+     * dir2/g.txt
+     * 
+ * + * read('.', '', -1, 2) will uncompress everything and recurse in + * only 2 levels in subdirectories or archives + *
+     * a.txt
+     * b.tar/c.txt
+     * b.tar/d.tgz/e.txt
+     * dir2/g.txt
+     * 
+ * + * The recursion level is determined by the real path, not the symbolic one. + * So read('.', 'myBaseDir', -1, 2) will result to the same files: + *
+     * myBaseDir/a.txt
+     * myBaseDir/b.tar/c.txt
+     * myBaseDir/b.tar/d.tgz/e.txt (accepted because the real depth is 2)
+     * myBaseDir/dir2/g.txt
+     * 
+ * + * Use readSource to do the same thing, reading from a specified reader instead of + * reading from the system files + * + * To read a single file, you can do read('a.txt', 'public_name.txt') + * If no public name is provided, the default one is the name of the file + * read('dir2/g.txt') contains the single file named 'g.txt' + * read('b.tar/c.txt') contains the single file named 'c.txt' + * + * Note: This function uncompress files reading their extension + * The compressed files must have a tar, zip, gz or tgz extension + * Since it is impossible for some URLs to use is_dir or is_file, this + * function may not work with + * URLs containing folders which name ends with such an extension + */ + function readSource(&$source, $URL, $symbolic = null, + $uncompression = 0, $directoryDepth = -1) + { + return File_Archive::_readSource($source, $URL, $reachable, $baseDir, + $symbolic, $uncompression, $directoryDepth); + } + + /** + * This function performs exactly as readSource, but with two additional parameters + * ($reachable and $baseDir) that will be set so that $reachable."/".$baseDir == $URL + * and $reachable can be reached (in case of error) + * + * @access private + */ + function _readSource(&$toConvert, $URL, &$reachable, &$baseDir, $symbolic = null, + $uncompression = 0, $directoryDepth = -1) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + if (is_array($URL)) { + $converted = array(); + foreach($URL as $key => $foo) { + $converted[] =& File_Archive::_convertToReader($URL[$key]); + } + return File_Archive::readMulti($converted); + } + + //No need to uncompress more than $directoryDepth + //That's not perfect, and some archives will still be uncompressed just + //to be filtered out :( + if ($directoryDepth >= 0) { + $uncompressionLevel = min($uncompression, $directoryDepth); + } else { + $uncompressionLevel = $uncompression; + } + + require_once 'File/Archive/Reader.php'; + $std = File_Archive_Reader::getStandardURL($URL); + + //Modify the symbolic name if necessary + $slashPos = strrpos($std, '/'); + if ($symbolic === null) { + if ($slashPos === false) { + $realSymbolic = $std; + } else { + $realSymbolic = substr($std, $slashPos+1); + } + } else { + $realSymbolic = $symbolic; + } + if ($slashPos !== false) { + $baseFile = substr($std, 0, $slashPos+1); + $lastFile = substr($std, $slashPos+1); + } else { + $baseFile = ''; + $lastFile = $std; + } + + if (strpos($lastFile, '*')!==false || + strpos($lastFile, '?')!==false) { + //We have to build a regexp here + $regexp = str_replace( + array('\*', '\?'), + array('[^/]*', '[^/]'), + preg_quote($lastFile) + ); + $result = File_Archive::_readSource($source, $baseFile, + $reachable, $baseDir, null, 0, -1); + return File_Archive::filter( + File_Archive::predEreg('^'.$regexp.'$'), + $result + ); + } + + //If the URL can be interpreted as a directory, and we are reading from the file system + if ((empty($URL) || is_dir($URL)) && $source === null) { + require_once "File/Archive/Reader/Directory.php"; + require_once "File/Archive/Reader/ChangeName.php"; + + if ($uncompressionLevel != 0) { + require_once "File/Archive/Reader/Uncompress.php"; + $result = new File_Archive_Reader_Uncompress( + new File_Archive_Reader_Directory($std, '', $directoryDepth), + $uncompressionLevel + ); + } else { + $result = new File_Archive_Reader_Directory($std, '', $directoryDepth); + } + + if ($directoryDepth >= 0) { + require_once 'File/Archive/Reader/Filter.php'; + require_once 'File/Archive/Predicate/MaxDepth.php'; + + $tmp =& File_Archive::filter( + new File_Archive_Predicate_MaxDepth($directoryDepth), + $result + ); + unset($result); + $result =& $tmp; + } + if (!empty($realSymbolic)) { + if ($symbolic === null) { + $realSymbolic = ''; + } + $tmp =& new File_Archive_Reader_AddBaseName( + $realSymbolic, + $result + ); + unset($result); + $result =& $tmp; + } + + //If the URL can be interpreted as a file, and we are reading from the file system + } else if (is_file($URL) && substr($URL, -1)!='/' && $source === null) { + require_once "File/Archive/Reader/File.php"; + $result = new File_Archive_Reader_File($URL, $realSymbolic); + + //Else, we will have to build a complex reader + } else { + require_once "File/Archive/Reader/File.php"; + + $realPath = $std; + + // Try to find a file with a known extension in the path ( + // (to manage URLs like archive.tar/directory/file) + $pos = 0; + do { + if ($pos+1setBaseDir($std); + if (PEAR::isError($isDir)) { + return $isDir; + } + if ($isDir && $symbolic==null) { + //Default symbolic name for directories is empty + $realSymbolic = ''; + } + + if ($directoryDepth >= 0) { + //Limit the maximum depth if necessary + require_once "File/Archive/Predicate/MaxDepth.php"; + + $tmp = new File_Archive_Reader_Filter( + new File_Archive_Predicate( + $directoryDepth + + substr_count(substr($std, $pos+1), '/') + ), + $result + ); + unset($result); + $result =& $tmp; + } + + if ($std != $realSymbolic) { + require_once "File/Archive/Reader/ChangeName.php"; + + //Change the base name to the symbolic one if necessary + $tmp = new File_Archive_Reader_ChangeBaseName( + $std, + $realSymbolic, + $result + ); + unset($result); + $result =& $tmp; + } + } + + $cacheCondition = File_Archive::getOption('cacheCondition'); + if ($cacheCondition !== false && + preg_match($cacheCondition, $URL)) { + $tmp =& File_Archive::cache($result); + unset($result); + $result =& $tmp; + } + + return $result; + } + function read($URL, $symbolic = null, + $uncompression = 0, $directoryDepth = -1) + { + $source = null; + return File_Archive::readSource($source, $URL, $symbolic, $uncompression, $directoryDepth); + } + + /** + * Create a file reader on an uploaded file. The reader will read + * $_FILES[$name]['tmp_name'] and will have $_FILES[$name]['name'] + * as a symbolic filename. + * + * A PEAR error is returned if one of the following happen + * - $_FILES[$name] is not set + * - $_FILES[$name]['error'] is not 0 + * - is_uploaded_file returns false + * + * @param string $name Index of the file in the $_FILES array + * @return File_Archive_Reader File reader on the uploaded file + */ + function readUploadedFile($name) + { + if (!isset($_FILES[$name])) { + return PEAR::raiseError("File $name has not been uploaded"); + } + switch ($_FILES[$name]['error']) { + case 0: + //No error + break; + case 1: + return PEAR::raiseError( + "The upload size limit didn't allow to upload file ". + $_FILES[$name]['name'] + ); + case 2: + return PEAR::raiseError( + "The form size limit didn't allow to upload file ". + $_FILES[$name]['name'] + ); + case 3: + return PEAR::raiseError( + "The file was not entirely uploaded" + ); + case 4: + return PEAR::raiseError( + "The uploaded file is empty" + ); + default: + return PEAR::raiseError( + "Unknown error ".$_FILES[$name]['error']." in file upload. ". + "Please, report a bug" + ); + } + if (!is_uploaded_file($_FILES[$name]['tmp_name'])) { + return PEAR::raiseError("The file is not an uploaded file"); + } + + require_once "File/Archive/Reader/File.php"; + return new File_Archive_Reader_File( + $_FILES[$name]['tmp_name'], + $_FILES[$name]['name'], + $_FILES[$name]['type'] + ); + } + + /** + * Adds a cache layer above the specified reader + * The data of the reader is saved in a temporary file for future access. + * The cached reader will be read only once, even if you read it several times. + * This can be usefull to read compressed files or downloaded files (from http or ftp) + * + * @param mixed $toConvert The reader to cache + * It can be a File_Archive_Reader or a string, which will be converted using the + * read function + */ + function cache(&$toConvert) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + + require_once 'File/Archive/Reader/Cache.php'; + return new File_Archive_Reader_Cache($source); + } + + /** + * Try to interpret the object as a reader + * Strings are converted to readers using File_Archive::read + * Arrays are converted to readers using File_Archive::readMulti + * + * @access private + */ + function &_convertToReader(&$source) + { + if (is_string($source)) { + $cacheCondition = File_Archive::getOption('cacheCondition'); + if ($cacheCondition !== false && + preg_match($cacheCondition, $source)) { + return File_Archive::cache(File_Archive::read($source)); + } else { + return File_Archive::read($source); + } + } else if (is_array($source)) { + return File_Archive::readMulti($source); + } else { + return $source; + } + } + + /** + * Try to interpret the object as a writer + * Strings are converted to writers using File_Archive::appender + * Arrays are converted to writers using a multi writer + * + * @access private + */ + function &_convertToWriter(&$dest) + { + if (is_string($dest)) { + return File_Archive::appender($dest); + } else if (is_array($dest)) { + require_once 'File/Archive/Writer/Multi.php'; + $writer = new File_Archive_Writer_Multi(); + foreach($dest as $key => $foo) { + $writer->addWriter($dest[$key]); + } + } else { + return $dest; + } + } + + /** + * Check if a file with a specific extension can be read as an archive + * with File_Archive::read* + * This function is case sensitive. + * + * @param string $extension the checked extension + * @return bool whether this file can be understood reading its extension + * Currently, supported extensions are tar, zip, gz, tgz, tbz, bz2, + * bzip2, ar, deb + */ + function isKnownExtension($extension) + { + return $extension == 'tar' || + $extension == 'zip' || + $extension == 'gz' || + $extension == 'tgz' || + $extension == 'tbz' || + $extension == 'bz2' || + $extension == 'bzip2' || + $extension == 'ar' || + $extension == 'deb' /* || + $extension == 'cab' || + $extension == 'rar' */; + } + + /** + * Create a reader that will read the single file source $source as + * a specific archive + * + * @param string $extension determines the kind of archive $source contains + * $extension is case sensitive + * @param File_Archive_Reader $source stores the archive + * @param bool $sourceOpened specifies if the archive is already opened + * if false, next will be called on source + * Closing the returned archive will close $source iif $sourceOpened + * is true + * @return A File_Archive_Reader that uncompresses the archive contained in + * $source interpreting it as a $extension archive + * If $extension is not handled return false + */ + function readArchive($extension, &$toConvert, $sourceOpened = false) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + + switch($extension) { + case 'tgz': + return File_Archive::readArchive('tar', + File_Archive::readArchive('gz', $source, $sourceOpened) + ); + case 'tbz': + return File_Archive::readArchive('tar', + File_Archive::readArchive('bz2', $source, $sourceOpened) + ); + case 'tar': + require_once 'File/Archive/Reader/Tar.php'; + return new File_Archive_Reader_Tar($source, $sourceOpened); + + case 'gz': + case 'gzip': + require_once 'File/Archive/Reader/Gzip.php'; + return new File_Archive_Reader_Gzip($source, $sourceOpened); + + case 'zip': + require_once 'File/Archive/Reader/Zip.php'; + return new File_Archive_Reader_Zip($source, $sourceOpened); + + case 'bz2': + case 'bzip2': + require_once 'File/Archive/Reader/Bzip2.php'; + return new File_Archive_Reader_Bzip2($source, $sourceOpened); + + case 'deb': + case 'ar': + require_once 'File/Archive/Reader/Ar.php'; + return new File_Archive_Reader_Ar($source, $sourceOpened); + +/* case 'cab': + require_once 'File/Archive/Reader/Cab.php'; + return new File_Archive_Reader_Cab($source, $sourceOpened); + + + case 'rar': + require_once "File/Archive/Reader/Rar.php"; + return new File_Archive_Reader_Rar($source, $sourceOpened); */ + + default: + return false; + } + } + + /** + * Contains only one file with data read from a memory buffer + * + * @param string $memory content of the file + * @param string $filename public name of the file + * @param array $stat statistics of the file. Index 7 (size) will be + * overwritten to match the size of $memory + * @param string $mime mime type of the file. Default will determine the + * mime type thanks to the extension of $filename + * @see File_Archive_Reader_Memory + */ + function readMemory($memory, $filename, $stat=array(), $mime=null) + { + require_once "File/Archive/Reader/Memory.php"; + return new File_Archive_Reader_Memory($memory, $filename, $stat, $mime); + } + + /** + * Contains several other sources. Take care the sources don't have several + * files with the same filename. The sources are given as a parameter, or + * can be added thanks to the reader addSource method + * + * @param array $sources Array of strings or readers that will be added to + * the multi reader. If the parameter is a string, a reader will be + * built thanks to the read function + * @see File_Archive_Reader_Multi, File_Archive::read() + */ + function readMulti($sources = array()) + { + require_once "File/Archive/Reader/Multi.php"; + $result = new File_Archive_Reader_Multi(); + foreach ($sources as $index => $foo) { + $s =& File_Archive::_convertToReader($sources[$index]); + if (PEAR::isError($s)) { + return $s; + } else { + $result->addSource($s); + } + } + return $result; + } + /** + * Make the files of a source appear as one large file whose content is the + * concatenation of the content of all the files + * + * @param File_Archive_Reader $source The source whose files must be + * concatened + * @param string $filename name of the only file of the created reader + * @param array $stat statistics of the file. Index 7 (size) will be + * overwritten to match the total size of the files + * @param string $mime mime type of the file. Default will determine the + * mime type thanks to the extension of $filename + * @see File_Archive_Reader_Concat + */ + function readConcat(&$toConvert, $filename, $stat=array(), $mime=null) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + + require_once "File/Archive/Reader/Concat.php"; + return new File_Archive_Reader_Concat($source, $filename, $stat, $mime); + } + + /** + * Removes from a source the files that do not follow a given predicat + * + * @param File_Archive_Predicate $predicate Only the files for which + * $predicate->isTrue() will be kept + * @param File_Archive_Reader $source Source that will be filtered + * @see File_Archive_Reader_Filter + */ + function filter($predicate, &$toConvert) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + + require_once "File/Archive/Reader/Filter.php"; + return new File_Archive_Reader_Filter($predicate, $source); + } + /** + * Predicate that always evaluate to true + * + * @see File_Archive_Predicate_True + */ + function predTrue() + { + require_once "File/Archive/Predicate/True.php"; + return new File_Archive_Predicate_True(); + } + /** + * Predicate that always evaluate to false + * + * @see File_Archive_Predicate_False + */ + function predFalse() + { + require_once "File/Archive/Predicate/False.php"; + return new File_Archive_Predicate_False(); + } + /** + * Predicate that evaluates to the logical AND of the parameters + * You can add other predicates thanks to the + * File_Archive_Predicate_And::addPredicate() function + * + * @param File_Archive_Predicate (any number of them) + * @see File_Archive_Predicate_And + */ + function predAnd() + { + require_once "File/Archive/Predicate/And.php"; + $pred = new File_Archive_Predicate_And(); + $args = func_get_args(); + foreach ($args as $p) { + $pred->addPredicate($p); + } + return $pred; + } + /** + * Predicate that evaluates to the logical OR of the parameters + * You can add other predicates thanks to the + * File_Archive_Predicate_Or::addPredicate() function + * + * @param File_Archive_Predicate (any number of them) + * @see File_Archive_Predicate_Or + */ + function predOr() + { + require_once "File/Archive/Predicate/Or.php"; + $pred = new File_Archive_Predicate_Or(); + $args = func_get_args(); + foreach ($args as $p) { + $pred->addPredicate($p); + } + return $pred; + } + /** + * Negate a predicate + * + * @param File_Archive_Predicate $pred Predicate to negate + * @see File_Archive_Predicate_Not + */ + function predNot($pred) + { + require_once "File/Archive/Predicate/Not.php"; + return new File_Archive_Predicate_Not($pred); + } + /** + * Evaluates to true iif the file is larger than a given size + * + * @param int $size the minimal size of the files (in Bytes) + * @see File_Archive_Predicate_MinSize + */ + function predMinSize($size) + { + require_once "File/Archive/Predicate/MinSize.php"; + return new File_Archive_Predicate_MinSize($size); + } + /** + * Evaluates to true iif the file has been modified after a given time + * + * @param int $time Unix timestamp of the minimal modification time of the + * files + * @see File_Archive_Predicate_MinTime + */ + function predMinTime($time) + { + require_once "File/Archive/Predicate/MinTime.php"; + return new File_Archive_Predicate_MinTime($time); + } + /** + * Evaluates to true iif the file has less that a given number of + * directories in its path + * + * @param int $depth Maximal number of directories in path of the files + * @see File_Archive_Predicate_MaxDepth + */ + function predMaxDepth($depth) + { + require_once "File/Archive/Predicate/MaxDepth.php"; + return new File_Archive_Predicate_MaxDepth($depth); + } + /** + * Evaluates to true iif the extension of the file is in a given list + * + * @param array or string $list List or comma separated string of possible + * extension of the files + * @see File_Archive_Predicate_Extension + */ + function predExtension($list) + { + require_once "File/Archive/Predicate/Extension.php"; + return new File_Archive_Predicate_Extension($list); + } + /** + * Evaluates to true iif the MIME type of the file is in a given list + * + * @param array or string $list List or comma separated string of possible + * MIME types of the files. You may enter wildcards like "image/*" to + * select all the MIME in class image + * @see File_Archive_Predicate_MIME, MIME_Type::isWildcard() + */ + function predMIME($list) + { + require_once "File/Archive/Predicate/MIME.php"; + return new File_Archive_Predicate_MIME($list); + } + /** + * Evaluates to true iif the name of the file follow a given regular + * expression + * + * @param string $ereg regular expression that the filename must follow + * @see File_Archive_Predicate_Ereg, ereg() + */ + function predEreg($ereg) + { + require_once "File/Archive/Predicate/Ereg.php"; + return new File_Archive_Predicate_Ereg($ereg); + } + /** + * Evaluates to true iif the name of the file follow a given regular + * expression (case insensitive version) + * + * @param string $ereg regular expression that the filename must follow + * @see File_Archive_Predicate_Eregi, eregi + */ + function predEregi($ereg) + { + require_once "File/Archive/Predicate/Eregi.php"; + return new File_Archive_Predicate_Eregi($ereg); + } + /** + * Evaluates to true only after a given number of evaluations + * This can be used to select files by index since the evaluation is done + * once per file + * + * @param array The indexes for which the returned predicate will return true + * are the keys of the array + * The predicate will return true if isset($indexes[$pos]) + */ + function predIndex($indexes) + { + require_once "File/Archive/Predicate/Index.php"; + return new File_Archive_Predicate_Index($indexes); + } + /** + * Custom predicate built by supplying a string expression + * + * Here are different ways to create a predicate that keeps only files + * with names shorter than 100 chars + * + * File_Archive::predCustom("return strlen($name)<100;") + * File_Archive::predCustom("strlen($name)<100;") + * File_Archive::predCustom("strlen($name)<100") + * File_Archive::predCustom("strlen($source->getFilename())<100") + * + * + * @param string $expression String containing an expression that evaluates + * to a boolean. If the expression doesn't contain a return + * statement, it will be added at the begining of the expression + * A ';' will be added at the end of the expression so that you don't + * have to write it. You may use the $name variable to refer to the + * current filename (with path...), $time for the modification time + * (unix timestamp), $size for the size of the file in bytes, $mime + * for the MIME type of the file + * @see File_Archive_Predicate_Custom + */ + function predCustom($expression) + { + require_once "File/Archive/Predicate/Custom.php"; + return new File_Archive_Predicate_Custom($expression); + } + + /** + * Send the files as a mail attachment + * + * @param Mail $mail Object used to send mail (see Mail::factory) + * @param array or String $to An array or a string with comma separated + * recipients + * @param array $headers The headers that will be passed to the Mail_mime + * object + * @param string $message Text body of the mail + * @see File_Archive_Writer_Mail + */ + function toMail($to, $headers, $message, $mail = null) + { + require_once "File/Archive/Writer/Mail.php"; + return new File_Archive_Writer_Mail($to, $headers, $message, $mail); + } + /** + * Write the files on the hard drive + * + * @param string $baseDir if specified, the files will be created in that + * directory. If they don't exist, the directories will automatically + * be created + * @see File_Archive_Writer_Files + */ + function toFiles($baseDir = "") + { + require_once "File/Archive/Writer/Files.php"; + return new File_Archive_Writer_Files($baseDir); + } + /** + * Send the content of the files to a memory buffer + * + * toMemory returns a writer where the data will be written. + * In this case, the data is accessible using the getData member + * + * toVariable returns a writer that will write into the given + * variable + * + * @param out $data if specified, the data will be written to this buffer + * Else, you can retrieve the buffer with the + * File_Archive_Writer_Memory::getData() function + * @see File_Archive_Writer_Memory + */ + function toMemory() + { + $v = ''; + return File_Archive::toVariable($v); + } + function toVariable(&$v) + { + require_once "File/Archive/Writer/Memory.php"; + return new File_Archive_Writer_Memory($v); + } + /** + * Duplicate the writing operation on two writers + * + * @param File_Archive_Writer $a, $b writers where data will be duplicated + * @see File_Archive_Writer_Multi + */ + function toMulti(&$aC, &$bC) + { + $a =& File_Archive::_convertToWriter($aC); + $b =& File_Archive::_convertToWriter($bC); + + if (PEAR::isError($a)) { + return $a; + } + if (PEAR::isError($b)) { + return $b; + } + + require_once "File/Archive/Writer/Multi.php"; + $writer = new File_Archive_Writer_Multi(); + $writer->addWriter($a); + $writer->addWriter($b); + return $writer; + } + /** + * Send the content of the files to the standard output (so to the client + * for a website) + * + * @param bool $sendHeaders If true some headers will be sent to force the + * download of the file. Default value is true + * @see File_Archive_Writer_Output + */ + function toOutput($sendHeaders = true) + { + require_once "File/Archive/Writer/Output.php"; + return new File_Archive_Writer_Output($sendHeaders); + } + /** + * Compress the data to a tar, gz, tar/gz or zip format + * + * @param string $filename name of the archive file + * @param File_Archive_Writer $innerWriter writer where the archive will be + * written + * @param string $type can be one of tgz, tbz, tar, zip, gz, gzip, bz2, + * bzip2 (default is the extension of $filename) or any composition + * of them (for example tar.gz or tar.bz2). The case of this + * parameter is not important. + * @param array $stat Statistics of the archive (see stat function) + * @param bool $autoClose If set to true, $innerWriter will be closed when + * the returned archive is close. Default value is true. + */ + function toArchive($filename, &$toConvert, $type = null, + $stat = array(), $autoClose = true) + { + $innerWriter =& File_Archive::_convertToWriter($toConvert); + if (PEAR::isError($innerWriter)) { + return $innerWriter; + } + $shortcuts = array("tgz" , "tbz" ); + $reals = array("tar.gz", "tar.bz2"); + + if ($type === null) { + $extensions = strtolower($filename); + } else { + $extensions = strtolower($type); + } + $extensions = explode('.', str_replace($shortcuts, $reals, $extensions)); + if ($innerWriter !== null) { + $writer =& $innerWriter; + } else { + $writer = File_Archive::toFiles(); + } + $nbCompressions = 0; + $currentFilename = $filename; + while (($extension = array_pop($extensions)) !== null) { + unset($next); + switch($extension) { + case "tar": + require_once "File/Archive/Writer/Tar.php"; + $next = new File_Archive_Writer_Tar( + $currentFilename, $writer, $stat, $autoClose + ); + unset($writer); $writer =& $next; + break; + case "zip": + require_once "File/Archive/Writer/Zip.php"; + $next = new File_Archive_Writer_Zip( + $currentFilename, $writer, $stat, $autoClose + ); + unset($writer); $writer =& $next; + break; + case "gz": + case "gzip": + require_once "File/Archive/Writer/Gzip.php"; + $next = new File_Archive_Writer_Gzip( + $currentFilename, $writer, $stat, $autoClose + ); + unset($writer); $writer =& $next; + break; + case "bz2": + case "bzip2": + require_once "File/Archive/Writer/Bzip2.php"; + $next = new File_Archive_Writer_Bzip2( + $currentFilename, $writer, $stat, $autoClose + ); + unset($writer); $writer =& $next; + break; + case "deb": + case "ar": + require_once "File/Archive/Writer/Ar.php"; + $next = new File_Archive_Writer_Ar( + $currentFilename, $writer, $stat, $autoClose + ); + unset($writer); $writer =& $next; + break; + default: + if ($type !== null || $nbCompressions == 0) { + return PEAR::raiseError("Archive $extension unknown"); + } + break; + } + $nbCompressions ++; + $autoClose = true; + $currentFilename = implode(".", $extensions); + } + return $writer; + } + + + /** + * File_Archive::extract($source, $dest) is equivalent to $source->extract($dest) + * If $source is a PEAR error, the error will be returned + * It is thus easier to use this function than $source->extract, since it reduces the number of + * error checking and doesn't force you to define a variable $source + * + * You may use strings as source and dest. In that case the source is automatically + * converted to a reader using File_Archive::read and the dest is converted to a + * writer using File_Archive::appender + * Since PHP doesn't allow to pass literal strings by ref, you will have to use temporary + * variables. + * File_Archive::extract($src = 'archive.zip/', $dest = 'dir') will extract the archive to 'dir' + * It is the same as + * File_Archive::extract( + * File_Archive::read('archive.zip/'), + * File_Archive::appender('dir') + * ); + * You may use any variable in the extract function ($from/$to, $a/$b...). + * + * @param File_Archive_Reader $source The source that will be read + * @param File_Archive_Writer $dest Where to copy $source files + * @param bool $autoClose if true (default), $dest will be closed after the extraction + * @param int $bufferSize Size of the buffer to use to move data from the reader to the buffer + * If $bufferSize <= 0 (default), the blockSize option is used + * You shouldn't need to change that + * @return null or a PEAR error if an error occured + */ + function extract(&$sourceToConvert, &$destToConvert, $autoClose = true, $bufferSize = 0) + { + $source =& File_Archive::_convertToReader($sourceToConvert); + if (PEAR::isError($source)) { + return $source; + } + $dest =& File_Archive::_convertToWriter($destToConvert); + return $source->extract($dest, $autoClose, $bufferSize); + } + + /** + * Create a writer that can be used to append files to an archive inside a source + * If the archive can't be found in the source, it will be created + * If source is set to null, File_Archive::toFiles will be assumed + * If type is set to null, the type of the archive will be determined looking at + * the extension in the URL + * stat is the array of stat (returned by stat() PHP function of Reader getStat()) + * to use if the archive must be created + * + * This function allows to create or append data to nested archives. Only one + * archive will be created and if your creation requires creating several nested + * archives, a PEAR error will be returned + * + * After this call, $source will be closed and should not be used until the + * returned writer is closed. + * + * @param File_Archive_Reader $source A reader where some files will be appended + * @param string $URL URL to reach the archive in the source. + * if $URL is null, a writer to append files to the $source reader will + * be returned + * @param bool $unique If true, the duplicate files will be deleted on close + * Default is false (and setting it to true may have some performance + * consequences) + * @param string $type Extension of the archive (or null to use the one in the URL) + * @param array $stat Used only if archive is created, array of stat as returned + * by PHP stat function or Reader getStat function: stats of the archive) + * Time (index 9) will be overwritten to current time + * @return File_Archive_Writer a writer that you can use to append files to the reader + */ + function appenderFromSource(&$toConvert, $URL = null, $unique = null, + $type = null, $stat = array()) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + if ($unique == null) { + $unique = File_Archive::getOption("appendRemoveDuplicates"); + } + + //Do not report the fact that the archive does not exist as an error + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + + if ($URL === null) { + $result =& $source; + } else { + if ($type === null) { + $result = File_Archive::_readSource($source, $URL.'/', $reachable, $baseDir); + } else { + $result = File_Archive::readArchive( + $type, + File_Archive::_readSource($source, $URL, $reachable, $baseDir) + ); + } + } + + PEAR::popErrorHandling(); + + if (!PEAR::isError($result)) { + if ($unique) { + require_once "File/Archive/Writer/UniqueAppender.php"; + return new File_Archive_Writer_UniqueAppender($result); + } else { + return $result->makeAppendWriter(); + } + } + + //The source can't be found and has to be created + $stat[9] = $stat['mtime'] = time(); + + if (empty($baseDir)) { + if ($source !== null) { + $writer =& $source->makeWriter(); + } else { + $writer =& File_Archive::toFiles(); + } + if (PEAR::isError($writer)) { + return $writer; + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $result = File_Archive::toArchive($reachable, $writer, $type); + PEAR::popErrorHandling(); + + if (PEAR::isError($result)) { + $result = File_Archive::toFiles($reachable); + } + } else { + $reachedSource = File_Archive::readSource($source, $reachable); + if (PEAR::isError($reachedSource)) { + return $reachedSource; + } + $writer = $reachedSource->makeWriter(); + if (PEAR::isError($writer)) { + return $writer; + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $result = File_Archive::toArchive($baseDir, $writer, $type); + PEAR::popErrorHandling(); + + if (PEAR::isError($result)) { + require_once "File/Archive/Writer/AddBaseName.php"; + $result = new File_Archive_Writer_AddBaseName( + $baseDir, $writer); + if (PEAR::isError($result)) { + return $result; + } + } + } + return $result; + } + + /** + * Create a writer that allows appending new files to an existing archive + * This function actes as appendToSource with source being the system files + * $URL can't be null here + * + * @param File_Archive_Reader $source A reader where some files will be appended + * @return File_Archive_Writer a writer that you can use to append files to the reader + */ + function appender($URL, $unique = null, $type = null, $stat = array()) + { + $source = null; + return File_Archive::appenderFromSource($source, $URL, $unique, $type, $stat); + } + + /** + * Remove the files that follow a given predicate from the source + * If URL is null, the files will be removed from the source directly + * Else, URL must link to a source from which the files will be removed + * + * @param File_Archive_Predicate $pred The files that follow the predicate + * (for which $pred->isTrue($source) is true) will be erased + * @param File_Archive_Reader $source A reader that contains the files to remove + */ + function removeFromSource(&$pred, &$toConvert, $URL = null) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + if ($URL === null) { + $result = &$source; + } else { + if (substr($URL, -1) !== '/') { + $URL .= '/'; + } + $result = File_Archive::readSource($source, $URL); + } + + $writer = $result->makeWriterRemoveFiles($pred); + if (PEAR::isError($writer)) { + return $writer; + } + $writer->close(); + } + + /** + * Remove the files that follow a given predicate from the archive specified + * in $URL + * + * @param $URL URL of the archive where some files must be removed + */ + function remove($pred, $URL) + { + $source = null; + return File_Archive::removeFromSource($pred, $source, $URL); + } + + /** + * Remove duplicates from a source, keeping the most recent one (or the one that has highest pos in + * the archive if the files have same date or no date specified) + * + * @param File_Archive_Reader a reader that may contain duplicates + */ + function removeDuplicatesFromSource(&$toConvert, $URL = null) + { + $source =& File_Archive::_convertToReader($toConvert); + if (PEAR::isError($source)) { + return $source; + } + if ($URL !== null && substr($URL, -1) != '/') { + $URL .= '/'; + } + + if ($source === null) { + $source = File_Archive::read($URL); + } + + require_once "File/Archive/Predicate/Duplicate.php"; + $pred = new File_Archive_Predicate_Duplicate($source); + $source->close(); + return File_Archive::removeFromSource( + $pred, + $source, + null + ); + } + + /** + * Remove duplicates from the archive specified in the URL + */ + function removeDuplicates($URL) + { + $source = null; + return File_Archive::removeDuplicatesFromSource($source, $URL); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate.php b/thirdparty/pear/File/Archive/Predicate.php new file mode 100644 index 0000000..437e7c5 --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate.php @@ -0,0 +1,57 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Predicate.php,v 1.7 2005/05/26 21:30:18 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; + +/** + * A predicate is an object that can evaluate to true or false depending on the + * file currently read by a File_Archive_Reader + * + * @see File_Archive_Reader_Filter + */ +class File_Archive_Predicate +{ + /** + * Indicates whether the current file from the reader should be kept + * + * @param File_Archive_Reader $source Reader which will be filtered + * @return bool False iif the current file must be filtered out + */ + function isTrue(&$source) + { + return PEAR::raiseError("Predicat abstract function call"); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/And.php b/thirdparty/pear/File/Archive/Predicate/And.php new file mode 100644 index 0000000..04bfc7f --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/And.php @@ -0,0 +1,87 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: And.php,v 1.8 2005/04/21 10:01:46 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Evaluates to true iif all predicates given as constructor parameters evaluate + * to true + * + * Example: + * new File_Archive_Predicate_And($pred1, $pred2, $pred3) + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_And extends File_Archive_Predicate +{ + /** + * @var Array List of File_Archive_Predicate objects given as an argument + * @access private + */ + var $preds; + + /** + * Build the predicate using the optional File_Archive_Predicates given as + * arguments + * + * Example: + * new File_Archive_Predicate_And($pred1, $pred2, $pred3) + */ + function File_Archive_Predicate_And() + { + $this->preds = func_get_args(); + } + + /** + * Add a new predicate to the list + * + * @param File_Archive_Predicate The predicate to add + */ + function addPredicate($pred) + { + $this->preds[] = $pred; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + foreach ($this->preds as $p) { + if (!$p->isTrue($source)) { + return false; + } + } + return true; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/Current.php b/thirdparty/pear/File/Archive/Predicate/Current.php new file mode 100644 index 0000000..e331104 --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/Current.php @@ -0,0 +1,52 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Current.php,v 1.1 2005/05/28 23:17:28 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Evaluates to true only once, and then always to false + */ +class File_Archive_Predicate_Current extends File_Archive_Predicate +{ + var $value = true; + + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $tmp = $this->value; + $this->value = false; + return $tmp; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/Custom.php b/thirdparty/pear/File/Archive/Predicate/Custom.php new file mode 100644 index 0000000..6e517dc --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/Custom.php @@ -0,0 +1,88 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Custom.php,v 1.7 2005/04/21 10:01:46 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Custom predicate built by supplying a string expression + * + * Example: + * new File_Archive_Predicate_Custom("return strlen($name)<100;") + * new File_Archive_Predicate_Custom("strlen($name)<100;") + * new File_Archive_Predicate_Custom("strlen($name)<100") + * new File_Archive_Predicate_Custom("strlen($source->getFilename())<100") + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_Custom extends File_Archive_Predicate +{ + var $expression; + var $useName; + var $useStat; + var $useMIME; + + /** + * @param string $expression PHP code that evaluates too a boolean + * It can use the $source variable. If return is ommited, it will be + * added to the begining of the expression. A ; will also be added at + * the end so that you don't need to write it + */ + function File_Archive_Predicate_Custom($expression) + { + $this->expression = $expression.";"; + if (strpos($this->expression, "return") === false) { + $this->expression = "return ".$this->expression; + } + $this->useName = (strpos($this->expression, '$name') !== false); + $this->useStat = (strpos($this->expression, '$stat') !== false); + $this->useMIME = (strpos($this->expression, '$mime') !== false); + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + if ($this->useName) { + $name = $source->getFilename(); + } + if ($this->useStat) { + $stat = $source->getStat(); + $size = $stat[7]; + $time = (isset($stat[9]) ? $stat[9] : null); + } + if ($this->useMIME) { + $mime = $source->getMIME(); + } + return eval($this->expression); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/Duplicate.php b/thirdparty/pear/File/Archive/Predicate/Duplicate.php new file mode 100644 index 0000000..ba1ecdc --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/Duplicate.php @@ -0,0 +1,116 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Duplicate.php,v 1.1 2005/05/30 17:18:11 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Evaluates to true if a for the files for which a newer version + * can be found in a specified archive + * Comparison is by default made on dates of the files, or position + * in the archive (if two files have the same date or the date of a + * file is not specified). + */ +class File_Archive_Predicate_Duplicate extends File_Archive_Predicate +{ + /** + * @var array Key is the filename, value is an array of date (index 0) and + * position in the archive (index) 1 of the newest entry with this filename + */ + var $newest = array(); + + /** + * @var int The current position of the file in the source + */ + var $pos = 0; + + /** + * @param File_Archive_Reader $source The source will be inspected to find + * the date of old files + * The predicate should then be used on the same source to remove the + * old duplicate files + */ + function File_Archive_Predicate_Duplicate(&$source) + { + //Ensure we are at the begining of the file + $source->close(); + $pos = 0; + while ($source->next()) { + $filename = $source->getFilename(); + $stat = $source->getStat(); + $value = isset($this->newest[$filename]) ? $this->newest[$filename] : null; + + if ($value === null || + $this->compare($stat[9], $value[0]) >= 0 + ) { + $this->newest[$filename] = array($stat[9], $pos); + } + $pos++; + } + } + + /** + * Compare the dates of two files. null is considered infinitely old + * + * @return int < 0 if $a can be considered older than $b + * = 0 if $a and $b can be considered same age + * > 0 if $a can be considered newer than $b + */ + function compare($a, $b) { + return ($a === null ? -1 : $a) - ($b === null ? -1 : $b); + } + + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $filename = $source->getFilename(); + $stat = $source->getStat(); + $value = isset($this->newest[$filename]) ? $this->newest[$filename] : null; + if ($value === null) { + $delete = false; + } else { + $comp = $this->compare($stat[9], $value[0]); + + $delete = $comp < 0 || + ($comp == 0 && $this->pos != $value[1]); + + } + $this->pos++; + return $delete; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/Ereg.php b/thirdparty/pear/File/Archive/Predicate/Ereg.php new file mode 100644 index 0000000..f0c33c6 --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/Ereg.php @@ -0,0 +1,59 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Ereg.php,v 1.5 2005/04/21 10:01:46 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Keep only the files which name follow a given regular expression + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter ereg + */ +class File_Archive_Predicate_Ereg extends File_Archive_Predicate +{ + var $ereg; + + /** + * @param string $ereg is the regular expression + */ + function File_Archive_Predicate_Ereg($ereg) + { + $this->ereg = $ereg; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + return ereg($this->ereg, $source->getFilename()); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/Eregi.php b/thirdparty/pear/File/Archive/Predicate/Eregi.php new file mode 100644 index 0000000..bdf9e50 --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/Eregi.php @@ -0,0 +1,61 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Eregi.php,v 1.6 2005/04/21 10:01:46 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Keep only the files which name follow a given case insensitive regular + * expression + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter eregi + */ +class File_Archive_Predicate_Eregi extends File_Archive_Predicate +{ + var $ereg; + + /** + * @param string $ereg is the regular expression + */ + function File_Archive_Predicate_Eregi($ereg) + { + $this->ereg = $ereg; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + return eregi($this->ereg, $source->getFilename()); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/Extension.php b/thirdparty/pear/File/Archive/Predicate/Extension.php new file mode 100644 index 0000000..137fd8f --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/Extension.php @@ -0,0 +1,71 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Extension.php,v 1.5 2005/04/21 10:01:46 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Keep only the files that have a specific extension + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_Extension extends File_Archive_Predicate +{ + var $extensions; + + /** + * @param $extensions array or comma separated string of allowed extensions + */ + function File_Archive_Predicate_Extension($extensions) + { + if (is_string($extensions)) { + $this->extensions = explode(",",$extensions); + } else { + $this->extensions = $extensions; + } + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $filename = $source->getFilename(); + $pos = strrpos($filename, '.'); + $extension = ""; + if ($pos !== FALSE) { + $extension = strtolower(substr($filename, $pos+1)); + } + $result = in_array($extension, $this->extensions); + + return $result; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/False.php b/thirdparty/pear/File/Archive/Predicate/False.php new file mode 100644 index 0000000..21d137b --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/False.php @@ -0,0 +1,47 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: False.php,v 1.5 2005/04/21 10:01:46 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Always evaluate to false + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_False extends File_Archive_Predicate +{ + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) { return false; } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/Index.php b/thirdparty/pear/File/Archive/Predicate/Index.php new file mode 100644 index 0000000..3ac0d68 --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/Index.php @@ -0,0 +1,62 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Index.php,v 1.1 2005/05/30 19:44:53 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Evaluates to true if the index is in a given array of indexes + * The array has the indexes in key (so you may want to call + * array_flip if your array has indexes as value) + */ +class File_Archive_Predicate_Index extends File_Archive_Predicate +{ + var $indexes; + var $pos = 0; + + /** + * @param $extensions array or comma separated string of allowed extensions + */ + function File_Archive_Predicate_Index($indexes) + { + $this->indexes = $indexes; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + return isset($this->indexes[$this->pos++]); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/MIME.php b/thirdparty/pear/File/Archive/Predicate/MIME.php new file mode 100644 index 0000000..9b7e48e --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/MIME.php @@ -0,0 +1,75 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: MIME.php,v 1.5 2005/04/21 10:01:46 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; +require_once "MIME/Type.php"; + +/** + * Keep only the files that have a specific MIME type + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_MIME extends File_Archive_Predicate +{ + var $mimes; + + /** + * @param $extensions array or comma separated string of allowed extensions + */ + function File_Archive_Predicate_MIME($mimes) + { + if (is_string($mimes)) { + $this->mimes = explode(",",$mimes); + } else { + $this->mimes = $mimes; + } + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $sourceMIME = $source->getMIME(); + foreach ($this->mimes as $mime) { + if (MIME_Type::isWildcard($mime)) { + $result = MIME_Type::wildcardMatch($mime, $sourceMIME); + } else { + $result = ($mime == $sourceMIME); + } + if ($result !== false) { + return $result; + } + } + return false; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/MaxDepth.php b/thirdparty/pear/File/Archive/Predicate/MaxDepth.php new file mode 100644 index 0000000..d210a4f --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/MaxDepth.php @@ -0,0 +1,63 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: MaxDepth.php,v 1.6 2005/04/21 10:01:46 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Remove the URLs with a too high number of nested directories + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_MaxDepth extends File_Archive_Predicate +{ + var $maxDepth; + + /** + * @param int $maxDepth Maximal number of folders before the actual file in + * $source->getFilename(). + * '1/2/3/4/foo.txt' will be accepted with $maxDepth == 4 and + * rejected with $maxDepth == 5 + */ + function File_Archive_Predicate_MaxDepth($maxDepth) + { + $this->maxDepth = $maxDepth; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $url = parse_url($source->getFilename()); + return substr_count($url['path'], '/') <= $this->maxDepth ; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/MinSize.php b/thirdparty/pear/File/Archive/Predicate/MinSize.php new file mode 100644 index 0000000..5159832 --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/MinSize.php @@ -0,0 +1,59 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: MinSize.php,v 1.5 2005/04/21 10:01:47 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Keep only the files larger than a given size + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_MinSize extends File_Archive_Predicate +{ + var $minSize = 0; + + /** + * @param int $minSize minimal size of the file (in Bytes) + */ + function File_Archive_Predicate_MinSize($minSize) + { + $this->minSize = $minSize; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $stat = $source->getStat(); + return !isset($stat[7]) || $stat[7]>=$this->minSize; + } +} +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/MinTime.php b/thirdparty/pear/File/Archive/Predicate/MinTime.php new file mode 100644 index 0000000..aa74145 --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/MinTime.php @@ -0,0 +1,63 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: MinTime.php,v 1.6 2005/04/21 10:01:47 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Keep only the files modified after a given date (or with unknown modification + * date) + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_MinTime extends File_Archive_Predicate +{ + var $minTime = 0; + + /** + * @param int $minTime Unix timestamp of the minimal modification date of + * the files + */ + function File_Archive_Predicate_MinTime($minTime) + { + $this->minTime = $minTime; + + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + $stat = $source->getStat(); + return !isset($stat[9]) || $stat[9]>=$this->minTime; + } +} +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/Not.php b/thirdparty/pear/File/Archive/Predicate/Not.php new file mode 100644 index 0000000..28fac53 --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/Not.php @@ -0,0 +1,55 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Not.php,v 1.5 2005/04/21 10:01:47 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Evaluates to true iif the predicate given in parameter evaluates to false + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_Not extends File_Archive_Predicate +{ + var $pred; + function File_Archive_Predicate_Not($pred) + { + $this->pred = $pred; + } + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + return !$this->pred->isTrue($source); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/Or.php b/thirdparty/pear/File/Archive/Predicate/Or.php new file mode 100644 index 0000000..9d4c473 --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/Or.php @@ -0,0 +1,85 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Or.php,v 1.8 2005/04/21 10:01:47 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Evaluates to true iif one at least of the predicates + * given as constructor parameters evaluate to true + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +class File_Archive_Predicate_Or extends File_Archive_Predicate +{ + /** + * @var Array List of File_Archive_Predicate objects given as an argument + * @access private + */ + var $preds; + + /** + * Build the predicate using the optional File_Archive_Predicates given as + * arguments + * + * Example: + * new File_Archive_Predicate_And($pred1, $pred2, $pred3) + */ + function File_Archive_Predicate_And() + { + $this->preds = func_get_args(); + } + + /** + * Add a new predicate to the list + * + * @param File_Archive_Predicate The predicate to add + */ + function addPredicate($pred) + { + $this->preds[] = $pred; + } + + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) + { + foreach ($this->preds as $p) { + if ($p->isTrue($source)) { + return true; + } + } + return false; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Predicate/True.php b/thirdparty/pear/File/Archive/Predicate/True.php new file mode 100644 index 0000000..db1491e --- /dev/null +++ b/thirdparty/pear/File/Archive/Predicate/True.php @@ -0,0 +1,45 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: True.php,v 1.5 2005/04/21 10:01:47 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Predicate.php"; + +/** + * Always evaluate to true + */ +class File_Archive_Predicate_True extends File_Archive_Predicate +{ + /** + * @see File_Archive_Predicate::isTrue() + */ + function isTrue(&$source) { return true; } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader.php b/thirdparty/pear/File/Archive/Reader.php new file mode 100644 index 0000000..0149965 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader.php @@ -0,0 +1,416 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Reader.php,v 1.33 2005/07/07 12:24:57 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "PEAR.php"; + +/** + * Abstract base class for all the readers + * + * A reader is a compilation of serveral files that can be read + */ +class File_Archive_Reader +{ + /** + * Move to the next file in the reader + * + * @return bool false iif no more files are available + */ + function next() + { + return false; + } + + /** + * Move to the next file whose name is in directory $filename + * or is exactly $filename + * + * @param string $filename Name of the file to find in the archive + * @param bool $close If true, close the reader and search from the first file + * @return bool whether the file was found in the archive or not + */ + function select($filename, $close = true) + { + $std = $this->getStandardURL($filename); + + if ($close) { + $error = $this->close(); + if (PEAR::isError($error)) { + return $error; + } + } + while (($error = $this->next()) === true) { + $sourceName = $this->getFilename(); + if ( + empty($std) || + + //$std is a file + $std == $sourceName || + + //$std is a directory + strncmp($std.'/', $sourceName, strlen($std)+1) == 0 + ) { + return true; + } + } + return $error; + } + + /** + * Returns the standard path + * Changes \ to / + * Removes the .. and . from the URL + * @param string $path a valid URL that may contain . or .. and \ + * @static + */ + function getStandardURL($path) + { + if ($path == '.') { + return ''; + } + $std = str_replace("\\", "/", $path); + while ($std != ($std = preg_replace("/[^\/:?]+\/\.\.\//", "", $std))) ; + $std = str_replace("/./", "", $std); + if (strncmp($std, "./", 2) == 0) { + return substr($std, 2); + } else { + return $std; + } + } + + /** + * Returns the name of the file currently read by the reader + * + * Warning: undefined behaviour if no call to next have been + * done or if last call to next has returned false + * + * @return string Name of the current file + */ + function getFilename() + { + return PEAR::raiseError("Reader abstract function call (getFilename)"); + } + + /** + * Returns the list of filenames from the current pos to the end of the source + * The source will be closed after having called this function + * This function goes through the whole archive (which may be slow). + * If you intend to work on the reader, doing it in one pass would be faster + * + * @return array filenames from the current pos to the end of the source + */ + function getFileList() + { + $result = array(); + while ( ($error = $this->next()) === true) { + $result[] = $this->getFilename(); + } + $this->close(); + if (PEAR::isError($error)) { + return $error; + } else { + return $result; + } + } + + /** + * Returns an array of statistics about the file + * (see the PHP stat function for more information) + * + * The returned array may be empty, even if readers should try + * their best to return as many data as possible + */ + function getStat() { return array(); } + + /** + * Returns the MIME associated with the current file + * The default function does that by looking at the extension of the file + */ + function getMime() + { + require_once "File/Archive/Reader/MimeList.php"; + return File_Archive_Reader_GetMime($this->getFilename()); + } + + /** + * If the current file of the archive is a physical file, + * + * @return the name of the physical file containing the data + * or null if no such file exists + * + * The data filename may not be the same as the filename. + */ + function getDataFilename() { return null; } + + /** + * Reads some data from the current file + * If the end of the file is reached, returns null + * If $length is not specified, reads up to the end of the file + * If $length is specified reads up to $length + */ + function getData($length = -1) + { + return PEAR::raiseError("Reader abstract function call (getData)"); + } + + /** + * Skip some data and returns how many bytes have been skipped + * This is strictly equivalent to + * return strlen(getData($length)) + * But could be far more efficient + */ + function skip($length = -1) + { + $data = $this->getData($length); + if (PEAR::isError($data)) { + return $data; + } else { + return strlen($data); + } + } + + /** + * Move the current position back of a given amount of bytes. + * Not all readers may implement this function (a PEAR error will + * be returned if the reader can't rewind) + * + * @param int $length number of bytes to seek before the current pos + * or -1 to move back to the begining of the current file + * @return the number of bytes really rewinded (which may be less than + * $length if the current pos is less than $length + */ + function rewind($length = -1) + { + return PEAR::raiseError('Rewind function is not implemented on this reader'); + } + + /** + * Returns the current offset in the current file + */ + function tell() + { + $offset = $this->rewind(); + $this->skip($offset); + return $offset; + } + + /** + * Put back the reader in the state it was before the first call + * to next() + */ + function close() + { + } + + /** + * Sends the current file to the Writer $writer + * The data will be sent by chunks of at most $bufferSize bytes + * If $bufferSize <= 0 (default), the blockSize option is used + */ + function sendData(&$writer, $bufferSize = 0) + { + if (PEAR::isError($writer)) { + return $writer; + } + if ($bufferSize <= 0) { + $bufferSize = File_Archive::getOption('blockSize'); + } + + $filename = $this->getDataFilename(); + if ($filename !== null) { + $error = $writer->writeFile($filename); + if (PEAR::isError($error)) { + return $error; + } + } else { + while (($data = $this->getData($bufferSize)) !== null) { + if (PEAR::isError($data)) { + return $data; + } + $error = $writer->writeData($data); + if (PEAR::isError($error)) { + return $error; + } + } + } + } + + /** + * Sends the whole reader to $writer and close the reader + * + * @param File_Archive_Writer $writer Where to write the files of the reader + * @param bool $autoClose If true, close $writer at the end of the function. + * Default value is true + * @param int $bufferSize Size of the chunks that will be sent to the writer + * If $bufferSize <= 0 (default value), the blockSize option is used + */ + function extract(&$writer, $autoClose = true, $bufferSize = 0) + { + if (PEAR::isError($writer)) { + $this->close(); + return $writer; + } + + while (($error = $this->next()) === true) { + if ($writer->newFileNeedsMIME()) { + $mime = $this->getMime(); + } else { + $mime = null; + } + $error = $writer->newFile( + $this->getFilename(), + $this->getStat(), + $mime + ); + if (PEAR::isError($error)) { + break; + } + $error = $this->sendData($writer, $bufferSize); + if (PEAR::isError($error)) { + break; + } + } + $this->close(); + if ($autoClose) { + $writer->close(); + } + if (PEAR::isError($error)) { + return $error; + } + } + + /** + * Extract only one file (given by the URL) + * + * @param string $filename URL of the file to extract from this + * @param File_Archive_Writer $writer Where to write the file + * @param bool $autoClose If true, close $writer at the end of the function + * Default value is true + * @param int $bufferSize Size of the chunks that will be sent to the writer + * If $bufferSize <= 0 (default value), the blockSize option is used + */ + function extractFile($filename, &$writer, + $autoClose = true, $bufferSize = 0) + { + if (PEAR::isError($writer)) { + return $writer; + } + + if (($error = $this->select($filename)) === true) { + $result = $this->sendData($writer, $bufferSize); + if (!PEAR::isError($result)) { + $result = true; + } + } else if ($error === false) { + $result = PEAR::raiseError("File $filename not found"); + } else { + $result = $error; + } + if ($autoClose) { + $error = $writer->close(); + if (PEAR::isError($error)) { + return $error; + } + } + return $result; + } + + /** + * Return a writer that allows appending files to the archive + * After having called makeAppendWriter, $this is closed and should not be + * used until the returned writer is closed. + * + * @return a writer that will allow to append files to an existing archive + * @see makeWriter + */ + function makeAppendWriter() + { + require_once "File/Archive/Predicate/False.php"; + return $this->makeWriterRemoveFiles(new File_Archive_Predicate_False()); + } + + /** + * Return a writer that has the same properties as the one returned by + * makeAppendWriter, but after having removed all the files that follow a + * given predicate. + * After a call to makeWriterRemoveFiles, $this is closed and should not + * be used until the returned writer is closed + * + * @param File_Archive_Predicate $pred the predicate verified by removed files + * @return File_Archive_Writer that allows to append files to the archive + */ + function makeWriterRemoveFiles($pred) + { + return PEAR::raiseError("Reader abstract function call (makeWriterRemoveFiles)"); + } + + /** + * Returns a writer that removes the current file + * This is a syntaxic sugar for makeWriterRemoveFiles(new File_Archive_Predicate_Current()); + */ + function makeWriterRemove() + { + require_once "File/Archive/Predicate/Current.php"; + return $this->makeWriterRemoveFiles(new File_Archive_Predicate_Current()); + } + + /** + * Removes the current file from the reader + */ + function remove() + { + $writer = $this->makeWriterRemove(); + if (PEAR::isError($writer)) { + return $writer; + } + $writer->close(); + } + + /** + * Return a writer that has the same properties as the one returned by makeWriter, but after + * having removed a block of data from the current file. The writer will append data to the current file + * no data (other than the block) will be removed + * + * @param array Lengths of the blocks. The first one will be discarded, the second one kept, the third + * one discarded... If the sum of the blocks is less than the size of the file, the comportment is the + * same as if a last block was set in the array to reach the size of the file + * if $length is -1, the file is truncated from the specified pos + * It is possible to specify blocks of size 0 + * @param int $seek relative pos of the block + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + return PEAR::raiseError("Reader abstract function call (makeWriterRemoveBlocks)"); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Ar.php b/thirdparty/pear/File/Archive/Reader/Ar.php new file mode 100644 index 0000000..9170bf1 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Ar.php @@ -0,0 +1,387 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Archive.php"; + +/** + * Read an Ar archive + */ +class File_Archive_Reader_Ar extends File_Archive_Reader_Archive +{ + /** + * @var int The number of files to read to reach the end of the + * current ar file + * + * @access private + */ + var $_nbBytesLeft = 0; + + /** + * @var int The size of the header in number of bytes + * The header is not always 60 bytes since it sometimes + * contains a long filename + * @access private + */ + var $_header = 0; + + /** + * @var boolean Flag set if their is a 1 byte footer after the data + * of the current ar file + * + * @access private + */ + var $_footer = false; + + /** + * @var boolean Flag that has tell us if we have read the header of the + * current file + * @access private + */ + var $_alreadyRead = false; + + /** + * @var string Name of the file being read + * @access private + */ + var $_currentFilename = null; + + /** + * @var string Stat properties of the file being read + * It has: name, utime, uid, gid, mode, size and data + * @access private + */ + var $_currentStat = null; + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() + { + return $this->_currentFilename; + } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $this->_currentFilename = null; + $this->_currentStat = null; + $this->_nbBytesLeft = 0; + $this->_header = 0; + $this->_footer = false; + $this->_alreadyRead = false; + return parent::close(); + } + + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() + { + return $this->_currentStat; + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + $error = parent::next(); + if ($error !== true) { + return $error; + } + + $this->source->skip( + $this->_nbBytesLeft + ($this->_footer ? 1 : 0) + ); + + $filename = $this->source->getDataFilename(); + + if (!$this->_alreadyRead) { + $header = $this->source->getData(8); + if ($header != "!\n") { + return PEAR::raiseError("File {$filename} is not a valid Ar file format (starts with $header)"); + } + $this->_alreadyRead = true; + } + + + $name = $this->source->getData(16); + $mtime = $this->source->getData(12); + $uid = $this->source->getData(6); + $gid = $this->source->getData(6); + $mode = $this->source->getData(8); + $size = $this->source->getData(10); + $delim = $this->source->getData(2); + + if ($delim === null) { + return false; + } + + // All files inside should have more than 0 bytes of size + if ($size < 0) { + return PEAR::raiseError("Files must be at least one byte long"); + } + + $this->_footer = ($size % 2 == 1); + + // if the filename starts with a length, then just read the bytes of it + if (preg_match("/\#1\/(\d+)/", $name, $matches)) { + $this->_header = 60 + $matches[1]; + $name = $this->source->getData($matches[1]); + $size -= $matches[1]; + } else { + // strip trailing spaces in name, so we can distinguish spaces in a filename with padding + $this->_header = 60; + $name = preg_replace ("/\s+$/", "", $name); + } + + $this->_nbBytesLeft = $size; + if (empty($name) || empty($mtime) || empty($uid) || + empty($gid) || empty($mode) || empty($size)) { + return PEAR::raiseError("An ar field is empty"); + } + + $this->_currentFilename = $this->getStandardURL($name); + $this->_currentStat = array( + 2 => $mode, + 'mode' => $mode, + 4 => $uid, + 'uid' => $uid, + 5 => $gid, + 'gid' => $gid, + 7 => $size, + 'size' => $size, + 9 => $mtime, + 'mtime' => $mtime + ); + + return true; + } + + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($length == -1) { + $length = $this->_nbBytesLeft; + } else { + $length = min($length, $this->_nbBytesLeft); + } + if ($length == 0) { + return null; + } else { + $this->_nbBytesLeft -= $length; + $data = $this->source->getData($length); + if (PEAR::isError($data)) { + return $data; + } + if (strlen($data) != $length) { + return PEAR::raiseError('Unexpected end of Ar archive'); + } + return $data; + } + } + + /** + * @see File_Archive_Reader::skip + */ + function skip($length = -1) + { + if ($length == -1) { + $length = $this->_nbBytesLeft; + } else { + $length = min($length, $this->_nbBytesLeft); + } + if ($length == 0) { + return 0; + } else { + $this->_nbBytesLeft -= $length; + $skipped = $this->source->skip($length); + if (PEAR::isError($skipped)) { + return $skipped; + } + if ($skipped != $length) { + return PEAR::raiseError('Unexpected end of Ar archive'); + } + return $skipped; + } + } + + /** + * @see File_Archive_Reader::rewind + */ + function rewind($length = -1) + { + if ($length == -1) { + $length = $this->_currentStat[7] - $this->_nbBytesLeft; + } else { + $length = min($length, $this->_currentStat[7] - $this->_nbBytesLeft); + } + if ($length == 0) { + return 0; + } else { + $rewinded = $this->source->rewind($length); + if (!PEAR::isError($rewinded)) { + $this->_nbBytesLeft += $rewinded; + } + return $rewinded; + } + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->_currentStat[7] - $this->_nbBytesLeft; + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + require_once "File/Archive/Writer/Ar.php"; + + $blocks = array(); + $seek = null; + $gap = 0; + if ($this->_currentFilename !== null && $pred->isTrue($this)) { + $seek = $this->_header + $this->_currentStat[7] + ($this->_footer ? 1 : 0); + $blocks[] = $seek; //Remove this file + } + + while (($error = $this->next()) === true) { + $size = $this->_header + $this->_currentStat[7] + ($this->_footer ? 1 : 0); + if ($pred->isTrue($this)) { + if ($seek === null) { + $seek = $size; + $blocks[] = $size; + } else if ($gap > 0) { + $blocks[] = $gap; //Don't remove the files between the gap + $blocks[] = $size; + $seek += $size; + } else { + $blocks[count($blocks)-1] += $size; //Also remove this file + $seek += $size; + } + $gap = 0; + } else { + if ($seek !== null) { + $seek += $size; + $gap += $size; + } + } + } + if ($seek === null) { + $seek = 0; + } else { + if ($gap == 0) { + array_pop($blocks); + } else { + $blocks[] = $gap; + } + } + + $writer = new File_Archive_Writer_Ar(null, + $this->source->makeWriterRemoveBlocks($blocks, -$seek) + ); + $this->close(); + return $writer; + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + if ($this->_currentStat === null) { + return PEAR::raiseError('No file selected'); + } + + $blockPos = $this->_currentStat[7] - $this->_nbBytesLeft + $seek; + + $this->rewind(); + $keep = false; + + $data = $this->getData($blockPos); + foreach ($blocks as $length) { + if ($keep) { + $data .= $this->getData($length); + } else { + $this->skip($length); + } + $keep = !$keep; + } + if ($keep) { + $data .= $this->getData(); + } + + $filename = $this->_currentFilename; + $stat = $this->_currentStat; + + $writer = $this->makeWriterRemove(); + if (PEAR::isError($writer)) { + return $writer; + } + + unset($stat[7]); + $writer->newFile($filename, $stat); + $writer->writeData($data); + return $writer; + } + + /** + * @see File_Archive_Reader::makeAppendWriter + */ + function makeAppendWriter() + { + require_once "File/Archive/Writer/Ar.php"; + + while (($error = $this->next()) === true) { } + if (PEAR::isError($error)) { + $this->close(); + return $error; + } + + $innerWriter = $this->source->makeWriterRemoveBlocks(array()); + if (PEAR::isError($innerWriter)) { + return $innerWriter; + } + + unset($this->source); + $this->close(); + + return new File_Archive_Writer_Ar(null, $innerWriter); + } +} +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Archive.php b/thirdparty/pear/File/Archive/Reader/Archive.php new file mode 100644 index 0000000..2a9004f --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Archive.php @@ -0,0 +1,98 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Archive.php,v 1.12 2005/05/23 19:25:24 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; + +/** + * Base class for all the archive readers (that read from a single file) + */ +class File_Archive_Reader_Archive extends File_Archive_Reader +{ + /** + * @var File_Archive_Reader Single file source that contains the archive + * to uncompress + * @access protected + */ + var $source = null; + + /** + * @var bool Indicate whether the $source is currently opened + * @access private + */ + var $sourceOpened = false; + + /** + * The source was let in this state at the end + * + * @var bool Indicate whether the $source was given opened + * @access private + */ + var $sourceInitiallyOpened; + +//ABSTRACT + /** + * @see File_Archive_Reader::next() + * + * Open the source if necessary + */ + function next() + { + if (!$this->sourceOpened && ($error = $this->source->next()) !== true) { + return $error; + } + + $this->sourceOpened = true; + return true; + } + +//PUBLIC + function File_Archive_Reader_Archive(&$source, $sourceOpened = false) + { + $this->source =& $source; + $this->sourceOpened = $this->sourceInitiallyOpened = $sourceOpened; + } + /** + * Close the source if it was given closed in the constructor + * + * @see File_Archive_Reader::close() + */ + function close() + { + if (!$this->sourceInitiallyOpened && $this->sourceOpened) { + $this->sourceOpened = false; + if ($this->source !== null) { + return $this->source->close(); + } + } + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Bzip2.php b/thirdparty/pear/File/Archive/Reader/Bzip2.php new file mode 100644 index 0000000..495b1f5 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Bzip2.php @@ -0,0 +1,254 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Bzip2.php,v 1.19 2005/07/26 09:06:03 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Archive.php"; +require_once "File/Archive/Writer/Files.php"; + +/** + * Uncompress a file that was compressed in the Bzip2 format + */ +class File_Archive_Reader_Bzip2 extends File_Archive_Reader_Archive +{ + var $nbRead = 0; + var $bzfile = null; + var $tmpName = null; + var $filePos = 0; + + /** + * @see File_Archive_Reader::close() + */ + function close($innerClose = true) + { + if ($this->bzfile !== null) + bzclose($this->bzfile); + if ($this->tmpName !== null) + unlink($this->tmpName); + + $this->bzfile = null; + $this->tmpName = null; + $this->nbRead = 0; + $this->filePos = 0; + return parent::close($innerClose); + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + if (!parent::next()) { + return false; + } + + $this->nbRead++; + if ($this->nbRead > 1) { + return false; + } + + $dataFilename = $this->source->getDataFilename(); + if ($dataFilename !== null) + { + $this->tmpName = null; + $this->bzfile = @bzopen($dataFilename, 'r'); + if ($this->bzfile === false) { + return PEAR::raiseError("bzopen failed to open $dataFilename"); + } + } else { + $this->tmpName = tempnam(File_Archive::getOption('tmpDirectory'), 'far'); + + //Generate the tmp data + $dest = new File_Archive_Writer_Files(); + $dest->newFile($this->tmpName); + $this->source->sendData($dest); + $dest->close(); + + $this->bzfile = bzopen($this->tmpName, 'r'); + } + + return true; + } + /** + * Return the name of the single file contained in the archive + * deduced from the name of the archive (the extension is removed) + * + * @see File_Archive_Reader::getFilename() + */ + function getFilename() + { + $name = $this->source->getFilename(); + $pos = strrpos($name, "."); + if ($pos === false || $pos === 0) { + return $name; + } else { + return substr($name, 0, $pos); + } + } + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($length == -1) { + $data = ''; + do { + $newData = bzread($this->bzfile); + $data .= $newData; + } while ($newData != ''); + $this->filePos += strlen($data); + } else if ($length == 0) { + return ''; + } else { + $data = ''; + + //The loop is here to correct what appears to be a bzread bug + while (strlen($data) < $length) { + $newData = bzread($this->bzfile, $length - strlen($data)); + if ($newData == '') { + break; + } + $data .= $newData; + } + $this->filePos += strlen($data); + } + + return $data == '' ? null : $data; + } + + /** + * @see File_Archive_Reader::rewind + */ + function rewind($length = -1) + { + $before = $this->filePos; + + bzclose($this->bzfile); + if ($this->tmpName === null) { + $this->bzfile = bzopen($this->source->getDataFilename(), 'r'); + } else { + $this->bzfile = bzopen($this->tmpName, 'r'); + } + $this->filePos = 0; + + if ($length != -1) { + $this->skip($before - $length); + } + return $before - $this->filePos; + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->filePos; + } + + /** + * @see File_Archive_Reader::makeAppendWriter() + */ + function makeAppendWriter() + { + return PEAR::raiseError('Unable to append files to a bzip2 archive'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + return PEAR::raiseError('Unable to remove files from a bzip2 archive'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + require_once "File/Archive/Writer/Bzip2.php"; + + if ($this->nbRead == 0) { + return PEAR::raiseError('No file selected'); + } + + //Uncompress data to a temporary file + $tmp = tmpfile(); + $expectedPos = $this->filePos + $seek; + + $this->rewind(); + + //Read the begining of the file + while ($this->filePos < $expectedPos && + ($data = $this->getData(min($expectedPos - $this->filePos, 8192))) !== null) { + fwrite($tmp, $data); + } + + $keep = false; + foreach ($blocks as $length) { + if ($keep) { + $expectedPos = $this->filePos + $length; + while ($this->filePos < $expectedPos && + ($data = $this->getData(min($expectedPos - $this->filePos, 8192))) !== null) { + fwrite($tmp, $data); + } + } else { + $this->skip($length); + } + $keep = !$keep; + } + if ($keep) { + //Read the end of the file + while(($data = $this->getData(8192)) !== null) { + fwrite($tmp, $data); + } + } + fseek($tmp, 0); + + //Create the writer + $this->source->rewind(); + $innerWriter = $this->source->makeWriterRemoveBlocks(array()); //Truncate the source + unset($this->source); + $writer = new File_Archive_Writer_Bzip2(null, $innerWriter); + + //And compress data from the temporary file + while (!feof($tmp)) { + $data = fread($tmp, 8192); + $writer->writeData($data); + } + fclose($tmp); + + //Do not close inner writer since makeWriter was called + $this->close(); + + return $writer; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Cache.php b/thirdparty/pear/File/Archive/Reader/Cache.php new file mode 100644 index 0000000..f352b68 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Cache.php @@ -0,0 +1,262 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Cache.php,v 1.1 2005/07/07 12:24:58 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; + +/** + * This reader caches the files of another reader + * It allow fast access to files. This is usefull if the access to the reader + * is slow (HTTP, FTP...), but will need more IO if the file is only extracted + */ +class File_Archive_Reader_Cache extends File_Archive_Reader +{ + var $tmpFile; + var $files = array(); + var $pos = 0; + var $fromSource = true; + var $endOfSource = false; + var $source; + + /** + * $source is the reader to filter + */ + function File_Archive_Reader_Cache(&$source) + { + $this->source =& $source; + $this->tmpFile = tmpfile(); + } + + function _writeEndOfFile() + { + $bufferSize = File_Archive::getOption('blockSize'); + while (($data = $this->source->getData($bufferSize))!=null) { + fwrite($this->tmpFile, $data); + } + } + /** + * @see File_Archive_Reader::next() + */ + function next() + { + //Write the end of the current file to the temp file + if ($this->fromSource && !empty($this->files)) { + $this->_writeEndOfFile(); + } + + if ($this->pos+1 < count($this->files) && !$this->fromSource) { + $this->pos++; + fseek($this->tmpFile, $this->files[$this->pos]['pos'], SEEK_SET); + return true; + } else { + $this->fromSource = true; + if ($this->endOfSource) { + return false; + } + + $ret = $this->source->next(); + if ($ret !== true) { + $this->endOfSource = true; + $this->source->close(); + return $ret; + } + + $this->endOfSource = false; + fseek($this->tmpFile, 0, SEEK_END); + $this->files[] = array( + 'name' => $this->source->getFilename(), + 'stat' => $this->source->getStat(), + 'mime' => $this->source->getMime(), + 'pos' => ftell($this->tmpFile) + ); + $this->pos = count($this->files)-1; + + return true; + } + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->files[$this->pos]['name']; } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() { return $this->files[$this->pos]['stat']; } + /** + * @see File_Archive_Reader::getMime() + */ + function getMime() { return $this->files[$this->pos]['mime']; } + /** + * @see File_Archive_Reader::getDataFilename() + */ + function getDataFilename() { return null; } + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($this->fromSource) { + $data = $this->source->getData($length); + if (PEAR::isError($data)) { + return $data; + } + + fwrite($this->tmpFile, $data); + return $data; + } else { + if ($length == 0) { + return ''; + } + + if ($length > 0 && $this->pos+1 < count($this->files)) { + $maxSize = $this->files[$this->pos+1]['pos'] - ftell($this->tmpFile); + if ($maxSize == 0) { + return null; + } + if ($length > $maxSize) { + $length = $maxSize; + } + return fread($this->tmpFile, $length); + } else { + $contents = ''; + $blockSize = File_Archive::getOption('blockSize'); + while (!feof($this->tmpFile)) { + $contents .= fread($this->tmpFile, $blockSize); + } + return $contents == '' ? null : $contents; + } + } + } + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + if ($this->fromSource) { + return strlen($this->getData($length)); + } else { + if ($length >= 0 && $this->pos+1 < count($this->files)) { + $maxSize = $this->files[$this->pos+1]['pos'] - ftell($this->tmpFile); + if ($maxSize == 0) { + return null; + } + if ($length > $maxSize) { + $length = $maxSize; + } + fseek($this->tmpFile, $length, SEEK_CUR); + return $length; + } else { + $before = ftell($this->tmpFile); + fseek($this->tmpFile, 0, SEEK_SET); + $after = fteel($this->tmpFile); + return $after - $before; + } + } + } + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + if ($this->fromSource) { + $this->_writeEndOfFile(); + $this->fromSource = false; + } + $before = ftell($this->tmpFile); + $pos = $this->files[$this->pos]['pos']; + fseek($this->tmpFile, $pos, SEEK_SET); + return $pos - $before; + } + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return ftell($this->tmpFile) - $this->files[$this->pos]['pos']; + } + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $this->fromSource = false; + $this->pos = 0; + fseek($this->tmpFile, 0, SEEK_SET); + } + function _closeAndReset() + { + $this->close(); + + fclose($this->tmpFile); + $this->tmpFile = tmpfile(); + $this->endOfSource = false; + $this->files = array(); + $this->source->close(); + } + /** + * @see File_Archive_Reader::makeAppendWriter() + */ + function makeAppendWriter() + { + $writer = $this->source->makeAppendWriter(); + if (!PEAR::isError($writer)) { + $this->_closeAndReset(); + } + + return $writer; + } + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + $writer = $this->source->makeWriterRemoveFiles($pred); + if (!PEAR::isError($writer)) { + $this->_closeAndReset(); + } + return $writer; + } + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + $writer = $this->source->makeWriterRemoveBlocks($blocks, $seek); + if (!PEAR::isError($writer)) { + $this->_closeAndReset(); + } + return $writer; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/ChangeName.php b/thirdparty/pear/File/Archive/Reader/ChangeName.php new file mode 100644 index 0000000..595b481 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/ChangeName.php @@ -0,0 +1,212 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: ChangeName.php,v 1.19 2005/07/09 12:54:35 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Relay.php"; + +/** + * Add a directory to the public name of all the files of a reader + * + * Example: + * If archive.tar is a file archive containing files a.txt and foo/b.txt + * new File_Archive_Reader_AddBaseName('bar', + * new File_Archive_Reader_Tar( + * new File_Archive_Reader_File('archive.tar') + * ) + * ) is a reader containing files bar/a.txt and bar/foo/b.txt + */ +class File_Archive_Reader_AddBaseName extends File_Archive_Reader_Relay +{ + var $baseName; + function File_Archive_Reader_AddBaseName($baseName, &$source) + { + parent::File_Archive_Reader_Relay($source); + $this->baseName = $this->getStandardURL($baseName); + } + + /** + * Modify the name by adding baseName to it + */ + function modifyName($name) + { + return $this->baseName. + (empty($this->baseName) || empty($name) ? '': '/'). + $name; + } + + /** + * Remove baseName from the name + * Return false if the name doesn't start with baseName + */ + function unmodifyName($name) + { + if (strncmp($name, $this->baseName.'/', strlen($this->baseName)+1) == 0) { + $res = substr($name, strlen($this->baseName)+1); + if ($res === false) { + return ''; + } else { + return $res; + } + } else if (empty($this->baseName)) { + return $name; + } else if ($name == $this->baseName) { + return ''; + } else { + return false; + } + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() + { + return $this->modifyName(parent::getFilename()); + } + /** + * @see File_Archive_Reader::getFileList() + */ + function getFileList() + { + $list = parent::getFileList(); + $result = array(); + foreach ($list as $name) { + $result[] = $this->modifyName($name); + } + return $result; + } + /** + * @see File_Archive_Reader::select() + */ + function select($filename, $close = true) + { + $name = $this->unmodifyName($filename); + if ($name === false) { + return false; + } else { + return $this->source->select($name, $close); + } + } +} + +/** + * Change a directory name to another + * + * Example: + * If archive.tar is a file archive containing files a.txt and foo/b.txt + * new File_Archive_Reader_ChangeBaseName('foo', 'bar' + * new File_Archive_Reader_Tar( + * new File_Archive_Reader_File('archive.tar') + * ) + * ) is a reader containing files a.txt and bar/b.txt + */ +class File_Archive_Reader_ChangeBaseName extends File_Archive_Reader_Relay +{ + var $oldBaseName; + var $newBaseName; + + function File_Archive_Reader_ChangeBaseName + ($oldBaseName, $newBaseName, &$source) + { + parent::File_Archive_Reader_Relay($source); + $this->oldBaseName = $this->getStandardURL($oldBaseName); + if (substr($this->oldBaseName, -1) == '/') { + $this->oldBaseName = substr($this->oldBaseName, 0, -1); + } + + $this->newBaseName = $this->getStandardURL($newBaseName); + if (substr($this->newBaseName, -1) == '/') { + $this->newBaseName = substr($this->newBaseName, 0, -1); + } + } + + function modifyName($name) + { + if (empty($this->oldBaseName) || + !strncmp($name, $this->oldBaseName.'/', strlen($this->oldBaseName)+1) || + strcmp($name, $this->oldBaseName) == 0) { + return $this->newBaseName. + ( + empty($this->newBaseName) || + strlen($name)<=strlen($this->oldBaseName)+1 ? + '' : '/' + ). + substr($name, strlen($this->oldBaseName)+1); + } else { + return $name; + } + } + function unmodifyName($name) + { + if (empty($this->newBaseName) || + !strncmp($name, $this->newBaseName.'/', strlen($this->newBaseName)+1) || + strcmp($name, $this->newBaseName) == 0) { + return $this->oldBaseName. + ( + empty($this->oldBaseName) || + strlen($name)<=strlen($this->newBaseName)+1 ? + '' : '/' + ). + substr($name, strlen($this->newBaseName)+1); + } else { + return $name; + } + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() + { + return $this->modifyName(parent::getFilename()); + } + /** + * @see File_Archive_Reader::getFileList() + */ + function getFileList() + { + $list = parent::getFileList(); + $result = array(); + foreach ($list as $name) { + $result[] = $this->modifyName($name); + } + return $result; + } + /** + * @see File_Archive_Reader::select() + */ + function select($filename, $close = true) + { + return $this->source->select($this->unmodifyName($filename)); + } + +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Concat.php b/thirdparty/pear/File/Archive/Reader/Concat.php new file mode 100644 index 0000000..3885554 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Concat.php @@ -0,0 +1,187 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Concat.php,v 1.17 2005/07/07 15:48:28 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Relay.php"; + +/** + * This reader provides one single file that is the concatenation of the data of + * all the files of another reader + */ +class File_Archive_Reader_Concat extends File_Archive_Reader +{ + var $source; + var $filename; + var $stat; + var $mime; + var $opened = false; + var $filePos = 0; + + function File_Archive_Reader_Concat(&$source, $filename, + $stat=array(), $mime=null) + { + $this->source =& $source; + $this->filename = $filename; + $this->stat = $stat; + $this->mime = $mime; + + //Compute the total length + $this->stat[7] = 0; + while (($error = $source->next()) === true) { + $sourceStat = $source->getStat(); + if (isset($sourceStat[7])) { + $this->stat[7] += $sourceStat[7]; + } else { + unset($this->stat[7]); + break; + } + } + if (isset($this->stat[7])) { + $this->stat['size'] = $this->stat[7]; + } + if (PEAR::isError($error) || PEAR::isError($source->close())) { + die("Error in File_Archive_Reader_Concat constructor ". + '('.$error->getMessage().'), cannot continue'); + } + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + if (!$this->opened) { + return $this->opened = $this->source->next(); + } else { + return false; + } + } + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->filename; } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() { return $this->stat; } + /** + * @see File_Archive_Reader::getMime() + */ + function getMime() + { + return $this->mime==null ? parent::getMime() : $this->mime; + } + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($length == 0) { + return ''; + } + + $result = ''; + while ($length == -1 || strlen($result)<$length) { + $sourceData = $this->source->getData( + $length==-1 ? -1 : $length - strlen($result) + ); + + if (PEAR::isError($sourceData)) { + return $sourceData; + } + + if ($sourceData === null) { + $error = $this->source->next(); + if (PEAR::isError($error)) { + return $error; + } + if (!$error) { + break; + } + } else { + $result .= $sourceData; + } + } + $this->filePos += strlen($result); + return $result == '' ? null : $result; + } + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + $skipped = 0; + while ($skipped < $length) { + $sourceSkipped = $this->source->skip($length); + if (PEAR::isError($sourceSkipped)) { + return $skipped; + } + $skipped += $sourceSkipped; + $filePos += $sourceSkipped; + } + return $skipped; + } + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + //TODO: implement rewind + return parent::rewind($length); + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->filePos; + } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $this->opened = false; + $this->filePos = 0; + return $this->source->close(); + } + + /** + * @see File_Archive_Reader::makeWriter + */ + function makeWriter($fileModif = true, $seek = 0) + { + return $this->source->makeWriter($fileModif, $seek); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Directory.php b/thirdparty/pear/File/Archive/Reader/Directory.php new file mode 100644 index 0000000..d1da2fa --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Directory.php @@ -0,0 +1,220 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Directory.php,v 1.21 2005/07/07 12:24:58 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Relay.php"; +require_once "File/Archive/Reader/File.php"; + +/** + * Recursively reads a directory + */ +class File_Archive_Reader_Directory extends File_Archive_Reader_Relay +{ + /** + * @var String URL of the directory that must be read + * @access private + */ + var $directory; + /** + * @var Int The subdirectories will be read up to a depth of maxRecurs + * If maxRecurs == 0, the subdirectories will not be read + * If maxRecurs == -1, the depth is considered infinite + * @access private + */ + var $maxRecurs; + /** + * @var Object Handle returned by the openedDirectory function + * @access private + */ + var $directoryHandle = null; + + /** + * $directory is the path of the directory that must be read + * If $maxRecurs is specified, the subdirectories will be read up to a depth + * of $maxRecurs. In particular, if $maxRecurs == 0, the subdirectories + * won't be read. + */ + function File_Archive_Reader_Directory($directory, $symbolic='', + $maxRecurs=-1) + { + parent::File_Archive_Reader_Relay($tmp = null); + $this->directory = empty($directory) ? '.' : $directory; + $this->symbolic = $this->getStandardURL($symbolic); + $this->maxRecurs = $maxRecurs; + } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $error = parent::close(); + + if ($this->directoryHandle !== null) { + closedir($this->directoryHandle); + $this->directoryHandle = null; + } + + return $error; + } + + /** + * @see File_Archive_Reader::next() + * + * The files are returned in the same order as readdir + */ + function next() + { + if ($this->directoryHandle === null) { + $this->directoryHandle = opendir($this->directory); + if (!is_resource($this->directoryHandle)) { + return PEAR::raiseError( + "Directory {$this->directory} not found" + ); + } + } + + while ($this->source === null || + ($error = $this->source->next()) !== true) { + + if ($this->source !== null) { + $this->source->close(); + } + + $file = readdir($this->directoryHandle); + if ($file == '.' || $file == '..') { + continue; + } + if ($file === false) { + return false; + } + + $current = $this->directory.'/'.$file; + if (is_dir($current)) { + if ($this->maxRecurs != 0) { + $this->source = new File_Archive_Reader_Directory( + $current, $file.'/', $this->maxRecurs-1 + ); + } + } else { + $this->source = new File_Archive_Reader_File($current, $file); + } + } + + return $error; + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->symbolic . parent::getFilename(); } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + if ($source !== null && $pred->isTrue($this)) { + $toUnlink = $this->getDataFilename(); + } else { + $toUnlink = null; + } + + while ($this->next()) { + if ($toUnlink !== null && + !@unlink($toUnlink)) { + return PEAR::raiseError("Unable to unlink $toUnlink"); + } + $toUnlink = ($pred->isTrue($this) ? $this->getDataFilename() : null); + } + if ($toUnlink !== null && + !@unlink("Unable to unlink $toUnlink")) { + return PEAR::raiseError($pred); + } + + require_once "File/Archive/Writer/Files.php"; + + $writer = new File_Archive_Writer_Files($this->directory); + $this->close(); + return $writer; + } + + function &getLastSource() + { + if ($this->source === null || + is_a($this->source, 'File_Archive_Reader_File')) { + return $this->source; + } else { + return $this->source->getLastSource(); + } + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + $lastSource = &$this->getLastSource(); + if ($lastSource === null) { + return PEAR::raiseError('No file selected'); + } + + require_once "File/Archive/Writer/Files.php"; + + $writer = $lastSource->makeWriterRemoveBlocks($blocks, $seek); + if (!PEAR::isError($writer)) { + $writer->basePath = $this->directory; + $this->close(); + } + + return $writer; + } + + /** + * @see File_Archive_Reader::makeAppendWriter + */ + function makeAppendWriter() + { + require_once "File/Archive/Writer/Files.php"; + + if ($this->source === null || + is_a($this->source, 'File_Archive_Reader_File') ) { + $writer = new File_Archive_Writer_Files($this->directory); + } else { + $writer = $this->source->makeAppendWriter($seek); + } + + $this->close(); + + return $writer; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/File.php b/thirdparty/pear/File/Archive/Reader/File.php new file mode 100644 index 0000000..81412d2 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/File.php @@ -0,0 +1,296 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: File.php,v 1.30 2005/07/11 11:53:53 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; +require_once "MIME/Type.php"; + +/** + * Reader that represents a single file + */ +class File_Archive_Reader_File extends File_Archive_Reader +{ + /** + * @var object Handle to the file being read + * @access private + */ + var $handle = null; + /** + * @var string Name of the physical file being read + * @access private + */ + var $filename; + /** + * @var string Name of the file returned by the reader + * @access private + */ + var $symbolic; + /** + * @var array Stats of the file + * Will only be set after a call to $this->getStat() + * @access private + */ + var $stat = null; + /** + * @var string Mime type of the file + * Will only be set after a call to $this->getMime() + */ + var $mime = null; + /** + * @var boolean Has the file already been read + * @access private + */ + var $alreadyRead = false; + + /** + * $filename is the physical file to read + * $symbolic is the name declared by the reader + * If $symbolic is not specified, $filename is assumed + */ + function File_Archive_Reader_File($filename, $symbolic = null, $mime = null) + { + $this->filename = $filename; + $this->mime = $mime; + if ($symbolic === null) { + $this->symbolic = $this->getStandardURL($filename); + } else { + $this->symbolic = $this->getStandardURL($symbolic); + } + } + /** + * @see File_Archive_Reader::close() + * + * Close the file handle + */ + function close() + { + $this->alreadyRead = false; + if ($this->handle !== null) { + fclose($this->handle); + $this->handle = null; + } + } + /** + * @see File_Archive_Reader::next() + * + * The first time next is called, it will open the file handle and return + * true. Then it will return false + * Raise an error if the file does not exist + */ + function next() + { + if ($this->alreadyRead) { + return false; + } else { + $this->alreadyRead = true; + return true; + } + } + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->symbolic; } + /** + * @see File_Archive_Reader::getDataFilename() + * + * Return the name of the file + */ + function getDataFilename() { return $this->filename; } + /** + * @see File_Archive_Reader::getStat() stat() + */ + function getStat() + { + if ($this->stat === null) { + $this->stat = @stat($this->filename); + + //If we can't use the stat function + if ($this->stat === false) { + $this->stat = array(); + } + } + return $this->stat; + } + + /** + * @see File_Archive_Reader::getMime + */ + function getMime() + { + if ($this->mime === null) { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $this->mime = MIME_Type::autoDetect($this->getDataFilename()); + PEAR::popErrorHandling(); + + if (PEAR::isError($this->mime)) { + $this->mime = parent::getMime(); + } + } + return $this->mime; + } + + /** + * Opens the file if it was not already opened + */ + function _ensureFileOpened() + { + if ($this->handle === null) { + $this->handle = @fopen($this->filename, "r"); + + if (!is_resource($this->handle)) { + $this->handle = null; + return PEAR::raiseError("Can't open {$this->filename} for reading"); + } + if ($this->handle === false) { + $this->handle = null; + return PEAR::raiseError("File {$this->filename} not found"); + } + } + } + + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + $error = $this->_ensureFileOpened(); + if (PEAR::isError($error)) { + return $error; + } + + if (feof($this->handle)) { + return null; + } + if ($length == -1) { + $contents = ''; + $blockSize = File_Archive::getOption('blockSize'); + while (!feof($this->handle)) { + $contents .= fread($this->handle, $blockSize); + } + return $contents; + } else { + if ($length == 0) { + return ""; + } else { + return fread($this->handle, $length); + } + } + } + + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + $error = $this->_ensureFileOpened(); + if (PEAR::isError($error)) { + return $error; + } + + $before = ftell($this->handle); + if (($length == -1 && @fseek($this->handle, 0, SEEK_END) === -1) || + ($length >= 0 && @fseek($this->handle, $length, SEEK_CUR) === -1)) { + return parent::skip($length); + } else { + return ftell($this->handle) - $before; + } + } + + /** + * @see File_Archive_Reader::rewind + */ + function rewind($length = -1) + { + if ($this->handle === null) { + return 0; + } + + $before = ftell($this->handle); + if (($length == -1 && @fseek($this->handle, 0, SEEK_SET) === -1) || + ($length >= 0 && @fseek($this->handle, -$length, SEEK_CUR) === -1)) { + return parent::rewind($length); + } else { + return $before - ftell($this->handle); + } + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + if ($this->handle === null) { + return 0; + } else { + return ftell($this->handle); + } + } + + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + return PEAR::raiseError( + 'File_Archive_Reader_File represents a single file, you cant remove it'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + require_once "File/Archive/Writer/Files.php"; + + $writer = new File_Archive_Writer_Files(); + + $file = $this->getDataFilename(); + $pos = $this->tell(); + $this->close(); + + $writer->openFileRemoveBlock($file, $pos + $seek, $blocks); + + return $writer; + } + + /** + * @see File_Archive_Reader::makeAppendWriter + */ + function makeAppendWriter() + { + return PEAR::raiseError( + 'File_Archive_Reader_File represents a single file.'. + ' makeAppendWriter cant be executed on it' + ); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Filter.php b/thirdparty/pear/File/Archive/Reader/Filter.php new file mode 100644 index 0000000..f8fd70b --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Filter.php @@ -0,0 +1,90 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Filter.php,v 1.10 2005/07/09 12:54:35 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Relay.php"; + +/** + * Filter out the files that do not respect a given predicat + */ +class File_Archive_Reader_Filter extends File_Archive_Reader_Relay +{ + /** + * @var File_Archive_Reader_Predicat + * @access private + */ + var $predicate; + + /** + * $source is the reader to filter + */ + function File_Archive_Reader_Filter($predicate, &$source) + { + parent::File_Archive_Reader_Relay($source); + $this->predicate = $predicate; + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + do { + $error = $this->source->next(); + if ($error !== true) { + return $error; + } + } while (!$this->predicate->isTrue($this->source)); + return true; + } + + /** + * @see File_Archive_Reader::select() + */ + function select($filename, $close = true) + { + if ($close) { + $error = $this->close(); + if (PEAR::isError($error)) { + return $error; + } + } + + do { + $error = $this->source->select($filename, false); + if ($error !== true) { + return $error; + } + } while (!$this->predicate->isTrue($this->source)); + return true; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Gzip.php b/thirdparty/pear/File/Archive/Reader/Gzip.php new file mode 100644 index 0000000..8f13f99 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Gzip.php @@ -0,0 +1,276 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Gzip.php,v 1.27 2005/06/19 20:09:57 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Archive.php"; +require_once "File/Archive/Writer/Files.php"; + +/** + * Uncompress a file that was compressed in the Gzip format + */ +class File_Archive_Reader_Gzip extends File_Archive_Reader_Archive +{ + var $nbRead = 0; + var $filePos = 0; + var $gzfile = null; + var $tmpName = null; + + /** + * @see File_Archive_Reader::close() + */ + function close($innerClose = true) + { + if ($this->gzfile !== null) { + gzclose($this->gzfile); + } + if ($this->tmpName !== null) { + unlink($this->tmpName); + } + + $this->nbRead = 0; + $this->filePos = 0; + $this->gzfile = null; + $this->tmpName = null; + + return parent::close($innerClose); + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + if (!parent::next()) { + return false; + } + + $this->nbRead++; + $this->filePos = 0; + if ($this->nbRead > 1) { + return false; + } + + $dataFilename = $this->source->getDataFilename(); + if ($dataFilename !== null) + { + $this->tmpName = null; + $this->gzfile = gzopen($dataFilename, 'r'); + } else { + $this->tmpName = tempnam(File_Archive::getOption('tmpDirectory'), 'far'); + + //Generate the tmp data + $dest = new File_Archive_Writer_Files(); + $dest->newFile($this->tmpName); + $this->source->sendData($dest); + $dest->close(); + + $this->gzfile = gzopen($this->tmpName, 'r'); + } + + return true; + } + + /** + * Return the name of the single file contained in the archive + * deduced from the name of the archive (the extension is removed) + * + * @see File_Archive_Reader::getFilename() + */ + function getFilename() + { + $name = $this->source->getFilename(); + $slashPos = strrpos($name, '/'); + if ($slashPos !== false) { + $name = substr($name, $slashPos+1); + } + $dotPos = strrpos($name, '.'); + if ($dotPos !== false && $dotPos > 0) { + $name = substr($name, 0, $dotPos); + } + + return $name; + } + + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($length == -1) { + $data = ''; + do + { + $newData = gzread($this->gzfile, 8192); + $data .= $newData; + } while ($newData != ''); + } else if ($length == 0) { + return ''; + } else { + $data = gzread($this->gzfile, $length); + } + + $this->filePos += strlen($data); + return $data == '' ? null : $data; + } + + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + if($length == -1) { + do + { + $tmp = gzread($this->gzfile, 8192); + $this->filePos += strlen($tmp); + } while ($tmp != ''); + } else { + if (@gzseek($this->gzfile, $this->filePos + $length) === -1) { + return parent::skip($length); + } else { + $this->filePos += $length; + return $length; + } + } + } + + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + if ($length == -1) { + if (@gzseek($this->gzfile, 0) === -1) { + return parent::rewind($length); + } else { + $tmp = $this->filePos; + $this->filePos = 0; + return $tmp; + } + } else { + $length = min($length, $this->filePos); + if (@gzseek($this->gzfile, $this->filePos - $length) === -1) { + return parent::rewind($length); + } else { + $this->filePos -= $length; + return $length; + } + } + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->filePos; + } + + /** + * @see File_Archive_Reader::makeAppendWriter() + */ + function makeAppendWriter() + { + return PEAR::raiseError('Unable to append files to a gzip archive'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + return PEAR::raiseError('Unable to remove files from a gzip archive'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + require_once "File/Archive/Writer/Gzip.php"; + + if ($this->nbRead == 0) { + return PEAR::raiseError('No file selected'); + } + + //Uncompress data to a temporary file + $tmp = tmpfile(); + $expectedPos = $this->filePos + $seek; + $this->rewind(); + + //Read the begining of the file + while ($this->filePos < $expectedPos && + ($data = $this->getData(min($expectedPos - $this->filePos, 8192))) !== null) { + fwrite($tmp, $data); + } + + $keep = false; + foreach ($blocks as $length) { + if ($keep) { + $expectedPos = $this->filePos + $length; + while ($this->filePos < $expectedPos && + ($data = $this->getData(min($expectedPos - $this->filePos, 8192))) !== null) { + fwrite($tmp, $data); + } + } else { + $this->skip($length); + } + $keep = !$keep; + } + if ($keep) { + //Read the end of the file + while(($data = $this->getData(8192)) !== null) { + fwrite($tmp, $data); + } + } + fseek($tmp, 0); + + //Create the writer + $this->source->rewind(); + $innerWriter = $this->source->makeWriterRemoveBlocks(array()); //Truncate the source + unset($this->source); + $writer = new File_Archive_Writer_Gzip(null, $innerWriter); + + //And compress data from the temporary file + while (!feof($tmp)) { + $data = fread($tmp, 8192); + $writer->writeData($data); + } + fclose($tmp); + + //Do not close inner writer since makeWriter was called + $this->close(); + + return $writer; + } + +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Memory.php b/thirdparty/pear/File/Archive/Reader/Memory.php new file mode 100644 index 0000000..d77928f --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Memory.php @@ -0,0 +1,227 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Memory.php,v 1.19 2005/06/19 20:09:57 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; + +/** + * A reader that takes its input from a memory buffer + */ +class File_Archive_Reader_Memory extends File_Archive_Reader +{ + /** + * @var String Name of the file exported by this reader + * @access private + */ + var $filename; + /** + * @var Array Stat of the file exported by this reader + * @access private + */ + var $stat; + /** + * @var String MIME type of the file exported by this reader + * @access private + */ + var $mime; + /** + * @var String Memory buffer that contains the data of the file + * @access private + */ + var $memory; + /** + * @var Int Current position in the file + * @access private + */ + var $offset = 0; + /** + * @var Boolean Has the file already been read + * @access private + */ + var $alreadyRead = false; + + /** + * @param string $memory is the content of the file. + * This parameter is passed as a reference for performance + * reasons. The content should not be changer after the constructor + * @param string $filename is the name of the file + * @param array $stat are the statistics of the file. The size will be + * recomputed from $memory + * @param string $mime is the mime type of the file + */ + function File_Archive_Reader_Memory(&$memory, $filename, + $stat=array(), $mime=null) + { + $this->memory = &$memory; + $this->filename = $this->getStandardURL($filename); + $this->stat = $stat; + $this->stat[7] = $this->stat['size'] = strlen($this->memory); + $this->mime = $mime; + } + + /** + * The subclass should overwrite this function to change the filename, stat + * and memory + */ + function next() + { + if ($this->alreadyRead) { + return false; + } else { + $this->alreadyRead = true; + return true; + } + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->filename; } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() { return $this->stat; } + /** + * @see File_Archive_Reader::getMime() + */ + function getMime() + { + return $this->mime==null ? parent::getMime() : $this->mime; + } + + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($this->offset == strlen($this->memory)) { + return null; + } + if ($length == -1) { + $actualLength = strlen($this->memory) - $this->offset; + } else { + $actualLength = min($length, strlen($this->memory) - $this->offset); + } + $result = substr($this->memory, $this->offset, $actualLength); + $this->offset += $actualLength; + return $result; + } + + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + if ($length == -1) { + $length = strlen($this->memory) - $this->offset; + } else { + $length = min($length, strlen($this->memory) - $this->offset); + } + $this->offset += $length; + return $length; + } + + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + if ($length == -1) { + $tmp = $this->offset; + $this->offset = 0; + return $tmp; + } else { + $length = min($length, $this->offset); + $this->offset -= $length; + return $length; + } + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->offset; + } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $this->offset = 0; + $this->alreadyRead = false; + } + + /** + * @see File_Archive_Reader::makeAppendWriter() + */ + function makeAppendWriter() + { + return PEAR::raiseError('Unable to append files to a memory archive'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + return PEAR::raiseError('Unable to remove files from a memory archive'); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + require_once "File/Archive/Writer/Memory.php"; + $data = substr($this->memory, 0, $this->offset + $seek); + $this->memory = substr($this->memory, $this->offset + $seek); + + $keep = false; + foreach ($blocks as $length) { + if ($keep) { + $data .= substr($this->memory, 0, $length); + } + $this->memory = substr($this->memory, $length); + $keep = !$keep; + } + if ($keep) { + $this->memory = $data . $this->memory; + } else { + $this->memory = $data; + } + $this->close(); + return new File_Archive_Writer_Memory($this->memory, strlen($this->memory)); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/MimeList.php b/thirdparty/pear/File/Archive/Reader/MimeList.php new file mode 100644 index 0000000..7f10f87 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/MimeList.php @@ -0,0 +1,939 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: MimeList.php,v 1.7 2005/02/23 20:11:42 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +/** + * Returns the MIME of the filename, deducted from its extension + * If the extension is unknown, returns "application/octet-stream" + */ +function File_Archive_Reader_GetMime($filename) +{ + $pos = strrpos($filename, '.'); + $extension = ""; + if ($pos !== false) { + $extension = strtolower(substr($filename, $pos+1)); + } + + switch($extension) { + case '3dmf': + return 'x-world/x-3dmf'; + case 'a': + return 'application/octet-stream'; + case 'aab': + return 'application/x-authorware-bin'; + case 'aam': + return 'application/x-authorware-map'; + case 'aas': + return 'application/x-authorware-seg'; + case 'abc': + return 'text/vnd.abc'; + case 'acgi': + return 'text/html'; + case 'afl': + return 'video/animaflex'; + case 'ai': + return 'application/postscript'; + case 'aif': + return 'audio/aiff'; + case 'aifc': + return 'audio/aiff'; + case 'aiff': + return 'audio/aiff'; + case 'aim': + return 'application/x-aim'; + case 'aip': + return 'text/x-audiosoft-intra'; + case 'ani': + return 'application/x-navi-animation'; + case 'aos': + return 'application/x-nokia-9000-communicator-add-on-software'; + case 'aps': + return 'application/mime'; + case 'arc': + return 'application/octet-stream'; + case 'arj': + return 'application/arj'; + case 'art': + return 'image/x-jg'; + case 'asf': + return 'video/x-ms-asf'; + case 'asm': + return 'text/x-asm'; + case 'asp': + return 'text/asp'; + case 'asx': + return 'application/x-mplayer2'; + case 'au': + return 'audio/basic'; + case 'avi': + return 'application/x-troff-msvideo'; + case 'avs': + return 'video/avs-video'; + case 'bcpio': + return 'application/x-bcpio'; + case 'bin': + return 'application/x-binary'; + case 'bm': + return 'image/bmp'; + case 'bmp': + return 'image/bmp'; + case 'boo': + return 'application/book'; + case 'book': + return 'application/book'; + case 'boz': + return 'application/x-bzip2'; + case 'bsh': + return 'application/x-bsh'; + case 'bz': + return 'application/x-bzip'; + case 'bz2': + return 'application/x-bzip2'; + case 'c': + return 'text/plain'; + case 'c++': + return 'text/plain'; + case 'cat': + return 'application/vnd.ms-pki.seccat'; + case 'cc': + return 'text/plain'; + case 'ccad': + return 'application/clariscad'; + case 'cco': + return 'application/x-cocoa'; + case 'cdf': + return 'application/cdf'; + case 'cer': + return 'application/pkix-cert'; + case 'cha': + return 'application/x-chat'; + case 'chat': + return 'application/x-chat'; + case 'class': + return 'application/java'; + case 'com': + return 'application/octet-stream'; + case 'conf': + return 'text/plain'; + case 'cpio': + return 'application/x-cpio'; + case 'cpp': + return 'text/x-c'; + case 'cpt': + return 'application/mac-compactpro'; + case 'crl': + return 'application/pkcs-crl'; + case 'csh': + return 'application/x-csh'; + case 'css': + return 'text/css'; + case 'cxx': + return 'text/plain'; + case 'dcr': + return 'application/x-director'; + case 'deepv': + return 'application/x-deepv'; + case 'def': + return 'text/plain'; + case 'der': + return 'application/x-x509-ca-cert'; + case 'dif': + return 'video/x-dv'; + case 'dir': + return 'application/x-director'; + case 'dl': + return 'video/dl'; + case 'doc': + return 'application/msword'; + case 'dot': + return 'application/msword'; + case 'dp': + return 'application/commonground'; + case 'drw': + return 'application/drafting'; + case 'dump': + return 'application/octet-stream'; + case 'dv': + return 'video/x-dv'; + case 'dvi': + return 'application/x-dvi'; + case 'dwf': + return 'drawing/x-dwf (old)'; + case 'dwg': + return 'application/acad'; + case 'dxf': + return 'application/dxf'; + case 'dxr': + return 'application/x-director'; + case 'el': + return 'text/x-script.elisp'; + case 'elc': + return 'application/x-bytecode.elisp (compiled elisp)'; + case 'env': + return 'application/x-envoy'; + case 'eps': + return 'application/postscript'; + case 'es': + return 'application/x-esrehber'; + case 'etx': + return 'text/x-setext'; + case 'evy': + return 'application/envoy'; + case 'exe': + return 'application/octet-stream'; + case 'f': + return 'text/plain'; + case 'f77': + return 'text/x-fortran'; + case 'f90': + return 'text/plain'; + case 'fdf': + return 'application/vnd.fdf'; + case 'fif': + return 'application/fractals'; + case 'fli': + return 'video/fli'; + case 'flo': + return 'image/florian'; + case 'flx': + return 'text/vnd.fmi.flexstor'; + case 'fmf': + return 'video/x-atomic3d-feature'; + case 'for': + return 'text/plain'; + case 'fpx': + return 'image/vnd.fpx'; + case 'frl': + return 'application/freeloader'; + case 'funk': + return 'audio/make'; + case 'g': + return 'text/plain'; + case 'g3': + return 'image/g3fax'; + case 'gif': + return 'image/gif'; + case 'gl': + return 'video/gl'; + case 'gsd': + return 'audio/x-gsm'; + case 'gsm': + return 'audio/x-gsm'; + case 'gsp': + return 'application/x-gsp'; + case 'gss': + return 'application/x-gss'; + case 'gtar': + return 'application/x-gtar'; + case 'gz': + return 'application/x-compressed'; + case 'gzip': + return 'application/x-gzip'; + case 'h': + return 'text/plain'; + case 'hdf': + return 'application/x-hdf'; + case 'help': + return 'application/x-helpfile'; + case 'hgl': + return 'application/vnd.hp-hpgl'; + case 'hh': + return 'text/plain'; + case 'hlb': + return 'text/x-script'; + case 'hlp': + return 'application/hlp'; + case 'hpg': + return 'application/vnd.hp-hpgl'; + case 'hpgl': + return 'application/vnd.hp-hpgl'; + case 'hqx': + return 'application/binhex'; + case 'hta': + return 'application/hta'; + case 'htc': + return 'text/x-component'; + case 'htm': + return 'text/html'; + case 'html': + return 'text/html'; + case 'htmls': + return 'text/html'; + case 'htt': + return 'text/webviewhtml'; + case 'htx': + return 'text/html'; + case 'ice': + return 'x-conference/x-cooltalk'; + case 'ico': + return 'image/x-icon'; + case 'idc': + return 'text/plain'; + case 'ief': + return 'image/ief'; + case 'iefs': + return 'image/ief'; + case 'iges': + return 'application/iges'; + case 'igs': + return 'application/iges'; + case 'ima': + return 'application/x-ima'; + case 'imap': + return 'application/x-httpd-imap'; + case 'inf': + return 'application/inf'; + case 'ins': + return 'application/x-internett-signup'; + case 'ip': + return 'application/x-ip2'; + case 'isu': + return 'video/x-isvideo'; + case 'it': + return 'audio/it'; + case 'iv': + return 'application/x-inventor'; + case 'ivr': + return 'i-world/i-vrml'; + case 'ivy': + return 'application/x-livescreen'; + case 'jam': + return 'audio/x-jam'; + case 'jav': + return 'text/plain'; + case 'java': + return 'text/plain'; + case 'jcm': + return 'application/x-java-commerce'; + case 'jfif': + return 'image/jpeg'; + case 'jfif-tbnl': + return 'image/jpeg'; + case 'jpe': + return 'image/jpeg'; + case 'jpeg': + return 'image/jpeg'; + case 'jpg': + return 'image/jpeg'; + case 'jps': + return 'image/x-jps'; + case 'js': + return 'application/x-javascript'; + case 'jut': + return 'image/jutvision'; + case 'kar': + return 'audio/midi'; + case 'ksh': + return 'application/x-ksh'; + case 'la': + return 'audio/nspaudio'; + case 'lam': + return 'audio/x-liveaudio'; + case 'latex': + return 'application/x-latex'; + case 'lha': + return 'application/lha'; + case 'lhx': + return 'application/octet-stream'; + case 'list': + return 'text/plain'; + case 'lma': + return 'audio/nspaudio'; + case 'log': + return 'text/plain'; + case 'lsp': + return 'application/x-lisp'; + case 'lst': + return 'text/plain'; + case 'lsx': + return 'text/x-la-asf'; + case 'ltx': + return 'application/x-latex'; + case 'lzh': + return 'application/octet-stream'; + case 'lzx': + return 'application/lzx'; + case 'm': + return 'text/plain'; + case 'm1v': + return 'video/mpeg'; + case 'm2a': + return 'audio/mpeg'; + case 'm2v': + return 'video/mpeg'; + case 'm3u': + return 'audio/x-mpequrl'; + case 'man': + return 'application/x-troff-man'; + case 'map': + return 'application/x-navimap'; + case 'mar': + return 'text/plain'; + case 'mbd': + return 'application/mbedlet'; + case 'mc$': + return 'application/x-magic-cap-package-1.0'; + case 'mcd': + return 'application/mcad'; + case 'mcf': + return 'image/vasa'; + case 'mcp': + return 'application/netmc'; + case 'me': + return 'application/x-troff-me'; + case 'mht': + return 'message/rfc822'; + case 'mhtml': + return 'message/rfc822'; + case 'mid': + return 'application/x-midi'; + case 'midi': + return 'audio/midi'; + case 'mif': + return 'application/x-frame'; + case 'mime': + return 'message/rfc822'; + case 'mjf': + return 'audio/x-vnd.audioexplosion.mjuicemediafile'; + case 'mjpg': + return 'video/x-motion-jpeg'; + case 'mm': + return 'application/base64'; + case 'mme': + return 'application/base64'; + case 'mod': + return 'audio/mod'; + case 'moov': + return 'video/quicktime'; + case 'mov': + return 'video/quicktime'; + case 'movie': + return 'video/x-sgi-movie'; + case 'mp2': + return 'video/mpeg'; + case 'mp3': + return 'video/mpeg'; + case 'mpa': + return 'audio/mpeg'; + case 'mpc': + return 'application/x-project'; + case 'mpe': + return 'video/mpeg'; + case 'mpeg': + return 'video/mpeg'; + case 'mpg': + return 'video/mpeg'; + case 'mpga': + return 'audio/mpeg'; + case 'mpp': + return 'application/vnd.ms-project'; + case 'mpt': + return 'application/x-project'; + case 'mpv': + return 'application/x-project'; + case 'mpx': + return 'application/x-project'; + case 'mrc': + return 'application/marc'; + case 'ms': + return 'application/x-troff-ms'; + case 'mv': + return 'video/x-sgi-movie'; + case 'my': + return 'audio/make'; + case 'mzz': + return 'application/x-vnd.audioexplosion.mzz'; + case 'nap': + return 'image/naplps'; + case 'naplps': + return 'image/naplps'; + case 'nc': + return 'application/x-netcdf'; + case 'ncm': + return 'application/vnd.nokia.configuration-message'; + case 'nif': + return 'image/x-niff'; + case 'niff': + return 'image/x-niff'; + case 'nix': + return 'application/x-mix-transfer'; + case 'nsc': + return 'application/x-conference'; + case 'nvd': + return 'application/x-navidoc'; + case 'o': + return 'application/octet-stream'; + case 'oda': + return 'application/oda'; + case 'omc': + return 'application/x-omc'; + case 'omcd': + return 'application/x-omcdatamaker'; + case 'omcr': + return 'application/x-omcregerator'; + case 'p': + return 'text/x-pascal'; + case 'p10': + return 'application/pkcs10'; + case 'p12': + return 'application/pkcs-12'; + case 'p7a': + return 'application/x-pkcs7-signature'; + case 'p7c': + return 'application/pkcs7-mime'; + case 'p7m': + return 'application/pkcs7-mime'; + case 'p7r': + return 'application/x-pkcs7-certreqresp'; + case 'p7s': + return 'application/pkcs7-signature'; + case 'part': + return 'application/pro_eng'; + case 'pas': + return 'text/pascal'; + case 'pbm': + return 'image/x-portable-bitmap'; + case 'pcl': + return 'application/vnd.hp-pcl'; + case 'pct': + return 'image/x-pict'; + case 'pcx': + return 'image/x-pcx'; + case 'pdb': + return 'chemical/x-pdb'; + case 'pdf': + return 'application/pdf'; + case 'pfunk': + return 'audio/make'; + case 'pgm': + return 'image/x-portable-graymap'; + case 'pic': + return 'image/pict'; + case 'pict': + return 'image/pict'; + case 'pkg': + return 'application/x-newton-compatible-pkg'; + case 'pko': + return 'application/vnd.ms-pki.pko'; + case 'pl': + return 'text/plain'; + case 'plx': + return 'application/x-pixclscript'; + case 'pm': + return 'image/x-xpixmap'; + case 'pm4': + return 'application/x-pagemaker'; + case 'pm5': + return 'application/x-pagemaker'; + case 'png': + return 'image/png'; + case 'pnm': + return 'application/x-portable-anymap'; + case 'pot': + return 'application/mspowerpoint'; + case 'pov': + return 'model/x-pov'; + case 'ppa': + return 'application/vnd.ms-powerpoint'; + case 'ppm': + return 'image/x-portable-pixmap'; + case 'pps': + return 'application/mspowerpoint'; + case 'ppt': + return 'application/mspowerpoint'; + case 'ppz': + return 'application/mspowerpoint'; + case 'pre': + return 'application/x-freelance'; + case 'prt': + return 'application/pro_eng'; + case 'ps': + return 'application/postscript'; + case 'psd': + return 'application/octet-stream'; + case 'pvu': + return 'paleovu/x-pv'; + case 'pwz': + return 'application/vnd.ms-powerpoint'; + case 'py': + return 'text/x-script.phyton'; + case 'pyc': + return 'applicaiton/x-bytecode.python'; + case 'qcp': + return 'audio/vnd.qcelp'; + case 'qd3': + return 'x-world/x-3dmf'; + case 'qd3d': + return 'x-world/x-3dmf'; + case 'qif': + return 'image/x-quicktime'; + case 'qt': + return 'video/quicktime'; + case 'qtc': + return 'video/x-qtc'; + case 'qti': + return 'image/x-quicktime'; + case 'qtif': + return 'image/x-quicktime'; + case 'ra': + return 'audio/x-pn-realaudio'; + case 'ram': + return 'audio/x-pn-realaudio'; + case 'ras': + return 'application/x-cmu-raster'; + case 'rast': + return 'image/cmu-raster'; + case 'rexx': + return 'text/x-script.rexx'; + case 'rf': + return 'image/vnd.rn-realflash'; + case 'rgb': + return 'image/x-rgb'; + case 'rm': + return 'application/vnd.rn-realmedia'; + case 'rmi': + return 'audio/mid'; + case 'rmm': + return 'audio/x-pn-realaudio'; + case 'rmp': + return 'audio/x-pn-realaudio'; + case 'rng': + return 'application/ringing-tones'; + case 'rnx': + return 'application/vnd.rn-realplayer'; + case 'roff': + return 'application/x-troff'; + case 'rp': + return 'image/vnd.rn-realpix'; + case 'rpm': + return 'audio/x-pn-realaudio-plugin'; + case 'rt': + return 'text/richtext'; + case 'rtf': + return 'application/rtf'; + case 'rtx': + return 'text/richtext'; + case 'rv': + return 'video/vnd.rn-realvideo'; + case 's': + return 'text/x-asm'; + case 's3m': + return 'audio/s3m'; + case 'saveme': + return 'application/octet-stream'; + case 'sbk': + return 'application/x-tbook'; + case 'scm': + return 'application/x-lotusscreencam'; + case 'sdml': + return 'text/plain'; + case 'sdp': + return 'application/sdp'; + case 'sdr': + return 'application/sounder'; + case 'sea': + return 'application/sea'; + case 'set': + return 'application/set'; + case 'sgm': + return 'text/sgml'; + case 'sgml': + return 'text/sgml'; + case 'sh': + return 'application/x-bsh'; + case 'shar': + return 'application/x-bsh'; + case 'shtml': + return 'text/html'; + case 'sid': + return 'audio/x-psid'; + case 'sit': + return 'application/x-sit'; + case 'skd': + return 'application/x-koan'; + case 'skm': + return 'application/x-koan'; + case 'skp': + return 'application/x-koan'; + case 'skt': + return 'application/x-koan'; + case 'sl': + return 'application/x-seelogo'; + case 'smi': + return 'application/smil'; + case 'smil': + return 'application/smil'; + case 'snd': + return 'audio/basic'; + case 'sol': + return 'application/solids'; + case 'spc': + return 'application/x-pkcs7-certificates'; + case 'spl': + return 'application/futuresplash'; + case 'spr': + return 'application/x-sprite'; + case 'sprite': + return 'application/x-sprite'; + case 'src': + return 'application/x-wais-source'; + case 'ssi': + return 'text/x-server-parsed-html'; + case 'ssm': + return 'application/streamingmedia'; + case 'sst': + return 'application/vnd.ms-pki.certstore'; + case 'step': + return 'application/step'; + case 'stl': + return 'application/sla'; + case 'stp': + return 'application/step'; + case 'sv4cpio': + return 'application/x-sv4cpio'; + case 'sv4crc': + return 'application/x-sv4crc'; + case 'svf': + return 'image/vnd.dwg'; + case 'svr': + return 'application/x-world'; + case 'swf': + return 'application/x-shockwave-flash'; + case 't': + return 'application/x-troff'; + case 'talk': + return 'text/x-speech'; + case 'tar': + return 'application/x-tar'; + case 'tbk': + return 'application/toolbook'; + case 'tcl': + return 'application/x-tcl'; + case 'tcsh': + return 'text/x-script.tcsh'; + case 'tex': + return 'application/x-tex'; + case 'texi': + return 'application/x-texinfo'; + case 'texinfo': + return 'application/x-texinfo'; + case 'text': + return 'text/plain'; + case 'tgz': + return 'application/x-compressed'; + case 'tif': + return 'image/tiff'; + case 'tiff': + return 'image/tiff'; + case 'tr': + return 'application/x-troff'; + case 'tsi': + return 'audio/tsp-audio'; + case 'tsp': + return 'application/dsptype'; + case 'tsv': + return 'text/tab-separated-values'; + case 'turbot': + return 'image/florian'; + case 'txt': + return 'text/plain'; + case 'uil': + return 'text/x-uil'; + case 'uni': + return 'text/uri-list'; + case 'unis': + return 'text/uri-list'; + case 'unv': + return 'application/i-deas'; + case 'uri': + return 'text/uri-list'; + case 'uris': + return 'text/uri-list'; + case 'ustar': + return 'multipart/x-ustar'; + case 'uu': + return 'application/octet-stream'; + case 'uue': + return 'text/x-uuencode'; + case 'vcd': + return 'application/x-cdlink'; + case 'vcs': + return 'text/x-vcalendar'; + case 'vda': + return 'application/vda'; + case 'vdo': + return 'video/vdo'; + case 'vew': + return 'application/groupwise'; + case 'viv': + return 'video/vivo'; + case 'vivo': + return 'video/vivo'; + case 'vmd': + return 'application/vocaltec-media-desc'; + case 'vmf': + return 'application/vocaltec-media-file'; + case 'voc': + return 'audio/voc'; + case 'vos': + return 'video/vosaic'; + case 'vox': + return 'audio/voxware'; + case 'vqe': + return 'audio/x-twinvq-plugin'; + case 'vqf': + return 'audio/x-twinvq'; + case 'vql': + return 'audio/x-twinvq-plugin'; + case 'vrml': + return 'application/x-vrml'; + case 'vrt': + return 'x-world/x-vrt'; + case 'vsd': + return 'application/x-visio'; + case 'vst': + return 'application/x-visio'; + case 'vsw': + return 'application/x-visio'; + case 'w60': + return 'application/wordperfect6.0'; + case 'w61': + return 'application/wordperfect6.1'; + case 'w6w': + return 'application/msword'; + case 'wav': + return 'audio/wav'; + case 'wb1': + return 'application/x-qpro'; + case 'wbmp': + return 'image/vnd.wap.wbmp'; + case 'web': + return 'application/vnd.xara'; + case 'wiz': + return 'application/msword'; + case 'wk1': + return 'application/x-123'; + case 'wmf': + return 'windows/metafile'; + case 'wml': + return 'text/vnd.wap.wml'; + case 'wmlc': + return 'application/vnd.wap.wmlc'; + case 'wmls': + return 'text/vnd.wap.wmlscript'; + case 'wmlsc': + return 'application/vnd.wap.wmlscriptc'; + case 'word': + return 'application/msword'; + case 'wp': + return 'application/wordperfect'; + case 'wp5': + return 'application/wordperfect6.0'; + case 'wp6': + return 'application/wordperfect'; + case 'wpd': + return 'application/x-wpwin'; + case 'wq1': + return 'application/x-lotus'; + case 'wri': + return 'application/mswrite'; + case 'wrl': + return 'model/vrml'; + case 'wrz': + return 'model/vrml'; + case 'wsc': + return 'text/scriplet'; + case 'wsrc': + return 'application/x-wais-source'; + case 'wtk': + return 'application/x-wintalk'; + case 'xbm': + return 'image/x-xbitmap'; + case 'xdr': + return 'video/x-amt-demorun'; + case 'xgz': + return 'xgl/drawing'; + case 'xif': + return 'image/vnd.xiff'; + case 'xl': + return 'application/excel'; + case 'xla': + return 'application/excel'; + case 'xlb': + return 'application/excel'; + case 'xlc': + return 'application/excel'; + case 'xld': + return 'application/excel'; + case 'xlk': + return 'application/excel'; + case 'xll': + return 'application/excel'; + case 'xlm': + return 'application/excel'; + case 'xls': + return 'application/excel'; + case 'xlt': + return 'application/excel'; + case 'xlv': + return 'application/excel'; + case 'xlw': + return 'application/excel'; + case 'xm': + return 'audio/xm'; + case 'xml': + return 'application/xml'; + case 'xmz': + return 'xgl/movie'; + case 'xpix': + return 'application/x-vnd.ls-xpix'; + case 'xpm': + return 'image/xpm'; + case 'x-png': + return 'image/png'; + case 'xsr': + return 'video/x-amt-showrun'; + case 'xwd': + return 'image/x-xwd'; + case 'xyz': + return 'chemical/x-pdb'; + case 'z': + return 'application/x-compress'; + case 'zip': + return 'application/x-compressed'; + case 'zoo': + return 'application/octet-stream'; + case 'zsh': + return 'text/x-script.zsh'; + default: + return 'application/octet-stream'; + } +} +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Multi.php b/thirdparty/pear/File/Archive/Reader/Multi.php new file mode 100644 index 0000000..b2c5ee3 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Multi.php @@ -0,0 +1,95 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Multi.php,v 1.10 2005/05/26 21:30:18 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Relay.php"; + +/** + * Regroups several readers to make them appear as a single one + */ +class File_Archive_Reader_Multi extends File_Archive_Reader_Relay +{ + /** + * @var Array All the sources regrouped in this reader + * @access private + */ + var $sources = array(); + /** + * @var Int Index of the source being read currently + * @access private + */ + var $currentIndex = 0; + + function File_Archive_Reader_Multi() + { + parent::File_Archive_Reader_Relay($tmp = null); + } + + /** + * Add a new reader to the list of readers + * @param File_Archive_Reader $source The source to add + */ + function addSource(&$source) + { + $this->sources[] =& $source; + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + while (array_key_exists($this->currentIndex, $this->sources)) { + $this->source =& $this->sources[$this->currentIndex]; + + if (($error = $this->source->next()) === false) { + $error = $this->source->close(); + if (PEAR::isError($error)) { + return $error; + } + $this->currentIndex++; + } else { + return $error; + } + } + return false; + } + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $error = parent::close(); + $this->currentIndex = 0; + return $error; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Relay.php b/thirdparty/pear/File/Archive/Reader/Relay.php new file mode 100644 index 0000000..c6e2323 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Relay.php @@ -0,0 +1,134 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Relay.php,v 1.19 2005/07/09 12:54:35 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; + +/** + * This reader appear exactly as $source does + * This is usefull if you want to dynamically change $source or change + * its behaviour + */ +class File_Archive_Reader_Relay extends File_Archive_Reader +{ + /** + * @var File_Archive_Reader This reader will have the same comportment as + * $source + * @access protected + */ + var $source; + + function File_Archive_Reader_Relay(&$source) + { + $this->source =& $source; + } + + /** + * @see File_Archive_Reader::next() + */ + function next() { return $this->source->next(); } + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->source->getFilename(); } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() { return $this->source->getStat(); } + /** + * @see File_Archive_Reader::getMime() + */ + function getMime() { return $this->source->getMime(); } + /** + * @see File_Archive_Reader::getDataFilename() + */ + function getDataFilename() { return $this->source->getDataFilename(); } + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) { return $this->source->getData($length); } + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) { return $this->source->skip($length); } + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) { return $this->source->rewind($length); } + /** + * @see File_Archive_Reader::tell() + */ + function tell() { return $this->source->tell(); } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + if ($this->source !== null) { + return $this->source->close(); + } + } + /** + * @see File_Archive_Reader::makeAppendWriter() + */ + function makeAppendWriter() + { + $writer = $this->source->makeAppendWriter(); + if (!PEAR::isError($writer)) { + $this->close(); + } + return $writer; + } + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + $writer = $this->source->makeWriterRemoveFiles($pred); + if (!PEAR::isError($writer)) { + $this->close(); + } + return $writer; + } + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + $writer = $this->source->makeWriterRemoveBlocks($blocks, $seek); + if (!PEAR::isError($writer)) { + $this->close(); + } + return $writer; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Select.php b/thirdparty/pear/File/Archive/Reader/Select.php new file mode 100644 index 0000000..a1a27fd --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Select.php @@ -0,0 +1,63 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Select.php,v 1.3 2005/05/26 21:30:18 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Relay.php"; + +/** + * Reader that keeps the files selected by File_Archive::select function + */ +class File_Archive_Reader_Select extends File_Archive_Reader_Relay +{ + /** + * @var File_Archive_Reader_Predicat + * @access private + */ + var $filename; + + /** + * $source is the reader to filter + */ + function File_Archive_Reader_Select($filename, &$source) + { + parent::File_Archive_Reader_Relay($source); + $this->filename = $filename; + } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + return $this->source->select($this->filename, false); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Tar.php b/thirdparty/pear/File/Archive/Reader/Tar.php new file mode 100644 index 0000000..ee16df6 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Tar.php @@ -0,0 +1,355 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Tar.php,v 1.29 2005/07/11 11:53:53 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Archive.php"; + +/** + * Read a tar archive + */ +class File_Archive_Reader_Tar extends File_Archive_Reader_Archive +{ + /** + * @var String Name of the file being read + * @access private + */ + var $currentFilename = null; + /** + * @var Array Stats of the file being read + * In TAR reader, indexes 2, 4, 5, 7, 9 are set + * @access private + */ + var $currentStat = null; + /** + * @var int Number of bytes that still have to be read before the end of + * file + * @access private + */ + var $leftLength = 0; + /** + * @var int Size of the footer + * A TAR file is made of chunks of 512 bytes. If 512 does not + * divide the file size a footer is added + * @access private + */ + var $footerLength = 0; + /** + * @var int nb bytes to seek back in order to reach the end of the archive + * or null if the end of the archive has not been reached + */ + var $seekToEnd = null; + + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + if ($length == -1) { + $length = $this->leftLength; + } else { + $length = min($this->leftLength, $length); + } + $skipped = $this->source->skip($length); + if (!PEAR::isError($skipped)) { + $this->leftLength -= $skipped; + } + return $skipped; + } + + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + if ($length == -1) { + $length = $this->currentStat[7] - $this->leftLength; + } else { + $length = min($length, $this->currentStat[7] - $this->leftLength); + } + $rewinded = $this->source->rewind($length); + if (!PEAR::isError($rewinded)) { + $this->leftLength += $rewinded; + } + return $rewinded; + } + + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->currentStat[7] - $this->leftLength; + } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $this->leftLength = 0; + $this->currentFilename = null; + $this->currentStat = null; + $this->seekToEnd = null; + return parent::close(); + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->currentFilename; } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() { return $this->currentStat; } + + /** + * @see File_Archive_Reader::next() + */ + function next() + { + $error = parent::next(); + if ($error !== true) { + return $error; + } + if ($this->seekToEnd !== null) { + return false; + } + + do + { + $error = $this->source->skip($this->leftLength + $this->footerLength); + if (PEAR::isError($error)) { + return $error; + } + $rawHeader = $this->source->getData(512); + if (PEAR::isError($rawHeader)) { + return $rawHeader; + } + if (strlen($rawHeader)<512 || $rawHeader == pack("a512", "")) { + $this->seekToEnd = strlen($rawHeader); + $this->currentFilename = null; + return false; + } + + $header = unpack( + "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/". + "a8checksum/a1type/a100linkname/a6magic/a2version/". + "a32uname/a32gname/a8devmajor/a8devminor/a155prefix", + $rawHeader); + $this->currentStat = array( + 2 => octdec($header['mode']), + 4 => octdec($header['uid']), + 5 => octdec($header['gid']), + 7 => octdec($header['size']), + 9 => octdec($header['mtime']) + ); + $this->currentStat['mode'] = $this->currentStat[2]; + $this->currentStat['uid'] = $this->currentStat[4]; + $this->currentStat['gid'] = $this->currentStat[5]; + $this->currentStat['size'] = $this->currentStat[7]; + $this->currentStat['mtime'] = $this->currentStat[9]; + + if ($header['magic'] == 'ustar') { + $this->currentFilename = $this->getStandardURL( + $header['prefix'] . $header['filename'] + ); + } else { + $this->currentFilename = $this->getStandardURL( + $header['filename'] + ); + } + + $this->leftLength = $this->currentStat[7]; + if ($this->leftLength % 512 == 0) { + $this->footerLength = 0; + } else { + $this->footerLength = 512 - $this->leftLength%512; + } + + $checksum = 8*ord(" "); + for ($i = 0; $i < 148; $i++) { + $checksum += ord($rawHeader{$i}); + } + for ($i = 156; $i < 512; $i++) { + $checksum += ord($rawHeader{$i}); + } + + if (octdec($header['checksum']) != $checksum) { + die('Checksum error on entry '.$this->currentFilename); + } + } while ($header['type'] != 0); + + return true; + } + + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($length == -1) { + $actualLength = $this->leftLength; + } else { + $actualLength = min($this->leftLength, $length); + } + + if ($this->leftLength == 0) { + return null; + } else { + $data = $this->source->getData($actualLength); + if (strlen($data) != $actualLength) { + return PEAR::raiseError('Unexpected end of tar archive'); + } + $this->leftLength -= $actualLength; + return $data; + } + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + require_once "File/Archive/Writer/Tar.php"; + + $blocks = array(); + $seek = null; + $gap = 0; + if ($this->currentFilename !== null && $pred->isTrue($this)) { + $seek = 512 + $this->currentStat[7] + $this->footerLength; + $blocks[] = $seek; //Remove this file + } + + while (($error = $this->next()) === true) { + $size = 512 + $this->currentStat[7] + $this->footerLength; + if ($pred->isTrue($this)) { + if ($seek === null) { + $seek = $size; + $blocks[] = $size; + } else if ($gap > 0) { + $blocks[] = $gap; //Don't remove the files between the gap + $blocks[] = $size; + $seek += $size; + } else { + $blocks[count($blocks)-1] += $size; //Also remove this file + $seek += $size; + } + $gap = 0; + } else { + if ($seek !== null) { + $seek += $size; + $gap += $size; + } + } + } + if ($seek === null) { + $seek = $this->seekToEnd; + } else { + $seek += $this->seekToEnd; + if ($gap == 0) { + array_pop($blocks); + } else { + $blocks[] = $gap; + } + } + + $writer = new File_Archive_Writer_Tar(null, + $this->source->makeWriterRemoveBlocks($blocks, -$seek) + ); + $this->close(); + return $writer; + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + if ($this->seekToEnd !== null || $this->currentStat === null) { + return PEAR::raiseError('No file selected'); + } + + $blockPos = $this->currentStat[7] - $this->leftLength + $seek; + + $this->rewind(); + $keep = false; + + $data = $this->getData($blockPos); + foreach ($blocks as $length) { + if ($keep) { + $data .= $this->getData($length); + } else { + $this->skip($length); + } + $keep = !$keep; + } + if ($keep) { + $data .= $this->getData(); + } + + $filename = $this->currentFilename; + $stat = $this->currentStat; + + $writer = $this->makeWriterRemove(); + if (PEAR::isError($writer)) { + return $writer; + } + + unset($stat[7]); + $stat[9] = $stat['mtime'] = time(); + $writer->newFile($filename, $stat); + $writer->writeData($data); + return $writer; + } + + /** + * @see File_Archive_Reader::makeAppendWriter + */ + function makeAppendWriter() + { + require_once "File/Archive/Writer/Tar.php"; + + while (($error = $this->next()) === true) { } + if (PEAR::isError($error)) { + $this->close(); + return $error; + } + + $innerWriter = $this->source->makeWriterRemoveBlocks(array(), -$this->seekToEnd); + if (PEAR::isError($innerWriter)) { + return $innerWriter; + } + + $this->close(); + return new File_Archive_Writer_Tar(null, $innerWriter); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Uncompress.php b/thirdparty/pear/File/Archive/Reader/Uncompress.php new file mode 100644 index 0000000..eb24ee3 --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Uncompress.php @@ -0,0 +1,312 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Uncompress.php,v 1.32 2005/07/09 12:54:35 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader.php"; +require_once "File/Archive/Reader/ChangeName.php"; + +/** + * Recursively uncompress every file it finds + */ +class File_Archive_Reader_Uncompress extends File_Archive_Reader_Relay +{ + /** + * @var Array Stack of readers + * @access private + */ + var $readers = array(); + + /** + * @var array of readers to close when closing $this + * @access private + */ + var $toClose = array(); + + /** + * @var File_Archive_Reader Reader from which all started (usefull to be + * able to close) + * @access private + */ + var $startReader; + + /** + * @var Int Maximum depth of uncompression after the basicDir + * (that may contain some uncompression also) + * -1 means no limit + * @access private + */ + var $uncompressionLevel; + + /** + * @var array Only files starting with $baseDir will be reported + * This array contains explode('/', $directoryName) + * @access private + */ + var $baseDir = ''; + + /** + * @var int Compression level required to go to reach the baseDir + * or null if it is currently being computed + * @access private + */ + var $baseDirCompressionLevel = null; + + /** + * @var int We are selecting substr($baseDir, 0, $baseDirProgression) + */ + var $baseDirProgression = 0; + + /** + * @var boolean Flag set to indicate that the current file has not been + * displayed + */ + var $currentFileNotDisplayed = false; + + function File_Archive_Reader_Uncompress( + &$innerReader, $uncompressionLevel = -1) + { + parent::File_Archive_Reader_Relay($innerReader); + $this->startReader =& $innerReader; + $this->uncompressionLevel = $uncompressionLevel; + } + + /** + * Attempt to change the current source (if the current file is an archive) + * If this is the case, push the current source onto the stack and make the + * good archive reader the current source. A file is considered as an + * archive if its extension is one of tar, gz, zip, tgz + * + * @return bool whether the source has been pushed or not + * @access private + */ + function push() + { + if ($this->uncompressionLevel >= 0 && + $this->baseDirCompressionLevel !== null && + count($this->readers) >= $this->uncompressionLevel + ) { + return false; + } + + // Check the extension of the file (maybe we need to uncompress it?) + $filename = $this->source->getFilename(); + + $extensions = explode('.', strtolower($filename)); + + $reader =& $this->source; + $nbUncompressions = 0; + + while (($extension = array_pop($extensions)) !== null) { + $nbUncompressions++; + unset($next); + $next = File_Archive::readArchive($extension, $reader, $nbUncompressions == 1); + if ($next === false) { + $extensions = array(); + } else { + unset($reader); + $reader =& $next; + } + } + if ($nbUncompressions == 1) { + return false; + } else { + $this->readers[count($this->readers)] =& $this->source; + unset($this->source); + $this->source = new File_Archive_Reader_AddBaseName( + $filename, $reader + ); + return true; + } + } + /** + * @see File_Archive_Reader::close() + */ + function next() + { + if ($this->currentFileNotDisplayed) { + $this->currentFileNotDisplayed = false; + return true; + } + + do { + do { + $selection = substr($this->baseDir, 0, $this->baseDirProgression); + if ($selection === false) { + $selection = ''; + } + + $error = $this->source->select($selection, false); + if (PEAR::isError($error)) { + return $error; + } + if (!$error) { + if (empty($this->readers)) { + return false; + } + $this->source->close(); + unset($this->source); + $this->source =& $this->readers[count($this->readers)-1]; + unset($this->readers[count($this->readers)-1]); + } + } while (!$error); + + $filename = $this->source->getFilename(); + if (strlen($filename) < strlen($this->baseDir)) { + $goodFile = (strncmp($filename, $this->baseDir, strlen($filename)) == 0 && + $this->baseDir{strlen($filename)} == '/'); + if ($goodFile) { + if (strlen($filename) + 2 < strlen($this->baseDirProgression)) { + $this->baseDirProgression = strpos($this->baseDir, '/', strlen($filename)+2); + if ($this->baseDirProgression === false) { + $this->baseDirProgression = strlen($this->baseDir); + } + } else { + $this->baseDirProgression = strlen($this->baseDir); + } + } + } else { + $goodFile = (strncmp($filename, $this->baseDir, strlen($this->baseDir)) == 0); + if ($goodFile) { + $this->baseDirProgression = strlen($this->baseDir); + } + } + } while ($goodFile && $this->push()); + + return true; + } + + /** + * Efficiently filter out the files which URL does not start with $baseDir + * Throws an error if the $baseDir can't be found + * @return bool Whether baseDir was a directory or a file + */ + function setBaseDir($baseDir) + { + $this->baseDir = $baseDir; + $this->baseDirProgression = strpos($baseDir, '/'); + if ($this->baseDirProgression === false) { + $this->baseDirProgression = strlen($baseDir); + } + + $error = $this->next(); + if ($error === false) { + return PEAR::raiseError("No directory $baseDir in inner reader"); + } else if (PEAR::isError($error)) { + return $error; + } + + $this->currentFileNotDisplayed = true; + return strlen($this->getFilename())>strlen($baseDir); + } + /** + * @see File_Archive_Reader::select() + */ + function select($filename, $close = true) + { + if ($close) { + $error = $this->close(); + if (PEAR::isError($close)) { + return $error; + } + } + + $oldBaseDir = $this->baseDir; + $oldProgression = $this->baseDirProgression; + + $this->baseDir = $filename; + $this->baseDirProgression = 0; + + $res = $this->next(); + + $this->baseDir = $oldBaseDir; + $this->baseDirProgression = $oldProgression; + + return $res; + } + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + for ($i=0; $ireaders); ++$i) { + $this->readers[$i]->close(); + } + //var_dump($this->toClose); + for ($i=0; $itoClose); ++$i) { + if ($this->toClose[$i] !== null) { + $this->toClose[$i]->close(); + } + } + + $this->readers = array(); + $this->toClose = array(); + $error = parent::close(); + $this->baseDirCompressionLevel = null; + $this->baseDirProgression = 0; + + unset($this->source); + $this->source =& $this->startReader; + $this->source->close(); + $this->currentFileNotDisplayed = false; + + return $error; + } + + /** + * @see File_Archive_Reader::makeAppendWriter() + */ + function makeAppendWriter() + { + //The reader needs to be open so that the base dir is found + $error = $this->next(); + if (PEAR::isError($error)) { + return $error; + } + + return parent::makeAppendWriter(); + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + //The reader needs to be open so that the base dir is found + $error = $this->next(); + if (PEAR::isError($error)) { + return $error; + } + + return parent::makeWriterRemoveFiles($pred); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Reader/Zip.php b/thirdparty/pear/File/Archive/Reader/Zip.php new file mode 100644 index 0000000..44d8aad --- /dev/null +++ b/thirdparty/pear/File/Archive/Reader/Zip.php @@ -0,0 +1,493 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Zip.php,v 1.26 2005/06/19 20:09:58 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Reader/Archive.php"; + +/** + * ZIP archive reader + * Currently only allows to browse the archive (getData is not available) + */ +class File_Archive_Reader_Zip extends File_Archive_Reader_Archive +{ + var $currentFilename = null; + var $currentStat = null; + var $header = null; + var $offset = 0; + var $data = null; + var $files = array(); + var $seekToEnd = 0; + + var $centralDirectory = null; + + /** + * @see File_Archive_Reader::close() + */ + function close() + { + $this->currentFilename = null; + $this->currentStat = null; + $this->compLength = 0; + $this->data = null; + $this->seekToEnd = 0; + $this->files = array(); + $this->centralDirectory = null; + + return parent::close(); + } + + /** + * @see File_Archive_Reader::getFilename() + */ + function getFilename() { return $this->currentFilename; } + /** + * @see File_Archive_Reader::getStat() + */ + function getStat() { return $this->currentStat; } + + /** + * Go to next entry in ZIP archive + * This function may stop on a folder, so it does not comply to the + * File_Archive_Reader::next specs + * + * @see File_Archive_Reader::next() + */ + function nextWithFolders() + { + if ($this->seekToEnd > 0) { + return false; + } + + //Skip the data and the footer if they haven't been uncompressed + if ($this->header !== null && $this->data === null) { + $toSkip = $this->header['CLen']; + $error = $this->source->skip($toSkip); + if (PEAR::isError($error)) { + return $error; + } + } + + $this->offset = 0; + $this->data = null; + + //Read the header + $header = $this->source->getData(4); + if (PEAR::isError($header)) { + return $header; + } + if ($header == "\x50\x4b\x03\x04") { + //New entry + $header = $this->source->getData(26); + if (PEAR::isError($header)) { + return $header; + } + $this->header = unpack( + "vVersion/vFlag/vMethod/vTime/vDate/VCRC/VCLen/VNLen/vFile/vExtra", + $header); + + //Check the compression method + if ($this->header['Method'] != 0 && + $this->header['Method'] != 8 && + $this->header['Method'] != 12) { + return PEAR::raiseError("File_Archive_Reader_Zip doesn't ". + "handle compression method {$this->header['Method']}"); + } + if ($this->header['Flag'] & 1) { + return PEAR::raiseError("File_Archive_Reader_Zip doesn't ". + "handle encrypted files"); + } + if ($this->header['Flag'] & 8) { + if ($this->centralDirectory === null) { + $this->readCentralDirectory(); + } + $centralDirEntry = $this->centralDirectory[count($this->files)]; + + $this->header['CRC'] = $centralDirEntry['CRC']; + $this->header['CLen'] = $centralDirEntry['CLen']; + $this->header['NLen'] = $centralDirEntry['NLen']; + } + if ($this->header['Flag'] & 32) { + return PEAR::raiseError("File_Archive_Reader_Zip doesn't ". + "handle compressed patched data"); + } + if ($this->header['Flag'] & 64) { + return PEAR::raiseError("File_Archive_Reader_Zip doesn't ". + "handle strong encrypted files"); + } + + $this->currentStat = array( + 7=>$this->header['NLen'], + 9=>mktime( + ($this->header['Time'] & 0xF800) >> 11, //hour + ($this->header['Time'] & 0x07E0) >> 5, //minute + ($this->header['Time'] & 0x001F) >> 1, //second + ($this->header['Date'] & 0x01E0) >> 5, //month + ($this->header['Date'] & 0x001F) , //day + (($this->header['Date'] & 0xFE00) >> 9) + 1980 //year + ) + ); + $this->currentStat['size'] = $this->currentStat[7]; + $this->currentStat['mtime'] = $this->currentStat[9]; + + $this->currentFilename = $this->source->getData($this->header['File']); + + $error = $this->source->skip($this->header['Extra']); + if (PEAR::isError($error)) { + return $error; + } + + $this->files[] = array('name' => $this->currentFilename, + 'stat' => $this->currentStat, + 'CRC' => $this->header['CRC'], + 'CLen' => $this->header['CLen'] + ); + + return true; + } else { + //Begining of central area + $this->seekToEnd = 4; + $this->currentFilename = null; + return false; + } + } + /** + * Go to next file entry in ZIP archive + * This function will not stop on a folder entry + * @see File_Archive_Reader::next() + */ + function next() + { + if (!parent::next()) { + return false; + } + + do { + $result = $this->nextWithFolders(); + if ($result !== true) { + return $result; + } + } while (substr($this->getFilename(), -1) == '/'); + + return true; + } + + /** + * @see File_Archive_Reader::getData() + */ + function getData($length = -1) + { + if ($this->offset >= $this->currentStat[7]) { + return null; + } + + if ($length>=0) { + $actualLength = min($length, $this->currentStat[7]-$this->offset); + } else { + $actualLength = $this->currentStat[7]-$this->offset; + } + + $error = $this->uncompressData(); + if (PEAR::isError($error)) { + return $error; + } + $result = substr($this->data, $this->offset, $actualLength); + $this->offset += $actualLength; + return $result; + } + /** + * @see File_Archive_Reader::skip() + */ + function skip($length = -1) + { + $before = $this->offset; + if ($length == -1) { + $this->offset = $this->currentStat[7]; + } else { + $this->offset = min($this->offset + $length, $this->currentStat[7]); + } + return $this->offset - $before; + } + /** + * @see File_Archive_Reader::rewind() + */ + function rewind($length = -1) + { + $before = $this->offset; + if ($length == -1) { + $this->offset = 0; + } else { + $this->offset = min(0, $this->offset - $length); + } + return $before - $this->offset; + } + /** + * @see File_Archive_Reader::tell() + */ + function tell() + { + return $this->offset; + } + + function uncompressData() + { + if ($this->data !== null) + return; + + $this->data = $this->source->getData($this->header['CLen']); + if (PEAR::isError($this->data)) { + return $this->data; + } + if ($this->header['Method'] == 8) { + $this->data = gzinflate($this->data); + } + if ($this->header['Method'] == 12) { + $this->data = bzdecompress($this->data); + } + + if (crc32($this->data) != $this->header['CRC']) { + return PEAR::raiseError("Zip archive: CRC fails on entry ". + $this->currentFilename); + } + } + + /** + * @see File_Archive_Reader::makeWriterRemoveFiles() + */ + function makeWriterRemoveFiles($pred) + { + require_once "File/Archive/Writer/Zip.php"; + + $blocks = array(); + $seek = null; + $gap = 0; + if ($this->currentFilename !== null && $pred->isTrue($this)) { + $seek = 30 + $this->header['File'] + $this->header['Extra'] + $this->header['CLen']; + $blocks[] = $seek; //Remove this file + array_pop($this->files); + } + + while (($error = $this->nextWithFolders()) === true) { + $size = 30 + $this->header['File'] + $this->header['Extra'] + $this->header['CLen']; + if (substr($this->getFilename(), -1) == '/' || $pred->isTrue($this)) { + array_pop($this->files); + if ($seek === null) { + $seek = $size; + $blocks[] = $size; + } else if ($gap > 0) { + $blocks[] = $gap; //Don't remove the files between the gap + $blocks[] = $size; + $seek += $size; + } else { + $blocks[count($blocks)-1] += $size; //Also remove this file + $seek += $size; + } + $gap = 0; + } else { + if ($seek !== null) { + $seek += $size; + $gap += $size; + } + } + } + if (PEAR::isError($error)) { + return $error; + } + + if ($seek === null) { + $seek = 4; + } else { + $seek += 4; + if ($gap == 0) { + array_pop($blocks); + } else { + $blocks[] = $gap; + } + } + + $writer = new File_Archive_Writer_Zip(null, + $this->source->makeWriterRemoveBlocks($blocks, -$seek) + ); + if (PEAR::isError($writer)) { + return $writer; + } + + foreach ($this->files as $file) { + $writer->alreadyWrittenFile($file['name'], $file['stat'], $file['CRC'], $file['CLen']); + } + + $this->close(); + return $writer; + } + + /** + * @see File_Archive_Reader::makeWriterRemoveBlocks() + */ + function makeWriterRemoveBlocks($blocks, $seek = 0) + { + if ($this->currentFilename === null) { + return PEAR::raiseError('No file selected'); + } + + $keep = false; + + $this->uncompressData(); + $newData = substr($this->data, 0, $this->offset + $seek); + $this->data = substr($this->data, $this->offset + $seek); + foreach ($blocks as $length) { + if ($keep) { + $newData .= substr($this->data, 0, $length); + } + $this->data = substr($this->data, $length); + $keep = !$keep; + } + if ($keep) { + $newData .= $this->data; + } + + $filename = $this->currentFilename; + $stat = $this->currentStat; + + $writer = $this->makeWriterRemove(); + if (PEAR::isError($writer)) { + return $writer; + } + + unset($stat[7]); + $stat[9] = $stat['mtime'] = time(); + $writer->newFile($filename, $stat); + $writer->writeData($newData); + return $writer; + } + + /** + * @see File_Archive_Reader::makeAppendWriter + */ + function makeAppendWriter() + { + require_once "File/Archive/Writer/Zip.php"; + + while (($error = $this->next()) === true) { } + if (PEAR::isError($error)) { + $this->close(); + return $error; + } + + $writer = new File_Archive_Writer_Zip(null, + $this->source->makeWriterRemoveBlocks(array(), -4) + ); + + foreach ($this->files as $file) { + $writer->alreadyWrittenFile($file['name'], $file['stat'], $file['CRC'], $file['CLen']); + } + + $this->close(); + return $writer; + } + + /** + * This function seeks to the start of the [end of central directory] field, + * just after the \x50\x4b\x05\x06 signature and returns the number of bytes + * skipped + * + * The stream must initially be positioned before the end of central directory + */ + function seekToEndOfCentralDirectory() + { + $nbSkipped = $this->source->skip(); + + $nbSkipped -= $this->source->rewind(22) - 4; + if ($this->source->getData(4) == "\x50\x4b\x05\x06") { + return $nbSkipped; + } + + while ($nbSkipped > 0) { + + $nbRewind = $this->source->rewind(min(100, $nbSkipped)); + while ($nbRewind >= -4) { + if ($nbRewind-- && $this->source->getData(1) == "\x50" && + $nbRewind-- && $this->source->getData(1) == "\x4b" && + $nbRewind-- && $this->source->getData(1) == "\x05" && + $nbRewind-- && $this->source->getData(1) == "\x06") { + //We finally found it! + return $nbSkipped - $nbRewind; + } + } + $nbSkipped -= $nbRewind; + } + + return PEAR::raiseError('End of central directory not found. The file is probably not a zip archive'); + } + + /** + * This function will fill the central directory variable + * and seek back to where it was called + */ + function readCentralDirectory() + { + $nbSkipped = $this->seekToEndOfCentralDirectory(); + if (PEAR::isError($nbSkipped)) { + return $nbSkipped; + } + + $this->source->skip(12); + $offset = $this->source->getData(4); + $nbSkipped += 16; + if (PEAR::isError($offset)) { + return $offset; + } + + $offset = unpack("Vvalue", $offset); + $offset = $offset['value']; + + $current = $this->source->tell(); + $nbSkipped -= $this->source->rewind($current - $offset); + + //Now we are the right pos to read the central directory + $this->centralDirectory = array(); + while ($this->source->getData(4) == "\x50\x4b\x01\x02") { + $this->source->skip(12); + $header = $this->source->getData(16); + $nbSkipped += 32; + + if (PEAR::isError($header)) { + return $header; + } + + $header = unpack('VCRC/VCLen/VNLen/vFileLength/vExtraLength', $header); + $this->centralDirectory[] = array('CRC' => $header['CRC'], + 'CLen' => $header['CLen'], + 'NLen' => $header['NLen']); + $nbSkipped += $this->source->skip(14 + $header['FileLength'] + $header['ExtraLength']); + } + + $this->source->rewind($nbSkipped+4); + } +} +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer.php b/thirdparty/pear/File/Archive/Writer.php new file mode 100644 index 0000000..3785f07 --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer.php @@ -0,0 +1,119 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Writer.php,v 1.12 2005/05/31 21:22:02 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "PEAR.php"; + +/** + * Base class for any writer + */ +class File_Archive_Writer +{ + /** + * Create a new file in the writer + * + * @param string $filename Name of the file, eventually including a path + * @param array $stat Its Statistics. None of the indexes are required + * @param string $mime MIME type of the file + */ + function newFile($filename, $stat = array(), $mime = "application/octet-stream") + { + } + + /** + * Create a new file in the writer with the content of the physical file $filename + * and then unlink $filename. + * newFromTempFile($tmpfile, $filename, $stat, $mime) is equivalent to + * newFile($filename, $stat, $mime); writeFile($tmpfile); unlink($tmpfile); + * but can be more efficient. + * A typical use is for File_Archive_Writer_Files: it renames the temporary + * file instead of copy/delete + * + * @param string $tmpfile Name of the physical file that contains data and will be unlinked + * @param string $filename Name of the file, eventually including a path + * @param array $stat Its Statistics. None of the indexes are required + * @param string $mime MIME type of the file + */ + function newFromTempFile($tmpfile, $filename, $stat = array(), $mime = "application/octet-stream") + { + $this->newFile($filename, $stat, $mime); + $this->writeFile($tmpfile); + unlink($tmpfile); + } + + /** + * Returns whether the writer newFile function needs the $mime parameter + * Default is false + */ + function newFileNeedsMIME() + { + return false; + } + + /** + * Append the specified data to the writer + * + * @param String $data the data to append to the writer + */ + function writeData($data) + { + } + + /** + * Append the content of the physical file $filename to the writer + * writeFile($filename) must be equivalent to + * writeData(file_get_contents($filename)) but can be more efficient + * + * @param string $filename Name of the file which content must be appended + * to the writer + */ + function writeFile($filename) + { + $handle = fopen($filename, "r"); + if (!is_resource($handle)) { + return PEAR::raiseError("Unable to write to $filename"); + } + while (!feof($handle)) { + $error = $this->writeData(fread($handle, 102400)); + if (PEAR::isError($error)) { + return $error; + } + } + fclose($handle); + } + + /** + * Close the writer, eventually flush the data, write the footer... + * This function must be called before the end of the script + */ + function close() { } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/AddBaseName.php b/thirdparty/pear/File/Archive/Writer/AddBaseName.php new file mode 100644 index 0000000..7444ca6 --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/AddBaseName.php @@ -0,0 +1,102 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: AddBaseName.php,v 1.1 2005/06/02 22:45:58 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Writer wrapper that adds a directory to the written file + */ +class File_Archive_Writer_AddBaseName +{ + var $writer; + var $baseName; + + function File_Archive_Writer_AddBaseName($baseName, &$writer) + { + if (substr($baseName, -1) == '/') { + $this->baseName = $baseName; + } else { + $this->baseName = $baseName.'/'; + } + + $this->writer =& $writer; + } + + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat = array(), $mime = "application/octet-stream") + { + $this->writer->newFile($this->baseName.$filename, $stat, $mime); + } + + /** + * @see File_Archive_Writer::newFromTempFile() + */ + function newFromTempFile($tmpfile, $filename, $stat = array(), $mime = "application/octet-stream") + { + $this->writer->newFromTempFile($tmpfilen $this->baseName.$filename, $stat, $mime); + } + + /** + * @see File_Archive_Writer::newFileNeedsMIME() + */ + function newFileNeedsMIME() + { + return $this->writer->newFileNeedsMIME(); + } + + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + $this->writer->writeData($data); + } + + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) + { + $this->writer->writeFile($filename); + } + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + $this->writer->close(); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/Ar.php b/thirdparty/pear/File/Archive/Writer/Ar.php new file mode 100644 index 0000000..5ddc051 --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/Ar.php @@ -0,0 +1,204 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer/Archive.php"; + +/** + * Write the files as an AR archive + */ +class File_Archive_Writer_Ar extends File_Archive_Writer_Archive +{ + + /** + * @var string Current data of the file. + * @access private + */ + var $_buffer = ""; + + /** + * @var string Filename of the current filename + * @access private + */ + var $_currentFilename = null; + + /** + * @var boolean Flag: use buffer or not. + * @access private + */ + var $_useBuffer; + + /** + * @var array Stats of the current filename + * @access private + */ + var $_currentStat = array (); + + /** + * @var boolean Flag: beginning of the archive or not + * @access private + */ + var $_atStart = true; + + /** + * Returns the header of the current file. + * + * More Info: + * http://publibn.boulder.ibm.com/doc_link/en_US/a_doc_lib/files/aixfiles/ar_IA64.htm + * + * @access private + * @param string $filename Name of the current file + * @param array $stat Stat array of the current file + * @return string The built header struct + */ + function arHeader ($filename, $stat) + { + $mode = isset($stat[2]) ? $stat[2] : 0x8000; + $uid = isset($stat[4]) ? $stat[4] : 0; + $gid = isset($stat[5]) ? $stat[5] : 0; + $size = $stat[7]; + $time = isset($stat[9]) ? $stat[9] : time(); + + $struct = ""; + $currentSize = $size; + //if file length is > than 16.. + if (strlen($filename) > 16) { + $currentSize += strlen($filename); + $struct .= sprintf("#1/%-13d", strlen($filename)); + $struct .= sprintf("%-12d%-6d%-6d%-8s%-10d", + $time, $uid, $gid, $mode, $currentSize); + $struct .= "`\n".$filename; + } else { + $struct .= sprintf("%-16s", $filename); + $struct .= sprintf("%-12d%-6d%-6d%-8s%-10d`\n", + $time, $uid, $gid, $mode, $size); + } + return $struct; + } + + /** + * Returns the footer of the current file, the footer depends + * of the size of the file + * + * @access private + * @param string $filename Name of the file, the footer depends on its length + * @param int $size Size of the current file, here the size does matters! + * @return string The footer struct + */ + function arFooter($filename, $size) + { + $size = (strlen ($filename) > 16) ? $size + strlen($filename) : $size; + + return ($size % 2 == 1) ? "\n" : ""; + } + + + /** + * Flush the memory we have in the ar. + * + * Build the buffer if its called at the end or initialize + * it if we are just creating it from the start. + */ + function flush() + { + if ($this->_atStart) { + $this->innerWriter->writeData("!\n"); + $this->_atStart = false; + } + if ($this->_currentFilename !== null) { + $this->_currentStat[7] = strlen($this->_buffer); + if ($this->_useBuffer) { + $this->innerWriter->writeData( + $this->arHeader($this->_currentFilename, $this->_currentStat) + ); + $this->innerWriter->writeData($this->_buffer); + } + $this->innerWriter->writeData($this->arFooter($this->_currentFilename, $this->_currentStat[7])); + } + $this->_buffer = ""; + } + + /** + * @see File_Archive_Writer::newFile() + * + */ + function newFile($filename, $stat = array (), + $mime = "application/octet-stream") + { + $this->flush(); + /* + * If the file is empty, there's no reason to have a buffer + * or use memory + */ + $this->_useBuffer = !isset($stats[7]); + /* + * Becaue ar fileformats doesn't support files in directories, + * then we need to just save with the filename an ommit the + * directory + */ + $this->_currentFilename = basename($filename); + $this->_currentStat = $stat; + + if(!$this->_useBuffer) { + return $this->innerWriter->writeData($this->arHeader($filename, $stat)); + } + } + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + $this->flush(); + parent::close(); + } + + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + if ($this->_useBuffer) { + $this->_buffer .= $data; + } else { + $this->innerWriter->writeData($data); + } + + } + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) + { + if ($this->_useBuffer) { + $this->_buffer .= file_get_contents($filename); + } else { + $this->innerWriter->writeFile($filename); + } + } +} \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/Archive.php b/thirdparty/pear/File/Archive/Writer/Archive.php new file mode 100644 index 0000000..8efe7af --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/Archive.php @@ -0,0 +1,99 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Archive.php,v 1.12 2005/06/02 12:24:43 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Base class for all the transformation writers that will generate one single + * file + */ +class File_Archive_Writer_Archive extends File_Archive_Writer +{ + /** + * @var File_Archive_Writer The compressed data will be written to this + * writer + * @access protected + */ + var $innerWriter; + + /** + * @var bool If true, the innerWriter will be closed when closing this + * @access private + */ + var $autoClose; + + /** + * @param String $filename Name to give to the archive (the name will + * be used by the inner writer) + * If $filename is null, the innerWriter is considered already + * opened (and thus newFile will not be called) + * @param File_Archive_Writer $innerWriter The inner writer to which the + * compressed data will be written + * @param array $stat The stat of the archive (see the PHP stat() function). + * No element are required in this array + * @param bool $autoClose Indicate if the inner writer must be closed when + * closing this + */ + function File_Archive_Writer_Archive($filename, &$innerWriter, + $stat = array(), $autoClose = true) + { + $this->innerWriter =& $innerWriter; + $this->autoClose = $autoClose; + if ($filename !== null) { + $this->innerWriter->newFile($filename, $stat, $this->getMime()); + } + } + +//MUST REWRITE FUNCTIONS + //function newFile($filename, $stat, $mime) { } + + /** + * @return the MIME extension of the files generated by this writer + */ + function getMime() { return "application/octet-stream"; } + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + if ($this->autoClose) { + return $this->innerWriter->close(); + } + } +// function writeData($data) + +//SHOULD REWRITE FUNCTIONS +// function writeFile($filename) +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/Bzip2.php b/thirdparty/pear/File/Archive/Writer/Bzip2.php new file mode 100644 index 0000000..5832c02 --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/Bzip2.php @@ -0,0 +1,137 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Bzip2.php,v 1.9 2005/06/02 16:22:47 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Compress a single file to Bzip2 format + */ +class File_Archive_Writer_Bzip2 extends File_Archive_Writer +{ + var $compressionLevel=9; + var $bzfile; + var $tmpName; + var $nbFiles = 0; + + var $innerWriter; + var $autoClose; + var $filename; + var $stat; + + /** + * @param string $filename Name to give to the archive + * @param File_Archive_Writer $innerWriter The inner writer to which the + * compressed data will be written + * @param array $stat The stat of the archive (see the PHP stat() function). + * No element are required in this array + * @param bool $autoClose Indicate if the inner writer must be closed when + * closing this + */ + function File_Archive_Writer_Bzip2($filename, &$innerWriter, + $stat = array(), $autoClose = true) + { + $this->innerWriter =& $innerWriter; + $this->autoClose = $autoClose; + + $this->filename = $filename; + $this->stat = $stat; + + if ($this->filename === null) { + $this->newFile(null); + } + } + + /** + * Set the compression level + * + * @param int $compressionLevel From 0 (no compression) to 9 (best + * compression) + */ + function setCompressionLevel($compressionLevel) + { + $this->compressionLevel = $compressionLevel; + } + + /** + * @see File_Archive_Writer::newFile() + * + * Check that one single file is written in the BZip2 archive + */ + function newFile($filename, $stat = array(), + $mime = "application/octet-stream") + { + if ($this->nbFiles > 1) { + return PEAR::raiseError("A Bzip2 archive can only contain one single file.". + "Use Tbz archive to be able to write several files"); + } + $this->nbFiles++; + + $this->tmpName = tempnam(File_Archive::getOption('tmpDirectory'), 'far'); + $this->bzfile = bzopen($this->tmpName, 'w'.$this->compressionLevel); + + return true; + } + + /** + * Actually write the tmp file to the inner writer + * Close and delete temporary file + * + * @see File_Archive_Writer::close() + */ + function close() + { + bzclose($this->bzfile); + + if ($this->filename === null) { + //Assume innerWriter is already opened on a file... + $this->innerWriter->writeFile($this->tmpName); + unlink($this->tmpName); + } else { + $this->innerWriter->newFromTempFile( + $this->tmpName, $this->filename, $this->stat, 'application/x-compressed' + ); + } + + if ($this->autoClose) { + return $this->innerWriter->close(); + } + } + + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + bzwrite($this->bzfile, $data); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/Files.php b/thirdparty/pear/File/Archive/Writer/Files.php new file mode 100644 index 0000000..501fbb6 --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/Files.php @@ -0,0 +1,250 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Files.php,v 1.21 2005/06/18 23:08:16 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Writer to files + */ +class File_Archive_Writer_Files extends File_Archive_Writer +{ + /** + * @var Object Handle to the file where the data are currently written + * @access private + */ + var $handle = null; + var $basePath; + var $stat = array(); + var $filename; + + function File_Archive_Writer_Files($base = '') + { + if ($base === null || $base == '') { + $this->basePath = ''; + } else { + if (substr($base, -1) == '/') { + $this->basePath = $base; + } else { + $this->basePath = $base.'/'; + } + } + } + + function getFilename($filename) + { + return $this->basePath.$filename; + } + + /** + * Ensure that $pathname exists, or create it if it does not + * @access private + */ + function mkdirr($pathname) + { + // Check if directory already exists + if (is_dir($pathname) || empty($pathname)) { + return; + } + + // Ensure a file does not already exist with the same name + if (is_file($pathname)) { + return PEAR::raiseError( + "File $pathname exists, unable to create directory" + ); + } + + // Crawl up the directory tree + $next_pathname = substr( + $pathname, + 0, strrpos($pathname, "/")); + $error = $this->mkdirr($next_pathname); + if (PEAR::isError($error)) { + return $error; + } + if (!@mkdir($pathname)) { + return PEAR::raiseError("Unable to create directory $pathname"); + } + } + + /** + * Open a file for writing from a given position + * + * @param string $filename The name of the file to open + * @param int $pos the initial position in the file + * @param $stat the stats of the file + */ + function openFile($filename, $pos = 0) + { + $this->close(); + + $this->handle = fopen($filename, 'r+'); + $this->stat = array(); + $this->filename = $filename; + + if (!is_resource($this->handle)) { + return PEAR::raiseError("Unable to open file $filename"); + } + + if ($pos > 0) { + if (fseek($this->handle, $pos) == -1) { + fread($this->handle, $pos); + } + } + } + + /** + * Open a file for appending after having removed a block of data from it + * See File_Archive_Reader::makeWriterRemoveBlocks + */ + function openFileRemoveBlock($filename, $pos, $blocks) + { + $error = $this->openFile($filename, $pos); + if (PEAR::isError($error)) { + return $error; + } + + if (!empty($blocks)) { + //This will be used to read the initial file + //The data, with the unusefull block removed will be written to $this->handle + $read = fopen($filename, 'r'); + if ($pos > 0) { + if (fseek($this->handle, $pos) == -1) { + fread($this->handle, $pos); + } + } + + $keep = false; + $data = ''; + foreach ($blocks as $length) { + if ($keep) { + while ($length > 0 && + ($data = fread($read, min($length, 8192))) != '') { + $length -= strlen($data); + fwrite($this->handle, $data); + } + } else { + fseek($read, $length, SEEK_CUR); + } + $keep = !$keep; + } + if ($keep) { + while(!feof($this->handle)) { + fwrite($this->handle, fread($read, 8196)); + } + } + + fclose($read); + } + + ftruncate($this->handle, ftell($this->handle)); + } + + + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat = array(), $mime = "application/octet-stream") + { + $this->close(); + $this->stat = $stat; + $this->filename = $this->getFilename($filename); + + $pos = strrpos($this->filename, "/"); + if ($pos !== false) { + $error = $this->mkdirr(substr($this->filename, 0, $pos)); + if (PEAR::isError($error)) { + return $error; + } + } + $this->handle = @fopen($this->filename, "w"); + if (!is_resource($this->handle)) { + return PEAR::raiseError("Unable to write to file $filename"); + } + } + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) { fwrite($this->handle, $data); } + /** + * @see File_Archive_Writer::newFromTempFile() + */ + function newFromTempFile($tmpfile, $filename, $stat = array(), $mime = "application/octet-stream") + { + $this->filename = filename; + $complete = $this->getFilename($filename); + $pos = strrpos($complete, "/"); + if ($pos !== false) { + $error = $this->mkdirr(substr($complete, 0, $pos)); + if (PEAR::isError($error)) { + return $error; + } + } + + if ((file_exists($complete) && !@unlink($complete)) || + !@rename($tmpfile, $complete)) { + return parent::newFromTempFile($tmpfile, $filename, $stat, $mime); + } + } + + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + if ($this->handle !== null) { + fclose($this->handle); + $this->handle = null; + + if (isset($this->stat[9])) { + if (isset($this->stat[8])) { + touch($this->filename, $this->stat[9], $this->stat[8]); + } else { + touch($this->filename, $this->stat[9]); + } + } else if (isset($this->stat[8])) { + touch($this->filename, time(), $this->stat[8]); + } + + if (isset($this->stat[2])) { + chmod($this->filename, $this->stat[2]); + } + if (isset($this->stat[5])) { + chgrp($this->filename, $this->stat[5]); + } + if (isset($this->stat[4])) { + chown($this->filename, $this->stat[4]); + } + } + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/Gzip.php b/thirdparty/pear/File/Archive/Writer/Gzip.php new file mode 100644 index 0000000..e6cded6 --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/Gzip.php @@ -0,0 +1,139 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Gzip.php,v 1.15 2005/06/02 16:22:48 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Compress a single file to Gzip format + */ +class File_Archive_Writer_Gzip extends File_Archive_Writer +{ + var $compressionLevel=9; + var $gzfile; + var $tmpName; + var $nbFiles = 0; + + var $innerWriter; + var $autoClose; + var $filename; + var $stat; + + /** + * @param string $filename Name to give to the archive + * @param File_Archive_Writer $innerWriter The inner writer to which the + * compressed data will be written + * @param array $stat The stat of the archive (see the PHP stat() function). + * No element are required in this array + * @param bool $autoClose Indicate if the inner writer must be closed when + * closing this + */ + function File_Archive_Writer_Gzip($filename, &$innerWriter, + $stat = array(), $autoClose = true) + { + $this->innerWriter =& $innerWriter; + $this->autoClose = $autoClose; + + $this->filename = $filename; + $this->stat = $stat; + + if ($this->filename === null) { + $this->newFile(null); + } + + $compressionLevel = File_Archive::getOption('gzCompressionLevel', 9); + } + + /** + * Set the compression level + * + * @param int $compressionLevel From 0 (no compression) to 9 (best + * compression) + */ + function setCompressionLevel($compressionLevel) + { + $this->compressionLevel = $compressionLevel; + } + + /** + * @see File_Archive_Writer::newFile() + * + * Check that one single file is written in the GZip archive + */ + function newFile($filename, $stat = array(), + $mime = "application/octet-stream") + { + if ($this->nbFiles > 1) { + return PEAR::raiseError("A Gz archive can only contain one single file.". + "Use Tgz archive to be able to write several files"); + } + $this->nbFiles++; + + $this->tmpName = tempnam(File_Archive::getOption('tmpDirectory'), 'far'); + $this->gzfile = gzopen($this->tmpName, 'w'.$this->compressionLevel); + + return true; + } + + + /** + * Actually write the tmp file to the inner writer + * Close and delete temporary file + * + * @see File_Archive_Writer::close() + */ + function close() + { + gzclose($this->gzfile); + if ($this->filename === null) { + //Assume innerWriter is already opened on a file... + $this->innerWriter->writeFile($this->tmpName); + unlink($this->tmpName); + } else { + $this->innerWriter->newFromTempFile( + $this->tmpName, $this->filename, $this->stat, 'application/x-compressed' + ); + } + + if ($this->autoClose) { + return $this->innerWriter->close(); + } + } + + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + gzwrite($this->gzfile, $data); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/Mail.php b/thirdparty/pear/File/Archive/Writer/Mail.php new file mode 100644 index 0000000..fd1e51c --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/Mail.php @@ -0,0 +1,200 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Mail.php,v 1.11 2005/06/02 12:24:43 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; +require_once "Mail.php"; +require_once "Mail/mime.php"; + +/** + * Send the files attached to a mail. + */ +class File_Archive_Writer_Mail extends File_Archive_Writer +{ + /** + * @var Mail_mime object + * @access private + */ + var $mime; + + /** + * @var Mail object used to send email (built thanks to the factory) + * @access private + */ + var $mail; + + /** + * @var Array or String An array or a string with comma separated recipients + * @access private + */ + var $to; + + /** + * @var Array The headers that will be passed to the Mail_mime object + * @access private + */ + var $headers; + + /** + * @var String Data read from the current file so far + * @access private + */ + var $currentData = null; + + /** + * @var String Name of the file being attached + * @access private + */ + var $currentFilename = null; + + /** + * @var String MIME of the file being attached + * @access private + */ + var $currentMime = null; + + /** + * @param Mail $mail Object used to send mail (see Mail::factory) + * @param array or string $to An array or a string with comma separated + * recipients + * @param array $headers The headers that will be passed to the Mail_mime + * object + * @param string $message Text body of the mail + */ + function File_Archive_Writer_Mail($to, $headers, $message, &$mail) + { + $this->mime = new Mail_mime(); + $this->mime->setTXTBody($message); + if (!empty($htmlMessage)) { + $this->mime->setHTMLBody($htmlMessage); + } + + if ($mail === null) + $this->mail = Mail::factory("mail"); + else + $this->mail =& $mail; + + $this->to = $to; + $this->headers = $headers; + } + + /** + * @see Mail_Mime::setHTMLBody() + */ + function setHTMLBody($data, $isfile = false) + { + return $this->mime->setHTMLBody($data, $isfile); + } + /** + * @see Mail_Mime::addHTMLImage() + */ + function addHTMLImage($file, $c_type = 'application/octet-stream', + $name = '', $isfile = true) + { + return $this->mime->addHTMLImage($file, $c_type, $name, $isfile); + } + + /** + * @see File_Archive_Writer::writeData() + * + * This function just put the data in $currentData until the end of file + * At that time, addCurrentData is called to attach $currentData to the mail + * and to clear $currentData for a new file + */ + function writeData($data) + { + $this->currentData .= $data; + } + /** + * Called when a file is finished and must be added as attachment to the mail + */ + function addCurrentData() + { + if ($this->currentFilename === null) { + return; + } + + $error = $this->mime->addAttachment( + $this->currentData, + $this->currentMime, + $this->currentFilename, + false); + $this->currentData = ""; + return $error; + } + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat, $mime = "application/octet-stream") + { + $error = $this->addCurrentData(); + if (PEAR::isError($error)) { + return $error; + } + + $this->currentFilename = $filename; + $this->currentMime = $mime; + } + /** + * @see File_Archive_Writer::newFileNeedsMIME() + */ + function newFileNeedsMIME() + { + return true; + } + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + $error = parent::close(); + if (PEAR::isError($error)) { + return $error; + } + $error = $this->addCurrentData(); + if (PEAR::isError($error)) { + return $error; + } + + $body = $this->mime->get(); + $headers = $this->mime->headers($this->headers); + + if (!$this->mail->send( + $this->to, + $headers, + $body) + ) { + return PEAR::raiseError("Error sending mail"); + } + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/Memory.php b/thirdparty/pear/File/Archive/Writer/Memory.php new file mode 100644 index 0000000..6faba95 --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/Memory.php @@ -0,0 +1,127 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Memory.php,v 1.14 2005/06/02 12:24:43 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Write the concatenation of the files in a buffer + */ +class File_Archive_Writer_Memory extends File_Archive_Writer +{ + /** + * @var string $data The buffer + * @access private + */ + var $data = ""; + /** + * Information about the file being written into this writer + * @access private + */ + var $filename; + var $stat; + var $mime; + + /** + * @param reference $data If provided, the data will be output in this + * variable. Any existent data in $data will be overwritten by the + * actual data of the writer. You should not modify manually this + * variable while using this writer (you can safely use all the + * functions of the archive, like clear for example) + * @param int keptData is the offset from where to start writing in $data + * Any data located after $seek will be erased + * The default value is 0 + */ + function File_Archive_Writer_Memory(&$data, $seek = 0) + { + $this->data =& $data; + $this->data = substr($data, 0, $seek); + } + + function writeData($d) { $this->data .= $d; } + + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat, $mime = "application/octet-stream") + { + $this->filename = $filename; + $this->stat = $stat; + $this->mime = $mime; + } + /** + * @see File_Archive_Writer::newFileNeedsMIME + */ + function newFileNeedsMIME() + { + return true; + } + + /** + * Retrieve the concatenated data + * The value is returned by reference for performance problems, but you + * should not manually modify it + * + * @return string buffer + */ + function &getData() { return $this->data; } + + /** + * Clear the buffer + */ + function clear() { $this->data = ""; } + + /** + * Returns true iif the buffer is empty + */ + function isEmpty() { return empty($this->data); } + + /** + * Create a reader from this writer + * + * @param string $filename Name of the file provided by the reader + * @param array $stat Statistics of the file provided by the reader + * @param string $mime Mime type of the file provided by the reader + * + * Any unspecified parameter will be set to the value of the last file + * written in this writer + */ + function makeReader($filename = null, $stat = null, $mime = null) + { + require_once "File/Archive/Reader/Memory.php"; + return new File_Archive_Reader_Memory( + $this->data, + $filename === null ? $this->filename : $filename, + $stat === null ? $this->stat : $stat, + $mime === null ? $this->mime : $mime); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/MemoryArchive.php b/thirdparty/pear/File/Archive/Writer/MemoryArchive.php new file mode 100644 index 0000000..51687ea --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/MemoryArchive.php @@ -0,0 +1,213 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: MemoryArchive.php,v 1.16 2005/06/02 12:24:43 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer/Archive.php"; +require_once "File/Archive/Writer/Memory.php"; + +/** + * Base class for all the archiveWriters that can only work on complete files + * (the write data function may be called with small chunks of data) + */ +class File_Archive_Writer_MemoryArchive extends File_Archive_Writer_Archive +{ + /** + * @var File_Archive_Writer_Memory A buffer where the data will be put + * waiting for the file to be complete + * @access private + */ + var $buffer = ''; + /** + * @var string Name of the file which data are coming + * @access private + */ + var $currentFilename = null; + /** + * @var array Stats of the file which data are coming + * @access private + */ + var $currentStat = null; + /** + * @var string URL of the file being treated if it is a physical file + * @access private + */ + var $currentDataFile = null; + /** + * @var int Number of times newFile function has been called + * @access protected + */ + var $nbFiles = 0; + + /** + * @see File_Archive_Writer::File_Archive_Writer() + */ + function File_Archive_Writer_MemoryArchive + ($filename, &$t, $stat = array(), $autoClose = true) + { + parent::File_Archive_Writer_Archive($filename, $t, $stat, $autoClose); + } + + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat = array(), + $mime = "application/octet-stream") + { + if ($this->nbFiles == 0) { + $error = $this->sendHeader(); + if (PEAR::isError($error)) { + return $error; + } + } else { + $error = $this->flush(); + if (PEAR::isError($error)) { + return $error; + } + } + + $this->nbFiles++; + + $this->currentFilename = $filename; + $this->currentStat = $stat; + + return true; + } + /** + * @see File_Archive_Writer::close() + */ + function close() + { + $error = $this->flush(); + if (PEAR::isError($error)) { + return $error; + } + $error = $this->sendFooter(); + if (PEAR::isError($error)) { + return $error; + } + + return parent::close(); + } + /** + * Indicate that all the data have been read from the current file + * and send it to appendFileData + * Send the current data to the appendFileData function + * + * @access private + */ + function flush() + { + if ($this->currentFilename !== null) { + if ($this->currentDataFile !== null) { + $error = $this->appendFile($this->currentFilename, + $this->currentDataFile); + } else { + $error = $this->appendFileData($this->currentFilename, + $this->currentStat, + $this->buffer); + } + if (PEAR::isError($error)) { + return $error; + } + + $this->currentFilename = null; + $this->currentDataFile = null; + $this->buffer = ''; + } + } + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + if ($this->currentDataFile !== null) { + $this->buffer .= file_get_contents($this->currentDataFile); + $this->currentDataFile = null; + } + $this->buffer .= $data; + } + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) + { + if ($this->currentDataFile === null && empty($this->buffer)) { + $this->currentDataFile = $filename; + } else { + if ($this->currentDataFile !== null) { + $this->buffer .= file_get_contents($this->currentDataFile); + $this->currentDataFile = null; + } + $this->buffer .= file_get_contents($filename); + } + } + +//MUST REWRITE FUNCTIONS + /** + * The subclass must treat the data $data + * $data is the entire data of the filename $filename + * $stat is the stat of the file + * + * @access protected + */ + function appendFileData($filename, $stat, &$data) { } + +//SHOULD REWRITE FUNCTIONS + /** + * The subclass may rewrite the sendHeader function if it needs to execute + * code before the first file + * + * @access protected + */ + function sendHeader() { } + /** + * The subclass may rewrite the sendFooter function if it needs to execute + * code before closing the archive + * + * @access protected + */ + function sendFooter() { } + /** + * The subclass may rewrite this class if it knows an efficient way to treat + * a physical file. + * + * @access protected + */ + function appendFile($filename, $dataFilename) + { + return $this->appendFileData( + $filename, + stat($dataFilename), + file_get_contents($dataFilename)); + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/Multi.php b/thirdparty/pear/File/Archive/Writer/Multi.php new file mode 100644 index 0000000..2e21d8b --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/Multi.php @@ -0,0 +1,130 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Multi.php,v 1.10 2005/06/05 18:19:33 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Write to several writers + */ +class File_Archive_Writer_Multi extends File_Archive_Writer +{ + /** + * @var File_Archive_Writer_Writer Data will be copied to these two writers + * @access private + */ + var $writers; + + function addWriter(&$writer) + { + $this->writers[] =& $writer; + } + + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat = array(), $mime = "application/octet-stream") + { + $globalError = null; + foreach($this->writers as $key => $foo) { + $error = $this->writers[$key]->newFile($filename, $stat, $mime); + if (PEAR::isError($error)) { + $globalError = $error; + } + } + if (PEAR::isError($globalError)) { + return $globalError; + } + } + /** + * @see File_Archive_Writer::newFileNeedsMIME() + */ + function newFileNeedsMIME() + { + foreach($this->writers as $key => $foo) { + if ($this->writers[$key]->newFileNeedsMIME()) { + return true; + } + } + return false; + } + + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + $globalError = null; + foreach($this->writers as $key => $foo) { + $error = $this->writers[$key]->writeData($data); + if (PEAR::isError($error)) { + $globalError = $error; + } + } + if (PEAR::isError($globalError)) { + return $globalError; + } + } + + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) + { + $globalError = null; + foreach($this->writers as $key => $foo) { + $error = $this->writers[$key]->writeFile($filename); + if (PEAR::isError($error)) { + $globalError = $error; + } + } + if (PEAR::isError($globalError)) { + return $globalError; + } + } + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + $globalError = null; + foreach($this->writers as $key => $foo) { + $error = $this->writers[$key]->close(); + if (PEAR::isError($error)) { + $globalError = $error; + } + } + if (PEAR::isError($globalError)) { + return $globalError; + } + } +} +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/Output.php b/thirdparty/pear/File/Archive/Writer/Output.php new file mode 100644 index 0000000..61db440 --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/Output.php @@ -0,0 +1,93 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Output.php,v 1.8 2005/05/30 15:25:14 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; + +/** + * Writer to the standard output + * It will concatenate the files that it receive + * It may send some headers, but will do so only for the first file + */ +class File_Archive_Writer_Output extends File_Archive_Writer +{ + /** + * @var bool If true, the Content-type and Content-disposition headers + * will be sent. The file will be considered as an attachment and + * the MIME will be deduced from its extension + * @access private + */ + var $sendHeaders; + + /** + * @param $sendHeaders see the variable + */ + function File_Archive_Writer_Output($sendHeaders = true) + { + $this->sendHeaders = $sendHeaders; + } + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat = array(), $mime = "application/octet-stream") + { + if ($this->sendHeaders) { + if(headers_sent()) { + return PEAR::raiseError( + 'The headers have already been sent. '. + 'Use File_Archive::toOutput(false) to write '. + 'to output without sending headers'); + } + + header("Content-type: $mime"); + header("Content-disposition: attachment; filename=$filename"); + $this->sendHeaders = false; + } + } + /** + * @see File_Archive_Writer::newFileNeedsMIME + */ + function newFileNeedsMIME() + { + return $this->sendHeaders; + } + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) { echo $data; } + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) { readfile($filename); } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/Tar.php b/thirdparty/pear/File/Archive/Writer/Tar.php new file mode 100644 index 0000000..cca3c23 --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/Tar.php @@ -0,0 +1,224 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Tar.php,v 1.18 2005/06/02 12:24:43 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer/Archive.php"; + +/** + * Write the files as a TAR archive + */ +class File_Archive_Writer_Tar extends File_Archive_Writer_Archive +{ + var $buffer; + var $useBuffer; + + var $filename = null; + var $stats = null; + + + /** + * Creates the TAR header for a file + * + * @param string $filename name of the file + * @param array $stat statistics of the file + * @return string A 512 byte header for the file + * @access private + */ + function tarHeader($filename, $stat) + { + $mode = isset($stat[2]) ? $stat[2] : 0x8000; + $uid = isset($stat[4]) ? $stat[4] : 0; + $gid = isset($stat[5]) ? $stat[5] : 0; + $size = $stat[7]; + $time = isset($stat[9]) ? $stat[9] : time(); + $link = ""; + + if ($mode & 0x4000) { + $type = 5; // Directory + } else if ($mode & 0x8000) { + $type = 0; // Regular + } else if ($mode & 0xA000) { + $type = 1; // Link + $link = @readlink($current); + } else { + $type = 9; // Unknown + } + + $filePrefix = ''; + if (strlen($filename) > 255) { + return PEAR::raiseError( + "$filename is too long to be put in a tar archive" + ); + } else if (strlen($filename) > 100) { + $filePrefix = substr($filename, 0, strlen($filename)-100); + $filename = substr($filename, -100); + } + + $blockbeg = pack("a100a8a8a8a12a12", + $filename, + decoct($mode), + sprintf("%6s ",decoct($uid)), + sprintf("%6s ",decoct($gid)), + sprintf("%11s ",decoct($size)), + sprintf("%11s ",decoct($time)) + ); + + $blockend = pack("a1a100a6a2a32a32a8a8a155a12", + $type, + $link, + "ustar", + "00", + "Unknown", + "Unknown", + "", + "", + $filePrefix, + ""); + + $checksum = 8*ord(" "); + for ($i = 0; $i < 148; $i++) { + $checksum += ord($blockbeg{$i}); + } + for ($i = 0; $i < 356; $i++) { + $checksum += ord($blockend{$i}); + } + + $checksum = pack("a8",sprintf("%6s ",decoct($checksum))); + + return $blockbeg . $checksum . $blockend; + } + /** + * Creates the TAR footer for a file + * + * @param int $size the size of the data that has been written to the TAR + * @return string A string made of less than 512 characteres to fill the + * last 512 byte long block + * @access private + */ + function tarFooter($size) + { + if ($size % 512 > 0) { + return pack("a".(512 - $size%512), ""); + } else { + return ""; + } + } + + function flush() + { + if ($this->filename !== null) { + if ($this->useBuffer) { + $this->stats[7] = strlen($this->buffer); + + $this->innerWriter->writeData( + $this->tarHeader($this->filename, $this->stats) + ); + $this->innerWriter->writeData( + $this->buffer + ); + } + $this->innerWriter->writeData( + $this->tarFooter($this->stats[7]) + ); + } + $this->buffer = ""; + } + + function newFile($filename, $stats = array(), + $mime = "application/octet-stream") + { + $this->flush(); + + $this->useBuffer = !isset($stats[7]); + $this->filename = $filename; + $this->stats = $stats; + + if (!$this->useBuffer) { + return $this->innerWriter->writeData( + $this->tarHeader($filename, $stats) + ); + } + } + + /** + * @see File_Archive_Writer::close() + */ + function close() + { + $this->flush(); + $this->innerWriter->writeData(pack("a1024", "")); + parent::close(); + } + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + if ($this->useBuffer) { + $this->buffer .= $data; + } else { + $this->innerWriter->writeData($data); + } + + } + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) + { + if ($this->useBuffer) { + $this->buffer .= file_get_contents($filename); + } else { + $this->innerWriter->writeFile($filename); + } + } + /** + * @see File_Archive_Writer::getMime() + */ + function getMime() { return "application/x-tar"; } +} + + +/** + * A tar archive cannot contain files with name of folders longer than 255 chars + * This filter removes them + * + * @see File_Archive_Predicate, File_Archive_Reader_Filter + */ +require_once "File/Archive/Predicate.php"; +class File_Archive_Predicate_TARCompatible extends File_Archive_Predicate +{ + function isTrue($source) + { + return strlen($source->getFilename()) <= 255; + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/UniqueAppender.php b/thirdparty/pear/File/Archive/Writer/UniqueAppender.php new file mode 100644 index 0000000..07116a8 --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/UniqueAppender.php @@ -0,0 +1,143 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: UniqueAppender.php,v 1.1 2005/05/30 19:44:53 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer.php"; +require_once "File/Archive/Reader.php"; +require_once "File/Archive/Predicate/Index.php"; + +/** + * A writer wrapper that will remove the files the eventual duplicate + * files from the reader to keep only the new ones + * If there were already some duplications in the provided reader, not + * all duplication will be removed + * If you use newFile with the same filename several file, only the latest + * write will be kept (no time comparision is done) + */ +class File_Archive_Writer_UniqueAppender extends File_Archive_Writer +{ + var $reader; + var $writer; + var $fileList = array(); + var $toDelete = array(); + + /** + * Construct a unique writer that will write to the specified writer + * and remove duplicate files from the reader on close + */ + function File_Archive_Writer_UniqueAppender(&$reader) + { + $reader->close(); + $pos = 0; + while ($reader->next()) { + $this->fileList[$reader->getFilename()] = $pos++; + } + + $this->reader =& $reader; + $this->writer = $reader->makeAppendWriter(); + } + + /** + * @see File_Archive_Writer::newFile() + */ + function newFile($filename, $stat = array(), $mime = "application/octet-stream") + { + if (isset($this->fileList[$filename])) { + $this->toDelete[$this->fileList[$filename]] = true; + } + + return $this->writer->newFile($filename, $stat, $mime); + } + + /** + * @see File_Archive_Writer::newFromTempFile() + */ + function newFromTempFile($tmpfile, $filename, $stat = array(), $mime = "application/octet-stream") + { + if (isset($this->fileList[$filename])) { + $this->toDelete[$this->fileList[$filename]] = true; + } + + return $this->writer->newFromTempFile($tmpfile, $filename, $stat, $mime); + } + + /** + * @see File_Archive_Writer::newFileNeedsMIME() + */ + function newFileNeedsMIME() + { + return $this->writer->newFileNeedsMIME(); + } + + /** + * @see File_Archive_Writer::writeData() + */ + function writeData($data) + { + return $this->writer->writeData($data); + } + + /** + * @see File_Archive_Writer::writeFile() + */ + function writeFile($filename) + { + return $this->writer->writeFile($filename); + } + + /** + * Close the writer, eventually flush the data, write the footer... + * This function must be called before the end of the script + */ + function close() + { + $error = $this->writer->close(); + if (PEAR::isError($error)) { + return $error; + } + + if (!empty($this->toDelete)) { + $tmp = $this->reader->makeWriterRemoveFiles( + new File_Archive_Predicate_Index($this->toDelete) + ); + if (PEAR::isError($tmp)) { + return $tmp; + } + + return $tmp->close(); + } + } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/File/Archive/Writer/Zip.php b/thirdparty/pear/File/Archive/Writer/Zip.php new file mode 100644 index 0000000..ac6ee1b --- /dev/null +++ b/thirdparty/pear/File/Archive/Writer/Zip.php @@ -0,0 +1,260 @@ + + * @copyright 1997-2005 The PHP Group + * @license http://www.gnu.org/copyleft/lesser.html LGPL + * @version CVS: $Id: Zip.php,v 1.20 2005/08/15 18:03:03 vincentlascaux Exp $ + * @link http://pear.php.net/package/File_Archive + */ + +require_once "File/Archive/Writer/MemoryArchive.php"; + +/** + * ZIP archive writer + */ +class File_Archive_Writer_Zip extends File_Archive_Writer_MemoryArchive +{ + /** + * @var int Compression level + * @access private + */ + var $compressionLevel; + + /** + * @var int Current position in the writer + * @access private + */ + var $offset = 0; + + /** + * @var string Optionnal comment to add to the zip + * @access private + */ + var $comment = ""; + + /** + * @var string Data written at the end of the ZIP file + * @access private + */ + var $central = ""; + + function File_Archive_Writer_Zip($filename, &$innerWriter, + $stat=array(), $autoClose = true) + { + global $_File_Archive_Options; + parent::File_Archive_Writer_MemoryArchive( + $filename, $innerWriter, $stat, $autoClose + ); + + $this->compressionLevel = File_Archive::getOption('zipCompressionLevel', 9); + } + + /** + * Change the level of the compression. This may be done between two files + * + * @param Int $compressionLevel New compression level from 0 to 9 + */ + function setCompressionLevel($compressionLevel) + { + $this->compressionLevel = $compressionLevel; + } + + /** + * Set a comment on the ZIP file + */ + function setComment($comment) { $this->comment = $comment; } + + /** + * @param int $time Unix timestamp of the date to convert + * @return the date formated as a ZIP date + */ + function getMTime($time) + { + $mtime = ($time !== null ? getdate($time) : getdate()); + $mtime = preg_replace( + "/(..){1}(..){1}(..){1}(..){1}/", + "\\x\\4\\x\\3\\x\\2\\x\\1", + dechex(($mtime['year']-1980<<25)| + ($mtime['mon' ]<<21)| + ($mtime['mday' ]<<16)| + ($mtime['hours' ]<<11)| + ($mtime['minutes']<<5)| + ($mtime['seconds']>>1))); + eval('$mtime = "'.$mtime.'";'); + return $mtime; + } + + /** + * Inform the archive that $filename is present. + * Consequences are the same as appendFileData, but no data is output + * to the inner writer. + * This is used by File_Archive_Reader_Zip::makeWriter() + * + * @param string $filename name of the file + * @param array $stat stats of the file, indexes 9 and 7 must be present + * @param int $crc32 checksum of the file + * @param int $compLength length of the compressed data + */ + function alreadyWrittenFile($filename, $stat, $crc32, $complength) + { + $filename = preg_replace("/^(\.{1,2}(\/|\\\))+/","",$filename); + + $mtime = $this->getMTime(isset($stat[9]) ? $stat[9] : null); + $normlength = $stat[7]; + + $this->nbFiles++; + + $this->central .= "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00". + $mtime. + pack("VVVvvvvvVV", + $crc32, $complength, $normlength, + strlen($filename), 0x00,0x00,0x00,0x00, + 0x0000,$this->offset). + $filename; + + $this->offset += 30 + strlen($filename) + $complength; + } + + /** + * @see File_Archive_Writer_MemoryArchive::appendFileData() + * @access protected + */ + function appendFileData($filename, $stat, $data) + { + $crc32 = crc32($data); + $normlength = strlen($data); + $data = gzcompress($data,$this->compressionLevel); + $data = substr($data,2,strlen($data)-6); + + return $this->appendCompressedData($filename, $stat, $data, $crc32, $normlength); + } + + function appendCompressedData($filename, $stat, $data, $crc32, $normlength) + { + $filename = preg_replace("/^(\.{1,2}(\/|\\\))+/","",$filename); + $mtime = $this->getMTime(isset($stat[9]) ? $stat[9] : null); + + $complength = strlen($data); + + $zipData = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00". + $mtime. + pack("VVVvv", + $crc32, + $complength, + $normlength, + strlen($filename), + 0x00). + $filename. + $data; + + $error = $this->innerWriter->writeData($zipData); + if (PEAR::isError($error)) { + return $error; + } + + $this->central .= "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00". + $mtime. + pack("VVVvvvvvVV", + $crc32, $complength, $normlength, + strlen($filename), 0x00,0x00,0x00,0x00, + 0x0000,$this->offset). + $filename; + + $this->offset += strlen($zipData); + } + + function appendFile($filename, $dataFilename) + { + //Try to read from the cache + $cache = File_Archive::getOption('cache', null); + if ($cache !== null && $this->compressionLevel > 0) { + $id = realpath($dataFilename); + $id = urlencode($id); + $id = str_replace('_', '%5F', $id); + + $group = 'FileArchiveZip'.$this->compressionLevel; + $mtime = filemtime($dataFilename); + + //Tries to read from cache + if (($data = $cache->get($id, $group)) !== false) { + $info = unpack('Vmtime/Vcrc/Vnlength', substr($data, 0, 12)); + $data = substr($data, 12); + } + + //If cache failed or file modified since then + if ($data === false || + $info['mtime'] != $mtime) { + + $data = file_get_contents($dataFilename); + + $info = array( + 'crc' => crc32($data), + 'nlength' => strlen($data), + 'mtime' => $mtime + ); + + $data = gzcompress($data,$this->compressionLevel); + $data = substr($data,2,strlen($data)-6); + $data = pack('VVV', $info['mtime'], $info['crc'], $info['nlength']).$data; + $cache->save($data, $id, $group); + } + + return $this->appendCompressedData( + $filename, + stat($dataFilename), + $data, + $info['crc'], + $info['nlength'] + ); + + } + + //If no cache system, use the standard way + return parent::appendFile($filename, $dataFilename); + } + + /** + * @see File_Archive_Writer_MemoryArchive::sendFooter() + * @access protected + */ + function sendFooter() + { + return $this->innerWriter->writeData( + $this->central. + "\x50\x4b\x05\x06\x00\x00\x00\x00". + pack("vvVVv", + $this->nbFiles,$this->nbFiles, + strlen($this->central),$this->offset, + strlen($this->comment)). + $this->comment + ); + } + /** + * @see File_Archive_Writer::getMime() + */ + function getMime() { return "application/zip"; } +} + +?> \ No newline at end of file diff --git a/thirdparty/pear/MIME/Type.php b/thirdparty/pear/MIME/Type.php new file mode 100644 index 0000000..6acc15e --- /dev/null +++ b/thirdparty/pear/MIME/Type.php @@ -0,0 +1,395 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Type.php,v 1.2 2004/08/07 22:19:04 ieure Exp $ + +require_once 'PEAR.php'; + +$_fileCmd = &PEAR::getStaticProperty('MIME_Type', 'fileCmd'); +$_fileCmd = 'file'; + +/** + * Class for working with MIME types + * + * @version @version@ + * @package @package@ + * @author Ian Eure + */ +class MIME_Type { + /** + * The MIME media type + * + * @var string + */ + var $media = ''; + + /** + * The MIME media sub-type + * + * @var string + */ + var $subType = ''; + + /** + * Optional MIME parameters + * + * @var array + */ + var $parameters = array(); + + /** + * List of valid media types + * + * @var array + */ + var $validMediaTypes = array( + 'text', + 'image', + 'audio', + 'video', + 'application', + 'multipart', + 'message' + ); + + + /** + * Constructor. + * + * If $type is set, if will be parsed and the appropriate class vars set. If not, + * you get an empty class. This is useful, but not quite as useful as parsing a + * type. + * + * @param string $type MIME type + * @return void + */ + function MIME_Type($type = false) + { + if ($type) { + $this->parse($type); + } + } + + + /** + * Parse a mime-type + * + * @param $type string MIME type to parse + * @return void + */ + function parse($type) + { + $this->media = $this->getMedia($type); + $this->subType = $this->getSubType($type); + if (MIME_Type::hasParameters($type)) { + require_once 'MIME/Type/Parameter.php'; + foreach (MIME_Type::getParameters($type) as $param) { + $param = &new MIME_Type_Parameter($param); + $this->parameters[$param->name] = $param; + } + } + } + + + /** + * Does this type have any parameters? + * + * @param $type string MIME type to check + * @return boolean true if $type has parameters, false otherwise + * @static + */ + function hasParameters($type) + { + if (strstr($type, ';')) { + return true; + } + return false; + } + + + /** + * Get a MIME type's parameters + * + * @param $type string MIME type to get parameters of + * @return array $type's parameters + * @static + */ + function getParameters($type) + { + $params = array(); + $tmp = explode(';', $type); + for ($i = 1; $i < count($tmp); $i++) { + $params[] = trim($tmp[$i]); + } + return $params; + } + + + /** + * Strip paramaters from a MIME type string + * + * @param string $type MIME type string + * @return string MIME type with parameters removed + * @static + */ + function stripParameters($type) + { + if (strstr($type, ';')) { + return substr($type, 0, strpos($type, ';')); + } + return $type; + } + + + /** + * Get a MIME type's media + * + * @note 'media' refers to the portion before the first slash + * @param $type string MIME type to get media of + * @return string $type's media + * @static + */ + function getMedia($type) + { + $tmp = explode('/', $type); + return strtolower($tmp[0]); + } + + + /** + * Get a MIME type's subtype + * + * @param $type string MIME type to get subtype of + * @return string $type's subtype + * @static + */ + function getSubType($type) + { + $tmp = explode('/', $type); + $tmp = explode(';', $tmp[1]); + return strtolower(trim($tmp[0])); + } + + + /** + * Create a textual MIME type from object values + * + * This function performs the opposite function of parse(). + * + * @return string MIME type string + */ + function get() + { + $type = strtolower($this->media.'/'.$this->subType); + if (count($this->parameters)) { + foreach ($this->parameters as $key => $null) { + $type .= '; '.$this->parameters[$key]->get(); + } + } + return $type; + } + + + /** + * Is this type experimental? + * + * @note Experimental types are denoted by a leading 'x-' in the media or + * subtype, e.g. text/x-vcard or x-world/x-vrml. + * @param string $type MIME type to check + * @return boolean true if $type is experimental, false otherwise + * @static + */ + function isExperimental($type) + { + if (substr(MIME_Type::getMedia($type), 0, 2) == 'x-' || + substr(MIME_Type::getSubType($type), 0, 2) == 'x-') { + return true; + } + return false; + } + + + /** + * Is this a vendor MIME type? + * + * @note Vendor types are denoted with a leading 'vnd. in the subtype. + * @param string $type MIME type to check + * @return boolean true if $type is a vendor type, false otherwise + * @static + */ + function isVendor($type) + { + if (substr(MIME_Type::getSubType($type), 0, 4) == 'vnd.') { + return true; + } + return false; + } + + + /** + * Is this a wildcard type? + * + * @param string $type MIME type to check + * @return boolean true if $type is a wildcard, false otherwise + * @static + */ + function isWildcard($type) + { + if ($type == '*/*' || MIME_Type::getSubtype($type) == '*') { + return true; + } + return false; + } + + + /** + * Perform a wildcard match on a MIME type + * + * Example: + * MIME_Type::wildcardMatch('image/*', 'image/png') + * + * @param string $card Wildcard to check against + * @param string $type MIME type to check + * @return boolean true if there was a match, false otherwise + */ + function wildcardMatch($card, $type) + { + if (!MIME_Type::isWildcard($card)) { + return false; + } + + if ($card == '*/*') { + return true; + } + + if (MIME_Type::getMedia($card) == + MIME_Type::getMedia($type)) { + return true; + } + return false; + } + + + /** + * Add a parameter to this type + * + * @param string $name Attribute name + * @param string $value Attribute value + * @param string $comment Comment for this parameter + * @return void + */ + function addParameter($name, $value, $comment = false) + { + $tmp = &new MIME_Type_Parameter; + $tmp->name = $name; + $tmp->value = $value; + $tmp->comment = $comment; + $this->parameters[$name] = $tmp; + } + + + /** + * Remove a parameter from this type + * + * @param string $name Parameter name + * @return void + */ + function removeParameter($name) + { + unset ($this->parameters[$name]); + } + + + /** + * Autodetect a file's MIME-type + * + * This function may be called staticly. + * + * @param string $file Path to the file to get the type of + * @param bool $params Append MIME parameters if true + * @return string $file's MIME-type on success, PEAR_Error otherwise + * @since 1.0.0beta1 + * @static + */ + function autoDetect($file, $params = false) + { + @include_once 'System/Command.php'; + if (function_exists('mime_content_type')) { + $type = mime_content_type($file); + } else if (class_exists('System_Command')) { + $type = MIME_Type::_fileAutoDetect($file); + } else { + return PEAR::raiseError("Sorry, can't autodetect; you need the mime_magic extension or System_Command and 'file' installed to use this function."); + } + + // _fileAutoDetect() may have returned an error. + if (PEAR::isError($type)) { + return $type; + } + + // Don't return an empty string + if (!$type || !strlen($type)) { + return PEAR::raiseError("Sorry, couldn't determine file type."); + } + + // Strip parameters if present & requested + if (MIME_Type::hasParameters($type) && !$params) { + $type = MIME_Type::stripParameters($type); + } + + return $type; + } + + /** + * Autodetect a file's MIME-type with 'file' and System_Command + * + * This function may be called staticly. + * + * @param string $file Path to the file to get the type of + * @return string $file's MIME-type + * @since 1.0.0beta1 + * @static + */ + function _fileAutoDetect($file) + { + // Sanity checks + if (!file_exists($file)) { + return PEAR::raiseError("File \"$file\" doesn't exist"); + } + + if (!is_readable($file)) { + return PEAR::raiseError("File \"$file\" is not readable"); + } + + $cmd = new System_Command; + + + // Make sure we have the 'file' command. + $fileCmd = PEAR::getStaticProperty('MIME_Type', 'fileCmd'); + if (!$cmd->which($fileCmd)) { + unset($cmd); + return PEAR::raiseError("Can't find file command \"{$fileCmd}\""); + } + + $cmd->pushCommand($fileCmd, "-bi '{$file}'"); + $res = $cmd->execute(); + unset($cmd); + + return $res; + } +} \ No newline at end of file diff --git a/thirdparty/pear/MIME/Type/Parameter.php b/thirdparty/pear/MIME/Type/Parameter.php new file mode 100644 index 0000000..c37d7bb --- /dev/null +++ b/thirdparty/pear/MIME/Type/Parameter.php @@ -0,0 +1,162 @@ + | +// +----------------------------------------------------------------------+ +// +// $Id: Parameter.php,v 1.1 2004/06/16 08:46:19 ieure Exp $ + +/** + * Class for working with MIME type parameters + * + * @version @version@ + * @package @package@ + * @author Ian Eure + */ +class MIME_Type_Parameter { + /** + * Parameter name + * + * @var string + */ + var $name; + + /** + * Parameter value + * + * @var string + */ + var $value; + + /** + * Parameter comment + * + * @var string + */ + var $comment; + + + /** + * Constructor. + * + * @param string $param MIME parameter to parse, if set. + * @return void + */ + function MIME_Type_Parameter($param = false) + { + if ($param) { + $this->parse($param); + } + } + + + /** + * Parse a MIME type parameter and set object fields + * + * @param string $param MIME type parameter to parse + * @return void + */ + function parse($param) + { + $this->name = $this->getAttribute($param); + $this->value = $this->getValue($param); + if ($this->hasComment($param)) { + $this->comment = $this->getComment($param); + } + } + + + /** + * Get a parameter attribute (e.g. name) + * + * @param string MIME type parameter + * @return string Attribute name + * @static + */ + function getAttribute($param) + { + $tmp = explode('=', $param); + return trim($tmp[0]); + } + + + /** + * Get a parameter value + * + * @param string $param MIME type parameter + * @return string Value + * @static + */ + function getValue($param) + { + $tmp = explode('=', $param); + $value = $tmp[1]; + if (MIME_Type_Parameter::hasComment($param)) { + $cs = strpos($value, '('); + $value = substr($value, 0, $cs); + } + return trim($value, '" '); + } + + + /** + * Get a parameter comment + * + * @param string $param MIME type parameter + * @return string Parameter comment + * @see getComment() + * @static + */ + function getComment($param) + { + $cs = strpos($param, '('); + $comment = substr($param, $cs); + return trim($comment, '() '); + } + + + /** + * Does this parameter have a comment? + * + * @param string $param MIME type parameter + * @return boolean true if $param has a comment, false otherwise + * @static + */ + function hasComment($param) + { + if (strstr($param, '(')) { + return true; + } + return false; + } + + + /** + * Get a string representation of this parameter + * + * This function performs the oppsite of parse() + * + * @return string String representation of parameter + */ + function get() + { + $val = $this->name.'="'.$this->value.'"'; + if ($this->comment) { + $val .= ' ('.$this->comment.')'; + } + return $val; + } +} +?> \ No newline at end of file -- libgit2 0.21.4