parsing $message to magicHTML for better handling message/rfc822 attachments
[squirrelmail.git] / functions / smtp.php
index 122ab7e49503529623e0f03b2066f944799098c2..d10f6854a45a541b0b6d7b49a86bbe59c395be85 100644 (file)
@@ -31,20 +31,6 @@ if (!$domain) {
     $domain = getenv('HOSTNAME');
 }
 
-/**
- * Return which separator we should be using.
- * \r\n for SMTP delivery, just \n for Sendmail.
- */
-function sqm_nrn(){
-    global $useSendmail;
-    if ($useSendmail){
-        return "\n";
-    } else {
-        return "\r\n";
-    }
-}
-
-
 /* Returns true only if this message is multipart */
 function isMultipart ($session) {
     global $attachments;
@@ -124,11 +110,10 @@ function expandRcptAddrs ($array) {
 
 /* Attach the files that are due to be attached
  */
-function attachFiles ($fp, $session) {
+function attachFiles ($fp, $session, $rn="\r\n") {
     global $attachments, $attachment_dir, $username;
 
     $length = 0;
-    $rn = sqm_nrn();
 
     $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
     if (isMultipart($session)) {
@@ -149,7 +134,7 @@ function attachFiles ($fp, $session) {
                     $header .= "Content-Disposition: attachment; filename=\""
                         . $info['remotefilename'] . "\"$rn";
                 } else {
-                    $header .= "Content-Type: $filetype;$rn";
+                    $header .= "Content-Type: $filetype$rn";
                 }
 
                 
@@ -162,8 +147,10 @@ function attachFiles ($fp, $session) {
                 $file = fopen ($filename, 'rb');
                 if (substr($filetype, 0, 5) == 'text/' ||
                     substr($filetype, 0, 8) == 'message/' ) {
-                    $header .= "$rn";
-                    fputs ($fp, $header);
+                    $header .= $rn;
+                                       if ($fp) {
+                                           fputs ($fp, $header);
+                                       }
                     $length += strlen($header);
                     while ($tmp = fgets($file, 4096)) {
                         $tmp = str_replace("\r\n", "\n", $tmp);
@@ -175,21 +162,23 @@ function attachFiles ($fp, $session) {
                          * Check if the last line has newline ($rn) in it
                          * and append if it doesn't.
                          */
-                        if (feof($fp) && !strstr($tmp, "$rn")){
-                            $tmp .= "$rn";
+                        if ($fp && feof($fp) && !strstr($tmp, "$rn")){
+                            $tmp .= $rn;
+                        }
+                        if ($fp) {
+                            fputs($fp, $tmp);
                         }
-                        fputs($fp, $tmp);
                         $length += strlen($tmp);
                     }
                 } else {
                     $header .= "Content-Transfer-Encoding: base64" 
                         . "$rn" . "$rn";
-                    fputs ($fp, $header);
+                    if ($fp) fputs ($fp, $header);
                     $length += strlen($header);
                     while ($tmp = fread($file, 570)) {
                         $encoded = chunk_split(base64_encode($tmp));
                         $length += strlen($encoded);
-                        fputs ($fp, $encoded);
+                        if ($fp) fputs ($fp, $encoded);
                     }
                 }
                 fclose ($file);
@@ -260,37 +249,30 @@ function timezone () {
 }
 
 /* Print all the needed RFC822 headers */
-function write822Header ($fp, $t, $c, $b, $subject, $more_headers, $session) {
+function write822Header ($fp, $t, $c, $b, $subject, $more_headers, $session, $rn="\r\n") {
     global $REMOTE_ADDR, $SERVER_NAME, $REMOTE_PORT;
     global $data_dir, $username, $popuser, $domain, $version, $useSendmail;
     global $default_charset, $HTTP_VIA, $HTTP_X_FORWARDED_FOR;
     global $REMOTE_HOST, $identity;
-    /**
-     * Get which delimiter we are going to use.
-     */
-    $rn = sqm_nrn();
+
     /* Storing the header to make sure the header is the same
      * everytime the header is printed.
      */
-    static $header, $headerlength;
+    static $header, $headerlength, $headerrn;
     
     if ($header == '') {
+               $headerrn = $rn;
         $to = expandAddrs(parseAddrs($t));
         $cc = expandAddrs(parseAddrs($c));
         $bcc = expandAddrs(parseAddrs($b));
         if (isset($identity) && $identity != 'default') {
             $reply_to = getPref($data_dir, $username, 'reply_to' . $identity);
             $from = getPref($data_dir, $username, 'full_name' . $identity);
-            $from_addr = getPref($data_dir, $username, 
-                                 'email_address' . $identity);
+            $from_addr = getFrom();
         } else {
             $reply_to = getPref($data_dir, $username, 'reply_to');
             $from = getPref($data_dir, $username, 'full_name');
-            $from_addr = getPref($data_dir, $username, 'email_address');
-        }
-        
-        if ($from_addr == '') {
-            $from_addr = $popuser.'@'.$domain;
+            $from_addr = getFrom();
         }
         
         $to_list = getLineOfAddrs($to);
@@ -362,6 +344,9 @@ function write822Header ($fp, $t, $c, $b, $subject, $more_headers, $session) {
         if(is_array($more_headers)) {
             reset($more_headers);
             while(list($h_name, $h_val) = each($more_headers)) {
+               if ($h_name == 'References') {
+                   $h_val = str_replace(' ', "$rn        ", $h_val);
+               }    
                 $header .= sprintf("%s: %s%s", $h_name, $h_val, $rn);
             }
         }
@@ -399,21 +384,23 @@ function write822Header ($fp, $t, $c, $b, $subject, $more_headers, $session) {
         
         $headerlength = strlen($header);
     }     
+
+       if ($headerrn != $rn) {
+               $header = str_replace($headerrn, $rn, $header);
+        $headerlength = strlen($header);
+               $headerrn = $rn;
+       }
     
     /* Write the header */
-    fputs ($fp, $header);
+    if ($fp) fputs ($fp, $header);
     
     return $headerlength;
 }
 
 /* Send the body
  */
-function writeBody ($fp, $passedBody, $session) {
+function writeBody ($fp, $passedBody, $session, $rn="\r\n") {
     global $default_charset;
-    /**
-     * Get delimiter.
-     */
-    $rn = sqm_nrn();
 
     $attachmentlength = 0;
     
@@ -429,20 +416,20 @@ function writeBody ($fp, $passedBody, $session) {
         
         $body .= "Content-Transfer-Encoding: 8bit" . $rn . $rn;
         $body .= $passedBody . $rn . $rn;
-        fputs ($fp, $body);
+        if ($fp) fputs ($fp, $body);
         
-        $attachmentlength = attachFiles($fp, $session);
+        $attachmentlength = attachFiles($fp, $session, $rn);
         
         if (!isset($postbody)) { 
             $postbody = ""; 
         }
         $postbody .= $rn . "--" . mimeBoundary() . "--" . $rn . $rn;
-        fputs ($fp, $postbody);
+        if ($fp) fputs ($fp, $postbody);
     } else {
         $body = $passedBody . $rn;
-        fputs ($fp, $body);
+        if ($fp) fputs ($fp, $body);
         $postbody = $rn;
-        fputs ($fp, $postbody);
+        if ($fp) fputs ($fp, $postbody);
     }
 
     return (strlen($body) + strlen($postbody) + $attachmentlength);
@@ -457,7 +444,7 @@ function sendSendmail($t, $c, $b, $subject, $body, $more_headers, $session) {
      * spaces or other "weird" chars that would allow a user to
      * exploit the shell/pipe it is used in.
      */
-    $envelopefrom = "$popuser@$domain";
+    $envelopefrom = getFrom();
     $envelopefrom = ereg_replace("[[:blank:]]",'', $envelopefrom);
     $envelopefrom = ereg_replace("[[:space:]]",'', $envelopefrom);
     $envelopefrom = ereg_replace("[[:cntrl:]]",'', $envelopefrom);
@@ -473,11 +460,11 @@ function sendSendmail($t, $c, $b, $subject, $body, $more_headers, $session) {
     }
     
     $headerlength = write822Header ($fp, $t, $c, $b, $subject, 
-                                    $more_headers, $session);
-    $bodylength = writeBody($fp, $body, $session);
+                                    $more_headers, $session, "\n");
+    $bodylength = writeBody($fp, $body, $session, "\n");
     
     pclose($fp);
-    
+
     return ($headerlength + $bodylength);
 }
 
@@ -759,10 +746,7 @@ function errorCheck($line, $smtpConnection, $verbose = false) {
 /* create new reference header per rfc2822 */
 
 function calculate_references($refs, $inreplyto, $old_reply_to) {
-    /**
-     * Get the delimiter.
-     */
-    $rn = sqm_nrn();
+
     $refer = "";
     for ($i=1;$i<count($refs[0]);$i++) {
         if (!empty($refs[0][$i])) {
@@ -787,7 +771,6 @@ function calculate_references($refs, $inreplyto, $old_reply_to) {
         }                        
     }
     trim($refer);
-    $refer = str_replace(' ', "$rn        ", $refer);
     return $refer;
 }
 
@@ -798,10 +781,6 @@ function sendMessage($t, $c, $b, $subject, $body, $reply_id, $MDN,
         $imapServerAddress, $imapPort, $default_use_priority, $more_headers, 
         $request_mdn, $request_dr;
 
-    /**
-     * Get the delimiter.
-     */
-    $rn = sqm_nrn();
     $more_headers = Array();
     
     do_hook('smtp_send');
@@ -818,15 +797,31 @@ function sendMessage($t, $c, $b, $subject, $body, $reply_id, $MDN,
          * The References header should really be the old Referenced header
          * with the message ID appended, and now it is (jmunro)
          */
-        $hdr = sqimap_get_small_header ($imap_stream, $reply_id, false);
-        if(strlen($hdr->message_id) > 2) {
+       $sid = sqimap_session_id(); 
+       $query = "$sid FETCH $reply_id (BODY.PEEK[HEADER.FIELDS (Message-Id In-Reply-To)])\r\n";
+       fputs ($imap_stream, $query);
+       $read = sqimap_read_data($imap_stream, $sid, true, $response, $message);
+       $message_id = '';
+       $in_reply_to = '';
+
+       foreach ($read as $r) {
+               if (preg_match("/^message-id:(.*)/iA", $r, $regs)) {
+                   $message_id = trim($regs[1]);
+               }
+               if (preg_match("/^in-reply-to:(.*)/iA", $r, $regs)) {
+                   $in_reply_to = trim($regs[1]);
+               }
+       }
+
+        if(strlen($message_id) > 2) {
             $refs = get_reference_header ($imap_stream, $reply_id);
-            $inreplyto = $hdr->message_id;
-            $old_reply_to = $hdr->inrepto;
+            $inreplyto = $message_id;
+            $old_reply_to = $in_reply_to;
             $refer = calculate_references ($refs, $inreplyto, $old_reply_to);
             $more_headers['In-Reply-To'] = $inreplyto;
             $more_headers['References']  = $refer;
         }
+
     }
     if ($default_use_priority) {
         $more_headers = array_merge($more_headers, createPriorityHeaders($prio));
@@ -855,9 +850,6 @@ function sendMessage($t, $c, $b, $subject, $body, $reply_id, $MDN,
      * into just \n inside the compose.php file.
      * But only if delimiter is, in fact, \r\n.
      */
-    if ($rn == "\r\n"){
-        $body = ereg_replace("\n", "\r\n", $body);
-    }
     
     if ($MDN) {
         $more_headers["Content-Type"] = "multipart/report; ".
@@ -867,11 +859,17 @@ function sendMessage($t, $c, $b, $subject, $body, $reply_id, $MDN,
     if ($useSendmail) {
         $length = sendSendmail($t, $c, $b, $subject, $body, $more_headers, 
                                $session);
+        $body = ereg_replace("\n", "\r\n", $body);
     } else {
+        $body = ereg_replace("\n", "\r\n", $body);
         $length = sendSMTP($t, $c, $b, $subject, $body, $more_headers, 
                            $session);
     }
     if (sqimap_mailbox_exists ($imap_stream, $sent_folder)) {
+               $headerlength = write822Header (FALSE, $t, $c, $b, $subject, $more_headers, $session, "\r\n");
+               $bodylength = writeBody(FALSE, $body, $session, "\r\n");
+               $length = $headerlength + $bodylength;
+
         sqimap_append ($imap_stream, $sent_folder, $length);
         write822Header ($imap_stream, $t, $c, $b, $subject, $more_headers, 
                         $session);
@@ -912,11 +910,19 @@ function createPriorityHeaders($prio) {
 
 function createReceiptHeaders($receipt) {
 
-    GLOBAL $data_dir, $username;
+    GLOBAL $data_dir, $username, $identity, $popuser, $domain;
 
     $receipt_headers = Array();
-    $from_addr = getPref($data_dir, $username, 'email_address');
-    $from = getPref($data_dir, $username, 'full_name');
+    if (isset($identity) && $identity != 'default') {
+        $from = getPref($data_dir, $username, 'full_name' . $identity);
+        $from_addr = getPref($data_dir, $username, 'email_address' . $identity);
+    } else {
+        $from = getPref($data_dir, $username, 'full_name');
+        $from_addr = getPref($data_dir, $username, 'email_address');
+    }
+    if ($from_addr == '') {
+        $from_addr = $popuser.'@'.$domain;
+    }
 
     if ($from == '') {
         $from = "<$from_addr>";
@@ -941,5 +947,24 @@ function createReceiptHeaders($receipt) {
     return $receipt_headers;
 }
 
+/* Figure out what the 'From:' address is
+ */
+
+function getFrom() {
+    global $username, $popuser, $domain, $data_dir, $identity;
+    if (isset($identity) && $identity != 'default') {
+        $from_addr = getPref($data_dir, $username, 
+                             'email_address' . $identity);
+    }
+    else {
+        $from_addr = getPref($data_dir, $username, 'email_address');
+    }
+    
+    if (!$from_addr) {
+        $from_addr = "$popuser@$domain";
+    }
+    return $from_addr;
+}
+
 
 ?>