From cb2bc809ef29f349d38c89e202d821e67bb4c947 Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Tue, 21 Sep 2010 14:47:55 -0400
Subject: [PATCH] Fix db_mode check in insert_id()

---
 program/steps/mail/sendmail.inc |  211 +++++++++++++++++++++++++++++++++-------------------
 1 files changed, 134 insertions(+), 77 deletions(-)

diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index 13c162d..3902b9a 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -5,7 +5,7 @@
  | program/steps/mail/sendmail.inc                                       |
  |                                                                       |
  | This file is part of the RoundCube Webmail client                     |
- | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
+ | Copyright (C) 2005-2010, RoundCube Dev. - Switzerland                 |
  | Licensed under the GNU GPL                                            |
  |                                                                       |
  | PURPOSE:                                                              |
@@ -29,11 +29,11 @@
 /****** checks ********/
 
 if (!isset($_SESSION['compose']['id'])) {
-  raise_error(array('code' => 500, 'type' => 'smtp',
+  raise_error(array('code' => 500, 'type' => 'php',
     'file' => __FILE__, 'line' => __LINE__,
     'message' => "Invalid compose ID"), true, false);
 
-  $OUTPUT->show_message("An internal error occured. Please try again.", 'error');
+  $OUTPUT->show_message('internalerror', 'error');
   $OUTPUT->send('iframe');
 }
 
@@ -95,18 +95,14 @@
 
 /**
  * go from this:
- * <img src=".../tiny_mce/plugins/emotions/images/smiley-cool.gif" border="0" alt="Cool" title="Cool" />
+ * <img src="http[s]://.../tiny_mce/plugins/emotions/images/smiley-cool.gif" border="0" alt="Cool" title="Cool" />
  *
  * to this:
  *
- * <IMG src="cid:smiley-cool.gif"/>
+ * <img src="/path/on/server/.../tiny_mce/plugins/emotions/images/smiley-cool.gif" border="0" alt="Cool" title="Cool" />
  * ...
- * ------part...
- * Content-Type: image/gif
- * Content-Transfer-Encoding: base64
- * Content-ID: <smiley-cool.gif>
  */
-function rcmail_attach_emoticons(&$mime_message)
+function rcmail_fix_emoticon_paths(&$mime_message)
 {
   global $CONFIG;
 
@@ -149,10 +145,10 @@
   return $body;
 }
 
-// parse email address input
-function rcmail_email_input_format($mailto)
+// parse email address input (and count addresses)
+function rcmail_email_input_format($mailto, $count=false)
 {
-  global $EMAIL_FORMAT_ERROR;
+  global $EMAIL_FORMAT_ERROR, $RECIPIENT_COUNT;
 
   $regexp = array('/[,;]\s*[\r\n]+/', '/[\r\n]+/', '/[,;]\s*$/m', '/;/', '/(\S{1})(<\S+@\S+>)/U');
   $replace = array(', ', ', ', '', ',', '\\1 \\2');
@@ -197,6 +193,10 @@
     }
   }
 
+  if ($count) {
+    $RECIPIENT_COUNT += count($result);
+  }
+
   return implode(', ', $result);
 }
 
@@ -205,17 +205,18 @@
 if (strlen($_POST['_draft_saveid']) > 3)
   $olddraftmessageid = get_input_value('_draft_saveid', RCUBE_INPUT_POST);
 
-$message_id = sprintf('<%s@%s>', md5(uniqid('rcmail'.mt_rand(),true)), $RCMAIL->config->mail_domain($_SESSION['imap_host']));
+$message_id = rcmail_gen_message_id();
 
 // set default charset
 $input_charset = $OUTPUT->get_charset();
 $message_charset = isset($_POST['_charset']) ? $_POST['_charset'] : $input_charset;
 
 $EMAIL_FORMAT_ERROR = NULL;
+$RECIPIENT_COUNT = 0;
 
-$mailto = rcmail_email_input_format(get_input_value('_to', RCUBE_INPUT_POST, TRUE, $message_charset));
-$mailcc = rcmail_email_input_format(get_input_value('_cc', RCUBE_INPUT_POST, TRUE, $message_charset));
-$mailbcc = rcmail_email_input_format(get_input_value('_bcc', RCUBE_INPUT_POST, TRUE, $message_charset));
+$mailto = rcmail_email_input_format(get_input_value('_to', RCUBE_INPUT_POST, TRUE, $message_charset), true);
+$mailcc = rcmail_email_input_format(get_input_value('_cc', RCUBE_INPUT_POST, TRUE, $message_charset), true);
+$mailbcc = rcmail_email_input_format(get_input_value('_bcc', RCUBE_INPUT_POST, TRUE, $message_charset), true);
 
 if ($EMAIL_FORMAT_ERROR) {
   $OUTPUT->show_message('emailformaterror', 'error', array('email' => $EMAIL_FORMAT_ERROR)); 
@@ -248,7 +249,7 @@
 // if configured, the Received headers goes to top, for good measure
 if ($CONFIG['http_received_header'])
 {
-  $nldlm = $RCMAIL->config->header_delimiter() . "\t";
+  $nldlm = "\r\n\t";
   // FROM/VIA
   $http_header = 'from ';
   if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
@@ -260,8 +261,8 @@
         $http_header .= ' ('. rcmail_encrypt_header($host) . ')';
     } else {
       $http_header .= (($host != $hostname) ? $hostname : '[' . $host . ']');
-      $http_header .= ' ('. ($host == $hostname ? '' : $hostname . ' ') .
-        '[' . $host .'])';
+      if ($host != $hostname)
+        $http_header .= ' (['. $host .'])';
     }
     $http_header .= $nldlm . ' via ';
   }
@@ -273,20 +274,20 @@
       $http_header .= ' ('. rcmail_encrypt_header($host) . ')';
   } else {
     $http_header .= (($host != $hostname) ? $hostname : '[' . $host . ']');
-    $http_header .= ' ('. ($host == $hostname ? '' : $hostname . ' ') .
-      '[' . $host .'])';
+    if ($host != $hostname)
+      $http_header .= ' (['. $host .'])';
   }
   // BY
   $http_header .= $nldlm . 'by ' . $_SERVER['HTTP_HOST'];
   // WITH
-  $http_header .= $nldlm . 'with ' . $_SERVER['SERVER_PROTOCOL'] .
-      ' ('.$_SERVER['REQUEST_METHOD'] . '); ' . date('r');
+  $http_header .= $nldlm . 'with HTTP (' . $_SERVER['SERVER_PROTOCOL'] .
+      ' '.$_SERVER['REQUEST_METHOD'] . '); ' . date('r');
   $http_header = wordwrap($http_header, 69, $nldlm);
 
   $headers['Received'] = $http_header;
 }
 
-$headers['Date'] = date('r');
+$headers['Date'] = rcmail_user_date();
 $headers['From'] = rcube_charset_convert($identity_arr['string'], RCMAIL_CHARSET, $message_charset);
 $headers['To'] = $mailto;
 
@@ -297,8 +298,17 @@
 if (!empty($mailbcc))
   $headers['Bcc'] = $mailbcc;
   
-if (!empty($identity_arr['bcc']))
+if (!empty($identity_arr['bcc'])) {
   $headers['Bcc'] = ($headers['Bcc'] ? $headers['Bcc'].', ' : '') . $identity_arr['bcc'];
+  $RECIPIENT_COUNT ++;
+}
+
+if (($max_recipients = (int) $RCMAIL->config->get('max_recipients')) > 0) {
+  if ($RECIPIENT_COUNT > $max_recipients) {
+    $OUTPUT->show_message('toomanyrecipients', 'error', array('max' => $max_recipients));
+    $OUTPUT->send('iframe');
+  }
+}
 
 // add subject
 $headers['Subject'] = trim(get_input_value('_subject', RCUBE_INPUT_POST, TRUE, $message_charset));
@@ -313,6 +323,12 @@
 
 if (!empty($_SESSION['compose']['reply_msgid']))
   $headers['In-Reply-To'] = $_SESSION['compose']['reply_msgid'];
+  
+// remember reply/forward UIDs in special headers
+if (!empty($_SESSION['compose']['reply_uid']) && $savedraft)
+  $headers['X-Draft-Info'] = array('type' => 'reply', 'uid' => $_SESSION['compose']['reply_uid']);
+else if (!empty($_SESSION['compose']['forward_uid']) && $savedraft)
+  $headers['X-Draft-Info'] = array('type' => 'forward', 'uid' => $_SESSION['compose']['forward_uid']);
 
 if (!empty($_SESSION['compose']['references']))
   $headers['References'] = $_SESSION['compose']['references'];
@@ -335,35 +351,63 @@
 $headers['Message-ID'] = $message_id;
 $headers['X-Sender'] = $from;
 
+if (is_array($headers['X-Draft-Info']))
+  $headers['X-Draft-Info'] = rcmail_draftinfo_encode($headers['X-Draft-Info'] + array('folder' => $_SESSION['compose']['mailbox']));
+
 if (!empty($CONFIG['useragent']))
   $headers['User-Agent'] = $CONFIG['useragent'];
 
-$isHtmlVal = strtolower(get_input_value('_is_html', RCUBE_INPUT_POST));
-$isHtml = ($isHtmlVal == "1");
+// exec hook for header checking and manipulation
+$data = $RCMAIL->plugins->exec_hook('message_outgoing_headers', array('headers' => $headers));
+
+// sending aborted by plugin
+if ($data['abort'] && !$savedraft) {
+  $OUTPUT->show_message($data['message'] ? $data['message'] : 'sendingfailed');
+  $OUTPUT->send('iframe');
+}
+else
+  $headers = $data['headers'];
+
+
+$isHtml = (bool) get_input_value('_is_html', RCUBE_INPUT_POST);
 
 // fetch message body
 $message_body = get_input_value('_message', RCUBE_INPUT_POST, TRUE, $message_charset);
 
 if (!$savedraft) {
-  // remove signature's div ID
-  if ($isHtml)
+  if ($isHtml) {
+    // remove signature's div ID
     $message_body = preg_replace('/\s*id="_rc_sig"/', '', $message_body);
 
+    // add inline css for blockquotes
+    $bstyle = 'padding-left:5px; border-left:#1010ff 2px solid; margin-left:5px; width:100%';
+    $message_body = preg_replace('/<blockquote>/',
+	'<blockquote type="cite" style="'.$bstyle.'">', $message_body);
+  }
+
   // generic footer for all messages
-  if (!empty($CONFIG['generic_message_footer'])) {
+  if ($isHtml && !empty($CONFIG['generic_message_footer_html'])) {
+      $footer = file_get_contents(realpath($CONFIG['generic_message_footer_html']));
+      $footer = rcube_charset_convert($footer, RCMAIL_CHARSET, $message_charset);
+  }
+  else if (!empty($CONFIG['generic_message_footer'])) {
     $footer = file_get_contents(realpath($CONFIG['generic_message_footer']));
     $footer = rcube_charset_convert($footer, RCMAIL_CHARSET, $message_charset);
+    if ($isHtml)
+      $footer = '<pre>'.$footer.'</pre>';
   }
+  if ($footer)
+    $message_body .= "\r\n" . $footer;
 }
 
 // set line length for body wrapping
-$LINE_LENGTH = $RCMAIL->config->get('line_length', 75);
+$LINE_LENGTH = $RCMAIL->config->get('line_length', 72);
 
 // Since we can handle big messages with disk usage, we need more time to work
 @set_time_limit(0);
 
 // create PEAR::Mail_mime instance
-$MAIL_MIME = new Mail_mime($RCMAIL->config->header_delimiter());
+$MAIL_MIME = new Mail_mime("\r\n");
 
 // Check if we have enough memory to handle the message in it
 // It's faster than using files, so we'll do this if we only can
@@ -384,54 +428,67 @@
 // the HTML part and the plain-text part
 
 if ($isHtml) {
-  $plugin = $RCMAIL->plugins->exec_hook('outgoing_message_body', array('body' => $message_body, 'type' => 'html', 'message' => $MAIL_MIME));
-  $MAIL_MIME->setHTMLBody($plugin['body'] . ($footer ? "\r\n<pre>".$footer.'</pre>' : ''));
+  $plugin = $RCMAIL->plugins->exec_hook('message_outgoing_body',
+    array('body' => $message_body, 'type' => 'html', 'message' => $MAIL_MIME));
+
+  $MAIL_MIME->setHTMLBody($plugin['body']);
 
   // add a plain text version of the e-mail as an alternative part.
   $h2t = new html2text($plugin['body'], false, true, 0);
-  $plainTextPart = rc_wordwrap($h2t->get_text(), $LINE_LENGTH, "\r\n") . ($footer ? "\r\n".$footer : '');
+  $plainTextPart = rc_wordwrap($h2t->get_text(), $LINE_LENGTH, "\r\n");
   $plainTextPart = wordwrap($plainTextPart, 998, "\r\n", true);
-  if (!strlen($plainTextPart)) {
+  if (!$plainTextPart) {
     // empty message body breaks attachment handling in drafts 
     $plainTextPart = "\r\n"; 
   }
-  $plugin = $RCMAIL->plugins->exec_hook('outgoing_message_body', array('body' => $plainTextPart, 'type' => 'alternative', 'message' => $MAIL_MIME));
+  else {
+    // make sure all line endings are CRLF (#1486712)
+    $plainTextPart = preg_replace('/\r?\n/', "\r\n", $plainTextPart);
+  }
+
+  $plugin = $RCMAIL->plugins->exec_hook('message_outgoing_body',
+    array('body' => $plainTextPart, 'type' => 'alternative', 'message' => $MAIL_MIME));
+
   $MAIL_MIME->setTXTBody($plugin['body']);
 
-  // look for "emoticon" images from TinyMCE and copy into message as attachments
-  $message_body = rcmail_attach_emoticons($MAIL_MIME);
+  // look for "emoticon" images from TinyMCE and change their src paths to
+  // be file paths on the server instead of URL paths.
+  $message_body = rcmail_fix_emoticon_paths($MAIL_MIME);
 }
-else
-  {
-  $message_body = rc_wordwrap($message_body, $LINE_LENGTH, "\r\n");
-  if ($footer)
-    $message_body .= "\r\n" . $footer;
+else {
+  $plugin = $RCMAIL->plugins->exec_hook('message_outgoing_body',
+    array('body' => $message_body, 'type' => 'plain', 'message' => $MAIL_MIME));
+
+  $message_body = $plugin['body'];
+
+  // compose format=flowed content if enabled
+  if ($flowed = $RCMAIL->config->get('send_format_flowed', true))
+    $message_body = rcube_message::format_flowed($message_body, min($LINE_LENGTH+2, 79));
+  else
+    $message_body = rc_wordwrap($message_body, $LINE_LENGTH, "\r\n");
+
   $message_body = wordwrap($message_body, 998, "\r\n", true);
   if (!strlen($message_body)) { 
     // empty message body breaks attachment handling in drafts 
     $message_body = "\r\n"; 
   }
-  $plugin = $RCMAIL->plugins->exec_hook('outgoing_message_body', array('body' => $message_body, 'type' => 'plain', 'message' => $MAIL_MIME));
-  $MAIL_MIME->setTXTBody($plugin['body'], false, true);
-}
 
-// chose transfer encoding
-$charset_7bit = array('ASCII', 'ISO-2022-JP', 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-15');
-$transfer_encoding = in_array(strtoupper($message_charset), $charset_7bit) ? '7bit' : '8bit';
+  $MAIL_MIME->setTXTBody($message_body, false, true);
+}
 
 // add stored attachments, if any
 if (is_array($_SESSION['compose']['attachments']))
 {
   foreach ($_SESSION['compose']['attachments'] as $id => $attachment) {
     // This hook retrieves the attachment contents from the file storage backend
-    $attachment = $RCMAIL->plugins->exec_hook('get_attachment', $attachment);
+    $attachment = $RCMAIL->plugins->exec_hook('attachment_get', $attachment);
 
-    $dispurl = '/\ssrc\s*=\s*[\'"]*\S+display-attachment\S+file=rcmfile' . preg_quote($attachment['id']) . '[\s\'"]\s*/';
+    $dispurl = '/\ssrc\s*=\s*[\'"]*\S+display-attachment\S+file=rcmfile' . preg_quote($attachment['id']) . '[\s\'"]*/';
     $message_body = $MAIL_MIME->getHTMLBody();
     if ($isHtml && (preg_match($dispurl, $message_body) > 0)) {
       $message_body = preg_replace($dispurl, ' src="'.$attachment['name'].'" ', $message_body);
       $MAIL_MIME->setHTMLBody($message_body);
-      
+
       if ($attachment['data'])
         $MAIL_MIME->addHTMLImage($attachment['data'], $attachment['mimetype'], $attachment['name'], false);
       else
@@ -446,7 +503,7 @@
         $ctype, 
         $attachment['name'],
         ($attachment['data'] ? false : true),
-        ($ctype == 'message/rfc822' ? $transfer_encoding : 'base64'),
+        ($ctype == 'message/rfc822' ? '8bit' : 'base64'),
         ($ctype == 'message/rfc822' ? 'inline' : 'attachment'),
         $message_charset, '', '', 
         $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL,
@@ -456,23 +513,26 @@
   }
 }
 
+// choose transfer encoding for plain/text body
+if (preg_match('/[^\x00-\x7F]/', $MAIL_MIME->getTXTBody()))
+  $transfer_encoding = $RCMAIL->config->get('force_7bit') ? 'quoted-printable' : '8bit';
+else
+  $transfer_encoding = '7bit';
+
 // encoding settings for mail composing
 $MAIL_MIME->setParam('text_encoding', $transfer_encoding);
 $MAIL_MIME->setParam('html_encoding', 'quoted-printable');
 $MAIL_MIME->setParam('head_encoding', 'quoted-printable');
 $MAIL_MIME->setParam('head_charset', $message_charset);
 $MAIL_MIME->setParam('html_charset', $message_charset);
-$MAIL_MIME->setParam('text_charset', $message_charset);
-
-$data = $RCMAIL->plugins->exec_hook('outgoing_message_headers', array('headers' => $headers));
-$headers = $data['headers'];
+$MAIL_MIME->setParam('text_charset', $message_charset . ($flowed ? ";\r\n format=flowed" : ''));
 
 // encoding subject header with mb_encode provides better results with asian characters
 if (function_exists('mb_encode_mimeheader'))
 {
   mb_internal_encoding($message_charset);
   $headers['Subject'] = mb_encode_mimeheader($headers['Subject'],
-    $message_charset, 'Q', $RCMAIL->config->header_delimiter(), 8);
+    $message_charset, 'Q', "\r\n", 8);
   mb_internal_encoding(RCMAIL_CHARSET);
 }
 
@@ -526,17 +586,14 @@
 
 if ($store_target)
   {
-  // check if mailbox exists
-  if (!in_array($store_target, $IMAP->list_mailboxes()))
-    {
-      // folder may be existing but not subscribed (#1485241)
-      if (!in_array($store_target, $IMAP->list_unsubscribed()))
-        $store_folder = $IMAP->create_mailbox($store_target, TRUE);
-      else if ($IMAP->subscribe($store_target))
-        $store_folder = TRUE;
-    }
-  else
-    $store_folder = TRUE;
+  // check if folder is subscribed
+  if ($IMAP->mailbox_exists($store_target, true))
+    $store_folder = true;
+  // folder may be existing but not subscribed (#1485241)
+  else if (!$IMAP->mailbox_exists($store_target))
+    $store_folder = $IMAP->create_mailbox($store_target, true);
+  else if ($IMAP->subscribe($store_target))
+    $store_folder = true;
 
   // append message to sent box
   if ($store_folder) {
@@ -590,9 +647,9 @@
   if ($olddraftmessageid)
     {
     // delete previous saved draft
-    $a_deleteid = $IMAP->search($CONFIG['drafts_mbox'], 'HEADER Message-ID '.$olddraftmessageid);
-
-    $deleted = $IMAP->delete_message($IMAP->get_uid($a_deleteid[0], $CONFIG['drafts_mbox']), $CONFIG['drafts_mbox']);
+    $a_deleteid = $IMAP->search_once($CONFIG['drafts_mbox'],
+        'HEADER Message-ID '.$olddraftmessageid, true);
+    $deleted = $IMAP->delete_message($a_deleteid, $CONFIG['drafts_mbox']);
 
     // raise error if deletion of old draft failed
     if (!$deleted)
@@ -612,8 +669,8 @@
   $msgid = strtr($message_id, array('>' => '', '<' => ''));
   
   // remember new draft-uid
-  $draftids = $IMAP->search($CONFIG['drafts_mbox'], 'HEADER Message-ID '.$msgid);
-  $_SESSION['compose']['param']['_draft_uid'] = $IMAP->get_uid($draftids[0], $CONFIG['drafts_mbox']);
+  $draftuids = $IMAP->search_once($CONFIG['drafts_mbox'], 'HEADER Message-ID '.$msgid, true);
+  $_SESSION['compose']['param']['_draft_uid'] = $draftuids[0];
 
   // display success
   $OUTPUT->show_message('messagesaved', 'confirmation');
@@ -638,4 +695,4 @@
   $OUTPUT->send('iframe');
   }
 
-?>
+

--
Gitblit v1.9.1