/** */ public function __toString() { $pos = $this->_stream->pos(); $out = $this->_current . ' ' . $this->_stream->getString(); $this->_stream->seek($pos, false); return $out; }
/** * Find the location of the end of the header text. * * @return array 1st element: Header position, 2nd element: Length of * trailing EOL. */ protected function _findHeader() { $i = 0; while (!$this->_stream->eof()) { $data = $this->_stream->substring(0, 8192); $hdr_pos = strpos($data, "\r\n\r\n"); if ($hdr_pos !== false) { return array($hdr_pos + $i * 8192, 4); } $hdr_pos = strpos($data, "\n\n"); if ($hdr_pos !== false) { return array($hdr_pos + $i * 8192, 2); } $i++; } $this->_stream->end(); return array($this->_stream->pos(), 0); }
/** * @return mixed Either a string, boolean (true for open paren, false for * close paren/EOS), Horde_Stream object, or null. */ public function next() { $level = isset($this->_nextModify['level']) ? $this->_nextModify['level'] : null; /* Directly access stream here to drastically reduce the number of * getChar() calls we would have to make. */ $stream = $this->_stream->stream; do { $check_len = true; $in_quote = $text = $binary = false; while (($c = fgetc($stream)) !== false) { switch ($c) { case '\\': $text .= $in_quote ? fgetc($stream) : $c; break; case '"': if ($in_quote) { $check_len = false; break 2; } $in_quote = true; /* Set $text to non-false (could be empty string). */ $text = ''; break; default: if ($in_quote) { $text .= $c; break; } switch ($c) { case '(': ++$this->_level; $check_len = false; $text = true; break 3; case ')': if ($text === false) { --$this->_level; $check_len = $text = false; } else { $this->_stream->seek(-1); } break 3; case '~': // Ignore binary string identifier. PHP strings are // binary-safe. But keep it if it is not used as string // identifier. $binary = true; $text .= $c; continue; case '{': if ($binary) { $text = substr($text, 0, -1); } $literal_len = intval($this->_stream->getToChar('}')); $pos = $this->_stream->pos(); if (isset($this->_literals[$pos])) { $text = $this->_literals[$pos]; if (!$this->_literalStream) { $text = strval($text); } } elseif ($this->_literalStream) { $text = new Horde_Stream_Temp(); while ($literal_len > 0 && !feof($stream)) { $part = $this->_stream->substring(0, min($literal_len, 8192)); $text->add($part); $literal_len -= strlen($part); } } else { $text = $this->_stream->substring(0, $literal_len); } $check_len = false; break 3; case ' ': if ($text !== false) { break 3; } break; default: $text .= $c; break; } break; } $binary = false; } if ($check_len) { switch (strlen($text)) { case 0: $text = false; break; case 3: if (strcasecmp($text, 'NIL') === 0) { $text = null; } break; } } if ($text === false && feof($stream)) { $this->_key = $this->_level = false; break; } ++$this->_key; if (is_null($level) || $level > $this->_level) { break; } if ($level === $this->_level && !is_bool($text)) { $this->_nextModify['out'][] = $text; } } while (true); $this->_current = $text; return $text; }
/** * Sends a redirect (a/k/a resent) message. * * @param Horde_Stream $message Message content. * * @throws Horde_Spam_Exception */ protected function _redirectMessage(Horde_Stream $message) { /* Split up headers and message. */ $message->rewind(); $eol = $message->getEOL(); $headers = $message->getToChar($eol . $eol); if (!strlen($headers)) { throw new Horde_Spam_Exception('Invalid message reported, header not found'); } $body = fopen('php://temp', 'r+'); stream_copy_to_stream($message->stream, $body, -1, $message->pos()); /* We need to set the Return-Path header to the sending user - see RFC * 2821 [4.4]. */ $headers = preg_replace('/return-path:.*?(\\r?\\n)/i', 'Return-Path: <' . $this->_from_addr . '>$1', $headers); try { $this->_mail->send($this->_email, array('_raw' => $headers, 'from' => $this->_from_addr), $body); } catch (Horde_Mail_Exception $e) { $this->_logger->warn($e); throw new Horde_Spam_Exception($e); } }