thomascube
2006-08-25 f7bfec96be8bf095ffc0af64a761f3866d5947b9
Finalized new message parsing. Attention: changes in database schema

3 files added
12 files modified
668 ■■■■ changed files
CHANGELOG 8 ●●●●● patch | view | raw | blame | history
INSTALL 4 ●●●● patch | view | raw | blame | history
SQL/mysql.initial.sql 8 ●●●● patch | view | raw | blame | history
SQL/mysql.update-0.1a.sql 51 ●●●●● patch | view | raw | blame | history
SQL/mysql.update.sql 60 ●●●● patch | view | raw | blame | history
SQL/mysql5.initial.sql 18 ●●●● patch | view | raw | blame | history
SQL/postgres.initial.sql 3 ●●●● patch | view | raw | blame | history
SQL/postgres.update.sql 7 ●●●●● patch | view | raw | blame | history
SQL/sqlite.initial.sql 4 ●●●● patch | view | raw | blame | history
SQL/sqlite.update.sql 27 ●●●●● patch | view | raw | blame | history
UPGRADING 228 ●●●● patch | view | raw | blame | history
program/include/rcube_imap.inc 134 ●●●● patch | view | raw | blame | history
program/lib/imap.inc 14 ●●●●● patch | view | raw | blame | history
program/steps/mail/func.inc 93 ●●●●● patch | view | raw | blame | history
program/steps/mail/get.inc 9 ●●●●● patch | view | raw | blame | history
CHANGELOG
@@ -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 @@
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
INSTALL
@@ -40,7 +40,7 @@
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 @@
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
SQL/mysql.initial.sql
@@ -1,5 +1,5 @@
-- RoundCube Webmail initial database structure
-- Version 0.1beta2
-- Version 0.1-beta2
-- 
-- --------------------------------------------------------
@@ -116,12 +116,12 @@
  `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`)
);
SQL/mysql.update-0.1a.sql
New file
@@ -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;
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` ;
SQL/mysql5.initial.sql
@@ -1,5 +1,5 @@
-- RoundCube Webmail initial database structure
-- Version 0.1beta2
-- Version 0.1-beta2
-- 
-- --------------------------------------------------------
@@ -16,7 +16,7 @@
 `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 @@
 `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 @@
 `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 `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',
SQL/postgres.initial.sql
@@ -163,6 +163,7 @@
    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);
SQL/postgres.update.sql
New file
@@ -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);
SQL/sqlite.initial.sql
@@ -1,5 +1,5 @@
-- RoundCube Webmail initial database structure
-- Version 0.1a
-- Version 0.1-beta2
-- 
-- --------------------------------------------------------
@@ -118,7 +118,7 @@
  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);
SQL/sqlite.update.sql
New file
@@ -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);
UPGRADING
@@ -5,13 +5,127 @@
of RoundCube Webmail.
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
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/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';
  $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-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;
  $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
  $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-20050820
----------------------------------------
* 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';
* 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;
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/
- run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql
- add these line 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['trash_mbox'] = 'Trash';
  $rcmail_config['default_imap_folders'] = array('INBOX', 'Drafts', 'Sent', 'Junk', 'Trash');
  $rcmail_config['prefer_html'] = TRUE;
@@ -25,109 +139,9 @@
  $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)
* 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
* add these lines to /config/db.inc.php
  $rcmail_config['db_max_length'] = 512000;
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 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';
- 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;
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
  $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;
  $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
  $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-20051021
----------------------------------------
- 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
  $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
  $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
----------------------------------------
- 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;
program/include/rcube_imap.inc
@@ -35,7 +35,7 @@
 *
 * @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 @@
                       '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 @@
    $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 @@
   */
  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 @@
        $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 @@
        $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 @@
    // 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 @@
    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 @@
    }
  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 @@
        $_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 @@
    }
  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
        );
      }
    }
    
    
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 @@
    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 @@
    /* 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 @@
        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_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;
}
program/steps/mail/func.inc
@@ -671,6 +671,9 @@
  // 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 @@
  }
// 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 @@
    {
    $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'));
    }
program/steps/mail/get.inc
@@ -69,12 +69,12 @@
      // 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 @@
      {
      // 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
      {