diff -r 5c807fe77020 -r 68060328e9c6 install/includes/cli-core.php
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/install/includes/cli-core.php Wed Jan 14 20:33:05 2009 -0500
@@ -0,0 +1,633 @@
+set_visible_stage($ui->add_stage('Error', true));
+
+ $ui->step = 'Access denied';
+ $ui->show_header();
+ echo '
CLI only
+ This script must be run from the command line.
';
+ $ui->show_footer();
+ exit;
+}
+
+// parse command line args
+foreach ( array('silent', 'driver', 'dbhost', 'dbuser', 'dbpasswd', 'dbname', 'db_prefix', 'user', 'pass', 'email', 'sitename', 'sitedesc', 'copyright', 'urlscheme', 'lang_id', 'scriptpath') as $var )
+{
+ if ( !isset($$var) )
+ {
+ $$var = false;
+ }
+}
+
+for ( $i = 1; $i < count($argv); $i++ )
+{
+ switch($argv[$i])
+ {
+ case '-q':
+ $silent = true;
+ break;
+ case '--db-driver':
+ case '-b':
+ $driver = @$argv[++$i];
+ break;
+ case '--db-host':
+ case '-h':
+ $dbhost = @$argv[++$i];
+ break;
+ case '--db-user':
+ case '-u':
+ $dbuser = @$argv[++$i];
+ break;
+ case '--db-pass':
+ case '-p':
+ $dbpasswd = @$argv[++$i];
+ break;
+ case '--db-name':
+ case '-d':
+ $dbname = @$argv[++$i];
+ break;
+ case '--table-prefix':
+ case '-t':
+ $db_prefix = @$argv[++$i];
+ break;
+ case '--admin-user':
+ case '-a':
+ $user = @$argv[++$i];
+ break;
+ case '--admin-pass':
+ case '-w':
+ $pass = @$argv[++$i];
+ break;
+ case '--admin-email':
+ case '-e':
+ $email = @$argv[++$i];
+ break;
+ case '--site-name':
+ case '-n':
+ $sitename = @$argv[++$i];
+ break;
+ case '--site-desc':
+ case '-s':
+ $sitedesc = @$argv[++$i];
+ break;
+ case '--copyright':
+ case '-c':
+ $copyright = @$argv[++$i];
+ break;
+ case '--url-scheme':
+ case '-r':
+ $urlscheme_temp = @$argv[++$i];
+ if ( in_array($urlscheme_temp, array('standard', 'short', 'rewrite')) )
+ $urlscheme = $urlscheme_temp;
+ break;
+ case '--language':
+ case '-l':
+ $lang_id = @$argv[++$i];
+ break;
+ case '-i':
+ case '--scriptpath':
+ $scriptpath = @$argv[++$i];
+ break;
+ default:
+ $vers = installer_enano_version();
+ echo << $metadata )
+ {
+ $id_spaced = $id;
+ while ( strlen($id_spaced) < 10 )
+ $id_spaced = "$id_spaced ";
+ echo " \x1B[1;34m$id_spaced\x1B[0m {$metadata['name']} ({$metadata['name_eng']})\n";
+ }
+ while ( !in_array($lang_id, $langids) )
+ {
+ $lang_id = cli_prompt('Language: ', $langids[0]);
+ }
+}
+
+// We have a language ID - init language
+$language_dir = $languages[$lang_id]['dir'];
+
+// Initialize language support
+$lang = new Language($lang_id);
+$lang->load_file(ENANO_ROOT . '/language/' . $language_dir . '/install.json');
+
+##
+## WELCOME MESSAGE
+##
+
+if ( !$silent )
+{
+ echo parse_shellcolor_string($lang->get('cli_welcome_line1'));
+ echo parse_shellcolor_string($lang->get('cli_welcome_line2', array('enano_version' => installer_enano_version(), 'php_version' => PHP_VERSION)));
+}
+
+$defaults = array(
+ 'driver' => 'mysql',
+ 'dbhost' => 'localhost',
+ 'dbuser' => false,
+ 'dbpasswd' => false,
+ 'dbname' => false,
+ 'db_prefix' => '',
+ 'user' => 'admin',
+ 'pass' => false,
+ 'email' => false,
+ 'sitename' => $lang->get('cli_default_site_name'),
+ 'sitedesc' => $lang->get('cli_default_site_desc'),
+ 'copyright' => $lang->get('cli_default_copyright', array('year' => date('Y'))),
+ 'urlscheme' => 'standard',
+ 'scriptpath'=> '/enano'
+);
+
+$terms = array(
+ 'driver' => $lang->get('cli_prompt_driver'),
+ 'dbhost' => $lang->get('cli_prompt_dbhost'),
+ 'dbuser' => $lang->get('cli_prompt_dbuser'),
+ 'dbpasswd' => $lang->get('cli_prompt_dbpasswd'),
+ 'dbname' => $lang->get('cli_prompt_dbname'),
+ 'db_prefix' => $lang->get('cli_prompt_db_prefix'),
+ 'user' => $lang->get('cli_prompt_user'),
+ 'pass' => $lang->get('cli_prompt_pass'),
+ 'email' => $lang->get('cli_prompt_email'),
+ 'sitename' => $lang->get('cli_prompt_sitename'),
+ 'sitedesc' => $lang->get('cli_prompt_sitedesc'),
+ 'copyright' => $lang->get('cli_prompt_copyright'),
+ 'urlscheme' => $lang->get('cli_prompt_urlscheme'),
+ 'scriptpath'=> $lang->get('cli_prompt_scriptpath')
+);
+
+foreach ( array('driver', 'dbhost', 'dbuser', 'dbpasswd', 'dbname', 'db_prefix', 'scriptpath', 'user', 'pass', 'email', 'sitename', 'sitedesc', 'copyright', 'urlscheme') as $var )
+{
+ if ( empty($$var) )
+ {
+ switch($var)
+ {
+ default:
+ $$var = cli_prompt($terms[$var], $defaults[$var]);
+ break;
+ case 'pass':
+ case 'dbpasswd':
+ if ( @file_exists('/bin/stty') && @is_executable('/bin/stty') )
+ {
+ exec('/bin/stty -echo');
+ while ( true )
+ {
+ $$var = cli_prompt($terms[$var], $defaults[$var]);
+ echo "\n";
+ $confirm = cli_prompt($lang->get('cli_prompt_confirm'), $defaults[$var]);
+ echo "\n";
+ if ( $$var === $confirm )
+ break;
+ else
+ echo parse_shellcolor_string($lang->get('cli_err_pass_no_match'));
+ }
+ exec('/bin/stty echo');
+ }
+ else
+ {
+ $$var = cli_prompt("{$terms[$var]} " . $lang->get('cli_msg_echo_warning'), $defaults[$var]);
+ }
+ break;
+ case 'urlscheme':
+ $temp = '';
+ while ( !in_array($temp, array('standard', 'short', 'rewrite')) )
+ {
+ $temp = cli_prompt($terms[$var], $defaults[$var]);
+ }
+ $$var = $temp;
+ break;
+ case 'db_prefix':
+ while ( !preg_match('/^[a-z0-9_]*$/', $$var) )
+ {
+ $$var = cli_prompt($terms[$var], $defaults[$var]);
+ }
+ break;
+ }
+ }
+}
+
+##
+## DB TEST
+##
+
+require( ENANO_ROOT . '/includes/dbal.php' );
+require( ENANO_ROOT . '/includes/sql_parse.php' );
+$dbal = new $driver();
+
+if ( !$silent )
+ echo parse_shellcolor_string($lang->get('cli_msg_testing_db'));
+
+$result = $dbal->connect(true, $dbhost, $dbuser, $dbpasswd, $dbname);
+if ( !$result )
+{
+ if ( !$silent )
+ echo parse_shellcolor_string($lang->get('cli_test_fail')) . "\n";
+ installer_fail($lang->get('cli_err_db_connect_fail'));
+}
+
+if ( !$silent )
+ echo parse_shellcolor_string($lang->get('cli_test_pass')) . "\n";
+
+##
+## SERVER REQUIREMENTS
+##
+
+if ( !$silent )
+{
+ echo parse_shellcolor_string($lang->get('cli_stage_sysreqs'));
+}
+
+$test_failed = false;
+
+run_test('return version_compare(\'5.2.0\', PHP_VERSION, \'<=\');', $lang->get('sysreqs_req_php5'), $lang->get('sysreqs_req_desc_php5'), true);
+run_test('return function_exists(\'mysql_connect\');', $lang->get('sysreqs_req_mysql'), $lang->get('sysreqs_req_desc_mysql'), true);
+run_test('return function_exists(\'pg_connect\');', $lang->get('sysreqs_req_postgres'), $lang->get('sysreqs_req_desc_postgres'), true);
+run_test('return @ini_get(\'file_uploads\');', $lang->get('sysreqs_req_uploads'), $lang->get('sysreqs_req_desc_uploads') );
+run_test('return config_write_test();', $lang->get('sysreqs_req_config'), $lang->get('sysreqs_req_desc_config') );
+run_test('return file_exists(\'/usr/bin/convert\');', $lang->get('sysreqs_req_magick'), $lang->get('sysreqs_req_desc_magick'), true);
+run_test('return is_writable(ENANO_ROOT.\'/cache/\');', $lang->get('sysreqs_req_cachewriteable'), $lang->get('sysreqs_req_desc_cachewriteable'), true);
+run_test('return is_writable(ENANO_ROOT.\'/files/\');', $lang->get('sysreqs_req_fileswriteable'), $lang->get('sysreqs_req_desc_fileswriteable'), true);
+if ( !function_exists('mysql_connect') && !function_exists('pg_connect') )
+{
+ installer_fail($lang->get('cli_err_no_drivers'));
+}
+if ( $test_failed )
+{
+ installer_fail($lang->get('cli_err_sysreqs_fail'));
+}
+
+##
+## STAGE 1 INSTALLATION
+##
+
+if ( !$silent )
+{
+ echo parse_shellcolor_string($lang->get('cli_msg_tests_passed'));
+ echo parse_shellcolor_string($lang->get('cli_msg_installing_db_stage1'));
+}
+
+// Create the config table
+try
+{
+ $sql_parser = new SQL_Parser( ENANO_ROOT . "/install/schemas/{$driver}_stage1.sql" );
+}
+catch ( Exception $e )
+{
+ if ( !$silent )
+ echo "\n";
+ installer_fail($lang->get('cli_err_schema_load'));
+}
+// Check to see if the config table already exists
+$q = $dbal->sql_query('SELECT config_name, config_value FROM ' . $db_prefix . 'config LIMIT 1;');
+if ( !$q )
+{
+ $sql_parser->assign_vars(array(
+ 'TABLE_PREFIX' => $db_prefix
+ ));
+ $sql = $sql_parser->parse();
+ foreach ( $sql as $q )
+ {
+ if ( !$dbal->sql_query($q) )
+ {
+ if ( !$silent )
+ echo "\n";
+ echo "[$driver] " . $dbal->sql_error() . "\n";
+ installer_fail($lang->get('cli_err_db_query'));
+ }
+ }
+}
+else
+{
+ $dbal->free_result();
+ if ( !$dbal->sql_query('DELETE FROM ' . $db_prefix . 'config WHERE config_name = \'install_aes_key\';') )
+ {
+ if ( !$silent )
+ echo "\n";
+ echo "[$driver] " . $dbal->sql_error() . "\n";
+ installer_fail($lang->get('cli_err_db_query'));
+ }
+}
+
+if ( !$silent )
+ echo parse_shellcolor_string($lang->get('cli_msg_ok')) . "\n";
+
+define('table_prefix', $db_prefix);
+
+##
+## STAGE 2 INSTALLATION
+##
+
+$db =& $dbal;
+$dbdriver =& $driver;
+
+// Yes, I am predicting the future here. Because I have that kind of power.
+$_SERVER['REMOTE_ADDR'] = ( intval(date('Y')) >= 2011 ) ? '::1' : '127.0.0.1';
+
+if ( !$silent )
+ echo parse_shellcolor_string($lang->get('cli_msg_parsing_schema'));
+
+require_once( ENANO_ROOT . '/includes/rijndael.php' );
+require_once( ENANO_ROOT . '/includes/hmac.php' );
+
+$aes = AESCrypt::singleton(AES_BITS, AES_BLOCKSIZE);
+$hmac_secret = hexencode(AESCrypt::randkey(20), '', '');
+
+$admin_pass_clean =& $pass;
+$admin_pass = hmac_sha1($admin_pass_clean, $hmac_secret);
+
+unset($admin_pass_clean); // Security
+
+try
+{
+ $sql_parser = new SQL_Parser( ENANO_ROOT . "/install/schemas/{$dbdriver}_stage2.sql" );
+}
+catch ( Exception $e )
+{
+ if ( !$silent )
+ echo "\n";
+ installer_fail($lang->get('cli_err_schema_load'));
+}
+
+$wkt = ENANO_ROOT . "/language/{$languages[$lang_id]['dir']}/install/mainpage-default.wkt";
+if ( !file_exists( $wkt ) )
+{
+ if ( !$silent )
+ echo "\n";
+ installer_fail($lang->get('cli_err_mainpage_load'));
+}
+$wkt = @file_get_contents($wkt);
+if ( empty($wkt) )
+ return false;
+
+$wkt = $db->escape($wkt);
+
+$vars = array(
+ 'TABLE_PREFIX' => table_prefix,
+ 'SITE_NAME' => $sitename,
+ 'SITE_DESC' => $sitedesc,
+ 'COPYRIGHT' => $copyright,
+ 'WIKI_MODE' => '0',
+ 'ENABLE_CACHE' => ( is_writable( ENANO_ROOT . '/cache/' ) ? '1' : '0' ),
+ 'VERSION' => installer_enano_version(),
+ 'ADMIN_USER' => $db->escape($user),
+ 'ADMIN_PASS' => $admin_pass,
+ 'ADMIN_PASS_SALT' => $hmac_secret,
+ 'ADMIN_EMAIL' => $db->escape($email),
+ 'REAL_NAME' => '', // This has always been stubbed.
+ 'ADMIN_EMBED_PHP' => strval(AUTH_DISALLOW),
+ 'UNIX_TIME' => strval(time()),
+ 'MAIN_PAGE_CONTENT' => $wkt,
+ 'IP_ADDRESS' => $_SERVER['REMOTE_ADDR']
+ );
+
+$sql_parser->assign_vars($vars);
+$schema = $sql_parser->parse();
+
+if ( !$silent )
+ echo parse_shellcolor_string($lang->get('cli_msg_ok')) . "\n";
+
+##
+## PAYLOAD DELIVERY
+##
+
+if ( !$silent )
+ echo parse_shellcolor_string($lang->get('cli_msg_installing_db_stage2'));
+
+foreach ( $schema as $sql )
+{
+ if ( !$db->check_query($sql) )
+ {
+ if ( !$silent )
+ echo "\n";
+ installer_fail($lang->get('cli_err_query_sanity_failed'));
+ }
+}
+
+foreach ( $schema as $sql )
+{
+ if ( !$db->sql_query($sql) )
+ {
+ if ( !$silent )
+ echo "\n";
+ echo "[$dbdriver] " . $db->sql_error() . "\n";
+ installer_fail($lang->get('cli_err_db_query'));
+ }
+}
+
+if ( !$silent )
+ echo parse_shellcolor_string($lang->get('cli_msg_ok')) . "\n";
+
+##
+## CONFIG FILE GENERATION
+##
+
+require_once( ENANO_ROOT . '/install/includes/payload.php' );
+require_once( ENANO_ROOT . '/install/includes/libenanoinstallcli.php' );
+define('scriptPath', $scriptpath);
+$urlscheme = strtr($urlscheme, array(
+ 'short' => 'shortened'
+));
+$_POST['url_scheme'] =& $urlscheme;
+
+run_installer_stage('writeconfig', 'writing_config', 'stg_write_config', 'install_stg_writeconfig_body');
+
+##
+## FINAL STAGES
+##
+
+if ( !$silent )
+ echo parse_shellcolor_string($lang->get('cli_msg_starting_api'));
+
+// Start up the Enano API
+$db->close();
+@define('ENANO_ALLOW_LOAD_NOLANG', 1);
+// If this fails, it fails hard.
+require(ENANO_ROOT . '/includes/common.php');
+
+if ( !$silent )
+ echo parse_shellcolor_string($lang->get('cli_msg_ok')) . "\n";
+
+run_installer_stage('importlang', 'importing_language', 'stg_language_setup', $lang->get('install_stg_importlang_body'));
+run_installer_stage('initlogs', 'initting_logs', 'stg_init_logs', $lang->get('install_stg_initlogs_body'));
+run_installer_stage('cleanup', 'cleaning_up', 'stg_aes_cleanup', $lang->get('install_stg_cleanup_body'), false);
+run_installer_stage('buildindex', 'initting_index', 'stg_build_index', $lang->get('install_stg_buildindex_body'));
+run_installer_stage('renameconfig', 'renaming_config', 'stg_rename_config', $lang->get('install_stg_rename_body', array('mainpage_link' => scriptPath . '/index.php')));
+
+if ( !$silent )
+{
+ echo parse_shellcolor_string($lang->get('cli_msg_install_success'));
+}
+
+return true;
+
+##
+## FUNCTIONS
+##
+
+function cli_prompt($prompt, $default = false)
+{
+ if ( is_string($default) )
+ {
+ echo "$prompt [$default]: ";
+ $stdin = fopen('php://stdin', 'r');
+ $input = trim(fgets($stdin, 1024));
+ fclose($stdin);
+ if ( empty($input) )
+ return $default;
+ return $input;
+ }
+ else
+ {
+ while ( true )
+ {
+ echo "$prompt: ";
+ $stdin = fopen('php://stdin', 'r');
+ $input = trim(fgets($stdin, 1024));
+ fclose($stdin);
+ if ( !empty($input) )
+ return $input;
+ }
+ }
+}
+
+function run_test($evalme, $test, $description, $warnonly = false)
+{
+ global $silent, $test_failed, $lang;
+ if ( !$silent )
+ echo "$test: ";
+ $result = eval($evalme);
+ if ( $result )
+ {
+ if ( !$silent )
+ echo parse_shellcolor_string($lang->get('cli_test_pass'));
+ }
+ else
+ {
+ if ( !$silent )
+ echo $warnonly ? parse_shellcolor_string($lang->get('cli_test_warn')) : parse_shellcolor_string($lang->get('cli_test_fail'));
+ if ( !$silent )
+ echo "\n" . preg_replace('/^/m', ' ', wordwrap(strip_tags($description)));
+ if ( !$warnonly )
+ $test_failed = true;
+ }
+ if ( !$silent )
+ echo "\n";
+}
+
+function installer_fail($message)
+{
+ global $silent;
+ if ( $silent )
+ file_put_contents('php://stderr', "$message\n");
+ else
+ echo "\x1B[1;31m" . "Error:\x1B[0;1m $message\x1B[0m\n";
+ exit(1);
+}
+
+function config_write_test()
+{
+ if ( !is_writable(ENANO_ROOT.'/config.new.php') )
+ return false;
+ // We need to actually _open_ the file to make sure it can be written, because sometimes this fails even when is_writable() returns
+ // true on Windows/IIS servers. Don't ask me why.
+ $h = @fopen( ENANO_ROOT . '/config.new.php', 'a+' );
+ if ( !$h )
+ return false;
+ fclose($h);
+ return true;
+}
+
+function parse_shellcolor_string($str)
+{
+ $expr = '/([\w\W]*?)<\/c>/';
+ while ( preg_match($expr, $str) )
+ $str = preg_replace($expr, "\x1B[\\1m\\2\x1B[0m", $str);
+
+ return $str;
+}
+