summaryrefslogtreecommitdiff
path: root/webmail/bin
diff options
context:
space:
mode:
authorTristan Zur <tzur@web.web.ccwn.org>2014-03-27 22:27:47 +0100
committerTristan Zur <tzur@web.web.ccwn.org>2014-03-27 22:27:47 +0100
commitb62676ca5d3d6f6ba3f019ea3f99722e165a98d8 (patch)
tree86722cb80f07d4569f90088eeaea2fc2f6e2ef94 /webmail/bin
Initial commit of intern.ccwn.org contentsHEADmaster
Diffstat (limited to 'webmail/bin')
-rwxr-xr-xwebmail/bin/cleandb.sh78
-rwxr-xr-xwebmail/bin/decrypt.sh67
-rwxr-xr-xwebmail/bin/exportgettext.sh236
-rwxr-xr-xwebmail/bin/importgettext.sh199
-rwxr-xr-xwebmail/bin/indexcontacts.sh54
-rwxr-xr-xwebmail/bin/installto.sh81
-rwxr-xr-xwebmail/bin/jsshrink.sh67
-rwxr-xr-xwebmail/bin/jsunshrink.sh14
-rwxr-xr-xwebmail/bin/moduserprefs.sh82
-rwxr-xr-xwebmail/bin/msgexport.sh143
-rwxr-xr-xwebmail/bin/msgimport.sh113
-rwxr-xr-xwebmail/bin/update.sh170
-rwxr-xr-xwebmail/bin/updatecss.sh122
-rwxr-xr-xwebmail/bin/updatedb.sh202
14 files changed, 1628 insertions, 0 deletions
diff --git a/webmail/bin/cleandb.sh b/webmail/bin/cleandb.sh
new file mode 100755
index 0000000..ea905c8
--- /dev/null
+++ b/webmail/bin/cleandb.sh
@@ -0,0 +1,78 @@
+#!/usr/bin/env php
+<?php
+/*
+ +-----------------------------------------------------------------------+
+ | bin/cleandb.sh |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2010, 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. |
+ | |
+ | PURPOSE: |
+ | Finally remove all db records marked as deleted some time ago |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
+
+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 = rcmail::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 = get_table_name($table);
+
+ // 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 = get_table_name('contactgroupmembers');
+
+ $db->query(
+ "DELETE FROM $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 --git a/webmail/bin/decrypt.sh b/webmail/bin/decrypt.sh
new file mode 100755
index 0000000..ff7c430
--- /dev/null
+++ b/webmail/bin/decrypt.sh
@@ -0,0 +1,67 @@
+#!/usr/bin/env php
+<?php
+/*
+ +-----------------------------------------------------------------------+
+ | bin/decrypt.sh |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2005-2009, 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. |
+ | |
+ | PURPOSE: |
+ | Decrypt the encrypted parts of the HTTP Received: headers |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Tomas Tevesz <ice@extreme.hu> |
+ +-----------------------------------------------------------------------+
+*/
+
+/**
+ * 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(dirname(__FILE__).'/..') . '/');
+
+require INSTALL_PATH . 'program/include/clisetup.php';
+
+if ($argc < 2) {
+ die("Usage: " . basename($argv[0]) . " encrypted-hdr-part [encrypted-hdr-part ...]\n");
+}
+
+$RCMAIL = rcmail::get_instance();
+
+for ($i = 1; $i < $argc; $i++) {
+ printf("%s\n", $RCMAIL->decrypt($argv[$i]));
+};
diff --git a/webmail/bin/exportgettext.sh b/webmail/bin/exportgettext.sh
new file mode 100755
index 0000000..c1e6302
--- /dev/null
+++ b/webmail/bin/exportgettext.sh
@@ -0,0 +1,236 @@
+#!/usr/bin/env php
+<?php
+/*
+
+ +-----------------------------------------------------------------------+
+ | bin/exportgettext.sh |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2011, The Roundcube Dev Team |
+ | Licensed under the GNU General Public License |
+ | |
+ | PURPOSE: |
+ | Export PHP-based localization files to PO files for gettext |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id$
+
+*/
+
+define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
+require INSTALL_PATH.'program/include/clisetup.php';
+
+if ($argc < 2) {
+ die("Usage: " . basename($argv[0]) . " SRCDIR DESTDIR\n");
+}
+
+$srcdir = unslashify(realpath($argv[1]));
+$destdir = unslashify($argv[2]);
+$layout = 'launchpad'; # or 'narro';
+$langcode_map = array(
+ 'hy_AM' => 'hy',
+ 'ar_SA' => 'ar',
+ 'az_AZ' => 'az',
+ 'bg_BG' => 'bg',
+ 'bs_BA' => 'bs',
+ 'ca_ES' => 'ca',
+ 'cs_CZ' => 'cs',
+ 'cy_GB' => 'cy',
+ 'da_DK' => 'da',
+ 'et_EE' => 'et',
+ 'el_GR' => 'el',
+ 'eu_ES' => 'eu',
+ 'fa_IR' => 'fa',
+ 'ga_IE' => 'ga',
+ 'ka_GE' => 'ka',
+ 'gl_ES' => 'gl',
+ 'he_IL' => 'he',
+ 'hi_IN' => 'hi',
+ 'hr_HR' => 'hr',
+ 'ja_JP' => 'ja',
+ 'ko_KR' => 'ko',
+ 'km_KH' => 'km',
+ 'ms_MY' => 'ms',
+ 'mr_IN' => 'mr',
+ 'pl_PL' => 'pl',
+ 'si_LK' => 'si',
+ 'sl_SI' => 'sl',
+ 'sq_AL' => 'sq',
+ 'sr_CS' => 'sr',
+ 'sv_SE' => 'sv',
+ 'uk_UA' => 'uk',
+ 'vi_VN' => 'vi',
+);
+
+
+// converting roundcube localization dir
+if (is_dir($srcdir.'/en_US')) {
+ load_en_US($srcdir.'/en_US');
+
+ foreach (glob($srcdir.'/*') as $locdir) {
+ if (is_dir($locdir)) {
+ $lang = basename($locdir);
+ //echo "$locdir => $destdir$lang\n";
+ convert_dir($locdir, $destdir . ($layout != 'launchpad' ? $lang : ''));
+ }
+ }
+}
+// converting single localization directory
+else if (is_dir($srcdir)) {
+ if (is_file($srcdir.'/en_US.inc')) // plugin localization
+ load_en_US($srcdir.'/en_US.inc');
+ else
+ load_en_US(realpath($srcdir.'/../en_US')); // single language
+ convert_dir($srcdir, $destdir);
+}
+// converting a single file
+else if (is_file($srcdir)) {
+ //load_en_US();
+ convert_file($srcdir, $destdir);
+}
+
+
+/**
+ * Load en_US localization which is used to build msgids
+ */
+function load_en_US($fn)
+{
+ $texts = array();
+
+ if (is_dir($fn)) {
+ foreach (glob($fn.'/*.inc') as $ifn) {
+ include($ifn);
+ $texts = array_merge($texts, (array)$labels, (array)$messages);
+ }
+ }
+ else if (is_file($fn)) {
+ include($fn);
+ $texts = array_merge($texts, (array)$labels, (array)$messages);
+ }
+
+ $GLOBALS['en_US'] = $texts;
+}
+
+/**
+ * Convert all .inc files in the given src directory
+ */
+function convert_dir($indir, $outdir)
+{
+ global $layout;
+
+ if (!is_dir($outdir)) // attempt to create destination dir
+ mkdir($outdir, 0777, true);
+
+ foreach (glob($indir.'/*.inc') as $fn) {
+ $filename = basename($fn);
+
+ // create subdir for each template (launchpad rules)
+ if ($layout == 'launchpad' && preg_match('/^(labels|messages)/', $filename, $m)) {
+ $lang = end(explode('/', $indir));
+ $destdir = $outdir . '/' . $m[1];
+ if (!is_dir($destdir))
+ mkdir($destdir, 0777, true);
+ $outfn = $destdir . '/' . $lang . '.po';
+ }
+ else {
+ $outfn = $outdir . '/' . preg_replace('/\.[a-z0-9]+$/i', '', basename($fn)) . '.po';
+ }
+
+ convert_file($fn, $outfn);
+ }
+}
+
+/**
+ * Convert the given Roundcube localization file into a gettext .po file
+ */
+function convert_file($fn, $outfn)
+{
+ global $layout, $langcode_map;
+
+ $basename = basename($fn);
+ $srcname = str_replace(INSTALL_PATH, '', $fn);
+ $product = preg_match('!plugins/(\w+)!', $srcname, $m) ? 'roundcube-plugin-' . $m[1] : 'roundcubemail';
+ $lang = preg_match('!/([a-z]{2}(_[A-Z]{2})?)[./]!', $outfn, $m) ? $m[1] : '';
+ $labels = $messages = $seen = array();
+
+ if (is_dir($outfn))
+ $outfn .= '/' . $basename . '.po';
+
+ // launchpad requires the template file to have the same name as the directory
+ if (strstr($outfn, '/en_US') && $layout == 'launchpad') {
+ $a = explode('/', $outfn);
+ array_pop($a);
+ $templ = end($a);
+ $a[] = $templ . '.pot';
+ $outfn = join('/', $a);
+ $is_pot = true;
+ }
+ // launchpad is very picky about file names
+ else if ($layout == 'launchpad' && preg_match($regex = '!/([a-z]{2})_([A-Z]{2})!', $outfn, $m)) {
+ if ($shortlang = $langcode_map[$lang])
+ $outfn = preg_replace($regex, '/'.$shortlang, $outfn);
+ else if ($m[1] == strtolower($m[2]))
+ $outfn = preg_replace($regex, '/\1', $outfn);
+ }
+
+ include($fn);
+ $texts = array_merge($labels, $messages);
+
+ // write header
+ $header = <<<EOF
+# Converted from Roundcube PHP localization files
+# Copyright (C) 2011 The Roundcube Dev Team
+# This file is distributed under the same license as the Roundcube package.
+#
+#: %s
+msgid ""
+msgstr ""
+"Project-Id-Version: %s\\n"
+"Report-Msgid-Bugs-To: \\n"
+"%s: %s\\n"
+"Last-Translator: \\n"
+"Language-Team: Translations <hello@roundcube.net>\\n"
+"Language: %s\\n"
+"Content-Type: text/plain; charset=UTF-8\\n"
+"Content-Transfer-Encoding: 8bit\\n"
+EOF;
+
+ $out = sprintf($header, $srcname, $product, $is_pot ? "POT-Creation-Date" : "PO-Revision-Date", date('c'), $shortlang ? $shortlang : $lang);
+ $out .= "\n";
+
+ $messages = array();
+ foreach ((array)$texts as $label => $msgstr) {
+ $msgid = $is_pot ? $msgstr : ($GLOBALS['en_US'][$label] ?: $label);
+ $messages[$msgid][] = $label;
+ }
+
+ foreach ($messages as $msgid => $labels) {
+ $out .= "\n";
+ foreach ($labels as $label)
+ $out .= "#: $srcname:$label\n";
+ $msgstr = $texts[$label];
+ $out .= 'msgid ' . gettext_quote($msgid) . "\n";
+ $out .= 'msgstr ' . gettext_quote(!$is_pot ? $msgstr : '') . "\n";
+ }
+
+ if ($outfn == '-')
+ echo $out;
+ else {
+ echo "$fn\t=>\t$outfn\n";
+ file_put_contents($outfn, $out);
+ }
+}
+
+function gettext_quote($str)
+{
+ $out = "";
+ $lines = explode("\n", wordwrap(stripslashes($str)));
+ $last = count($lines) - 1;
+ foreach ($lines as $i => $line)
+ $out .= '"' . addcslashes($line, '"') . ($i < $last ? ' ' : '') . "\"\n";
+ return rtrim($out);
+}
+
+?>
diff --git a/webmail/bin/importgettext.sh b/webmail/bin/importgettext.sh
new file mode 100755
index 0000000..cda1f6e
--- /dev/null
+++ b/webmail/bin/importgettext.sh
@@ -0,0 +1,199 @@
+#!/usr/bin/env php
+<?php
+/*
+
+ +-----------------------------------------------------------------------+
+ | bin/importgettext.sh |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2011, The Roundcube Dev Team |
+ | Licensed under the GNU General Public License |
+ | |
+ | PURPOSE: |
+ | Import localizations from gettext PO format |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id$
+
+*/
+
+define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
+require INSTALL_PATH.'program/include/clisetup.php';
+
+if ($argc < 2) {
+ die("Usage: " . basename($argv[0]) . " SRCDIR\n");
+}
+
+$srcdir = unslashify(realpath($argv[1]));
+
+if (is_dir($srcdir)) {
+ $out = import_dir($srcdir);
+}
+else if (is_file($srcdir)) {
+ $out = import_file($srcdir);
+}
+
+// write output files
+foreach ($out as $outfn => $texts) {
+ $lang = preg_match('!/([a-z]{2}(_[A-Z]{2})?)[./]!', $outfn, $m) ? $m[1] : '';
+ $varname = strpos($outfn, 'messages.inc') !== false ? 'messages' : 'labels';
+
+ $header = <<<EOF
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | localization/%s/%-51s|
+ | |
+ | Language file of the Roundcube Webmail client |
+ | Copyright (C) %s, The Roundcube Dev Team |
+ | Licensed under the GNU General Public License |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: %-62s|
+ +-----------------------------------------------------------------------+
+*/
+
+$%s = array();
+
+EOF;
+
+ $author = preg_replace('/\s*<Unknown>/i', '', $texts['_translator']);
+ $output = sprintf($header, $lang, $varname.'.inc', date('Y'), $author, $varname);
+
+ foreach ($texts as $label => $value) {
+ if (is_array($value)) { var_dump($outfn, $label, $value); exit; }
+ if ($label[0] != '_' && strlen($value))
+ $output .= sprintf("\$%s['%s'] = '%s';\n", $varname, $label, strtr(addcslashes($value, "'"), array("\r" => '', "\n" => '\n')));
+ }
+
+ $output .= "\n";
+ $dir = dirname($outfn);
+ @mkdir($dir, 664, true);
+ if (file_put_contents($outfn, $output))
+ echo "-> $outfn\n";
+}
+
+
+/**
+ * Convert all .po files in the given src directory
+ */
+function import_dir($indir)
+{
+ $out = array();
+ foreach (glob($indir.'/*.po') as $fn) {
+ $out = array_merge_recursive($out, import_file($fn));
+ }
+ return $out;
+}
+
+/**
+ * Convert the given .po file into a Roundcube localization array
+ */
+function import_file($fn)
+{
+ $out = array();
+ $lines = file($fn);
+ $language = '';
+ $translator = '';
+
+ // get language code from file name
+ if (preg_match('/-([a-z_]+).po$/i', $fn, $m))
+ $language = expand_langcode($m[1]);
+
+ $is_header = true;
+ $msgid = null;
+ $msgstr = '';
+ $dests = array();
+ foreach ($lines as $i => $line) {
+ $line = trim($line);
+
+ // parse header
+ if ($is_header && $line[0] == '"') {
+ list($key, $val) = explode(": ", preg_replace('/\\\n$/', '', trim($line, '"')), 2);
+ switch (strtolower($key)) {
+ case 'language':
+ $language = expand_langcode($val);
+ break;
+ case 'last-translator':
+ $translator = $val;
+ break;
+ }
+ }
+
+ // empty line
+ if ($line == '') {
+ if ($msgid && $dests) {
+ foreach ($dests as $dest) {
+ list($file, $label) = explode(':', $dest);
+ $out[$file][$label] = $msgstr;
+ }
+ }
+
+ $msgid = null;
+ $msgstr = '';
+ $dests = array();
+ }
+
+ // meta line
+ if ($line[0] == '#') {
+ $value = trim(substr($line, 2));
+ if ($line[1] == ':')
+ $dests[] = str_replace('en_US', $language, $value);
+ }
+ else if (strpos($line, 'msgid') === 0) {
+ $msgid = gettext_decode(substr($line, 6));
+
+ if (!empty($msgid))
+ $is_header = false;
+ }
+ else if (strpos($line, 'msgstr') === 0) {
+ $msgstr = gettext_decode(substr($line, 7));
+ }
+ else if ($msgid && $line[0] == '"') {
+ $msgstr .= gettext_decode($line);
+ }
+ else if ($msgid !== null && $line[0] == '"') {
+ $msgid .= gettext_decode($line);
+ }
+ }
+
+ if ($msgid && $dests) {
+ foreach ($dests as $dest) {
+ list($file, $label) = explode(':', $dest);
+ $out[$file][$label] = $msgstr;
+ $out[$file]['_translator'] = $translator;
+ }
+ }
+
+ return $language ? $out : array();
+}
+
+
+function gettext_decode($str)
+{
+ return stripslashes(trim($str, '"'));
+}
+
+/**
+ * Translate two-chars language codes to our internally used language identifiers
+ */
+function expand_langcode($lang)
+{
+ static $rcube_language_aliases, $rcube_languages;
+
+ if (!$rcube_language_aliases)
+ include(INSTALL_PATH . 'program/localization/index.inc');
+
+ if ($rcube_language_aliases[$lang])
+ return $rcube_language_aliases[$lang];
+ else if (strlen($lang) == 2 && !isset($rcube_languages[$lang]))
+ return strtolower($lang) . '_' . strtoupper($lang);
+ else
+ return $lang;
+}
+
+
+?>
diff --git a/webmail/bin/indexcontacts.sh b/webmail/bin/indexcontacts.sh
new file mode 100755
index 0000000..413dc4b
--- /dev/null
+++ b/webmail/bin/indexcontacts.sh
@@ -0,0 +1,54 @@
+#!/usr/bin/env php
+<?php
+/*
+ +-----------------------------------------------------------------------+
+ | bin/indexcontacts.sh |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2011, 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. |
+ | |
+ | PURPOSE: |
+ | Update the fulltext index for all contacts of the internal |
+ | address book. |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
+
+require_once INSTALL_PATH.'program/include/clisetup.php';
+ini_set('memory_limit', -1);
+
+// connect to DB
+$RCMAIL = rcmail::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 " . $RCMAIL->config->get('db_table_users', 'users')." WHERE 1=1");
+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 --git a/webmail/bin/installto.sh b/webmail/bin/installto.sh
new file mode 100755
index 0000000..8e1ab1f
--- /dev/null
+++ b/webmail/bin/installto.sh
@@ -0,0 +1,81 @@
+#!/usr/bin/env php
+<?php
+/*
+ +-----------------------------------------------------------------------+
+ | bin/installto.sh |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 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. |
+ | |
+ | PURPOSE: |
+ | Update an existing Roundcube installation with files from |
+ | this version |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
+
+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 <TARGET>", 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...";
+ foreach (array('program','installer','bin','SQL','plugins','skins') as $dir) {
+ if (!system("rsync -avC " . INSTALL_PATH . "$dir/* $target_dir/$dir/")) {
+ $err = true;
+ break;
+ }
+ }
+ foreach (array('index.php','.htaccess','config/main.inc.php.dist','config/db.inc.php.dist','CHANGELOG','README.md','UPGRADING','LICENSE') as $file) {
+ if (!system("rsync -av " . INSTALL_PATH . "$file $target_dir/$file")) {
+ $err = true;
+ break;
+ }
+ }
+ 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 && bin/update.sh --version=$oldversion");
+ echo "All done.\n";
+ }
+}
+else
+ echo "Update cancelled. See ya!\n";
+
+?>
diff --git a/webmail/bin/jsshrink.sh b/webmail/bin/jsshrink.sh
new file mode 100755
index 0000000..1d77ff3
--- /dev/null
+++ b/webmail/bin/jsshrink.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+JS_DIR=`dirname "$0"`/../program/js
+JAR_DIR='/tmp'
+LANG_IN='ECMASCRIPT3'
+CLOSURE_COMPILER_URL='http://closure-compiler.googlecode.com/files/compiler-latest.zip'
+
+do_shrink() {
+ rm -f "$2"
+ java -jar $JAR_DIR/compiler.jar --compilation_level=SIMPLE_OPTIMIZATIONS --js="$1" --js_output_file="$2" --language_in="$3"
+}
+
+if [ ! -d "$JS_DIR" ]; then
+ echo "Directory $JS_DIR not found."
+ exit 1
+fi
+
+if [ ! -w "$JAR_DIR" ]; then
+ JAR_DIR=`dirname "$0"`
+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
+
+ if [ ! -r "${JS_FILE}.src" ]; then
+ mv "$JS_FILE" "${JS_FILE}.src"
+ fi
+ echo "Shrinking $JS_FILE"
+ do_shrink "${JS_FILE}.src" "$JS_FILE" "$LANG_IN"
+ exit
+fi
+
+# default: compress application scripts
+for fn in app common googiespell list; do
+ if [ -r "$JS_DIR/${fn}.js.src" ]; then
+ echo "$JS_DIR/${fn}.js.src already exists, not overwriting"
+ else
+ mv "$JS_DIR/${fn}.js" "$JS_DIR/${fn}.js.src"
+ fi
+ echo "Shrinking $JS_DIR/${fn}.js"
+ do_shrink "$JS_DIR/${fn}.js.src" "$JS_DIR/${fn}.js" "$LANG_IN"
+done
diff --git a/webmail/bin/jsunshrink.sh b/webmail/bin/jsunshrink.sh
new file mode 100755
index 0000000..9d77550
--- /dev/null
+++ b/webmail/bin/jsunshrink.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+JS_DIR=`dirname "$0"`/../program/js
+
+if [ ! -d "$JS_DIR" ]; then
+ echo "Directory $JS_DIR not found."
+ exit 1
+fi
+
+for fn in app common googiespell list; do
+ if [ -r "$JS_DIR/${fn}.js.src" ]; then
+ mv "$JS_DIR/${fn}.js.src" "$JS_DIR/${fn}.js"
+ echo "Reverted $JS_DIR/${fn}.js"
+ fi
+done
diff --git a/webmail/bin/moduserprefs.sh b/webmail/bin/moduserprefs.sh
new file mode 100755
index 0000000..049372c
--- /dev/null
+++ b/webmail/bin/moduserprefs.sh
@@ -0,0 +1,82 @@
+#!/usr/bin/env php
+<?php
+/*
+ +-----------------------------------------------------------------------+
+ | bin/moduserprefs.sh |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 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. |
+ | |
+ | PURPOSE: |
+ | Bulk-change settings stored in user preferences |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
+
+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 = rcmail::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 " . $rcmail->config->get('db_table_users', 'users')." 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);
+ echo "saved.\n";
+ }
+ else {
+ echo "nothing changed.\n";
+ }
+}
+
+?>
diff --git a/webmail/bin/msgexport.sh b/webmail/bin/msgexport.sh
new file mode 100755
index 0000000..e98e5fe
--- /dev/null
+++ b/webmail/bin/msgexport.sh
@@ -0,0 +1,143 @@
+#!/usr/bin/env php
+<?php
+
+define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
+ini_set('memory_limit', -1);
+
+require_once INSTALL_PATH.'program/include/clisetup.php';
+
+function print_usage()
+{
+ print "Usage: msgexport -h imap-host -u user-name -m mailbox name\n";
+ print "--host IMAP host\n";
+ print "--user IMAP user name\n";
+ print "--mbox Folder name, set to '*' for all\n";
+ print "--file Output file\n";
+}
+
+function vputs($str)
+{
+ $out = $GLOBALS['args']['file'] ? STDOUT : STDERR;
+ fwrite($out, $str);
+}
+
+function progress_update($pos, $max)
+{
+ $percent = round(100 * $pos / $max);
+ vputs(sprintf("%3d%% [%-51s] %d/%d\033[K\r", $percent, @str_repeat('=', $percent / 2) . '>', $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));
+ fwrite($out, $IMAP->print_raw_body($headers->uid));
+ 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 --git a/webmail/bin/msgimport.sh b/webmail/bin/msgimport.sh
new file mode 100755
index 0000000..1fcc346
--- /dev/null
+++ b/webmail/bin/msgimport.sh
@@ -0,0 +1,113 @@
+#!/usr/bin/env php
+<?php
+
+define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
+ini_set('memory_limit', -1);
+
+require_once INSTALL_PATH.'program/include/clisetup.php';
+
+function print_usage()
+{
+ print "Usage: msgimport -h imap-host -u user-name -m mailbox -f message-file\n";
+ print "--host IMAP host\n";
+ print "--user IMAP user name\n";
+ print "--mbox Target mailbox\n";
+ print "--file Message file to upload\n";
+}
+
+
+// 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'] && $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 --git a/webmail/bin/update.sh b/webmail/bin/update.sh
new file mode 100755
index 0000000..05956b9
--- /dev/null
+++ b/webmail/bin/update.sh
@@ -0,0 +1,170 @@
+#!/usr/bin/env php
+<?php
+/*
+ +-----------------------------------------------------------------------+
+ | bin/update.sh |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2010-2011, 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. |
+ | |
+ | PURPOSE: |
+ | Check local configuration and database schema after upgrading |
+ | to a new version |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
+
+require_once INSTALL_PATH . 'program/include/clisetup.php';
+require_once INSTALL_PATH . 'installer/rcube_install.php';
+
+// get arguments
+$opts = rcube_utils::get_opt(array('v' => 'version'));
+
+// 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;
+}
+
+if ($opts['version'] && version_compare(version_parse($opts['version']), version_parse(RCMAIL_VERSION), '>='))
+ die("Nothing to be done here. Bye!\n");
+
+
+$RCI = rcube_install::get_instance();
+$RCI->load_config();
+
+if ($RCI->configured) {
+ $success = true;
+
+ if ($messages = $RCI->check_config()) {
+ $success = false;
+ $err = 0;
+
+ // list missing config options
+ if (is_array($messages['missing'])) {
+ echo "WARNING: Missing config options:\n";
+ echo "(These config options should be present in the current configuration)\n";
+
+ foreach ($messages['missing'] as $msg) {
+ echo "- '" . $msg['prop'] . ($msg['name'] ? "': " . $msg['name'] : "'") . "\n";
+ $err++;
+ }
+ echo "\n";
+ }
+
+ // 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";
+ }
+
+ // ask user to update config files
+ if ($err) {
+ 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 (strtolower($input) == 'y') {
+ $copy1 = $copy2 = $write1 = $write2 = false;
+
+ // backup current config
+ echo ". backing up the current config files...\n";
+ $copy1 = copy(RCMAIL_CONFIG_DIR . '/main.inc.php', RCMAIL_CONFIG_DIR . '/main.old.php');
+ $copy2 = copy(RCMAIL_CONFIG_DIR . '/db.inc.php', RCMAIL_CONFIG_DIR . '/db.old.php');
+
+ if ($copy1 && $copy2) {
+ $RCI->merge_config();
+
+ echo ". writing " . RCMAIL_CONFIG_DIR . "/main.inc.php...\n";
+ $write1 = file_put_contents(RCMAIL_CONFIG_DIR . '/main.inc.php', $RCI->create_config('main', true));
+ echo ". writing " . RCMAIL_CONFIG_DIR . "/main.db.php...\n";
+ $write2 = file_put_contents(RCMAIL_CONFIG_DIR . '/db.inc.php', $RCI->create_config('db', true));
+ }
+
+ // Success!
+ if ($write1 && $write2) {
+ 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";
+ }
+ }
+ else {
+ echo "Failed to write config files!\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 database schema
+ if ($RCI->config['db_dsnw']) {
+ echo "Executing database schema update.\n";
+ system(INSTALL_PATH . "bin/updatedb.sh --package=roundcube --version=" . $opts['version']
+ . " --dir=" . INSTALL_PATH . DIRECTORY_SEPARATOR . "SQL", $res);
+
+ $success = !$res;
+ }
+
+ // index contacts for fulltext searching
+ if (version_compare(version_parse($opts['version']), '0.6.0', '<')) {
+ system(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 --git a/webmail/bin/updatecss.sh b/webmail/bin/updatecss.sh
new file mode 100755
index 0000000..53d237c
--- /dev/null
+++ b/webmail/bin/updatecss.sh
@@ -0,0 +1,122 @@
+#!/usr/bin/env php
+<?php
+/*
+ +-----------------------------------------------------------------------+
+ | bin/updatecss.sh |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2010-2013, 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. |
+ | |
+ | PURPOSE: |
+ | Update cache-baster marks for css background images |
+ +-----------------------------------------------------------------------+
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
+
+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 --git a/webmail/bin/updatedb.sh b/webmail/bin/updatedb.sh
new file mode 100755
index 0000000..e344cf3
--- /dev/null
+++ b/webmail/bin/updatedb.sh
@@ -0,0 +1,202 @@
+#!/usr/bin/env php
+<?php
+/*
+ +-----------------------------------------------------------------------+
+ | bin/updatedb.sh |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2010-2012, The Roundcube Dev Team |
+ | Copyright (C) 2010-2012, Kolab Systems AG |
+ | |
+ | 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. |
+ | |
+ | PURPOSE: |
+ | Update database schema |
+ +-----------------------------------------------------------------------+
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ +-----------------------------------------------------------------------+
+*/
+
+define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
+
+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'));
+
+// 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 " . $DB->quote_identifier('value')
+ ." FROM " . $DB->quote_identifier($DB->table_name('system'))
+ ." WHERE " . $DB->quote_identifier('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'] . DIRECTORY_SEPARATOR . $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 . DIRECTORY_SEPARATOR . "$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 ($lines = file($file)) {
+ $sql = '';
+ foreach ($lines as $line) {
+ if (preg_match('/^--/', $line) || trim($line) == '')
+ continue;
+
+ $sql .= $line . "\n";
+ if (preg_match('/(;|^GO)$/', trim($line))) {
+ @$DB->query(fix_table_names($sql));
+ $sql = '';
+ if ($error = $DB->is_error()) {
+ return $error;
+ }
+ }
+ }
+ }
+
+ // escape if 'system' table does not exist
+ if ($version < 2013011000) {
+ return;
+ }
+
+ $system_table = $DB->quote_identifier($DB->table_name('system'));
+
+ $DB->query("UPDATE " . $system_table
+ ." SET " . $DB->quote_identifier('value') . " = ?"
+ ." WHERE " . $DB->quote_identifier('name') . " = ?",
+ $version, $package . '-version');
+
+ if (!$DB->is_error() && !$DB->affected_rows()) {
+ $DB->query("INSERT INTO " . $system_table
+ ." (" . $DB->quote_identifier('name') . ", " . $DB->quote_identifier('value') . ")"
+ ." VALUES (?, ?)",
+ $package . '-version', $version);
+ }
+
+ return $DB->is_error();
+}
+
+function fix_table_names($sql)
+{
+ global $DB;
+
+ foreach (array('users','identities','contacts','contactgroups','contactgroupmembers','session','cache','cache_index','cache_index','cache_messages','dictionary','searches','system') as $table) {
+ $real_table = $DB->table_name($table);
+ if ($real_table != $table) {
+ $sql = preg_replace("/([^a-z0-9_])$table([^a-z0-9_])/i", "\\1$real_table\\2", $sql);
+ }
+ }
+
+ return $sql;
+}
+
+?>