Fix IMAP PARSE reponse matching. This should get rid of retrival errors
[squirrelmail.git] / functions / smtp.php
index 8ad4d243c6428bf3b0138731ff05959b8619fb44..1e5395857566865e61ff9e3d1ecd1fac88b96f5a 100644 (file)
@@ -32,15 +32,15 @@ if (!$domain) {
 }
 
 /* Returns true only if this message is multipart */
-function isMultipart () {
+function isMultipart ($session) {
     global $attachments;
-    
-    if (count($attachments)>0) {
-        return true;
-    }
-    else {
-        return false;
+
+    foreach ($attachments as $info) {
+       if ($info['session'] == $session) {
+           return true;
+       }
     }
+    return false;
 }
 
 /* looks up aliases in the addressbook and expands them to
@@ -55,7 +55,7 @@ function expandAddrs ($array) {
     /* don't show errors -- kinda critical that we don't see
      * them here since the redirect won't work if we do show them
      */
-    $abook = addressbook_init(false);
+    $abook = addressbook_init(false, true);
     for ($i=0; $i < count($array); $i++) {
         $result = $abook->lookup($array[$i]);
         $ret = "";
@@ -89,7 +89,7 @@ function expandRcptAddrs ($array) {
     /* don't show errors -- kinda critical that we don't see
      * them here since the redirect won't work if we do show them
      */
-    $abook = addressbook_init(false);
+    $abook = addressbook_init(false, true);
     for ($i=0; $i < count($array); $i++) {
         $result = $abook->lookup($array[$i]);
         $ret = "";
@@ -110,14 +110,15 @@ function expandRcptAddrs ($array) {
 
 /* Attach the files that are due to be attached
  */
-function attachFiles ($fp) {
+function attachFiles ($fp, $session) {
     global $attachments, $attachment_dir, $username;
 
     $length = 0;
 
     $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
-    if (isMultipart()) {
+    if (isMultipart($session)) {
         foreach ($attachments as $info) {
+         if ($info['session'] == $session) {
             if (isset($info['type'])) {
                 $filetype = $info['type'];
             }
@@ -143,7 +144,7 @@ function attachFiles ($fp) {
             $filename = $hashed_attachment_dir . '/' . $info['localfilename'];
             $file = fopen ($filename, 'rb');
             if (substr($filetype, 0, 5) == 'text/' ||
-                $filetype == 'message/rfc822' || $filetype == 'message/disposition-notification' )  {
+                substr($filetype, 0, 8) == 'message/' ) {
                 $header .= "\r\n";
                 fputs ($fp, $header);
                 $length += strlen($header);
@@ -168,6 +169,7 @@ function attachFiles ($fp) {
                 }
             }
             fclose ($file);
+         }
         }
     }
     return $length;
@@ -175,20 +177,22 @@ function attachFiles ($fp) {
 
 /* Delete files that are uploaded for attaching
  */
-function deleteAttachments() {
-    global $attachments, $attachment_dir;
-    
+function deleteAttachments($session) {
+    global $username, $attachments, $attachment_dir;
     $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
-    if (isMultipart()) {
-        reset($attachments);
-        while (list($localname, $remotename) = each($attachments)) {
-            if (!ereg ("\\/", $localname)) {
-                $filename = $hashed_attachment_dir . '/' . $localname;
-                unlink ($filename);
-                unlink ("$filename.info");
-            }
-        }
-    }
+
+    $rem_attachments = array();
+    foreach ($attachments as $info) {
+       if ($info['session'] == $session) {
+           $attached_file = "$hashed_attachment_dir/$info[localfilename]";
+           if (file_exists($attached_file)) {
+               unlink($attached_file);
+           }
+       } else {
+           $rem_attachments[] = $info;
+       }
+    }
+    $attachments = $rem_attachments;
 }
 
 /* Return a nice MIME-boundary
@@ -231,12 +235,11 @@ function timezone () {
 }
 
 /* Print all the needed RFC822 headers */
-function write822Header ($fp, $t, $c, $b, $subject, $MDN, $more_headers) {
+function write822Header ($fp, $t, $c, $b, $subject, $more_headers, $session) {
     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;
-    global $request_mdn;    
     
     /* Storing the header to make sure the header is the same
      * everytime the header is printed.
@@ -294,24 +297,38 @@ function write822Header ($fp, $t, $c, $b, $subject, $MDN, $more_headers) {
                 $HTTP_X_FORWARDED_FOR = 'unknown';
             }
             $received_from .= " (proxying for $HTTP_X_FORWARDED_FOR)";
-        }            
-        
+        }
+
         $header  = "Received: from $received_from\r\n";
         $header .= "        (SquirrelMail authenticated user $username)\r\n";
         $header .= "        by $SERVER_NAME with HTTP;\r\n";
         $header .= "        $date\r\n";
-        
+
         /* Insert the rest of the header fields */
         $header .= "Message-ID: $message_id\r\n";
         $header .= "Date: $date\r\n";
         $header .= "Subject: $subject\r\n";
         $header .= "From: $from\r\n";
         $header .= "To: $to_list\r\n";    // Who it's TO
-        
-        if (isset($request_mdn)) {
-            $more_headers["Disposition-Notification-To"] = "$from_addr";
+
+        if (isset($more_headers["Content-Type"])) {
+            $contentType = $more_headers["Content-Type"];
+            unset($more_headers["Content-Type"]);
         }
-        
+        else {
+            if (isMultipart($session)) {
+                $contentType = "multipart/mixed;";
+            }
+            else {
+                if ($default_charset != '') {
+                    $contentType = 'text/plain; charset='.$default_charset;
+                }
+                else {
+                    $contentType = 'text/plain;';
+                }
+            }
+        }
+
         /* Insert headers from the $more_headers array */
         if(is_array($more_headers)) {
             reset($more_headers);
@@ -319,47 +336,33 @@ function write822Header ($fp, $t, $c, $b, $subject, $MDN, $more_headers) {
                 $header .= sprintf("%s: %s\r\n", $h_name, $h_val);
             }
         }
-        
+
         if ($cc_list) {
             $header .= "Cc: $cc_list\r\n"; // Who the CCs are
         }
-        
+
         if ($reply_to != '') {
             $header .= "Reply-To: $reply_to\r\n";
         }
-        
+
         if ($useSendmail) {
             if ($bcc_list) {
                 // BCCs is removed from header by sendmail
-                $header .= "Bcc: $bcc_list\r\n"; 
+                $header .= "Bcc: $bcc_list\r\n";
             }
         }
-        
+
         $header .= "X-Mailer: SquirrelMail (version $version)\r\n"; /* Identify SquirrelMail */
 
         /* Do the MIME-stuff */
         $header .= "MIME-Version: 1.0\r\n";
-        
-        if (isMultipart()) {
-            if ($MDN) {
-                $header .= "Content-Type: multipart/report;\r\n";
-                $header .= "        report-type=disposition-notification;\r\n";
-                $header .= '        boundary="';
-                $header .= mimeBoundary();
-                $header .= "\"\r\n";
-            }
-            else {
-                $header .= 'Content-Type: multipart/mixed; boundary="';
-                $header .= mimeBoundary();
-                $header .= "\"\r\n";
-            }
+
+        if (isMultipart($session)) {
+            $header .= 'Content-Type: '.$contentType.' boundary="';
+            $header .= mimeBoundary();
+            $header .= "\"\r\n";
         } else {
-            if ($default_charset != '') {
-                $header .= "Content-Type: text/plain; charset=$default_charset\r\n";
-            }
-            else {
-                $header .= "Content-Type: text/plain;\r\n";
-            }
+            $header .= 'Content-Type: '.$contentType."\r\n";
             $header .= "Content-Transfer-Encoding: 8bit\r\n";
         }
         $header .= "\r\n"; // One blank line to separate header and body
@@ -375,12 +378,12 @@ function write822Header ($fp, $t, $c, $b, $subject, $MDN, $more_headers) {
 
 /* Send the body
  */
-function writeBody ($fp, $passedBody) {
+function writeBody ($fp, $passedBody, $session) {
     global $default_charset;
     
     $attachmentlength = 0;
     
-    if (isMultipart()) {
+    if (isMultipart($session)) {
         $body = '--'.mimeBoundary()."\r\n";
         
         if ($default_charset != "") {
@@ -394,7 +397,7 @@ function writeBody ($fp, $passedBody) {
         $body .= $passedBody . "\r\n\r\n";
         fputs ($fp, $body);
         
-        $attachmentlength = attachFiles($fp);
+        $attachmentlength = attachFiles($fp, $session);
         
         if (!isset($postbody)) { 
             $postbody = ""; 
@@ -407,13 +410,13 @@ function writeBody ($fp, $passedBody) {
         $postbody = "\r\n";
         fputs ($fp, $postbody);
     }
-    
+
     return (strlen($body) + strlen($postbody) + $attachmentlength);
 }
 
 /* Send mail using the sendmail command
  */
-function sendSendmail($t, $c, $b, $subject, $body, $MDN, $more_headers) {
+function sendSendmail($t, $c, $b, $subject, $body, $more_headers, $session) {
     global $sendmail_path, $popuser, $username, $domain;
     
     /* Build envelope sender address. Make sure it doesn't contain 
@@ -432,8 +435,8 @@ function sendSendmail($t, $c, $b, $subject, $body, $MDN, $more_headers) {
         $fp = popen (escapeshellcmd("$sendmail_path -t -f$envelopefrom"), "w");
     }
     
-    $headerlength = write822Header ($fp, $t, $c, $b, $subject, $MDN, $more_headers);
-    $bodylength = writeBody($fp, $body);
+    $headerlength = write822Header ($fp, $t, $c, $b, $subject, $more_headers, $session);
+    $bodylength = writeBody($fp, $body, $session);
     
     pclose($fp);
     
@@ -451,7 +454,7 @@ function smtpReadData($smtpConnection) {
     }
 }
 
-function sendSMTP($t, $c, $b, $subject, $body, $MDN, $more_headers) {
+function sendSMTP($t, $c, $b, $subject, $body, $more_headers, $session) {
     global $username, $popuser, $domain, $version, $smtpServerAddress, 
         $smtpPort, $data_dir, $color, $use_authenticated_smtp, $identity, 
         $key, $onetimepad;
@@ -477,7 +480,9 @@ function sendSMTP($t, $c, $b, $subject, $body, $MDN, $more_headers) {
         exit;
     }
     $tmp = fgets($smtpConnection, 1024);
-    if (errorCheck($tmp, $smtpConnection)!=5) return(0);
+    if (errorCheck($tmp, $smtpConnection)!=5) {
+        return(0);
+    }
     
     $to_list = getLineOfAddrs($to);
     $cc_list = getLineOfAddrs($cc);
@@ -549,18 +554,13 @@ function sendSMTP($t, $c, $b, $subject, $body, $MDN, $more_headers) {
     }
 
     /* Send the message */
-    $headerlength = write822Header ($smtpConnection, $t, $c, $b, $subject, $MDN, $more_headers);
-    $bodylength = writeBody($smtpConnection, $body);
+    $headerlength = write822Header ($smtpConnection, $t, $c, $b, $subject, $more_headers, $session);
+    $bodylength = writeBody($smtpConnection, $body, $session);
     
     fputs($smtpConnection, ".\r\n"); /* end the DATA part */
     $tmp = fgets($smtpConnection, 1024);
     $num = errorCheck($tmp, $smtpConnection, true);
     if ($num != 250) {
-        $tmp = nl2br(htmlspecialchars($tmp));
-        displayPageHeader($color, 'None');
-        include_once('../functions/display_messages.php');
-        $msg  = "Message not sent!<br>\nReason given: $tmp";
-        plain_error_message($msg, $color);
         return(0);
     }
     
@@ -573,7 +573,7 @@ function sendSMTP($t, $c, $b, $subject, $body, $MDN, $more_headers) {
 
 
 function errorCheck($line, $smtpConnection, $verbose = false) {
-    global $color;
+    global $color, $compose_new_win;
     
     /* Read new lines on a multiline response */
     $lines = $line;
@@ -662,10 +662,15 @@ function errorCheck($line, $smtpConnection, $verbose = false) {
         $error_num = '001';
         break;
     }
-    
+
     if ($status == 0) {
         include_once('../functions/page_header.php');
-        displayPageHeader($color, 'None');
+        if ($compose_new_win == '1') {
+            compose_Header($color, 'None');
+        }
+        else {
+            displayPageHeader($color, 'None');
+        }
         include_once('../functions/display_messages.php');
         $lines = nl2br(htmlspecialchars($lines));
         $msg  = $message . "<br>\nServer replied: $lines";
@@ -675,12 +680,10 @@ function errorCheck($line, $smtpConnection, $verbose = false) {
     return $err_num;
 }
 
-function sendMessage($t, $c, $b, $subject, $body, $reply_id, $MDN, $prio = 3) {
+function sendMessage($t, $c, $b, $subject, $body, $reply_id, $MDN, $prio = 3, $session) {
     global $useSendmail, $msg_id, $is_reply, $mailbox, $onetimepad,
-           $data_dir, $username, $domain, $key, $version, $sent_folder, $imapServerAddress, $imapPort,
-           $default_use_priority,
-           $more_headers,
-           $request_mdn;
+           $data_dir, $username, $domain, $key, $version, $sent_folder, $imapServerAddress, 
+           $imapPort, $default_use_priority, $more_headers, $request_mdn, $request_dr;
 
     $more_headers = Array();
     
@@ -707,6 +710,17 @@ function sendMessage($t, $c, $b, $subject, $body, $reply_id, $MDN, $prio = 3) {
         $more_headers = array_merge($more_headers, createPriorityHeaders($prio));
     }
 
+    $requestRecipt = 0;
+    if (isset($request_dr)) {
+        $requestRecipt += 1;
+    }
+    if (isset($request_mdn)) {
+        $requestRecipt += 2;
+    }
+    if ( $requestRecipt > 0) {
+        $more_headers = array_merge($more_headers, createReceiptHeaders($requestRecipt));
+    }
+
     /* In order to remove the problem of users not able to create
      * messages with "." on a blank line, RFC821 has made provision
      * in section 4.5.2 (Transparency).
@@ -719,16 +733,21 @@ function sendMessage($t, $c, $b, $subject, $body, $reply_id, $MDN, $prio = 3) {
      * into just \n inside the compose.php file.
      */
     $body = ereg_replace("\n", "\r\n", $body);
+    
+    if ($MDN) {
+        $more_headers["Content-Type"] = "multipart/report; ".
+            "report-type=disposition-notification;";
+    }
 
     if ($useSendmail) {
-        $length = sendSendmail($t, $c, $b, $subject, $body, $MDN, $more_headers);
+        $length = sendSendmail($t, $c, $b, $subject, $body,  $more_headers, $session);
     } else {
-        $length = sendSMTP($t, $c, $b, $subject, $body, $MDN, $more_headers);
+        $length = sendSMTP($t, $c, $b, $subject, $body, $more_headers, $session);
     }
     if (sqimap_mailbox_exists ($imap_stream, $sent_folder)) {
         sqimap_append ($imap_stream, $sent_folder, $length);
-        write822Header ($imap_stream, $t, $c, $b, $subject, $MDN, $more_headers);
-        writeBody ($imap_stream, $body);
+        write822Header ($imap_stream, $t, $c, $b, $subject, $more_headers, $session);
+        writeBody ($imap_stream, $body, $session);
         sqimap_append_done ($imap_stream);
     }
     sqimap_logout($imap_stream);
@@ -736,7 +755,7 @@ function sendMessage($t, $c, $b, $subject, $body, $reply_id, $MDN, $prio = 3) {
      * only if $length != 0 (if there was no error)
      */
     if ($length) {
-        ClearAttachments();
+        ClearAttachments($session);
     }
 
     return $length;
@@ -763,4 +782,36 @@ function createPriorityHeaders($prio) {
     return  $prio_headers;
 }
 
+function createReceiptHeaders($receipt) {
+
+    GLOBAL $data_dir, $username;
+
+    $receipt_headers = Array();
+    $from_addr = getPref($data_dir, $username, 'email_address');
+    $from = getPref($data_dir, $username, 'full_name');
+
+    if ($from == '') {
+        $from = "<$from_addr>";
+    }
+    else {
+        $from = '"' . encodeHeader($from) . "\" <$from_addr>";
+    }
+
+    /* On Delivery */
+    if ( $receipt == 1
+        || $receipt == 3 ) {
+        $receipt_headers["Return-Receipt-To"] = $from;
+    }
+    /* On Read */
+    if ($receipt == 2
+        || $receipt == 3 ) {
+        /* Pegasus Mail */
+        $receipt_headers["X-Confirm-Reading-To"] = $from;
+        /* RFC 2298 */
+        $receipt_headers["Disposition-Notification-To"] = $from;
+    }
+    return $receipt_headers;
+}
+
+
 ?>