3
* The MIME_Viewer_rar class renders out the contents of .rar archives in HTML
6
* $Horde: framework/MIME/MIME/Viewer/rar.php,v 1.18.10.2 2005/01/03 12:19:06 jan Exp $
8
* Copyright 1999-2005 Anil Madhavapeddy <anil@recoil.org>
9
* Copyright 2002-2005 Michael Cochrane <mike@graftonhall.co.nz>
11
* See the enclosed file COPYING for license information (LGPL). If you
12
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
14
* @author Anil Madhavapeddy <anil@recoil.org>
15
* @author Michael Cochrane <mike@graftonhall.co.nz>
16
* @version $Revision: 1.18.10.2 $
18
* @package Horde_MIME_Viewer
20
class MIME_Viewer_rar extends MIME_Viewer {
23
* Rar compression methods.
25
* @var array $_methods
27
var $_methods = array(
37
* Render out the currently set contents using rar.
41
* @param optional array $params Any parameters the Viewer may need.
43
* @return string The rendered contents.
45
function render($params = array())
47
$contents = $this->mime_part->getContents();
49
/* Make sure this is a valid rar file. */
50
if ($this->checkRarData($contents) === false) {
51
return '<pre>' . _("This does not appear to be a valid rar archive.") . '</pre>';
54
require_once 'Horde/Text.php';
56
$rarData = $this->getRarData($contents);
57
$fileCount = count($rarData);
59
$text = '<b>' . htmlspecialchars(sprintf(_("Contents of '%s'"), $this->mime_part->getName())) . ':</b>' . "\n";
60
$text .= '<table><tr><td align="left"><tt><span class="fixed">';
61
$text .= Text::htmlAllSpaces(_("Archive Name") . ': ' . $this->mime_part->getName()) . "\n";
62
$text .= Text::htmlAllSpaces(_("Archive File Size") . ': ' . strlen($contents) . ' bytes') . "\n";
63
$text .= Text::htmlAllSpaces(($fileCount != 1) ? sprintf(_("File Count: %s files"), $fileCount) : sprintf(_("File Count: %s file"), $fileCount));
65
$text .= Text::htmlAllSpaces(
66
str_pad(_("File Name"), 50, ' ', STR_PAD_RIGHT) .
67
str_pad(_("Attributes"), 10, ' ', STR_PAD_LEFT) .
68
str_pad(_("Size"), 10, ' ', STR_PAD_LEFT) .
69
str_pad(_("Modified Date"), 19, ' ', STR_PAD_LEFT) .
70
str_pad(_("Method"), 10, ' ', STR_PAD_LEFT) .
71
str_pad(_("Ratio"), 7, ' ', STR_PAD_LEFT)
74
$text .= str_repeat('-', 106) . "\n";
76
foreach ($rarData as $val) {
77
$ratio = (empty($val['size'])) ? 0 : 100 * ($val['csize'] / $val['size']);
78
$text .= Text::htmlAllSpaces(
79
str_pad($val['name'], 50, ' ', STR_PAD_RIGHT) .
80
str_pad($val['attr'], 10, ' ', STR_PAD_LEFT) .
81
str_pad($val['size'], 10, ' ', STR_PAD_LEFT) .
82
str_pad(strftime("%d-%b-%Y %H:%M", $val['date']), 19, ' ', STR_PAD_LEFT) .
83
str_pad($val['method'], 10, ' ', STR_PAD_LEFT) .
84
str_pad(sprintf("%1.1f%%", $ratio), 7, ' ', STR_PAD_LEFT)
88
$text .= str_repeat('-', 106) . "\n";
89
$text .= '</span></tt></td></tr></table>';
95
* Returns the MIME type of this part.
99
* @return string The MIME type of this part.
103
return 'text/html; charset=' . NLS::getCharset();
107
* Checks to see if the data is a valid Rar archive.
111
* @param string &$data The rar archive data.
113
* @return boolean True if valid, false if invalid.
115
function checkRarData(&$data)
117
$fileHeader = "\x52\x61\x72\x21\x1a\x07\x00";
118
if (strpos($data, $fileHeader) === false) {
126
* Get the list of files/data from the rar archive.
130
* @param string &$data The rar archive data.
132
* @return array KEY: Position in RAR archive
133
* VALUES: 'attr' -- File attributes
134
* 'date' -- File modification time
135
* 'csize' -- Compressed file size
136
* 'method' -- Compression method
138
* 'size' -- Original file size
140
function getRarData(&$data)
142
$return_array = array();
144
$blockStart = strpos($data, "\x52\x61\x72\x21\x1a\x07\x00");
145
$position = $blockStart + 7;
147
while ($position < strlen($data)) {
148
$head_crc = substr($data, $position + 0, 2);
149
$head_type = ord(substr($data, $position + 2, 1));
150
$head_flags = unpack('vFlags', substr($data, $position + 3, 2));
151
$head_flags = $head_flags['Flags'];
152
$head_size = unpack('vSize', substr($data, $position + 5, 2));
153
$head_size = $head_size['Size'];
158
switch ($head_type) {
162
$position += $head_size;
170
$info = unpack('VPacked/VUnpacked/COS/VCRC32/VTime/CVersion/CMethod/vLength/vAttrib', substr($data, $position));
172
$file['name'] = substr($data, $position + 25, $info['Length']);
173
$file['size'] = $info['Unpacked'];
174
$file['csize'] = $info['Packed'];
176
$file['date'] = mktime((($info['Time'] >> 11) & 0x1f),
177
(($info['Time'] >> 5) & 0x3f),
178
(($info['Time'] << 1) & 0x3e),
179
(($info['Time'] >> 21) & 0x07),
180
(($info['Time'] >> 16) & 0x1f),
181
((($info['Time'] >> 25) & 0x7f) + 80));
183
$file['method'] = $this->_methods[$info['Method']];
186
$file['attr'] .= ($info['Attrib'] & 0x10) ? 'D' : '-';
187
$file['attr'] .= ($info['Attrib'] & 0x20) ? 'A' : '-';
188
$file['attr'] .= ($info['Attrib'] & 0x03) ? 'S' : '-';
189
$file['attr'] .= ($info['Attrib'] & 0x02) ? 'H' : '-';
190
$file['attr'] .= ($info['Attrib'] & 0x01) ? 'R' : '-';
192
$return_array[] = $file;
194
$position += $head_size;
195
$position += $info['Packed'];
199
$position += $head_size;
200
if (isset($add_size)) {
201
$position += $add_size;
208
return $return_array;