Example #1
0
 /**
  * Constructor.
  *
  * @param mixed $rfc822              The incoming message. Either a string
  *                                   or a stream resource.
  * @param boolean $auto_add_headers  Automatically add the standard
  *                                   Message-ID and User-Agent headers?
  *                                   @since 2.14.0
  */
 public function __construct($rfc822, $auto_add_headers = true)
 {
     if (is_resource($rfc822)) {
         $stream = new Horde_Stream_Existing(array('stream' => $rfc822));
         $stream->rewind();
     } else {
         $stream = new Horde_Stream_Temp(array('max_memory' => self::$memoryLimit));
         $stream->add($rfc822, true);
     }
     $this->_parseStream($stream);
     if ($auto_add_headers) {
         $this->addStandardHeaders();
     }
 }
Example #2
0
 /**
  */
 protected function _read()
 {
     try {
         if (method_exists($this->_vfs, 'readStream')) {
             $stream = new Horde_Stream_Existing(array('stream' => $this->_vfs->readStream($this->_vfspath, $this->_id)));
             $stream->rewind();
         } else {
             $stream = new Horde_Stream_Temp();
             $stream->add($this->_vfs->read($this->_vfspath, $this->_id), true);
         }
         return $stream;
     } catch (Horde_Vfs_Exception $e) {
         throw new IMP_Compose_Exception($e);
     }
 }
Example #3
0
 /**
  */
 protected function _get($keys)
 {
     if (!$this->_stream) {
         return parent::_get($keys);
     }
     $out = array();
     foreach ($keys as $key) {
         try {
             if (method_exists($this->_vfs, 'readStream')) {
                 $data = new Horde_Stream_Existing(array('stream' => $this->_vfs->readStream($this->_params['vfspath'], $key)));
                 $data->rewind();
             } else {
                 $data = new Horde_Stream_Temp();
                 $data->add($this->_vfs->read($this->_params['vfspath'], $key), true);
             }
         } catch (Horde_Vfs_Exception $e) {
             $data = false;
         }
         $out[$key] = $data;
     }
     return $out;
 }
Example #4
0
 /**
  * Replace the MIME part of the message sent from the client. Headers from
  * the original message are always used.
  *
  * @param  Horde_Mime_Part $part  The new MIME part.
  * @since 2.19.0
  */
 public function replaceMime(Horde_Mime_Part $part)
 {
     $mime_stream = $part->toString(array('stream' => true, 'headers' => false));
     $mime_stream = new Horde_Stream_Existing(array('stream' => $mime_stream));
     // Since we are still using the headers sent from the device, we can
     // simply zero out the position members etc...
     $this->_hdr_pos = 0;
     $this->_stream = $mime_stream;
     $mime_stream->rewind();
 }
Example #5
0
 /**
  * Creates a new file in the directory
  *
  * @param string $name Name of the file
  * @param resource|string $data Initial payload
  * @return null|string
  */
 public function createFile($name, $data = null)
 {
     list($app) = explode('/', $this->_path);
     if (is_resource($data)) {
         $content = new Horde_Stream_Existing(array('stream' => $data));
         $type = Horde_Mime_Magic::analyzeData($content->getString(0, 100), $this->_mimedb);
     } else {
         $content = $data;
         $type = Horde_Mime_Magic::analyzeData($content, $this->_mimedb);
     }
     if (!$type) {
         $type = Horde_Mime_Magic::filenameToMime($name);
     }
     try {
         $this->_registry->callByPackage($app, 'put', array($this->_path . '/' . $name, $content, $type));
     } catch (Horde_Exception $e) {
         throw new DAV\Exception($e->getMessage(), $e->getCode(), $e);
     }
 }
Example #6
0
 /**
  * Return the full message text.
  *
  * @param boolean $stream  Return data as a stream?
  *
  * @return mixed  A string or stream resource.
  * @throws Horde_ActiveSync_Exception
  */
 public function getFullMsg($stream = false)
 {
     // First see if we already have it.
     if ($stream) {
         $full = new Horde_Stream_Existing(array('stream' => $this->_data->getFullMsg($stream)));
         $length = $full->length();
         if (!$length) {
             $full->close();
         }
     } else {
         $full = $this->_data->getFullMsg(false);
         $length = strlen($full);
     }
     if (!$length) {
         $query = new Horde_Imap_Client_Fetch_Query();
         $query->fullText(array('peek' => true));
         try {
             $fetch_ret = $this->_imap->fetch($this->_mbox, $query, array('ids' => new Horde_Imap_Client_Ids(array($this->uid))));
         } catch (Horde_Imap_Exception $e) {
             throw new Horde_ActiveSync_Exception($e);
         }
         $data = $fetch_ret[$this->uid];
         $full = $data->getFullMsg($stream);
     }
     return $full;
 }
Example #7
0
 /**
  * Encodes the contents of the part as necessary for transport.
  *
  * @param resource $fp      A stream containing the data to encode.
  * @param string $encoding  The encoding to use.
  *
  * @return resource  A new file resource with the encoded data.
  */
 protected function _transferEncode($fp, $encoding)
 {
     $this->_temp['transferEncodeClose'] = true;
     switch ($encoding) {
         case 'base64':
             /* Base64 Encoding: See RFC 2045, section 6.8 */
             return $this->_writeStream($fp, array('filter' => array('convert.base64-encode' => array('line-break-chars' => $this->getEOL(), 'line-length' => 76))));
         case 'quoted-printable':
             // PHP Bug 65776 - Must normalize the EOL characters.
             stream_filter_register('horde_eol', 'Horde_Stream_Filter_Eol');
             $stream = new Horde_Stream_Existing(array('stream' => $fp));
             $stream->stream = $this->_writeStream($stream->stream, array('filter' => array('horde_eol' => array('eol' => $stream->getEOL()))));
             /* Quoted-Printable Encoding: See RFC 2045, section 6.7 */
             return $this->_writeStream($fp, array('filter' => array('convert.quoted-printable-encode' => array_filter(array('line-break-chars' => $stream->getEOL(), 'line-length' => 76)))));
         default:
             $this->_temp['transferEncodeClose'] = false;
             return $fp;
     }
 }
Example #8
0
 /**
  * Encodes the contents of the part as necessary for transport.
  *
  * @param resource $fp      A stream containing the data to encode.
  * @param string $encoding  The encoding to use.
  *
  * @return resource  A new file resource with the encoded data.
  */
 protected function _transferEncode($fp, $encoding)
 {
     $this->_temp['transferEncodeClose'] = true;
     switch ($encoding) {
         case 'base64':
             /* Base64 Encoding: See RFC 2045, section 6.8 */
             return $this->_writeStream($fp, array('filter' => array('convert.base64-encode' => array('line-break-chars' => $this->getEOL(), 'line-length' => 76))));
         case 'quoted-printable':
             $stream = new Horde_Stream_Existing(array('stream' => $fp));
             /* Quoted-Printable Encoding: See RFC 2045, section 6.7 */
             return $this->_writeStream($fp, array('filter' => array('convert.quoted-printable-encode' => array_filter(array('line-break-chars' => $stream->getEOL(), 'line-length' => 76)))));
         default:
             $this->_temp['transferEncodeClose'] = false;
             return $fp;
     }
 }
Example #9
0
 /**
  *
  * @param mixed $path  Filename -or- an open PHP stream.
  *
  * @return array
  */
 protected function _readData($path)
 {
     if (is_resource($path)) {
         $in = new Horde_Stream_Existing(array('stream' => $path));
         $in->rewind();
     } else {
         $in = new Horde_Stream_Existing(array('stream' => @fopen($path, 'rb')));
     }
     $globalOffset = 0;
     $result = array('Errors' => 0);
     // if the path was invalid, this error will catch it
     if (!$in) {
         $result['Errors'] = 1;
         $result['Error'][$result['Errors']] = Horde_Image_Translation::t("The file could not be opened.");
         return $result;
     }
     // First 2 bytes of JPEG are 0xFFD8
     $data = bin2hex($in->substring(0, 2));
     if ($data == 'ffd8') {
         $result['ValidJpeg'] = 1;
     } else {
         $result['ValidJpeg'] = 0;
         if (!is_resource($path)) {
             $in->close();
         }
         return $result;
     }
     $result['ValidIPTCData'] = 0;
     $result['ValidJFIFData'] = 0;
     $result['ValidEXIFData'] = 0;
     $result['ValidAPP2Data'] = 0;
     $result['ValidCOMData'] = 0;
     // Next 2 bytes are marker tag (0xFFE#)
     $data = bin2hex($in->substring(0, 2));
     $size = bin2hex($in->substring(0, 2));
     // Loop through markers till you get to FFE1 (Exif marker)
     while (!$in->eof() && $data != 'ffe1' && $data != 'ffc0' && $data != 'ffd9') {
         switch ($data) {
             case 'ffe0':
                 // JFIF Marker
                 $result['ValidJFIFData'] = 1;
                 $result['JFIF']['Size'] = hexdec($size);
                 if (hexdec($size) - 2 > 0) {
                     $data = $in->substring(0, hexdec($size) - 2);
                     $result['JFIF']['Data'] = $data;
                 }
                 $result['JFIF']['Identifier'] = substr($data, 0, 5);
                 $result['JFIF']['ExtensionCode'] = bin2hex(substr($data, 6, 1));
                 $globalOffset += hexdec($size) + 2;
                 break;
             case 'ffed':
                 // IPTC Marker
                 $result['ValidIPTCData'] = 1;
                 $result['IPTC']['Size'] = hexdec($size);
                 if (hexdec($size) - 2 > 0) {
                     $data = $in->substring(0, hexdec($size) - 2);
                     $result['IPTC']['Data'] = $data;
                 }
                 $globalOffset += hexdec($size) + 2;
                 break;
             case 'ffe2':
                 // EXIF extension Marker
                 $result['ValidAPP2Data'] = 1;
                 $result['APP2']['Size'] = hexdec($size);
                 if (hexdec($size) - 2 > 0) {
                     $data = $in->substring(0, hexdec($size) - 2);
                     $result['APP2']['Data'] = $data;
                 }
                 $globalOffset += hexdec($size) + 2;
                 break;
             case 'fffe':
                 // COM extension Marker
                 $result['ValidCOMData'] = 1;
                 $result['COM']['Size'] = hexdec($size);
                 if (hexdec($size) - 2 > 0) {
                     $data = $in->substring(0, hexdec($size) - 2);
                     $result['COM']['Data'] = $data;
                 }
                 $globalOffset += hexdec($size) + 2;
                 break;
             case 'ffe1':
                 $result['ValidEXIFData'] = 1;
                 break;
         }
         $data = bin2hex($in->substring(0, 2));
         $size = bin2hex($in->substring(0, 2));
     }
     if ($data != 'ffe1') {
         if (!is_resource($path)) {
             $in->close();
         }
         return $result;
     }
     $result['ValidEXIFData'] = 1;
     // Size of APP1
     $result['APP1Size'] = hexdec($size);
     // Start of APP1 block starts with 'Exif' header (6 bytes)
     $header = $in->substring(0, 6);
     // Then theres a TIFF header with 2 bytes of endieness (II or MM)
     $header = $in->substring(0, 2);
     switch ($header) {
         case 'II':
             $intel = 1;
             $result['Endien'] = 'Intel';
             break;
         case 'MM':
             $intel = 0;
             $result['Endien'] = 'Motorola';
             break;
         default:
             // not sure what the default should be, but this seems reasonable
             $intel = 1;
             $result['Endien'] = 'Unknown';
             break;
     }
     // 2 bytes of 0x002a
     if (bin2hex($in->substring(0, 2)) != '002a') {
         $result['Errors'] = $result['Errors'] + 1;
         $result['Error'][$result['Errors']] = 'Unexpected value.';
         return $result;
     }
     // Then 4 bytes of offset to IFD0 (usually 8 which includes all 8 bytes
     // of TIFF header)
     $offset = bin2hex($in->substring(0, 4));
     if ($intel == 1) {
         $offset = Horde_Image_Exif::intel2Moto($offset);
     }
     // Check for extremely large values here
     if (hexdec($offset) > 100000) {
         $result['ValidEXIFData'] = 0;
         if (!is_resource($path)) {
             $in->close();
         }
         return $result;
     }
     if (hexdec($offset) > 8) {
         $unknown = $in->substring(0, hexdec($offset) - 8);
     }
     // add 12 to the offset to account for TIFF header
     $globalOffset += 12;
     //===========================================================
     // Start of IFD0
     $num = bin2hex($in->substring(0, 2));
     if ($intel == 1) {
         $num = Horde_Image_Exif::intel2Moto($num);
     }
     $num = hexdec($num);
     $result['IFD0NumTags'] = $num;
     // 1000 entries is too much and is probably an error.
     if ($num < 1000) {
         for ($i = 0; $i < $num; $i++) {
             $this->_readEntry($result, $in, $intel, 'IFD0', $globalOffset);
         }
     } else {
         $result['Errors'] = $result['Errors'] + 1;
         $result['Error'][$result['Errors']] = 'Illegal size for IFD0';
     }
     // store offset to IFD1
     $offset = bin2hex($in->substring(0, 4));
     if ($intel == 1) {
         $offset = Horde_Image_Exif::intel2Moto($offset);
     }
     $result['IFD1Offset'] = hexdec($offset);
     // Check for SubIFD
     if (!isset($result['IFD0']['ExifOffset']) || $result['IFD0']['ExifOffset'] == 0) {
         if (!is_resource($path)) {
             $in->close();
         }
         return $result;
     }
     // seek to SubIFD (Value of ExifOffset tag) above.
     $ExifOffset = $result['IFD0']['ExifOffset'];
     if (!$in->seek($globalOffset + $ExifOffset, false)) {
         $result['Errors'] = $result['Errors'] + 1;
         $result['Error'][$result['Errors']] = Horde_Image_Translation::t("Couldnt Find SubIFD");
     }
     //===========================================================
     // Start of SubIFD
     $num = bin2hex($in->substring(0, 2));
     if ($intel == 1) {
         $num = Horde_Image_Exif::intel2Moto($num);
     }
     $num = hexdec($num);
     $result['SubIFDNumTags'] = $num;
     // 1000 entries is too much and is probably an error.
     if ($num < 1000) {
         for ($i = 0; $i < $num; $i++) {
             $this->_readEntry($result, $in, $intel, 'SubIFD', $globalOffset);
         }
     } else {
         $result['Errors'] = $result['Errors'] + 1;
         $result['Error'][$result['Errors']] = Horde_Image_Translation::t("Illegal size for SubIFD");
     }
     // Add the 35mm equivalent focal length:
     // Now properly get this using the FocalLength35mmFilm tag
     //$result['SubIFD']['FocalLength35mmEquiv'] = get35mmEquivFocalLength($result);
     // Check for IFD1
     if (!isset($result['IFD1Offset']) || $result['IFD1Offset'] == 0) {
         if (!is_resource($path)) {
             $in->close();
         }
         return $result;
     }
     // seek to IFD1
     if (!$in->seek($globalOffset + $result['IFD1Offset'], false)) {
         $result['Errors'] = $result['Errors'] + 1;
         $result['Error'][$result['Errors']] = Horde_Image_Translation::t("Couldnt Find IFD1");
     }
     //===========================================================
     // Start of IFD1
     $num = bin2hex($in->substring(0, 2));
     if ($intel == 1) {
         $num = Horde_Image_Exif::intel2Moto($num);
     }
     $num = hexdec($num);
     $result['IFD1NumTags'] = $num;
     // 1000 entries is too much and is probably an error.
     if ($num < 1000) {
         for ($i = 0; $i < $num; $i++) {
             $this->_readEntry($result, $in, $intel, 'IFD1', $globalOffset);
         }
     } else {
         $result['Errors'] = $result['Errors'] + 1;
         $result['Error'][$result['Errors']] = Horde_Image_Translation::t("Illegal size for IFD1");
     }
     // include the thumbnail raw data...
     if ($result['IFD1']['JpegIFOffset'] > 0 && $result['IFD1']['JpegIFByteCount'] > 0) {
         $cpos = $in->pos();
         if ($in->seek($globalOffset + $result['IFD1']['JpegIFOffset'], false)) {
             $data = $in->substring(0, $result['IFD1']['JpegIFByteCount']);
         } else {
             $result['Errors'] = $result['Errors'] + 1;
         }
         $result['IFD1']['ThumbnailData'] = $data;
     }
     // Check for Interoperability IFD
     if (!isset($result['SubIFD']['ExifInteroperabilityOffset']) || $result['SubIFD']['ExifInteroperabilityOffset'] == 0) {
         if (!is_resource($path)) {
             $in->close();
         }
         return $result;
     }
     // Seek to InteroperabilityIFD
     if (!$in->seek($globalOffset + $result['SubIFD']['ExifInteroperabilityOffset'], false)) {
         $result['Errors'] = $result['Errors'] + 1;
         $result['Error'][$result['Errors']] = Horde_Image_Translation::t("Couldnt Find InteroperabilityIFD");
     }
     //===========================================================
     // Start of InteroperabilityIFD
     $num = bin2hex($in->substring(0, 2));
     if ($intel == 1) {
         $num = Horde_Image_Exif::intel2Moto($num);
     }
     $num = hexdec($num);
     $result['InteroperabilityIFDNumTags'] = $num;
     // 1000 entries is too much and is probably an error.
     if ($num < 1000) {
         for ($i = 0; $i < $num; $i++) {
             $this->_readEntry($result, $in, $intel, 'InteroperabilityIFD', $globalOffset);
         }
     } else {
         $result['Errors'] = $result['Errors'] + 1;
         $result['Error'][$result['Errors']] = Horde_Image_Translation::t("Illegal size for InteroperabilityIFD");
     }
     if (!is_resource($path)) {
         $in->close();
     }
     return $result;
 }