--- /dev/null
+<?php
+/**
+ * The Horde_Compress:: class provides an API for various compression
+ * techniques that can be used by Horde applications.
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @package Horde_Compress
+ */
+class Horde_Compress
+{
+ /**
+ * Attempts to return a concrete instance based on $driver.
+ *
+ * @param mixed $driver The type of concrete subclass to
+ * return. If $driver is an array, then we will look
+ * in $driver[0]/lib/Compress/ for the subclass
+ * implementation named $driver[1].php.
+ * @param array $params A hash containing any additional configuration or
+ * parameters a subclass might need.
+ *
+ * @return Horde_Compress The newly created concrete instance.
+ * @throws Horde_Exception
+ */
+ static public function factory($driver, $params = null)
+ {
+ if (is_array($driver)) {
+ list($app, $driv_name) = $driver;
+ $driver = basename($driv_name);
+ } else {
+ $driver = basename($driver);
+ }
+
+ $class = (empty($app) ? 'Horde' : $app) . '_Auth_' . ucfirst($driver);
+
+ if (class_exists($class)) {
+ return new $class($params);
+ }
+
+ throw new Horde_Exception('Class definition of ' . $class . ' not found.');
+ }
+
+ /**
+ * Compress the data.
+ *
+ * @param string $data The data to compress.
+ * @param array $params An array of arguments needed to compress the data.
+ *
+ * @return mixed The compressed data.
+ * @throws Horde_Exception
+ */
+ public function compress($data, $params = array())
+ {
+ return $data;
+ }
+
+ /**
+ * Decompress the data.
+ *
+ * @param string $data The data to decompress.
+ * @param array $params An array of arguments needed to decompress the
+ * data.
+ *
+ * @return array The decompressed data.
+ * @throws Horde_Exception
+ */
+ public function decompress($data, $params = array())
+ {
+ return $data;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Compress_Dbx class allows dbx files (e.g. from Outlook Express)
+ * to be read.
+ *
+ * This class is based on code by:
+ * Antony Raijekov <dev@strategma.bg>
+ * http://uruds.gateway.bg/zeos/
+ *
+ * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_Compress
+ */
+class Horde_Compress_Dbx extends Horde_Compress
+{
+ /**
+ * TODO
+ *
+ * @var array
+ */
+ protected $_flagArray = array(
+ 0x1 => 'MsgFlags',
+ 0x2 => 'Sent',
+ 0x4 => 'position',
+ 0x7 => 'MessageID',
+ 0x8 => 'Subject',
+ 0x9 => 'From_reply',
+ 0xA => 'References',
+ 0xB => 'Newsgroup',
+ 0xD => 'From',
+ 0xE => 'Reply_To',
+ 0x12 => 'Received',
+ 0x13 => 'Receipt',
+ 0x1A => 'Account',
+ 0x1B => 'AccountID',
+ 0x80 => 'Msg',
+ 0x81 => 'MsgFlags',
+ 0x84 => 'position',
+ 0x91 => 'size',
+ );
+
+ /**
+ * TODO
+ *
+ * @var array
+ */
+ protected $_mails = array();
+
+ /**
+ * TODO
+ *
+ * @var array
+ */
+ protected $_tmp = array();
+
+ /**
+ * Decompresses a DBX file and gets information from it.
+ *
+ * @param string $data The dbx file data.
+ * @param array $params Not used.
+ *
+ * @return mixed The requested data.
+ * @throws Horde_Exception
+ */
+ public function decompress($data, $params = null)
+ {
+ $this->_mails = $this->_tmp = array();
+
+ $position = 0xC4;
+ $header_info = unpack('Lposition/LDataLength/nHeaderLength/nFlagCount', substr($data, $position, 12));
+ $position += 12;
+
+ // Go to the first table offest and process it.
+ if ($header_info['position'] > 0) {
+ $position = 0x30;
+ $buf = unpack('Lposition', substr($data, $position, 4));
+ $position = $buf['position'];
+ $result = $this->_readIndex($data, $position);
+ }
+
+ return $this->_mails;
+ }
+
+ /**
+ * Returns a null-terminated string from the specified data.
+ *
+ * @param string $buf TODO
+ * @param integer $pos TODO
+ *
+ * @return string TODO
+ */
+ protected function _readString($buf, $pos)
+ {
+ return ($len = strpos(substr($buf, $pos), chr(0)))
+ ? substr($buf, $pos, $len)
+ : '';
+ }
+
+ /**
+ * TODO
+ *
+ * @param string $data TODO
+ * @param integer $position TODO
+ *
+ * @return string TODO
+ * @throws Horde_Exception
+ */
+ protected function _readMessage($data, $position)
+ {
+ $msg = '';
+ $part = 0;
+
+ if ($position > 0) {
+ $IndexItemsCount = array_pop(unpack('S', substr($data, 0xC4, 4)));
+ if ($IndexItemsCount > 0) {
+ while ($position < strlen($data)) {
+ $part++;
+ $s = substr($data, $position, 528);
+ if (strlen($s) == 0) {
+ break;
+ }
+ $msg_item = unpack('LFilePos/LUnknown/LItemSize/LNextItem/a512Content', $s);
+ if ($msg_item['FilePos'] != $position) {
+ throw new Horde_Exception(_("Invalid file format"));
+ }
+ $position += 528;
+ $msg .= substr($msg_item['Content'], 0, $msg_item['ItemSize']);
+ $position = $msg_item['NextItem'];
+ if ($position == 0) {
+ break;
+ }
+ }
+ }
+ }
+
+ return $msg;
+ }
+
+ /**
+ * TODO
+ *
+ * @param string $data TODO
+ * @param integer $position TODO
+ *
+ * @return array TODO
+ * @throws Horde_Exception
+ */
+ protected function _readMessageInfo($data, $position)
+ {
+ $message_info = array();
+ $msg_header = unpack('Lposition/LDataLength/SHeaderLength/SFlagCount', substr($data, $position, 12));
+ if ($msg_header['position'] != $position) {
+ throw new Horde_Exception(_("Invalid file format"));
+ }
+ $position += 12;
+ $message_info['HeaderPosition'] = $msg_header['position'];
+ $flags = $msg_header['FlagCount'] & 0xFF;
+ $DataSize = $msg_header['DataLength'] - $flags * 4;
+ $size = 4 * $flags;
+ $FlagsBuffer = substr($data, $position, $size);
+ $position += $size;
+ $size = $DataSize;
+ $DataBuffer = substr($data, $position, $size);
+ $position += $size;
+ $message_info = array();
+
+ /* Process flags */
+ for ($i = 0; $i < $flags; ++$i) {
+ $pos = 0;
+ $f = array_pop(unpack('L', substr($FlagsBuffer, $i * 4, 4)));
+
+ $mask = $f & 0xFF;
+ switch ($mask) {
+ case 0x1:
+ $pos = $pos + ($f >> 8);
+ $message_info['MsgFlags'] = array_pop(unpack('C', substr($DataBuffer, $pos++, 1)));
+ $message_info['MsgFlags'] += array_pop(unpack('C', substr($DataBuffer, $pos++, 1))) * 256;
+ $message_info['MsgFlags'] += array_pop(unpack('C', substr($DataBuffer, $pos, 1))) * 65536;
+ break;
+
+ case 0x2:
+ case 0x4:
+ $pos += array_pop(unpack('L', substr($FlagsBuffer, $i * 4, 4))) >> 8;
+ $message_info[$this->_flagArray[$mask]] = array_pop(unpack('L', substr($DataBuffer, $pos, 4)));
+ break;
+
+ case 0x7:
+ case 0x8:
+ case 0x9:
+ case 0xA:
+ case 0xB:
+ case 0xD:
+ case 0xE:
+ case 0x13:
+ case 0x1A:
+ $pos += array_pop(unpack('L', substr($FlagsBuffer, $i * 4, 4))) >> 8;
+ $message_info[$this->_flagArray[$mask]] = $this->_readString($DataBuffer, $pos);
+ break;
+
+ case 0x12:
+ $pos += array_pop(unpack('L', substr($FlagsBuffer, $i * 4, 4))) >> 8;
+ $message_info['Received'] = array_pop(unpack('L', substr($DataBuffer, $pos, 4)));
+ break;
+
+ case 0x1B:
+ $pos += array_pop(unpack('L', substr($FlagsBuffer, $i * 4, 4))) >> 8;
+ $message_info['AccountID'] = intval($this->_readString($DataBuffer, $pos));
+ break;
+
+ case 0x80:
+ case 0x81:
+ case 0x84:
+ case 0x91:
+ $message_info[$this->_flagArray[$mask]] = array_pop(unpack('L', substr($FlagsBuffer, $i * 4, 4))) >> 8;
+ break;
+ }
+ }
+
+ return $message_info;
+ }
+
+ /**
+ * TODO
+ *
+ * @param string $data TODO
+ * @param integer $position TODO
+ *
+ * @throws Horde_Exception
+ */
+ protected function _readIndex($data, $position)
+ {
+ $index_header = unpack('LFilePos/LUnknown1/LPrevIndex/LNextIndex/LCount/LUnknown', substr($data, $position, 24));
+ if ($index_header['FilePos'] != $position) {
+ throw new Horde_Exception(_("Invalid file format"));
+ }
+
+ // Push it into list of processed items.
+ $this->_tmp[$position] = true;
+ if (($index_header['NextIndex'] > 0) &&
+ empty($this->_tmp[$index_header['NextIndex']])) {
+ $this->_readIndex($data, $index_header['NextIndex']);
+ }
+ if (($index_header['PrevIndex'] > 0) &&
+ empty($this->_tmp[$index_header['PrevIndex']])) {
+ $this->_readIndex($data, $index_header['PrevIndex']);
+ }
+ $position += 24;
+ $icount = $index_header['Count'] >> 8;
+ if ($icount > 0) {
+ $buf = substr($data, $position, 12 * $icount);
+ for ($i = 0; $i < $icount; $i++) {
+ $hdr_buf = substr($buf, $i * 12, 12);
+ $IndexItem = unpack('LHeaderPos/LChildIndex/LUnknown', $hdr_buf);
+ if ($IndexItem['HeaderPos'] > 0) {
+ $mail['info'] = $this->_readMessageInfo($data, $IndexItem['HeaderPos']);
+ $mail['content'] = $this->_readMessage($data, $mail['info']['position']);
+ $this->_mails[] = $mail;
+ }
+ if (($IndexItem['ChildIndex'] > 0) &&
+ empty($this->_tmp[$IndexItem['ChildIndex']])) {
+ $this->_readIndex($fp, $IndexItem['ChildIndex']);
+ }
+ }
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Compress_Gzip class allows gzip files to be read.
+ *
+ * Copyright 2002-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael Cochrane <mike@graftonhall.co.nz>
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @package Horde_Compress
+ */
+class Horde_Compress_Gzip extends Horde_Compress
+{
+ /**
+ * Gzip file flags.
+ *
+ * @var array
+ */
+ protected $_flags = array(
+ 'FTEXT' => 0x01,
+ 'FHCRC' => 0x02,
+ 'FEXTRA' => 0x04,
+ 'FNAME' => 0x08,
+ 'FCOMMENT' => 0x10
+ );
+
+ /**
+ * Decompress a gzip file and get information from it.
+ *
+ * @param string $data The tar file data.
+ * @param array $params The parameter array (Unused).
+ *
+ * @return string The uncompressed data.
+ * @throws Horde_Exception
+ */
+ public function decompress($data, $params = array())
+ {
+ /* If gzip is not compiled into PHP, return now. */
+ if (!Horde_Util::extensionExists('zlib')) {
+ throw new Horde_Exception(_("This server can't uncompress gzip files."));
+ }
+
+ /* Gzipped File - decompress it first. */
+ $position = 0;
+ $info = @unpack('CCM/CFLG/VTime/CXFL/COS', substr($data, $position + 2));
+ if (!$info) {
+ throw new Horde_Exception(_("Unable to decompress data."));
+ }
+ $position += 10;
+
+ if ($info['FLG'] & $this->_flags['FEXTRA']) {
+ $XLEN = unpack('vLength', substr($data, $position + 0, 2));
+ $XLEN = $XLEN['Length'];
+ $position += $XLEN + 2;
+ }
+
+ if ($info['FLG'] & $this->_flags['FNAME']) {
+ $filenamePos = strpos($data, "\x0", $position);
+ $filename = substr($data, $position, $filenamePos - $position);
+ $position = $filenamePos + 1;
+ }
+
+ if ($info['FLG'] & $this->_flags['FCOMMENT']) {
+ $commentPos = strpos($data, "\x0", $position);
+ $comment = substr($data, $position, $commentPos - $position);
+ $position = $commentPos + 1;
+ }
+
+ if ($info['FLG'] & $this->_flags['FHCRC']) {
+ $hcrc = unpack('vCRC', substr($data, $position + 0, 2));
+ $hcrc = $hcrc['CRC'];
+ $position += 2;
+ }
+
+ $result = @gzinflate(substr($data, $position, strlen($data) - $position));
+ if (empty($result)) {
+ throw new Horde_Exception(_("Unable to decompress data."));
+ }
+
+ return $result;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Compress_Rar class allows rar files to be read.
+ *
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael Cochrane <mike@graftonhall.co.nz>
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @package Horde_Compress
+ */
+class Horde_Compress_Rar extends Horde_Compress
+{
+ /**
+ * Rar compression methods
+ *
+ * @var array
+ */
+ protected $_methods = array(
+ 0x30 => 'Store',
+ 0x31 => 'Fastest',
+ 0x32 => 'Fast',
+ 0x33 => 'Normal',
+ 0x34 => 'Good',
+ 0x35 => 'Best'
+ );
+
+ /**
+ * Decompress a rar file and get information from it.
+ *
+ * @param string $data The rar file data.
+ * @param array $params The parameter array (Unused).
+ *
+ * @return array The uncompressed data:
+ * <pre>
+ * KEY: Position in RAR archive
+ * VALUES:
+ * 'attr' -- File attributes
+ * 'date' -- File modification time
+ * 'csize' -- Compressed file size
+ * 'method' -- Compression method
+ * 'name' -- Filename
+ * 'size' -- Original file size
+ * </pre>
+ *
+ * @throws Horde_Exception
+ */
+ public function decompress($data, $params = array())
+ {
+ $blockStart = strpos($data, "\x52\x61\x72\x21\x1a\x07\x00");
+ if ($blockStart === false) {
+ throw new Horde_Exception(_("Invalid RAR data."));
+ }
+
+ $position = $blockStart + 7;
+ $return_array = array();
+
+ while ($position < strlen($data)) {
+ $head_crc = substr($data, $position + 0, 2);
+ $head_type = ord(substr($data, $position + 2, 1));
+ $head_flags = unpack('vFlags', substr($data, $position + 3, 2));
+ $head_flags = $head_flags['Flags'];
+ $head_size = unpack('vSize', substr($data, $position + 5, 2));
+ $head_size = $head_size['Size'];
+
+ $position += 7;
+ $head_size -= 7;
+
+ switch ($head_type) {
+ case 0x73:
+ /* Archive header */
+ $position += $head_size;
+ break;
+
+ case 0x74:
+ /* File Header */
+ $info = unpack('VPacked/VUnpacked/COS/VCRC32/VTime/CVersion/CMethod/vLength/vAttrib', substr($data, $position));
+
+ $return_array[] = array(
+ 'name' => substr($data, $position + 25, $info['Length']),
+ 'size' => $info['Unpacked'],
+ 'csize' => $info['Packed'],
+ 'date' => mktime((($info['Time'] >> 11) & 0x1f),
+ (($info['Time'] >> 5) & 0x3f),
+ (($info['Time'] << 1) & 0x3e),
+ (($info['Time'] >> 21) & 0x07),
+ (($info['Time'] >> 16) & 0x1f),
+ ((($info['Time'] >> 25) & 0x7f) + 80)),
+ 'method' => $this->_methods[$info['Method']],
+ 'attr' => (($info['Attrib'] & 0x10) ? 'D' : '-') .
+ (($info['Attrib'] & 0x20) ? 'A' : '-') .
+ (($info['Attrib'] & 0x03) ? 'S' : '-') .
+ (($info['Attrib'] & 0x02) ? 'H' : '-') .
+ (($info['Attrib'] & 0x01) ? 'R' : '-')
+ );
+
+ $position += $head_size + $info['Packed'];
+ break;
+
+ default:
+ $position += $head_size;
+ if (isset($add_size)) {
+ $position += $add_size;
+ }
+ break;
+ }
+ }
+
+ return $return_array;
+ }
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Compress_Tar class allows tar files to be read.
+ *
+ * Copyright 2002-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Michael Cochrane <mike@graftonhall.co.nz>
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @package Horde_Compress
+ */
+class Horde_Compress_Tar extends Horde_Compress
+{
+ /**
+ * Tar file types.
+ *
+ * @var array
+ */
+ protected $_types = array(
+ 0x0 => 'Unix file',
+ 0x30 => 'File',
+ 0x31 => 'Link',
+ 0x32 => 'Symbolic link',
+ 0x33 => 'Character special file',
+ 0x34 => 'Block special file',
+ 0x35 => 'Directory',
+ 0x36 => 'FIFO special file',
+ 0x37 => 'Contiguous file'
+ );
+
+ /**
+ * Tar file flags.
+ *
+ * @var array
+ */
+ protected $_flags = array(
+ 'FTEXT' => 0x01,
+ 'FHCRC' => 0x02,
+ 'FEXTRA' => 0x04,
+ 'FNAME' => 0x08,
+ 'FCOMMENT' => 0x10
+ );
+
+ /**
+ * Decompress a tar file and get information from it.
+ *
+ * @param string $data The tar file data.
+ * @param array $params The parameter array (Unused).
+ *
+ * @return array The requested data.
+ * <pre>
+ * KEY: Position in the array
+ * VALUES: 'attr' -- File attributes
+ * 'data' -- Raw file contents
+ * 'date' -- File modification time
+ * 'name' -- Filename
+ * 'size' -- Original file size
+ * 'type' -- File type
+ * </pre>
+ *
+ * @throws Horde_Exception
+ */
+ public function decompress($data, $params = array())
+ {
+ $position = 0;
+ $return_array = array();
+
+ while ($position < strlen($data)) {
+ $info = @unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/Ctypeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", substr($data, $position));
+ if (!$info) {
+ throw new Horde_Exception(_("Unable to decompress data."));
+ }
+
+ $position += 512;
+ $contents = substr($data, $position, octdec($info['size']));
+ $position += ceil(octdec($info['size']) / 512) * 512;
+
+ if ($info['filename']) {
+ $file = array(
+ 'attr' => null,
+ 'data' => null,
+ 'date' => octdec($info['mtime']),
+ 'name' => trim($info['filename']),
+ 'size' => octdec($info['size']),
+ 'type' => isset($this->_types[$info['typeflag']]) ? $this->_types[$info['typeflag']] : null
+ );
+
+ if (($info['typeflag'] == 0) ||
+ ($info['typeflag'] == 0x30) ||
+ ($info['typeflag'] == 0x35)) {
+ /* File or folder. */
+ $file['data'] = $contents;
+
+ $mode = hexdec(substr($info['mode'], 4, 3));
+ $file['attr'] =
+ (($info['typeflag'] == 0x35) ? 'd' : '-') .
+ (($mode & 0x400) ? 'r' : '-') .
+ (($mode & 0x200) ? 'w' : '-') .
+ (($mode & 0x100) ? 'x' : '-') .
+ (($mode & 0x040) ? 'r' : '-') .
+ (($mode & 0x020) ? 'w' : '-') .
+ (($mode & 0x010) ? 'x' : '-') .
+ (($mode & 0x004) ? 'r' : '-') .
+ (($mode & 0x002) ? 'w' : '-') .
+ (($mode & 0x001) ? 'x' : '-');
+ } else {
+ /* Some other type. */
+ }
+
+ $return_array[] = $file;
+ }
+ }
+
+ return $return_array;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Compress_Tnef class allows MS-TNEF data to be displayed.
+ *
+ * The TNEF rendering is based on code by:
+ * Graham Norbury <gnorbury@bondcar.com>
+ * Original design by:
+ * Thomas Boll <tb@boll.ch>, Mark Simpson <damned@world.std.com>
+ *
+ * Copyright 2002-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Jan Schneider <jan@horde.org>
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @package Horde_Compress
+ */
+class Horde_Compress_Tnef extends Horde_Compress
+{
+ const SIGNATURE = 0x223e9f78;
+ const LVL_MESSAGE = 0x01;
+ const LVL_ATTACHMENT = 0x02;
+
+ const STRING = 0x00010000;
+ const BYTE = 0x00060000;
+ const WORD = 0x00070000;
+ const DWORD = 0x00080000;
+
+ const ASUBJECT = self::DWORD | 0x8004;
+ const AMCLASS = self::WORD | 0x8008;
+ const ATTACHDATA = self::BYTE | 0x800f;
+ const AFILENAME = self::STRING | 0x8010;
+ const ARENDDATA = self::BYTE | 0x9002;
+ const AMAPIATTRS = self::BYTE | 0x9005;
+ const AVERSION = self::DWORD | 0x9006;
+
+ const MAPI_NULL = 0x0001;
+ const MAPI_SHORT = 0x0002;
+ const MAPI_INT = 0x0003;
+ const MAPI_FLOAT = 0x0004;
+ const MAPI_DOUBLE = 0x0005;
+ const MAPI_CURRENCY = 0x0006;
+ const MAPI_APPTIME = 0x0007;
+ const MAPI_ERROR = 0x000a;
+ const MAPI_BOOLEAN = 0x000b;
+ const MAPI_OBJECT = 0x000d;
+ const MAPI_INT8BYTE = 0x0014;
+ const MAPI_STRING = 0x001e;
+ const MAPI_UNICODE_STRING = 0x001f;
+ const MAPI_SYSTIME = 0x0040;
+ const MAPI_CLSID = 0x0048;
+ const MAPI_BINARY = 0x0102;
+
+ const MAPI_ATTACH_LONG_FILENAME = 0x3707;
+ const MAPI_ATTACH_MIME_TAG = 0x370E;
+
+ const MAPI_NAMED_TYPE_ID = 0x0000;
+ const MAPI_NAMED_TYPE_STRING = 0x0001;
+ const MAPI_MV_FLAG = 0x1000;
+
+ /**
+ * Decompress the data.
+ *
+ * @param string $data The data to decompress.
+ * @param array $params An array of arguments needed to decompress the
+ * data.
+ *
+ * @return mixed The decompressed data.
+ * @throws Horde_Exception
+ */
+ public function decompress($data, $params = array())
+ {
+ $out = array();
+
+ if ($this->_geti($data, 32) == self::SIGNATURE) {
+ $this->_geti($data, 16);
+
+ while (strlen($data) > 0) {
+ switch ($this->_geti($data, 8)) {
+ case self::LVL_MESSAGE:
+ $this->_decodeMessage($data);
+ break;
+
+ case self::LVL_ATTACHMENT:
+ $this->_decodeAttachment($data, $out);
+ break;
+ }
+ }
+ }
+
+ return array_reverse($out);
+ }
+
+ /**
+ * TODO
+ *
+ * @param string &$data The data string.
+ * @param integer $bits How many bits to retrieve.
+ *
+ * @return TODO
+ */
+ protected function _getx(&$data, $bits)
+ {
+ $value = null;
+
+ if (strlen($data) >= $bits) {
+ $value = substr($data, 0, $bits);
+ $data = substr_replace($data, '', 0, $bits);
+ }
+
+ return $value;
+ }
+
+ /**
+ * TODO
+ *
+ * @param string &$data The data string.
+ * @param integer $bits How many bits to retrieve.
+ *
+ * @return TODO
+ */
+ protected function _geti(&$data, $bits)
+ {
+ $bytes = $bits / 8;
+ $value = null;
+
+ if (strlen($data) >= $bytes) {
+ $value = ord($data[0]);
+ if ($bytes >= 2) {
+ $value += (ord($data[1]) << 8);
+ }
+ if ($bytes >= 4) {
+ $value += (ord($data[2]) << 16) + (ord($data[3]) << 24);
+ }
+ $data = substr_replace($data, '', 0, $bytes);
+ }
+
+ return $value;
+ }
+
+ /**
+ * TODO
+ *
+ * @param string &$data The data string.
+ * @param string $attribute TODO
+ */
+ protected function _decodeAttribute(&$data, $attribute)
+ {
+ /* Data. */
+ $this->_getx($data, $this->_geti($data, 32));
+
+ /* Checksum. */
+ $this->_geti($data, 16);
+ }
+
+ /**
+ * TODO
+ *
+ * @param string $data The data string.
+ * @param array &$attachment_data TODO
+ */
+ protected function _extractMapiAttributes($data, &$attachment_data)
+ {
+ /* Number of attributes. */
+ $number = $this->_geti($data, 32);
+
+ while ((strlen($data) > 0) && $number--) {
+ $have_mval = false;
+ $num_mval = 1;
+ $named_id = $value = null;
+ $attr_type = $this->_geti($data, 16);
+ $attr_name = $this->_geti($data, 16);
+
+ if (($attr_type & self::MAPI_MV_FLAG) != 0) {
+ $have_mval = true;
+ $attr_type = $attr_type & ~self::MAPI_MV_FLAG;
+ }
+
+ if (($attr_name >= 0x8000) && ($attr_name < 0xFFFE)) {
+ $this->_getx($data, 16);
+ $named_type = $this->_geti($data, 32);
+
+ switch ($named_type) {
+ case self::MAPI_NAMED_TYPE_ID:
+ $named_id = $this->_geti($data, 32);
+ $attr_name = $named_id;
+ break;
+
+ case self::MAPI_NAMED_TYPE_STRING:
+ $attr_name = 0x9999;
+ $idlen = $this->_geti($data, 32);
+ $datalen = $idlen + ((4 - ($idlen % 4)) % 4);
+ $named_id = substr($this->_getx($data, $datalen), 0, $idlen);
+ break;
+ }
+ }
+
+ if ($have_mval) {
+ $num_mval = $this->_geti($data, 32);
+ }
+
+ switch ($attr_type) {
+ case self::MAPI_SHORT:
+ $value = $this->_geti($data, 16);
+ break;
+
+ case self::MAPI_INT:
+ case self::MAPI_BOOLEAN:
+ for ($i = 0; $i < $num_mval; $i++) {
+ $value = $this->_geti($data, 32);
+ }
+ break;
+
+ case self::MAPI_FLOAT:
+ case self::MAPI_ERROR:
+ $value = $this->_getx($data, 4);
+ break;
+
+ case self::MAPI_DOUBLE:
+ case self::MAPI_APPTIME:
+ case self::MAPI_CURRENCY:
+ case self::MAPI_INT8BYTE:
+ case self::MAPI_SYSTIME:
+ $value = $this->_getx($data, 8);
+ break;
+
+ case self::MAPI_STRING:
+ case self::MAPI_UNICODE_STRING:
+ case self::MAPI_BINARY:
+ case self::MAPI_OBJECT:
+ $num_vals = ($have_mval) ? $num_mval : $this->_geti($data, 32);
+ for ($i = 0; $i < $num_vals; $i++) {
+ $length = $this->_geti($data, 32);
+
+ /* Pad to next 4 byte boundary. */
+ $datalen = $length + ((4 - ($length % 4)) % 4);
+
+ if ($attr_type == self::MAPI_STRING) {
+ $length -= 1;
+ }
+
+ /* Read and truncate to length. */
+ $value = substr($this->_getx($data, $datalen), 0, $length);
+ }
+ break;
+ }
+
+ /* Store any interesting attributes. */
+ switch ($attr_name) {
+ case self::MAPI_ATTACH_LONG_FILENAME:
+ /* Used in preference to AFILENAME value. */
+ $attachment_data[0]['name'] = preg_replace('/.*[\/](.*)$/', '\1', $value);
+ $attachment_data[0]['name'] = str_replace("\0", '', $attachment_data[0]['name']);
+ break;
+
+ case self::MAPI_ATTACH_MIME_TAG:
+ /* Is this ever set, and what is format? */
+ $attachment_data[0]['type'] = preg_replace('/^(.*)\/.*/', '\1', $value);
+ $attachment_data[0]['subtype'] = preg_replace('/.*\/(.*)$/', '\1', $value);
+ $attachment_data[0]['subtype'] = str_replace("\0", '', $attachment_data[0]['subtype']);
+ break;
+ }
+ }
+ }
+
+ /**
+ * TODO
+ *
+ * @param string &$data The data string.
+ */
+ protected function _decodeMessage(&$data)
+ {
+ $this->_decodeAttribute($data, $this->_geti($data, 32));
+ }
+
+ /**
+ * TODO
+ *
+ * @param string &$data The data string.
+ * @param array &$attachment_data TODO
+ */
+ protected function _decodeAttachment(&$data, &$attachment_data)
+ {
+ $attribute = $this->_geti($data, 32);
+
+ switch ($attribute) {
+ case self::ARENDDATA:
+ /* Marks start of new attachment. */
+ $this->_getx($data, $this->_geti($data, 32));
+
+ /* Checksum */
+ $this->_geti($data, 16);
+
+ /* Add a new default data block to hold details of this
+ attachment. Reverse order is easier to handle later! */
+ array_unshift($attachment_data, array('type' => 'application',
+ 'subtype' => 'octet-stream',
+ 'name' => 'unknown',
+ 'stream' => ''));
+ break;
+
+ case self::AFILENAME:
+ /* Strip path. */
+ $attachment_data[0]['name'] = preg_replace('/.*[\/](.*)$/', '\1', $this->_getx($data, $this->_geti($data, 32)));
+ $attachment_data[0]['name'] = str_replace("\0", '', $attachment_data[0]['name']);
+
+ /* Checksum */
+ $this->_geti($data, 16);
+ break;
+
+ case self::ATTACHDATA:
+ /* The attachment itself. */
+ $length = $this->_geti($data, 32);
+ $attachment_data[0]['size'] = $length;
+ $attachment_data[0]['stream'] = $this->_getx($data, $length);
+
+ /* Checksum */
+ $this->_geti($data, 16);
+ break;
+
+ case self::AMAPIATTRS:
+ $length = $this->_geti($data, 32);
+ $value = $this->_getx($data, $length);
+
+ /* Checksum */
+ $this->_geti($data, 16);
+ $this->_extractMapiAttributes($value, $attachment_data);
+ break;
+
+ default:
+ $this->_decodeAttribute($data, $attribute);
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Horde_Compress_zip class allows ZIP files to be created and read.
+ *
+ * The ZIP compression code is partially based on code from:
+ * Eric Mueller <eric@themepark.com>
+ * http://www.zend.com/codex.php?id=535&single=1
+ *
+ * Deins125 <webmaster@atlant.ru>
+ * http://www.zend.com/codex.php?id=470&single=1
+ *
+ * The ZIP compression date code is partially based on code from
+ * Peter Listiak <mlady@users.sourceforge.net>
+ *
+ * Copyright 2000-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Michael Cochrane <mike@graftonhall.co.nz>
+ * @author Michael Slusarz <slusarz@horde.org>
+ * @package Horde_Compress
+ */
+class Horde_Compress_Zip extends Horde_Compress
+{
+ /* Constants used with decompress(). */
+ const ZIP_LIST = 1;
+ const ZIP_DATA = 2;
+
+ /* Beginning of central directory record. */
+ const CTRL_DIR_HEADER = "\x50\x4b\x01\x02";
+
+ /* End of central directory record. */
+ const CTRL_DIR_END = "\x50\x4b\x05\x06\x00\x00\x00\x00";
+
+ /* Beginning of file contents. */
+ const FILE_HEADER = "\x50\x4b\x03\x04";
+
+ /**
+ * ZIP compression methods.
+ *
+ * @var array
+ */
+ protected $_methods = array(
+ 0x0 => 'None',
+ 0x1 => 'Shrunk',
+ 0x2 => 'Super Fast',
+ 0x3 => 'Fast',
+ 0x4 => 'Normal',
+ 0x5 => 'Maximum',
+ 0x6 => 'Imploded',
+ 0x8 => 'Deflated'
+ );
+
+ /**
+ * Create a ZIP compressed file from an array of file data.
+ *
+ * @param array $data The data to compress.
+ * <pre>
+ * Requires an array of arrays - each subarray should contain the
+ * following fields:
+ * 'data' - (string) The data to compress.
+ * 'name' - (string) The pathname to the file.
+ * 'time' - (integer) [optional] The timestamp to use for the file.
+ * </pre>
+ * @param array $params The parameter array (unused).
+ *
+ * @return string The ZIP file.
+ */
+ public function compress($data, $params = array())
+ {
+ $contents = '';
+ $ctrldir = array();
+
+ reset($data);
+ while (list(, $val) = each($data)) {
+ $ctrldir = $this->_addToZipFile($val, $contents, $ctrldir);
+ }
+
+ return $this->_createZIPFile($contents, $ctrldir);
+ }
+
+ /**
+ * Decompress a ZIP file and get information from it.
+ *
+ * @param string $data The zipfile data.
+ * @param array $params The parameter array.
+ * <pre>
+ * The following parameters are REQUIRED:
+ * 'action' - (integer) The action to take on the data. Either
+ * self::ZIP_LIST or self::ZIP_DATA.
+ *
+ * The following parameters are REQUIRED for self::ZIP_DATA also:
+ * 'info' - (array) The zipfile list.
+ * 'key' - (integer) The position of the file in the archive list.
+ * </pre>
+ *
+ * @return mixed The requested data.
+ * @throws Horde_Exception
+ */
+ public function decompress($data, $params)
+ {
+ if (isset($params['action'])) {
+ switch ($params['action']) {
+ case self::ZIP_LIST:
+ return $this->_getZipInfo($data);
+
+ case self::ZIP_DATA:
+ return $this->_getZipData($data, $params['info'], $params['key']);
+ }
+ }
+ }
+
+ /**
+ * Get the list of files/data from the zip archive.
+ *
+ * @param string $data The zipfile data.
+ *
+ * @return array KEY: Position in zipfile
+ * VALUES:
+ * <pre>
+ * 'attr' -- File attributes
+ * 'crc' -- CRC checksum
+ * 'csize' -- Compressed file size
+ * 'date' -- File modification time
+ * 'name' -- Filename
+ * 'method' -- Compression method
+ * 'size' -- Original file size
+ * 'type' -- File type
+ * </pre>
+ *
+ * @throws Horde_Exception
+ */
+ protected function _getZipInfo($data)
+ {
+ $entries = array();
+
+ /* Get details from Central directory structure. */
+ $fhStart = strpos($data, self::CTRL_DIR_HEADER);
+
+ do {
+ if (strlen($data) < $fhStart + 31) {
+ throw new Horde_Exception(_("Invalid ZIP data"));
+ }
+ $info = unpack('vMethod/VTime/VCRC32/VCompressed/VUncompressed/vLength', substr($data, $fhStart + 10, 20));
+ $name = substr($data, $fhStart + 46, $info['Length']);
+
+ $entries[$name] = array(
+ 'attr' => null,
+ 'crc' => sprintf("%08s", dechex($info['CRC32'])),
+ 'csize' => $info['Compressed'],
+ 'date' => null,
+ '_dataStart' => null,
+ 'name' => $name,
+ 'method' => $this->_methods[$info['Method']],
+ '_method' => $info['Method'],
+ 'size' => $info['Uncompressed'],
+ 'type' => null
+ );
+
+ $entries[$name]['date'] =
+ mktime((($info['Time'] >> 11) & 0x1f),
+ (($info['Time'] >> 5) & 0x3f),
+ (($info['Time'] << 1) & 0x3e),
+ (($info['Time'] >> 21) & 0x07),
+ (($info['Time'] >> 16) & 0x1f),
+ ((($info['Time'] >> 25) & 0x7f) + 1980));
+
+ if (strlen($data) < $fhStart + 43) {
+ throw new Horde_Exception(_("Invalid ZIP data"));
+ }
+ $info = unpack('vInternal/VExternal', substr($data, $fhStart + 36, 6));
+
+ $entries[$name]['type'] = ($info['Internal'] & 0x01) ? 'text' : 'binary';
+ $entries[$name]['attr'] =
+ (($info['External'] & 0x10) ? 'D' : '-') .
+ (($info['External'] & 0x20) ? 'A' : '-') .
+ (($info['External'] & 0x03) ? 'S' : '-') .
+ (($info['External'] & 0x02) ? 'H' : '-') .
+ (($info['External'] & 0x01) ? 'R' : '-');
+ } while (($fhStart = strpos($data, self::CTRL_DIR_HEADER, $fhStart + 46)) !== false);
+
+ /* Get details from local file header. */
+ $fhStart = strpos($data, self::FILE_HEADER);
+
+ do {
+ if (strlen($data) < $fhStart + 34) {
+ throw new Horde_Exception(_("Invalid ZIP data"));
+ }
+ $info = unpack('vMethod/VTime/VCRC32/VCompressed/VUncompressed/vLength/vExtraLength', substr($data, $fhStart + 8, 25));
+ $name = substr($data, $fhStart + 30, $info['Length']);
+ $entries[$name]['_dataStart'] = $fhStart + 30 + $info['Length'] + $info['ExtraLength'];
+ } while (strlen($data) > $fhStart + 30 + $info['Length'] &&
+ ($fhStart = strpos($data, self::FILE_HEADER, $fhStart + 30 + $info['Length'])) !== false);
+
+ return array_values($entries);
+ }
+
+ /**
+ * Returns the data for a specific archived file.
+ *
+ * @param string $data The zip archive contents.
+ * @param array $info The information array from _getZipInfo().
+ * @param integer $key The position of the file in the archive.
+ *
+ * @return string The file data.
+ */
+ protected function _getZipData($data, $info, $key)
+ {
+ if (($info[$key]['_method'] == 0x8) &&
+ Horde_Util::extensionExists('zlib')) {
+ /* If the file has been deflated, and zlib is installed,
+ then inflate the data again. */
+ return @gzinflate(substr($data, $info[$key]['_dataStart'], $info[$key]['csize']));
+ } elseif ($info[$key]['_method'] == 0x0) {
+ /* Files that aren't compressed. */
+ return substr($data, $info[$key]['_dataStart'], $info[$key]['csize']);
+ }
+
+ return '';
+ }
+
+ /**
+ * Checks to see if the data is a valid ZIP file.
+ *
+ * @param string $data The ZIP file data.
+ *
+ * @return boolean True if valid, false if invalid.
+ */
+ public function checkZipData($data)
+ {
+ return (strpos($data, self::FILE_HEADER) !== false);
+ }
+
+ /**
+ * Converts a UNIX timestamp to a 4-byte DOS date and time format
+ * (date in high 2-bytes, time in low 2-bytes allowing magnitude
+ * comparison).
+ *
+ * @param integer $unixtime The current UNIX timestamp.
+ *
+ * @return integer The current date in a 4-byte DOS format.
+ */
+ protected function _unix2DOSTime($unixtime = null)
+ {
+ $timearray = (is_null($unixtime)) ? getdate() : getdate($unixtime);
+
+ if ($timearray['year'] < 1980) {
+ $timearray['year'] = 1980;
+ $timearray['mon'] = 1;
+ $timearray['mday'] = 1;
+ $timearray['hours'] = 0;
+ $timearray['minutes'] = 0;
+ $timearray['seconds'] = 0;
+ }
+
+ return (($timearray['year'] - 1980) << 25) |
+ ($timearray['mon'] << 21) |
+ ($timearray['mday'] << 16) |
+ ($timearray['hours'] << 11) |
+ ($timearray['minutes'] << 5) |
+ ($timearray['seconds'] >> 1);
+ }
+
+ /**
+ * Adds a "file" to the ZIP archive.
+ *
+ * @param array $file See self::createZipFile().
+ * @param string $contents The zip data.
+ * @param array $ctrldir An array of central directory information.
+ *
+ * @return array The updated value of $ctrldir.
+ */
+ protected function _addToZipFile($file, $contents, $ctrldir)
+ {
+ $data = $file['data'];
+ $name = str_replace('\\', '/', $file['name']);
+
+ /* See if time/date information has been provided. */
+ $ftime = (isset($file['time'])) ? $file['time'] : null;
+
+ /* Get the hex time. */
+ $dtime = dechex($this->_unix2DosTime($ftime));
+ $hexdtime = chr(hexdec($dtime[6] . $dtime[7])) .
+ chr(hexdec($dtime[4] . $dtime[5])) .
+ chr(hexdec($dtime[2] . $dtime[3])) .
+ chr(hexdec($dtime[0] . $dtime[1]));
+
+ /* "Local file header" segment. */
+ $unc_len = strlen($data);
+ $crc = crc32($data);
+ $zdata = gzcompress($data);
+ $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);
+ $c_len = strlen($zdata);
+ $old_offset = strlen($contents);
+
+ /* Common data for the two entries. */
+ $common =
+ "\x14\x00" . /* Version needed to extract. */
+ "\x00\x00" . /* General purpose bit flag. */
+ "\x08\x00" . /* Compression method. */
+ $hexdtime . /* Last modification time/date. */
+ pack('V', $crc) . /* CRC 32 information. */
+ pack('V', $c_len) . /* Compressed filesize. */
+ pack('V', $unc_len) . /* Uncompressed filesize. */
+ pack('v', strlen($name)) . /* Length of filename. */
+ pack('v', 0); /* Extra field length. */
+
+ /* Add this entry to zip data. */
+ $contents .=
+ self::FILE_HEADER . /* Begin creating the ZIP data. */
+ $common . /* Common data. */
+ $name . /* File name. */
+ $zdata; /* "File data" segment. */
+
+ /* Add to central directory record. */
+ $cdrec = self::CTRL_DIR_HEADER .
+ "\x00\x00" . /* Version made by. */
+ $common . /* Common data. */
+ pack('v', 0) . /* File comment length. */
+ pack('v', 0) . /* Disk number start. */
+ pack('v', 0) . /* Internal file attributes. */
+ pack('V', 32) . /* External file attributes -
+ 'archive' bit set. */
+ pack('V', $old_offset) . /* Relative offset of local
+ header. */
+ $name; /* File name. */
+
+ // Save to central directory array. */
+ $ctrldir[] = $cdrec;
+
+ return $ctrldir;
+ }
+
+ /**
+ * Creates the ZIP file.
+ * Official ZIP file format: http://www.pkware.com/appnote.txt
+ *
+ * @return string The ZIP file.
+ */
+ protected function _createZIPFile($contents, $ctrlDir)
+ {
+ $dir = implode('', $ctrlDir);
+
+ return $contents . $dir . self::CTRL_DIR_END .
+ /* Total # of entries "on this disk". */
+ pack('v', count($ctrlDir)) .
+ /* Total # of entries overall. */
+ pack('v', count($ctrlDir)) .
+ /* Size of central directory. */
+ pack('V', strlen($dir)) .
+ /* Offset to start of central dir. */
+ pack('V', strlen($contents)) .
+ /* ZIP file comment length. */
+ "\x00\x00";
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.4.9" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+http://pear.php.net/dtd/tasks-1.0.xsd
+http://pear.php.net/dtd/package-2.0
+http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Compress</name>
+ <channel>pear.horde.org</channel>
+ <summary>Horde Compression API</summary>
+ <description>This package provides an API for various compression techniques.
+ </description>
+ <lead>
+ <name>Chuck Hagenbuch</name>
+ <user>chuck</user>
+ <email>chuck@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <lead>
+ <name>Jan Schneider</name>
+ <user>jan</user>
+ <email>jan@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <lead>
+ <name>Michael Slusarz</name>
+ <user>slusarz</user>
+ <email>slusarz@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <date>2009-07-13</date>
+ <version>
+ <release>0.1.0</release>
+ <api>0.1.0</api>
+ </version>
+ <stability>
+ <release>beta</release>
+ <api>beta</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>* Initial Horde 4 package.
+ </notes>
+ <contents>
+ <dir name="/">
+ <dir name="lib">
+ <dir name="Horde">
+ <dir name="Compress">
+ <file name="Dbx.php" role="php" />
+ <file name="Gzip.php" role="php" />
+ <file name="Rar.php" role="php" />
+ <file name="Tar.php" role="php" />
+ <file name="Tnef.php" role="php" />
+ <file name="Zip.php" role="php" />
+ </dir> <!-- /lib/Horde/Compress -->
+ <file name="Compress.php" role="php" />
+ </dir> <!-- /lib/Horde -->
+ </dir> <!-- /lib -->
+ </dir> <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.2.0</min>
+ </php>
+ <pearinstaller>
+ <min>1.5.4</min>
+ </pearinstaller>
+ <package>
+ <name>Exception</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ <package>
+ <name>Util</name>
+ <channel>pear.horde.org</channel>
+ </package>
+ </required>
+ <optional>
+ <extension>
+ <name>gettext</name>
+ </extension>
+ <extension>
+ <name>zlib</name>
+ </extension>
+ </optional>
+ </dependencies>
+ <phprelease>
+ <filelist>
+ <install name="lib/Horde/Compress/Dbx.php" as="Horde/Compress/Dbx.php" />
+ <install name="lib/Horde/Compress/Gzip.php" as="Horde/Compress/Gzip.php" />
+ <install name="lib/Horde/Compress/Rar.php" as="Horde/Compress/Rar.php" />
+ <install name="lib/Horde/Compress/Tar.php" as="Horde/Compress/Tar.php" />
+ <install name="lib/Horde/Compress/Tnef.php" as="Horde/Compress/Tnef.php" />
+ <install name="lib/Horde/Compress/Zip.php" as="Horde/Compress/Zip.php" />
+ <install name="lib/Horde/Compress.php" as="Horde/Compress.php" />
+ </filelist>
+ </phprelease>
+ <changelog>
+ <release>
+ <date>2006-05-08</date>
+ <time>18:34:08</time>
+ <version>
+ <release>0.0.2</release>
+ <api>0.0.2</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>* Added rar driver.
+ * Converted to package.xml 2.0 for pear.horde.org
+ </notes>
+ </release>
+ <release>
+ <version>
+ <release>0.0.1</release>
+ <api>0.0.1</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <date>2003-07-03</date>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>Initial release as a PEAR package
+ </notes>
+ </release>
+ </changelog>
+</package>
'table:number-columns-spanned=' => 'colspan='
);
- $zip = Horde_Compress::singleton('zip');
+ $zip = Horde_Compress::factory('zip');
$list = $zip->decompress($this->_mimepart->getContents(), array('action' => HORDE_COMPRESS_ZIP_LIST));
foreach ($list as $key => $file) {
{
$contents = $this->_mimepart->getContents();
- $rar = Horde_Compress::singleton('rar');
-
+ $rar = Horde_Compress::factory('rar');
$rarData = $rar->decompress($contents);
- if (is_a($rarData, 'PEAR_Error')) {
- return array();
- }
$charset = Horde_Nls::getCharset();
$fileCount = count($rarData);
/* Decompress gzipped files. */
if (in_array($subtype, $this->_gzipSubtypes)) {
- $gzip = Horde_Compress::singleton('gzip');
+ $gzip = Horde_Compress::factory('gzip');
$contents = $gzip->decompress($contents);
- if (is_a($contents, 'PEAR_Error') || empty($contents)) {
- return array();
- }
}
/* Obtain the list of files/data in the tar file. */
- $tar = Horde_Compress::singleton('tar');
+ $tar = Horde_Compress::factory('tar');
$tarData = $tar->decompress($contents);
- if (is_a($tarData, 'PEAR_Error')) {
- return array();
- }
$charset = Horde_Nls::getCharset();
$fileCount = count($tarData);
*/
protected function _renderInline()
{
- $tnef = Horde_Compress::singleton('tnef');
+ $tnef = Horde_Compress::factory('tnef');
+ $info = $tnef->decompress($this->_mimepart->getContents());
$data = '<table border="1">';
- $info = $tnef->decompress($this->_mimepart->getContents());
- if (empty($info) || is_a($info, 'PEAR_Error')) {
+ if (empty($info)) {
$data .= '<tr><td>' . _("MS-TNEF Attachment contained no data.") . '</td></tr>';
} else {
$data .= '<tr><td>' . _("Name") . '</td><td>' . _("Mime Type") . '</td></tr>';
{
$contents = $this->_mimepart->getContents();
- $zip = Horde_Compress::singleton('zip');
-
- /* Make sure this is a valid zip file. */
- if ($zip->checkZipData($contents) === false) {
- return array();
- }
-
+ $zip = Horde_Compress::factory('zip');
$zipInfo = $zip->decompress($contents, array('action' => HORDE_COMPRESS_ZIP_LIST));
- if (is_a($zipInfo, 'PEAR_Error')) {
- return array();
- }
+
$fileCount = count($zipInfo);
/* Determine maximum file name length. */