+ // send mail using PHP's mail() function
+ else {
+ // unset some headers because they will be added by the mail() function
+ $headers_enc = $message->headers($headers);
+ $headers_php = $message->_headers;
+ unset($headers_php['To'], $headers_php['Subject']);
+
+ // reset stored headers and overwrite
+ $message->_headers = array();
+ $header_str = $message->txtHeaders($headers_php);
+
+ // #1485779
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+ if (preg_match_all('/<([^@]+@[^>]+)>/', $headers_enc['To'], $m)) {
+ $headers_enc['To'] = implode(', ', $m[1]);
+ }
+ }
+
+ $msg_body = $message->get();
+
+ if (PEAR::isError($msg_body))
+ raise_error(array('code' => 600, 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Could not create message: ".$msg_body->getMessage()),
+ TRUE, FALSE);
+ else {
+ $delim = $RCMAIL->config->header_delimiter();
+ $to = $headers_enc['To'];
+ $subject = $headers_enc['Subject'];
+ $header_str = rtrim($header_str);
+
+ if ($delim != "\r\n") {
+ $header_str = str_replace("\r\n", $delim, $header_str);
+ $msg_body = str_replace("\r\n", $delim, $msg_body);
+ $to = str_replace("\r\n", $delim, $to);
+ $subject = str_replace("\r\n", $delim, $subject);
+ }
+
+ if (ini_get('safe_mode'))
+ $sent = mail($to, $subject, $msg_body, $header_str);
+ else
+ $sent = mail($to, $subject, $msg_body, $header_str, "-f$from");
+ }
+ }
+
+ if ($sent) {
+ $RCMAIL->plugins->exec_hook('message_sent', array('headers' => $headers, 'body' => $msg_body));
+
+ // remove MDN headers after sending
+ unset($headers['Return-Receipt-To'], $headers['Disposition-Notification-To']);
+
+ // get all recipients
+ if ($headers['Cc'])
+ $mailto .= $headers['Cc'];
+ if ($headers['Bcc'])
+ $mailto .= $headers['Bcc'];
+ if (preg_match_all('/<([^@]+@[^>]+)>/', $mailto, $m))
+ $mailto = implode(', ', array_unique($m[1]));
+
+ if ($CONFIG['smtp_log']) {
+ write_log('sendmail', sprintf("User %s [%s]; Message for %s; %s",
+ $RCMAIL->user->get_username(),
+ $_SERVER['REMOTE_ADDR'],
+ $mailto,
+ !empty($smtp_response) ? join('; ', $smtp_response) : ''));
+ }
+ }
+
+ if (is_resource($msg_body)) {
+ fclose($msg_body);
+ }
+
+ $message->_headers = array();
+ $message->headers($headers);
+
+ return $sent;
+}
+
+/**
+ * Send the MDN response
+ *
+ * @param mixed $message Original message object (rcube_message) or UID
+ * @param array $smtp_error SMTP error array (reference)
+ *
+ * @return boolean Send status
+ */
+function rcmail_send_mdn($message, &$smtp_error)
+{
+ global $RCMAIL, $IMAP;
+
+ if (!is_a($message, rcube_message))
+ $message = new rcube_message($message);
+
+ if ($message->headers->mdn_to && !$message->headers->mdn_sent &&
+ ($IMAP->check_permflag('MDNSENT') || $IMAP->check_permflag('*')))
+ {
+ $identity = $RCMAIL->user->get_identity();
+ $sender = format_email_recipient($identity['email'], $identity['name']);
+ $recipient = array_shift($IMAP->decode_address_list($message->headers->mdn_to));
+ $mailto = $recipient['mailto'];
+
+ $compose = new Mail_mime("\r\n");
+
+ $compose->setParam('text_encoding', 'quoted-printable');
+ $compose->setParam('html_encoding', 'quoted-printable');
+ $compose->setParam('head_encoding', 'quoted-printable');
+ $compose->setParam('head_charset', RCMAIL_CHARSET);
+ $compose->setParam('html_charset', RCMAIL_CHARSET);
+ $compose->setParam('text_charset', RCMAIL_CHARSET);
+
+ // compose headers array
+ $headers = array(
+ 'Date' => rcmail_user_date(),
+ 'From' => $sender,
+ 'To' => $message->headers->mdn_to,
+ 'Subject' => rcube_label('receiptread') . ': ' . $message->subject,
+ 'Message-ID' => rcmail_gen_message_id(),
+ 'X-Sender' => $identity['email'],
+ 'References' => trim($message->headers->references . ' ' . $message->headers->messageID),
+ );
+
+ if ($agent = $RCMAIL->config->get('useragent'))
+ $headers['User-Agent'] = $agent;
+
+ $body = rcube_label("yourmessage") . "\r\n\r\n" .
+ "\t" . rcube_label("to") . ': ' . rcube_imap::decode_mime_string($message->headers->to, $message->headers->charset) . "\r\n" .
+ "\t" . rcube_label("subject") . ': ' . $message->subject . "\r\n" .
+ "\t" . rcube_label("sent") . ': ' . format_date($message->headers->date, $RCMAIL->config->get('date_long')) . "\r\n" .
+ "\r\n" . rcube_label("receiptnote") . "\r\n";
+
+ $ua = $RCMAIL->config->get('useragent', "Roundcube Webmail (Version ".RCMAIL_VERSION.")");
+ $report = "Reporting-UA: $ua\r\n";
+
+ if ($message->headers->to)
+ $report .= "Original-Recipient: {$message->headers->to}\r\n";
+
+ $report .= "Final-Recipient: rfc822; {$identity['email']}\r\n" .
+ "Original-Message-ID: {$message->headers->messageID}\r\n" .
+ "Disposition: manual-action/MDN-sent-manually; displayed\r\n";
+
+ $compose->headers($headers);
+ $compose->setContentType('multipart/report', array('report-type'=> 'disposition-notification'));
+ $compose->setTXTBody(rc_wordwrap($body, 75, "\r\n"));
+ $compose->addAttachment($report, 'message/disposition-notification', 'MDNPart2.txt', false, '7bit', 'inline');
+
+ $sent = rcmail_deliver_message($compose, $identity['email'], $mailto, $smtp_error, $body_file);
+
+ if ($sent)
+ {
+ $IMAP->set_flag($message->uid, 'MDNSENT');
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Returns unique Message-ID
+function rcmail_gen_message_id()
+{
+ global $RCMAIL;
+
+ $local_part = md5(uniqid('rcmail'.mt_rand(),true));
+ $domain_part = $RCMAIL->user->get_username('domain');
+
+ // Try to find FQDN, some spamfilters doesn't like 'localhost' (#1486924)
+ if (!preg_match('/\.[a-z]+$/i', $domain_part)) {
+ if (($host = preg_replace('/:[0-9]+$/', '', $_SERVER['HTTP_HOST']))
+ && preg_match('/\.[a-z]+$/i', $host)) {
+ $domain_part = $host;
+ }
+ else if (($host = preg_replace('/:[0-9]+$/', '', $_SERVER['SERVER_NAME']))
+ && preg_match('/\.[a-z]+$/i', $host)) {
+ $domain_part = $host;
+ }
+ }
+
+ return sprintf('<%s@%s>', $local_part, $domain_part);
+}
+
+// Returns RFC2822 formatted current date in user's timezone
+function rcmail_user_date()
+{
+ global $CONFIG;
+
+ // get user's timezone
+ if ($CONFIG['timezone'] === 'auto') {
+ $tz = isset($_SESSION['timezone']) ? $_SESSION['timezone'] : date('Z')/3600;
+ }
+ else {
+ $tz = $CONFIG['timezone'];
+ if ($CONFIG['dst_active'])
+ $tz++;
+ }
+
+ $date = time() + $tz * 60 * 60;
+ $date = gmdate('r', $date);
+ $tz = sprintf('%+05d', intval($tz) * 100 + ($tz - intval($tz)) * 60);
+ $date = preg_replace('/[+-][0-9]{4}$/', $tz, $date);
+
+ return $date;
+}
+
+// Fixes some content-type names
+function rcmail_fix_mimetype($name)
+{
+ // Some versions of Outlook create garbage Content-Type:
+ // application/pdf.A520491B_3BF7_494D_8855_7FAC2C6C0608
+ if (preg_match('/^application\/pdf.+/', $name))
+ $name = 'application/pdf';
+
+ return $name;
+}
+
+function rcmail_search_filter($attrib)
+{
+ global $OUTPUT, $CONFIG;
+
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmlistfilter';
+
+ $attrib['onchange'] = JS_OBJECT_NAME.'.filter_mailbox(this.value)';
+
+ /*
+ RFC3501 (6.4.4): 'ALL', 'RECENT',
+ 'ANSWERED', 'DELETED', 'FLAGGED', 'SEEN',
+ 'UNANSWERED', 'UNDELETED', 'UNFLAGGED', 'UNSEEN',
+ 'NEW', // = (RECENT UNSEEN)
+ 'OLD' // = NOT RECENT
+ */
+
+ $select_filter = new html_select($attrib);
+ $select_filter->add(rcube_label('all'), 'ALL');
+ $select_filter->add(rcube_label('unread'), 'UNSEEN');
+ $select_filter->add(rcube_label('flagged'), 'FLAGGED');
+ $select_filter->add(rcube_label('unanswered'), 'UNANSWERED');
+ if (!$CONFIG['skip_deleted'])
+ $select_filter->add(rcube_label('deleted'), 'DELETED');
+
+ $out = $select_filter->show($_SESSION['search_filter']);
+
+ $OUTPUT->add_gui_object('search_filter', $attrib['id']);