From f7bfec96be8bf095ffc0af64a761f3866d5947b9 Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Fri, 25 Aug 2006 07:51:11 -0400
Subject: [PATCH] Finalized new message parsing. Attention: changes in database schema

---
 CHANGELOG                      |    8 
 INSTALL                        |    4 
 SQL/mysql5.initial.sql         |   18 
 SQL/mysql.update-0.1a.sql      |   51 ++++
 program/lib/imap.inc           |   14 
 SQL/mysql.update.sql           |   60 ----
 UPGRADING                      |  228 ++++++++++--------
 SQL/sqlite.initial.sql         |    4 
 SQL/sqlite.update.sql          |   27 ++
 program/steps/mail/func.inc    |   93 -------
 SQL/postgres.update.sql        |    7 
 program/steps/mail/get.inc     |    9 
 SQL/postgres.initial.sql       |    3 
 SQL/mysql.initial.sql          |    8 
 program/include/rcube_imap.inc |  134 +++++++---
 15 files changed, 351 insertions(+), 317 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index bcb50d8..29c425c 100644
--- a/CHANGELOG
+++ b/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
 
 
diff --git a/INSTALL b/INSTALL
index 0c7e7cb..c5f1d30 100644
--- a/INSTALL
+++ b/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
diff --git a/SQL/mysql.initial.sql b/SQL/mysql.initial.sql
index 7546e52..716268b 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 @@
   `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 0000000..054814a
--- /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 7fa296b..cfd5af3 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 0116468..24e1431 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 @@
  `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',
diff --git a/SQL/postgres.initial.sql b/SQL/postgres.initial.sql
index 55e1396..029afaa 100755
--- a/SQL/postgres.initial.sql
+++ b/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);
diff --git a/SQL/postgres.update.sql b/SQL/postgres.update.sql
new file mode 100644
index 0000000..6ca855e
--- /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 ae16a31..4ddc40d 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 @@
   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 0000000..e725729
--- /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);
diff --git a/UPGRADING b/UPGRADING
index bb8b36b..b274373 100644
--- a/UPGRADING
+++ b/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;
-  
-  
diff --git a/program/include/rcube_imap.inc b/program/include/rcube_imap.inc
index fe97a92..dbb00a5 100644
--- a/program/include/rcube_imap.inc
+++ b/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
+        );
+      }
     }
     
     
diff --git a/program/lib/imap.inc b/program/lib/imap.inc
index 2c07f34..b2e1d43 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 @@
 	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;
 }
 
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index cbe4559..a2f2e07 100644
--- a/program/steps/mail/func.inc
+++ b/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'));
     }
diff --git a/program/steps/mail/get.inc b/program/steps/mail/get.inc
index ded6a00..f05bbbd 100644
--- a/program/steps/mail/get.inc
+++ b/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
       {

--
Gitblit v1.9.1