From f23ef1c96859f6b01a9268c8606a22ceb719cf3d Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Fri, 26 Apr 2013 05:26:58 -0400
Subject: [PATCH] Fix error handling in CLI mode, use STDERR and non-empty exit code (#1489043)

---
 program/lib/Roundcube/rcube.php |   23 +++++++++--
 CHANGELOG                       |    1 
 bin/indexcontacts.sh            |    9 ++--
 installer/rcube_install.php     |    6 ++-
 bin/installto.sh                |    6 +-
 bin/decrypt.sh                  |    8 ++--
 bin/cleandb.sh                  |    5 +-
 bin/moduserprefs.sh             |    2 
 bin/msgimport.sh                |    7 +--
 bin/updatedb.sh                 |   20 +++------
 10 files changed, 49 insertions(+), 38 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 045437e..51cc8cf 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Fix error handling in CLI mode, use STDERR and non-empty exit code (#1489043)
 - Fix error when using check_referer=true
 - Fix incorrect handling of some specific links (#1489060)
 - Fix incorrect handling of leading spaces in text wrapping
diff --git a/bin/cleandb.sh b/bin/cleandb.sh
index ecf2583..ea905c8 100755
--- a/bin/cleandb.sh
+++ b/bin/cleandb.sh
@@ -34,8 +34,9 @@
 $db = $RCMAIL->get_dbh();
 $db->db_connect('w');
 
-if (!$db->is_connected() || $db->is_error())
-    die("No DB connection\n");
+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]);
diff --git a/bin/decrypt.sh b/bin/decrypt.sh
index 95fdefc..ff7c430 100755
--- a/bin/decrypt.sh
+++ b/bin/decrypt.sh
@@ -19,7 +19,7 @@
  +-----------------------------------------------------------------------+
 */
 
-/*-
+/**
  * 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
@@ -28,8 +28,8 @@
  * 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
+ *  [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
@@ -48,7 +48,7 @@
  *
  * If (most likely binary) junk is shown, then
  *  - either the encryption password has, between the time the mail was sent
- *    and `now', changed, or
+ *    and 'now', changed, or
  *  - you are dealing with counterfeit header data.
  */
 
diff --git a/bin/indexcontacts.sh b/bin/indexcontacts.sh
index a9a5a95..413dc4b 100755
--- a/bin/indexcontacts.sh
+++ b/bin/indexcontacts.sh
@@ -30,17 +30,18 @@
 $db = $RCMAIL->get_dbh();
 $db->db_connect('w');
 
-if (!$db->is_connected() || $db->is_error())
-    die("No DB connection\n");
+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']);
diff --git a/bin/installto.sh b/bin/installto.sh
index e6cf79d..8e1ab1f 100755
--- a/bin/installto.sh
+++ b/bin/installto.sh
@@ -26,17 +26,17 @@
 $target_dir = unslashify($_SERVER['argv'][1]);
 
 if (empty($target_dir) || !is_dir(realpath($target_dir)))
-  die("Invalid target: not a directory\nUsage: installto.sh <TARGET>\n");
+  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))
-  die("No valid Roundcube installation found at $target_dir\n");
+  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), '>='))
-  die("Installation at target location is up-to-date!\n");
+  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));
diff --git a/bin/moduserprefs.sh b/bin/moduserprefs.sh
index b8ba985..049372c 100755
--- a/bin/moduserprefs.sh
+++ b/bin/moduserprefs.sh
@@ -2,7 +2,7 @@
 <?php
 /*
  +-----------------------------------------------------------------------+
- | bin/moduserprefs.sh                                                      |
+ | bin/moduserprefs.sh                                                   |
  |                                                                       |
  | This file is part of the Roundcube Webmail client                     |
  | Copyright (C) 2012, The Roundcube Dev Team                            |
diff --git a/bin/msgimport.sh b/bin/msgimport.sh
index 41bcd7e..1fcc346 100755
--- a/bin/msgimport.sh
+++ b/bin/msgimport.sh
@@ -33,8 +33,7 @@
 }
 else if (!is_file($args['file']))
 {
-	print "Cannot read message file\n";
-	exit;
+	rcube::raise_error("Cannot read message file.", false, true);
 }
 
 // prompt for username if not set
@@ -87,7 +86,7 @@
 				if ($IMAP->save_message($args['mbox'], rtrim($message)))
 					$count++;
 				else
-					die("Failed to save message to {$args['mbox']}\n");
+					rcube::raise_error("Failed to save message to {$args['mbox']}", false, true);
 				$message = '';
 			}
 			continue;
@@ -108,7 +107,7 @@
 }
 else
 {
-	print "IMAP login failed.\n";
+	rcube::raise_error("IMAP login failed.", false, true);
 }
 
 ?>
diff --git a/bin/updatedb.sh b/bin/updatedb.sh
index 7fa8cce..aeeaf68 100755
--- a/bin/updatedb.sh
+++ b/bin/updatedb.sh
@@ -31,18 +31,15 @@
 ));
 
 if (empty($opts['dir'])) {
-  echo "ERROR: Database schema directory not specified (--dir).\n";
-  exit(1);
+    rcube::raise_error("Database schema directory not specified (--dir).", false, true);
 }
 if (empty($opts['package'])) {
-  echo "ERROR: Database schema package name not specified (--package).\n";
-  exit(1);
+    rcube::raise_error("Database schema package name not specified (--package).", false, true);
 }
 
 // Check if directory exists
 if (!file_exists($opts['dir'])) {
-  echo "ERROR: Specified database schema directory doesn't exist.\n";
-  exit(1);
+    rcube::raise_error("Specified database schema directory doesn't exist.", false, true);
 }
 
 $RC = rcube::get_instance();
@@ -51,8 +48,7 @@
 // Connect to database
 $DB->db_connect('w');
 if (!$DB->is_connected()) {
-    echo "Error connecting to database: " . $DB->is_error() . ".\n";
-    exit(1);
+    rcube::raise_error("Error connecting to database: " . $DB->is_error(), false, true);
 }
 
 // Read DB schema version from database (if 'system' table exists)
@@ -113,8 +109,7 @@
 
 $dir = $opts['dir'] . DIRECTORY_SEPARATOR . $DB->db_provider;
 if (!file_exists($dir)) {
-    echo "DDL Upgrade files for " . $DB->db_provider . " driver not found.\n";
-    exit(1);
+    rcube::raise_error("DDL Upgrade files for " . $DB->db_provider . " driver not found.", false, true);
 }
 
 $dh     = opendir($dir);
@@ -132,13 +127,12 @@
     $error = update_db_schema($opts['package'], $v, $dir . DIRECTORY_SEPARATOR . "$v.sql");
 
     if ($error) {
-        echo "\nError in DDL upgrade $v: $error\n";
-        exit(1);
+        echo "[FAILED]\n";
+        rcube::raise_error("Error in DDL upgrade $v: $error", false, true);
     }
     echo "[OK]\n";
 }
 
-exit(0);
 
 function update_db_schema($package, $version, $file)
 {
diff --git a/installer/rcube_install.php b/installer/rcube_install.php
index b86ccab..2e12987 100644
--- a/installer/rcube_install.php
+++ b/installer/rcube_install.php
@@ -637,8 +637,10 @@
    */
   function update_db($version)
   {
-    system(INSTALL_PATH . "bin/updatedb.sh --package=roundcube --version=" . $version
-      . " --dir=" . INSTALL_PATH . "SQL", $result);
+    system(INSTALL_PATH . "bin/updatedb.sh --package=roundcube"
+      . " --version=" . escapeshellarg($version)
+      . " --dir=" . INSTALL_PATH . "SQL"
+      . " 2>&1", $result);
 
     return !$result;
   }
diff --git a/program/lib/Roundcube/rcube.php b/program/lib/Roundcube/rcube.php
index 77da83d..b681f05 100644
--- a/program/lib/Roundcube/rcube.php
+++ b/program/lib/Roundcube/rcube.php
@@ -1082,6 +1082,9 @@
                 'message' => $arg->getMessage(),
             );
         }
+        else if (is_string($arg)) {
+            $arg = array('message' => $arg, 'type' => 'php');
+        }
 
         if (empty($arg['code'])) {
             $arg['code'] = 500;
@@ -1094,14 +1097,24 @@
             return;
         }
 
-        if (($log || $terminate) && $arg['type'] && $arg['message']) {
+        $cli = php_sapi_name() == 'cli';
+
+        if (($log || $terminate) && !$cli && $arg['type'] && $arg['message']) {
             $arg['fatal'] = $terminate;
             self::log_bug($arg);
         }
 
-        // display error page and terminate script
-        if ($terminate && is_object(self::$instance->output)) {
-            self::$instance->output->raise_error($arg['code'], $arg['message']);
+        // terminate script
+        if ($terminate) {
+            // display error page
+            if (is_object(self::$instance->output)) {
+                self::$instance->output->raise_error($arg['code'], $arg['message']);
+            }
+            else if ($cli) {
+                fwrite(STDERR, 'ERROR: ' . $arg['message']);
+            }
+
+            exit(1);
         }
     }
 
@@ -1140,7 +1153,7 @@
 
             if (!self::write_log('errors', $log_entry)) {
                 // send error to PHPs error handler if write_log didn't succeed
-                trigger_error($arg_arr['message']);
+                trigger_error($arg_arr['message'], E_USER_WARNING);
             }
         }
 

--
Gitblit v1.9.1