From ef4998c11084b2c99f8af9976f9860d5f7709a0f Mon Sep 17 00:00:00 2001 From: thomascube <thomas@roundcube.net> Date: Thu, 22 Sep 2011 04:48:05 -0400 Subject: [PATCH] Fix compose command from other tasks than mail and address book; skip common request parameters --- program/include/main.inc | 544 ++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 420 insertions(+), 124 deletions(-) diff --git a/program/include/main.inc b/program/include/main.inc index baaca65..226fa8a 100644 --- a/program/include/main.inc +++ b/program/include/main.inc @@ -97,9 +97,9 @@ * * @see rcmail::text_exists() */ -function rcube_label_exists($name, $domain=null) +function rcube_label_exists($name, $domain=null, &$ref_domain = null) { - return rcmail::get_instance()->text_exists($name, $domain); + return rcmail::get_instance()->text_exists($name, $domain, $ref_domain); } @@ -136,26 +136,24 @@ * Remove temp files older than two days */ function rcmail_temp_gc() - { +{ $rcmail = rcmail::get_instance(); $tmp = unslashify($rcmail->config->get('temp_dir')); $expire = mktime() - 172800; // expire in 48 hours - if ($dir = opendir($tmp)) - { - while (($fname = readdir($dir)) !== false) - { + if ($dir = opendir($tmp)) { + while (($fname = readdir($dir)) !== false) { if ($fname{0} == '.') continue; if (filemtime($tmp.'/'.$fname) < $expire) @unlink($tmp.'/'.$fname); - } + } closedir($dir); - } } +} /** @@ -164,19 +162,25 @@ * @return void */ function rcmail_cache_gc() - { +{ $rcmail = rcmail::get_instance(); $db = $rcmail->get_dbh(); - + // get target timestamp $ts = get_offset_time($rcmail->config->get('message_cache_lifetime', '30d'), -1); - - $db->query("DELETE FROM ".get_table_name('messages')." - WHERE created < " . $db->fromunixtime($ts)); - $db->query("DELETE FROM ".get_table_name('cache')." - WHERE created < " . $db->fromunixtime($ts)); - } + $db->query("DELETE FROM ".get_table_name('cache_messages') + ." WHERE changed < " . $db->fromunixtime($ts)); + + $db->query("DELETE FROM ".get_table_name('cache_index') + ." WHERE changed < " . $db->fromunixtime($ts)); + + $db->query("DELETE FROM ".get_table_name('cache_thread') + ." WHERE changed < " . $db->fromunixtime($ts)); + + $db->query("DELETE FROM ".get_table_name('cache') + ." WHERE created < " . $db->fromunixtime($ts)); +} /** @@ -186,9 +190,9 @@ * @param string Error message */ function rcube_error_handler($errno, $errstr) - { +{ throw new ErrorException($errstr, 0, $errno); - } +} /** @@ -201,11 +205,10 @@ * @return string Converted string */ function rcube_charset_convert($str, $from, $to=NULL) - { +{ static $iconv_options = null; static $mbstring_loaded = null; static $mbstring_list = null; - static $convert_warning = false; static $conv = null; $error = false; @@ -243,11 +246,11 @@ if ($mbstring_loaded === null) $mbstring_loaded = extension_loaded('mbstring'); - + // convert charset using mbstring module if ($mbstring_loaded) { $aliases['WINDOWS-1257'] = 'ISO-8859-13'; - + if ($mbstring_list === null) { $mbstring_list = mb_list_encodings(); $mbstring_list = array_map('strtoupper', $mbstring_list); @@ -255,7 +258,7 @@ $mb_from = $aliases[$from] ? $aliases[$from] : $from; $mb_to = $aliases[$to] ? $aliases[$to] : $to; - + // return if encoding found, string matches encoding and convert succeeded if (in_array($mb_from, $mbstring_list) && in_array($mb_to, $mbstring_list)) { if (mb_check_encoding($str, $mb_from) && ($out = mb_convert_encoding($str, $mb_to, $mb_from))) @@ -310,22 +313,9 @@ $error = true; } - // report error - if ($error && !$convert_warning) { - raise_error(array( - 'code' => 500, - 'type' => 'php', - 'file' => __FILE__, - 'line' => __LINE__, - 'message' => "Could not convert string from $from to $to. Make sure iconv/mbstring is installed or lib/utf8.class is available." - ), true, false); - - $convert_warning = true; - } - // return UTF-8 or original string return $str; - } +} /** @@ -337,7 +327,7 @@ * @return string The validated charset name */ function rcube_parse_charset($input) - { +{ static $charsets = array(); $charset = strtoupper($input); @@ -404,11 +394,11 @@ // some clients sends windows-1252 text as latin1, // it is safe to use windows-1252 for all latin1 $result = $iso == 'ISO-8859-1' ? 'WINDOWS-1252' : $iso; - } + } // handle broken charset names e.g. WINDOWS-1250HTTP-EQUIVCONTENT-TYPE else if (preg_match('/(WIN|WINDOWS)([0-9]+)/', $str, $m)) { $result = 'WINDOWS-' . $m[2]; - } + } // LATIN else if (preg_match('/LATIN(.*)/', $str, $m)) { $aliases = array('2' => 2, '3' => 3, '4' => 4, '5' => 9, '6' => 10, @@ -419,24 +409,24 @@ // it is safe to use windows-1252 for all latin1 if ($m[1] == 1) { $result = 'WINDOWS-1252'; - } + } // if iconv is not supported we need ISO labels, it's also safe for iconv else if (!empty($aliases[$m[1]])) { $result = 'ISO-8859-'.$aliases[$m[1]]; - } + } // iconv requires convertion of e.g. LATIN-1 to LATIN1 else { $result = $str; - } } + } else { $result = $charset; - } + } $charsets[$input] = $result; return $result; - } +} /** @@ -715,13 +705,14 @@ * @param int Source to get value from (GPC) * @return array Hash array with all request parameters */ -function request2param($mode = RCUBE_INPUT_GPC) +function request2param($mode = RCUBE_INPUT_GPC, $ignore = 'task|action') { $out = array(); $src = $mode == RCUBE_INPUT_GET ? $_GET : ($mode == RCUBE_INPUT_POST ? $_POST : $_REQUEST); foreach ($src as $key => $value) { $fname = $key[0] == '_' ? substr($key, 1) : $key; - $out[$fname] = get_input_value($key, $mode); + if ($ignore && !preg_match("/($ignore)/", $fname)) + $out[$fname] = get_input_value($key, $mode); } return $out; @@ -867,8 +858,7 @@ // use value from post if (isset($_POST[$fname])) { - $postvalue = get_input_value($fname, RCUBE_INPUT_POST, - $type == 'textarea' && strpos($attrib['class'], 'mce_editor')!==false ? true : false); + $postvalue = get_input_value($fname, RCUBE_INPUT_POST, true); $value = $attrib['array'] ? $postvalue[intval($colcounts[$col]++)] : $postvalue; } @@ -1038,7 +1028,7 @@ */ function format_date($date, $format=NULL) { - global $CONFIG; + global $RCMAIL, $CONFIG; $ts = NULL; @@ -1049,13 +1039,7 @@ return ''; // 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++; - } + $tz = $RCMAIL->config->get_timezone(); // convert time to user's timezone $timestamp = $ts - date('Z', $ts) + ($tz * 3600); @@ -1072,13 +1056,13 @@ // define date format depending on current time if (!$format) { if ($CONFIG['prettydate'] && $timestamp > $today_limit && $timestamp < $now) { - $format = $CONFIG['date_today'] ? $CONFIG['date_today'] : 'H:i'; + $format = $RCMAIL->config->get('date_today', $RCMAIL->config->get('time_format', 'H:i')); $today = true; } else if ($CONFIG['prettydate'] && $timestamp > $week_limit && $timestamp < $now) - $format = $CONFIG['date_short'] ? $CONFIG['date_short'] : 'D H:i'; + $format = $RCMAIL->config->get('date_short', 'D H:i'); else - $format = $CONFIG['date_long'] ? $CONFIG['date_long'] : 'd.m.Y H:i'; + $format = $RCMAIL->config->get('date_long', 'Y-m-d H:i'); } // strftime() format @@ -1091,28 +1075,28 @@ // an alternative would be to convert the date() format string to fit with strftime() $out = ''; for($i=0; $i<strlen($format); $i++) { - if ($format{$i}=='\\') // skip escape chars + if ($format[$i]=='\\') // skip escape chars continue; // write char "as-is" - if ($format{$i}==' ' || $format{$i-1}=='\\') - $out .= $format{$i}; + if ($format[$i]==' ' || $format{$i-1}=='\\') + $out .= $format[$i]; // weekday (short) - else if ($format{$i}=='D') + else if ($format[$i]=='D') $out .= rcube_label(strtolower(date('D', $timestamp))); // weekday long - else if ($format{$i}=='l') + else if ($format[$i]=='l') $out .= rcube_label(strtolower(date('l', $timestamp))); // month name (short) - else if ($format{$i}=='M') + else if ($format[$i]=='M') $out .= rcube_label(strtolower(date('M', $timestamp))); // month name (long) - else if ($format{$i}=='F') + else if ($format[$i]=='F') $out .= rcube_label('long'.strtolower(date('M', $timestamp))); - else if ($format{$i}=='x') + else if ($format[$i]=='x') $out .= strftime('%x %X', $timestamp); else - $out .= date($format{$i}, $timestamp); + $out .= date($format[$i], $timestamp); } if ($today) { @@ -1158,25 +1142,28 @@ { global $RCMAIL; static $a_mailboxes; - + $attrib += array('maxlength' => 100, 'realnames' => false); // add some labels to client $RCMAIL->output->add_label('purgefolderconfirm', 'deletemessagesconfirm'); - + $type = $attrib['type'] ? $attrib['type'] : 'ul'; unset($attrib['type']); if ($type=='ul' && !$attrib['id']) $attrib['id'] = 'rcmboxlist'; + if (empty($attrib['folder_name'])) + $attrib['folder_name'] = '*'; + // get mailbox list $mbox_name = $RCMAIL->imap->get_mailbox_name(); - + // build the folders tree if (empty($a_mailboxes)) { // get mailbox list - $a_folders = $RCMAIL->imap->list_mailboxes(); + $a_folders = $RCMAIL->imap->list_mailboxes('', $attrib['folder_name'], $attrib['folder_filter']); $delimiter = $RCMAIL->imap->get_hierarchy_delimiter(); $a_mailboxes = array(); @@ -1187,23 +1174,23 @@ // allow plugins to alter the folder tree or to localize folder names $hook = $RCMAIL->plugins->exec_hook('render_mailboxlist', array('list' => $a_mailboxes, 'delimiter' => $delimiter)); - if ($type=='select') { + if ($type == 'select') { $select = new html_select($attrib); - + // add no-selection option if ($attrib['noselection']) - $select->add(rcube_label($attrib['noselection']), '0'); - + $select->add(rcube_label($attrib['noselection']), ''); + rcmail_render_folder_tree_select($hook['list'], $mbox_name, $attrib['maxlength'], $select, $attrib['realnames']); $out = $select->show(); } else { $js_mailboxlist = array(); $out = html::tag('ul', $attrib, rcmail_render_folder_tree_html($hook['list'], $mbox_name, $js_mailboxlist, $attrib), html::$common_attrib); - + $RCMAIL->output->add_gui_object('mailboxlist', $attrib['id']); $RCMAIL->output->set_env('mailboxes', $js_mailboxlist); - $RCMAIL->output->set_env('collapsed_folders', $RCMAIL->config->get('collapsed_folders')); + $RCMAIL->output->set_env('collapsed_folders', (string)$RCMAIL->config->get('collapsed_folders')); } return $out; @@ -1219,14 +1206,17 @@ function rcmail_mailbox_select($p = array()) { global $RCMAIL; - + $p += array('maxlength' => 100, 'realnames' => false); $a_mailboxes = array(); + if (empty($p['folder_name'])) + $p['folder_name'] = '*'; + if ($p['unsubscribed']) - $list = $RCMAIL->imap->list_unsubscribed(); + $list = $RCMAIL->imap->list_unsubscribed('', $p['folder_name'], $p['folder_filter']); else - $list = $RCMAIL->imap->list_mailboxes(); + $list = $RCMAIL->imap->list_mailboxes('', $p['folder_name'], $p['folder_filter']); $delimiter = $RCMAIL->imap->get_hierarchy_delimiter(); @@ -1240,7 +1230,7 @@ if ($p['noselection']) $select->add($p['noselection'], ''); - rcmail_render_folder_tree_select($a_mailboxes, $mbox, $p['maxlength'], $select, $p['realnames']); + rcmail_render_folder_tree_select($a_mailboxes, $mbox, $p['maxlength'], $select, $p['realnames'], 0, $p['exceptions']); return $select; } @@ -1306,7 +1296,7 @@ if (strlen($subFolders)) rcmail_build_folder_tree($arrFolders[$currentFolder]['folders'], $subFolders, $delm, $path.$delm); } - + /** * Return html for a structured list <ul> for the mailbox tree @@ -1316,7 +1306,7 @@ function rcmail_render_folder_tree_html(&$arrFolders, &$mbox_name, &$jslist, $attrib, $nestLevel=0) { global $RCMAIL, $CONFIG; - + $maxlength = intval($attrib['maxlength']); $realnames = (bool)$attrib['realnames']; $msgcounts = $RCMAIL->imap->get_cache('messagecount'); @@ -1347,27 +1337,27 @@ $classes = array('mailbox'); // set special class for Sent, Drafts, Trash and Junk - if ($folder['id']==$CONFIG['sent_mbox']) + if ($folder['id'] == $CONFIG['sent_mbox']) $classes[] = 'sent'; - else if ($folder['id']==$CONFIG['drafts_mbox']) + else if ($folder['id'] == $CONFIG['drafts_mbox']) $classes[] = 'drafts'; - else if ($folder['id']==$CONFIG['trash_mbox']) + else if ($folder['id'] == $CONFIG['trash_mbox']) $classes[] = 'trash'; - else if ($folder['id']==$CONFIG['junk_mbox']) + else if ($folder['id'] == $CONFIG['junk_mbox']) $classes[] = 'junk'; - else if ($folder['id']=='INBOX') + else if ($folder['id'] == 'INBOX') $classes[] = 'inbox'; else $classes[] = '_'.asciiwords($folder_class ? $folder_class : strtolower($folder['id']), true); - + $classes[] = $zebra_class; - + if ($folder['id'] == $mbox_name) $classes[] = 'selected'; - $collapsed = preg_match('/&'.rawurlencode($folder['id']).'&/', $RCMAIL->config->get('collapsed_folders')); + $collapsed = strpos($CONFIG['collapsed_folders'], '&'.rawurlencode($folder['id']).'&') !== false; $unread = $msgcounts ? intval($msgcounts[$folder['id']]['UNSEEN']) : 0; - + if ($folder['virtual']) $classes[] = 'virtual'; else if ($unread) @@ -1392,9 +1382,9 @@ 'style' => "position:absolute", 'onclick' => sprintf("%s.command('collapse-folder', '%s')", JS_OBJECT_NAME, $js_name) ), ' ') : '')); - + $jslist[$folder_id] = array('id' => $folder['id'], 'name' => $foldername, 'virtual' => $folder['virtual']); - + if (!empty($folder['folders'])) { $out .= html::tag('ul', array('style' => ($collapsed ? "display:none;" : null)), rcmail_render_folder_tree_html($folder['folders'], $mbox_name, $jslist, $attrib, $nestLevel+1)); @@ -1413,33 +1403,34 @@ * @access private * @return string */ -function rcmail_render_folder_tree_select(&$arrFolders, &$mbox_name, $maxlength, &$select, $realnames=false, $nestLevel=0) - { - $idx = 0; +function rcmail_render_folder_tree_select(&$arrFolders, &$mbox_name, $maxlength, &$select, $realnames=false, $nestLevel=0, $exceptions=array()) +{ $out = ''; - foreach ($arrFolders as $key=>$folder) - { - if (!$realnames && ($folder_class = rcmail_folder_classname($folder['id']))) - $foldername = rcube_label($folder_class); - else - { - $foldername = $folder['name']; - - // shorten the folder name to a given length - if ($maxlength && $maxlength>1) - $foldername = abbreviate_string($foldername, $maxlength); + + foreach ($arrFolders as $key => $folder) { + if (empty($exceptions) || !in_array($folder['id'], $exceptions)) { + if (!$realnames && ($folder_class = rcmail_folder_classname($folder['id']))) + $foldername = rcube_label($folder_class); + else { + $foldername = $folder['name']; + + // shorten the folder name to a given length + if ($maxlength && $maxlength>1) + $foldername = abbreviate_string($foldername, $maxlength); } - $select->add(str_repeat(' ', $nestLevel*4) . $foldername, $folder['id']); + $select->add(str_repeat(' ', $nestLevel*4) . $foldername, $folder['id']); + } + else if ($nestLevel) + continue; if (!empty($folder['folders'])) - $out .= rcmail_render_folder_tree_select($folder['folders'], $mbox_name, $maxlength, $select, $realnames, $nestLevel+1); - - $idx++; - } + $out .= rcmail_render_folder_tree_select($folder['folders'], $mbox_name, $maxlength, + $select, $realnames, $nestLevel+1, $exceptions); + } return $out; - } +} /** @@ -1476,6 +1467,31 @@ return rcube_label($folder_class); else return rcube_charset_convert($name, 'UTF7-IMAP'); +} + + +function rcmail_localize_folderpath($path) +{ + global $RCMAIL; + + $protect_folders = $RCMAIL->config->get('protect_default_folders'); + $default_folders = (array) $RCMAIL->config->get('default_imap_folders'); + $delimiter = $RCMAIL->imap->get_hierarchy_delimiter(); + $path = explode($delimiter, $path); + $result = array(); + + foreach ($path as $idx => $dir) { + $directory = implode($delimiter, array_slice($path, 0, $idx+1)); + if ($protect_folders && in_array($directory, $default_folders)) { + unset($result); + $result[] = rcmail_localize_foldername($directory); + } + else { + $result[] = rcube_charset_convert($dir, 'UTF7-IMAP'); + } + } + + return implode($delimiter, $result); } @@ -1559,7 +1575,11 @@ $RCMAIL->output->show_message('errorreadonly', 'error'); } else if ($err_code && ($err_str = $RCMAIL->imap->get_error_str())) { - $RCMAIL->output->show_message('servererrormsg', 'error', array('msg' => $err_str)); + // try to detect access rights problem and display appropriate message + if (stripos($err_str, 'Permission denied') !== false) + $RCMAIL->output->show_message('errornoperm', 'error'); + else + $RCMAIL->output->show_message('servererrormsg', 'error', array('msg' => $err_str)); } else if ($fallback) { $RCMAIL->output->show_message($fallback, 'error', $fallback_args); @@ -1582,7 +1602,7 @@ $hook = $RCMAIL->plugins->exec_hook('html_editor', array('mode' => $mode)); if ($hook['abort']) - return; + return; $lang = strtolower($_SESSION['language']); @@ -1594,9 +1614,14 @@ $RCMAIL->output->include_script('tiny_mce/tiny_mce.js'); $RCMAIL->output->include_script('editor.js'); - $RCMAIL->output->add_script(sprintf("rcmail_editor_init('\$__skin_path', '%s', %d, '%s');", - JQ($lang), intval($CONFIG['enable_spellcheck']), $mode), - 'foot'); + $RCMAIL->output->add_script(sprintf("rcmail_editor_init(%s)", + json_encode(array( + 'mode' => $mode, + 'skin_path' => '$__skin_path', + 'lang' => $lang, + 'spellcheck' => intval($CONFIG['enable_spellcheck']), + 'spelldict' => intval($CONFIG['spellcheck_dictionary']), + ))), 'foot'); } @@ -1634,6 +1659,192 @@ } return preg_replace($search, $replace, $html); +} + + +/** + * Send the given message using the configured method + * + * @param object $message Reference to Mail_MIME object + * @param string $from Sender address string + * @param array $mailto Array of recipient address strings + * @param array $smtp_error SMTP error array (reference) + * @param string $body_file Location of file with saved message body (reference), + * used when delay_file_io is enabled + * @param array $smtp_opts SMTP options (e.g. DSN request) + * + * @return boolean Send status. + */ +function rcmail_deliver_message(&$message, $from, $mailto, &$smtp_error, &$body_file=null, $smtp_opts=null) +{ + global $CONFIG, $RCMAIL; + + $headers = $message->headers(); + + // send thru SMTP server using custom SMTP library + if ($CONFIG['smtp_server']) { + // generate list of recipients + $a_recipients = array($mailto); + + if (strlen($headers['Cc'])) + $a_recipients[] = $headers['Cc']; + if (strlen($headers['Bcc'])) + $a_recipients[] = $headers['Bcc']; + + // clean Bcc from header for recipients + $send_headers = $headers; + unset($send_headers['Bcc']); + // here too, it because txtHeaders() below use $message->_headers not only $send_headers + unset($message->_headers['Bcc']); + + $smtp_headers = $message->txtHeaders($send_headers, true); + + if ($message->getParam('delay_file_io')) { + // use common temp dir + $temp_dir = $RCMAIL->config->get('temp_dir'); + $body_file = tempnam($temp_dir, 'rcmMsg'); + if (PEAR::isError($mime_result = $message->saveMessageBody($body_file))) { + raise_error(array('code' => 650, 'type' => 'php', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Could not create message: ".$mime_result->getMessage()), + TRUE, FALSE); + return false; + } + $msg_body = fopen($body_file, 'r'); + } else { + $msg_body = $message->get(); + } + + // send message + if (!is_object($RCMAIL->smtp)) + $RCMAIL->smtp_init(true); + + $sent = $RCMAIL->smtp->send_mail($from, $a_recipients, $smtp_headers, $msg_body, $smtp_opts); + $smtp_response = $RCMAIL->smtp->get_response(); + $smtp_error = $RCMAIL->smtp->get_error(); + + // log error + if (!$sent) + raise_error(array('code' => 800, 'type' => 'smtp', 'line' => __LINE__, 'file' => __FILE__, + 'message' => "SMTP error: ".join("\n", $smtp_response)), TRUE, FALSE); + } + // 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' => 650, '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; +} + + +// 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 $RCMAIL, $CONFIG; + + // get user's timezone + $tz = $RCMAIL->config->get_timezone(); + + $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; } @@ -1808,6 +2019,10 @@ $domain = $is_utf ? idn_to_ascii($domain) : idn_to_utf8($domain); + if ($domain === false) { + return ''; + } + return $at ? $user . '@' . $domain : $domain; } @@ -1932,8 +2147,8 @@ if (!$RCMAIL->config->get('log_logins') || !$RCMAIL->user) return; - write_log('userlogins', sprintf('Successful login for %s (ID: %d) from %s', - $RCMAIL->user->get_username(), $RCMAIL->user->ID, rcmail_remote_ip())); + write_log('userlogins', sprintf('Successful login for %s (ID: %d) from %s in session %s', + $RCMAIL->user->get_username(), $RCMAIL->user->ID, rcmail_remote_ip(), session_id())); } @@ -2091,3 +2306,84 @@ } } +function rcube_upload_progress() +{ + global $RCMAIL; + + $prefix = ini_get('apc.rfc1867_prefix'); + $params = array( + 'action' => $RCMAIL->action, + 'name' => get_input_value('_progress', RCUBE_INPUT_GET), + ); + + if (function_exists('apc_fetch')) { + $status = apc_fetch($prefix . $params['name']); + + if (!empty($status)) { + $status['percent'] = round($status['current']/$status['total']*100); + $params = array_merge($status, $params); + } + } + + if (isset($params['percent'])) + $params['text'] = rcube_label(array('name' => 'uploadprogress', 'vars' => array( + 'percent' => $params['percent'] . '%', + 'current' => show_bytes($params['current']), + 'total' => show_bytes($params['total']) + ))); + + $RCMAIL->output->command('upload_progress_update', $params); + $RCMAIL->output->send(); +} + +function rcube_upload_init() +{ + global $RCMAIL; + + // Enable upload progress bar + if (($seconds = $RCMAIL->config->get('upload_progress')) && ini_get('apc.rfc1867')) { + if ($field_name = ini_get('apc.rfc1867_name')) { + $RCMAIL->output->set_env('upload_progress_name', $field_name); + $RCMAIL->output->set_env('upload_progress_time', (int) $seconds); + } + } + + // find max filesize value + $max_filesize = parse_bytes(ini_get('upload_max_filesize')); + $max_postsize = parse_bytes(ini_get('post_max_size')); + if ($max_postsize && $max_postsize < $max_filesize) + $max_filesize = $max_postsize; + + $RCMAIL->output->set_env('max_filesize', $max_filesize); + $max_filesize = show_bytes($max_filesize); + $RCMAIL->output->set_env('filesizeerror', rcube_label(array( + 'name' => 'filesizeerror', 'vars' => array('size' => $max_filesize)))); + + return $max_filesize; +} + +/** + * Initializes client-side autocompletion + */ +function rcube_autocomplete_init() +{ + global $RCMAIL; + static $init; + + if ($init) + return; + + $init = 1; + + if (($threads = (int)$RCMAIL->config->get('autocomplete_threads')) > 0) { + $book_types = (array) $RCMAIL->config->get('autocomplete_addressbooks', 'sql'); + if (count($book_types) > 1) { + $RCMAIL->output->set_env('autocomplete_threads', $threads); + $RCMAIL->output->set_env('autocomplete_sources', $book_types); + } + } + + $RCMAIL->output->set_env('autocomplete_max', (int)$RCMAIL->config->get('autocomplete_max', 15)); + $RCMAIL->output->set_env('autocomplete_min_length', $RCMAIL->config->get('autocomplete_min_length')); + $RCMAIL->output->add_label('autocompletechars', 'autocompletemore'); +} -- Gitblit v1.9.1