install.php
changeset 238 a78537db2850
parent 231 b11a2f1353c0
parent 237 c26308d81882
child 239 0f1b353570a7
equal deleted inserted replaced
231:b11a2f1353c0 238:a78537db2850
    62 require('includes/constants.php');
    62 require('includes/constants.php');
    63 require('includes/rijndael.php');
    63 require('includes/rijndael.php');
    64 require('includes/functions.php');
    64 require('includes/functions.php');
    65 
    65 
    66 strip_magic_quotes_gpc();
    66 strip_magic_quotes_gpc();
       
    67 $neutral_color = 'C';
       
    68 
       
    69 //
       
    70 // INSTALLER LIBRARY
       
    71 //
       
    72 
       
    73 function run_installer_stage($stage_id, $stage_name, $function, $failure_explanation, $allow_skip = true)
       
    74 {
       
    75   static $resumed = false;
       
    76   static $resume_stack = array();
       
    77   
       
    78   if ( empty($resume_stack) && isset($_POST['resume_stack']) && preg_match('/[a-z_]+((\|[a-z_]+)+)/', $_POST['resume_stack']) )
       
    79   {
       
    80     $resume_stack = explode('|', $_POST['resume_stack']);
       
    81   }
       
    82   
       
    83   $already_run = false;
       
    84   if ( in_array($stage_id, $resume_stack) )
       
    85   {
       
    86     $already_run = true;
       
    87   }
       
    88   
       
    89   if ( !$resumed )
       
    90   {
       
    91     if ( !isset($_GET['stage']) )
       
    92       $resumed = true;
       
    93     if ( isset($_GET['stage']) && $_GET['stage'] == $stage_id )
       
    94     {
       
    95       $resumed = true;
       
    96     }
       
    97   }
       
    98   if ( !$resumed && $allow_skip )
       
    99   {
       
   100     echo_stage_success($stage_id, "[dbg: skipped] $stage_name");
       
   101     return false;
       
   102   }
       
   103   if ( !function_exists($function) )
       
   104     die('libenanoinstall: CRITICAL: function "' . $function . '" for ' . $stage_id . ' doesn\'t exist');
       
   105   $result = @call_user_func($function, false, $already_run);
       
   106   if ( $result )
       
   107   {
       
   108     echo_stage_success($stage_id, $stage_name);
       
   109     $resume_stack[] = $stage_id;
       
   110     return true;
       
   111   }
       
   112   else
       
   113   {
       
   114     echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack);
       
   115     return false;
       
   116   }
       
   117 }
       
   118 
       
   119 function start_install_table()
       
   120 {
       
   121   echo '<table border="0" cellspacing="0" cellpadding="0">' . "\n";
       
   122 }
       
   123 
       
   124 function close_install_table()
       
   125 {
       
   126   echo '</table>' . "\n\n";
       
   127 }
       
   128 
       
   129 function echo_stage_success($stage_id, $stage_name)
       
   130 {
       
   131   global $neutral_color;
       
   132   $neutral_color = ( $neutral_color == 'A' ) ? 'C' : 'A';
       
   133   ob_start();
       
   134   echo '<tr><td style="width: 500px; background-color: #' . "{$neutral_color}{$neutral_color}FF{$neutral_color}{$neutral_color}" . '; padding: 0 5px;">' . htmlspecialchars($stage_name) . '</td><td style="padding: 0 5px;"><img alt="Done" src="images/good.gif" /></td></tr>' . "\n";
       
   135   ob_end_flush();
       
   136 }
       
   137 
       
   138 function echo_stage_failure($stage_id, $stage_name, $failure_explanation, $resume_stack)
       
   139 {
       
   140   global $neutral_color;
       
   141   
       
   142   $neutral_color = ( $neutral_color == 'A' ) ? 'C' : 'A';
       
   143   ob_start();
       
   144   echo '<tr><td style="width: 500px; background-color: #' . "FF{$neutral_color}{$neutral_color}{$neutral_color}{$neutral_color}" . '; padding: 0 5px;">' . htmlspecialchars($stage_name) . '</td><td style="padding: 0 5px;"><img alt="Failed" src="images/bad.gif" /></td></tr>' . "\n";
       
   145   ob_end_flush();
       
   146   close_install_table();
       
   147   $post_data = '';
       
   148   $mysql_error = mysql_error();
       
   149   foreach ( $_POST as $key => $value )
       
   150   {
       
   151     $value = htmlspecialchars($value);
       
   152     $key = htmlspecialchars($key);
       
   153     $post_data .= "          <input type=\"hidden\" name=\"$key\" value=\"$value\" />\n";
       
   154   }
       
   155   echo '<form action="install.php?mode=install&amp;stage=' . $stage_id . '" method="post">
       
   156           ' . $post_data . '
       
   157           <input type="hidden" name="resume_stack" value="' . htmlspecialchars(implode('|', $resume_stack)) . '" />
       
   158           <h3>Enano installation failed.</h3>
       
   159            <p>' . $failure_explanation . '</p>
       
   160            ' . ( !empty($mysql_error) ? "<p>The error returned from MySQL was: $mysql_error</p>" : '' ) . '
       
   161            <p>When you have corrected the error, click the button below to attempt to continue the installation.</p>
       
   162            <p style="text-align: center;"><input type="submit" value="Retry installation" /></p>
       
   163         </form>';
       
   164   global $template, $template_bak;
       
   165   if ( is_object($template_bak) )
       
   166     $template_bak->footer();
       
   167   else
       
   168     $template->footer();
       
   169   exit;
       
   170 }
       
   171 
       
   172 //
       
   173 // INSTALLER STAGES
       
   174 //
       
   175 
       
   176 function stg_mysql_connect($act_get = false)
       
   177 {
       
   178   static $conn = false;
       
   179   if ( $act_get )
       
   180     return $conn;
       
   181   
       
   182   $db_user = mysql_real_escape_string($_POST['db_user']);
       
   183   $db_pass = mysql_real_escape_string($_POST['db_pass']);
       
   184   $db_name = mysql_real_escape_string($_POST['db_name']);
       
   185   
       
   186   if ( !preg_match('/^[a-z0-9_]+$/', $db_name) )
       
   187     die("<p>SECURITY: malformed database name</p>");
       
   188   
       
   189   // First, try to connect using the normal credentials
       
   190   $conn = @mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']);
       
   191   if ( !$conn )
       
   192   {
       
   193     // Connection failed. Do we have the root username and password?
       
   194     if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) )
       
   195     {
       
   196       $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']);
       
   197       if ( !$conn_root )
       
   198       {
       
   199         // Couldn't connect using either set of credentials. Bail out.
       
   200         return false;
       
   201       }
       
   202       // Create the user account
       
   203       $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'localhost' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root);
       
   204       if ( !$q )
       
   205       {
       
   206         return false;
       
   207       }
       
   208       // Revoke privileges from test, we don't need them
       
   209       $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'localhost';", $conn_root);
       
   210       if ( !$q )
       
   211       {
       
   212         return false;
       
   213       }
       
   214       if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' )
       
   215       {
       
   216         // If not connecting to a server running on localhost, allow from any host
       
   217         // this is safer than trying to detect the hostname of the webserver, but less secure
       
   218         $q = @mysql_query("GRANT ALL PRIVILEGES ON test.* TO '{$db_user}'@'%' IDENTIFIED BY '$db_pass' WITH GRANT OPTION;", $conn_root);
       
   219         if ( !$q )
       
   220         {
       
   221           return false;
       
   222         }
       
   223         // Revoke privileges from test, we don't need them
       
   224         $q = @mysql_query("REVOKE ALL PRIVILEGES ON test.* FROM '{$db_user}'@'%';", $conn_root);
       
   225         if ( !$q )
       
   226         {
       
   227           return false;
       
   228         }
       
   229       }
       
   230     }
       
   231   }
       
   232   $q = @mysql_query("USE $db_name;", $conn);
       
   233   if ( !$q )
       
   234   {
       
   235     // access denied to the database; try the whole root schenanegan again
       
   236     if ( !empty($_POST['db_root_user']) && !empty($_POST['db_root_pass']) )
       
   237     {
       
   238       $conn_root = @mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']);
       
   239       if ( !$conn_root )
       
   240       {
       
   241         // Couldn't connect as root; bail out
       
   242         return false;
       
   243       }
       
   244       // create the database, if it doesn't exist
       
   245       $q = @mysql_query("CREATE DATABASE IF NOT EXISTS $db_name;", $conn_root);
       
   246       if ( !$q )
       
   247       {
       
   248         // this really should never fail, so don't give any tolerance to it
       
   249         return false;
       
   250       }
       
   251       // we're in with root rights; grant access to the database
       
   252       $q = @mysql_query("GRANT ALL PRIVILEGES ON $db_name.* TO '{$db_user}'@'localhost';", $conn_root);
       
   253       if ( !$q )
       
   254       {
       
   255         return false;
       
   256       }
       
   257       if ( $_POST['db_host'] != 'localhost' && $_POST['db_host'] != '127.0.0.1' && $_POST['db_host'] != '::1' )
       
   258       {
       
   259         $q = @mysql_query("GRANT ALL PRIVILEGES ON $db_name.* TO '{$db_user}'@'%';", $conn_root);
       
   260         if ( !$q )
       
   261         {
       
   262           return false;
       
   263         }
       
   264       }
       
   265     }
       
   266     else
       
   267     {
       
   268       return false;
       
   269     }
       
   270     // try again
       
   271     $q = @mysql_query("USE $db_name;", $conn);
       
   272     if ( !$q )
       
   273     {
       
   274       // really failed this time; bail out
       
   275       return false;
       
   276     }
       
   277   }
       
   278   // connected and database exists
       
   279   return true;
       
   280 }
       
   281 
       
   282 function stg_drop_tables()
       
   283 {
       
   284   $conn = stg_mysql_connect(true);
       
   285   if ( !$conn )
       
   286     return false;
       
   287   // Our list of tables included in Enano
       
   288   $tables = Array( 'categories', 'comments', 'config', 'logs', 'page_text', 'session_keys', 'pages', 'users', 'users_extra', 'themes', 'buddies', 'banlist', 'files', 'privmsgs', 'sidebar', 'hits', 'search_index', 'groups', 'group_members', 'acl', 'search_cache', 'tags', 'page_groups', 'page_group_members' );
       
   289   
       
   290   // Drop each table individually; if it fails, it probably means we're trying to drop a
       
   291   // table that didn't exist in the Enano version we're deleting the database for.
       
   292   foreach ( $tables as $table )
       
   293   {
       
   294     // Remember that table_prefix is sanitized.
       
   295     $table = "{$_POST['table_prefix']}$table";
       
   296     @mysql_query("DROP TABLE $table;", $conn);
       
   297   }
       
   298   return true;
       
   299 }
       
   300 
       
   301 function stg_decrypt_admin_pass($act_get = false)
       
   302 {
       
   303   static $decrypted_pass = false;
       
   304   if ( $act_get )
       
   305     return $decrypted_pass;
       
   306   
       
   307   $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
       
   308   
       
   309   if ( !empty($_POST['crypt_data']) )
       
   310   {
       
   311     require('config.new.php');
       
   312     if ( !isset($cryptkey) )
       
   313     {
       
   314       return false;
       
   315     }
       
   316     define('_INSTRESUME_AES_KEYBACKUP', $key);
       
   317     $key = hexdecode($cryptkey);
       
   318     
       
   319     $decrypted_pass = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX);
       
   320     
       
   321   }
       
   322   else
       
   323   {
       
   324     $decrypted_pass = $_POST['admin_pass'];
       
   325   }
       
   326   if ( empty($decrypted_pass) )
       
   327     return false;
       
   328   return true;
       
   329 }
       
   330 
       
   331 function stg_generate_aes_key($act_get = false)
       
   332 {
       
   333   static $key = false;
       
   334   if ( $act_get )
       
   335     return $key;
       
   336   
       
   337   $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
       
   338   $key = $aes->gen_readymade_key();
       
   339   return true;
       
   340 }
       
   341 
       
   342 function stg_parse_schema($act_get = false)
       
   343 {
       
   344   static $schema;
       
   345   if ( $act_get )
       
   346     return $schema;
       
   347   
       
   348   $admin_pass = stg_decrypt_admin_pass(true);
       
   349   $key = stg_generate_aes_key(true);
       
   350   $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
       
   351   $key = $aes->hextostring($key);
       
   352   $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX);
       
   353   
       
   354   $cacheonoff = is_writable(ENANO_ROOT.'/cache/') ? '1' : '0';
       
   355   
       
   356   $schema = file_get_contents('schema.sql');
       
   357   $schema = str_replace('{{SITE_NAME}}',    mysql_real_escape_string($_POST['sitename']   ), $schema);
       
   358   $schema = str_replace('{{SITE_DESC}}',    mysql_real_escape_string($_POST['sitedesc']   ), $schema);
       
   359   $schema = str_replace('{{COPYRIGHT}}',    mysql_real_escape_string($_POST['copyright']  ), $schema);
       
   360   $schema = str_replace('{{ADMIN_USER}}',   mysql_real_escape_string($_POST['admin_user'] ), $schema);
       
   361   $schema = str_replace('{{ADMIN_PASS}}',   mysql_real_escape_string($admin_pass          ), $schema);
       
   362   $schema = str_replace('{{ADMIN_EMAIL}}',  mysql_real_escape_string($_POST['admin_email']), $schema);
       
   363   $schema = str_replace('{{ENABLE_CACHE}}', mysql_real_escape_string($cacheonoff          ), $schema);
       
   364   $schema = str_replace('{{REAL_NAME}}',    '',                                              $schema);
       
   365   $schema = str_replace('{{TABLE_PREFIX}}', $_POST['table_prefix'],                          $schema);
       
   366   $schema = str_replace('{{VERSION}}',      ENANO_VERSION,                                   $schema);
       
   367   $schema = str_replace('{{ADMIN_EMBED_PHP}}', $_POST['admin_embed_php'],                    $schema);
       
   368   // Not anymore!! :-D
       
   369   // $schema = str_replace('{{BETA_VERSION}}', ENANO_BETA_VERSION,                              $schema);
       
   370   
       
   371   if(isset($_POST['wiki_mode']))
       
   372   {
       
   373     $schema = str_replace('{{WIKI_MODE}}', '1', $schema);
       
   374   }
       
   375   else
       
   376   {
       
   377     $schema = str_replace('{{WIKI_MODE}}', '0', $schema);
       
   378   }
       
   379   
       
   380   // Build an array of queries      
       
   381   $schema = explode("\n", $schema);
       
   382   
       
   383   foreach ( $schema as $i => $sql )
       
   384   {
       
   385     $query =& $schema[$i];
       
   386     $t = trim($query);
       
   387     if ( empty($t) || preg_match('/^(\#|--)/i', $t) )
       
   388     {
       
   389       unset($schema[$i]);
       
   390       unset($query);
       
   391     }
       
   392   }
       
   393   
       
   394   $schema = array_values($schema);
       
   395   $schema = implode("\n", $schema);
       
   396   $schema = explode(";\n", $schema);
       
   397   
       
   398   foreach ( $schema as $i => $sql )
       
   399   {
       
   400     $query =& $schema[$i];
       
   401     if ( substr($query, ( strlen($query) - 1 ), 1 ) != ';' )
       
   402     {
       
   403       $query .= ';';
       
   404     }
       
   405   }
       
   406   
       
   407   return true;
       
   408 }
       
   409 
       
   410 function stg_install($_unused, $already_run)
       
   411 {
       
   412   // This one's pretty easy.
       
   413   $conn = stg_mysql_connect(true);
       
   414   if ( !is_resource($conn) )
       
   415     return false;
       
   416   $schema = stg_parse_schema(true);
       
   417   if ( !is_array($schema) )
       
   418     return false;
       
   419   
       
   420   // If we're resuming installation, the encryption key was regenerated.
       
   421   // This means we'll have to update the encrypted password in the database.
       
   422   if ( $already_run )
       
   423   {
       
   424     $admin_pass = stg_decrypt_admin_pass(true);
       
   425     $key = stg_generate_aes_key(true);
       
   426     $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
       
   427     $key = $aes->hextostring($key);
       
   428     $admin_pass = $aes->encrypt($admin_pass, $key, ENC_HEX);
       
   429     $admin_user = mysql_real_escape_string($_POST['admin_user']);
       
   430     
       
   431     $q = @mysql_query("UPDATE {$_POST['table_prefix']}users SET password='$admin_pass' WHERE username='$admin_user';");
       
   432     if ( !$q )
       
   433     {
       
   434       echo '<p><tt>MySQL return: ' . mysql_error() . '</tt></p>';
       
   435       return false;
       
   436     }
       
   437     
       
   438     return true;
       
   439   }
       
   440   
       
   441   // OK, do the loop, baby!!!
       
   442   foreach($schema as $q)
       
   443   {
       
   444     $r = mysql_query($q, $conn);
       
   445     if ( !$r )
       
   446     {
       
   447       echo '<p><tt>MySQL return: ' . mysql_error() . '</tt></p>';
       
   448       return false;
       
   449     }
       
   450   }
       
   451   
       
   452   return true;
       
   453 }
       
   454 
       
   455 function stg_write_config()
       
   456 {
       
   457   $privkey = stg_generate_aes_key(true);
       
   458   
       
   459   switch($_POST['urlscheme'])
       
   460   {
       
   461     case "ugly":
       
   462     default:
       
   463       $cp = scriptPath.'/index.php?title=';
       
   464       break;
       
   465     case "short":
       
   466       $cp = scriptPath.'/index.php/';
       
   467       break;
       
   468     case "tiny":
       
   469       $cp = scriptPath.'/';
       
   470       break;
       
   471   }
       
   472   
       
   473   if ( $_POST['urlscheme'] == 'tiny' )
       
   474   {
       
   475     $contents = '# Begin Enano rules
       
   476 RewriteEngine on
       
   477 RewriteCond %{REQUEST_FILENAME} !-d
       
   478 RewriteCond %{REQUEST_FILENAME} !-f
       
   479 RewriteRule ^(.+) '.scriptPath.'/index.php?title=$1 [L,QSA]
       
   480 RewriteRule \.(php|html|gif|jpg|png|css|js)$ - [L]
       
   481 # End Enano rules
       
   482 ';
       
   483     if ( file_exists('./.htaccess') )
       
   484       $ht = fopen(ENANO_ROOT.'/.htaccess', 'a+');
       
   485     else
       
   486       $ht = fopen(ENANO_ROOT.'/.htaccess.new', 'w');
       
   487     if ( !$ht )
       
   488       return false;
       
   489     fwrite($ht, $contents);
       
   490     fclose($ht);
       
   491   }
       
   492 
       
   493   $config_file = '<?php
       
   494 /* Enano auto-generated configuration file - editing not recommended! */
       
   495 $dbhost   = \''.addslashes($_POST['db_host']).'\';
       
   496 $dbname   = \''.addslashes($_POST['db_name']).'\';
       
   497 $dbuser   = \''.addslashes($_POST['db_user']).'\';
       
   498 $dbpasswd = \''.addslashes($_POST['db_pass']).'\';
       
   499 if ( !defined(\'ENANO_CONSTANTS\') )
       
   500 {
       
   501 define(\'ENANO_CONSTANTS\', \'\');
       
   502 define(\'table_prefix\', \''.addslashes($_POST['table_prefix']).'\');
       
   503 define(\'scriptPath\', \''.scriptPath.'\');
       
   504 define(\'contentPath\', \''.$cp.'\');
       
   505 define(\'ENANO_INSTALLED\', \'true\');
       
   506 }
       
   507 $crypto_key = \''.$privkey.'\';
       
   508 ?>';
       
   509 
       
   510   $cf_handle = fopen(ENANO_ROOT.'/config.new.php', 'w');
       
   511   if ( !$cf_handle )
       
   512     return false;
       
   513   fwrite($cf_handle, $config_file);
       
   514   
       
   515   fclose($cf_handle);
       
   516   
       
   517   return true;
       
   518 }
       
   519 
       
   520 function _stg_rename_config_revert()
       
   521 {
       
   522   if ( file_exists('./config.php') )
       
   523   {
       
   524     @rename('./config.php', './config.new.php');
       
   525   }
       
   526   
       
   527   $handle = @fopen('./config.php.new', 'w');
       
   528   if ( !$handle )
       
   529     return false;
       
   530   $contents = '<?php $cryptkey = \'' . _INSTRESUME_AES_KEYBACKUP . '\'; ?>';
       
   531   fwrite($handle, $contents);
       
   532   fclose($handle);
       
   533   return true;
       
   534 }
       
   535 
       
   536 function stg_rename_config()
       
   537 {
       
   538   if ( !@rename('./config.new.php', './config.php') )
       
   539   {
       
   540     echo '<p>Can\'t rename config.php</p>';
       
   541     _stg_rename_config_revert();
       
   542     return false;
       
   543   }
       
   544   
       
   545   if ( $_POST['urlscheme'] == 'tiny' && !file_exists('./.htaccess') )
       
   546   {
       
   547     if ( !@rename('./.htaccess.new', './.htaccess') )
       
   548     {
       
   549       echo '<p>Can\'t rename .htaccess</p>';
       
   550       _stg_rename_config_revert();
       
   551       return false;
       
   552     }
       
   553   }
       
   554   return true;
       
   555 }
       
   556 
       
   557 function stg_start_api_success()
       
   558 {
       
   559   return true;
       
   560 }
       
   561 
       
   562 function stg_start_api_failure()
       
   563 {
       
   564   return false;
       
   565 }
       
   566 
       
   567 function stg_init_logs()
       
   568 {
       
   569   global $db, $session, $paths, $template, $plugins; // Common objects
       
   570   
       
   571   $q = $db->sql_query('INSERT INTO ' . table_prefix . 'logs(log_type,action,time_id,date_string,author,page_text,edit_summary) VALUES(\'security\', \'install_enano\', ' . time() . ', \'' . date('d M Y h:i a') . '\', \'' . mysql_real_escape_string($_POST['admin_user']) . '\', \'' . mysql_real_escape_string(ENANO_VERSION) . '\', \'' . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . '\');');
       
   572   if ( !$q )
       
   573   {
       
   574     echo '<p><tt>MySQL return: ' . mysql_error() . '</tt></p>';
       
   575     return false;
       
   576   }
       
   577   
       
   578   if ( !$session->get_permissions('clear_logs') )
       
   579   {
       
   580     echo '<p><tt>$session: denied clear_logs</tt></p>';
       
   581     return false;
       
   582   }
       
   583   
       
   584   PageUtils::flushlogs('Main_Page', 'Article');
       
   585   
       
   586   return true;
       
   587 }
    67 
   588 
    68 //die('Key size: ' . AES_BITS . '<br />Block size: ' . AES_BLOCKSIZE);
   589 //die('Key size: ' . AES_BITS . '<br />Block size: ' . AES_BLOCKSIZE);
    69 
   590 
    70 if(!function_exists('wikiFormat'))
   591 if(!function_exists('wikiFormat'))
    71 {
   592 {
   388     run_test('return version_compare(\'4.3.0\', PHP_VERSION, \'<\');', 'PHP Version >=4.3.0', 'It seems that the version of PHP that your server is running is too old to support Enano properly. If this is your server, please upgrade to the most recent version of PHP, remembering to use the --with-mysql configure option if you compile it yourself. If this is not your server, please contact your webhost and ask them if it would be possible to upgrade PHP. If this is not possible, you will need to switch to a different webhost in order to use Enano.');
   909     run_test('return version_compare(\'4.3.0\', PHP_VERSION, \'<\');', 'PHP Version >=4.3.0', 'It seems that the version of PHP that your server is running is too old to support Enano properly. If this is your server, please upgrade to the most recent version of PHP, remembering to use the --with-mysql configure option if you compile it yourself. If this is not your server, please contact your webhost and ask them if it would be possible to upgrade PHP. If this is not possible, you will need to switch to a different webhost in order to use Enano.');
   389     run_test('return function_exists(\'mysql_connect\');', 'MySQL extension for PHP', 'It seems that your PHP installation does not have the MySQL extension enabled. If this is your own server, you may need to just enable the "libmysql.so" extension in php.ini. If you do not have the MySQL extension installed, you will need to either use your distribution\'s package manager to install it, or you will have to compile PHP from source. If you compile PHP from source, please remember to use the "--with-mysql" configure option, and you will have to have the MySQL development files installed (they usually are). If this is not your server, please contact your hosting company and ask them to install the PHP MySQL extension.');
   910     run_test('return function_exists(\'mysql_connect\');', 'MySQL extension for PHP', 'It seems that your PHP installation does not have the MySQL extension enabled. If this is your own server, you may need to just enable the "libmysql.so" extension in php.ini. If you do not have the MySQL extension installed, you will need to either use your distribution\'s package manager to install it, or you will have to compile PHP from source. If you compile PHP from source, please remember to use the "--with-mysql" configure option, and you will have to have the MySQL development files installed (they usually are). If this is not your server, please contact your hosting company and ask them to install the PHP MySQL extension.');
   390     run_test('return @ini_get(\'file_uploads\');', 'File upload support', 'It seems that your server does not support uploading files. Enano *requires* this functionality in order to work properly. Please ask your server administrator to set the "file_uploads" option in php.ini to "On".');
   911     run_test('return @ini_get(\'file_uploads\');', 'File upload support', 'It seems that your server does not support uploading files. Enano *requires* this functionality in order to work properly. Please ask your server administrator to set the "file_uploads" option in php.ini to "On".');
   391     run_test('return is_apache();', 'Apache HTTP Server', 'Apparently your server is running a web server other than Apache. Enano will work nontheless, but there are some known bugs with non-Apache servers, and the "fancy" URLs will not work properly. The "Standard URLs" option will be set on the website configuration page, only change it if you are absolutely certain that your server is running Apache.', true);
   912     run_test('return is_apache();', 'Apache HTTP Server', 'Apparently your server is running a web server other than Apache. Enano will work nontheless, but there are some known bugs with non-Apache servers, and the "fancy" URLs will not work properly. The "Standard URLs" option will be set on the website configuration page, only change it if you are absolutely certain that your server is running Apache.', true);
   392     //run_test('return function_exists(\'finfo_file\');', 'Fileinfo PECL extension', 'The MIME magic PHP extension is used to determine the type of a file by looking for a certain "magic" string of characters inside it. This functionality is used by Enano to more effectively prevent malicious file uploads. The MIME magic option will be disabled by default.', true);
   913     //run_test('return function_exists(\'finfo_file\');', 'Fileinfo PECL extension', 'The MIME magic PHP extension is used to determine the type of a file by looking for a certain "magic" string of characters inside it. This functionality is used by Enano to more effectively prevent malicious file uploads. The MIME magic option will be disabled by default.', true);
   393     run_test('return is_writable(ENANO_ROOT.\'/config.php\');', 'Configuration file writable', 'It looks like the configuration file, config.php, is not writable. Enano needs to be able to write to this file in order to install.<br /><br /><b>If you are installing Enano on a SourceForge web site:</b><br />SourceForge mounts the web partitions read-only now, so you will need to use the project shell service to symlink config.php to a file in the /tmp/persistent directory.');
   914     run_test('return is_writable(ENANO_ROOT.\'/config.new.php\');', 'Configuration file writable', 'It looks like the configuration file, config.new.php, is not writable. Enano needs to be able to write to this file in order to install.<br /><br /><b>If you are installing Enano on a SourceForge web site:</b><br />SourceForge mounts the web partitions read-only now, so you will need to use the project shell service to symlink config.php to a file in the /tmp/persistent directory.');
   394     run_test('return file_exists(\'/usr/bin/convert\');', 'ImageMagick support', 'Enano uses ImageMagick to scale images into thumbnails. Because ImageMagick was not found on your server, Enano will use the width= and height= attributes on the &lt;img&gt; tag to scale images. This can cause somewhat of a performance increase, but bandwidth usage will be higher, especially if you use high-resolution images on your site.<br /><br />If you are sure that you have ImageMagick, you can set the location of the "convert" program using the administration panel after installation is complete.', true);
   915     run_test('return file_exists(\'/usr/bin/convert\');', 'ImageMagick support', 'Enano uses ImageMagick to scale images into thumbnails. Because ImageMagick was not found on your server, Enano will use the width= and height= attributes on the &lt;img&gt; tag to scale images. This can cause somewhat of a performance increase, but bandwidth usage will be higher, especially if you use high-resolution images on your site.<br /><br />If you are sure that you have ImageMagick, you can set the location of the "convert" program using the administration panel after installation is complete.', true);
   395     run_test('return is_writable(ENANO_ROOT.\'/cache/\');', 'Cache directory writable', 'Apparently the cache/ directory is not writable. Enano will still work, but you will not be able to cache thumbnails, meaning the server will need to re-render them each time they are requested. In some cases, this can cause a significant slowdown.', true);
   916     run_test('return is_writable(ENANO_ROOT.\'/cache/\');', 'Cache directory writable', 'Apparently the cache/ directory is not writable. Enano will still work, but you will not be able to cache thumbnails, meaning the server will need to re-render them each time they are requested. In some cases, this can cause a significant slowdown.', true);
   396     run_test('return is_writable(ENANO_ROOT.\'/files/\');', 'File uploads directory writable', 'It seems that the directory where uploaded files are stored (' . ENANO_ROOT . '/files) cannot be written by the server. Enano will still function, but file uploads will not function, and will be disabled by default.', true);
   917     run_test('return is_writable(ENANO_ROOT.\'/files/\');', 'File uploads directory writable', 'It seems that the directory where uploaded files are stored (' . ENANO_ROOT . '/files) cannot be written by the server. Enano will still function, but file uploads will not function, and will be disabled by default.', true);
   397     echo '</table>';
   918     echo '</table>';
   398     if(!$failed)
   919     if(!$failed)
   738       echo 'No POST data signature found. Please <a href="install.php?mode=license">restart the installation</a>.';
  1259       echo 'No POST data signature found. Please <a href="install.php?mode=license">restart the installation</a>.';
   739       $template->footer();
  1260       $template->footer();
   740       exit;
  1261       exit;
   741     }
  1262     }
   742     unset($_POST['_cont']);
  1263     unset($_POST['_cont']);
   743     require('config.php');
  1264     require('config.new.php');
   744     $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
  1265     $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
   745     if ( isset($crypto_key) )
  1266     if ( isset($crypto_key) )
   746     {
  1267     {
   747       $cryptkey = $crypto_key;
  1268       $cryptkey = $crypto_key;
   748     }
  1269     }
   749     if(!isset($cryptkey) || ( isset($cryptkey) && strlen($cryptkey) != AES_BITS / 4) )
  1270     if(!isset($cryptkey) || ( isset($cryptkey) && strlen($cryptkey) != AES_BITS / 4) )
   750     {
  1271     {
   751       $cryptkey = $aes->gen_readymade_key();
  1272       $cryptkey = $aes->gen_readymade_key();
   752       $handle = @fopen(ENANO_ROOT.'/config.php', 'w');
  1273       $handle = @fopen(ENANO_ROOT.'/config.new.php', 'w');
   753       if(!$handle)
  1274       if(!$handle)
   754       {
  1275       {
   755         echo '<p>ERROR: Cannot open config.php for writing - exiting!</p>';
  1276         echo '<p>ERROR: Cannot open config.php for writing - exiting!</p>';
   756         $template->footer();
  1277         $template->footer();
   757         exit;
  1278         exit;
   758       }
  1279       }
   759       fwrite($handle, '<?php $cryptkey = \''.$cryptkey.'\'; ?>');
  1280       fwrite($handle, '<?php $cryptkey = \''.$cryptkey.'\'; ?>');
   760       fclose($handle);
  1281       fclose($handle);
   761     }
  1282     }
   762     ?>
  1283     // Sorry for the ugly hack, but this f***s up jEdit badly.
       
  1284     echo '
   763     <script type="text/javascript">
  1285     <script type="text/javascript">
   764       function verify()
  1286       function verify()
   765       {
  1287       {
   766         var frm = document.forms.login;
  1288         var frm = document.forms.login;
   767         ret = true;
  1289         ret = true;
   768         if ( frm.admin_user.value.match(/^([A-z0-9 \-\.]+)$/g) && !frm.admin_user.value.match(/^(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/) && frm.admin_user.value.toLowerCase() != 'anonymous' )
  1290         if ( frm.admin_user.value.match(/^([A-z0-9 \\-\\.]+)$/) && !frm.admin_user.value.match(/^(?:(?:\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$/) && frm.admin_user.value.toLowerCase() != \'anonymous\' )
   769         {
  1291         {
   770           document.getElementById('s_user').src = 'images/good.gif';
  1292           document.getElementById(\'s_user\').src = \'images/good.gif\';
   771         }
  1293         }
   772         else
  1294         else
   773         {
  1295         {
   774           document.getElementById('s_user').src = 'images/bad.gif';
  1296           document.getElementById(\'s_user\').src = \'images/bad.gif\';
   775           ret = false;
  1297           ret = false;
   776         }
  1298         }
   777         if(frm.admin_pass.value.length >= 6 && frm.admin_pass.value == frm.admin_pass_confirm.value)
  1299         if(frm.admin_pass.value.length >= 6 && frm.admin_pass.value == frm.admin_pass_confirm.value)
   778         {
  1300         {
   779           document.getElementById('s_password').src = 'images/good.gif';
  1301           document.getElementById(\'s_password\').src = \'images/good.gif\';
   780         }
  1302         }
   781         else
  1303         else
   782         {
  1304         {
   783           document.getElementById('s_password').src = 'images/bad.gif';
  1305           document.getElementById(\'s_password\').src = \'images/bad.gif\';
   784           ret = false;
  1306           ret = false;
   785         }
  1307         }
   786         if(frm.admin_email.value.match(/^(?:[\w\d]+\.?)+@(?:(?:[\w\d]\-?)+\.)+\w{2,4}$/))
  1308         if(frm.admin_email.value.match(/^(?:[\\w\\d]+\\.?)+@(?:(?:[\\w\\d]\\-?)+\\.)+\\w{2,4}$/))
   787         {
  1309         {
   788           document.getElementById('s_email').src = 'images/good.gif';
  1310           document.getElementById(\'s_email\').src = \'images/good.gif\';
   789         }
  1311         }
   790         else
  1312         else
   791         {
  1313         {
   792           document.getElementById('s_email').src = 'images/bad.gif';
  1314           document.getElementById(\'s_email\').src = \'images/bad.gif\';
   793           ret = false;
  1315           ret = false;
   794         }
  1316         }
   795         if(ret) frm._cont.disabled = false;
  1317         if(ret) frm._cont.disabled = false;
   796         else    frm._cont.disabled = true;
  1318         else    frm._cont.disabled = true;
   797         return ret;
  1319         return ret;
   801       function cryptdata() 
  1323       function cryptdata() 
   802       {
  1324       {
   803         if(!verify()) return false;
  1325         if(!verify()) return false;
   804       }
  1326       }
   805     </script>
  1327     </script>
       
  1328     ';
       
  1329     ?>
   806     <form name="login" action="install.php?mode=confirm" method="post" onsubmit="runEncryption();">
  1330     <form name="login" action="install.php?mode=confirm" method="post" onsubmit="runEncryption();">
   807       <?php
  1331       <?php
   808         $k = array_keys($_POST);
  1332         $k = array_keys($_POST);
   809         for($i=0;$i<sizeof($_POST);$i++) {
  1333         for($i=0;$i<sizeof($_POST);$i++) {
   810           echo '<input type="hidden" name="'.htmlspecialchars($k[$i]).'" value="'.htmlspecialchars($_POST[$k[$i]]).'" />'."\n";
  1334           echo '<input type="hidden" name="'.htmlspecialchars($k[$i]).'" value="'.htmlspecialchars($_POST[$k[$i]]).'" />'."\n";
   845      <input type="hidden" name="crypt_key" value="<?php echo $cryptkey; ?>" />
  1369      <input type="hidden" name="crypt_key" value="<?php echo $cryptkey; ?>" />
   846      <input type="hidden" name="crypt_data" value="" />
  1370      <input type="hidden" name="crypt_data" value="" />
   847     </form>
  1371     </form>
   848     <script type="text/javascript">
  1372     <script type="text/javascript">
   849     // <![CDATA[
  1373     // <![CDATA[
       
  1374       var frm = document.forms.login;
   850       frm.admin_user.focus();
  1375       frm.admin_user.focus();
   851       function runEncryption()
  1376       function runEncryption()
   852       {
  1377       {
   853         str = '';
  1378         str = '';
   854         for(i=0;i<keySizeInBits/4;i++) str+='0';
  1379         for(i=0;i<keySizeInBits/4;i++) str+='0';
   917     </script>
  1442     </script>
   918     <?php
  1443     <?php
   919     break;
  1444     break;
   920   case "confirm":
  1445   case "confirm":
   921     if(!isset($_POST['_cont'])) {
  1446     if(!isset($_POST['_cont'])) {
   922       echo 'No POST data signature found. Please <a href="install.php?mode=license">restart the installation</a>.';
  1447       echo 'No POST data signature found. Please <a href="install.php?mode=sysreqs">restart the installation</a>.';
   923       $template->footer();
  1448       $template->footer();
   924       exit;
  1449       exit;
   925     }
  1450     }
   926     unset($_POST['_cont']);
  1451     unset($_POST['_cont']);
   927     ?>
  1452     ?>
   986         $cp = scriptPath.'/';
  1511         $cp = scriptPath.'/';
   987         break;
  1512         break;
   988     }
  1513     }
   989     function err($t) { global $template; echo $t; $template->footer(); exit; }
  1514     function err($t) { global $template; echo $t; $template->footer(); exit; }
   990     
  1515     
   991       echo 'Connecting to MySQL...';
  1516     // $stages = array('connect', 'decrypt', 'genkey', 'parse', 'sql', 'writeconfig', 'renameconfig', 'startapi', 'initlogs');
   992       if($_POST['db_root_user'] != '')
  1517     
   993       {
  1518     if ( !preg_match('/^[a-z0-9_]*$/', $_POST['table_prefix']) )
   994         $conn = mysql_connect($_POST['db_host'], $_POST['db_root_user'], $_POST['db_root_pass']);
  1519       err('Hacking attempt was detected in table_prefix.');
   995         if(!$conn) err('Error connecting to MySQL: '.mysql_error());
  1520     
   996         $q = mysql_query('USE '.$_POST['db_name']);
  1521       start_install_table();
   997         if(!$q)
  1522       // The stages connect, decrypt, genkey, and parse are preprocessing and don't do any actual data modification.
   998         {
  1523       // Thus, they need to be run on each retry, e.g. never skipped.
   999           $q = mysql_query('CREATE DATABASE '.$_POST['db_name']);
  1524       run_installer_stage('connect', 'Connect to MySQL', 'stg_mysql_connect', 'MySQL denied our attempt to connect to the database. This is most likely because your login information was incorrect. You will most likely need to <a href="install.php?mode=license">restart the installation</a>.', false);
  1000           if(!$q) err('Error initializing database: '.mysql_error());
  1525       if ( isset($_POST['drop_tables']) )
  1001         }
  1526       {
  1002         $q = mysql_query('GRANT ALL PRIVILEGES ON '.$_POST['db_name'].'.* TO \''.$_POST['db_user'].'\'@\'localhost\' IDENTIFIED BY \''.$_POST['db_pass'].'\' WITH GRANT OPTION;');
  1527         // Are we supposed to drop any existing tables? If so, do it now
  1003         if(!$q) err('Could not create the user account');
  1528         run_installer_stage('drop', 'Drop existing Enano tables', 'stg_drop_tables', 'This step never returns failure');
  1004         $q = mysql_query('GRANT ALL PRIVILEGES ON '.$_POST['db_name'].'.* TO \''.$_POST['db_user'].'\'@\'%\' IDENTIFIED BY \''.$_POST['db_pass'].'\' WITH GRANT OPTION;');
  1529       }
  1005         if(!$q) err('Could not create the user account');
  1530       run_installer_stage('decrypt', 'Decrypt administration password', 'stg_decrypt_admin_pass', 'The administration password you entered couldn\'t be decrypted. It is possible that your server did not properly store the encryption key in the configuration file. Please check the file permissions on config.new.php. You may have to return to the login stage of the installation, clear your browser cache, and then rerun this installation.', false);
  1006         mysql_close($conn);
  1531       run_installer_stage('genkey', 'Generate ' . AES_BITS . '-bit AES private key', 'stg_generate_aes_key', 'Enano encountered an internal error while generating the site encryption key. Please contact the Enano team for support.', false);
  1007       }
  1532       run_installer_stage('parse', 'Prepare to execute schema file', 'stg_parse_schema', 'Enano encountered an internal error while parsing the SQL file that contains the database structure and initial data. Please contact the Enano team for support.', false);
  1008       $conn = mysql_connect($_POST['db_host'], $_POST['db_user'], $_POST['db_pass']);
  1533       run_installer_stage('sql', 'Execute installer schema', 'stg_install', 'The installation failed because an SQL query wasn\'t quite correct. It is possible that you entered malformed data into a form field, or there may be a bug in Enano with your version of MySQL. Please contact the Enano team for support.', false);
  1009       if(!$conn) err('Error connecting to MySQL: '.mysql_error());
  1534       run_installer_stage('writeconfig', 'Write configuration files', 'stg_write_config', 'Enano was unable to write the configuration file with your site\'s database credentials. This is almost always because your configuration file does not have the correct permissions. On Windows servers, you may see this message even if the check on the System Requirements page passed. Temporarily running IIS as the Administrator user may help.');
  1010       $q = mysql_query('USE '.$_POST['db_name']);
  1535       run_installer_stage('renameconfig', 'Rename configuration files', 'stg_rename_config', 'Enano couldn\'t rename the configuration files to their correct production names. On some UNIX systems, you need to CHMOD the directory with your Enano files to 777 in order for this stage to succeed.');
  1011       if(!$q) err('Error selecting database: '.mysql_error());
       
  1012       echo 'done!<br />';
       
  1013       
  1536       
  1014       // Are we supposed to drop any existing tables? If so, do it now
  1537       // Mainstream installation complete - Enano should be usable now
  1015       if(isset($_POST['drop_tables']))
  1538       // The stage of starting the API is special because it has to be called out of function context.
  1016       {
  1539       // To alleviate this, we have two functions, one that returns success and one that returns failure
  1017         echo 'Dropping existing Enano tables...';
  1540       // If the Enano API load is successful, the success function is called to report the action to the user
  1018         // Our list of tables included in Enano
  1541       // If unsuccessful, the failure report is sent
  1019         $tables = Array( 'mdg_categories', 'mdg_comments', 'mdg_config', 'mdg_logs', 'mdg_page_text', 'mdg_session_keys', 'mdg_pages', 'mdg_users', 'mdg_users_extra', 'mdg_themes', 'mdg_buddies', 'mdg_banlist', 'mdg_files', 'mdg_privmsgs', 'mdg_sidebar', 'mdg_hits', 'mdg_search_index', 'mdg_groups', 'mdg_group_members', 'mdg_acl', 'mdg_search_cache', 'mdg_tags', 'mdg_page_groups', 'mdg_page_group_members' );
       
  1020         $tables = implode(', ', $tables);
       
  1021         $tables = str_replace('mdg_', $_POST['table_prefix'], $tables);
       
  1022         $query_of_death = 'DROP TABLE '.$tables.';';
       
  1023         mysql_query($query_of_death); // We won't check for errors here because if this operation fails it probably means the tables didn't exist
       
  1024         echo 'done!<br />';
       
  1025       }
       
  1026       
       
  1027       $cacheonoff = is_writable(ENANO_ROOT.'/cache/') ? '1' : '0';
       
  1028       
       
  1029       echo 'Decrypting administration password...';
       
  1030       
       
  1031       $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
       
  1032       
       
  1033       if ( !empty($_POST['crypt_data']) )
       
  1034       {
       
  1035         require('config.php');
       
  1036         if ( !isset($cryptkey) )
       
  1037         {
       
  1038           echo 'failed!<br />Cannot get the key from config.php';
       
  1039           break;
       
  1040         }
       
  1041         $key = hexdecode($cryptkey);
       
  1042         
       
  1043         $dec = $aes->decrypt($_POST['crypt_data'], $key, ENC_HEX);
       
  1044         
       
  1045       }
       
  1046       else
       
  1047       {
       
  1048         $dec = $_POST['admin_pass'];
       
  1049       }
       
  1050       echo 'done!<br />Generating '.AES_BITS.'-bit AES private key...';
       
  1051       $privkey = $aes->gen_readymade_key();
       
  1052       $pkba = hexdecode($privkey);
       
  1053       $encpass = $aes->encrypt($dec, $pkba, ENC_HEX);
       
  1054       
       
  1055       echo 'done!<br />Preparing for schema execution...';
       
  1056       $schema = file_get_contents('schema.sql');
       
  1057       $schema = str_replace('{{SITE_NAME}}',    mysql_real_escape_string($_POST['sitename']   ), $schema);
       
  1058       $schema = str_replace('{{SITE_DESC}}',    mysql_real_escape_string($_POST['sitedesc']   ), $schema);
       
  1059       $schema = str_replace('{{COPYRIGHT}}',    mysql_real_escape_string($_POST['copyright']  ), $schema);
       
  1060       $schema = str_replace('{{ADMIN_USER}}',   mysql_real_escape_string($_POST['admin_user'] ), $schema);
       
  1061       $schema = str_replace('{{ADMIN_PASS}}',   mysql_real_escape_string($encpass             ), $schema);
       
  1062       $schema = str_replace('{{ADMIN_EMAIL}}',  mysql_real_escape_string($_POST['admin_email']), $schema);
       
  1063       $schema = str_replace('{{ENABLE_CACHE}}', mysql_real_escape_string($cacheonoff          ), $schema);
       
  1064       $schema = str_replace('{{REAL_NAME}}',    '',                                              $schema);
       
  1065       $schema = str_replace('{{TABLE_PREFIX}}', $_POST['table_prefix'],                          $schema);
       
  1066       $schema = str_replace('{{VERSION}}',      ENANO_VERSION,                                   $schema);
       
  1067       $schema = str_replace('{{ADMIN_EMBED_PHP}}', $_POST['admin_embed_php'],                    $schema);
       
  1068       // Not anymore!! :-D
       
  1069       // $schema = str_replace('{{BETA_VERSION}}', ENANO_BETA_VERSION,                              $schema);
       
  1070       
       
  1071       if(isset($_POST['wiki_mode']))
       
  1072       {
       
  1073         $schema = str_replace('{{WIKI_MODE}}', '1', $schema);
       
  1074       }
       
  1075       else
       
  1076       {
       
  1077         $schema = str_replace('{{WIKI_MODE}}', '0', $schema);
       
  1078       }
       
  1079       
       
  1080       // Build an array of queries      
       
  1081       $schema = explode("\n", $schema);
       
  1082       
       
  1083       foreach ( $schema as $i => $sql )
       
  1084       {
       
  1085         $query =& $schema[$i];
       
  1086         $t = trim($query);
       
  1087         if ( empty($t) || preg_match('/^(\#|--)/i', $t) )
       
  1088         {
       
  1089           unset($schema[$i]);
       
  1090           unset($query);
       
  1091         }
       
  1092       }
       
  1093       
       
  1094       $schema = array_values($schema);
       
  1095       $schema = implode("\n", $schema);
       
  1096       $schema = explode(";\n", $schema);
       
  1097       
       
  1098       foreach ( $schema as $i => $sql )
       
  1099       {
       
  1100         $query =& $schema[$i];
       
  1101         if ( substr($query, ( strlen($query) - 1 ), 1 ) != ';' )
       
  1102         {
       
  1103           $query .= ';';
       
  1104         }
       
  1105       }
       
  1106       
       
  1107       // echo '<pre>' . htmlspecialchars(print_r($schema, true)) . '</pre>';
       
  1108       // break;
       
  1109       
       
  1110       echo 'done!<br />Executing schema.sql...';
       
  1111       
       
  1112       // OK, do the loop, baby!!!
       
  1113       foreach($schema as $q)
       
  1114       {
       
  1115         $r = mysql_query($q, $conn);
       
  1116         if(!$r) err('Error during mainstream installation: '.mysql_error());
       
  1117       }
       
  1118       
       
  1119       echo 'done!<br />Writing configuration files...';
       
  1120       if($_POST['urlscheme']=='tiny')
       
  1121       {
       
  1122         $ht = fopen(ENANO_ROOT.'/.htaccess', 'a+');
       
  1123         if(!$ht) err('Error opening file .htaccess for writing');
       
  1124         fwrite($ht, '
       
  1125 RewriteEngine on
       
  1126 RewriteCond %{REQUEST_FILENAME} !-d
       
  1127 RewriteCond %{REQUEST_FILENAME} !-f
       
  1128 RewriteRule ^(.+) '.scriptPath.'/index.php?title=$1 [L,QSA]
       
  1129 RewriteRule \.(php|html|gif|jpg|png|css|js)$ - [L]
       
  1130 ');
       
  1131         fclose($ht);
       
  1132       }
       
  1133   
       
  1134       $config_file = '<?php
       
  1135 /* Enano auto-generated configuration file - editing not recommended! */
       
  1136 $dbhost   = \''.addslashes($_POST['db_host']).'\';
       
  1137 $dbname   = \''.addslashes($_POST['db_name']).'\';
       
  1138 $dbuser   = \''.addslashes($_POST['db_user']).'\';
       
  1139 $dbpasswd = \''.addslashes($_POST['db_pass']).'\';
       
  1140 if(!defined(\'ENANO_CONSTANTS\')) {
       
  1141 define(\'ENANO_CONSTANTS\', \'\');
       
  1142 define(\'table_prefix\', \''.$_POST['table_prefix'].'\');
       
  1143 define(\'scriptPath\', \''.scriptPath.'\');
       
  1144 define(\'contentPath\', \''.$cp.'\');
       
  1145 define(\'ENANO_INSTALLED\', \'true\');
       
  1146 }
       
  1147 $crypto_key = \''.$privkey.'\';
       
  1148 ?>';
       
  1149 
       
  1150       $cf_handle = fopen(ENANO_ROOT.'/config.php', 'w');
       
  1151       if(!$cf_handle) err('Couldn\'t open file config.php for writing');
       
  1152       fwrite($cf_handle, $config_file);
       
  1153       fclose($cf_handle);
       
  1154       
       
  1155       echo 'done!<br />Starting the Enano API...';
       
  1156       
  1542       
  1157       $template_bak = $template;
  1543       $template_bak = $template;
  1158       
  1544       
  1159       // Get Enano loaded
       
  1160       $_GET['title'] = 'Main_Page';
  1545       $_GET['title'] = 'Main_Page';
  1161       require('includes/common.php');
  1546       require('includes/common.php');
  1162       
  1547       
       
  1548       if ( is_object($db) && is_object($session) )
       
  1549       {
       
  1550         run_installer_stage('startapi', 'Start the Enano API', 'stg_start_api_success', '...', false);
       
  1551       }
       
  1552       else
       
  1553       {
       
  1554         run_installer_stage('startapi', 'Start the Enano API', 'stg_start_api_failure', 'The Enano API could not be started. This is an error that should never occur; please contact the Enano team for support.', false);
       
  1555       }
       
  1556       
  1163       // We need to be logged in (with admin rights) before logs can be flushed
  1557       // We need to be logged in (with admin rights) before logs can be flushed
  1164       $session->login_without_crypto($_POST['admin_user'], $dec, false);
  1558       $admin_password = stg_decrypt_admin_pass(true);
       
  1559       $session->login_without_crypto($_POST['admin_user'], $admin_password, false);
  1165       
  1560       
  1166       // Now that login cookies are set, initialize the session manager and ACLs
  1561       // Now that login cookies are set, initialize the session manager and ACLs
  1167       $session->start();
  1562       $session->start();
  1168       $paths->init();
  1563       $paths->init();
  1169       
  1564       
       
  1565       run_installer_stage('initlogs', 'Initialize logs', 'stg_init_logs', '<b>The session manager denied the request to flush logs for the main page.</b><br />
       
  1566                            While under most circumstances you can still <a href="install.php?mode=finish">finish the installation</a>, you should be aware that some servers cannot
       
  1567                            properly set cookies due to limitations with PHP. These limitations are exposed primarily when this issue is encountered during installation. If you choose
       
  1568                            to finish the installation, please be aware that you may be unable to log into your site.');
       
  1569       close_install_table();
       
  1570       
  1170       unset($template);
  1571       unset($template);
  1171       $template =& $template_bak;
  1572       $template =& $template_bak;
  1172       
  1573     
  1173       echo 'done!<br />Initializing logs...';
  1574       echo '<h3>Installation of Enano is complete.</h3><p>Review any warnings above, and then <a href="install.php?mode=finish">click here to finish the installation</a>.';
  1174       
       
  1175       $q = $db->sql_query('INSERT INTO ' . $_POST['table_prefix'] . 'logs(log_type,action,time_id,date_string,author,page_text,edit_summary) VALUES(\'security\', \'install_enano\', ' . time() . ', \'' . date('d M Y h:i a') . '\', \'' . mysql_real_escape_string($_POST['admin_user']) . '\', \'' . mysql_real_escape_string(ENANO_VERSION) . '\', \'' . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . '\');', $conn);
       
  1176       if ( !$q )
       
  1177         err('Error setting up logs: '.$db->get_error());
       
  1178       
       
  1179       if ( !$session->get_permissions('clear_logs') )
       
  1180       {
       
  1181         echo '<br />Error: session manager won\'t permit flushing logs, these is a bug.';
       
  1182         break;
       
  1183       }
       
  1184       
       
  1185       // unset($session);
       
  1186       // $session = new sessionManager();
       
  1187       // $session->start();
       
  1188       
       
  1189       PageUtils::flushlogs('Main_Page', 'Article');
       
  1190       
       
  1191       echo 'done!<h3>Installation of Enano is complete.</h3><p>Review any warnings above, and then <a href="install.php?mode=finish">click here to finish the installation</a>.';
       
  1192       
  1575       
  1193       // echo '<script type="text/javascript">window.location="'.scriptPath.'/install.php?mode=finish";</script>';
  1576       // echo '<script type="text/javascript">window.location="'.scriptPath.'/install.php?mode=finish";</script>';
  1194       
  1577       
  1195     break;
  1578     break;
  1196   case "finish":
  1579   case "finish":