X-Git-Url: https://vcs.fsf.org/?p=squirrelmail.git;a=blobdiff_plain;f=class%2Fdeliver%2FDeliver.class.php;h=cbf12187c752d51d330cb57a63666bad004d3475;hp=8188bacaf466684807be053b1a62a97ba4fe0d93;hb=b67d61ee36dc1cc591fcb6c84e344ec9e10f7ea4;hpb=4b5049de2fa934c45599d6e4c74bf2bbee10d34d diff --git a/class/deliver/Deliver.class.php b/class/deliver/Deliver.class.php index 8188baca..cbf12187 100644 --- a/class/deliver/Deliver.class.php +++ b/class/deliver/Deliver.class.php @@ -28,15 +28,47 @@ */ class Deliver { + /** + * Most recently calculated Message-ID + * External code should NEVER access this directly! + * @var string + */ + var $message_id; + /** * function mail - send the message parts to the SMTP stream * - * @param Message $message Message class to send - * @param resource $stream file handle to the SMTP stream + * @param Message $message Message object to send + * @param resource $stream Handle to the SMTP stream + * (when FALSE, nothing will be + * written to the stream; this can + * be used to determine the actual + * number of bytes that will be + * written to the stream) + * @param string $reply_id Identifies message being replied to + * (OPTIONAL; caller should ONLY specify + * a value for this when the message + * being sent is a reply) + * @param string $reply_ent_id Identifies message being replied to + * in the case it was an embedded/attached + * message inside another (OPTIONAL; caller + * should ONLY specify a value for this + * when the message being sent is a reply) + * @param mixed $extra Any implementation-specific variables + * can be passed in here and used in + * an overloaded version of this method + * if needed. + * + * @return array An array containing at least these elements in this order: + * - The number of bytes written (or that would have been + * written) to the output stream + * - The message ID (WARNING: if $stream is FALSE, this + * may not be supplied, or may not be accurate) * - * @return integer $raw_length */ - function mail($message, $stream=false) { + function mail($message, $stream=false, $reply_id=0, $reply_ent_id=0, + $extra=NULL) { + $rfc822_header = $message->rfc822_header; if (count($message->entities)) { $boundary = $this->mimeBoundary(); @@ -45,16 +77,80 @@ class Deliver { $boundary=''; } $raw_length = 0; + + + // calculate reply header if needed + // + if ($reply_id) { + global $imapConnection, $username, $imapServerAddress, + $imapPort, $mailbox; + + if (!is_resource($imapConnection)) + $imapConnection = sqimap_login($username, FALSE, + $imapServerAddress, $imapPort, 0); + + sqimap_mailbox_select($imapConnection, $mailbox); + $reply_message = sqimap_get_message($imapConnection, $reply_id, $mailbox); + + if ($reply_ent_id) { + /* redefine the messsage in case of message/rfc822 */ + $reply_message = $message->getEntity($reply_ent_id); + /* message is an entity which contains the envelope and type0=message + * and type1=rfc822. The actual entities are childs from + * $reply_message->entities[0]. That's where the encoding and is located + */ + + $orig_header = $reply_message->rfc822_header; /* here is the envelope located */ + + } else { + $orig_header = $reply_message->rfc822_header; + } + $message->reply_rfc822_header = $orig_header; + } + + $reply_rfc822_header = (isset($message->reply_rfc822_header) ? $message->reply_rfc822_header : ''); $header = $this->prepareRFC822_Header($rfc822_header, $reply_rfc822_header, $raw_length); + $this->send_mail($message, $header, $boundary, $stream, $raw_length, $extra); + + return array($raw_length, $this->message_id); + } + + /** + * function send_mail - send the message parts to the IMAP stream + * + * @param Message $message Message object to send + * @param string $header Headers ready to send + * @param string $boundary Message parts boundary + * @param resource $stream Handle to the SMTP stream + * (when FALSE, nothing will be + * written to the stream; this can + * be used to determine the actual + * number of bytes that will be + * written to the stream) + * @param int &$raw_length The number of bytes written (or that + * would have been written) to the + * output stream - NOTE that this is + * passed by reference + * @param mixed $extra Any implementation-specific variables + * can be passed in here and used in + * an overloaded version of this method + * if needed. + * + * @return void + * + */ + function send_mail($message, $header, $boundary, $stream=false, + &$raw_length, $extra=NULL) { + + if ($stream) { $this->preWriteToStream($header); $this->writeToStream($stream, $header); } $this->writeBody($message, $stream, $raw_length, $boundary); - return $raw_length; } /** @@ -65,6 +161,11 @@ class Deliver { * * @param Message $message Message object to transform * @param resource $stream SMTP output stream + * (when FALSE, nothing will be + * written to the stream; this can + * be used to determine the actual + * number of bytes that will be + * written to the stream) * @param integer &$length_raw raw length of the message (part) * as returned by mail fn * @param string $boundary custom boundary to call, usually for subparts @@ -123,6 +224,11 @@ class Deliver { * * @param Message $message Message object to transform * @param resource $stream SMTP output stream + * (when FALSE, nothing will be + * written to the stream; this can + * be used to determine the actual + * number of bytes that will be + * written to the stream) * @param integer &$length length of the message part * as returned by mail fn * @@ -151,8 +257,10 @@ class Deliver { } $last = $body_part; } elseif ($message->att_local_name) { + global $username, $attachment_dir; + $hashed_attachment_dir = getHashedDir($username, $attachment_dir); $filename = $message->att_local_name; - $file = fopen ($filename, 'rb'); + $file = fopen ($hashed_attachment_dir . '/' . $filename, 'rb'); while ($body_part = fgets($file, 4096)) { // remove NUL characters $body_part = str_replace("\0",'',$body_part); @@ -176,8 +284,10 @@ class Deliver { $this->writeToStream($stream, $body_part); } } elseif ($message->att_local_name) { + global $username, $attachment_dir; + $hashed_attachment_dir = getHashedDir($username, $attachment_dir); $filename = $message->att_local_name; - $file = fopen ($filename, 'rb'); + $file = fopen ($hashed_attachment_dir . '/' . $filename, 'rb'); while ($tmp = fread($file, 570)) { $body_part = chunk_split(base64_encode($tmp)); // Up to 4.3.10 chunk_split always appends a newline, @@ -378,7 +488,7 @@ class Deliver { * @return string $header */ function prepareRFC822_Header($rfc822_header, $reply_rfc822_header, &$raw_length) { - global $domain, $version, $username, $encode_header_key, + global $domain, $username, $encode_header_key, $edit_identity, $hide_auth_header; /* if server var SERVER_NAME not available, use $domain */ @@ -397,7 +507,8 @@ class Deliver { /* This creates an RFC 822 date */ $date = date('D, j M Y H:i:s ', time()) . $this->timezone(); /* Create a message-id */ - $message_id = '<' . $REMOTE_PORT . '.'; + $message_id = '<' . (!empty($REMOTE_PORT) ? $REMOTE_PORT . '.' : ''); +//FIXME: if $REMOTE_ADDR is missing, should we skip this if/else block? or perhaps try to generate it with some different kind of info? if (isset($encode_header_key) && trim($encode_header_key)!='') { // use encrypted form of remote address $message_id.= OneTimePadEncrypt($this->ip2hex($REMOTE_ADDR),base64_encode($encode_header_key)); @@ -405,6 +516,8 @@ class Deliver { $message_id.= $REMOTE_ADDR; } $message_id .= '.' . time() . '.squirrel@' . $SERVER_NAME .'>'; + $this->message_id = $message_id; + /* Make an RFC822 Received: line */ if (isset($REMOTE_HOST)) { $received_from = "$REMOTE_HOST ([$REMOTE_ADDR])"; @@ -497,7 +610,7 @@ class Deliver { } } /* Identify SquirrelMail */ - $header[] = 'User-Agent: SquirrelMail/' . $version . $rn; + $header[] = 'User-Agent: SquirrelMail/' . SM_VERSION . $rn; /* Do the MIME-stuff */ $header[] = 'MIME-Version: 1.0' . $rn; $contenttype = 'Content-Type: '. $rfc822_header->content_type->type0 .'/'. @@ -555,7 +668,9 @@ class Deliver { $aRefs = explode(' ',$sRefs); $sLine = 'References:'; foreach ($aRefs as $sReference) { - if (strlen($sLine)+strlen($sReference) >76) { + if ( trim($sReference) == '' ) { + /* Don't add spaces. */ + } elseif (strlen($sLine)+strlen($sReference) >76) { $hdr_s .= $sLine; $sLine = $rn . ' ' . $sReference; } else {