[ Index ] |
|
Code source de Horde 3.1.3 |
1 <?php 2 /** 3 * The Horde_Compress_dbx class allows dbx files (e.g. from Outlook Express) 4 * to be read. 5 * 6 * This class is based on code by: 7 * Antony Raijekov <dev@strategma.bg> 8 * http://uruds.gateway.bg/zeos/ 9 * 10 * $Horde: framework/Compress/Compress/dbx.php,v 1.3.12.9 2006/01/01 21:28:11 jan Exp $ 11 * 12 * Copyright 2003-2006 Jan Schneider <jan@horde.org> 13 * 14 * See the enclosed file COPYING for license information (LGPL). If you 15 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. 16 * 17 * @author Jan Schneider <jan@horde.org> 18 * @since Horde 3.0 19 * @package Horde_Compress 20 */ 21 class Horde_Compress_dbx extends Horde_Compress { 22 23 /** 24 * TODO 25 * 26 * @var array 27 */ 28 var $_mails = array(); 29 30 /** 31 * TODO 32 * 33 * @var array 34 */ 35 var $_tmp = array(); 36 37 /** 38 * Decompresses a DBX file and gets information from it. 39 * 40 * @param string $data The dbx file data. 41 * @param array $params Any 42 * 43 * @return mixed The requested data. 44 */ 45 function decompress(&$data, $params = null) 46 { 47 $this->_mails = array(); 48 $this->_tmp = array(); 49 $position = 0xC4; 50 $header_info = unpack('Lposition/LDataLength/nHeaderLength/nFlagCount', substr($data, $position, 12)); 51 $position += 12; 52 // Go to the first table offest and process it. 53 if ($header_info['position'] > 0) { 54 $position = 0x30; 55 $buf = unpack('Lposition', substr($data, $position, 4)); 56 $position = $buf['position']; 57 $result = $this->_readIndex($data, $position); 58 if (is_a($result, 'PEAR_Error')) { 59 return $result; 60 } 61 } 62 return $this->_mails; 63 } 64 65 /** 66 * Returns a null-terminated string from the specified data. 67 * 68 * @access private 69 * 70 * @param string &$buf TODO 71 * @param integer $pos TODO 72 * 73 * @return string TODO 74 */ 75 function _readString(&$buf, $pos) 76 { 77 if ($len = strpos(substr($buf, $pos), chr(0))) { 78 return substr($buf, $pos, $len); 79 } 80 return ''; 81 } 82 83 /** 84 * TODO 85 * 86 * @access private 87 * 88 * @param string &$data TODO 89 * @param integer $position TODO 90 * 91 * @return string TODO 92 */ 93 function _readMessage(&$data, $position) 94 { 95 $msg = ''; 96 $part = 0; 97 98 if ($position > 0) { 99 $IndexItemsCount = array_pop(unpack('S', substr($data, 0xC4, 4))); 100 if ($IndexItemsCount > 0) { 101 while ($position < strlen($data)) { 102 $part++; 103 $s = substr($data, $position, 528); 104 if (strlen($s) == 0) { 105 break; 106 } 107 $msg_item = unpack('LFilePos/LUnknown/LItemSize/LNextItem/a512Content', $s); 108 if ($msg_item['FilePos'] != $position) { 109 return PEAR::raiseError(_("Invalid file format")); 110 } 111 $position += 528; 112 $msg .= substr($msg_item['Content'], 0, $msg_item['ItemSize']); 113 $position = $msg_item['NextItem']; 114 if ($position == 0) { 115 break; 116 } 117 } 118 } 119 } 120 121 return $msg; 122 } 123 124 /** 125 * TODO 126 * 127 * @access private 128 * 129 * @param string &$data TODO 130 * @param integer $position TODO 131 * 132 * @return array TODO 133 */ 134 function _readMessageInfo(&$data, $position) 135 { 136 $message_info = array(); 137 $msg_header = unpack('Lposition/LDataLength/SHeaderLength/SFlagCount', substr($data, $position, 12)); 138 if ($msg_header['position'] != $position) { 139 return PEAR::raiseError(_("Invalid file format")); 140 } 141 $position += 12; 142 $message_info['HeaderPosition'] = $msg_header['position']; 143 $flags = $msg_header['FlagCount'] & 0xFF; 144 $DataSize = $msg_header['DataLength'] - $flags * 4; 145 $size = 4 * $flags; 146 $FlagsBuffer = substr($data, $position, $size); 147 $position += $size; 148 $size = $DataSize; 149 $DataBuffer = substr($data, $position, $size); 150 $position += $size; 151 $message_info = array(); 152 153 $flag_array = array( 154 0x1 => 'MsgFlags', 155 0x2 => 'Sent', 156 0x4 => 'position', 157 0x7 => 'MessageID', 158 0x8 => 'Subject', 159 0x9 => 'From_reply', 160 0xA => 'References', 161 0xB => 'Newsgroup', 162 0xD => 'From', 163 0xE => 'Reply_To', 164 0x12 => 'Received', 165 0x13 => 'Receipt', 166 0x1A => 'Account', 167 0x1B => 'AccountID', 168 0x80 => 'Msg', 169 0x81 => 'MsgFlags', 170 0x84 => 'position', 171 0x91 => 'size', 172 ); 173 174 /* Process flags */ 175 for ($i = 0; $i < $flags; $i++) { 176 $pos = 0; 177 $f = array_pop(unpack('L', substr($FlagsBuffer, $i * 4, 4))); 178 179 $mask = $f & 0xFF; 180 switch ($mask) { 181 case 0x1: 182 $pos = $pos + ($f >> 8); 183 $message_info['MsgFlags'] = array_pop(unpack('C', substr($DataBuffer, $pos++, 1))); 184 $message_info['MsgFlags'] += array_pop(unpack('C', substr($DataBuffer, $pos++, 1))) * 256; 185 $message_info['MsgFlags'] += array_pop(unpack('C', substr($DataBuffer, $pos, 1))) * 65536; 186 break; 187 188 case 0x2: 189 case 0x4: 190 $pos += array_pop(unpack('L', substr($FlagsBuffer, $i * 4, 4))) >> 8; 191 $message_info[$flag_array[$mask]] = array_pop(unpack('L', substr($DataBuffer, $pos, 4))); 192 break; 193 194 case 0x7: 195 case 0x8: 196 case 0x9: 197 case 0xA: 198 case 0xB: 199 case 0xD: 200 case 0xE: 201 case 0x13: 202 case 0x1A: 203 $pos += array_pop(unpack('L', substr($FlagsBuffer, $i * 4, 4))) >> 8; 204 $message_info[$flag_array[$mask]] = $this->_readString($DataBuffer, $pos); 205 break; 206 207 case 0x12: 208 $pos += array_pop(unpack('L', substr($FlagsBuffer, $i * 4, 4))) >> 8; 209 $message_info['Received'] = array_pop(unpack('L', substr($DataBuffer, $pos, 4))); 210 break; 211 212 case 0x1B: 213 $pos += array_pop(unpack('L', substr($FlagsBuffer, $i * 4, 4))) >> 8; 214 $message_info['AccountID'] = intval($this->_readString($DataBuffer, $pos)); 215 break; 216 217 case 0x80: 218 case 0x81: 219 case 0x84: 220 case 0x91: 221 $message_info[$flag_array[$mask]] = array_pop(unpack('L', substr($FlagsBuffer, $i * 4, 4))) >> 8; 222 break; 223 } 224 } 225 226 return $message_info; 227 } 228 229 /** 230 * TODO 231 * 232 * @access private 233 * 234 * @param string &$data TODO 235 * @param integer $position TODO 236 */ 237 function _readIndex(&$data, $position) 238 { 239 $index_header = unpack('LFilePos/LUnknown1/LPrevIndex/LNextIndex/LCount/LUnknown', substr($data, $position, 24)); 240 if ($index_header['FilePos'] != $position) { 241 return PEAR::raiseError(_("Invalid file format")); 242 } 243 244 // Push it into list of processed items. 245 $this->_tmp[$position] = true; 246 if (($index_header['NextIndex'] > 0) && 247 empty($this->_tmp[$index_header['NextIndex']])) { 248 $this->_readIndex($data, $index_header['NextIndex']); 249 } 250 if (($index_header['PrevIndex'] > 0) && 251 empty($this->_tmp[$index_header['PrevIndex']])) { 252 $this->_readIndex($data, $index_header['PrevIndex']); 253 } 254 $position += 24; 255 $icount = $index_header['Count'] >> 8; 256 if ($icount > 0) { 257 $buf = substr($data, $position, 12 * $icount); 258 for ($i = 0; $i < $icount; $i++) { 259 $hdr_buf = substr($buf, $i * 12, 12); 260 $IndexItem = unpack('LHeaderPos/LChildIndex/LUnknown', $hdr_buf); 261 if ($IndexItem['HeaderPos'] > 0) { 262 $mail['info'] = $this->_readMessageInfo($data, $IndexItem['HeaderPos']); 263 $mail['content'] = $this->_readMessage($data, $mail['info']['position']); 264 $this->_mails[] = $mail; 265 } 266 if (($IndexItem['ChildIndex'] > 0) && 267 empty($this->_tmp[$IndexItem['ChildIndex']])) { 268 $this->_readIndex($fp, $IndexItem['ChildIndex']); 269 } 270 } 271 } 272 } 273 274 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 18:01:28 2007 | par Balluche grâce à PHPXref 0.7 |