diff options
-rw-r--r-- | CHANGELOG | 8 | ||||
-rw-r--r-- | INSTALL | 4 | ||||
-rw-r--r-- | SQL/mysql.initial.sql | 8 | ||||
-rw-r--r-- | SQL/mysql.update-0.1a.sql | 51 | ||||
-rw-r--r-- | SQL/mysql.update.sql | 60 | ||||
-rw-r--r-- | SQL/mysql5.initial.sql | 18 | ||||
-rwxr-xr-x | SQL/postgres.initial.sql | 3 | ||||
-rw-r--r-- | SQL/postgres.update.sql | 7 | ||||
-rw-r--r-- | SQL/sqlite.initial.sql | 4 | ||||
-rw-r--r-- | SQL/sqlite.update.sql | 27 | ||||
-rw-r--r-- | UPGRADING | 178 | ||||
-rw-r--r-- | program/include/rcube_imap.inc | 134 | ||||
-rw-r--r-- | program/lib/imap.inc | 14 | ||||
-rw-r--r-- | program/steps/mail/func.inc | 93 | ||||
-rw-r--r-- | program/steps/mail/get.inc | 9 |
15 files changed, 326 insertions, 292 deletions
@@ -1,6 +1,13 @@ CHANGELOG RoundCube Webmail --------------------------- +2006/08/25 (thomasb) +---------- +- Fixed folder renaming: unsubscribe before rename (Bug #1483920) +- Finalized new message parsing (+ chaching) +- Updated SQL scripts and UPGRADING instructions + + 2006/08/23 (thomasb) ---------- - Updated Polish, Portuguese, Latvian, Chinese and Japanese localization @@ -16,6 +23,7 @@ CHANGELOG RoundCube Webmail 2006/08/18 (thomasb) ---------- - Re-built message parsing (Bug #1327068) + Now based on the message structure delivered by the IMAP server. - Fixed some XSS and SQL injection issues @@ -40,7 +40,7 @@ importing the table layout and granting the proper permissions to the roundcube user. Here is an example of that procedure: # mysql -> CREATE DATABASE 'roundcubemail'; +> CREATE DATABASE roundcubemail; > GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'password'; > quit @@ -53,7 +53,7 @@ For MySQL version 4.1 and up, it's recommended to create the database for RoundCube with utf-8 charset. Here's an example of the init procedure: # mysql -> CREATE DATABASE 'roundcubemail' DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; +> CREATE DATABASE roundcubemail DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; > GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'password'; > quit diff --git a/SQL/mysql.initial.sql b/SQL/mysql.initial.sql index 7546e52da..716268b1a 100644 --- a/SQL/mysql.initial.sql +++ b/SQL/mysql.initial.sql @@ -1,5 +1,5 @@ -- RoundCube Webmail initial database structure --- Version 0.1beta2 +-- Version 0.1-beta2 -- -- -------------------------------------------------------- @@ -116,12 +116,12 @@ CREATE TABLE `messages` ( `date` datetime NOT NULL default '0000-00-00 00:00:00', `size` int(11) unsigned NOT NULL default '0', `headers` text NOT NULL, - `body` longtext, + `structure` text, PRIMARY KEY (`message_id`), KEY `user_id` (`user_id`), - KEY `cache_key` (`cache_key`), KEY `idx` (`idx`), - KEY `uid` (`uid`) + KEY `uid` (`uid`), + UNIQUE `uniqueness` (`cache_key`, `uid`) ); diff --git a/SQL/mysql.update-0.1a.sql b/SQL/mysql.update-0.1a.sql new file mode 100644 index 000000000..054814af5 --- /dev/null +++ b/SQL/mysql.update-0.1a.sql @@ -0,0 +1,51 @@ +-- RoundCube Webmail update script for MySQL databases +-- Updates from version 0.1-20051007 + + +ALTER TABLE `session` ADD `ip` VARCHAR(15) NOT NULL AFTER changed; +ALTER TABLE `users` ADD `alias` VARCHAR(128) NOT NULL AFTER mail_host; + + + +-- RoundCube Webmail update script for MySQL databases +-- Updates from version 0.1-20051021 + +ALTER TABLE `session` CHANGE `sess_id` `sess_id` VARCHAR(40) NOT NULL; + +ALTER TABLE `contacts` CHANGE `del` `del` TINYINT(1) NOT NULL; +ALTER TABLE `contacts` ADD `changed` DATETIME NOT NULL AFTER `user_id`; + +UPDATE `contacts` SET `del`=0 WHERE `del`=1; +UPDATE `contacts` SET `del`=1 WHERE `del`=2; + +ALTER TABLE `identities` CHANGE `default` `standard` TINYINT(1) NOT NULL; +ALTER TABLE `identities` CHANGE `del` `del` TINYINT(1) NOT NULL; + +UPDATE `identities` SET `del`=0 WHERE `del`=1; +UPDATE `identities` SET `del`=1 WHERE `del`=2; +UPDATE `identities` SET `standard`=0 WHERE `standard`=1; +UPDATE `identities` SET `standard`=1 WHERE `standard`=2; + +CREATE TABLE `messages` ( + `message_id` int(11) unsigned NOT NULL auto_increment, + `user_id` int(11) unsigned NOT NULL default '0', + `del` tinyint(1) NOT NULL default '0', + `cache_key` varchar(128) NOT NULL default '', + `created` datetime NOT NULL default '0000-00-00 00:00:00', + `idx` int(11) unsigned NOT NULL default '0', + `uid` int(11) unsigned NOT NULL default '0', + `subject` varchar(255) NOT NULL default '', + `from` varchar(255) NOT NULL default '', + `to` varchar(255) NOT NULL default '', + `cc` varchar(255) NOT NULL default '', + `date` datetime NOT NULL default '0000-00-00 00:00:00', + `size` int(11) unsigned NOT NULL default '0', + `headers` text NOT NULL, + `structure` text, + PRIMARY KEY (`message_id`), + KEY `user_id` (`user_id`), + KEY `idx` (`idx`), + KEY `uid` (`uid`), + UNIQUE `uniqueness` (`cache_key`, `uid`) +) TYPE=MyISAM; + diff --git a/SQL/mysql.update.sql b/SQL/mysql.update.sql index 7fa296b0b..cfd5af361 100644 --- a/SQL/mysql.update.sql +++ b/SQL/mysql.update.sql @@ -1,57 +1,9 @@ -- RoundCube Webmail update script for MySQL databases --- Updates from version 0.1-20051007 +-- Updates from version 0.1-beta and 0.1-beta2 +ALTER TABLE `messages` + DROP `body`, + DROP INDEX `cache_key`, + ADD `structure` TEXT, + ADD UNIQUE `uniqueness` (`cache_key`, `uid`); -ALTER TABLE `session` ADD `ip` VARCHAR(15) NOT NULL AFTER changed; -ALTER TABLE `users` ADD `alias` VARCHAR(128) NOT NULL AFTER mail_host; - - - --- RoundCube Webmail update script for MySQL databases --- Updates from version 0.1-20051021 - -ALTER TABLE `session` CHANGE `sess_id` `sess_id` VARCHAR(40) NOT NULL; - -ALTER TABLE `contacts` CHANGE `del` `del` TINYINT(1) NOT NULL; -ALTER TABLE `contacts` ADD `changed` DATETIME NOT NULL AFTER `user_id`; - -UPDATE `contacts` SET `del`=0 WHERE `del`=1; -UPDATE `contacts` SET `del`=1 WHERE `del`=2; - -ALTER TABLE `identities` CHANGE `default` `standard` TINYINT(1) NOT NULL; -ALTER TABLE `identities` CHANGE `del` `del` TINYINT(1) NOT NULL; - -UPDATE `identities` SET `del`=0 WHERE `del`=1; -UPDATE `identities` SET `del`=1 WHERE `del`=2; -UPDATE `identities` SET `standard`=0 WHERE `standard`=1; -UPDATE `identities` SET `standard`=1 WHERE `standard`=2; - -CREATE TABLE `messages` ( - `message_id` int(11) unsigned NOT NULL auto_increment, - `user_id` int(11) unsigned NOT NULL default '0', - `del` tinyint(1) NOT NULL default '0', - `cache_key` varchar(128) NOT NULL default '', - `created` datetime NOT NULL default '0000-00-00 00:00:00', - `idx` int(11) unsigned NOT NULL default '0', - `uid` int(11) unsigned NOT NULL default '0', - `subject` varchar(255) NOT NULL default '', - `from` varchar(255) NOT NULL default '', - `to` varchar(255) NOT NULL default '', - `cc` varchar(255) NOT NULL default '', - `date` datetime NOT NULL default '0000-00-00 00:00:00', - `size` int(11) unsigned NOT NULL default '0', - `headers` text NOT NULL, - `body` longtext, - PRIMARY KEY (`message_id`), - KEY `user_id` (`user_id`), - KEY `cache_key` (`cache_key`), - KEY `idx` (`idx`), - KEY `uid` (`uid`) -) TYPE=MyISAM; - - - --- RoundCube Webmail update script for MySQL databases --- Updates from version 0.1-20051216 - -ALTER TABLE `messages` ADD `created` DATETIME NOT NULL AFTER `cache_key` ; diff --git a/SQL/mysql5.initial.sql b/SQL/mysql5.initial.sql index 0116468ee..24e143119 100644 --- a/SQL/mysql5.initial.sql +++ b/SQL/mysql5.initial.sql @@ -1,5 +1,5 @@ -- RoundCube Webmail initial database structure --- Version 0.1beta2 +-- Version 0.1-beta2 -- -- -------------------------------------------------------- @@ -16,7 +16,7 @@ CREATE TABLE `session` ( `ip` varchar(15) NOT NULL, `vars` text NOT NULL, PRIMARY KEY(`sess_id`) -) TYPE=MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci; +) TYPE=MYISAM CHARACTER SET ascii COLLATE ascii_general_ci; -- Table structure for table `users` @@ -31,15 +31,16 @@ CREATE TABLE `users` ( `language` varchar(5) NOT NULL DEFAULT 'en', `preferences` text NOT NULL, PRIMARY KEY(`user_id`) -) TYPE=MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci; +) TYPE=MYISAM CHARACTER SET ascii COLLATE ascii_general_ci; -- Table structure for table `messages` CREATE TABLE `messages` ( `message_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0', `del` tinyint(1) NOT NULL DEFAULT '0', - `cache_key` varchar(128) NOT NULL, + `cache_key` varchar(128) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL, `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `idx` int(11) UNSIGNED NOT NULL DEFAULT '0', `uid` int(11) UNSIGNED NOT NULL DEFAULT '0', @@ -50,12 +51,11 @@ CREATE TABLE `messages` ( `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `size` int(11) UNSIGNED NOT NULL DEFAULT '0', `headers` text NOT NULL, - `body` longtext, - `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0', + `structure` text, PRIMARY KEY(`message_id`), - INDEX `cache_key`(`cache_key`), INDEX `idx`(`idx`), INDEX `uid`(`uid`), + UNIQUE `uniqueness` (`cache_key`, `uid`), CONSTRAINT `User_ID_FK_messages` FOREIGN KEY (`user_id`) REFERENCES `users`(`user_id`) ON DELETE CASCADE @@ -67,8 +67,8 @@ CREATE TABLE `messages` ( CREATE TABLE `cache` ( `cache_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `session_id` varchar(40), - `cache_key` varchar(128) NOT NULL, + `session_id` varchar(40) CHARACTER SET ascii COLLATE ascii_general_ci, + `cache_key` varchar(128) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL, `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `data` longtext NOT NULL, `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0', diff --git a/SQL/postgres.initial.sql b/SQL/postgres.initial.sql index 55e139603..029afaab3 100755 --- a/SQL/postgres.initial.sql +++ b/SQL/postgres.initial.sql @@ -163,6 +163,7 @@ CREATE TABLE "messages" ( date timestamp with time zone NOT NULL, size integer DEFAULT 0 NOT NULL, headers text NOT NULL, - body text + structure text ); +ALTER TABLE "messages" ADD UNIQUE (cache_key, uid); diff --git a/SQL/postgres.update.sql b/SQL/postgres.update.sql new file mode 100644 index 000000000..6ca855edc --- /dev/null +++ b/SQL/postgres.update.sql @@ -0,0 +1,7 @@ +-- RoundCube Webmail update script for Postres databases +-- Updates from version 0.1-beta and older + +ALTER TABLE "messages" DROP body; +ALTER TABLE "messages" ADD structure TEXT; +ALTER TABLE "messages" ADD UNIQUE (cache_key, uid); + diff --git a/SQL/sqlite.initial.sql b/SQL/sqlite.initial.sql index ae16a31d8..4ddc40d5d 100644 --- a/SQL/sqlite.initial.sql +++ b/SQL/sqlite.initial.sql @@ -1,5 +1,5 @@ -- RoundCube Webmail initial database structure --- Version 0.1a +-- Version 0.1-beta2 -- -- -------------------------------------------------------- @@ -118,7 +118,7 @@ CREATE TABLE messages ( date datetime NOT NULL default '0000-00-00 00:00:00', size integer NOT NULL default '0', headers text NOT NULL, - body text + structure text ); CREATE INDEX ix_messages_user_id ON messages(user_id); diff --git a/SQL/sqlite.update.sql b/SQL/sqlite.update.sql new file mode 100644 index 000000000..e725729ad --- /dev/null +++ b/SQL/sqlite.update.sql @@ -0,0 +1,27 @@ +-- RoundCube Webmail update script for SQLite databases +-- Updates from version 0.1-beta2 and older + +DROP TABLE messages; + +CREATE TABLE messages ( + message_id integer NOT NULL PRIMARY KEY, + user_id integer NOT NULL default '0', + del tinyint NOT NULL default '0', + cache_key varchar(128) NOT NULL default '', + created datetime NOT NULL default '0000-00-00 00:00:00', + idx integer NOT NULL default '0', + uid integer NOT NULL default '0', + subject varchar(255) NOT NULL default '', + "from" varchar(255) NOT NULL default '', + "to" varchar(255) NOT NULL default '', + cc varchar(255) NOT NULL default '', + date datetime NOT NULL default '0000-00-00 00:00:00', + size integer NOT NULL default '0', + headers text NOT NULL, + structure text +); + +CREATE INDEX ix_messages_user_id ON messages(user_id); +CREATE INDEX ix_messages_cache_key ON messages(cache_key); +CREATE INDEX ix_messages_idx ON messages(idx); +CREATE INDEX ix_messages_uid ON messages(uid); @@ -5,64 +5,72 @@ Follow these instructions if upgrading from a previous version of RoundCube Webmail. -from versions 0.1-alpha and 0.1-20050811 +from version 1.0-beta2 ---------------------------------------- -- replace index.php -- replace all files in folder /program/ -- replace all files in folder /skins/default/ -- run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql -- add these line to /config/main.inc.php - $rcmail_config['trash_mbox'] = 'Trash'; - $rcmail_config['default_imap_folders'] = array('INBOX', 'Drafts', 'Sent', 'Junk', 'Trash'); - $rcmail_config['prefer_html'] = TRUE; - $rcmail_config['prettydate'] = TRUE; - $rcmail_config['smtp_port'] = 25; - $rcmail_config['default_port'] = 143; - $rcmail_config['session_lifetime'] = 20; - $rcmail_config['skip_deleted'] = FALSE; - $rcmail_config['message_sort_col'] = 'date'; - $rcmail_config['message_sort_order'] = 'DESC'; - $rcmail_config['log_dir'] = 'logs/'; - $rcmail_config['temp_dir'] = 'temp/'; - $rcmail_config['message_cache_lifetime'] = '10d'; -- replace database properties (db_type, db_host, db_user, db_pass, $d_name) - in /config/db.inc.php with the following line: - $rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail'; -- add these lines to /config/db.inc.php - $rcmail_config['db_max_length'] = 512000; +* replace index.php +* replace all files in folder /program/ +* replace all files in folder /skins/default/ +* run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql -from version 0.1-20050820 + +form version 0.1-beta ---------------------------------------- -- replace index.php -- replace all files in folder /program/ -- replace all files in folder /skins/default/ -- run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql -- add these line to /config/main.inc.php - $rcmail_config['prettydate'] = TRUE; - $rcmail_config['smtp_port'] = 25; - $rcmail_config['default_port'] = 143; - $rcmail_config['session_lifetime'] = 20; +* replace index.php +* replace all files in folder /program/ +* replace all files in folder /skins/default/ +* run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql +* add these line to /config/db.inc.php + $rcmail_config['db_persistent'] = TRUE; +* add these lines to /config/main.inc.php + $rcmail_config['drafts_mbox'] = 'Drafts'; + $rcmail_config['junk_mbox'] = 'Junk'; + $rcmail_config['product_name'] = 'RoundCube Webmail'; + $rcmail_config['read_when_deleted'] = TRUE; + $rcmail_config['enable_spellcheck'] = TRUE; + $rcmail_config['protect_default_folders'] = TRUE; +* replace the following line from /config/main.inc.php + @include($_SERVER['HTTP_HOST'].'.inc.php'); + with + $rcmail_config['include_host_config'] = TRUE; + + + +from version 0.1-20051021 +---------------------------------------- +* replace index.php +* replace all files in folder /program/ +* replace all files in folder /skins/default/ +* run all commands in SQL/*.update-0.1a.sql or re-initalize database with *.initial.sql +* add these lines to /config/main.inc.php $rcmail_config['skip_deleted'] = FALSE; $rcmail_config['message_sort_col'] = 'date'; $rcmail_config['message_sort_order'] = 'DESC'; $rcmail_config['log_dir'] = 'logs/'; $rcmail_config['temp_dir'] = 'temp/'; $rcmail_config['message_cache_lifetime'] = '10d'; -- replace database properties (db_type, db_host, db_user, db_pass, $d_name) - in /config/db.inc.php with the following line: - $rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail'; -- add these lines to /config/db.inc.php + $rcmail_config['drafts_mbox'] = 'Drafts'; + $rcmail_config['product_name'] = 'RoundCube Webmail'; + $rcmail_config['read_when_deleted'] = TRUE; + $rcmail_config['enable_spellcheck'] = TRUE; +* add these lines to /config/db.inc.php $rcmail_config['db_max_length'] = 512000; + $rcmail_config['db_sequence_user_ids'] = 'user_ids'; + $rcmail_config['db_sequence_identity_ids'] = 'identity_ids'; + $rcmail_config['db_sequence_contact_ids'] = 'contact_ids'; + $rcmail_config['db_sequence_cache_ids'] = 'cache_ids'; + $rcmail_config['db_sequence_message_ids'] = 'message_ids'; + $rcmail_config['db_persistent'] = TRUE; + from version 0.1-20051007 ---------------------------------------- -- replace index.php -- replace all files in folder /program/ -- replace all files in folder /skins/default/ -- run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql -- add these lines to /config/main.inc.php +* replace index.php +* replace all files in folder /program/ +* replace all files in folder /skins/default/ +* run all commands in SQL/*.update-0.1a.sql or re-initalize database with *.initial.sql +* add these lines to /config/main.inc.php $rcmail_config['smtp_auth_type'] = ''; // if you need to specify an auth method for SMTP $rcmail_config['session_lifetime'] = 20; // to specify the session lifetime in minutes $rcmail_config['skip_deleted'] = FALSE; @@ -75,7 +83,7 @@ from version 0.1-20051007 $rcmail_config['product_name'] = 'RoundCube Webmail'; $rcmail_config['read_when_deleted'] = TRUE; $rcmail_config['enable_spellcheck'] = TRUE; -- add these lines to /config/db.inc.php +* add these lines to /config/db.inc.php $rcmail_config['db_max_length'] = 512000; $rcmail_config['db_sequence_user_ids'] = 'user_ids'; $rcmail_config['db_sequence_identity_ids'] = 'identity_ids'; @@ -84,50 +92,56 @@ from version 0.1-20051007 $rcmail_config['db_sequence_message_ids'] = 'message_ids'; $rcmail_config['db_persistent'] = TRUE; -from version 0.1-20051021 + + +from version 0.1-20050820 ---------------------------------------- -- replace index.php -- replace all files in folder /program/ -- replace all files in folder /skins/default/ -- run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql -- add these lines to /config/main.inc.php +* replace index.php +* replace all files in folder /program/ +* replace all files in folder /skins/default/ +* run all commands in SQL/*.update-0.1a.sql or re-initalize database with *.initial.sql +* add these line to /config/main.inc.php + $rcmail_config['prettydate'] = TRUE; + $rcmail_config['smtp_port'] = 25; + $rcmail_config['default_port'] = 143; + $rcmail_config['session_lifetime'] = 20; $rcmail_config['skip_deleted'] = FALSE; $rcmail_config['message_sort_col'] = 'date'; $rcmail_config['message_sort_order'] = 'DESC'; $rcmail_config['log_dir'] = 'logs/'; $rcmail_config['temp_dir'] = 'temp/'; $rcmail_config['message_cache_lifetime'] = '10d'; - $rcmail_config['drafts_mbox'] = 'Drafts'; - $rcmail_config['product_name'] = 'RoundCube Webmail'; - $rcmail_config['read_when_deleted'] = TRUE; - $rcmail_config['enable_spellcheck'] = TRUE; -- add these lines to /config/db.inc.php +* replace database properties (db_type, db_host, db_user, db_pass, $d_name) + in /config/db.inc.php with the following line: + $rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail'; +* add these lines to /config/db.inc.php $rcmail_config['db_max_length'] = 512000; - $rcmail_config['db_sequence_user_ids'] = 'user_ids'; - $rcmail_config['db_sequence_identity_ids'] = 'identity_ids'; - $rcmail_config['db_sequence_contact_ids'] = 'contact_ids'; - $rcmail_config['db_sequence_cache_ids'] = 'cache_ids'; - $rcmail_config['db_sequence_message_ids'] = 'message_ids'; - $rcmail_config['db_persistent'] = TRUE; - - -form version 0.1-beta + + + +from versions 0.1-alpha and 0.1-20050811 ---------------------------------------- -- replace index.php -- replace all files in folder /program/ -- replace all files in folder /skins/default/ -- add these line to /config/db.inc.php - $rcmail_config['db_persistent'] = TRUE; -- add these lines to /config/main.inc.php - $rcmail_config['drafts_mbox'] = 'Drafts'; - $rcmail_config['junk_mbox'] = 'Junk'; - $rcmail_config['product_name'] = 'RoundCube Webmail'; - $rcmail_config['read_when_deleted'] = TRUE; - $rcmail_config['enable_spellcheck'] = TRUE; - $rcmail_config['protect_default_folders'] = TRUE; -- replace the following line from /config/main.inc.php - @include($_SERVER['HTTP_HOST'].'.inc.php'); - with - $rcmail_config['include_host_config'] = TRUE; - - +* replace index.php +* replace all files in folder /program/ +* replace all files in folder /skins/default/ +* run all commands in SQL/*.update-0.1a.sql or re-initalize database with *.initial.sql +* add these line to /config/main.inc.php + $rcmail_config['trash_mbox'] = 'Trash'; + $rcmail_config['default_imap_folders'] = array('INBOX', 'Drafts', 'Sent', 'Junk', 'Trash'); + $rcmail_config['prefer_html'] = TRUE; + $rcmail_config['prettydate'] = TRUE; + $rcmail_config['smtp_port'] = 25; + $rcmail_config['default_port'] = 143; + $rcmail_config['session_lifetime'] = 20; + $rcmail_config['skip_deleted'] = FALSE; + $rcmail_config['message_sort_col'] = 'date'; + $rcmail_config['message_sort_order'] = 'DESC'; + $rcmail_config['log_dir'] = 'logs/'; + $rcmail_config['temp_dir'] = 'temp/'; + $rcmail_config['message_cache_lifetime'] = '10d'; +* replace database properties (db_type, db_host, db_user, db_pass, $d_name) + in /config/db.inc.php with the following line: + $rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail'; +* add these lines to /config/db.inc.php + $rcmail_config['db_max_length'] = 512000; + diff --git a/program/include/rcube_imap.inc b/program/include/rcube_imap.inc index fe97a92f2..dbb00a5cf 100644 --- a/program/include/rcube_imap.inc +++ b/program/include/rcube_imap.inc @@ -35,7 +35,7 @@ require_once('lib/mime.inc'); * * @package RoundCube Webmail * @author Thomas Bruederli <roundcube@gmail.com> - * @version 1.31 + * @version 1.34 * @link http://ilohamail.org */ class rcube_imap @@ -132,11 +132,10 @@ class rcube_imap 'message' => $GLOBALS['iil_error']), TRUE, FALSE); } - // get account namespace + // get server properties if ($this->conn) { $this->_parse_capability($this->conn->capability); - iil_C_NameSpace($this->conn); if (!empty($this->conn->delimiter)) $this->delimiter = $this->conn->delimiter; @@ -883,15 +882,19 @@ class rcube_imap $uid = $is_uid ? $id : $this->_id2uid($id); // get cached headers - if ($uid && ($headers = $this->get_cached_message($mailbox.'.msg', $uid))) + if ($uid && ($headers = &$this->get_cached_message($mailbox.'.msg', $uid))) return $headers; - $msg_id = $is_uid ? $this->_uid2id($id) : $id; - $headers = iil_C_FetchHeader($this->conn, $mailbox, $msg_id); + $headers = iil_C_FetchHeader($this->conn, $mailbox, $id, $is_uid); // write headers cache if ($headers) - $this->add_message_cache($mailbox.'.msg', $msg_id, $headers); + { + if ($is_uid) + $this->uid_id_map[$mbox_name][$uid] = $headers->id; + + $this->add_message_cache($mailbox.'.msg', $headers->id, $headers); + } return $headers; } @@ -906,6 +909,14 @@ class rcube_imap */ function &get_structure($uid) { + $cache_key = $this->mailbox.'.msg'; + $headers = &$this->get_cached_message($cache_key, $uid, true); + + // return cached message structure + if (is_object($headers) && is_object($headers->structure)) + return $headers->structure; + + // resolve message sequence number if (!($msg_id = $this->_uid2id($uid))) return FALSE; @@ -929,6 +940,10 @@ class rcube_imap $struct->mimetype = strtolower($struct->headers['ctype']); list($struct->ctype_primary, $struct->ctype_secondary) = explode('/', $struct->mimetype); } + + // write structure to cache + if ($this->caching_enabled) + $this->add_message_cache($cache_key, $msg_id, $headers, $struct); } return $struct; @@ -1109,8 +1124,14 @@ class rcube_imap $body = $this->mime_decode($body, $o_part->encoding); // convert charset (if text or message part) - if (!empty($o_part->charset) && ($o_part->ctype_primary=='text' || $o_part->ctype_primary=='message') && !stristr($body, 'charset=')) + if ($o_part->ctype_primary=='text' || $o_part->ctype_primary=='message') + { + // assume ISO-8859-1 if no charset specified + if (empty($o_part->charset)) + $o_part->charset = 'ISO-8859-1'; + $body = rcube_charset_convert($body, $o_part->charset); + } } return $body; @@ -1533,6 +1554,14 @@ class rcube_imap // make absolute path $mailbox = $this->_mod_mailbox($mbox_name); $abs_name = $this->_mod_mailbox($name); + + // check if mailbox is subscribed + $a_subscribed = $this->_list_mailboxes(); + $subscribed = in_array($mailbox, $a_subscribed); + + // unsubscribe folder + if ($subscribed) + iil_C_UnSubscribe($this->conn, $mailbox); if (strlen($abs_name)) $result = iil_C_RenameFolder($this->conn, $mailbox, $abs_name); @@ -1541,11 +1570,12 @@ class rcube_imap if ($result) { $this->clear_message_cache($mailbox.'.msg'); - $this->clear_cache('mailboxes'); + $this->clear_cache('mailboxes'); } - + // try to subscribe it - $this->subscribe($name); + if ($result && $subscribed) + iil_C_Subscribe($this->conn, $abs_name); return $result ? $name : FALSE; } @@ -1842,18 +1872,16 @@ class rcube_imap } - function &get_cached_message($key, $uid, $body=FALSE) + function &get_cached_message($key, $uid, $struct=false) { if (!$this->caching_enabled) return FALSE; $internal_key = '__single_msg'; - if ($this->caching_enabled && (!isset($this->cache[$internal_key][$uid]) || $body)) + if ($this->caching_enabled && (!isset($this->cache[$internal_key][$uid]) || + ($struct && empty($this->cache[$internal_key][$uid]->structure)))) { - $sql_select = "idx, uid, headers"; - if ($body) - $sql_select .= ", body"; - + $sql_select = "idx, uid, headers" . ($struct ? ", structure" : ''); $sql_result = $this->db->query( "SELECT $sql_select FROM ".get_table_name('messages')." @@ -1863,14 +1891,12 @@ class rcube_imap $_SESSION['user_id'], $key, $uid); - + if ($sql_arr = $this->db->fetch_assoc($sql_result)) { - $headers = unserialize($sql_arr['headers']); - if (is_object($headers) && !empty($sql_arr['body'])) - $headers->body = $sql_arr['body']; - - $this->cache[$internal_key][$uid] = $headers; + $this->cache[$internal_key][$uid] = unserialize($sql_arr['headers']); + if (is_object($this->cache[$internal_key][$uid]) && !empty($sql_arr['structure'])) + $this->cache[$internal_key][$uid]->structure = unserialize($sql_arr['structure']); } } @@ -1906,25 +1932,55 @@ class rcube_imap } - function add_message_cache($key, $index, $headers) + function add_message_cache($key, $index, $headers, $struct=null) { - if (!$key || !is_object($headers) || empty($headers->uid)) + if (empty($key) || !is_object($headers) || empty($headers->uid)) return; + + // check for an existing record (probly headers are cached but structure not) + $sql_result = $this->db->query( + "SELECT message_id + FROM ".get_table_name('messages')." + WHERE user_id=? + AND cache_key=? + AND uid=? + AND del<>1", + $_SESSION['user_id'], + $key, + $headers->uid); - $this->db->query( - "INSERT INTO ".get_table_name('messages')." - (user_id, del, cache_key, created, idx, uid, subject, ".$this->db->quoteIdentifier('from').", ".$this->db->quoteIdentifier('to').", cc, date, size, headers) - VALUES (?, 0, ?, now(), ?, ?, ?, ?, ?, ?, ".$this->db->fromunixtime($headers->timestamp).", ?, ?)", - $_SESSION['user_id'], - $key, - $index, - $headers->uid, - (string)substr($this->decode_header($headers->subject, TRUE), 0, 128), - (string)substr($this->decode_header($headers->from, TRUE), 0, 128), - (string)substr($this->decode_header($headers->to, TRUE), 0, 128), - (string)substr($this->decode_header($headers->cc, TRUE), 0, 128), - (int)$headers->size, - serialize($headers)); + // update cache record + if ($sql_arr = $this->db->fetch_assoc($sql_result)) + { + $this->db->query( + "UPDATE ".get_table_name('messages')." + SET idx=?, headers=?, structure=? + WHERE message_id=?", + $index, + serialize($headers), + is_object($struct) ? serialize($struct) : NULL, + $sql_arr['message_id'] + ); + } + else // insert new record + { + $this->db->query( + "INSERT INTO ".get_table_name('messages')." + (user_id, del, cache_key, created, idx, uid, subject, ".$this->db->quoteIdentifier('from').", ".$this->db->quoteIdentifier('to').", cc, date, size, headers, structure) + VALUES (?, 0, ?, now(), ?, ?, ?, ?, ?, ?, ".$this->db->fromunixtime($headers->timestamp).", ?, ?, ?)", + $_SESSION['user_id'], + $key, + $index, + $headers->uid, + (string)substr($this->decode_header($headers->subject, TRUE), 0, 128), + (string)substr($this->decode_header($headers->from, TRUE), 0, 128), + (string)substr($this->decode_header($headers->to, TRUE), 0, 128), + (string)substr($this->decode_header($headers->cc, TRUE), 0, 128), + (int)$headers->size, + serialize($headers), + is_object($struct) ? serialize($struct) : NULL + ); + } } diff --git a/program/lib/imap.inc b/program/lib/imap.inc index 2c07f3409..b2e1d43c0 100644 --- a/program/lib/imap.inc +++ b/program/lib/imap.inc @@ -46,6 +46,7 @@ - Casting date parts in iil_StrToTime() to avoid mktime() warnings - Also acceppt LIST responses in iil_C_ListSubscribed() - Sanity check of $message_set in iil_C_FetchHeaders(), iil_C_FetchHeaderIndex(), iil_C_FetchThreadHeaders() + - Implemented UID FETCH in iil_C_FetchHeaders() - Removed some debuggers (echo ...) ********************************************************/ @@ -1195,7 +1196,7 @@ function iil_IndexThreads(&$tree){ return $t_index; } -function iil_C_FetchHeaders(&$conn, $mailbox, $message_set){ +function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false){ global $IMAP_USE_INTERNAL_DATE; $c=0; @@ -1231,7 +1232,8 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set){ /* FETCH date,from,subject headers */ $key="fh".($c++); - $request=$key." FETCH $message_set (BODY.PEEK[HEADER.FIELDS (DATE FROM TO SUBJECT REPLY-TO IN-REPLY-TO CC BCC CONTENT-TRANSFER-ENCODING CONTENT-TYPE MESSAGE-ID REFERENCE)])\r\n"; + $prefix=$uidfetch?" UID":""; + $request=$key.$prefix." FETCH $message_set (BODY.PEEK[HEADER.FIELDS (DATE FROM TO SUBJECT REPLY-TO IN-REPLY-TO CC BCC CONTENT-TRANSFER-ENCODING CONTENT-TYPE MESSAGE-ID REFERENCE)])\r\n"; if (!fputs($fp, $request)) return false; do{ @@ -1309,7 +1311,7 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set){ Sample reply line: "* 3 FETCH (UID 2417 RFC822.SIZE 2730 FLAGS (\Seen \Deleted))" */ $command_key="fh".($c++); - $request= $command_key." FETCH $message_set (UID RFC822.SIZE FLAGS INTERNALDATE)\r\n"; + $request= $command_key.$prefix." FETCH $message_set (UID RFC822.SIZE FLAGS INTERNALDATE)\r\n"; if (!fputs($fp, $request)) return false; do{ $line=chop(iil_ReadLine($fp, 200)); @@ -1401,10 +1403,10 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set){ } -function iil_C_FetchHeader(&$conn, $mailbox, $id){ +function iil_C_FetchHeader(&$conn, $mailbox, $id, $uidfetch=false){ $fp = $conn->fp; - $a=iil_C_FetchHeaders($conn, $mailbox, $id); - if (is_array($a)) return $a[$id]; + $a=iil_C_FetchHeaders($conn, $mailbox, $id, $uidfetch); + if (is_array($a)) return array_shift($a); else return false; } diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index cbe455934..a2f2e07c2 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -671,6 +671,9 @@ function rcmail_print_body($part, $safe=FALSE, $plain=FALSE) // text/html if ($part->ctype_secondary=='html') { + // remove charset specification in HTML message + $body = preg_replace('/charset=[a-z0-9\-]+/i', '', $body); + if (!$safe) // remove remote images and scripts { $remote_patterns = array('/(src|background)=(["\']?)([hftps]{3,5}:\/{2}[^"\'\s]+)(\2|\s|>)/Ui', @@ -1247,94 +1250,6 @@ function rcmail_first_text_part($message_struct) } -// get source code of a specific message and cache it -// deprecated -function rcmail_message_source($uid) - { - global $IMAP, $DB, $CONFIG; - - // get message ID if uid is given - $cache_key = $IMAP->mailbox.'.msg'; - $cached = $IMAP->get_cached_message($cache_key, $uid, FALSE); - - // message is cached in database - if ($cached && !empty($cached->body)) - return $cached->body; - - if (!$cached) - $headers = $IMAP->get_headers($uid); - else - $headers = &$cached; - - // create unique identifier based on message_id - if (!empty($headers->messageID)) - $message_id = md5($headers->messageID); - else - $message_id = md5($headers->uid.'@'.$_SESSION['imap_host']); - - $temp_dir = $CONFIG['temp_dir'].(!eregi('\/$', $CONFIG['temp_dir']) ? '/' : ''); - $cache_dir = $temp_dir.$_SESSION['client_id']; - $cache_path = $cache_dir.'/'.$message_id; - - // message is cached in temp dir - if ($CONFIG['enable_caching'] && is_dir($cache_dir) && is_file($cache_path)) - { - if ($fp = fopen($cache_path, 'r')) - { - $msg_source = fread($fp, filesize($cache_path)); - fclose($fp); - return $msg_source; - } - } - - - // get message from server - $msg_source = $IMAP->get_raw_body($uid); - - // return message source without caching - if (!$CONFIG['enable_caching']) - return $msg_source; - - - // let's cache the message body within the database - if ($cached && ($CONFIG['db_max_length'] -300) > $headers->size) - { - $DB->query("UPDATE ".get_table_name('messages')." - SET body=? - WHERE user_id=? - AND cache_key=? - AND uid=?", - $msg_source, - $_SESSION['user_id'], - $cache_key, - $uid); - - return $msg_source; - } - - - // create dir for caching - if (!is_dir($cache_dir)) - $dir = mkdir($cache_dir); - else - $dir = true; - - // attempt to write a file with the message body - if ($dir && ($fp = fopen($cache_path, 'w'))) - { - fwrite($fp, $msg_source); - fclose($fp); - } - else - { - raise_error(array('code' => 403, 'type' => 'php', 'line' => __LINE__, 'file' => __FILE__, - 'message' => "Failed to write to temp dir"), TRUE, FALSE); - } - - return $msg_source; - } - - // decode address string and re-format it as HTML links function rcmail_address_string($input, $max=NULL, $addicon=NULL) { @@ -1412,7 +1327,7 @@ function rcmail_message_part_controls() { $out .= sprintf('<tr><td class="title">%s</td><td>%s</td><td>[<a href="./?%s">%s</a>]</tr>'."\n", rcube_label('filename'), - rep_specialchars_output($filename), + rep_specialchars_output(rcube_imap::decode_mime_string($filename)), str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING']), rcube_label('download')); } diff --git a/program/steps/mail/get.inc b/program/steps/mail/get.inc index ded6a0022..f05bbbd94 100644 --- a/program/steps/mail/get.inc +++ b/program/steps/mail/get.inc @@ -69,12 +69,12 @@ else if ($pid = get_input_value('_part', RCUBE_INPUT_GET)) // send download headers header("Content-Type: application/octet-stream"); header(sprintf('Content-Disposition: attachment; filename="%s"', - $filename ? $filename : "roundcube.$ctype_secondary")); + $filename ? rcube_imap::decode_mime_string($filename) : "roundcube.$ctype_secondary")); } else { header("Content-Type: $mimetype"); - header(sprintf('Content-Disposition: inline; filename="%s"', $filename)); + header(sprintf('Content-Disposition: inline; filename="%s"', rcube_imap::decode_mime_string($filename))); } // We need to set the following headers to make downloads work using IE in HTTPS mode. @@ -89,14 +89,15 @@ else if ($pid = get_input_value('_part', RCUBE_INPUT_GET)) { // get part body if not available if (!$part->body) - $part->body = $IMAP->get_message_part($MESSAGE['UID'], $part->mime_id, $part); + $part->body = $IMAP->get_message_part($MESSAGE['UID'], $part->mime_id, $part); list($MESSAGE['parts']) = rcmail_parse_message($part, array('safe' => (bool)$_GET['_safe'], 'prefer_html' => TRUE, 'get_url' => $GET_URL.'&_part=%s')); - print rcmail_print_body($MESSAGE['parts'][0], (bool)$_GET['_safe']); + $OUTPUT = new rcube_html_page(); + $OUTPUT->write(rcmail_print_body($MESSAGE['parts'][0], (bool)$_GET['_safe'])); } else { |