# HG changeset patch
# User Charlie Root
# Date 1515099151 18000
# Node ID 4681f974d28b39c72857f7975bd431961906bbee
vanilla 1.3.3 distro, I hope
diff -r 000000000000 -r 4681f974d28b .htaccess
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/.htaccess Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,59 @@
+# AddDefaultCharset UTF-8
+AddType text/x-component .htc
+
+
+php_flag display_errors Off
+php_flag log_errors On
+# php_value error_log logs/errors
+
+php_value upload_max_filesize 5M
+php_value post_max_size 6M
+php_value memory_limit 64M
+
+php_flag register_globals Off
+php_flag zlib.output_compression Off
+php_flag magic_quotes_gpc Off
+php_flag magic_quotes_runtime Off
+php_flag suhosin.session.encrypt Off
+
+#php_value session.cookie_path /
+php_flag session.auto_start Off
+php_value session.gc_maxlifetime 21600
+php_value session.gc_divisor 500
+php_value session.gc_probability 1
+
+
+
+Options +FollowSymLinks
+RewriteEngine On
+RewriteRule ^favicon\.ico$ skins/larry/images/favicon.ico
+
+# security rules:
+# - deny access to files not containing a dot or starting with a dot
+# in all locations except installer directory
+RewriteRule ^(?!installer|\.well-known\/|[a-f0-9]{16})(\.?[^\.]+)$ - [F]
+# - deny access to some locations
+RewriteRule ^/?(\.git|\.tx|SQL|bin|config|logs|temp|tests|program\/(include|lib|localization|steps)) - [F]
+# - deny access to some documentation files
+RewriteRule /?(README\.md|composer\.json-dist|composer\.json|package\.xml|Dockerfile)$ - [F]
+
+
+
+SetOutputFilter DEFLATE
+
+
+
+# replace 'append' with 'merge' for Apache version 2.2.9 and later
+#Header append Cache-Control public env=!NO_CACHE
+
+
+
+ExpiresActive On
+ExpiresDefault "access plus 1 month"
+
+
+FileETag MTime Size
+
+
+Options -Indexes
+
diff -r 000000000000 -r 4681f974d28b SQL/mssql.initial.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql.initial.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,398 @@
+CREATE TABLE [dbo].[cache] (
+ [user_id] [int] NOT NULL ,
+ [cache_key] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [created] [datetime] NOT NULL ,
+ [expires] [datetime] NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[cache_shared] (
+ [cache_key] [varchar] (255) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [created] [datetime] NOT NULL ,
+ [expires] [datetime] NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[cache_index] (
+ [user_id] [int] NOT NULL ,
+ [mailbox] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [expires] [datetime] NULL ,
+ [valid] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[cache_thread] (
+ [user_id] [int] NOT NULL ,
+ [mailbox] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [expires] [datetime] NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[cache_messages] (
+ [user_id] [int] NOT NULL ,
+ [mailbox] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [uid] [int] NOT NULL ,
+ [expires] [datetime] NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL ,
+ [flags] [int] NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[contacts] (
+ [contact_id] [int] IDENTITY (1, 1) NOT NULL ,
+ [user_id] [int] NOT NULL ,
+ [changed] [datetime] NOT NULL ,
+ [del] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [name] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [email] [varchar] (8000) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [firstname] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [surname] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [vcard] [text] COLLATE Latin1_General_CI_AI NULL ,
+ [words] [text] COLLATE Latin1_General_CI_AI NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[contactgroups] (
+ [contactgroup_id] [int] IDENTITY (1, 1) NOT NULL ,
+ [user_id] [int] NOT NULL ,
+ [changed] [datetime] NOT NULL ,
+ [del] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [name] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[contactgroupmembers] (
+ [contactgroup_id] [int] NOT NULL ,
+ [contact_id] [int] NOT NULL ,
+ [created] [datetime] NOT NULL
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[identities] (
+ [identity_id] [int] IDENTITY (1, 1) NOT NULL ,
+ [user_id] [int] NOT NULL ,
+ [changed] [datetime] NOT NULL ,
+ [del] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [standard] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [name] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [organization] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [email] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [reply-to] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [bcc] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [signature] [text] COLLATE Latin1_General_CI_AI NULL,
+ [html_signature] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[session] (
+ [sess_id] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [created] [datetime] NOT NULL ,
+ [changed] [datetime] NULL ,
+ [ip] [varchar] (40) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [vars] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[users] (
+ [user_id] [int] IDENTITY (1, 1) NOT NULL ,
+ [username] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [mail_host] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [created] [datetime] NOT NULL ,
+ [last_login] [datetime] NULL ,
+ [language] [varchar] (5) COLLATE Latin1_General_CI_AI NULL ,
+ [preferences] [text] COLLATE Latin1_General_CI_AI NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[dictionary] (
+ [user_id] [int] ,
+ [language] [varchar] (5) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[searches] (
+ [search_id] [int] IDENTITY (1, 1) NOT NULL ,
+ [user_id] [int] NOT NULL ,
+ [type] [tinyint] NOT NULL ,
+ [name] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[system] (
+ [name] [varchar] (64) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [value] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[cache_index] WITH NOCHECK ADD
+ PRIMARY KEY CLUSTERED
+ (
+ [user_id],[mailbox]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[cache_thread] WITH NOCHECK ADD
+ PRIMARY KEY CLUSTERED
+ (
+ [user_id],[mailbox]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[cache_messages] WITH NOCHECK ADD
+ PRIMARY KEY CLUSTERED
+ (
+ [user_id],[mailbox],[uid]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[contacts] WITH NOCHECK ADD
+ CONSTRAINT [PK_contacts_contact_id] PRIMARY KEY CLUSTERED
+ (
+ [contact_id]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[contactgroups] WITH NOCHECK ADD
+ CONSTRAINT [PK_contactgroups_contactgroup_id] PRIMARY KEY CLUSTERED
+ (
+ [contactgroup_id]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[contactgroupmembers] WITH NOCHECK ADD
+ CONSTRAINT [PK_contactgroupmembers_id] PRIMARY KEY CLUSTERED
+ (
+ [contactgroup_id], [contact_id]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[identities] WITH NOCHECK ADD
+ PRIMARY KEY CLUSTERED
+ (
+ [identity_id]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[session] WITH NOCHECK ADD
+ CONSTRAINT [PK_session_sess_id] PRIMARY KEY CLUSTERED
+ (
+ [sess_id]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[users] WITH NOCHECK ADD
+ CONSTRAINT [PK_users_user_id] PRIMARY KEY CLUSTERED
+ (
+ [user_id]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[searches] WITH NOCHECK ADD
+ CONSTRAINT [PK_searches_search_id] PRIMARY KEY CLUSTERED
+ (
+ [search_id]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[system] WITH NOCHECK ADD
+ CONSTRAINT [PK_system_name] PRIMARY KEY CLUSTERED
+ (
+ [name]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[cache] ADD
+ CONSTRAINT [DF_cache_user_id] DEFAULT ('0') FOR [user_id],
+ CONSTRAINT [DF_cache_cache_key] DEFAULT ('') FOR [cache_key],
+ CONSTRAINT [DF_cache_created] DEFAULT (getdate()) FOR [created]
+GO
+
+ALTER TABLE [dbo].[cache_shared] ADD
+ CONSTRAINT [DF_cache_shared_created] DEFAULT (getdate()) FOR [created]
+GO
+
+ALTER TABLE [dbo].[cache_index] ADD
+ CONSTRAINT [DF_cache_index_valid] DEFAULT ('0') FOR [valid]
+GO
+
+ALTER TABLE [dbo].[cache_messages] ADD
+ CONSTRAINT [DF_cache_messages_flags] DEFAULT (0) FOR [flags]
+GO
+
+CREATE INDEX [IX_cache_user_id] ON [dbo].[cache]([user_id]) ON [PRIMARY]
+GO
+
+CREATE INDEX [IX_cache_cache_key] ON [dbo].[cache]([cache_key]) ON [PRIMARY]
+GO
+
+CREATE INDEX [IX_cache_shared_cache_key] ON [dbo].[cache_shared]([cache_key]) ON [PRIMARY]
+GO
+
+CREATE INDEX [IX_cache_index_user_id] ON [dbo].[cache_index]([user_id]) ON [PRIMARY]
+GO
+
+CREATE INDEX [IX_cache_thread_user_id] ON [dbo].[cache_thread]([user_id]) ON [PRIMARY]
+GO
+
+CREATE INDEX [IX_cache_messages_user_id] ON [dbo].[cache_messages]([user_id]) ON [PRIMARY]
+GO
+
+CREATE INDEX [IX_cache_expires] ON [dbo].[cache]([expires]) ON [PRIMARY]
+GO
+
+CREATE INDEX [IX_cache_shared_expires] ON [dbo].[cache_shared]([expires]) ON [PRIMARY]
+GO
+
+CREATE INDEX [IX_cache_index_expires] ON [dbo].[cache_index]([expires]) ON [PRIMARY]
+GO
+
+CREATE INDEX [IX_cache_thread_expires] ON [dbo].[cache_thread]([expires]) ON [PRIMARY]
+GO
+
+CREATE INDEX [IX_cache_messages_expires] ON [dbo].[cache_messages]([expires]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[contacts] ADD
+ CONSTRAINT [DF_contacts_user_id] DEFAULT (0) FOR [user_id],
+ CONSTRAINT [DF_contacts_changed] DEFAULT (getdate()) FOR [changed],
+ CONSTRAINT [DF_contacts_del] DEFAULT ('0') FOR [del],
+ CONSTRAINT [DF_contacts_name] DEFAULT ('') FOR [name],
+ CONSTRAINT [DF_contacts_email] DEFAULT ('') FOR [email],
+ CONSTRAINT [DF_contacts_firstname] DEFAULT ('') FOR [firstname],
+ CONSTRAINT [DF_contacts_surname] DEFAULT ('') FOR [surname],
+ CONSTRAINT [CK_contacts_del] CHECK ([del] = '1' or [del] = '0')
+GO
+
+CREATE INDEX [IX_contacts_user_id] ON [dbo].[contacts]([user_id]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[contactgroups] ADD
+ CONSTRAINT [DF_contactgroups_user_id] DEFAULT (0) FOR [user_id],
+ CONSTRAINT [DF_contactgroups_changed] DEFAULT (getdate()) FOR [changed],
+ CONSTRAINT [DF_contactgroups_del] DEFAULT ('0') FOR [del],
+ CONSTRAINT [DF_contactgroups_name] DEFAULT ('') FOR [name],
+ CONSTRAINT [CK_contactgroups_del] CHECK ([del] = '1' or [del] = '0')
+GO
+
+CREATE INDEX [IX_contactgroups_user_id] ON [dbo].[contactgroups]([user_id]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[contactgroupmembers] ADD
+ CONSTRAINT [DF_contactgroupmembers_contactgroup_id] DEFAULT (0) FOR [contactgroup_id],
+ CONSTRAINT [DF_contactgroupmembers_contact_id] DEFAULT (0) FOR [contact_id],
+ CONSTRAINT [DF_contactgroupmembers_created] DEFAULT (getdate()) FOR [created]
+GO
+
+CREATE INDEX [IX_contactgroupmembers_contact_id] ON [dbo].[contactgroupmembers]([contact_id]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[identities] ADD
+ CONSTRAINT [DF_identities_user] DEFAULT ('0') FOR [user_id],
+ CONSTRAINT [DF_identities_del] DEFAULT ('0') FOR [del],
+ CONSTRAINT [DF_identities_standard] DEFAULT ('0') FOR [standard],
+ CONSTRAINT [DF_identities_name] DEFAULT ('') FOR [name],
+ CONSTRAINT [DF_identities_organization] DEFAULT ('') FOR [organization],
+ CONSTRAINT [DF_identities_email] DEFAULT ('') FOR [email],
+ CONSTRAINT [DF_identities_reply] DEFAULT ('') FOR [reply-to],
+ CONSTRAINT [DF_identities_bcc] DEFAULT ('') FOR [bcc],
+ CONSTRAINT [DF_identities_html_signature] DEFAULT ('0') FOR [html_signature],
+ CHECK ([standard] = '1' or [standard] = '0'),
+ CHECK ([del] = '1' or [del] = '0')
+GO
+
+CREATE INDEX [IX_identities_user_id] ON [dbo].[identities]([user_id]) ON [PRIMARY]
+GO
+CREATE INDEX [IX_identities_email] ON [dbo].[identities]([email],[del]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[session] ADD
+ CONSTRAINT [DF_session_sess_id] DEFAULT ('') FOR [sess_id],
+ CONSTRAINT [DF_session_created] DEFAULT (getdate()) FOR [created],
+ CONSTRAINT [DF_session_ip] DEFAULT ('') FOR [ip]
+GO
+
+CREATE INDEX [IX_session_changed] ON [dbo].[session]([changed]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[users] ADD
+ CONSTRAINT [DF_users_username] DEFAULT ('') FOR [username],
+ CONSTRAINT [DF_users_mail_host] DEFAULT ('') FOR [mail_host],
+ CONSTRAINT [DF_users_created] DEFAULT (getdate()) FOR [created]
+GO
+
+CREATE UNIQUE INDEX [IX_users_username] ON [dbo].[users]([username],[mail_host]) ON [PRIMARY]
+GO
+
+CREATE UNIQUE INDEX [IX_dictionary_user_language] ON [dbo].[dictionary]([user_id],[language]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[searches] ADD
+ CONSTRAINT [DF_searches_user] DEFAULT (0) FOR [user_id],
+ CONSTRAINT [DF_searches_type] DEFAULT (0) FOR [type]
+GO
+
+CREATE UNIQUE INDEX [IX_searches_user_type_name] ON [dbo].[searches]([user_id],[type],[name]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[identities] ADD CONSTRAINT [FK_identities_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[contacts] ADD CONSTRAINT [FK_contacts_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[contactgroups] ADD CONSTRAINT [FK_contactgroups_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[cache] ADD CONSTRAINT [FK_cache_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[cache_index] ADD CONSTRAINT [FK_cache_index_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[cache_thread] ADD CONSTRAINT [FK_cache_thread_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[cache_messages] ADD CONSTRAINT [FK_cache_messages_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[contactgroupmembers] ADD CONSTRAINT [FK_contactgroupmembers_contactgroup_id]
+ FOREIGN KEY ([contactgroup_id]) REFERENCES [dbo].[contactgroups] ([contactgroup_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[searches] ADD CONSTRAINT [FK_searches_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+-- Use trigger instead of foreign key (#1487112)
+-- "Introducing FOREIGN KEY constraint ... may cause cycles or multiple cascade paths."
+CREATE TRIGGER [contact_delete_member] ON [dbo].[contacts]
+ AFTER DELETE AS
+ DELETE FROM [dbo].[contactgroupmembers]
+ WHERE [contact_id] IN (SELECT [contact_id] FROM deleted)
+GO
+
+INSERT INTO [dbo].[system] ([name], [value]) VALUES ('roundcube-version', '2015030800')
+GO
+
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2009103100.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2009103100.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,87 @@
+-- Updates from version 0.3.1
+
+ALTER TABLE [dbo].[messages] ADD CONSTRAINT [FK_messages_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[cache] ADD CONSTRAINT [FK_cache_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[contacts] ADD CONSTRAINT [FK_contacts_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[identities] ADD CONSTRAINT [FK_identities_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[identities] ADD [changed] [datetime] NULL
+GO
+
+CREATE TABLE [dbo].[contactgroups] (
+ [contactgroup_id] [int] IDENTITY (1, 1) NOT NULL ,
+ [user_id] [int] NOT NULL ,
+ [changed] [datetime] NOT NULL ,
+ [del] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [name] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[contactgroupmembers] (
+ [contactgroup_id] [int] NOT NULL ,
+ [contact_id] [int] NOT NULL ,
+ [created] [datetime] NOT NULL
+) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[contactgroups] WITH NOCHECK ADD
+ CONSTRAINT [PK_contactgroups_contactgroup_id] PRIMARY KEY CLUSTERED
+ (
+ [contactgroup_id]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[contactgroupmembers] WITH NOCHECK ADD
+ CONSTRAINT [PK_contactgroupmembers_id] PRIMARY KEY CLUSTERED
+ (
+ [contactgroup_id], [contact_id]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[contactgroups] ADD
+ CONSTRAINT [DF_contactgroups_user_id] DEFAULT (0) FOR [user_id],
+ CONSTRAINT [DF_contactgroups_changed] DEFAULT (getdate()) FOR [changed],
+ CONSTRAINT [DF_contactgroups_del] DEFAULT ('0') FOR [del],
+ CONSTRAINT [DF_contactgroups_name] DEFAULT ('') FOR [name],
+ CONSTRAINT [CK_contactgroups_del] CHECK ([del] = '1' or [del] = '0')
+GO
+
+CREATE INDEX [IX_contactgroups_user_id] ON [dbo].[contacts]([user_id]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[contactgroupmembers] ADD
+ CONSTRAINT [DF_contactgroupmembers_contactgroup_id] DEFAULT (0) FOR [contactgroup_id],
+ CONSTRAINT [DF_contactgroupmembers_contact_id] DEFAULT (0) FOR [contact_id],
+ CONSTRAINT [DF_contactgroupmembers_created] DEFAULT (getdate()) FOR [created]
+GO
+
+ALTER TABLE [dbo].[contactgroupmembers] ADD CONSTRAINT [FK_contactgroupmembers_contactgroup_id]
+ FOREIGN KEY ([contactgroup_id]) REFERENCES [dbo].[contactgroups] ([contactgroup_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+CREATE TRIGGER [contact_delete_member] ON [dbo].[contacts]
+ AFTER DELETE AS
+ DELETE FROM [dbo].[contactgroupmembers]
+ WHERE [contact_id] IN (SELECT [contact_id] FROM deleted)
+GO
+
+ALTER TABLE [dbo].[contactgroups] ADD CONSTRAINT [FK_contactgroups_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2010100600.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2010100600.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,9 @@
+-- Updates from version 0.4.2
+
+DROP INDEX [IX_users_username]
+GO
+CREATE UNIQUE INDEX [IX_users_username] ON [dbo].[users]([username],[mail_host]) ON [PRIMARY]
+GO
+ALTER TABLE [dbo].[contacts] ALTER COLUMN [email] [varchar] (255) COLLATE Latin1_General_CI_AI NOT NULL
+GO
+
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2011011200.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2011011200.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,10 @@
+-- Updates from version 0.5.x
+
+ALTER TABLE [dbo].[contacts] ADD [words] [text] COLLATE Latin1_General_CI_AI NULL
+GO
+CREATE INDEX [IX_contactgroupmembers_contact_id] ON [dbo].[contactgroupmembers]([contact_id]) ON [PRIMARY]
+GO
+DELETE FROM [dbo].[messages]
+GO
+DELETE FROM [dbo].[cache]
+GO
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2011092800.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2011092800.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,127 @@
+-- Updates from version 0.6
+
+CREATE TABLE [dbo].[dictionary] (
+ [user_id] [int] ,
+ [language] [varchar] (5) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+CREATE UNIQUE INDEX [IX_dictionary_user_language] ON [dbo].[dictionary]([user_id],[language]) ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[searches] (
+ [search_id] [int] IDENTITY (1, 1) NOT NULL ,
+ [user_id] [int] NOT NULL ,
+ [type] [tinyint] NOT NULL ,
+ [name] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[searches] WITH NOCHECK ADD
+ CONSTRAINT [PK_searches_search_id] PRIMARY KEY CLUSTERED
+ (
+ [search_id]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[searches] ADD
+ CONSTRAINT [DF_searches_user] DEFAULT (0) FOR [user_id],
+ CONSTRAINT [DF_searches_type] DEFAULT (0) FOR [type],
+GO
+
+CREATE UNIQUE INDEX [IX_searches_user_type_name] ON [dbo].[searches]([user_id],[type],[name]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[searches] ADD CONSTRAINT [FK_searches_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+DROP TABLE [dbo].[messages]
+GO
+CREATE TABLE [dbo].[cache_index] (
+ [user_id] [int] NOT NULL ,
+ [mailbox] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [changed] [datetime] NOT NULL ,
+ [valid] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[cache_thread] (
+ [user_id] [int] NOT NULL ,
+ [mailbox] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [changed] [datetime] NOT NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+CREATE TABLE [dbo].[cache_messages] (
+ [user_id] [int] NOT NULL ,
+ [mailbox] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [uid] [int] NOT NULL ,
+ [changed] [datetime] NOT NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL ,
+ [flags] [int] NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[cache_index] WITH NOCHECK ADD
+ PRIMARY KEY CLUSTERED
+ (
+ [user_id],[mailbox]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[cache_thread] WITH NOCHECK ADD
+ PRIMARY KEY CLUSTERED
+ (
+ [user_id],[mailbox]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[cache_messages] WITH NOCHECK ADD
+ PRIMARY KEY CLUSTERED
+ (
+ [user_id],[mailbox],[uid]
+ ) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[cache_index] ADD
+ CONSTRAINT [DF_cache_index_changed] DEFAULT (getdate()) FOR [changed],
+ CONSTRAINT [DF_cache_index_valid] DEFAULT ('0') FOR [valid]
+GO
+
+CREATE INDEX [IX_cache_index_user_id] ON [dbo].[cache_index]([user_id]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[cache_thread] ADD
+ CONSTRAINT [DF_cache_thread_changed] DEFAULT (getdate()) FOR [changed]
+GO
+
+CREATE INDEX [IX_cache_thread_user_id] ON [dbo].[cache_thread]([user_id]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[cache_messages] ADD
+ CONSTRAINT [DF_cache_messages_changed] DEFAULT (getdate()) FOR [changed],
+ CONSTRAINT [DF_cache_messages_flags] DEFAULT (0) FOR [flags]
+GO
+
+CREATE INDEX [IX_cache_messages_user_id] ON [dbo].[cache_messages]([user_id]) ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[cache_index] ADD CONSTRAINT [FK_cache_index_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[cache_thread] ADD CONSTRAINT [FK_cache_thread_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
+
+ALTER TABLE [dbo].[cache_messages] ADD CONSTRAINT [FK_cache_messages_user_id]
+ FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
+ ON DELETE CASCADE ON UPDATE CASCADE
+GO
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2011111600.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2011111600.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,4 @@
+-- Updates from version 0.7-beta
+
+ALTER TABLE [dbo].[session] ALTER COLUMN [sess_id] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL
+GO
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2011121400.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2011121400.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,9 @@
+-- Updates from version 0.7
+
+ALTER TABLE [dbo].[contacts] DROP CONSTRAINT [DF_contacts_email]
+GO
+ALTER TABLE [dbo].[contacts] ALTER COLUMN [email] [text] COLLATE Latin1_General_CI_AI NOT NULL
+GO
+ALTER TABLE [dbo].[contacts] ADD CONSTRAINT [DF_contacts_email] DEFAULT ('') FOR [email]
+GO
+
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2012051800.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2012051800.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,18 @@
+-- Updates from version 0.8-rc
+
+ALTER TABLE [dbo].[contacts] DROP CONSTRAINT [DF_contacts_email]
+GO
+ALTER TABLE [dbo].[contacts] ALTER COLUMN [email] [varchar] (8000) COLLATE Latin1_General_CI_AI NOT NULL
+GO
+ALTER TABLE [dbo].[contacts] ADD CONSTRAINT [DF_contacts_email] DEFAULT ('') FOR [email]
+GO
+
+-- Updates from version 0.8
+
+ALTER TABLE [dbo].[cache] DROP COLUMN [cache_id]
+GO
+ALTER TABLE [dbo].[users] DROP COLUMN [alias]
+GO
+CREATE INDEX [IX_identities_email] ON [dbo].[identities]([email],[del]) ON [PRIMARY]
+GO
+
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2012080700.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2012080700.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,8 @@
+-- Updates from version 0.8
+
+ALTER TABLE [dbo].[cache] DROP COLUMN [cache_id]
+GO
+ALTER TABLE [dbo].[users] DROP COLUMN [alias]
+GO
+CREATE INDEX [IX_identities_email] ON [dbo].[identities]([email],[del]) ON [PRIMARY]
+GO
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2013011000.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2013011000.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,14 @@
+-- Upgrades from 0.9-beta
+
+CREATE TABLE [dbo].[system] (
+ [name] [varchar] (64) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [value] [text] COLLATE Latin1_General_CI_AI
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[system] WITH NOCHECK ADD
+ CONSTRAINT [PK_system_name] PRIMARY KEY CLUSTERED
+ (
+ [name]
+ ) ON [PRIMARY]
+GO
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2013042700.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2013042700.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+-- empty
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2013052500.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2013052500.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,17 @@
+CREATE TABLE [dbo].[cache_shared] (
+ [cache_key] [varchar] (255) COLLATE Latin1_General_CI_AI NOT NULL ,
+ [created] [datetime] NOT NULL ,
+ [data] [text] COLLATE Latin1_General_CI_AI NOT NULL
+) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
+GO
+
+ALTER TABLE [dbo].[cache_shared] ADD
+ CONSTRAINT [DF_cache_shared_created] DEFAULT (getdate()) FOR [created]
+GO
+
+CREATE INDEX [IX_cache_shared_cache_key] ON [dbo].[cache_shared]([cache_key]) ON [PRIMARY]
+GO
+
+CREATE INDEX [IX_cache_shared_created] ON [dbo].[cache_shared]([created]) ON [PRIMARY]
+GO
+
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2013061000.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2013061000.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,44 @@
+ALTER TABLE [dbo].[cache] ADD [expires] [datetime] NULL
+GO
+ALTER TABLE [dbo].[cache_shared] ADD [expires] [datetime] NULL
+GO
+ALTER TABLE [dbo].[cache_index] ADD [expires] [datetime] NULL
+GO
+ALTER TABLE [dbo].[cache_thread] ADD [expires] [datetime] NULL
+GO
+ALTER TABLE [dbo].[cache_messages] ADD [expires] [datetime] NULL
+GO
+
+UPDATE [dbo].[cache] SET [expires] = DATEADD(second, 604800, [created])
+GO
+UPDATE [dbo].[cache_shared] SET [expires] = DATEADD(second, 604800, [created])
+GO
+UPDATE [dbo].[cache_index] SET [expires] = DATEADD(second, 604800, [changed])
+GO
+UPDATE [dbo].[cache_thread] SET [expires] = DATEADD(second, 604800, [changed])
+GO
+UPDATE [dbo].[cache_messages] SET [expires] = DATEADD(second, 604800, [changed])
+GO
+
+DROP INDEX [IX_cache_created]
+GO
+DROP INDEX [IX_cache_shared_created]
+GO
+ALTER TABLE [dbo].[cache_index] DROP COLUMN [changed]
+GO
+ALTER TABLE [dbo].[cache_thread] DROP COLUMN [changed]
+GO
+ALTER TABLE [dbo].[cache_messages] DROP COLUMN [changed]
+GO
+
+CREATE INDEX [IX_cache_expires] ON [dbo].[cache]([expires]) ON [PRIMARY]
+GO
+CREATE INDEX [IX_cache_shared_expires] ON [dbo].[cache_shared]([expires]) ON [PRIMARY]
+GO
+CREATE INDEX [IX_cache_index_expires] ON [dbo].[cache_index]([expires]) ON [PRIMARY]
+GO
+CREATE INDEX [IX_cache_thread_expires] ON [dbo].[cache_thread]([expires]) ON [PRIMARY]
+GO
+CREATE INDEX [IX_cache_messages_expires] ON [dbo].[cache_messages]([expires]) ON [PRIMARY]
+GO
+
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2014042900.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2014042900.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+-- empty
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/mssql/2015030800.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mssql/2015030800.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+-- empty
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/mysql.initial.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql.initial.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,212 @@
+-- Roundcube Webmail initial database structure
+
+
+/*!40014 SET FOREIGN_KEY_CHECKS=0 */;
+
+-- Table structure for table `session`
+
+CREATE TABLE `session` (
+ `sess_id` varchar(128) NOT NULL,
+ `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `ip` varchar(40) NOT NULL,
+ `vars` mediumtext NOT NULL,
+ PRIMARY KEY(`sess_id`),
+ INDEX `changed_index` (`changed`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+
+-- Table structure for table `users`
+
+CREATE TABLE `users` (
+ `user_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `username` varchar(128) BINARY NOT NULL,
+ `mail_host` varchar(128) NOT NULL,
+ `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `last_login` datetime DEFAULT NULL,
+ `language` varchar(5),
+ `preferences` longtext,
+ PRIMARY KEY(`user_id`),
+ UNIQUE `username` (`username`, `mail_host`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+
+-- Table structure for table `cache`
+
+CREATE TABLE `cache` (
+ `user_id` int(10) UNSIGNED NOT NULL,
+ `cache_key` varchar(128) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL,
+ `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `expires` datetime DEFAULT NULL,
+ `data` longtext NOT NULL,
+ CONSTRAINT `user_id_fk_cache` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ INDEX `expires_index` (`expires`),
+ INDEX `user_cache_index` (`user_id`,`cache_key`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+
+-- Table structure for table `cache_shared`
+
+CREATE TABLE `cache_shared` (
+ `cache_key` varchar(255) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL,
+ `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `expires` datetime DEFAULT NULL,
+ `data` longtext NOT NULL,
+ INDEX `expires_index` (`expires`),
+ INDEX `cache_key_index` (`cache_key`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+
+-- Table structure for table `cache_index`
+
+CREATE TABLE `cache_index` (
+ `user_id` int(10) UNSIGNED NOT NULL,
+ `mailbox` varchar(255) BINARY NOT NULL,
+ `expires` datetime DEFAULT NULL,
+ `valid` tinyint(1) NOT NULL DEFAULT '0',
+ `data` longtext NOT NULL,
+ CONSTRAINT `user_id_fk_cache_index` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ INDEX `expires_index` (`expires`),
+ PRIMARY KEY (`user_id`, `mailbox`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+
+-- Table structure for table `cache_thread`
+
+CREATE TABLE `cache_thread` (
+ `user_id` int(10) UNSIGNED NOT NULL,
+ `mailbox` varchar(255) BINARY NOT NULL,
+ `expires` datetime DEFAULT NULL,
+ `data` longtext NOT NULL,
+ CONSTRAINT `user_id_fk_cache_thread` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ INDEX `expires_index` (`expires`),
+ PRIMARY KEY (`user_id`, `mailbox`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+
+-- Table structure for table `cache_messages`
+
+CREATE TABLE `cache_messages` (
+ `user_id` int(10) UNSIGNED NOT NULL,
+ `mailbox` varchar(255) BINARY NOT NULL,
+ `uid` int(11) UNSIGNED NOT NULL DEFAULT '0',
+ `expires` datetime DEFAULT NULL,
+ `data` longtext NOT NULL,
+ `flags` int(11) NOT NULL DEFAULT '0',
+ CONSTRAINT `user_id_fk_cache_messages` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ INDEX `expires_index` (`expires`),
+ PRIMARY KEY (`user_id`, `mailbox`, `uid`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+
+-- Table structure for table `contacts`
+
+CREATE TABLE `contacts` (
+ `contact_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `del` tinyint(1) NOT NULL DEFAULT '0',
+ `name` varchar(128) NOT NULL DEFAULT '',
+ `email` text NOT NULL,
+ `firstname` varchar(128) NOT NULL DEFAULT '',
+ `surname` varchar(128) NOT NULL DEFAULT '',
+ `vcard` longtext NULL,
+ `words` text NULL,
+ `user_id` int(10) UNSIGNED NOT NULL,
+ PRIMARY KEY(`contact_id`),
+ CONSTRAINT `user_id_fk_contacts` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ INDEX `user_contacts_index` (`user_id`,`del`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+-- Table structure for table `contactgroups`
+
+CREATE TABLE `contactgroups` (
+ `contactgroup_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `user_id` int(10) UNSIGNED NOT NULL,
+ `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `del` tinyint(1) NOT NULL DEFAULT '0',
+ `name` varchar(128) NOT NULL DEFAULT '',
+ PRIMARY KEY(`contactgroup_id`),
+ CONSTRAINT `user_id_fk_contactgroups` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ INDEX `contactgroups_user_index` (`user_id`,`del`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+CREATE TABLE `contactgroupmembers` (
+ `contactgroup_id` int(10) UNSIGNED NOT NULL,
+ `contact_id` int(10) UNSIGNED NOT NULL,
+ `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ PRIMARY KEY (`contactgroup_id`, `contact_id`),
+ CONSTRAINT `contactgroup_id_fk_contactgroups` FOREIGN KEY (`contactgroup_id`)
+ REFERENCES `contactgroups`(`contactgroup_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ CONSTRAINT `contact_id_fk_contacts` FOREIGN KEY (`contact_id`)
+ REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ INDEX `contactgroupmembers_contact_index` (`contact_id`)
+) /*!40000 ENGINE=INNODB */;
+
+
+-- Table structure for table `identities`
+
+CREATE TABLE `identities` (
+ `identity_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `user_id` int(10) UNSIGNED NOT NULL,
+ `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `del` tinyint(1) NOT NULL DEFAULT '0',
+ `standard` tinyint(1) NOT NULL DEFAULT '0',
+ `name` varchar(128) NOT NULL,
+ `organization` varchar(128) NOT NULL DEFAULT '',
+ `email` varchar(128) NOT NULL,
+ `reply-to` varchar(128) NOT NULL DEFAULT '',
+ `bcc` varchar(128) NOT NULL DEFAULT '',
+ `signature` longtext,
+ `html_signature` tinyint(1) NOT NULL DEFAULT '0',
+ PRIMARY KEY(`identity_id`),
+ CONSTRAINT `user_id_fk_identities` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ INDEX `user_identities_index` (`user_id`, `del`),
+ INDEX `email_identities_index` (`email`, `del`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+
+-- Table structure for table `dictionary`
+
+CREATE TABLE `dictionary` (
+ `user_id` int(10) UNSIGNED DEFAULT NULL,
+ `language` varchar(5) NOT NULL,
+ `data` longtext NOT NULL,
+ CONSTRAINT `user_id_fk_dictionary` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ UNIQUE `uniqueness` (`user_id`, `language`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+
+-- Table structure for table `searches`
+
+CREATE TABLE `searches` (
+ `search_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `user_id` int(10) UNSIGNED NOT NULL,
+ `type` int(3) NOT NULL DEFAULT '0',
+ `name` varchar(128) NOT NULL,
+ `data` text,
+ PRIMARY KEY(`search_id`),
+ CONSTRAINT `user_id_fk_searches` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ UNIQUE `uniqueness` (`user_id`, `type`, `name`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+
+-- Table structure for table `system`
+
+CREATE TABLE `system` (
+ `name` varchar(64) NOT NULL,
+ `value` mediumtext,
+ PRIMARY KEY(`name`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+/*!40014 SET FOREIGN_KEY_CHECKS=1 */;
+
+INSERT INTO system (name, value) VALUES ('roundcube-version', '2015030800');
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2008030300.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2008030300.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,16 @@
+-- Updates from version 0.1-stable
+
+TRUNCATE TABLE `messages`;
+
+ALTER TABLE `messages`
+ DROP INDEX `idx`,
+ DROP INDEX `uid`;
+
+ALTER TABLE `cache`
+ DROP INDEX `cache_key`,
+ DROP INDEX `session_id`,
+ ADD INDEX `user_cache_index` (`user_id`,`cache_key`);
+
+ALTER TABLE `users`
+ ADD INDEX `username_index` (`username`),
+ ADD INDEX `alias_index` (`alias`);
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2008040500.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2008040500.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,9 @@
+-- Updates from version 0.1.1
+
+ALTER TABLE `identities`
+ MODIFY `signature` text,
+ MODIFY `bcc` varchar(128) NOT NULL DEFAULT '',
+ MODIFY `reply-to` varchar(128) NOT NULL DEFAULT '',
+ MODIFY `organization` varchar(128) NOT NULL DEFAULT '',
+ MODIFY `name` varchar(128) NOT NULL,
+ MODIFY `email` varchar(128) NOT NULL;
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2008060900.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2008060900.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,4 @@
+-- Updates from version 0.2-alpha
+
+ALTER TABLE `messages`
+ ADD INDEX `created_index` (`created`);
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2008092100.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2008092100.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,20 @@
+-- Updates from version 0.2-beta (InnoDB required)
+
+ALTER TABLE `cache`
+ DROP `session_id`;
+
+ALTER TABLE `session`
+ ADD INDEX `changed_index` (`changed`);
+
+ALTER TABLE `cache`
+ ADD INDEX `created_index` (`created`);
+
+ALTER TABLE `users`
+ CHANGE `language` `language` varchar(5);
+
+ALTER TABLE `cache` ENGINE=InnoDB;
+ALTER TABLE `session` ENGINE=InnoDB;
+ALTER TABLE `messages` ENGINE=InnoDB;
+ALTER TABLE `users` ENGINE=InnoDB;
+ALTER TABLE `contacts` ENGINE=InnoDB;
+ALTER TABLE `identities` ENGINE=InnoDB;
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2009090400.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2009090400.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,12 @@
+-- Updates from version 0.3-stable
+
+TRUNCATE `messages`;
+
+ALTER TABLE `messages`
+ ADD INDEX `index_index` (`user_id`, `cache_key`, `idx`);
+
+ALTER TABLE `session`
+ CHANGE `vars` `vars` MEDIUMTEXT NOT NULL;
+
+ALTER TABLE `contacts`
+ ADD INDEX `user_contacts_index` (`user_id`,`email`);
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2009103100.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2009103100.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,52 @@
+-- Updates from version 0.3.1
+-- WARNING: Make sure that all tables are using InnoDB engine!!!
+-- If not, use: ALTER TABLE xxx ENGINE=InnoDB;
+
+/* MySQL bug workaround: http://bugs.mysql.com/bug.php?id=46293 */
+/*!40014 SET FOREIGN_KEY_CHECKS=0 */;
+
+ALTER TABLE `messages` DROP FOREIGN KEY `user_id_fk_messages`;
+ALTER TABLE `cache` DROP FOREIGN KEY `user_id_fk_cache`;
+ALTER TABLE `contacts` DROP FOREIGN KEY `user_id_fk_contacts`;
+ALTER TABLE `identities` DROP FOREIGN KEY `user_id_fk_identities`;
+
+ALTER TABLE `messages` ADD CONSTRAINT `user_id_fk_messages` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;
+ALTER TABLE `cache` ADD CONSTRAINT `user_id_fk_cache` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;
+ALTER TABLE `contacts` ADD CONSTRAINT `user_id_fk_contacts` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;
+ALTER TABLE `identities` ADD CONSTRAINT `user_id_fk_identities` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;
+
+ALTER TABLE `contacts` ALTER `name` SET DEFAULT '';
+ALTER TABLE `contacts` ALTER `firstname` SET DEFAULT '';
+ALTER TABLE `contacts` ALTER `surname` SET DEFAULT '';
+
+ALTER TABLE `identities` ADD INDEX `user_identities_index` (`user_id`, `del`);
+ALTER TABLE `identities` ADD `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00' AFTER `user_id`;
+
+CREATE TABLE `contactgroups` (
+ `contactgroup_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
+ `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `del` tinyint(1) NOT NULL DEFAULT '0',
+ `name` varchar(128) NOT NULL DEFAULT '',
+ PRIMARY KEY(`contactgroup_id`),
+ CONSTRAINT `user_id_fk_contactgroups` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ INDEX `contactgroups_user_index` (`user_id`,`del`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+CREATE TABLE `contactgroupmembers` (
+ `contactgroup_id` int(10) UNSIGNED NOT NULL,
+ `contact_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
+ `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ PRIMARY KEY (`contactgroup_id`, `contact_id`),
+ CONSTRAINT `contactgroup_id_fk_contactgroups` FOREIGN KEY (`contactgroup_id`)
+ REFERENCES `contactgroups`(`contactgroup_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ CONSTRAINT `contact_id_fk_contacts` FOREIGN KEY (`contact_id`)
+ REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE ON UPDATE CASCADE
+) /*!40000 ENGINE=INNODB */;
+
+/*!40014 SET FOREIGN_KEY_CHECKS=1 */;
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2010042300.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2010042300.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,4 @@
+-- Updates from version 0.4-beta
+
+ALTER TABLE `users` CHANGE `last_login` `last_login` datetime DEFAULT NULL;
+UPDATE `users` SET `last_login` = NULL WHERE `last_login` = '1000-01-01 00:00:00';
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2010100600.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2010100600.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,8 @@
+-- Updates from version 0.4.2
+
+ALTER TABLE `users` DROP INDEX `username_index`;
+ALTER TABLE `users` ADD UNIQUE `username` (`username`, `mail_host`);
+
+ALTER TABLE `contacts` MODIFY `email` varchar(255) NOT NULL;
+
+TRUNCATE TABLE `messages`;
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2011011200.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2011011200.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,8 @@
+-- Updates from version 0.5.x
+
+ALTER TABLE `contacts` ADD `words` TEXT NULL AFTER `vcard`;
+ALTER TABLE `contacts` CHANGE `vcard` `vcard` LONGTEXT /*!40101 CHARACTER SET utf8 */ NULL DEFAULT NULL;
+ALTER TABLE `contactgroupmembers` ADD INDEX `contactgroupmembers_contact_index` (`contact_id`);
+
+TRUNCATE TABLE `messages`;
+TRUNCATE TABLE `cache`;
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2011092800.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2011092800.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,67 @@
+-- Updates from version 0.6
+
+/*!40014 SET FOREIGN_KEY_CHECKS=0 */;
+
+ALTER TABLE `users` CHANGE `alias` `alias` varchar(128) BINARY NOT NULL;
+ALTER TABLE `users` CHANGE `username` `username` varchar(128) BINARY NOT NULL;
+
+CREATE TABLE `dictionary` (
+ `user_id` int(10) UNSIGNED DEFAULT NULL,
+ `language` varchar(5) NOT NULL,
+ `data` longtext NOT NULL,
+ CONSTRAINT `user_id_fk_dictionary` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ UNIQUE `uniqueness` (`user_id`, `language`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+CREATE TABLE `searches` (
+ `search_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
+ `type` int(3) NOT NULL DEFAULT '0',
+ `name` varchar(128) NOT NULL,
+ `data` text,
+ PRIMARY KEY(`search_id`),
+ CONSTRAINT `user_id_fk_searches` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ UNIQUE `uniqueness` (`user_id`, `type`, `name`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+DROP TABLE `messages`;
+
+CREATE TABLE `cache_index` (
+ `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
+ `mailbox` varchar(255) BINARY NOT NULL,
+ `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `valid` tinyint(1) NOT NULL DEFAULT '0',
+ `data` longtext NOT NULL,
+ CONSTRAINT `user_id_fk_cache_index` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ INDEX `changed_index` (`changed`),
+ PRIMARY KEY (`user_id`, `mailbox`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+CREATE TABLE `cache_thread` (
+ `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
+ `mailbox` varchar(255) BINARY NOT NULL,
+ `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `data` longtext NOT NULL,
+ CONSTRAINT `user_id_fk_cache_thread` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ INDEX `changed_index` (`changed`),
+ PRIMARY KEY (`user_id`, `mailbox`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+CREATE TABLE `cache_messages` (
+ `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
+ `mailbox` varchar(255) BINARY NOT NULL,
+ `uid` int(11) UNSIGNED NOT NULL DEFAULT '0',
+ `changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `data` longtext NOT NULL,
+ `flags` int(11) NOT NULL DEFAULT '0',
+ CONSTRAINT `user_id_fk_cache_messages` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+ INDEX `changed_index` (`changed`),
+ PRIMARY KEY (`user_id`, `mailbox`, `uid`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+/*!40014 SET FOREIGN_KEY_CHECKS=1 */;
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2011111600.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2011111600.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,3 @@
+-- Updates from version 0.7-beta
+
+ALTER TABLE `session` CHANGE `sess_id` `sess_id` varchar(128) NOT NULL;
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2011121400.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2011121400.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,22 @@
+-- Updates from version 0.7
+
+/*!40014 SET FOREIGN_KEY_CHECKS=0 */;
+
+ALTER TABLE `contacts` DROP FOREIGN KEY `user_id_fk_contacts`;
+ALTER TABLE `contacts` DROP INDEX `user_contacts_index`;
+ALTER TABLE `contacts` MODIFY `email` text NOT NULL;
+ALTER TABLE `contacts` ADD INDEX `user_contacts_index` (`user_id`,`del`);
+ALTER TABLE `contacts` ADD CONSTRAINT `user_id_fk_contacts` FOREIGN KEY (`user_id`)
+ REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;
+
+ALTER TABLE `cache` ALTER `user_id` DROP DEFAULT;
+ALTER TABLE `cache_index` ALTER `user_id` DROP DEFAULT;
+ALTER TABLE `cache_thread` ALTER `user_id` DROP DEFAULT;
+ALTER TABLE `cache_messages` ALTER `user_id` DROP DEFAULT;
+ALTER TABLE `contacts` ALTER `user_id` DROP DEFAULT;
+ALTER TABLE `contactgroups` ALTER `user_id` DROP DEFAULT;
+ALTER TABLE `contactgroupmembers` ALTER `contact_id` DROP DEFAULT;
+ALTER TABLE `identities` ALTER `user_id` DROP DEFAULT;
+ALTER TABLE `searches` ALTER `user_id` DROP DEFAULT;
+
+/*!40014 SET FOREIGN_KEY_CHECKS=1 */;
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2012080700.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2012080700.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,5 @@
+-- Updates from version 0.8
+
+ALTER TABLE `cache` DROP COLUMN `cache_id`;
+ALTER TABLE `users` DROP COLUMN `alias`;
+ALTER TABLE `identities` ADD INDEX `email_identities_index` (`email`, `del`);
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2013011000.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2013011000.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,7 @@
+-- Upgrade from 0.9-beta
+
+CREATE TABLE IF NOT EXISTS `system` (
+ `name` varchar(64) NOT NULL,
+ `value` mediumtext,
+ PRIMARY KEY(`name`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2013042700.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2013042700.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+-- empty
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2013052500.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2013052500.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,7 @@
+CREATE TABLE `cache_shared` (
+ `cache_key` varchar(255) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL,
+ `created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
+ `data` longtext NOT NULL,
+ INDEX `created_index` (`created`),
+ INDEX `cache_key_index` (`cache_key`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2013061000.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2013061000.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,24 @@
+ALTER TABLE `cache` ADD `expires` datetime DEFAULT NULL;
+ALTER TABLE `cache_shared` ADD `expires` datetime DEFAULT NULL;
+ALTER TABLE `cache_index` ADD `expires` datetime DEFAULT NULL;
+ALTER TABLE `cache_thread` ADD `expires` datetime DEFAULT NULL;
+ALTER TABLE `cache_messages` ADD `expires` datetime DEFAULT NULL;
+
+-- initialize expires column with created/changed date + 7days
+UPDATE `cache` SET `expires` = `created` + interval 604800 second;
+UPDATE `cache_shared` SET `expires` = `created` + interval 604800 second;
+UPDATE `cache_index` SET `expires` = `changed` + interval 604800 second;
+UPDATE `cache_thread` SET `expires` = `changed` + interval 604800 second;
+UPDATE `cache_messages` SET `expires` = `changed` + interval 604800 second;
+
+ALTER TABLE `cache` DROP INDEX `created_index`;
+ALTER TABLE `cache_shared` DROP INDEX `created_index`;
+ALTER TABLE `cache_index` DROP `changed`;
+ALTER TABLE `cache_thread` DROP `changed`;
+ALTER TABLE `cache_messages` DROP `changed`;
+
+ALTER TABLE `cache` ADD INDEX `expires_index` (`expires`);
+ALTER TABLE `cache_shared` ADD INDEX `expires_index` (`expires`);
+ALTER TABLE `cache_index` ADD INDEX `expires_index` (`expires`);
+ALTER TABLE `cache_thread` ADD INDEX `expires_index` (`expires`);
+ALTER TABLE `cache_messages` ADD INDEX `expires_index` (`expires`);
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2014042900.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2014042900.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+ALTER TABLE `users` CHANGE `preferences` `preferences` longtext;
diff -r 000000000000 -r 4681f974d28b SQL/mysql/2015030800.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/mysql/2015030800.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+ALTER TABLE `identities` CHANGE `signature` `signature` longtext;
diff -r 000000000000 -r 4681f974d28b SQL/oracle.initial.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/oracle.initial.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,221 @@
+-- Roundcube Webmail initial database structure
+-- This was tested with Oracle 11g
+
+CREATE TABLE "users" (
+ "user_id" integer PRIMARY KEY,
+ "username" varchar(128) NOT NULL,
+ "mail_host" varchar(128) NOT NULL,
+ "created" timestamp with time zone DEFAULT current_timestamp NOT NULL,
+ "last_login" timestamp with time zone DEFAULT NULL,
+ "language" varchar(5),
+ "preferences" long DEFAULT NULL,
+ CONSTRAINT "users_username_key" UNIQUE ("username", "mail_host")
+);
+
+CREATE SEQUENCE "users_seq"
+ START WITH 1 INCREMENT BY 1 NOMAXVALUE;
+
+CREATE TRIGGER "users_seq_trig"
+BEFORE INSERT ON "users" FOR EACH ROW
+BEGIN
+ :NEW."user_id" := "users_seq".nextval;
+END;
+/
+
+CREATE TABLE "session" (
+ "sess_id" varchar(128) NOT NULL PRIMARY KEY,
+ "created" timestamp with time zone DEFAULT current_timestamp NOT NULL,
+ "changed" timestamp with time zone DEFAULT current_timestamp NOT NULL,
+ "ip" varchar(41) NOT NULL,
+ "vars" long NOT NULL
+);
+
+CREATE INDEX "session_changed_idx" ON "session" ("changed");
+
+
+CREATE TABLE "identities" (
+ "identity_id" integer PRIMARY KEY,
+ "user_id" integer NOT NULL
+ REFERENCES "users" ("user_id") ON DELETE CASCADE,
+ "changed" timestamp with time zone DEFAULT current_timestamp NOT NULL,
+ "del" smallint DEFAULT 0 NOT NULL,
+ "standard" smallint DEFAULT 0 NOT NULL,
+ "name" varchar(128) NOT NULL,
+ "organization" varchar(128),
+ "email" varchar(128) NOT NULL,
+ "reply-to" varchar(128),
+ "bcc" varchar(128),
+ "signature" long,
+ "html_signature" integer DEFAULT 0 NOT NULL
+);
+
+CREATE INDEX "identities_user_id_idx" ON "identities" ("user_id", "del");
+CREATE INDEX "identities_email_idx" ON "identities" ("email", "del");
+
+CREATE SEQUENCE "identities_seq"
+ START WITH 1 INCREMENT BY 1 NOMAXVALUE;
+
+CREATE TRIGGER "identities_seq_trig"
+BEFORE INSERT ON "identities" FOR EACH ROW
+BEGIN
+ :NEW."identity_id" := "identities_seq".nextval;
+END;
+/
+
+CREATE TABLE "contacts" (
+ "contact_id" integer PRIMARY KEY,
+ "user_id" integer NOT NULL
+ REFERENCES "users" ("user_id") ON DELETE CASCADE,
+ "changed" timestamp with time zone DEFAULT current_timestamp NOT NULL,
+ "del" smallint DEFAULT 0 NOT NULL,
+ "name" varchar(128) DEFAULT NULL,
+ "email" varchar(4000) DEFAULT NULL,
+ "firstname" varchar(128) DEFAULT NULL,
+ "surname" varchar(128) DEFAULT NULL,
+ "vcard" long,
+ "words" varchar(4000)
+);
+
+CREATE INDEX "contacts_user_id_idx" ON "contacts" ("user_id", "del");
+
+CREATE SEQUENCE "contacts_seq"
+ START WITH 1 INCREMENT BY 1 NOMAXVALUE;
+
+CREATE TRIGGER "contacts_seq_trig"
+BEFORE INSERT ON "contacts" FOR EACH ROW
+BEGIN
+ :NEW."contact_id" := "contacts_seq".nextval;
+END;
+/
+
+CREATE TABLE "contactgroups" (
+ "contactgroup_id" integer PRIMARY KEY,
+ "user_id" integer NOT NULL
+ REFERENCES "users" ("user_id") ON DELETE CASCADE,
+ "changed" timestamp with time zone DEFAULT current_timestamp NOT NULL,
+ "del" smallint DEFAULT 0 NOT NULL,
+ "name" varchar(128) NOT NULL
+);
+
+CREATE INDEX "contactgroups_user_id_idx" ON "contactgroups" ("user_id", "del");
+
+CREATE SEQUENCE "contactgroups_seq"
+ START WITH 1 INCREMENT BY 1 NOMAXVALUE;
+
+CREATE TRIGGER "contactgroups_seq_trig"
+BEFORE INSERT ON "contactgroups" FOR EACH ROW
+BEGIN
+ :NEW."contactgroup_id" := "contactgroups_seq".nextval;
+END;
+/
+
+CREATE TABLE "contactgroupmembers" (
+ "contactgroup_id" integer NOT NULL
+ REFERENCES "contactgroups" ("contactgroup_id") ON DELETE CASCADE,
+ "contact_id" integer NOT NULL
+ REFERENCES "contacts" ("contact_id") ON DELETE CASCADE,
+ "created" timestamp with time zone DEFAULT current_timestamp NOT NULL,
+ PRIMARY KEY ("contactgroup_id", "contact_id")
+);
+
+CREATE INDEX "contactgroupmembers_idx" ON "contactgroupmembers" ("contact_id");
+
+
+CREATE TABLE "cache" (
+ "user_id" integer NOT NULL
+ REFERENCES "users" ("user_id") ON DELETE CASCADE,
+ "cache_key" varchar(128) NOT NULL,
+ "created" timestamp with time zone DEFAULT current_timestamp NOT NULL,
+ "expires" timestamp with time zone DEFAULT NULL,
+ "data" long NOT NULL
+);
+
+CREATE INDEX "cache_user_id_idx" ON "cache" ("user_id", "cache_key");
+CREATE INDEX "cache_expires_idx" ON "cache" ("expires");
+
+
+CREATE TABLE "cache_shared" (
+ "cache_key" varchar(255) NOT NULL,
+ "created" timestamp with time zone DEFAULT current_timestamp NOT NULL,
+ "expires" timestamp with time zone DEFAULT NULL,
+ "data" long NOT NULL
+);
+
+CREATE INDEX "cache_shared_cache_key_idx" ON "cache_shared" ("cache_key");
+CREATE INDEX "cache_shared_expires_idx" ON "cache_shared" ("expires");
+
+
+CREATE TABLE "cache_index" (
+ "user_id" integer NOT NULL
+ REFERENCES "users" ("user_id") ON DELETE CASCADE,
+ "mailbox" varchar(255) NOT NULL,
+ "expires" timestamp with time zone DEFAULT NULL,
+ "valid" smallint DEFAULT 0 NOT NULL,
+ "data" long NOT NULL,
+ PRIMARY KEY ("user_id", "mailbox")
+);
+
+CREATE INDEX "cache_index_expires_idx" ON "cache_index" ("expires");
+
+
+CREATE TABLE "cache_thread" (
+ "user_id" integer NOT NULL
+ REFERENCES "users" ("user_id") ON DELETE CASCADE,
+ "mailbox" varchar(255) NOT NULL,
+ "expires" timestamp with time zone DEFAULT NULL,
+ "data" long NOT NULL,
+ PRIMARY KEY ("user_id", "mailbox")
+);
+
+CREATE INDEX "cache_thread_expires_idx" ON "cache_thread" ("expires");
+
+
+CREATE TABLE "cache_messages" (
+ "user_id" integer NOT NULL
+ REFERENCES "users" ("user_id") ON DELETE CASCADE,
+ "mailbox" varchar(255) NOT NULL,
+ "uid" integer NOT NULL,
+ "expires" timestamp with time zone DEFAULT NULL,
+ "data" long NOT NULL,
+ "flags" integer DEFAULT 0 NOT NULL,
+ PRIMARY KEY ("user_id", "mailbox", "uid")
+);
+
+CREATE INDEX "cache_messages_expires_idx" ON "cache_messages" ("expires");
+
+
+CREATE TABLE "dictionary" (
+ "user_id" integer DEFAULT NULL
+ REFERENCES "users" ("user_id") ON DELETE CASCADE,
+ "language" varchar(5) NOT NULL,
+ "data" long DEFAULT NULL,
+ CONSTRAINT "dictionary_user_id_lang_key" UNIQUE ("user_id", "language")
+);
+
+
+CREATE TABLE "searches" (
+ "search_id" integer PRIMARY KEY,
+ "user_id" integer NOT NULL
+ REFERENCES "users" ("user_id") ON DELETE CASCADE,
+ "type" smallint DEFAULT 0 NOT NULL,
+ "name" varchar(128) NOT NULL,
+ "data" long NOT NULL,
+ CONSTRAINT "searches_user_id_key" UNIQUE ("user_id", "type", "name")
+);
+
+CREATE SEQUENCE "searches_seq"
+ START WITH 1 INCREMENT BY 1 NOMAXVALUE;
+
+CREATE TRIGGER "searches_seq_trig"
+BEFORE INSERT ON "searches" FOR EACH ROW
+BEGIN
+ :NEW."search_id" := "searches_seq".nextval;
+END;
+/
+
+CREATE TABLE "system" (
+ "name" varchar(64) NOT NULL PRIMARY KEY,
+ "value" long
+);
+
+INSERT INTO "system" ("name", "value") VALUES ('roundcube-version', '2015030800');
diff -r 000000000000 -r 4681f974d28b SQL/oracle/2015030800.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/oracle/2015030800.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+-- empty
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/postgres.initial.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres.initial.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,293 @@
+-- Roundcube Webmail initial database structure
+
+--
+-- Sequence "users_seq"
+-- Name: users_seq; Type: SEQUENCE; Schema: public; Owner: postgres
+--
+
+CREATE SEQUENCE users_seq
+ INCREMENT BY 1
+ NO MAXVALUE
+ NO MINVALUE
+ CACHE 1;
+
+--
+-- Table "users"
+-- Name: users; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE users (
+ user_id integer DEFAULT nextval('users_seq'::text) PRIMARY KEY,
+ username varchar(128) DEFAULT '' NOT NULL,
+ mail_host varchar(128) DEFAULT '' NOT NULL,
+ created timestamp with time zone DEFAULT now() NOT NULL,
+ last_login timestamp with time zone DEFAULT NULL,
+ "language" varchar(5),
+ preferences text DEFAULT ''::text NOT NULL,
+ CONSTRAINT users_username_key UNIQUE (username, mail_host)
+);
+
+
+--
+-- Table "session"
+-- Name: session; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE "session" (
+ sess_id varchar(128) DEFAULT '' PRIMARY KEY,
+ created timestamp with time zone DEFAULT now() NOT NULL,
+ changed timestamp with time zone DEFAULT now() NOT NULL,
+ ip varchar(41) NOT NULL,
+ vars text NOT NULL
+);
+
+CREATE INDEX session_changed_idx ON session (changed);
+
+
+--
+-- Sequence "identities_seq"
+-- Name: identities_seq; Type: SEQUENCE; Schema: public; Owner: postgres
+--
+
+CREATE SEQUENCE identities_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MAXVALUE
+ NO MINVALUE
+ CACHE 1;
+
+--
+-- Table "identities"
+-- Name: identities; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE identities (
+ identity_id integer DEFAULT nextval('identities_seq'::text) PRIMARY KEY,
+ user_id integer NOT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ changed timestamp with time zone DEFAULT now() NOT NULL,
+ del smallint DEFAULT 0 NOT NULL,
+ standard smallint DEFAULT 0 NOT NULL,
+ name varchar(128) NOT NULL,
+ organization varchar(128),
+ email varchar(128) NOT NULL,
+ "reply-to" varchar(128),
+ bcc varchar(128),
+ signature text,
+ html_signature integer DEFAULT 0 NOT NULL
+);
+
+CREATE INDEX identities_user_id_idx ON identities (user_id, del);
+CREATE INDEX identities_email_idx ON identities (email, del);
+
+
+--
+-- Sequence "contacts_seq"
+-- Name: contacts_seq; Type: SEQUENCE; Schema: public; Owner: postgres
+--
+
+CREATE SEQUENCE contacts_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MAXVALUE
+ NO MINVALUE
+ CACHE 1;
+
+--
+-- Table "contacts"
+-- Name: contacts; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE contacts (
+ contact_id integer DEFAULT nextval('contacts_seq'::text) PRIMARY KEY,
+ user_id integer NOT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ changed timestamp with time zone DEFAULT now() NOT NULL,
+ del smallint DEFAULT 0 NOT NULL,
+ name varchar(128) DEFAULT '' NOT NULL,
+ email text DEFAULT '' NOT NULL,
+ firstname varchar(128) DEFAULT '' NOT NULL,
+ surname varchar(128) DEFAULT '' NOT NULL,
+ vcard text,
+ words text
+);
+
+CREATE INDEX contacts_user_id_idx ON contacts (user_id, del);
+
+--
+-- Sequence "contactgroups_seq"
+-- Name: contactgroups_seq; Type: SEQUENCE; Schema: public; Owner: postgres
+--
+
+CREATE SEQUENCE contactgroups_seq
+ INCREMENT BY 1
+ NO MAXVALUE
+ NO MINVALUE
+ CACHE 1;
+
+--
+-- Table "contactgroups"
+-- Name: contactgroups; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE contactgroups (
+ contactgroup_id integer DEFAULT nextval('contactgroups_seq'::text) PRIMARY KEY,
+ user_id integer NOT NULL
+ REFERENCES users(user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ changed timestamp with time zone DEFAULT now() NOT NULL,
+ del smallint NOT NULL DEFAULT 0,
+ name varchar(128) NOT NULL DEFAULT ''
+);
+
+CREATE INDEX contactgroups_user_id_idx ON contactgroups (user_id, del);
+
+--
+-- Table "contactgroupmembers"
+-- Name: contactgroupmembers; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE contactgroupmembers (
+ contactgroup_id integer NOT NULL
+ REFERENCES contactgroups(contactgroup_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ contact_id integer NOT NULL
+ REFERENCES contacts(contact_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ created timestamp with time zone DEFAULT now() NOT NULL,
+ PRIMARY KEY (contactgroup_id, contact_id)
+);
+
+CREATE INDEX contactgroupmembers_contact_id_idx ON contactgroupmembers (contact_id);
+
+--
+-- Table "cache"
+-- Name: cache; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE "cache" (
+ user_id integer NOT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ cache_key varchar(128) DEFAULT '' NOT NULL,
+ created timestamp with time zone DEFAULT now() NOT NULL,
+ expires timestamp with time zone DEFAULT NULL,
+ data text NOT NULL
+);
+
+CREATE INDEX cache_user_id_idx ON "cache" (user_id, cache_key);
+CREATE INDEX cache_expires_idx ON "cache" (expires);
+
+--
+-- Table "cache_shared"
+-- Name: cache_shared; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE "cache_shared" (
+ cache_key varchar(255) NOT NULL,
+ created timestamp with time zone DEFAULT now() NOT NULL,
+ expires timestamp with time zone DEFAULT NULL,
+ data text NOT NULL
+);
+
+CREATE INDEX cache_shared_cache_key_idx ON "cache_shared" (cache_key);
+CREATE INDEX cache_shared_expires_idx ON "cache_shared" (expires);
+
+--
+-- Table "cache_index"
+-- Name: cache_index; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE cache_index (
+ user_id integer NOT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ mailbox varchar(255) NOT NULL,
+ expires timestamp with time zone DEFAULT NULL,
+ valid smallint NOT NULL DEFAULT 0,
+ data text NOT NULL,
+ PRIMARY KEY (user_id, mailbox)
+);
+
+CREATE INDEX cache_index_expires_idx ON cache_index (expires);
+
+--
+-- Table "cache_thread"
+-- Name: cache_thread; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE cache_thread (
+ user_id integer NOT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ mailbox varchar(255) NOT NULL,
+ expires timestamp with time zone DEFAULT NULL,
+ data text NOT NULL,
+ PRIMARY KEY (user_id, mailbox)
+);
+
+CREATE INDEX cache_thread_expires_idx ON cache_thread (expires);
+
+--
+-- Table "cache_messages"
+-- Name: cache_messages; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE cache_messages (
+ user_id integer NOT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ mailbox varchar(255) NOT NULL,
+ uid integer NOT NULL,
+ expires timestamp with time zone DEFAULT NULL,
+ data text NOT NULL,
+ flags integer NOT NULL DEFAULT 0,
+ PRIMARY KEY (user_id, mailbox, uid)
+);
+
+CREATE INDEX cache_messages_expires_idx ON cache_messages (expires);
+
+--
+-- Table "dictionary"
+-- Name: dictionary; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE dictionary (
+ user_id integer DEFAULT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ "language" varchar(5) NOT NULL,
+ data text NOT NULL,
+ CONSTRAINT dictionary_user_id_language_key UNIQUE (user_id, "language")
+);
+
+--
+-- Sequence "searches_seq"
+-- Name: searches_seq; Type: SEQUENCE; Schema: public; Owner: postgres
+--
+
+CREATE SEQUENCE searches_seq
+ INCREMENT BY 1
+ NO MAXVALUE
+ NO MINVALUE
+ CACHE 1;
+
+--
+-- Table "searches"
+-- Name: searches; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE searches (
+ search_id integer DEFAULT nextval('searches_seq'::text) PRIMARY KEY,
+ user_id integer NOT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ "type" smallint DEFAULT 0 NOT NULL,
+ name varchar(128) NOT NULL,
+ data text NOT NULL,
+ CONSTRAINT searches_user_id_key UNIQUE (user_id, "type", name)
+);
+
+
+--
+-- Table "system"
+-- Name: system; Type: TABLE; Schema: public; Owner: postgres
+--
+
+CREATE TABLE "system" (
+ name varchar(64) NOT NULL PRIMARY KEY,
+ value text
+);
+
+INSERT INTO system (name, value) VALUES ('roundcube-version', '2015030800');
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2008030300.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2008030300.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,18 @@
+-- Updates from version 0.1-stable to 0.1.1
+
+CREATE INDEX cache_user_id_idx ON cache (user_id, cache_key);
+CREATE INDEX contacts_user_id_idx ON contacts (user_id);
+CREATE INDEX identities_user_id_idx ON identities (user_id);
+
+CREATE INDEX users_username_id_idx ON users (username);
+CREATE INDEX users_alias_id_idx ON users (alias);
+
+-- added ON DELETE/UPDATE actions
+ALTER TABLE messages DROP CONSTRAINT messages_user_id_fkey;
+ALTER TABLE messages ADD FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE ON UPDATE CASCADE;
+ALTER TABLE identities DROP CONSTRAINT identities_user_id_fkey;
+ALTER TABLE identities ADD FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE ON UPDATE CASCADE;
+ALTER TABLE contacts DROP CONSTRAINT contacts_user_id_fkey;
+ALTER TABLE contacts ADD FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE ON UPDATE CASCADE;
+ALTER TABLE cache DROP CONSTRAINT cache_user_id_fkey;
+ALTER TABLE cache ADD FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE ON UPDATE CASCADE;
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2008060900.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2008060900.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,3 @@
+-- Updates from version 0.2-alpha
+
+CREATE INDEX messages_created_idx ON messages (created);
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2008092100.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2008092100.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,14 @@
+-- Updates from version 0.2-beta
+
+ALTER TABLE cache DROP session_id;
+
+CREATE INDEX session_changed_idx ON session (changed);
+CREATE INDEX cache_created_idx ON "cache" (created);
+
+ALTER TABLE users ALTER "language" DROP NOT NULL;
+ALTER TABLE users ALTER "language" DROP DEFAULT;
+
+ALTER TABLE identities ALTER del TYPE smallint;
+ALTER TABLE identities ALTER standard TYPE smallint;
+ALTER TABLE contacts ALTER del TYPE smallint;
+ALTER TABLE messages ALTER del TYPE smallint;
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2009090400.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2009090400.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,6 @@
+-- Updates from version 0.3-stable
+
+TRUNCATE messages;
+CREATE INDEX messages_index_idx ON messages (user_id, cache_key, idx);
+DROP INDEX contacts_user_id_idx;
+CREATE INDEX contacts_user_id_idx ON contacts (user_id, email);
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2009103100.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2009103100.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,32 @@
+-- Updates from version 0.3.1
+
+DROP INDEX identities_user_id_idx;
+CREATE INDEX identities_user_id_idx ON identities (user_id, del);
+
+ALTER TABLE identities ADD changed timestamp with time zone DEFAULT now() NOT NULL;
+
+CREATE SEQUENCE contactgroups_ids
+ INCREMENT BY 1
+ NO MAXVALUE
+ NO MINVALUE
+ CACHE 1;
+
+CREATE TABLE contactgroups (
+ contactgroup_id integer DEFAULT nextval('contactgroups_ids'::text) PRIMARY KEY,
+ user_id integer NOT NULL
+ REFERENCES users(user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ changed timestamp with time zone DEFAULT now() NOT NULL,
+ del smallint NOT NULL DEFAULT 0,
+ name varchar(128) NOT NULL DEFAULT ''
+);
+
+CREATE INDEX contactgroups_user_id_idx ON contactgroups (user_id, del);
+
+CREATE TABLE contactgroupmembers (
+ contactgroup_id integer NOT NULL
+ REFERENCES contactgroups(contactgroup_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ contact_id integer NOT NULL
+ REFERENCES contacts(contact_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ created timestamp with time zone DEFAULT now() NOT NULL,
+ PRIMARY KEY (contactgroup_id, contact_id)
+);
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2010042300.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2010042300.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,4 @@
+-- Updates from version 0.4-beta
+
+ALTER TABLE users ALTER last_login DROP NOT NULL;
+ALTER TABLE users ALTER last_login SET DEFAULT NULL;
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2010100600.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2010100600.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,7 @@
+-- Updates from version 0.4.2
+
+DROP INDEX users_username_id_idx;
+ALTER TABLE users ADD CONSTRAINT users_username_key UNIQUE (username, mail_host);
+ALTER TABLE contacts ALTER email TYPE varchar(255);
+
+TRUNCATE messages;
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2011011200.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2011011200.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,7 @@
+-- Updates from version 0.5.x
+
+ALTER TABLE contacts ADD words TEXT NULL;
+CREATE INDEX contactgroupmembers_contact_id_idx ON contactgroupmembers (contact_id);
+
+TRUNCATE messages;
+TRUNCATE cache;
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2011092800.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2011092800.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,64 @@
+-- Updates from version 0.6
+
+CREATE TABLE dictionary (
+ user_id integer DEFAULT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ "language" varchar(5) NOT NULL,
+ data text NOT NULL,
+ CONSTRAINT dictionary_user_id_language_key UNIQUE (user_id, "language")
+);
+
+CREATE SEQUENCE search_ids
+ INCREMENT BY 1
+ NO MAXVALUE
+ NO MINVALUE
+ CACHE 1;
+
+CREATE TABLE searches (
+ search_id integer DEFAULT nextval('search_ids'::text) PRIMARY KEY,
+ user_id integer NOT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ "type" smallint DEFAULT 0 NOT NULL,
+ name varchar(128) NOT NULL,
+ data text NOT NULL,
+ CONSTRAINT searches_user_id_key UNIQUE (user_id, "type", name)
+);
+
+DROP SEQUENCE message_ids;
+DROP TABLE messages;
+
+CREATE TABLE cache_index (
+ user_id integer NOT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ mailbox varchar(255) NOT NULL,
+ changed timestamp with time zone DEFAULT now() NOT NULL,
+ valid smallint NOT NULL DEFAULT 0,
+ data text NOT NULL,
+ PRIMARY KEY (user_id, mailbox)
+);
+
+CREATE INDEX cache_index_changed_idx ON cache_index (changed);
+
+CREATE TABLE cache_thread (
+ user_id integer NOT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ mailbox varchar(255) NOT NULL,
+ changed timestamp with time zone DEFAULT now() NOT NULL,
+ data text NOT NULL,
+ PRIMARY KEY (user_id, mailbox)
+);
+
+CREATE INDEX cache_thread_changed_idx ON cache_thread (changed);
+
+CREATE TABLE cache_messages (
+ user_id integer NOT NULL
+ REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
+ mailbox varchar(255) NOT NULL,
+ uid integer NOT NULL,
+ changed timestamp with time zone DEFAULT now() NOT NULL,
+ data text NOT NULL,
+ flags integer NOT NULL DEFAULT 0,
+ PRIMARY KEY (user_id, mailbox, uid)
+);
+
+CREATE INDEX cache_messages_changed_idx ON cache_messages (changed);
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2011111600.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2011111600.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,3 @@
+-- Updates from version 0.7-beta
+
+ALTER TABLE "session" ALTER sess_id TYPE varchar(128);
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2011121400.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2011121400.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,5 @@
+-- Updates from version 0.7
+
+DROP INDEX contacts_user_id_idx;
+CREATE INDEX contacts_user_id_idx ON contacts USING btree (user_id, del);
+ALTER TABLE contacts ALTER email TYPE text;
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2012080700.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2012080700.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,7 @@
+-- Updates from version 0.8
+
+ALTER TABLE cache DROP COLUMN cache_id;
+DROP SEQUENCE cache_ids;
+
+ALTER TABLE users DROP COLUMN alias;
+CREATE INDEX identities_email_idx ON identities (email, del);
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2013011000.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2013011000.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,4 @@
+CREATE TABLE "system" (
+ name varchar(64) NOT NULL PRIMARY KEY,
+ value text
+);
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2013042700.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2013042700.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,14 @@
+ALTER SEQUENCE user_ids RENAME TO users_seq;
+ALTER TABLE users ALTER COLUMN user_id SET DEFAULT nextval('users_seq'::text);
+
+ALTER SEQUENCE identity_ids RENAME TO identities_seq;
+ALTER TABLE identities ALTER COLUMN identity_id SET DEFAULT nextval('identities_seq'::text);
+
+ALTER SEQUENCE contact_ids RENAME TO contacts_seq;
+ALTER TABLE contacts ALTER COLUMN contact_id SET DEFAULT nextval('contacts_seq'::text);
+
+ALTER SEQUENCE contactgroups_ids RENAME TO contactgroups_seq;
+ALTER TABLE contactgroups ALTER COLUMN contactgroup_id SET DEFAULT nextval('contactgroups_seq'::text);
+
+ALTER SEQUENCE search_ids RENAME TO searches_seq;
+ALTER TABLE searches ALTER COLUMN search_id SET DEFAULT nextval('searches_seq'::text);
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2013052500.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2013052500.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,8 @@
+CREATE TABLE "cache_shared" (
+ cache_key varchar(255) NOT NULL,
+ created timestamp with time zone DEFAULT now() NOT NULL,
+ data text NOT NULL
+);
+
+CREATE INDEX cache_shared_cache_key_idx ON "cache_shared" (cache_key);
+CREATE INDEX cache_shared_created_idx ON "cache_shared" (created);
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2013061000.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2013061000.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,24 @@
+ALTER TABLE "cache" ADD expires timestamp with time zone DEFAULT NULL;
+ALTER TABLE "cache_shared" ADD expires timestamp with time zone DEFAULT NULL;
+ALTER TABLE "cache_index" ADD expires timestamp with time zone DEFAULT NULL;
+ALTER TABLE "cache_thread" ADD expires timestamp with time zone DEFAULT NULL;
+ALTER TABLE "cache_messages" ADD expires timestamp with time zone DEFAULT NULL;
+
+-- initialize expires column with created/changed date + 7days
+UPDATE "cache" SET expires = created + interval '604800 seconds';
+UPDATE "cache_shared" SET expires = created + interval '604800 seconds';
+UPDATE "cache_index" SET expires = changed + interval '604800 seconds';
+UPDATE "cache_thread" SET expires = changed + interval '604800 seconds';
+UPDATE "cache_messages" SET expires = changed + interval '604800 seconds';
+
+DROP INDEX cache_created_idx;
+DROP INDEX cache_shared_created_idx;
+ALTER TABLE "cache_index" DROP "changed";
+ALTER TABLE "cache_thread" DROP "changed";
+ALTER TABLE "cache_messages" DROP "changed";
+
+CREATE INDEX cache_expires_idx ON "cache" (expires);
+CREATE INDEX cache_shared_expires_idx ON "cache_shared" (expires);
+CREATE INDEX cache_index_expires_idx ON "cache_index" (expires);
+CREATE INDEX cache_thread_expires_idx ON "cache_thread" (expires);
+CREATE INDEX cache_messages_expires_idx ON "cache_messages" (expires);
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2014042900.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2014042900.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+-- empty
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/postgres/2015030800.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/postgres/2015030800.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+-- empty
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/sqlite.initial.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite.initial.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,204 @@
+-- Roundcube Webmail initial database structure
+
+--
+-- Table structure for table contacts and related
+--
+
+CREATE TABLE contacts (
+ contact_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL,
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ del tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default '',
+ email text NOT NULL default '',
+ firstname varchar(128) NOT NULL default '',
+ surname varchar(128) NOT NULL default '',
+ vcard text NOT NULL default '',
+ words text NOT NULL default ''
+);
+
+CREATE INDEX ix_contacts_user_id ON contacts(user_id, del);
+
+
+CREATE TABLE contactgroups (
+ contactgroup_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL default '0',
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ del tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default ''
+);
+
+CREATE INDEX ix_contactgroups_user_id ON contactgroups(user_id, del);
+
+
+CREATE TABLE contactgroupmembers (
+ contactgroup_id integer NOT NULL,
+ contact_id integer NOT NULL default '0',
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (contactgroup_id, contact_id)
+);
+
+CREATE INDEX ix_contactgroupmembers_contact_id ON contactgroupmembers (contact_id);
+
+--
+-- Table structure for table identities
+--
+
+CREATE TABLE identities (
+ identity_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL default '0',
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ del tinyint NOT NULL default '0',
+ standard tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default '',
+ organization varchar(128) default '',
+ email varchar(128) NOT NULL default '',
+ "reply-to" varchar(128) NOT NULL default '',
+ bcc varchar(128) NOT NULL default '',
+ signature text NOT NULL default '',
+ html_signature tinyint NOT NULL default '0'
+);
+
+CREATE INDEX ix_identities_user_id ON identities(user_id, del);
+CREATE INDEX ix_identities_email ON identities(email, del);
+
+--
+-- Table structure for table users
+--
+
+CREATE TABLE users (
+ user_id integer NOT NULL PRIMARY KEY,
+ username varchar(128) NOT NULL default '',
+ mail_host varchar(128) NOT NULL default '',
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ last_login datetime DEFAULT NULL,
+ language varchar(5),
+ preferences text NOT NULL default ''
+);
+
+CREATE UNIQUE INDEX ix_users_username ON users(username, mail_host);
+
+--
+-- Table structure for table session
+--
+
+CREATE TABLE session (
+ sess_id varchar(128) NOT NULL PRIMARY KEY,
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ ip varchar(40) NOT NULL default '',
+ vars text NOT NULL
+);
+
+CREATE INDEX ix_session_changed ON session (changed);
+
+--
+-- Table structure for table dictionary
+--
+
+CREATE TABLE dictionary (
+ user_id integer DEFAULT NULL,
+ "language" varchar(5) NOT NULL,
+ data text NOT NULL
+);
+
+CREATE UNIQUE INDEX ix_dictionary_user_language ON dictionary (user_id, "language");
+
+--
+-- Table structure for table searches
+--
+
+CREATE TABLE searches (
+ search_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL DEFAULT '0',
+ "type" smallint NOT NULL DEFAULT '0',
+ name varchar(128) NOT NULL,
+ data text NOT NULL
+);
+
+CREATE UNIQUE INDEX ix_searches_user_type_name ON searches (user_id, type, name);
+
+--
+-- Table structure for table cache
+--
+
+CREATE TABLE cache (
+ user_id integer NOT NULL default 0,
+ cache_key varchar(128) NOT NULL default '',
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ expires datetime DEFAULT NULL,
+ data text NOT NULL
+);
+
+CREATE INDEX ix_cache_user_cache_key ON cache(user_id, cache_key);
+CREATE INDEX ix_cache_expires ON cache(expires);
+
+--
+-- Table structure for table cache_shared
+--
+
+CREATE TABLE cache_shared (
+ cache_key varchar(255) NOT NULL,
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ expires datetime DEFAULT NULL,
+ data text NOT NULL
+);
+
+CREATE INDEX ix_cache_shared_cache_key ON cache_shared(cache_key);
+CREATE INDEX ix_cache_shared_expires ON cache_shared(expires);
+
+--
+-- Table structure for table cache_index
+--
+
+CREATE TABLE cache_index (
+ user_id integer NOT NULL,
+ mailbox varchar(255) NOT NULL,
+ expires datetime DEFAULT NULL,
+ valid smallint NOT NULL DEFAULT '0',
+ data text NOT NULL,
+ PRIMARY KEY (user_id, mailbox)
+);
+
+CREATE INDEX ix_cache_index_expires ON cache_index (expires);
+
+--
+-- Table structure for table cache_thread
+--
+
+CREATE TABLE cache_thread (
+ user_id integer NOT NULL,
+ mailbox varchar(255) NOT NULL,
+ expires datetime DEFAULT NULL,
+ data text NOT NULL,
+ PRIMARY KEY (user_id, mailbox)
+);
+
+CREATE INDEX ix_cache_thread_expires ON cache_thread (expires);
+
+--
+-- Table structure for table cache_messages
+--
+
+CREATE TABLE cache_messages (
+ user_id integer NOT NULL,
+ mailbox varchar(255) NOT NULL,
+ uid integer NOT NULL,
+ expires datetime DEFAULT NULL,
+ data text NOT NULL,
+ flags integer NOT NULL DEFAULT '0',
+ PRIMARY KEY (user_id, mailbox, uid)
+);
+
+CREATE INDEX ix_cache_messages_expires ON cache_messages (expires);
+
+--
+-- Table structure for table system
+--
+
+CREATE TABLE system (
+ name varchar(64) NOT NULL PRIMARY KEY,
+ value text NOT NULL
+);
+
+INSERT INTO system (name, value) VALUES ('roundcube-version', '2015030800');
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2008030300.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2008030300.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,25 @@
+-- Updates from version 0.1-stable to 0.1.1
+
+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_cache_uid ON messages(user_id,cache_key,uid);
+CREATE INDEX ix_users_username ON users(username);
+CREATE INDEX ix_users_alias ON users(alias);
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2008060900.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2008060900.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,3 @@
+-- Updates from version 0.2-alpha
+
+CREATE INDEX ix_messages_created ON messages (created);
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2008092100.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2008092100.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,4 @@
+-- Updates from version 0.2-beta
+
+CREATE INDEX ix_session_changed ON session (changed);
+CREATE INDEX ix_cache_created ON cache (created);
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2009090400.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2009090400.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,8 @@
+-- Updates from version 0.3-stable
+
+DELETE FROM messages;
+DROP INDEX ix_messages_user_cache_uid;
+CREATE UNIQUE INDEX ix_messages_user_cache_uid ON messages (user_id,cache_key,uid);
+CREATE INDEX ix_messages_index ON messages (user_id,cache_key,idx);
+DROP INDEX ix_contacts_user_id;
+CREATE INDEX ix_contacts_user_id ON contacts(user_id, email);
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2009103100.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2009103100.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,61 @@
+-- Updates from version 0.3.1
+
+-- ALTER TABLE identities ADD COLUMN changed datetime NOT NULL default '0000-00-00 00:00:00'; --
+
+CREATE TABLE temp_identities (
+ identity_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL default '0',
+ standard tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default '',
+ organization varchar(128) default '',
+ email varchar(128) NOT NULL default '',
+ "reply-to" varchar(128) NOT NULL default '',
+ bcc varchar(128) NOT NULL default '',
+ signature text NOT NULL default '',
+ html_signature tinyint NOT NULL default '0'
+);
+INSERT INTO temp_identities (identity_id, user_id, standard, name, organization, email, "reply-to", bcc, signature, html_signature)
+ SELECT identity_id, user_id, standard, name, organization, email, "reply-to", bcc, signature, html_signature
+ FROM identities WHERE del=0;
+
+DROP INDEX ix_identities_user_id;
+DROP TABLE identities;
+
+CREATE TABLE identities (
+ identity_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL default '0',
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ del tinyint NOT NULL default '0',
+ standard tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default '',
+ organization varchar(128) default '',
+ email varchar(128) NOT NULL default '',
+ "reply-to" varchar(128) NOT NULL default '',
+ bcc varchar(128) NOT NULL default '',
+ signature text NOT NULL default '',
+ html_signature tinyint NOT NULL default '0'
+);
+CREATE INDEX ix_identities_user_id ON identities(user_id, del);
+
+INSERT INTO identities (identity_id, user_id, standard, name, organization, email, "reply-to", bcc, signature, html_signature)
+ SELECT identity_id, user_id, standard, name, organization, email, "reply-to", bcc, signature, html_signature
+ FROM temp_identities;
+
+DROP TABLE temp_identities;
+
+CREATE TABLE contactgroups (
+ contactgroup_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL default '0',
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ del tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default ''
+);
+
+CREATE INDEX ix_contactgroups_user_id ON contactgroups(user_id, del);
+
+CREATE TABLE contactgroupmembers (
+ contactgroup_id integer NOT NULL,
+ contact_id integer NOT NULL default '0',
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ PRIMARY KEY (contactgroup_id, contact_id)
+);
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2010042300.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2010042300.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,35 @@
+-- Updates from version 0.4-beta
+
+CREATE TABLE tmp_users (
+ user_id integer NOT NULL PRIMARY KEY,
+ username varchar(128) NOT NULL default '',
+ mail_host varchar(128) NOT NULL default '',
+ alias varchar(128) NOT NULL default '',
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ last_login datetime NOT NULL default '0000-00-00 00:00:00',
+ language varchar(5),
+ preferences text NOT NULL default ''
+);
+
+INSERT INTO tmp_users (user_id, username, mail_host, alias, created, last_login, language, preferences)
+ SELECT user_id, username, mail_host, alias, created, last_login, language, preferences FROM users;
+
+DROP TABLE users;
+
+CREATE TABLE users (
+ user_id integer NOT NULL PRIMARY KEY,
+ username varchar(128) NOT NULL default '',
+ mail_host varchar(128) NOT NULL default '',
+ alias varchar(128) NOT NULL default '',
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ last_login datetime DEFAULT NULL,
+ language varchar(5),
+ preferences text NOT NULL default ''
+);
+
+INSERT INTO users (user_id, username, mail_host, alias, created, last_login, language, preferences)
+ SELECT user_id, username, mail_host, alias, created, last_login, language, preferences FROM tmp_users;
+
+CREATE INDEX ix_users_username ON users(username);
+CREATE INDEX ix_users_alias ON users(alias);
+DROP TABLE tmp_users;
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2010100600.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2010100600.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,40 @@
+-- Updates from version 0.4.2
+
+DROP INDEX ix_users_username;
+CREATE UNIQUE INDEX ix_users_username ON users(username, mail_host);
+
+CREATE TABLE contacts_tmp (
+ contact_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL default '0',
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ del tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default '',
+ email varchar(255) NOT NULL default '',
+ firstname varchar(128) NOT NULL default '',
+ surname varchar(128) NOT NULL default '',
+ vcard text NOT NULL default ''
+);
+
+INSERT INTO contacts_tmp (contact_id, user_id, changed, del, name, email, firstname, surname, vcard)
+ SELECT contact_id, user_id, changed, del, name, email, firstname, surname, vcard FROM contacts;
+
+DROP TABLE contacts;
+CREATE TABLE contacts (
+ contact_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL default '0',
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ del tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default '',
+ email varchar(255) NOT NULL default '',
+ firstname varchar(128) NOT NULL default '',
+ surname varchar(128) NOT NULL default '',
+ vcard text NOT NULL default ''
+);
+
+INSERT INTO contacts (contact_id, user_id, changed, del, name, email, firstname, surname, vcard)
+ SELECT contact_id, user_id, changed, del, name, email, firstname, surname, vcard FROM contacts_tmp;
+
+CREATE INDEX ix_contacts_user_id ON contacts(user_id, email);
+DROP TABLE contacts_tmp;
+
+DELETE FROM messages;
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2011011200.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2011011200.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,41 @@
+-- Updates from version 0.5.x
+
+CREATE TABLE contacts_tmp (
+ contact_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL default '0',
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ del tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default '',
+ email varchar(255) NOT NULL default '',
+ firstname varchar(128) NOT NULL default '',
+ surname varchar(128) NOT NULL default '',
+ vcard text NOT NULL default ''
+);
+
+INSERT INTO contacts_tmp (contact_id, user_id, changed, del, name, email, firstname, surname, vcard)
+ SELECT contact_id, user_id, changed, del, name, email, firstname, surname, vcard FROM contacts;
+
+DROP TABLE contacts;
+CREATE TABLE contacts (
+ contact_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL default '0',
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ del tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default '',
+ email varchar(255) NOT NULL default '',
+ firstname varchar(128) NOT NULL default '',
+ surname varchar(128) NOT NULL default '',
+ vcard text NOT NULL default '',
+ words text NOT NULL default ''
+);
+
+INSERT INTO contacts (contact_id, user_id, changed, del, name, email, firstname, surname, vcard)
+ SELECT contact_id, user_id, changed, del, name, email, firstname, surname, vcard FROM contacts_tmp;
+
+CREATE INDEX ix_contacts_user_id ON contacts(user_id, email);
+DROP TABLE contacts_tmp;
+
+
+DELETE FROM messages;
+DELETE FROM cache;
+CREATE INDEX ix_contactgroupmembers_contact_id ON contactgroupmembers (contact_id);
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2011092800.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2011092800.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,54 @@
+-- Updates from version 0.6
+
+CREATE TABLE dictionary (
+ user_id integer DEFAULT NULL,
+ "language" varchar(5) NOT NULL,
+ data text NOT NULL
+);
+
+CREATE UNIQUE INDEX ix_dictionary_user_language ON dictionary (user_id, "language");
+
+CREATE TABLE searches (
+ search_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL DEFAULT '0',
+ "type" smallint NOT NULL DEFAULT '0',
+ name varchar(128) NOT NULL,
+ data text NOT NULL
+);
+
+CREATE UNIQUE INDEX ix_searches_user_type_name ON searches (user_id, type, name);
+
+DROP TABLE messages;
+
+CREATE TABLE cache_index (
+ user_id integer NOT NULL,
+ mailbox varchar(255) NOT NULL,
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ valid smallint NOT NULL DEFAULT '0',
+ data text NOT NULL,
+ PRIMARY KEY (user_id, mailbox)
+);
+
+CREATE INDEX ix_cache_index_changed ON cache_index (changed);
+
+CREATE TABLE cache_thread (
+ user_id integer NOT NULL,
+ mailbox varchar(255) NOT NULL,
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ data text NOT NULL,
+ PRIMARY KEY (user_id, mailbox)
+);
+
+CREATE INDEX ix_cache_thread_changed ON cache_thread (changed);
+
+CREATE TABLE cache_messages (
+ user_id integer NOT NULL,
+ mailbox varchar(255) NOT NULL,
+ uid integer NOT NULL,
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ data text NOT NULL,
+ flags integer NOT NULL DEFAULT '0',
+ PRIMARY KEY (user_id, mailbox, uid)
+);
+
+CREATE INDEX ix_cache_messages_changed ON cache_messages (changed);
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2011111600.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2011111600.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,11 @@
+-- Updates from version 0.7-beta
+
+DROP TABLE session;
+CREATE TABLE session (
+ sess_id varchar(128) NOT NULL PRIMARY KEY,
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ ip varchar(40) NOT NULL default '',
+ vars text NOT NULL
+);
+CREATE INDEX ix_session_changed ON session (changed);
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2011121400.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2011121400.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,38 @@
+-- Updates from version 0.7
+
+CREATE TABLE contacts_tmp (
+ contact_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL,
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ del tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default '',
+ email text NOT NULL default '',
+ firstname varchar(128) NOT NULL default '',
+ surname varchar(128) NOT NULL default '',
+ vcard text NOT NULL default '',
+ words text NOT NULL default ''
+);
+
+INSERT INTO contacts_tmp (contact_id, user_id, changed, del, name, email, firstname, surname, vcard, words)
+ SELECT contact_id, user_id, changed, del, name, email, firstname, surname, vcard, words FROM contacts;
+
+DROP TABLE contacts;
+
+CREATE TABLE contacts (
+ contact_id integer NOT NULL PRIMARY KEY,
+ user_id integer NOT NULL,
+ changed datetime NOT NULL default '0000-00-00 00:00:00',
+ del tinyint NOT NULL default '0',
+ name varchar(128) NOT NULL default '',
+ email text NOT NULL default '',
+ firstname varchar(128) NOT NULL default '',
+ surname varchar(128) NOT NULL default '',
+ vcard text NOT NULL default '',
+ words text NOT NULL default ''
+);
+
+INSERT INTO contacts (contact_id, user_id, changed, del, name, email, firstname, surname, vcard, words)
+ SELECT contact_id, user_id, changed, del, name, email, firstname, surname, vcard, words FROM contacts_tmp;
+
+CREATE INDEX ix_contacts_user_id ON contacts(user_id, del);
+DROP TABLE contacts_tmp;
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2012080700.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2012080700.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,44 @@
+-- Updates from version 0.8
+
+DROP TABLE cache;
+CREATE TABLE cache (
+ user_id integer NOT NULL default 0,
+ cache_key varchar(128) NOT NULL default '',
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ data text NOT NULL
+);
+
+CREATE INDEX ix_cache_user_cache_key ON cache(user_id, cache_key);
+CREATE INDEX ix_cache_created ON cache(created);
+
+CREATE TABLE tmp_users (
+ user_id integer NOT NULL PRIMARY KEY,
+ username varchar(128) NOT NULL default '',
+ mail_host varchar(128) NOT NULL default '',
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ last_login datetime DEFAULT NULL,
+ language varchar(5),
+ preferences text NOT NULL default ''
+);
+
+INSERT INTO tmp_users (user_id, username, mail_host, created, last_login, language, preferences)
+ SELECT user_id, username, mail_host, created, last_login, language, preferences FROM users;
+
+DROP TABLE users;
+
+CREATE TABLE users (
+ user_id integer NOT NULL PRIMARY KEY,
+ username varchar(128) NOT NULL default '',
+ mail_host varchar(128) NOT NULL default '',
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ last_login datetime DEFAULT NULL,
+ language varchar(5),
+ preferences text NOT NULL default ''
+);
+
+INSERT INTO users (user_id, username, mail_host, created, last_login, language, preferences)
+ SELECT user_id, username, mail_host, created, last_login, language, preferences FROM tmp_users;
+
+CREATE UNIQUE INDEX ix_users_username ON users(username, mail_host);
+
+CREATE INDEX ix_identities_email ON identities(email, del);
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2013011000.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2013011000.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,6 @@
+-- Updates from version 0.9-beta
+
+CREATE TABLE IF NOT EXISTS system (
+ name varchar(64) NOT NULL PRIMARY KEY,
+ value text NOT NULL
+);
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2013011700.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2013011700.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,2 @@
+-- drop temp table created in 2012080700.sql
+DROP TABLE IF EXISTS tmp_users;
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2013042700.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2013042700.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+-- empty
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2013052500.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2013052500.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,8 @@
+CREATE TABLE cache_shared (
+ cache_key varchar(255) NOT NULL,
+ created datetime NOT NULL default '0000-00-00 00:00:00',
+ data text NOT NULL
+);
+
+CREATE INDEX ix_cache_shared_cache_key ON cache_shared(cache_key);
+CREATE INDEX ix_cache_shared_created ON cache_shared(created);
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2013061000.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2013061000.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,48 @@
+DROP TABLE cache_index;
+DROP TABLE cache_thread;
+DROP TABLE cache_messages;
+
+ALTER TABLE cache ADD expires datetime DEFAULT NULL;
+DROP INDEX ix_cache_created;
+
+ALTER TABLE cache_shared ADD expires datetime DEFAULT NULL;
+DROP INDEX ix_cache_shared_created;
+
+UPDATE cache SET expires = datetime(created, '+604800 seconds');
+UPDATE cache_shared SET expires = datetime(created, '+604800 seconds');
+
+CREATE INDEX ix_cache_expires ON cache(expires);
+CREATE INDEX ix_cache_shared_expires ON cache_shared(expires);
+
+CREATE TABLE cache_index (
+ user_id integer NOT NULL,
+ mailbox varchar(255) NOT NULL,
+ expires datetime DEFAULT NULL,
+ valid smallint NOT NULL DEFAULT '0',
+ data text NOT NULL,
+ PRIMARY KEY (user_id, mailbox)
+);
+
+CREATE INDEX ix_cache_index_expires ON cache_index (expires);
+
+CREATE TABLE cache_thread (
+ user_id integer NOT NULL,
+ mailbox varchar(255) NOT NULL,
+ expires datetime DEFAULT NULL,
+ data text NOT NULL,
+ PRIMARY KEY (user_id, mailbox)
+);
+
+CREATE INDEX ix_cache_thread_expires ON cache_thread (expires);
+
+CREATE TABLE cache_messages (
+ user_id integer NOT NULL,
+ mailbox varchar(255) NOT NULL,
+ uid integer NOT NULL,
+ expires datetime DEFAULT NULL,
+ data text NOT NULL,
+ flags integer NOT NULL DEFAULT '0',
+ PRIMARY KEY (user_id, mailbox, uid)
+);
+
+CREATE INDEX ix_cache_messages_expires ON cache_messages (expires);
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2014042900.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2014042900.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+-- empty
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b SQL/sqlite/2015030800.sql
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SQL/sqlite/2015030800.sql Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+-- empty
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b bin/cleandb.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/cleandb.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,78 @@
+#!/usr/bin/env php
+ |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
+
+require INSTALL_PATH.'program/include/clisetup.php';
+
+// mapping for table name => primary key
+$primary_keys = array(
+ 'contacts' => "contact_id",
+ 'contactgroups' => "contactgroup_id",
+);
+
+// connect to DB
+$RCMAIL = rcube::get_instance();
+$db = $RCMAIL->get_dbh();
+$db->db_connect('w');
+
+if (!$db->is_connected() || $db->is_error()) {
+ rcube::raise_error("No DB connection", false, true);
+}
+
+if (!empty($_SERVER['argv'][1]))
+ $days = intval($_SERVER['argv'][1]);
+else
+ $days = 7;
+
+// remove all deleted records older than two days
+$threshold = date('Y-m-d 00:00:00', time() - $days * 86400);
+
+foreach (array('contacts','contactgroups','identities') as $table) {
+
+ $sqltable = $db->table_name($table, true);
+
+ // also delete linked records
+ // could be skipped for databases which respect foreign key constraints
+ if ($db->db_provider == 'sqlite'
+ && ($table == 'contacts' || $table == 'contactgroups')
+ ) {
+ $pk = $primary_keys[$table];
+ $memberstable = $db->table_name('contactgroupmembers');
+
+ $db->query(
+ "DELETE FROM " . $db->quote_identifier($memberstable).
+ " WHERE `$pk` IN (".
+ "SELECT `$pk` FROM $sqltable".
+ " WHERE `del` = 1 AND `changed` < ?".
+ ")",
+ $threshold);
+
+ echo $db->affected_rows() . " records deleted from '$memberstable'\n";
+ }
+
+ // delete outdated records
+ $db->query("DELETE FROM $sqltable WHERE `del` = 1 AND `changed` < ?", $threshold);
+
+ echo $db->affected_rows() . " records deleted from '$table'\n";
+}
+
+?>
diff -r 000000000000 -r 4681f974d28b bin/cssshrink.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/cssshrink.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,62 @@
+#!/bin/sh
+PWD=`dirname "$0"`
+JAR_DIR='/tmp'
+VERSION='2.4.8'
+COMPILER_URL="https://github.com/yui/yuicompressor/releases/download/v${VERSION}/yuicompressor-${VERSION}.zip"
+
+do_shrink() {
+ rm -f "$2"
+ java -jar $JAR_DIR/yuicompressor.jar -v -o "$2" "$1"
+}
+
+if [ ! -w "$JAR_DIR" ]; then
+ JAR_DIR=$PWD
+fi
+
+if java -version >/dev/null 2>&1; then
+ :
+else
+ echo "Java not found. Please ensure that the 'java' program is in your PATH."
+ exit 1
+fi
+
+if [ ! -r "$JAR_DIR/yuicompressor.jar" ]; then
+ if which wget >/dev/null 2>&1 && which unzip >/dev/null 2>&1; then
+ wget "$COMPILER_URL" -O "/tmp/$$.zip"
+ elif which curl >/dev/null 2>&1 && which unzip >/dev/null 2>&1; then
+ curl "$COMPILER_URL" -o "/tmp/$$.zip"
+ else
+ echo "Please download $COMPILER_URL and extract compiler.jar to $JAR_DIR/."
+ exit 1
+ fi
+ (cd $JAR_DIR && unzip "/tmp/$$.zip" && mv "yuicompressor-${VERSION}.jar" "yuicompressor.jar")
+ rm -f "/tmp/$$.zip"
+fi
+
+# compress single file from argument
+if [ $# -gt 0 ]; then
+ CSS_FILE="$1"
+
+ echo "Shrinking $CSS_FILE"
+ minfile=`echo $CSS_FILE | sed -e 's/\.css$/\.min\.css/'`
+ do_shrink "$CSS_FILE" "$minfile"
+ exit
+fi
+
+DIRS="$PWD/../skins/* $PWD/../plugins/* $PWD/../plugins/*/skins/*"
+# default: compress application scripts
+for dir in $DIRS; do
+ for file in $dir/*.css; do
+ echo "$file" | grep -e '.min.css$' >/dev/null
+ if [ $? -eq 0 ]; then
+ continue
+ fi
+ if [ ! -f "$file" ]; then
+ continue
+ fi
+
+ echo "Shrinking $file"
+ minfile=`echo $file | sed -e 's/\.css$/\.min\.css/'`
+ do_shrink "$file" "$minfile"
+ done
+done
diff -r 000000000000 -r 4681f974d28b bin/decrypt.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/decrypt.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,67 @@
+#!/usr/bin/env php
+ |
+ +-----------------------------------------------------------------------+
+*/
+
+/**
+ * If http_received_header_encrypt is configured, the IP address and the
+ * host name of the added Received: header is encrypted with 3DES, to
+ * protect information that some could consider sensitve, yet their
+ * availability is a must in some circumstances.
+ *
+ * Such an encrypted Received: header might look like:
+ *
+ * Received: from DzgkvJBO5+bw+oje5JACeNIa/uSI4mRw2cy5YoPBba73eyBmjtyHnQ==
+ * [my0nUbjZXKtl7KVBZcsvWOxxtyVFxza4]
+ * with HTTP/1.1 (POST); Thu, 14 May 2009 19:17:28 +0200
+ *
+ * In this example, the two encrypted components are the sender host name
+ * (DzgkvJBO5+bw+oje5JACeNIa/uSI4mRw2cy5YoPBba73eyBmjtyHnQ==) and the IP
+ * address (my0nUbjZXKtl7KVBZcsvWOxxtyVFxza4).
+ *
+ * Using this tool, they can be decrypted into plain text:
+ *
+ * $ bin/decrypt.sh 'my0nUbjZXKtl7KVBZcsvWOxxtyVFxza4' \
+ * > 'DzgkvJBO5+bw+oje5JACeNIa/uSI4mRw2cy5YoPBba73eyBmjtyHnQ=='
+ * 84.3.187.208
+ * 5403BBD0.catv.pool.telekom.hu
+ * $
+ *
+ * Thus it is known that this particular message was sent by 84.3.187.208,
+ * having, at the time of sending, the name of 5403BBD0.catv.pool.telekom.hu.
+ *
+ * If (most likely binary) junk is shown, then
+ * - either the encryption password has, between the time the mail was sent
+ * and 'now', changed, or
+ * - you are dealing with counterfeit header data.
+ */
+
+define('INSTALL_PATH', realpath(__DIR__ .'/..') . '/');
+
+require INSTALL_PATH . 'program/include/clisetup.php';
+
+if ($argc < 2) {
+ die("Usage: " . basename($argv[0]) . " encrypted-hdr-part [encrypted-hdr-part ...]\n");
+}
+
+$RCMAIL = rcube::get_instance();
+
+for ($i = 1; $i < $argc; $i++) {
+ printf("%s\n", $RCMAIL->decrypt($argv[$i]));
+};
diff -r 000000000000 -r 4681f974d28b bin/deluser.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/deluser.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,125 @@
+#!/usr/bin/env php
+ |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
+
+require_once INSTALL_PATH . 'program/include/clisetup.php';
+
+function print_usage()
+{
+ print "Usage: deluser.sh [--host=mail_host] username\n";
+ print "--host=HOST The IMAP hostname or IP the given user is related to\n";
+}
+
+function _die($msg, $usage=false)
+{
+ fputs(STDERR, $msg . "\n");
+ if ($usage) print_usage();
+ exit(1);
+}
+
+$rcmail = rcmail::get_instance();
+
+// get arguments
+$args = rcube_utils::get_opt(array('h' => 'host'));
+$username = trim($args[0]);
+
+if (empty($username)) {
+ _die("Missing required parameters", true);
+}
+
+if (empty($args['host'])) {
+ $hosts = $rcmail->config->get('default_host', '');
+ if (is_string($hosts)) {
+ $args['host'] = $hosts;
+ }
+ else if (is_array($hosts) && count($hosts) == 1) {
+ $args['host'] = reset($hosts);
+ }
+ else {
+ _die("Specify a host name", true);
+ }
+
+ // host can be a URL like tls://192.168.12.44
+ $host_url = parse_url($args['host']);
+ if ($host_url['host']) {
+ $args['host'] = $host_url['host'];
+ }
+}
+
+// connect to DB
+$db = $rcmail->get_dbh();
+$db->db_connect('w');
+$transaction = false;
+
+if (!$db->is_connected() || $db->is_error()) {
+ _die("No DB connection\n" . $db->is_error());
+}
+
+// find user in loca database
+$user = rcube_user::query($username, $args['host']);
+
+if (!$user) {
+ die("User not found.\n");
+}
+
+// inform plugins about approaching user deletion
+$plugin = $rcmail->plugins->exec_hook('user_delete_prepare', array('user' => $user, 'username' => $username, 'host' => $args['host']));
+
+// let plugins cleanup their own user-related data
+if (!$plugin['abort']) {
+ $transaction = $db->startTransaction();
+ $plugin = $rcmail->plugins->exec_hook('user_delete', $plugin);
+}
+
+if ($plugin['abort']) {
+ if ($transaction) {
+ $db->rollbackTransaction();
+ }
+ _die("User deletion aborted by plugin");
+}
+
+// deleting the user record should be sufficient due to ON DELETE CASCADE foreign key references
+// but not all database backends actually support this so let's do it by hand
+foreach (array('identities','contacts','contactgroups','dictionary','cache','cache_index','cache_messages','cache_thread','searches','users') as $table) {
+ $db->query('DELETE FROM ' . $db->table_name($table, true) . ' WHERE `user_id` = ?', $user->ID);
+}
+
+if ($db->is_error()) {
+ $rcmail->plugins->exec_hook('user_delete_rollback', $plugin);
+ _die("DB error occurred: " . $db->is_error());
+}
+else {
+ // inform plugins about executed user deletion
+ $plugin = $rcmail->plugins->exec_hook('user_delete_commit', $plugin);
+
+ if ($plugin['abort']) {
+ unset($plugin['abort']);
+ $db->rollbackTransaction();
+ $rcmail->plugins->exec_hook('user_delete_rollback', $plugin);
+ }
+ else {
+ $db->endTransaction();
+ echo "Successfully deleted user $user->ID\n";
+ }
+}
+
diff -r 000000000000 -r 4681f974d28b bin/dumpschema.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/dumpschema.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,97 @@
+#!/usr/bin/env php
+ |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
+
+require INSTALL_PATH.'program/include/clisetup.php';
+
+/** callback function for schema dump **/
+function print_schema($dump)
+{
+ foreach ((array)$dump as $part)
+ echo $dump . "\n";
+}
+
+$config = new rcube_config();
+
+// don't allow public access if not in devel_mode
+if (!$config->get('devel_mode') && $_SERVER['REMOTE_ADDR']) {
+ header("HTTP/1.0 401 Access denied");
+ die("Access denied!");
+}
+
+$options = array(
+ 'use_transactions' => false,
+ 'log_line_break' => "\n",
+ 'idxname_format' => '%s',
+ 'debug' => false,
+ 'quote_identifier' => true,
+ 'force_defaults' => false,
+ 'portability' => false,
+);
+
+$dsnw = $config->get('db_dsnw');
+$dsn_array = MDB2::parseDSN($dsnw);
+
+// set options for postgres databases
+if ($dsn_array['phptype'] == 'pgsql') {
+ $options['disable_smart_seqname'] = true;
+ $options['seqname_format'] = '%s';
+}
+
+$schema =& MDB2_Schema::factory($dsnw, $options);
+$schema->db->supported['transactions'] = false;
+
+
+// send as text/xml when opened in browser
+if ($_SERVER['REMOTE_ADDR'])
+ header('Content-Type: text/xml');
+
+
+if (PEAR::isError($schema)) {
+ $error = $schema->getMessage() . ' ' . $schema->getUserInfo();
+}
+else {
+ $dump_config = array(
+ // 'output_mode' => 'file',
+ 'output' => 'print_schema',
+ );
+
+ $definition = $schema->getDefinitionFromDatabase();
+ $definition['charset'] = 'utf8';
+
+ if (PEAR::isError($definition)) {
+ $error = $definition->getMessage() . ' ' . $definition->getUserInfo();
+ }
+ else {
+ $operation = $schema->dumpDatabase($definition, $dump_config, MDB2_SCHEMA_DUMP_STRUCTURE);
+ if (PEAR::isError($operation)) {
+ $error = $operation->getMessage() . ' ' . $operation->getUserInfo();
+ }
+ }
+}
+
+$schema->disconnect();
+
+if ($error && !$_SERVER['REMOTE_ADDR'])
+ fputs(STDERR, $error);
+
+?>
diff -r 000000000000 -r 4681f974d28b bin/gc.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/gc.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+ |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
+
+require INSTALL_PATH.'program/include/clisetup.php';
+
+$rcmail = rcube::get_instance();
+
+$session_driver = $rcmail->config->get('session_storage', 'db');
+$session_lifetime = $rcmail->config->get('session_lifetime', 0) * 60 * 2;
+
+// Clean expired SQL sessions
+if ($session_driver == 'db' && $session_lifetime) {
+ $db = $rcmail->get_dbh();
+ $db->query("DELETE FROM " . $db->table_name('session')
+ . " WHERE changed < " . $db->now(-$session_lifetime));
+}
+
+// Clean caches and temp directory
+$rcmail->gc();
diff -r 000000000000 -r 4681f974d28b bin/indexcontacts.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/indexcontacts.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,54 @@
+#!/usr/bin/env php
+ |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
+
+require_once INSTALL_PATH.'program/include/clisetup.php';
+ini_set('memory_limit', -1);
+
+// connect to DB
+$RCMAIL = rcube::get_instance();
+
+$db = $RCMAIL->get_dbh();
+$db->db_connect('w');
+
+if (!$db->is_connected() || $db->is_error()) {
+ rcube::raise_error("No DB connection", false, true);
+}
+
+// iterate over all users
+$sql_result = $db->query("SELECT `user_id` FROM " . $db->table_name('users', true) . " ORDER BY `user_id`");
+while ($sql_result && ($sql_arr = $db->fetch_assoc($sql_result))) {
+ echo "Indexing contacts for user " . $sql_arr['user_id'] . "...";
+
+ $contacts = new rcube_contacts($db, $sql_arr['user_id']);
+ $contacts->set_pagesize(9999);
+
+ $result = $contacts->list_records();
+ while ($result->count && ($row = $result->next())) {
+ unset($row['words']);
+ $contacts->update($row['ID'], $row);
+ }
+
+ echo "done.\n";
+}
+
+?>
diff -r 000000000000 -r 4681f974d28b bin/installto.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/installto.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,87 @@
+#!/usr/bin/env php
+ |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
+
+require_once INSTALL_PATH . 'program/include/clisetup.php';
+
+$target_dir = unslashify($_SERVER['argv'][1]);
+
+if (empty($target_dir) || !is_dir(realpath($target_dir)))
+ rcube::raise_error("Invalid target: not a directory\nUsage: installto.sh ", false, true);
+
+// read version from iniset.php
+$iniset = @file_get_contents($target_dir . '/program/include/iniset.php');
+if (!preg_match('/define\(.RCMAIL_VERSION.,\s*.([0-9.]+[a-z-]*)/', $iniset, $m))
+ rcube::raise_error("No valid Roundcube installation found at $target_dir", false, true);
+
+$oldversion = $m[1];
+
+if (version_compare(version_parse($oldversion), version_parse(RCMAIL_VERSION), '>='))
+ rcube::raise_error("Installation at target location is up-to-date!", false, true);
+
+echo "Upgrading from $oldversion. Do you want to continue? (y/N)\n";
+$input = trim(fgets(STDIN));
+
+if (strtolower($input) == 'y') {
+ $err = false;
+ echo "Copying files to target location...";
+ $dirs = array('program','installer','bin','SQL','plugins','skins');
+ if (is_dir(INSTALL_PATH . 'vendor') && !is_file(INSTALL_PATH . 'composer.json')) {
+ $dirs[] = 'vendor';
+ }
+ foreach ($dirs as $dir) {
+ if (!system("rsync -avC " . INSTALL_PATH . "$dir/* $target_dir/$dir/")) {
+ $err = true;
+ break;
+ }
+ }
+ foreach (array('index.php','.htaccess','config/defaults.inc.php','composer.json-dist','CHANGELOG','README.md','UPGRADING','LICENSE','INSTALL') as $file) {
+ if (!system("rsync -av " . INSTALL_PATH . "$file $target_dir/$file")) {
+ $err = true;
+ break;
+ }
+ }
+ // remove old (<1.0) .htaccess file
+ @unlink("$target_dir/program/.htaccess");
+ echo "done.\n\n";
+
+ if (is_dir("$target_dir/skins/default")) {
+ echo "Removing old default skin...";
+ system("rm -rf $target_dir/skins/default $target_dir/plugins/jqueryui/themes/default");
+ foreach (glob(INSTALL_PATH . "plugins/*/skins") as $plugin_skin_dir) {
+ $plugin_skin_dir = preg_replace('!^.*' . INSTALL_PATH . '!', '', $plugin_skin_dir);
+ if (is_dir("$target_dir/$plugin_skin_dir/classic"))
+ system("rm -rf $target_dir/$plugin_skin_dir/default");
+ }
+ echo "done.\n\n";
+ }
+
+ if (!$err) {
+ echo "Running update script at target...\n";
+ system("cd $target_dir && php bin/update.sh --version=$oldversion");
+ echo "All done.\n";
+ }
+}
+else
+ echo "Update cancelled. See ya!\n";
+
+?>
diff -r 000000000000 -r 4681f974d28b bin/jsshrink.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/jsshrink.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,77 @@
+#!/bin/sh
+PWD=`dirname "$0"`
+JS_DIR="$PWD/../program/js"
+JAR_DIR='/tmp'
+LANG_IN='ECMASCRIPT3'
+# latest version requires Java 7, we'll use an older one
+#CLOSURE_COMPILER_URL='http://dl.google.com/closure-compiler/compiler-latest.zip'
+CLOSURE_COMPILER_URL='http://dl.google.com/closure-compiler/compiler-20131014.zip'
+
+do_shrink() {
+ rm -f "$2"
+ # copy the first comment block with license information for LibreJS
+ grep -q '@lic' $1 && sed -n '/\/\*/,/\*\// { p; /\*\//q; }' $1 > $2
+ java -jar $JAR_DIR/compiler.jar --compilation_level=SIMPLE_OPTIMIZATIONS --js="$1" --language_in="$3" >> $2
+}
+
+if [ ! -d "$JS_DIR" ]; then
+ echo "Directory $JS_DIR not found."
+ exit 1
+fi
+
+if [ ! -w "$JAR_DIR" ]; then
+ JAR_DIR=$PWD
+fi
+
+if java -version >/dev/null 2>&1; then
+ :
+else
+ echo "Java not found. Please ensure that the 'java' program is in your PATH."
+ exit 1
+fi
+
+if [ ! -r "$JAR_DIR/compiler.jar" ]; then
+ if which wget >/dev/null 2>&1 && which unzip >/dev/null 2>&1; then
+ wget "$CLOSURE_COMPILER_URL" -O "/tmp/$$.zip"
+ elif which curl >/dev/null 2>&1 && which unzip >/dev/null 2>&1; then
+ curl "$CLOSURE_COMPILER_URL" -o "/tmp/$$.zip"
+ else
+ echo "Please download $CLOSURE_COMPILER_URL and extract compiler.jar to $JAR_DIR/."
+ exit 1
+ fi
+ (cd $JAR_DIR && unzip "/tmp/$$.zip" "compiler.jar")
+ rm -f "/tmp/$$.zip"
+fi
+
+# compress single file from argument
+if [ $# -gt 0 ]; then
+ JS_DIR=`dirname "$1"`
+ JS_FILE="$1"
+
+ if [ $# -gt 1 ]; then
+ LANG_IN="$2"
+ fi
+
+ echo "Shrinking $JS_FILE"
+ minfile=`echo $JS_FILE | sed -e 's/\.js$/\.min\.js/'`
+ do_shrink "$JS_FILE" "$minfile" "$LANG_IN"
+ exit
+fi
+
+DIRS="$PWD/../program/js $PWD/../skins/* $PWD/../plugins/* $PWD/../plugins/*/skins/*"
+# default: compress application scripts
+for dir in $DIRS; do
+ for file in $dir/*.js; do
+ echo "$file" | grep -e '.min.js$' >/dev/null
+ if [ $? -eq 0 ]; then
+ continue
+ fi
+ if [ ! -f "$file" ]; then
+ continue
+ fi
+
+ echo "Shrinking $file"
+ minfile=`echo $file | sed -e 's/\.js$/\.min\.js/'`
+ do_shrink "$file" "$minfile" "$LANG_IN"
+ done
+done
diff -r 000000000000 -r 4681f974d28b bin/makedoc.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/makedoc.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+TITLE="Roundcube Webmail"
+PACKAGES="Webmail"
+
+INSTALL_PATH="`dirname $0`/.."
+PATH_PROJECT=$INSTALL_PATH/program/include
+PATH_FRAMEWORK=$INSTALL_PATH/program/lib/Roundcube
+PATH_DOCS=$INSTALL_PATH/doc/phpdoc
+BIN_PHPDOC="`/usr/bin/which phpdoc`"
+
+if [ ! -x "$BIN_PHPDOC" ]
+then
+ echo "phpdoc not found: $BIN_PHPDOC"
+ exit 1
+fi
+
+OUTPUTFORMAT=HTML
+TEMPLATE=responsive-twig
+
+# make documentation
+$BIN_PHPDOC -d $PATH_PROJECT,$PATH_FRAMEWORK -t $PATH_DOCS --title "$TITLE" --defaultpackagename $PACKAGES \
+ --template=$TEMPLATE
+
diff -r 000000000000 -r 4681f974d28b bin/moduserprefs.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/moduserprefs.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,82 @@
+#!/usr/bin/env php
+ |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
+
+require_once INSTALL_PATH.'program/include/clisetup.php';
+
+function print_usage()
+{
+ print "Usage: moduserprefs.sh [--user=user-id] pref-name [pref-value|--delete]\n";
+ print "--user User ID in local database\n";
+ print "--delete Unset the given preference\n";
+}
+
+
+// get arguments
+$args = rcube_utils::get_opt(array('u' => 'user', 'd' => 'delete'));
+
+if ($_SERVER['argv'][1] == 'help') {
+ print_usage();
+ exit;
+}
+else if (empty($args[0]) || (!isset($args[1]) && !$args['delete'])) {
+ print "Missing required parameters.\n";
+ print_usage();
+ exit;
+}
+
+$pref_name = trim($args[0]);
+$pref_value = $args['delete'] ? null : trim($args[1]);
+
+// connect to DB
+$rcmail = rcube::get_instance();
+
+$db = $rcmail->get_dbh();
+$db->db_connect('w');
+
+if (!$db->is_connected() || $db->is_error())
+ die("No DB connection\n" . $db->is_error());
+
+$query = '1=1';
+
+if ($args['user'])
+ $query = '`user_id` = ' . intval($args['user']);
+
+// iterate over all users
+$sql_result = $db->query("SELECT * FROM " . $db->table_name('users', true) . " WHERE $query");
+while ($sql_result && ($sql_arr = $db->fetch_assoc($sql_result))) {
+ echo "Updating prefs for user " . $sql_arr['user_id'] . "...";
+
+ $user = new rcube_user($sql_arr['user_id'], $sql_arr);
+ $prefs = $old_prefs = $user->get_prefs();
+
+ $prefs[$pref_name] = $pref_value;
+
+ if ($prefs != $old_prefs) {
+ $user->save_prefs($prefs, true);
+ echo "saved.\n";
+ }
+ else {
+ echo "nothing changed.\n";
+ }
+}
+
+?>
diff -r 000000000000 -r 4681f974d28b bin/msgexport.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/msgexport.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,143 @@
+#!/usr/bin/env php
+', $pos, $max));
+}
+
+function export_mailbox($mbox, $filename)
+{
+ global $IMAP;
+
+ $IMAP->set_folder($mbox);
+
+ $index = $IMAP->index($mbox, null, 'ASC');
+ $count = $index->count();
+ $index = $index->get();
+
+ vputs("Getting message list of {$mbox}...");
+ vputs("$count messages\n");
+
+ if ($filename)
+ {
+ if (!($out = fopen($filename, 'w')))
+ {
+ vputs("Cannot write to output file\n");
+ return;
+ }
+ vputs("Writing to $filename\n");
+ }
+ else
+ $out = STDOUT;
+
+ for ($i = 0; $i < $count; $i++)
+ {
+ $headers = $IMAP->get_message_headers($index[$i]);
+ $from = current(rcube_mime::decode_address_list($headers->from, 1, false));
+
+ fwrite($out, sprintf("From %s %s UID %d\n", $from['mailto'], $headers->date, $headers->uid));
+ $IMAP->get_raw_body($headers->uid, $out);
+ fwrite($out, "\n\n\n");
+
+ progress_update($i+1, $count);
+ }
+ vputs("\ncomplete.\n");
+
+ if ($filename)
+ fclose($out);
+}
+
+
+// get arguments
+$opts = array('h' => 'host', 'u' => 'user', 'p' => 'pass', 'm' => 'mbox', 'f' => 'file');
+$args = rcube_utils::get_opt($opts) + array('host' => 'localhost', 'mbox' => 'INBOX');
+
+if ($_SERVER['argv'][1] == 'help')
+{
+ print_usage();
+ exit;
+}
+else if (!$args['host'])
+{
+ vputs("Missing required parameters.\n");
+ print_usage();
+ exit;
+}
+
+// prompt for username if not set
+if (empty($args['user']))
+{
+ vputs("IMAP user: ");
+ $args['user'] = trim(fgets(STDIN));
+}
+
+// prompt for password
+$args['pass'] = rcube_utils::prompt_silent("Password: ");
+
+
+// parse $host URL
+$a_host = parse_url($args['host']);
+if ($a_host['host'])
+{
+ $host = $a_host['host'];
+ $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? TRUE : FALSE;
+ $imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : 143);
+}
+else
+{
+ $host = $args['host'];
+ $imap_port = 143;
+}
+
+// instantiate IMAP class
+$IMAP = new rcube_imap(null);
+
+// try to connect to IMAP server
+if ($IMAP->connect($host, $args['user'], $args['pass'], $imap_port, $imap_ssl))
+{
+ vputs("IMAP login successful.\n");
+
+ $filename = null;
+ $mailboxes = $args['mbox'] == '*' ? $IMAP->list_folders(null) : array($args['mbox']);
+
+ foreach ($mailboxes as $mbox)
+ {
+ if ($args['file'])
+ $filename = preg_replace('/\.[a-z0-9]{3,4}$/i', '', $args['file']) . asciiwords($mbox) . '.mbox';
+ else if ($args['mbox'] == '*')
+ $filename = asciiwords($mbox) . '.mbox';
+
+ if ($args['mbox'] == '*' && in_array(strtolower($mbox), array('junk','spam','trash')))
+ continue;
+
+ export_mailbox($mbox, $filename);
+ }
+}
+else
+{
+ vputs("IMAP login failed.\n");
+}
+
+?>
diff -r 000000000000 -r 4681f974d28b bin/msgimport.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/msgimport.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,113 @@
+#!/usr/bin/env php
+ 'host', 'u' => 'user', 'p' => 'pass', 'm' => 'mbox', 'f' => 'file');
+$args = rcube_utils::get_opt($opts) + array('host' => 'localhost', 'mbox' => 'INBOX');
+
+if ($_SERVER['argv'][1] == 'help')
+{
+ print_usage();
+ exit;
+}
+else if (!($args['host'] && $args['file']))
+{
+ print "Missing required parameters.\n";
+ print_usage();
+ exit;
+}
+else if (!is_file($args['file']))
+{
+ rcube::raise_error("Cannot read message file.", false, true);
+}
+
+// prompt for username if not set
+if (empty($args['user']))
+{
+ //fwrite(STDOUT, "Please enter your name\n");
+ echo "IMAP user: ";
+ $args['user'] = trim(fgets(STDIN));
+}
+
+// prompt for password
+if (empty($args['pass']))
+{
+ $args['pass'] = rcube_utils::prompt_silent("Password: ");
+}
+
+// parse $host URL
+$a_host = parse_url($args['host']);
+if ($a_host['host'])
+{
+ $host = $a_host['host'];
+ $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? TRUE : FALSE;
+ $imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : 143);
+}
+else
+{
+ $host = $args['host'];
+ $imap_port = 143;
+}
+
+// instantiate IMAP class
+$IMAP = new rcube_imap(null);
+
+// try to connect to IMAP server
+if ($IMAP->connect($host, $args['user'], $args['pass'], $imap_port, $imap_ssl))
+{
+ print "IMAP login successful.\n";
+ print "Uploading messages...\n";
+
+ $count = 0;
+ $message = $lastline = '';
+
+ $fp = fopen($args['file'], 'r');
+ while (($line = fgets($fp)) !== false)
+ {
+ if (preg_match('/^From\s+-/', $line) && $lastline == '')
+ {
+ if (!empty($message))
+ {
+ if ($IMAP->save_message($args['mbox'], rtrim($message)))
+ $count++;
+ else
+ rcube::raise_error("Failed to save message to {$args['mbox']}", false, true);
+ $message = '';
+ }
+ continue;
+ }
+
+ $message .= $line;
+ $lastline = rtrim($line);
+ }
+
+ if (!empty($message) && $IMAP->save_message($args['mbox'], rtrim($message)))
+ $count++;
+
+ // upload message from file
+ if ($count)
+ print "$count messages successfully added to {$args['mbox']}.\n";
+ else
+ print "Adding messages failed!\n";
+}
+else
+{
+ rcube::raise_error("IMAP login failed.", false, true);
+}
+
+?>
diff -r 000000000000 -r 4681f974d28b bin/update.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/update.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,278 @@
+#!/usr/bin/env php
+ |
+ +-----------------------------------------------------------------------+
+*/
+if ($_SERVER['RCMAIL_CONFIG_DIR']) {
+ define('RCMAIL_CONFIG_DIR', $_SERVER['RCMAIL_CONFIG_DIR']);
+}
+
+if ($_SERVER['DEBIAN_PKG']) {
+ define('DEBIAN_PKG', TRUE);
+}
+
+define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
+
+require_once INSTALL_PATH . 'program/include/clisetup.php';
+
+// get arguments
+$opts = rcube_utils::get_opt(array('v' => 'version', 'y' => 'accept'));
+
+// ask user if no version is specified
+if (!$opts['version']) {
+ echo "What version are you upgrading from? Type '?' if you don't know.\n";
+ if (($input = trim(fgets(STDIN))) && preg_match('/^[0-9.]+[a-z-]*$/', $input))
+ $opts['version'] = $input;
+ else
+ $opts['version'] = RCMAIL_VERSION;
+}
+
+$RCI = rcmail_install::get_instance();
+$RCI->load_config();
+
+if ($RCI->configured) {
+ $success = true;
+
+ if (($messages = $RCI->check_config()) || $RCI->legacy_config) {
+ $success = false;
+ $err = 0;
+
+ // list old/replaced config options
+ if (is_array($messages['replaced'])) {
+ echo "WARNING: Replaced config options:\n";
+ echo "(These config options have been replaced or renamed)\n";
+
+ foreach ($messages['replaced'] as $msg) {
+ echo "- '" . $msg['prop'] . "' was replaced by '" . $msg['replacement'] . "'\n";
+ $err++;
+ }
+ echo "\n";
+ }
+
+ // list obsolete config options (just a notice)
+ if (is_array($messages['obsolete'])) {
+ echo "NOTICE: Obsolete config options:\n";
+ echo "(You still have some obsolete or inexistent properties set. This isn't a problem but should be noticed)\n";
+
+ foreach ($messages['obsolete'] as $msg) {
+ echo "- '" . $msg['prop'] . ($msg['name'] ? "': " . $msg['name'] : "'") . "\n";
+ $err++;
+ }
+ echo "\n";
+ }
+
+ if (!$err && $RCI->legacy_config) {
+ echo "WARNING: Your configuration needs to be migrated!\n";
+ echo "We changed the configuration files structure and your two config files main.inc.php and db.inc.php have to be merged into one single file.\n";
+ $err++;
+ }
+
+ // ask user to update config files
+ if ($err) {
+ if (!$opts['accept']) {
+ echo "Do you want me to fix your local configuration? (y/N)\n";
+ $input = trim(fgets(STDIN));
+ }
+
+ // positive: let's merge the local config with the defaults
+ if ($opts['accept'] || strtolower($input) == 'y') {
+ $error = $written = false;
+
+ if (!DEBIAN_PKG) {
+ // backup current config
+ echo ". backing up the current config file(s)...\n";
+
+ foreach (array('config', 'main', 'db') as $file) {
+ if (file_exists(RCMAIL_CONFIG_DIR . '/' . $file . '.inc.php')) {
+ if (!copy(RCMAIL_CONFIG_DIR . '/' . $file . '.inc.php', RCMAIL_CONFIG_DIR . '/' . $file . '.old.php')) {
+ $error = true;
+ }
+ }
+ }
+ }
+
+ if (!$error) {
+ $RCI->merge_config();
+ if (DEBIAN_PKG) {
+ echo ". writing " . RCMAIL_CONFIG_DIR . "/config.inc.php.dpkg-new...\n";
+ } else {
+ echo ". writing " . RCMAIL_CONFIG_DIR . "/config.inc.php...\n";
+ }
+ $written = $RCI->save_configfile($RCI->create_config());
+ }
+
+ // Success!
+ if ($written) {
+ echo "Done.\n";
+ echo "Your configuration files are now up-to-date!\n";
+
+ if ($messages['missing']) {
+ echo "But you still need to add the following missing options:\n";
+ foreach ($messages['missing'] as $msg)
+ echo "- '" . $msg['prop'] . ($msg['name'] ? "': " . $msg['name'] : "'") . "\n";
+ }
+
+ if (!DEBIAN_PKG) {
+ if ($RCI->legacy_config) {
+ foreach (array('main', 'db') as $file) {
+ @unlink(RCMAIL_CONFIG_DIR . '/' . $file . '.inc.php');
+ }
+ }
+ }
+ }
+ else {
+ echo "Failed to write config file(s)!\n";
+ echo "Grant write privileges to the current user or update the files manually according to the above messages.\n";
+ }
+ }
+ else {
+ echo "Please update your config files manually according to the above messages.\n";
+ }
+ }
+
+ // check dependencies based on the current configuration
+ if (is_array($messages['dependencies'])) {
+ echo "WARNING: Dependency check failed!\n";
+ echo "(Some of your configuration settings require other options to be configured or additional PHP modules to be installed)\n";
+
+ foreach ($messages['dependencies'] as $msg) {
+ echo "- " . $msg['prop'] . ': ' . $msg['explain'] . "\n";
+ }
+ echo "Please fix your config files and run this script again!\n";
+ echo "See ya.\n";
+ }
+ }
+
+ // check file type detection
+ if ($RCI->check_mime_detection()) {
+ echo "WARNING: File type detection doesn't work properly!\n";
+ echo "Please check the 'mime_magic' config option or the finfo functions of PHP and run this script again.\n";
+ }
+ if ($RCI->check_mime_extensions()) {
+ echo "WARNING: Mimetype to file extension mapping doesn't work properly!\n";
+ echo "Please check the 'mime_types' config option and run this script again.\n";
+ }
+
+ if (!DEBIAN_PKG) {
+ // check database schema
+ if ($RCI->config['db_dsnw']) {
+ echo "Executing database schema update.\n";
+ system("php " . INSTALL_PATH . "bin/updatedb.sh --package=roundcube --version=" . $opts['version']
+ . " --dir=" . INSTALL_PATH . "SQL", $res);
+
+ $success = !$res;
+ }
+ }
+
+ // update composer dependencies
+ if (is_file(INSTALL_PATH . 'composer.json') && is_readable(INSTALL_PATH . 'composer.json-dist')) {
+ $composer_data = json_decode(file_get_contents(INSTALL_PATH . 'composer.json'), true);
+ $composer_template = json_decode(file_get_contents(INSTALL_PATH . 'composer.json-dist'), true);
+ $comsposer_json = null;
+
+ // update the require section with the new dependencies
+ if (is_array($composer_data['require']) && is_array($composer_template['require'])) {
+ $composer_data['require'] = array_merge($composer_data['require'], $composer_template['require']);
+ /* TO BE ADDED LATER
+ $old_packages = array();
+ for ($old_packages as $pkg) {
+ if (array_key_exists($composer_data['require'], $pkg)) {
+ unset($composer_data['require'][$pkg]);
+ }
+ }
+ */
+ }
+
+ // update the repositories section with the new dependencies
+ if (is_array($composer_template['repositories'])) {
+ if (!is_array($composer_data['repositories'])) {
+ $composer_data['repositories'] = array();
+ }
+
+ foreach ($composer_template['repositories'] as $repo) {
+ $rkey = $repo['type'] . preg_replace('/^https?:/', '', $repo['url']) . $repo['package']['name'];
+ $existing = false;
+ foreach ($composer_data['repositories'] as $k => $_repo) {
+ if ($rkey == $_repo['type'] . preg_replace('/^https?:/', '', $_repo['url']) . $_repo['package']['name']) {
+ $existing = true;
+ break;
+ }
+ // remove old repos
+ else if (strpos($_repo['url'], 'git://git.kolab.org') === 0) {
+ unset($composer_data['repositories'][$k]);
+ }
+ }
+ if (!$existing) {
+ $composer_data['repositories'][] = $repo;
+ }
+ }
+
+ $composer_data['repositories'] = array_values($composer_data['repositories']);
+ }
+
+ // use the JSON encoder from the Composer package
+ if (is_file('composer.phar')) {
+ include 'phar://composer.phar/src/Composer/Json/JsonFile.php';
+ $comsposer_json = \Composer\Json\JsonFile::encode($composer_data);
+ }
+ // PHP 5.4's json_encode() does the job, too
+ else if (defined('JSON_PRETTY_PRINT')) {
+ $comsposer_json = json_encode($composer_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
+ }
+ else {
+ $success = false;
+ $comsposer_json = null;
+ }
+
+ // write updated composer.json back to disk
+ if ($comsposer_json && is_writeable(INSTALL_PATH . 'composer.json')) {
+ $success &= (bool)file_put_contents(INSTALL_PATH . 'composer.json', $comsposer_json);
+ }
+ else {
+ echo "WARNING: unable to update composer.json!\n";
+ echo "Please replace the 'require' section in your composer.json with the following:\n";
+
+ $require_json = '';
+ foreach ($composer_data['require'] as $pkg => $ver) {
+ $require_json .= sprintf(' "%s": "%s",'."\n", $pkg, $ver);
+ }
+
+ echo ' "require": {'."\n";
+ echo rtrim($require_json, ",\n");
+ echo "\n }\n\n";
+ }
+
+ echo "NOTE: Update dependencies by running `php composer.phar update --no-dev`\n";
+ }
+
+ // index contacts for fulltext searching
+ if ($opts['version'] && version_compare(version_parse($opts['version']), '0.6.0', '<')) {
+ system("php " . INSTALL_PATH . 'bin/indexcontacts.sh');
+ }
+
+ if ($success) {
+ echo "This instance of Roundcube is up-to-date.\n";
+ echo "Have fun!\n";
+ }
+}
+else {
+ echo "This instance of Roundcube is not yet configured!\n";
+ echo "Open http://url-to-roundcube/installer/ in your browser and follow the instuctions.\n";
+}
+
+?>
diff -r 000000000000 -r 4681f974d28b bin/updatecss.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/updatecss.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,122 @@
+#!/usr/bin/env php
+ |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
+
+require_once INSTALL_PATH . 'program/include/clisetup.php';
+
+// get arguments
+$opts = rcube_utils::get_opt(array(
+ 'd' => 'dir',
+));
+
+if (empty($opts['dir'])) {
+ print "Skin directory not specified (--dir). Using skins/ and plugins/*/skins/.\n";
+
+ $dir = INSTALL_PATH . 'skins';
+ $dir_p = INSTALL_PATH . 'plugins';
+ $skins = glob("$dir/*", GLOB_ONLYDIR);
+ $skins_p = glob("$dir_p/*/skins/*", GLOB_ONLYDIR);
+
+ $dirs = array_merge($skins, $skins_p);
+}
+// Check if directory exists
+else if (!file_exists($opts['dir'])) {
+ rcube::raise_error("Specified directory doesn't exist.", false, true);
+}
+else {
+ $dirs = array($opts['dir']);
+}
+
+foreach ($dirs as $dir) {
+ $img_dir = $dir . '/images';
+ if (!file_exists($img_dir)) {
+ continue;
+ }
+
+ $files = get_files($dir);
+ $images = get_images($img_dir);
+ $find = array();
+ $replace = array();
+
+ // build regexps array
+ foreach ($images as $path => $sum) {
+ $path_ex = str_replace('.', '\\.', $path);
+ $find[] = "#url\(['\"]?images/$path_ex(\?v=[a-f0-9-\.]+)?['\"]?\)#";
+ $replace[] = "url(images/$path?v=$sum)";
+ }
+
+ foreach ($files as $file) {
+ $file = $dir . '/' . $file;
+ print "File: $file\n";
+ $content = file_get_contents($file);
+ $content = preg_replace($find, $replace, $content, -1, $count);
+ if ($count) {
+ file_put_contents($file, $content);
+ }
+ }
+}
+
+
+function get_images($dir)
+{
+ $images = array();
+ $dh = opendir($dir);
+
+ while ($file = readdir($dh)) {
+ if (preg_match('/^(.+)\.(gif|ico|png|jpg|jpeg)$/', $file, $m)) {
+ $filepath = "$dir/$file";
+ $images[$file] = substr(md5_file($filepath), 0, 4) . '.' . filesize($filepath);
+ print "Image: $filepath ({$images[$file]})\n";
+ }
+ else if ($file != '.' && $file != '..' && is_dir($dir . '/' . $file)) {
+ foreach (get_images($dir . '/' . $file) as $img => $sum) {
+ $images[$file . '/' . $img] = $sum;
+ }
+ }
+ }
+
+ closedir($dh);
+
+ return $images;
+}
+
+function get_files($dir)
+{
+ $files = array();
+ $dh = opendir($dir);
+
+ while ($file = readdir($dh)) {
+ if (preg_match('/^(.+)\.(css|html)$/', $file, $m)) {
+ $files[] = $file;
+ }
+ else if ($file != '.' && $file != '..' && is_dir($dir . '/' . $file)) {
+ foreach (get_files($dir . '/' . $file) as $f) {
+ $files[] = $file . '/' . $f;
+ }
+ }
+ }
+
+ closedir($dh);
+
+ return $files;
+}
+
+?>
diff -r 000000000000 -r 4681f974d28b bin/updatedb.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/updatedb.sh Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,178 @@
+#!/usr/bin/env php
+ |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
+
+require_once INSTALL_PATH . 'program/include/clisetup.php';
+
+// get arguments
+$opts = rcube_utils::get_opt(array(
+ 'v' => 'version',
+ 'd' => 'dir',
+ 'p' => 'package',
+));
+
+if (empty($opts['dir'])) {
+ rcube::raise_error("Database schema directory not specified (--dir).", false, true);
+}
+if (empty($opts['package'])) {
+ rcube::raise_error("Database schema package name not specified (--package).", false, true);
+}
+
+// Check if directory exists
+if (!file_exists($opts['dir'])) {
+ rcube::raise_error("Specified database schema directory doesn't exist.", false, true);
+}
+
+$RC = rcube::get_instance();
+$DB = rcube_db::factory($RC->config->get('db_dsnw'));
+
+$DB->set_debug((bool)$RC->config->get('sql_debug'));
+
+// Connect to database
+$DB->db_connect('w');
+if (!$DB->is_connected()) {
+ rcube::raise_error("Error connecting to database: " . $DB->is_error(), false, true);
+}
+
+// Read DB schema version from database (if 'system' table exists)
+if (in_array($DB->table_name('system'), (array)$DB->list_tables())) {
+ $DB->query("SELECT `value`"
+ ." FROM " . $DB->table_name('system', true)
+ ." WHERE `name` = ?",
+ $opts['package'] . '-version');
+
+ $row = $DB->fetch_array();
+ $version = preg_replace('/[^0-9]/', '', $row[0]);
+}
+
+// DB version not found, but release version is specified
+if (!$version && $opts['version']) {
+ // Map old release version string to DB schema version
+ // Note: This is for backward compat. only, do not need to be updated
+ $map = array(
+ '0.1-stable' => 1,
+ '0.1.1' => 2008030300,
+ '0.2-alpha' => 2008040500,
+ '0.2-beta' => 2008060900,
+ '0.2-stable' => 2008092100,
+ '0.2.1' => 2008092100,
+ '0.2.2' => 2008092100,
+ '0.3-stable' => 2008092100,
+ '0.3.1' => 2009090400,
+ '0.4-beta' => 2009103100,
+ '0.4' => 2010042300,
+ '0.4.1' => 2010042300,
+ '0.4.2' => 2010042300,
+ '0.5-beta' => 2010100600,
+ '0.5' => 2010100600,
+ '0.5.1' => 2010100600,
+ '0.5.2' => 2010100600,
+ '0.5.3' => 2010100600,
+ '0.5.4' => 2010100600,
+ '0.6-beta' => 2011011200,
+ '0.6' => 2011011200,
+ '0.7-beta' => 2011092800,
+ '0.7' => 2011111600,
+ '0.7.1' => 2011111600,
+ '0.7.2' => 2011111600,
+ '0.7.3' => 2011111600,
+ '0.7.4' => 2011111600,
+ '0.8-beta' => 2011121400,
+ '0.8-rc' => 2011121400,
+ '0.8.0' => 2011121400,
+ '0.8.1' => 2011121400,
+ '0.8.2' => 2011121400,
+ '0.8.3' => 2011121400,
+ '0.8.4' => 2011121400,
+ '0.8.5' => 2011121400,
+ '0.8.6' => 2011121400,
+ '0.9-beta' => 2012080700,
+ );
+
+ $version = $map[$opts['version']];
+}
+
+// Assume last version before the 'system' table was added
+if (empty($version)) {
+ $version = 2012080700;
+}
+
+$dir = $opts['dir'] . '/' . $DB->db_provider;
+if (!file_exists($dir)) {
+ rcube::raise_error("DDL Upgrade files for " . $DB->db_provider . " driver not found.", false, true);
+}
+
+$dh = opendir($dir);
+$result = array();
+
+while ($file = readdir($dh)) {
+ if (preg_match('/^([0-9]+)\.sql$/', $file, $m) && $m[1] > $version) {
+ $result[] = $m[1];
+ }
+}
+sort($result, SORT_NUMERIC);
+
+foreach ($result as $v) {
+ echo "Updating database schema ($v)... ";
+ $error = update_db_schema($opts['package'], $v, "$dir/$v.sql");
+
+ if ($error) {
+ echo "[FAILED]\n";
+ rcube::raise_error("Error in DDL upgrade $v: $error", false, true);
+ }
+ echo "[OK]\n";
+}
+
+
+function update_db_schema($package, $version, $file)
+{
+ global $DB;
+
+ // read DDL file
+ if ($sql = file_get_contents($file)) {
+ if (!$DB->exec_script($sql)) {
+ return $DB->is_error();
+ }
+ }
+
+ // escape if 'system' table does not exist
+ if ($version < 2013011000) {
+ return;
+ }
+
+ $system_table = $DB->table_name('system', true);
+
+ $DB->query("UPDATE " . $system_table
+ ." SET `value` = ?"
+ ." WHERE `name` = ?",
+ $version, $package . '-version');
+
+ if (!$DB->is_error() && !$DB->affected_rows()) {
+ $DB->query("INSERT INTO " . $system_table
+ ." (`name`, `value`) VALUES (?, ?)",
+ $package . '-version', $version);
+ }
+
+ return $DB->is_error();
+}
+
+?>
diff -r 000000000000 -r 4681f974d28b composer.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/composer.json Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,38 @@
+{
+ "name": "roundcube/roundcubemail",
+ "description": "The Roundcube Webmail suite",
+ "license": "GPL-3.0+",
+ "repositories": [
+ {
+ "type": "pear",
+ "url": "https://pear.php.net/"
+ },
+ {
+ "type": "composer",
+ "url": "https://plugins.roundcube.net/"
+ },
+ {
+ "type": "vcs",
+ "url": "https://git.kolab.org/diffusion/PNL/php-net_ldap.git"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.7",
+ "roundcube/plugin-installer": "~0.1.6",
+ "pear-pear.php.net/net_socket": ">=1.0.12",
+ "pear-pear.php.net/auth_sasl": ">=1.0.6",
+ "pear-pear.php.net/net_sieve": ">=1.3.2",
+ "pear-pear.php.net/mail_mime": ">=1.8.9",
+ "pear-pear.php.net/net_smtp": ">=1.6.2",
+ "patchwork/utf8": ">=1.1.25"
+ },
+ "require-dev": {
+ "pear-pear.php.net/crypt_gpg": "*",
+ "phpunit/phpunit": "*"
+ },
+ "suggest": {
+ "pear-pear.php.net/net_ldap2": ">=2.0.12",
+ "kolab/Net_LDAP3": "dev-master required for connecting to LDAP address books"
+ },
+ "minimum-stability": "dev"
+}
diff -r 000000000000 -r 4681f974d28b config.inc.php.sample
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/config.inc.php.sample Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,81 @@
+ |
+ | Author: Aleksander Machniak |
+ +-------------------------------------------------------------------------+
+*/
+
+// include environment
+require_once 'program/include/iniset.php';
+
+// init application, start session, init output class, etc.
+$RCMAIL = rcmail::get_instance($GLOBALS['env']);
+
+// Make the whole PHP output non-cacheable (#1487797)
+$RCMAIL->output->nocacheing_headers();
+$RCMAIL->output->common_headers();
+
+// turn on output buffering
+ob_start();
+
+// check if config files had errors
+if ($err_str = $RCMAIL->config->get_error()) {
+ rcmail::raise_error(array(
+ 'code' => 601,
+ 'type' => 'php',
+ 'message' => $err_str), false, true);
+}
+
+// check DB connections and exit on failure
+if ($err_str = $RCMAIL->db->is_error()) {
+ rcmail::raise_error(array(
+ 'code' => 603,
+ 'type' => 'db',
+ 'message' => $err_str), FALSE, TRUE);
+}
+
+// error steps
+if ($RCMAIL->action == 'error' && !empty($_GET['_code'])) {
+ rcmail::raise_error(array('code' => hexdec($_GET['_code'])), FALSE, TRUE);
+}
+
+// check if https is required (for login) and redirect if necessary
+if (empty($_SESSION['user_id']) && ($force_https = $RCMAIL->config->get('force_https', false))) {
+ $https_port = is_bool($force_https) ? 443 : $force_https;
+
+ if (!rcube_utils::https_check($https_port)) {
+ $host = preg_replace('/:[0-9]+$/', '', $_SERVER['HTTP_HOST']);
+ $host .= ($https_port != 443 ? ':' . $https_port : '');
+
+ header('Location: https://' . $host . $_SERVER['REQUEST_URI']);
+ exit;
+ }
+}
+
+// trigger startup plugin hook
+$startup = $RCMAIL->plugins->exec_hook('startup', array('task' => $RCMAIL->task, 'action' => $RCMAIL->action));
+$RCMAIL->set_task($startup['task']);
+$RCMAIL->action = $startup['action'];
+
+// try to log in
+if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
+ $request_valid = $_SESSION['temp'] && $RCMAIL->check_request();
+
+ // purge the session in case of new login when a session already exists
+ $RCMAIL->kill_session();
+
+ $auth = $RCMAIL->plugins->exec_hook('authenticate', array(
+ 'host' => $RCMAIL->autoselect_host(),
+ 'user' => trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST)),
+ 'pass' => rcube_utils::get_input_value('_pass', rcube_utils::INPUT_POST, true,
+ $RCMAIL->config->get('password_charset', 'ISO-8859-1')),
+ 'cookiecheck' => true,
+ 'valid' => $request_valid,
+ ));
+
+ // Login
+ if ($auth['valid'] && !$auth['abort']
+ && $RCMAIL->login($auth['user'], $auth['pass'], $auth['host'], $auth['cookiecheck'])
+ ) {
+ // create new session ID, don't destroy the current session
+ // it was destroyed already by $RCMAIL->kill_session() above
+ $RCMAIL->session->remove('temp');
+ $RCMAIL->session->regenerate_id(false);
+
+ // send auth cookie if necessary
+ $RCMAIL->session->set_auth_cookie();
+
+ // log successful login
+ $RCMAIL->log_login();
+
+ // restore original request parameters
+ $query = array();
+ if ($url = rcube_utils::get_input_value('_url', rcube_utils::INPUT_POST)) {
+ parse_str($url, $query);
+
+ // prevent endless looping on login page
+ if ($query['_task'] == 'login') {
+ unset($query['_task']);
+ }
+
+ // prevent redirect to compose with specified ID (#1488226)
+ if ($query['_action'] == 'compose' && !empty($query['_id'])) {
+ $query = array('_action' => 'compose');
+ }
+ }
+
+ // allow plugins to control the redirect url after login success
+ $redir = $RCMAIL->plugins->exec_hook('login_after', $query + array('_task' => 'mail'));
+ unset($redir['abort'], $redir['_err']);
+
+ // send redirect
+ $OUTPUT->redirect($redir, 0, true);
+ }
+ else {
+ if (!$auth['valid']) {
+ $error_code = RCMAIL::ERROR_INVALID_REQUEST;
+ }
+ else {
+ $error_code = is_numeric($auth['error']) ? $auth['error'] : $RCMAIL->login_error();
+ }
+
+ $error_labels = array(
+ RCMAIL::ERROR_STORAGE => 'storageerror',
+ RCMAIL::ERROR_COOKIES_DISABLED => 'cookiesdisabled',
+ RCMAIL::ERROR_INVALID_REQUEST => 'invalidrequest',
+ RCMAIL::ERROR_INVALID_HOST => 'invalidhost',
+ );
+
+ $error_message = !empty($auth['error']) && !is_numeric($auth['error']) ? $auth['error'] : ($error_labels[$error_code] ?: 'loginfailed');
+
+ $OUTPUT->show_message($error_message, 'warning');
+
+ // log failed login
+ $RCMAIL->log_login($auth['user'], true, $error_code);
+
+ $RCMAIL->plugins->exec_hook('login_failed', array(
+ 'code' => $error_code, 'host' => $auth['host'], 'user' => $auth['user']));
+
+ $RCMAIL->kill_session();
+ }
+}
+
+// end session
+else if ($RCMAIL->task == 'logout' && isset($_SESSION['user_id'])) {
+ $RCMAIL->request_security_check($mode = rcube_utils::INPUT_GET);
+
+ $userdata = array(
+ 'user' => $_SESSION['username'],
+ 'host' => $_SESSION['storage_host'],
+ 'lang' => $RCMAIL->user->language,
+ );
+
+ $OUTPUT->show_message('loggedout');
+
+ $RCMAIL->logout_actions();
+ $RCMAIL->kill_session();
+ $RCMAIL->plugins->exec_hook('logout_after', $userdata);
+}
+
+// check session and auth cookie
+else if ($RCMAIL->task != 'login' && $_SESSION['user_id']) {
+ if (!$RCMAIL->session->check_auth()) {
+ $RCMAIL->kill_session();
+ $session_error = true;
+ }
+}
+
+// not logged in -> show login page
+if (empty($RCMAIL->user->ID)) {
+ // log session failures
+ $task = rcube_utils::get_input_value('_task', rcube_utils::INPUT_GPC);
+
+ if ($task && !in_array($task, array('login','logout'))
+ && !$session_error && ($sess_id = $_COOKIE[ini_get('session.name')])
+ ) {
+ $RCMAIL->session->log("Aborted session $sess_id; no valid session data found");
+ $session_error = true;
+ }
+
+ if ($session_error || $_REQUEST['_err'] == 'session') {
+ $OUTPUT->show_message('sessionerror', 'error', null, true, -1);
+ }
+
+ if ($OUTPUT->ajax_call || $OUTPUT->get_env('framed')) {
+ $OUTPUT->command('session_error', $RCMAIL->url(array('_err' => 'session')));
+ $OUTPUT->send('iframe');
+ }
+
+ // check if installer is still active
+ if ($RCMAIL->config->get('enable_installer') && is_readable('./installer/index.php')) {
+ $OUTPUT->add_footer(html::div(array('style' => "background:#ef9398; border:2px solid #dc5757; padding:0.5em; margin:2em auto; width:50em"),
+ html::tag('h2', array('style' => "margin-top:0.2em"), "Installer script is still accessible") .
+ html::p(null, "The install script of your Roundcube installation is still stored in its default location!") .
+ html::p(null, "Please remove the whole installer folder from the Roundcube directory because .
+ these files may expose sensitive configuration data like server passwords and encryption keys
+ to the public. Make sure you cannot access the installer script from your browser.")
+ ));
+ }
+
+ $plugin = $RCMAIL->plugins->exec_hook('unauthenticated', array('task' => 'login', 'error' => $session_error));
+
+ $RCMAIL->set_task($plugin['task']);
+
+ $OUTPUT->send($plugin['task']);
+}
+else {
+ // CSRF prevention
+ $RCMAIL->request_security_check();
+
+ // check access to disabled actions
+ $disabled_actions = (array) $RCMAIL->config->get('disabled_actions');
+ if (in_array($RCMAIL->task . '.' . ($RCMAIL->action ?: 'index'), $disabled_actions)) {
+ rcube::raise_error(array(
+ 'code' => 403, 'type' => 'php',
+ 'message' => "Action disabled"), true, true);
+ }
+}
+
+// we're ready, user is authenticated and the request is safe
+$plugin = $RCMAIL->plugins->exec_hook('ready', array('task' => $RCMAIL->task, 'action' => $RCMAIL->action));
+$RCMAIL->set_task($plugin['task']);
+$RCMAIL->action = $plugin['action'];
+
+// handle special actions
+if ($RCMAIL->action == 'keep-alive') {
+ $OUTPUT->reset();
+ $RCMAIL->plugins->exec_hook('keep_alive', array());
+ $OUTPUT->send();
+}
+else if ($RCMAIL->action == 'save-pref') {
+ include INSTALL_PATH . 'program/steps/utils/save_pref.inc';
+}
+
+
+// include task specific functions
+if (is_file($incfile = INSTALL_PATH . 'program/steps/'.$RCMAIL->task.'/func.inc')) {
+ include_once $incfile;
+}
+
+// allow 5 "redirects" to another action
+$redirects = 0; $incstep = null;
+while ($redirects < 5) {
+ // execute a plugin action
+ if (preg_match('/^plugin\./', $RCMAIL->action)) {
+ $RCMAIL->plugins->exec_action($RCMAIL->action);
+ break;
+ }
+ // execute action registered to a plugin task
+ else if ($RCMAIL->plugins->is_plugin_task($RCMAIL->task)) {
+ if (!$RCMAIL->action) $RCMAIL->action = 'index';
+ $RCMAIL->plugins->exec_action($RCMAIL->task.'.'.$RCMAIL->action);
+ break;
+ }
+ // try to include the step file
+ else if (($stepfile = $RCMAIL->get_action_file())
+ && is_file($incfile = INSTALL_PATH . 'program/steps/'.$RCMAIL->task.'/'.$stepfile)
+ ) {
+ // include action file only once (in case it don't exit)
+ include_once $incfile;
+ $redirects++;
+ }
+ else {
+ break;
+ }
+}
+
+if ($RCMAIL->action == 'refresh') {
+ $RCMAIL->plugins->exec_hook('refresh', array('last' => intval(rcube_utils::get_input_value('_last', rcube_utils::INPUT_GPC))));
+}
+
+// parse main template (default)
+$OUTPUT->send($RCMAIL->task);
+
+// if we arrive here, something went wrong
+rcmail::raise_error(array(
+ 'code' => 404,
+ 'type' => 'php',
+ 'line' => __LINE__,
+ 'file' => __FILE__,
+ 'message' => "Invalid request"), true, true);
diff -r 000000000000 -r 4681f974d28b installer/check.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/installer/check.php Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,274 @@
+
+
diff -r 000000000000 -r 4681f974d28b installer/client.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/installer/client.js Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,51 @@
+/*
+ +-----------------------------------------------------------------------+
+ | Roundcube installer cleint function |
+ | |
+ | This file is part of the Roundcube web development suite |
+ | Copyright (C) 2009-2012, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli |
+ +-----------------------------------------------------------------------+
+*/
+
+function toggleblock(id, link)
+{
+ var block = document.getElementById(id);
+
+ return false;
+}
+
+
+function addhostfield()
+{
+ var container = document.getElementById('defaulthostlist');
+ var row = document.createElement('div');
+ var input = document.createElement('input');
+ var link = document.createElement('a');
+
+ input.name = '_default_host[]';
+ input.size = '30';
+ link.href = '#';
+ link.onclick = function() { removehostfield(this.parentNode); return false };
+ link.className = 'removelink';
+ link.innerHTML = 'remove';
+
+ row.appendChild(input);
+ row.appendChild(link);
+ container.appendChild(row);
+}
+
+
+function removehostfield(row)
+{
+ var container = document.getElementById('defaulthostlist');
+ container.removeChild(row);
+}
+
+
diff -r 000000000000 -r 4681f974d28b installer/client.min.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/installer/client.min.js Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,1 @@
+function toggleblock(c,a){var b=document.getElementById(c);return false}function addhostfield(){var a=document.getElementById("defaulthostlist");var d=document.createElement("div");var b=document.createElement("input");var c=document.createElement("a");b.name="_default_host[]";b.size="30";c.href="#";c.onclick=function(){removehostfield(this.parentNode);return false};c.className="removelink";c.innerHTML="remove";d.appendChild(b);d.appendChild(c);a.appendChild(d)}function removehostfield(b){var a=document.getElementById("defaulthostlist");a.removeChild(b)};
\ No newline at end of file
diff -r 000000000000 -r 4681f974d28b installer/config.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/installer/config.php Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,701 @@
+
+
';
+
+?>
+
diff -r 000000000000 -r 4681f974d28b installer/images/add.png
Binary file installer/images/add.png has changed
diff -r 000000000000 -r 4681f974d28b installer/images/banner_gradient.gif
Binary file installer/images/banner_gradient.gif has changed
diff -r 000000000000 -r 4681f974d28b installer/images/banner_schraffur.gif
Binary file installer/images/banner_schraffur.gif has changed
diff -r 000000000000 -r 4681f974d28b installer/images/delete.png
Binary file installer/images/delete.png has changed
diff -r 000000000000 -r 4681f974d28b installer/images/error.png
Binary file installer/images/error.png has changed
diff -r 000000000000 -r 4681f974d28b installer/images/roundcube_logo.png
Binary file installer/images/roundcube_logo.png has changed
diff -r 000000000000 -r 4681f974d28b installer/index.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/installer/index.php Thu Jan 04 15:52:31 2018 -0500
@@ -0,0 +1,179 @@
+ |
+ +-------------------------------------------------------------------------+
+*/
+
+ini_set('error_reporting', E_ALL &~ (E_NOTICE | E_STRICT));
+ini_set('display_errors', 1);
+
+define('INSTALL_PATH', realpath(__DIR__ . '/../').'/');
+define('RCUBE_INSTALL_PATH', INSTALL_PATH);
+define('RCUBE_CONFIG_DIR', INSTALL_PATH . 'config/');
+
+$include_path = INSTALL_PATH . 'program/lib' . PATH_SEPARATOR;
+$include_path .= INSTALL_PATH . 'program/include' . PATH_SEPARATOR;
+$include_path .= ini_get('include_path');
+
+set_include_path($include_path);
+
+// include composer autoloader (if available)
+if (@file_exists(INSTALL_PATH . 'vendor/autoload.php')) {
+ require INSTALL_PATH . 'vendor/autoload.php';
+}
+
+require_once 'Roundcube/bootstrap.php';
+// deprecated aliases (to be removed)
+require_once 'bc.php';
+
+if (function_exists('session_start'))
+ session_start();
+
+$RCI = rcmail_install::get_instance();
+$RCI->load_config();
+
+if (isset($_GET['_getconfig'])) {
+ $filename = 'config.inc.php';
+ if (!empty($_SESSION['config'])) {
+ header('Content-type: text/plain');
+ header('Content-Disposition: attachment; filename="'.$filename.'"');
+ echo $_SESSION['config'];
+ exit;
+ }
+ else {
+ header('HTTP/1.0 404 Not found');
+ die("The requested configuration was not found. Please run the installer from the beginning.");
+ }
+}
+
+if ($RCI->configured && ($RCI->getprop('enable_installer') || $_SESSION['allowinstaller']) &&
+ !empty($_GET['_mergeconfig'])) {
+ $filename = 'config.inc.php';
+
+ header('Content-type: text/plain');
+ header('Content-Disposition: attachment; filename="'.$filename.'"');
+
+ $RCI->merge_config();
+ echo $RCI->create_config();
+ exit;
+}
+
+// go to 'check env' step if we have a local configuration
+if ($RCI->configured && empty($_REQUEST['_step'])) {
+ header("Location: ./?_step=1");
+ exit;
+}
+
+?>
+
+
+
+Roundcube Webmail Installer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+configured && !$RCI->getprop('enable_installer') && !$_SESSION['allowinstaller']) {
+ // header("HTTP/1.0 404 Not Found");
+ if ($RCI->configured && $RCI->legacy_config) {
+ echo '
Your configuration needs to be migrated!
';
+ echo '
We changed the configuration files structure and your installation needs to be updated accordingly.
';
+ echo '
Please run the bin/update.sh script from the command line or set
$rcube_config[\'enable_installer\'] = true;
';
+ echo ' in your RCUBE_CONFIG_DIR/main.inc.php to let the installer help you migrating it.';
+ }
+ else {
+ echo '
The installer is disabled!
';
+ echo '
To enable it again, set $config[\'enable_installer\'] = true; in RCUBE_CONFIG_DIR/config.inc.php
';
+ }
+ echo '
';
+ exit;
+ }
+
+?>
+
+Roundcube Webmail Installer
+
+
+ './check.php',
+ 2 => './config.php',
+ 3 => './test.php',
+ );
+
+ if (!in_array($RCI->step, array_keys($include_steps))) {
+ $RCI->step = 1;
+ }
+
+ foreach (array('Check environment', 'Create config', 'Test config') as $i => $item) {
+ $j = $i + 1;
+ $link = ($RCI->step >= $j || $RCI->configured) ? '' . Q($item) . '' : Q($item);
+ printf('- %s
', $j+1, $RCI->step > $j ? ' passed' : ($RCI->step == $j ? ' current' : ''), $link);
+ }
+?>
+
+
+step];
+
+?>
+
+
+
+