diff --git a/include/class.json.php b/include/class.json.php
index f983c73e42fe0394e5a133baebab5e6b26fa639f..b5a589cfac122e008acc207f3bd2942931f31fe7 100644
--- a/include/class.json.php
+++ b/include/class.json.php
@@ -26,6 +26,10 @@ class JsonDataParser {
         while (!feof($stream)) {
             $contents .= fread($stream, 8192);
         }
+        return self::decode($contents);
+    }
+
+    function decode($contents) {
         if (function_exists("json_decode")) {
             return json_decode($contents, true);
         } else {
@@ -56,7 +60,11 @@ class JsonDataParser {
 
 class JsonDataEncoder {
     function encode($var) {
-        $decoder = new Services_JSON();
-        return $decoder->encode($var);
+        if (function_exists('json_encode'))
+            return json_encode($var);
+        else {
+            $decoder = new Services_JSON();
+            return $decoder->encode($var);
+        }
     }
 }
diff --git a/include/mysql.php b/include/mysql.php
index 7375616d9571f009433f0e88086f824621f52820..2a479072cf57eff4dcf6da1e2e7c026949c1a357 100644
--- a/include/mysql.php
+++ b/include/mysql.php
@@ -198,4 +198,8 @@
     function db_errno() {
         return mysql_errno();
     }
+
+    function db_field_type($res, $col=0) {
+        return mysql_field_type($res, $col);
+    }
 ?>
diff --git a/include/mysqli.php b/include/mysqli.php
index 52ce52763c6619ac9829c1bf6d3462124671d64f..ced95434a971b729e5934b3f5754f8f25166aad8 100644
--- a/include/mysqli.php
+++ b/include/mysqli.php
@@ -214,6 +214,11 @@ function db_input($var, $quote=true) {
     return db_real_escape($var, $quote);
 }
 
+function db_field_type($res, $col=0) {
+    global $__db;
+    return $res->fetch_field_direct($col);
+}
+
 function db_connect_error() {
     global $__db;
     return $__db->connect_error;
diff --git a/setup/cli/manage.php b/setup/cli/manage.php
index e11bfafeb3378a550993338117dc94cfcaf10d29..080fb3cf4bd9570e08882420c977a1d6d50d9319 100755
--- a/setup/cli/manage.php
+++ b/setup/cli/manage.php
@@ -13,7 +13,7 @@ class Manager extends Module {
 
     var $usage = '$script action [options] [arguments]';
 
-    var $autohelp = false;
+    var $autohelp = true;
 
     function showHelp() {
         foreach (glob(dirname(__file__).'/modules/*.php') as $script)
diff --git a/setup/cli/modules/export.php b/setup/cli/modules/export.php
new file mode 100644
index 0000000000000000000000000000000000000000..3b7589536fc8da44fd43b000e1be9c9412158e30
--- /dev/null
+++ b/setup/cli/modules/export.php
@@ -0,0 +1,94 @@
+<?php
+/*********************************************************************
+    cli/export.php
+
+    osTicket data exporter, used for migration and backup
+
+    Jared Hancock <jared@osticket.com>
+    Copyright (c)  2006-2013 osTicket
+    http://www.osticket.com
+
+    Released under the GNU General Public License WITHOUT ANY WARRANTY.
+    See LICENSE.TXT for details.
+
+    vim: expandtab sw=4 ts=4 sts=4:
+**********************************************************************/
+require_once dirname(__file__) . "/class.module.php";
+
+require_once dirname(__file__) . '/../../../main.inc.php';
+
+require_once INCLUDE_DIR . 'class.json.php';
+
+define('OSTICKET_BACKUP_SIGNATURE', 'osTicket-Backup');
+define('OSTICKET_BACKUP_VERSION', 'A');
+
+class Exporter extends Module {
+    var $prologue =
+        "Dumps the osTicket database in formats suitable for the importer";
+
+    var $tables = array(CONFIG_TABLE, SYSLOG_TABLE, FILE_TABLE,
+        FILE_CHUNK_TABLE, STAFF_TABLE, DEPT_TABLE, TOPIC_TABLE, GROUP_TABLE,
+        GROUP_DEPT_TABLE, TEAM_TABLE, TEAM_MEMBER_TABLE, FAQ_TABLE,
+        FAQ_ATTACHMENT_TABLE, FAQ_TOPIC_TABLE, FAQ_CATEGORY_TABLE,
+        CANNED_TABLE, CANNED_ATTACHMENT_TABLE, TICKET_TABLE, TICKET_THREAD_TABLE,
+        TICKET_ATTACHMENT_TABLE, TICKET_PRIORITY_TABLE, PRIORITY_TABLE,
+        TICKET_LOCK_TABLE, TICKET_EVENT_TABLE, TICKET_EMAIL_INFO_TABLE,
+        EMAIL_TABLE, EMAIL_TEMPLATE_TABLE, FILTER_TABLE, FILTER_RULE_TABLE,
+        SLA_TABLE, API_KEY_TABLE, TIMEZONE_TABLE, PAGE_TABLE);
+
+    var $options = array(
+        'stream' => array('-o', '--output', 'default'=>'compress.zlib://php://stdout',
+            "File or stream to receive the exported output. As a default,
+            zlib compressed output is sent to standard out.")
+    );
+
+    var $stream;
+
+    function write_block($what) {
+        fwrite($this->stream, JsonDataEncoder::encode($what));
+        fwrite($this->stream, "\x1e");
+    }
+
+    function run($args, $options) {
+        global $ost;
+        $this->stream = fopen($options['stream'], 'w');
+        $header = array(
+            array(OSTICKET_BACKUP_SIGNATURE, OSTICKET_BACKUP_VERSION),
+            array(
+                'version'=>THIS_VERSION,
+                'table_prefix'=>TABLE_PREFIX,
+                'salt'=>SECRET_SALT,
+            ),
+        );
+        $this->write_block($header);
+
+        foreach ($this->tables as $t) {
+            $this->stderr->write("$t\n");
+            // Inspect schema
+            $table = $indexes = array();
+            $res = db_query("show columns from $t");
+            while ($field = db_fetch_array($res))
+                $table[] = $field;
+
+            $res = db_query("show indexes from $t");
+            while ($col = db_fetch_array($res))
+                $indexes[] = $col;
+
+            $res = db_query("select * from $t");
+            $types = array();
+
+            $this->write_block(
+                array('table', substr($t, strlen(TABLE_PREFIX)), $table,
+                    $indexes));
+
+            // Dump row data
+            while ($row = db_fetch_row($res))
+                $this->write_block($row);
+
+            $this->write_block(array('end-table'));
+        }
+    }
+}
+
+Module::register('export', 'Exporter');
+?>