=== added file 'includes/install.mysql.inc'
--- /dev/null	
+++ includes/install.mysql.inc	
@@ -0,0 +1,133 @@
+<?php
+
+// MySQL specific install functions
+
+/**
+ * Check if MySQL is available.
+ *
+ * @return
+ *  TRUE/FALSE
+ */
+function mysql_is_available() {
+  return function_exists('mysql_connect');
+}
+
+/**
+ * Check if we can connect to MySQL.
+ *
+ * @return
+ *  TRUE/FALSE
+ */
+function drupal_test_mysql($url, &$success) {
+  if (!mysql_is_available()) {
+    drupal_set_message('PHP MySQL support not enabled.', 'error');
+  }
+
+  $url = parse_url($url);
+
+  // Decode url-encoded information in the db connection string
+  $url['user'] = urldecode($url['user']);
+  $url['pass'] = urldecode($url['pass']);
+  $url['host'] = urldecode($url['host']);
+  $url['path'] = urldecode($url['path']);
+
+  // Allow for non-standard MySQL port.
+  if (isset($url['port'])) {
+     $url['host'] = $url['host'] .':'. $url['port'];
+  }
+
+  if ($connection = @mysql_connect($url['host'], $url['user'], $url['pass'], TRUE, 2)) {
+    // Test selecting the database
+    if (!mysql_select_db(substr($url['path'], 1))) {
+      drupal_set_message('We were able to connect to the MySQL database server (which means your username and password are valid) but not able to select your database. MySQL reports the following message: <em>'. mysql_error() .'</em><ul><li>Are you sure you have the correct database name?</li><li>Are you sure the database exists?</li><li>Are you sure the username has permission to access the database?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', 'error');
+      return FALSE;
+    }
+
+    // Test CREATE
+    $query = 'CREATE TABLE drupal_install_test (id int(1) NULL);';
+    $result = mysql_query("$query");
+    if ($error = mysql_error()) {
+      drupal_set_message('We were unable to create a test table on your MySQL database server. MySQL reports the following message: "<em>'. $error .'</em>"<ul><li>Are you sure the configured username has the necessary MySQL permissions to create tables in the database?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', 'error');
+      return FALSE;
+    }
+    $err = FALSE;
+    $success = array('SELECT', 'CREATE');
+
+    // Test INSERT
+    $query = 'INSERT INTO drupal_install_test (id) VALUES(1);';
+    $result = mysql_query("$query");
+    if ($error = mysql_error()) {
+      drupal_set_message('We were unable to insert a value into a test table on your MySQL database server. We tried inserting a value with the command "<code>'. $query .'</code>" and MySQL reported the following error: "<em>'. $error .'</em>".', 'error');
+      $err = TRUE;
+    }
+    else {
+      $success[] = 'INSERT';
+    }
+
+    // Test UPDATE
+    $query = 'UPDATE drupal_install_test SET id = 2;';
+    $result = mysql_query("$query");
+    if ($error = mysql_error()) {
+      drupal_set_message('We were unable to update a value in a test table on your MySQL database server. We tried updating a value with the command "<code>'. $query .'</code>" and MySQL reported the following error: "<em>'. $error .'</em>".', 'error');
+      $err = TRUE;
+    }
+    else {
+      $success[] = 'UPDATE';
+    }
+
+    // Test LOCK
+    $query = 'LOCK TABLES drupal_install_test WRITE;';
+    $result = mysql_query("$query");
+    if ($error = mysql_error()) {
+      drupal_set_message('We were unable to lock a test table on your MySQL database server. We tried locking a table with the command "<code>'. $query .'</code>" and MySQL reported the following error: "<em>'. $error .'</em>".', 'error');
+      $err = TRUE;
+    }
+    else {
+      $success[] = 'LOCK';
+    }
+
+    // Test UNLOCK
+    $query = 'UNLOCK TABLES;';
+    $result = mysql_query("$query");
+    if ($error = mysql_error()) {
+      drupal_set_message('We were unable to unlock a test table on your MySQL database server. We tried unlocking a table with the command "<code>'. $query .'</code>" and MySQL reported the following error: "<em>'. $error .'</em>".', 'error');
+      $err = TRUE;
+    }
+    else {
+      $success[] = 'UNLOCK';
+    }
+
+    // Test DELETE
+    $query = 'DELETE FROM drupal_install_test;';
+    $result = mysql_query("$query");
+    if ($error = mysql_error()) {
+      drupal_set_message('We were unable to delete a value from a test table on your MySQL database server. We tried deleting a value with the command "<code>'. $query .'</code>" and MySQL reported the following error: "<em>'. $error .'</em>".', 'error');
+      $err = TRUE;
+    }
+    else {
+      $success[] = 'DELETE';
+    }
+
+    // Test DROP
+    $query = 'DROP TABLE drupal_install_test;';
+    $result = mysql_query("$query");
+    if ($error = mysql_error()) {
+      drupal_set_message('We were unable to drop a test table from your MySQL database server. We tried dropping a table with the command "<code>'. $query .'</code>" and MySQL reported the following error: "<em>'. $error .'</em>".', 'error');
+      $err = TRUE;
+    }
+    else {
+      $success[] = 'DROP';
+    }
+
+    if ($err) {
+      return FALSE;
+    }
+
+    mysql_close($connection);
+    return TRUE;
+  }
+  else {
+    drupal_set_message('Failure to connect to your MySQL database server. MySQL reports the following message: <em>'. mysql_error() .'</em><ul><li>Are you sure you have the correct username and password?</li><li>Are you sure that you have typed the correct database hostname?</li><li>Are you sure that the database server is running?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', 'error');
+  }
+  return FALSE;
+}
=== added file 'includes/install.mysqli.inc'
--- /dev/null	
+++ includes/install.mysqli.inc	
@@ -0,0 +1,136 @@
+<?php
+
+// MySQL specific install functions
+
+/**
+ * Check if MySQL is available.
+ *
+ * @return
+ *  TRUE/FALSE
+ */
+function mysqli_is_available() {
+  return function_exists('mysqli_init');
+}
+
+/**
+ * Check if we can connect to MySQL.
+ *
+ * @return
+ *  TRUE/FALSE
+ */
+function drupal_test_mysqli($url, &$success) {
+  if (!mysqli_is_available()) {
+    drupal_set_message('PHP MySQL support not enabled.', 'error');
+  }
+
+  $url = parse_url($url);
+
+  // Decode url-encoded information in the db connection string
+  $url['user'] = urldecode($url['user']);
+  $url['pass'] = urldecode($url['pass']);
+  $url['host'] = urldecode($url['host']);
+  $url['path'] = urldecode($url['path']);
+
+  // Allow for non-standard MySQL port.
+  if (isset($url['port'])) {
+     $url['host'] = $url['host'] .':'. $url['port'];
+  }
+
+  $connection = mysqli_init();
+  @mysqli_real_connect($connection, $url['host'], $url['user'], $url['pass'], substr($url['path'], 1), $url['port'], NULL, MYSQLI_CLIENT_FOUND_ROWS);
+
+  if (mysqli_connect_errno() >= 2000 || mysqli_connect_errno() == 1045) {
+    drupal_set_message('Failure to connect to your MySQL database server. MySQL reports the following message: <em>'. mysqli_error() .'</em><ul><li>Are you sure you have the correct username and password?</li><li>Are you sure that you have typed the correct database hostname?</li><li>Are you sure that the database server is running?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', 'error');
+    return FALSE;
+  }
+  // Test selecting the database
+  if (mysqli_connect_errno() > 0) {
+    drupal_set_message('We were able to connect to the MySQL database server (which means your username and password are valid) but not able to select your database. MySQL reports the following message: <em>'. mysqli_error() .'</em><ul><li>Are you sure you have the correct database name?</li><li>Are you sure the database exists?</li><li>Are you sure the username has permission to access the database?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', 'error');
+    return FALSE;
+  }
+
+  // Test CREATE
+  $query = 'CREATE TABLE drupal_install_test (id int(1) NULL);';
+  $result = mysqli_query($connection, $query);
+  if ($error = mysqli_error()) {
+    drupal_set_message('We were unable to create a test table on your MySQL database server. MySQL reports the following message: "<em>'. $error .'</em>"<ul><li>Are you sure the configured username has the necessary MySQL permissions to create tables in the database?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', 'error');
+    return FALSE;
+  }
+  $err = FALSE;
+  $success = array('SELECT', 'CREATE');
+
+  // Test INSERT
+  $query = 'INSERT INTO drupal_install_test (id) VALUES(1);';
+  $result = mysqli_query($query);
+  if ($error = mysqli_error()) {
+    drupal_set_message('We were unable to insert a value into a test table on your MySQL database server. We tried inserting a value with the command "<code>'. $query .'</code>" and MySQL reported the following error: "<em>'. $error .'</em>".', 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'INSERT';
+  }
+
+  // Test UPDATE
+  $query = 'UPDATE drupal_install_test SET id = 2;';
+  $result = mysqli_query("$query");
+  if ($error = mysqli_error()) {
+    drupal_set_message('We were unable to update a value in a test table on your MySQL database server. We tried updating a value with the command "<code>'. $query .'</code>" and MySQL reported the following error: "<em>'. $error .'</em>".', 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'UPDATE';
+  }
+
+  // Test LOCK
+  $query = 'LOCK TABLES drupal_install_test WRITE;';
+  $result = mysqli_query($query);
+  if ($error = mysqli_error()) {
+    drupal_set_message('We were unable to lock a test table on your MySQL database server. We tried locking a table with the command "<code>'. $query .'</code>" and MySQL reported the following error: "<em>'. $error .'</em>".', 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'LOCK';
+  }
+
+  // Test UNLOCK
+  $query = 'UNLOCK TABLES;';
+  $result = mysqli_query("$query");
+  if ($error = mysqli_error()) {
+    drupal_set_message('We were unable to unlock a test table on your MySQL database server. We tried unlocking a table with the command "<code>'. $query .'</code>" and MySQL reported the following error: "<em>'. $error .'</em>".', 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'UNLOCK';
+  }
+
+  // Test DELETE
+  $query = 'DELETE FROM drupal_install_test;';
+  $result = mysqli_query("$query");
+  if ($error = mysqli_error()) {
+    drupal_set_message('We were unable to delete a value from a test table on your MySQL database server. We tried deleting a value with the command "<code>'. $query .'</code>" and MySQL reported the following error: "<em>'. $error .'</em>".', 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'DELETE';
+  }
+
+  // Test DROP
+  $query = 'DROP TABLE drupal_install_test;';
+  $result = mysqli_query("$query");
+  if ($error = mysqli_error()) {
+    drupal_set_message('We were unable to drop a test table from your MySQL database server. We tried dropping a table with the command "<code>'. $query .'</code>" and MySQL reported the following error: "<em>'. $error .'</em>".', 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'DROP';
+  }
+
+  if ($err) {
+    return FALSE;
+  }
+
+  mysqli_close($connection);
+  return TRUE;
+}
+
+?>
=== added file 'install.php'
--- /dev/null	
+++ install.php	
@@ -0,0 +1,10 @@
+<?php
+$install = TRUE;
+require_once './includes/install.inc';
+
+if (isset($_GET['installed'])) {
+  drupal_install_complete();
+}
+else {
+  drupal_install_main();
+}
=== added file 'modules/aggregator.install'
--- /dev/null	
+++ modules/aggregator.install	
@@ -0,0 +1,58 @@
+<?php
+
+function aggregator_install() {
+  switch($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query("CREATE TABLE {aggregator_category} (
+        cid int(10) NOT NULL auto_increment,
+        title varchar(255) NOT NULL default '',
+        description longtext NOT NULL,
+        block tinyint(2) NOT NULL default '0',
+        PRIMARY KEY (cid),
+        UNIQUE KEY title (title)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {aggregator_category_feed} (
+        fid int(10) NOT NULL default '0',
+        cid int(10) NOT NULL default '0',
+        PRIMARY KEY (fid,cid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {aggregator_category_item} (
+        iid int(10) NOT NULL default '0',
+        cid int(10) NOT NULL default '0',
+        PRIMARY KEY (iid,cid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {aggregator_feed} (
+        fid int(10) NOT NULL auto_increment,
+        title varchar(255) NOT NULL default '',
+        url varchar(255) NOT NULL default '',
+        refresh int(10) NOT NULL default '0',
+        checked int(10) NOT NULL default '0',
+        link varchar(255) NOT NULL default '',
+        description longtext NOT NULL,
+        image longtext NOT NULL,
+        etag varchar(255) NOT NULL default '',
+        modified int(10) NOT NULL default '0',
+        block tinyint(2) NOT NULL default '0',
+        PRIMARY KEY (fid),
+        UNIQUE KEY link (url),
+        UNIQUE KEY title (title)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {aggregator_item} (
+        iid int(10) NOT NULL auto_increment,
+        fid int(10) NOT NULL default '0',
+        title varchar(255) NOT NULL default '',
+        link varchar(255) NOT NULL default '',
+        author varchar(255) NOT NULL default '',
+        description longtext NOT NULL,
+        timestamp int(11) default NULL,
+        PRIMARY KEY (iid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      break;
+  }
+}
=== added file 'modules/book.install'
--- /dev/null	
+++ modules/book.install	
@@ -0,0 +1,17 @@
+<?php
+
+function book_install() {
+  switch($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query("CREATE TABLE {book} (
+        vid int(10) unsigned NOT NULL default '0',
+        nid int(10) unsigned NOT NULL default '0',
+        parent int(10) NOT NULL default '0',
+        weight tinyint(3) NOT NULL default '0',
+        PRIMARY KEY (vid),
+        KEY nid (nid),
+        KEY parent (parent)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+  }
+}
\ No newline at end of file
=== added file 'modules/contact.install'
--- /dev/null	
+++ modules/contact.install	
@@ -0,0 +1,18 @@
+<?php
+
+function contact_install() {
+  switch($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query("CREATE TABLE {contact} (
+        cid int(10) unsigned NOT NULL auto_increment,
+        category varchar(255) NOT NULL default '',
+        recipients longtext NOT NULL default '',
+        reply longtext NOT NULL default '',
+        weight tinyint(3) NOT NULL default '0',
+        selected tinyint(1) NOT NULL default '0',
+        PRIMARY KEY (cid),
+        UNIQUE KEY category (category)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+  }
+}
\ No newline at end of file
=== added file 'modules/drupal.install'
--- /dev/null	
+++ modules/drupal.install	
@@ -0,0 +1,29 @@
+<?php
+
+function drupal_install() {
+  switch($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query("CREATE TABLE {client} (
+        cid int(10) unsigned NOT NULL auto_increment,
+        link varchar(255) NOT NULL default '',
+        name varchar(128) NOT NULL default '',
+        mail varchar(128) NOT NULL default '',
+        slogan longtext NOT NULL,
+        mission longtext NOT NULL,
+        users int(10) NOT NULL default '0',
+        nodes int(10) NOT NULL default '0',
+        version varchar(35) NOT NULL default'',
+        created int(11) NOT NULL default '0',
+        changed int(11) NOT NULL default '0',
+        PRIMARY KEY (cid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {client_system} (
+        cid int(10) NOT NULL default '0',
+        name varchar(255) NOT NULL default '',
+        type varchar(255) NOT NULL default '',
+        PRIMARY KEY (cid,name)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+  }
+}
\ No newline at end of file
=== added file 'modules/forum.install'
--- /dev/null	
+++ modules/forum.install	
@@ -0,0 +1,16 @@
+<?php
+
+function forum_install() {
+  switch($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query("CREATE TABLE {forum} (
+        nid int(10) unsigned NOT NULL default '0',
+        vid int(10) unsigned NOT NULL default '0',
+        tid int(10) unsigned NOT NULL default '0',
+        PRIMARY KEY (vid),
+        KEY nid (nid),
+        KEY tid (tid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+  }
+}
\ No newline at end of file
=== added file 'modules/locale.install'
--- /dev/null	
+++ modules/locale.install	
@@ -0,0 +1,37 @@
+<?php
+
+function locale_install() {
+  switch($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query("CREATE TABLE {locales_meta} (
+        locale varchar(12) NOT NULL default '',
+        name varchar(64) NOT NULL default '',
+        enabled int(2) NOT NULL default '0',
+        isdefault int(2) NOT NULL default '0',
+        plurals int(1) NOT NULL default '0',
+        formula varchar(128) NOT NULL default '',
+        PRIMARY KEY (locale)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {locales_source} (
+        lid int(11) NOT NULL auto_increment,
+        location varchar(255) NOT NULL default '',
+        source blob NOT NULL,
+        PRIMARY KEY (lid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {locales_target} (
+        lid int(11) NOT NULL default '0',
+        translation blob NOT NULL,
+        locale varchar(12) NOT NULL default '',
+        plid int(11) NOT NULL default '0',
+        plural int(1) NOT NULL default '0',
+        KEY lid (lid),
+        KEY lang (locale),
+        KEY plid (plid),
+        KEY plural (plural)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+  }
+  db_query("INSERT INTO {locales_meta} (locale, name, enabled, isdefault) VALUES ('en', 'English', '1', '1')");
+}
=== added file 'modules/poll.install'
--- /dev/null	
+++ modules/poll.install	
@@ -0,0 +1,34 @@
+<?php
+
+function poll_install() {
+  switch($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query("CREATE TABLE {poll} (
+        nid int(10) unsigned NOT NULL default '0',
+        runtime int(10) NOT NULL default '0',
+        active int(2) unsigned NOT NULL default '0',
+        PRIMARY KEY (nid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {poll_votes} (
+        nid int(10) unsigned NOT NULL,
+        uid int(10) unsigned NOT NULL default 0,
+        chorder int(10) NOT NULL default -1,
+        hostname varchar(128) NOT NULL default '',
+        INDEX (nid),
+        INDEX (uid),
+        INDEX (hostname)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {poll_choices} (
+        chid int(10) unsigned NOT NULL auto_increment,
+        nid int(10) unsigned NOT NULL default '0',
+        chtext varchar(128) NOT NULL default '',
+        chvotes int(6) NOT NULL default '0',
+        chorder int(2) NOT NULL default '0',
+        PRIMARY KEY (chid),
+        KEY nid (nid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+  }
+}
=== added file 'modules/profile.install'
--- /dev/null	
+++ modules/profile.install	
@@ -0,0 +1,34 @@
+<?php
+
+function profile_install() {
+  switch($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query("CREATE TABLE {profile_fields} (
+        fid int(10) NOT NULL auto_increment,
+        title varchar(255) default NULL,
+        name varchar(128) default NULL,
+        explanation TEXT default NULL,
+        category varchar(255) default NULL,
+        page varchar(255) default NULL,
+        type varchar(128) default NULL,
+        weight tinyint(1) DEFAULT '0' NOT NULL,
+        required tinyint(1) DEFAULT '0' NOT NULL,
+        register tinyint(1) DEFAULT '0' NOT NULL,
+        visibility tinyint(1) DEFAULT '0' NOT NULL,
+        autocomplete tinyint(1) DEFAULT '0' NOT NULL,
+        options text,
+        KEY category (category),
+        UNIQUE KEY name (name),
+        PRIMARY KEY (fid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {profile_values} (
+        fid int(10) unsigned default '0',
+        uid int(10) unsigned default '0',
+        value text,
+        KEY uid (uid),
+        KEY fid (fid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+  }
+}
\ No newline at end of file
=== added file 'modules/search.install'
--- /dev/null	
+++ modules/search.install	
@@ -0,0 +1,32 @@
+<?php
+
+function search_install() {
+  switch($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query("CREATE TABLE {search_dataset} (
+        sid int(10) unsigned NOT NULL default '0',
+        type varchar(16) default NULL,
+        data longtext NOT NULL,
+        KEY sid_type (sid, type)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {search_index} (
+        word varchar(50) NOT NULL default '',
+        sid int(10) unsigned NOT NULL default '0',
+        type varchar(16) default NULL,
+        fromsid int(10) unsigned NOT NULL default '0',
+        fromtype varchar(16) default NULL,
+        score float default NULL,
+        KEY sid_type (sid, type),
+        KEY from_sid_type (fromsid, fromtype),
+        KEY word (word)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {search_total} (
+        word varchar(50) NOT NULL default '',
+        count float default NULL,
+        PRIMARY KEY (word)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+  }
+}
\ No newline at end of file
=== added file 'modules/statistics.install'
--- /dev/null	
+++ modules/statistics.install	
@@ -0,0 +1,21 @@
+<?php
+
+function statistics_install() {
+  switch($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query("CREATE TABLE {accesslog} (
+        aid int(10) NOT NULL auto_increment,
+        sid varchar(32) NOT NULL default '',
+        title varchar(255) default NULL,
+        path varchar(255) default NULL,
+        url varchar(255) default NULL,
+        hostname varchar(128) default NULL,
+        uid int(10) unsigned default '0',
+        timer int(10) unsigned NOT NULL default '0',
+        timestamp int(11) unsigned NOT NULL default '0',
+        KEY accesslog_timestamp (timestamp),
+        PRIMARY KEY (aid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+  }
+}
\ No newline at end of file
=== added file 'modules/system.install'
--- /dev/null	
+++ modules/system.install	
@@ -0,0 +1,421 @@
+<?php
+
+function system_install() {
+  switch($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query("CREATE TABLE {access} (
+        aid tinyint(10) NOT NULL auto_increment,
+        mask varchar(255) NOT NULL default '',
+        type varchar(255) NOT NULL default '',
+        status tinyint(2) NOT NULL default '0',
+        PRIMARY KEY (aid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {authmap} (
+        aid int(10) unsigned NOT NULL auto_increment,
+        uid int(10) NOT NULL default '0',
+        authname varchar(128) NOT NULL default '',
+        module varchar(128) NOT NULL default '',
+        PRIMARY KEY (aid),
+        UNIQUE KEY authname (authname)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {blocks} (
+        module varchar(64) DEFAULT '' NOT NULL,
+        delta varchar(32) NOT NULL default '0',
+        theme varchar(255) NOT NULL default '',
+        status tinyint(2) DEFAULT '0' NOT NULL,
+        weight tinyint(1) DEFAULT '0' NOT NULL,
+        region varchar(64) DEFAULT 'left' NOT NULL,
+        custom tinyint(2) DEFAULT '0' NOT NULL,
+        throttle tinyint(1) DEFAULT '0' NOT NULL,
+        visibility tinyint(1) DEFAULT '0' NOT NULL,
+        pages text DEFAULT '' NOT NULL
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {boxes} (
+        bid tinyint(4) NOT NULL auto_increment,
+        title varchar(64) NOT NULL default '',
+        body longtext,
+        info varchar(128) NOT NULL default '',
+        format int(4) NOT NULL default '0',
+        PRIMARY KEY (bid),
+        UNIQUE KEY info (info)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {cache} (
+        cid varchar(255) NOT NULL default '',
+        data longblob,
+        expire int(11) NOT NULL default '0',
+        created int(11) NOT NULL default '0',
+        headers text,
+        PRIMARY KEY (cid),
+        INDEX expire (expire)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {comments} (
+        cid int(10) NOT NULL auto_increment,
+        pid int(10) NOT NULL default '0',
+        nid int(10) NOT NULL default '0',
+        uid int(10) NOT NULL default '0',
+        subject varchar(64) NOT NULL default '',
+        comment longtext NOT NULL,
+        hostname varchar(128) NOT NULL default '',
+        timestamp int(11) NOT NULL default '0',
+        score mediumint(9) NOT NULL default '0',
+        status tinyint(3) unsigned NOT NULL default '0',
+        format int(4) NOT NULL default '0',
+        thread varchar(255) NOT NULL,
+        users longtext,
+        name varchar(60) default NULL,
+        mail varchar(64) default NULL,
+        homepage varchar(255) default NULL,
+        PRIMARY KEY (cid),
+        KEY lid (nid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {node_comment_statistics} (
+        nid int(10) unsigned NOT NULL auto_increment,
+        last_comment_timestamp int(11) NOT NULL default '0',
+        last_comment_name varchar(60) default NULL,
+        last_comment_uid int(10) NOT NULL default '0',
+        comment_count int(10) unsigned NOT NULL default '0',
+        PRIMARY KEY (nid),
+        KEY node_comment_timestamp (last_comment_timestamp)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {files} (
+        fid int(10) unsigned NOT NULL default 0,
+        nid int(10) unsigned NOT NULL default 0,
+        filename varchar(255) NOT NULL default '',
+        filepath varchar(255) NOT NULL default '',
+        filemime varchar(255) NOT NULL default '',
+        filesize int(10) unsigned NOT NULL default 0,
+        PRIMARY KEY (fid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {file_revisions} (
+        fid int(10) unsigned NOT NULL default 0,
+        vid int(10) unsigned NOT NULL default 0,
+        description varchar(255) NOT NULL default '',
+        list tinyint(1) unsigned NOT NULL default 0,
+        PRIMARY KEY (fid, vid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {filter_formats} (
+        format int(4) NOT NULL auto_increment,
+        name varchar(255) NOT NULL default '',
+        roles varchar(255) NOT NULL default '',
+        cache tinyint(2) NOT NULL default '0',
+        PRIMARY KEY (format),
+        UNIQUE KEY (name)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {filters} (
+        format int(4) NOT NULL default '0',
+        module varchar(64) NOT NULL default '',
+        delta tinyint(2) DEFAULT '0' NOT NULL,
+        weight tinyint(2) DEFAULT '0' NOT NULL,
+        INDEX (weight)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {flood} (
+        event varchar(64) NOT NULL default '',
+        hostname varchar(128) NOT NULL default '',
+        timestamp int(11) NOT NULL default '0'
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {history} (
+        uid int(10) NOT NULL default '0',
+        nid int(10) NOT NULL default '0',
+        timestamp int(11) NOT NULL default '0',
+        PRIMARY KEY (uid,nid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {menu} (
+        mid int(10) unsigned NOT NULL default '0',
+        pid int(10) unsigned NOT NULL default '0',
+        path varchar(255) NOT NULL default '',
+        title varchar(255) NOT NULL default '',
+        description varchar(255) NOT NULL default '',
+        weight tinyint(4) NOT NULL default '0',
+        type int(2) unsigned NOT NULL default '0',
+        PRIMARY KEY (mid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+
+      db_query("CREATE TABLE {node} (
+        nid int(10) unsigned NOT NULL auto_increment,
+        vid int(10) unsigned NOT NULL default '0',
+        type varchar(32) NOT NULL default '',
+        title varchar(128) NOT NULL default '',
+        uid int(10) NOT NULL default '0',
+        status int(4) NOT NULL default '1',
+        created int(11) NOT NULL default '0',
+        changed int(11) NOT NULL default '0',
+        comment int(2) NOT NULL default '0',
+        promote int(2) NOT NULL default '0',
+        moderate int(2) NOT NULL default '0',
+        sticky int(2) NOT NULL default '0',
+        PRIMARY KEY  (nid, vid),
+        UNIQUE KEY vid (vid),
+        KEY node_type (type(4)),
+        KEY node_title_type (title, type(4)),
+        KEY status (status),
+        KEY uid (uid),
+        KEY node_moderate (moderate),
+        KEY node_promote_status (promote, status),
+        KEY node_created (created),
+        KEY node_changed (changed),
+        KEY node_status_type (status, type, nid),
+        KEY nid (nid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {node_access} (
+        nid int(10) unsigned NOT NULL default '0',
+        gid int(10) unsigned NOT NULL default '0',
+        realm varchar(255) NOT NULL default '',
+        grant_view tinyint(1) unsigned NOT NULL default '0',
+        grant_update tinyint(1) unsigned NOT NULL default '0',
+        grant_delete tinyint(1) unsigned NOT NULL default '0',
+        PRIMARY KEY (nid,gid,realm)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {node_revisions} (
+        nid int(10) unsigned NOT NULL,
+        vid int(10) unsigned NOT NULL,
+        uid int(10) NOT NULL default '0',
+        title varchar(128) NOT NULL default '',
+        body longtext NOT NULL default '',
+        teaser longtext NOT NULL default '',
+        log longtext NOT NULL default '',
+        timestamp int(11) NOT NULL default '0',
+        format int(4) NOT NULL default '0',
+        PRIMARY KEY  (vid),
+        KEY nid (nid),
+        KEY uid (uid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {url_alias} (
+        pid int(10) unsigned NOT NULL auto_increment,
+        src varchar(128) NOT NULL default '',
+        dst varchar(128) NOT NULL default '',
+        PRIMARY KEY (pid),
+        UNIQUE KEY dst (dst),
+        KEY src (src)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {permission} (
+        rid int(10) unsigned NOT NULL default '0',
+        perm longtext,
+        tid int(10) unsigned NOT NULL default '0',
+        KEY rid (rid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {role} (
+        rid int(10) unsigned NOT NULL auto_increment,
+        name varchar(32) NOT NULL default '',
+        PRIMARY KEY (rid),
+        UNIQUE KEY name (name)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {blocks_roles} (
+        module varchar(64) NOT NULL,
+        delta varchar(32) NOT NULL,
+        rid int(10) unsigned NOT NULL,
+        PRIMARY KEY (module, delta, rid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {sessions} (
+        uid int(10) unsigned NOT NULL,
+        sid varchar(32) NOT NULL default '',
+        hostname varchar(128) NOT NULL default '',
+        timestamp int(11) NOT NULL default '0',
+        cache int(11) NOT NULL default '0',
+        session longtext,
+        KEY uid (uid),
+        PRIMARY KEY (sid),
+        KEY timestamp (timestamp)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {sequences} (
+        name varchar(255) NOT NULL default '',
+        id int(10) unsigned NOT NULL default '0',
+        PRIMARY KEY (name)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {node_counter} (
+        nid int(10) NOT NULL default '0',
+        totalcount bigint(20) unsigned NOT NULL default '0',
+        daycount mediumint(8) unsigned NOT NULL default '0',
+        timestamp int(11) unsigned NOT NULL default '0',
+        PRIMARY KEY (nid),
+        KEY totalcount (totalcount),
+        KEY daycount (daycount),
+        KEY timestamp (timestamp)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {system} (
+        filename varchar(255) NOT NULL default '',
+        name varchar(255) NOT NULL default '',
+        type varchar(255) NOT NULL default '',
+        description varchar(255) NOT NULL default '',
+        status int(2) NOT NULL default '0',
+        throttle tinyint(1) DEFAULT '0' NOT NULL,
+        bootstrap int(2) NOT NULL default '0',
+        schema_version smallint(3) NOT NULL default -1,
+        weight int(2) NOT NULL default '0',
+        PRIMARY KEY (filename),
+        KEY (weight)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {term_data} (
+        tid int(10) unsigned NOT NULL auto_increment,
+        vid int(10) unsigned NOT NULL default '0',
+        name varchar(255) NOT NULL default '',
+        description longtext,
+        weight tinyint(4) NOT NULL default '0',
+        PRIMARY KEY (tid),
+        KEY vid (vid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {term_hierarchy} (
+        tid int(10) unsigned NOT NULL default '0',
+        parent int(10) unsigned NOT NULL default '0',
+        KEY tid (tid),
+        KEY parent (parent),
+        PRIMARY KEY (tid, parent)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {term_node} (
+        nid int(10) unsigned NOT NULL default '0',
+        tid int(10) unsigned NOT NULL default '0',
+        KEY nid (nid),
+        KEY tid (tid),
+        PRIMARY KEY (tid,nid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {term_relation} (
+        tid1 int(10) unsigned NOT NULL default '0',
+        tid2 int(10) unsigned NOT NULL default '0',
+        KEY tid1 (tid1),
+        KEY tid2 (tid2)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {term_synonym} (
+        tid int(10) unsigned NOT NULL default '0',
+        name varchar(255) NOT NULL default '',
+        KEY tid (tid),
+        KEY name (name(3))
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {users} (
+        uid int(10) unsigned NOT NULL default '0',
+        name varchar(60) NOT NULL default '',
+        pass varchar(32) NOT NULL default '',
+        mail varchar(64) default '',
+        mode tinyint(1) NOT NULL default '0',
+        sort tinyint(1) default '0',
+        threshold tinyint(1) default '0',
+        theme varchar(255) NOT NULL default '',
+        signature varchar(255) NOT NULL default '',
+        created int(11) NOT NULL default '0',
+        access int(11) NOT NULL default '0',
+        login int(11) NOT NULL default '0',
+        status tinyint(4) NOT NULL default '0',
+        timezone varchar(8) default NULL,
+        language varchar(12) NOT NULL default '',
+        picture varchar(255) NOT NULL DEFAULT '',
+        init varchar(64) default '',
+        data longtext,
+        PRIMARY KEY (uid),
+        UNIQUE KEY name (name),
+        KEY access (access)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {users_roles} (
+        uid int(10) unsigned NOT NULL default '0',
+        rid int(10) unsigned NOT NULL default '0',
+        PRIMARY KEY (uid, rid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {variable} (
+        name varchar(48) NOT NULL default '',
+        value longtext NOT NULL,
+        PRIMARY KEY (name)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {vocabulary} (
+        vid int(10) unsigned NOT NULL auto_increment,
+        name varchar(255) NOT NULL default '',
+        description longtext,
+        help varchar(255) NOT NULL default '',
+        relations tinyint(3) unsigned NOT NULL default '0',
+        hierarchy tinyint(3) unsigned NOT NULL default '0',
+        multiple tinyint(3) unsigned NOT NULL default '0',
+        required tinyint(3) unsigned NOT NULL default '0',
+        tags tinyint(3) unsigned NOT NULL default '0',
+        module varchar(255) NOT NULL default '',
+        weight tinyint(4) NOT NULL default '0',
+        PRIMARY KEY (vid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {vocabulary_node_types} (
+        vid int(10) unsigned NOT NULL DEFAULT '0',
+        type varchar(32) NOT NULL DEFAULT '',
+        PRIMARY KEY (vid, type)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      db_query("CREATE TABLE {watchdog} (
+        wid int(5) NOT NULL auto_increment,
+        uid int(10) NOT NULL default '0',
+        type varchar(16) NOT NULL default '',
+        message longtext NOT NULL,
+        severity tinyint(3) unsigned NOT NULL default '0',
+        link varchar(255) NOT NULL default '',
+        location varchar(128) NOT NULL default '',
+        referer varchar(128) NOT NULL default '',
+        hostname varchar(128) NOT NULL default '',
+        timestamp int(11) NOT NULL default '0',
+        PRIMARY KEY (wid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+
+      break;
+    case 'pgsql':
+      break;
+
+  }
+  db_query("INSERT INTO {system} (filename, name, type, description, status, throttle, bootstrap, schema_version) VALUES ('themes/engines/phptemplate/phptemplate.engine', 'phptemplate', 'theme_engine', '', 1, 0, 0, 0)");
+  db_query("INSERT INTO {system} (filename, name, type, description, status, throttle, bootstrap, schema_version) VALUES ('themes/bluemarine/page.tpl.php', 'bluemarine', 'theme', 'themes/engines/phptemplate/phptemplate.engine', 1, 0, 0, 0)");
+
+  db_query("INSERT INTO {users} (uid,name,mail) VALUES(0,'','')");
+
+  db_query("INSERT INTO {role} (name) VALUES ('anonymous user')");
+  db_query("INSERT INTO {role} (name) VALUES ('authenticated user')");
+
+  db_query("INSERT INTO {permission} VALUES (1,'access content',0)");
+  db_query("INSERT INTO {permission} VALUES (2,'access comments, access content, post comments, post comments without approval',0)");
+
+  db_query("INSERT INTO {variable} (name,value) VALUES('theme_default', 's:10:\"bluemarine\";')");
+
+  db_query("INSERT INTO {blocks} (module,delta,theme,status) VALUES('user', 0, 'bluemarine', 1)");
+  db_query("INSERT INTO {blocks} (module,delta,theme,status) VALUES('user', 1, 'bluemarine', 1)");
+
+  db_query("INSERT INTO {node_access} VALUES (0, 0, 'all', 1, 0, 0)");
+
+  db_query("INSERT INTO {filter_formats} (name, roles, cache) VALUES ('Filtered HTML',',1,2,',1)");
+  db_query("INSERT INTO {filter_formats} (name, roles, cache) VALUES ('PHP code','',0)");
+  db_query("INSERT INTO {filter_formats} (name, roles, cache) VALUES ('Full HTML','',1)");
+  db_query("INSERT INTO {filters} VALUES (1,'filter',0,0)");
+  db_query("INSERT INTO {filters} VALUES (1,'filter',2,1)");
+  db_query("INSERT INTO {filters} VALUES (2,'filter',1,0)");
+  db_query("INSERT INTO {filters} VALUES (3,'filter',2,0)");
+  db_query("INSERT INTO {variable} (name,value) VALUES ('filter_html_1','i:1;')");
+
+  db_query("INSERT INTO {variable} (name, value) VALUES ('node_options_forum', 'a:1:{i:0;s:6:\"status\";}')");
+
+  db_query("INSERT INTO {menu} (pid, path, title, description, weight, type) VALUES (0, '', 'Primary links', '', 0, 115)");
+  db_query("INSERT INTO {variable} VALUES ('menu_primary_menu', 'i:2;')");
+  db_query("INSERT INTO {variable} VALUES ('menu_secondary_menu', 'i:2;')");
+}
=== added directory 'profiles'
=== added file 'profiles/default.profile'
--- /dev/null	
+++ profiles/default.profile	
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * The modules that are enabled when this profile is installed.
+ *
+ * @return
+ *  An array of modules to be enabled.
+ */
+function default_profile_modules() {
+  return array('block', 'comment', 'filter', 'help', 'menu', 'node', 'page', 'story', 'system', 'taxonomy', 'user', 'watchdog');
+}
+
+/**
+ * A description of the profile.
+ */
+function default_profile_details() {
+  return array(
+           'name' => 'Drupal',
+           'description' => 'Select this profile to enable some basic Drupal functionality and the default theme.');
+}
+
+function default_profile_final_link() {
+  return l(t('Your new website'), '');
+}
\ No newline at end of file
=== modified file 'includes/bootstrap.inc'
--- includes/bootstrap.inc	
+++ includes/bootstrap.inc	
@@ -151,9 +151,9 @@ function drupal_unset_globals() {
  * Loads the configuration and sets the base URL correctly.
  */
 function conf_init() {
-  global $db_url, $db_prefix, $base_url, $base_path, $base_root, $conf;
+  global $db_url, $db_prefix, $base_url, $base_path, $base_root, $conf, $installed_profile;
   $conf = array();
-  require_once './'. conf_path() .'/settings.php';
+  include_once './'. conf_path() .'/settings.php';
 
   if (isset($base_url)) {
     // Parse fixed base URL from settings.php.
=== modified file 'includes/install.inc'
--- includes/install.inc	
+++ includes/install.inc	
@@ -4,15 +4,33 @@
 define('SCHEMA_UNINSTALLED', -1);
 define('SCHEMA_INSTALLED', 0);
 
+define('DRUPAL_MINIMUM_PHP',    '4.3.3');
+define('DRUPAL_MINIMUM_MEMORY', '8M');
+define('DRUPAL_MINIMUM_MYSQL',  '3.23.17'); // If using MySQL
+define('DRUPAL_MINIMUM_PGSQL',  '7.3');  // If using PostgreSQL
+define('DRUPAL_MINIMUM_APACHE', '1.3');  // If using Apache
 
-// The system module (Drupal core) is currently a special case
-include_once './database/updates.inc';
+define('FILE_EXIST',          1);
+define('FILE_READABLE',       2);
+define('FILE_WRITABLE',       4);
+define('FILE_WRITEABLE',      4);
+define('FILE_EXECUTABLE',     8);
+define('FILE_NOT_EXIST',      16);
+define('FILE_NOT_READABLE',   32);
+define('FILE_NOT_WRITABLE',   64);
+define('FILE_NOT_WRITEABLE',  64);
+define('FILE_NOT_EXECUTABLE', 128);
 
-// Include install files for each module
-foreach (module_list() as $module) {
-  $install_file = './'. drupal_get_path('module', $module) .'/'. $module .'.install';
-  if (is_file($install_file)) {
-    include_once $install_file;
+if (!$install) {
+  // The system module (Drupal core) is currently a special case
+  include_once './database/updates.inc';
+
+  // Include install files for each module
+  foreach (module_list() as $module) {
+    $install_file = './'. drupal_get_path('module', $module) .'/'. $module .'.install';
+    if (is_file($install_file)) {
+      include_once $install_file;
+    }
   }
 }
 
@@ -79,3 +97,782 @@ function drupal_get_installed_schema_ver
 function drupal_set_installed_schema_version($module, $version) {
   db_query("UPDATE {system} SET schema_version = %d WHERE name = '%s'", $version, $module);
 }
+
+/**
+ * The Drupal installation happens in a series of steps. We begin by verifying
+ * that the current environment meets our minimum requirements. We then go
+ * on to verify that settings.php is properly configured. From there we
+ * connect to the configured database and verify that it meets our minimum
+ * requirements. Finally we can allow the user to select an installation
+ * profile and complete the installation process.
+ *
+ * @param $phase
+ *  The installation phase we should proceed to.
+ */
+function drupal_install_main() {
+  global $profile;
+  require_once './includes/bootstrap.inc';
+  drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
+  require_once './modules/system.install';
+  if (!isset($GLOBALS['installed_profile'])) {
+    // Decide which profile to use
+    if (!empty($_GET['profile'])) {
+      $profile = preg_replace('/[^a-zA-Z_0-9]/', '', $_GET['profile']);
+    }
+    elseif ($profile = drupal_select_profile()) {
+      _install_goto("install.php?profile=$profile");
+    }
+    else {
+      _install_no_profile_error();
+    }
+
+    // Load the profile
+    require_once "./profiles/$profile.profile";
+
+    // Configure database settings.
+    install_verify_settings();
+
+    // Establish a connection to the database.
+    require_once './includes/database.inc';
+    db_set_active();
+    
+    // Perform actual installation defined in the profile.
+    drupal_install_profile($profile);
+    $settings_file = './'. conf_path() .'/settings.php';
+
+    if (!drupal_verify_install_file($settings_file, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITEABLE)) {
+      drupal_set_message(st('All necessary changes to %file have been made, so you should now remove write permissions to this file. Failure to remove write permissions to this file is a security risk.', array('%file' => $settings_file)), 'error');
+    }
+  }
+  // Show end page
+  drupal_install_complete();
+}
+
+/**
+ * Send the user to a different installer page. This issues an on-site HTTP
+ * redirect. Messages (and errors) are erased.
+ *
+ * @param $path
+ *   An installer path.
+ */
+function _install_goto($path) {
+  global $base_path;
+  header('Location: '. $base_path . $path);
+  exit();
+}
+
+/**
+ * Loads the profile definition, extracting the profile's defined name.
+ *
+ * @return
+ *  The name defined in the profile's _profile_details() hook.
+ */
+function _install_profile_name() {
+  global $profile;
+  static $name = NULL;
+
+  if (!isset($name)) {
+    // Load profile details
+    $function = $profile .'_profile_details';
+    if (function_exists($function)) {
+      $details = $function();
+    }
+    $name = isset($details['name']) ? $details['name'] : 'Drupal';
+  }
+
+  return $name;
+}
+
+/**
+ * Auto detect the base_url with PHP predefined variables.
+ *
+ * @param $file
+ *  The name of the file calling this function so we can strip it out of
+ *  the URI when generating the base_url.
+ *
+ * @return
+ *  The auto-detected $base_url that should be configured in settings.php
+ */
+function drupal_detect_baseurl($file = 'install.php') {
+  global $profile;
+  $proto = $_SERVER['HTTPS'] ? 'https://' : 'http://';
+  $host = $_SERVER['SERVER_NAME'];
+  $port = ($_SERVER['SERVER_PORT'] == 80 ? '' : ':'. $_SERVER['SERVER_PORT']);
+  $uri = str_replace("?profile=$profile", '', $_SERVER['REQUEST_URI']);
+  $dir = str_replace("/$file", '', $uri);
+
+  return "$proto$host$port$dir";
+}
+
+/**
+ * Detect all databases supported by Drupal that are compiled into the current
+ * PHP installation.
+ *
+ * @return
+ *  An array of database types compiled into PHP.
+ */
+function drupal_detect_database_types() {
+  $databases = array();
+
+  foreach (array('mysql', 'mysqli', 'pgsql') as $type) {
+    if (file_exists('./includes/install.'. $type .'.inc')) {
+      include_once './includes/install.'. $type .'.inc';
+      $function = $type .'_is_available';
+      if ($function()) {
+        $databases[$type] = $type;
+      }
+    }
+  }
+
+  return $databases;
+}
+
+/**
+ * Read settings.php into a buffer line by line, changing values specified in
+ * $settings array, then over-writing the old settings.php file.
+ *
+ * @param $settings
+ *  An array of settings that need to be updated.
+ */
+function drupal_rewrite_settings($settings = array(), $prefix = '') {
+  $settings_file = './'. conf_path() .'/'. $prefix .'settings.php';
+
+  // Build list of setting names and insert the values into the global namespace
+  $keys = array();
+  foreach ($settings as $setting => $data) {
+    $GLOBALS[$setting] = $data['value'];
+    $keys[] = $setting;
+  }
+
+  $buffer = NULL;
+  $first = TRUE;
+  if ($fp = @fopen($settings_file, 'r+')) {
+    // Step line by line through settings.php
+    while (!feof($fp)) {
+      $line = fgets($fp);
+      if ($first && substr($line, 0, 5) != '<?php') {
+        $buffer = "<?php\n\n";
+      }
+      $first = FALSE;
+      // Check for constants
+      if (substr($line, 0, 7) == 'define(') {
+        preg_match('/define\(\s*[\'"]([A-Z_-]+)[\'"]\s*,(.*?)\);/', $line, $variable);
+        if (in_array($variable[1], $keys)) {
+          $setting = $settings[$variable[1]];
+          $buffer .= str_replace($variable[2], " '". $setting['value'] ."'", $line);
+          unset($settings[$variable[1]]);
+          unset($settings[$variable[2]]);
+        }
+        else {
+          $buffer .= $line;
+        }
+      }
+      // Check for variables
+      elseif (substr($line, 0, 1) == '$') {
+        preg_match('/\$([^ ]*) /', $line, $variable);
+        if (in_array($variable[1], $keys)) {
+          // Write new value to settings.php in the following format:
+          //    $'setting' = 'value'; // 'comment'
+          $setting = $settings[$variable[1]];
+          $buffer .= '$'. $variable[1] ." = '". $setting['value'] ."';". ($setting['comment'] ? ' // '. $setting['comment'] ."\n" : "\n");
+          unset($settings[$variable[1]]);
+        }
+        else {
+          $buffer .= $line;
+        }
+      }
+      else {
+        $buffer .= $line;
+      }
+    }
+    fclose($fp);
+
+    // Add required settings that were missing from settings.php
+    foreach ($settings as $setting => $data) {
+      if ($data['required']) {
+        $buffer .= "\$$setting = '". $data['value'] ."';\n";
+      }
+    }
+
+    $fp = fopen($settings_file, 'w');
+    if ($fp && fwrite($fp, $buffer) === FALSE) {
+        drupal_set_message(st('Failed to modify %settings, please verify the file permissions.', array('%settings' => $settings_file)), 'error');
+    }
+  }
+  else {
+    drupal_set_message(st('Failed to open %settings, please verify the file permissions.', array('%settings' => $settings_file)), 'error');
+  }
+}
+ 
+/**
+ * Verify settings.php, rewriting if necessary.
+ */
+function install_verify_settings() {
+  global $profile, $db_url, $db_type, $db_prefix, $conf;
+  $settings_file = './'. conf_path() .'/settings.php';
+  include $settings_file;
+
+  $url = parse_url($db_url);
+  $db_user = urldecode($url['user']);
+  $db_pass = urldecode($url['pass']);
+  $db_host = urldecode($url['host']);
+  $db_path = ltrim(urldecode($url['path']), '/');
+  // We always need this because we want to run form_get_errors
+  include_once './includes/form.inc';
+
+  // Initialize module subsystem
+  $conf['module_list']['system']['filename'] = 'modules/system.module';
+  $conf['module_list']['filter']['filename'] = 'modules/filter.module';
+  include_once('./includes/module.inc');
+  module_load_all();
+
+  // Verify filesystem permissions for settings.php
+  if (!drupal_verify_install_file($settings_file, FILE_EXIST|FILE_READABLE|FILE_WRITEABLE)) {
+    drupal_maintenance_theme();
+    drupal_set_message(st('The Drupal installer requires write permissions to %file during the installation process.', array('%file' => $settings_file)), 'error');
+
+    drupal_set_title('Drupal Installation');
+    print theme('install_page', '');
+    exit;
+  }  
+
+  // Verify existing settings (if any)
+  if ($_SERVER['REQUEST_METHOD'] == 'GET' && $db_url != 'mysql://username:password@localhost/databasename') {
+    _drupal_install_settings_validate($db_prefix, $db_type, $db_user, $db_pass, $db_host, $db_path, $settings_file);
+    if (!form_get_errors()) {
+      return;
+    }
+  }
+
+  // Database type
+  $form['db_type'] = array(
+    '#type' => 'select',
+    '#title' => 'Database type',
+    '#required' => TRUE,
+    '#options' => drupal_detect_database_types(),
+    '#default_value' => $db_type,
+    '#description' => st('Select the type of database you would like to use with your %drupal installation. If you do not find your preferred database type listed here, verify that the database type is <a href="http://drupal.org/node/270#database">supported by Drupal</a> then confirm that it is properly installed and accessible from PHP. Only properly installed databases that are accessible from PHP and recognized by %drupal are displayed in this menu.', array('%drupal' => _install_profile_name())),
+  );
+  // Database username
+  $form['db_user'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Database username',
+    '#default_value' => $db_user,
+    '#size' => 45,
+    '#maxlength' => 45,
+    '#required' => TRUE,
+    '#description' => st('The database username that your %drupal installation will use to connect to your database server.', array('%drupal' => _install_profile_name())),
+  );
+
+  // Database username
+  $form['db_pass'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Database password',
+    '#default_value' => $db_pass,
+    '#size' => 45,
+    '#maxlength' => 45,
+    '#required' => TRUE,
+    '#description' => st('The database username that your %drupal installation will use to connect to your database server.', array('%drupal' => _install_profile_name())),
+  );
+
+  // Database name
+  $form['db_path'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Database name',
+    '#default_value' => $db_path,
+    '#size' => 45,
+    '#maxlength' => 45,
+    '#required' => TRUE,
+    '#description' => st('The name of the database where %drupal can install its database tables.', array('%drupal' => _install_profile_name())),
+  );
+
+  // Database host
+  $form['db_host'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Database host',
+    '#default_value' => $db_host,
+    '#size' => 45,
+    '#maxlength' => 45,
+    '#required' => TRUE,
+    '#description' => st('The hostname or IP address of your database server. If your database server is on the same machine as you are installing %drupal, you should probably enter "localhost".', array('%drupal' => _install_profile_name())),
+  );
+
+  // Database prefix
+  $form['db_prefix'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Database prefix',
+    '#default_value' => $db_prefix,
+    '#size' => 45,
+    '#maxlength' => 45,
+    '#required' => FALSE,
+    '#description' => 'Optionally set a prefix for all database table names. If a prefix is specified, all table names will be prepended with this value. Only alphanumeric characters and the underscore are allowed. If you do not wish to use a prefix, leave this field empty. If you wish to only prefix specific tables, you will need to manually edit your <code>settings.php</code> configuration file.',
+  );
+
+  $form['save'] = array(
+    '#type' => 'submit',
+    '#value' => 'Save configuration',
+  );
+  $form['errors'] = array();
+  $form['settings_file'] = array('#type' => 'value', '#value' => $settings_file);
+  $form['_db_url'] = array('#type' => 'value');
+  $form['#action'] = "install.php?profile=$profile";
+  $form['#redirect'] = NULL;
+  drupal_maintenance_theme();
+  $output = drupal_get_form('drupal_install_settings', $form);
+  drupal_set_title('Database configuration');
+  print theme('install_page', st('<p>Please fill out the following information to configure your %drupal site.</p>', array('%drupal' => _install_profile_name())). $output);
+  exit;
+}
+
+/**
+ * Hardcoded function for doing the equivalent of theme('placeholder')
+ * when the theme system is not available.
+ */
+function st($string, $args = array()) {
+  require_once './includes/theme.inc';
+  return strtr($string, array_map('theme_placeholder', $args));
+}
+
+/**
+ * Form API validate for drupal_install_settings form.
+ */
+function drupal_install_settings_validate($form_id, $form_values, $form) {
+  global $db_url;
+  _drupal_install_settings_validate($form_values['db_prefix'], $form_values['db_type'], $form_values['db_user'], $form_values['db_pass'], $form_values['db_host'], $form_values['db_path'], $form_values['settings_file'], $form);
+}
+
+/**
+ * Helper function for drupal_install_settings_validate.
+ */
+function _drupal_install_settings_validate($db_prefix, $db_type, $db_user, $db_pass, $db_host, $db_path, $settings_file, $form = NULL) {
+  global $db_url;
+  
+  // Check for default username/password
+  if ($db_user == 'username' && $db_pass == 'password') {
+    form_set_error('db_user', st('You have configured %drupal to use the default username and password. This is not allowed for security reasons.', array('%drupal' => _install_profile_name())));
+  }
+
+  // Verify database prefix
+  if (!empty($db_prefix) && preg_match('/[^A-Za-z0-9_]/', $db_prefix)) {
+    form_set_error('db_prefix', st('The database prefix you have entered, %db_prefix, is invalid. The database prefix can only contain alphanumeric characters and underscores.', array('%db_prefix' => $db_prefix)), 'error');
+  }
+
+  // Check database type
+  if (!isset($form)) {
+    $db_type = substr($db_url, 0, strpos($db_url, '://'));
+  }
+  $databases = drupal_detect_database_types();
+  if (!in_array($db_type, $databases)) {
+    form_set_error('db_type', st("In your %settings_file file you have configured Drupal to use a %db_type server, however your PHP installation currently does not support this database type.", array('%settings_file' => $settings_file, '%db_type' => $db_type)));
+  }
+  else {
+    // Verify 
+    $db_url = $db_type .'://'. $db_user .($db_pass ? ':'. $db_pass : '') .'@'. ($db_host ? $db_host : 'localhost') .'/'. $db_path;
+    if (isset($form)) {
+      form_set_value($form['_db_url'], $db_url);
+    }
+    $success = array();
+    
+    $function = 'drupal_test_'. $db_type;
+    if (!$function($db_url, $success)) {
+      form_set_error('db_type', st('In order for Drupal to work and to proceed with the installation process you must resolve all permission issues reported above. We were able to verify that we have permission for the following commands: %commands. For more help with configuring your database server, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what any of this means you should probably contact your hosting provider.', array('%commands' => implode($success, ', '))));
+    }
+  }
+}
+
+/**
+ * Form API submit for drupal_install_settings form.
+ */
+function drupal_install_settings_submit($form_id, $form_values) {
+  global $profile;
+
+  // Update global settings array and save
+  $settings['db_url'] = array(
+    'value'    => $form_values['_db_url'],
+    'required' => TRUE,
+  );
+  $settings['db_prefix'] = array(
+    'value'    => $form_values['db_prefix'],
+    'required' => TRUE,
+  );
+  drupal_rewrite_settings($settings);
+
+  // Continue to install profile step
+  _install_goto("install.php?profile=$profile");
+}
+
+/**
+ * Find all .profile files and allow admin to select which to install.
+ *
+ * @return
+ *  The selected profile.
+ */
+function drupal_select_profile() {
+  include_once './includes/file.inc';
+  include_once './includes/form.inc';
+
+  $profiles = file_scan_directory('./profiles', '\.profile$', array('.', '..', 'CVS'), 0, TRUE, 'name', 0);
+  // Don't need to choose profile if only one available
+  if (sizeof($profiles) == 1) {
+    $profile = array_pop($profiles);
+    require_once $profile->filename;
+    return $profile->name;
+  }
+  elseif (sizeof($profiles) > 1) {
+    drupal_maintenance_theme();
+    $form = '';
+    foreach ($profiles as $profile) {
+      include_once($profile->filename);
+      if ($_POST['profile'] == "$profile->name") {
+        return "$profile->name";
+      }
+      // Load profile details
+      $function = $profile->name .'_profile_details';
+      if (function_exists($function)) {
+        $details = $function();
+      }
+
+      // If set, used defined name. Otherwise use file name.
+      $name = isset($details['name']) ? $details['name'] : $profile->name;
+
+      // Build a quick form. We can't use the core forms api because we
+      // aren't able to bootstrap Drupal yet.
+      $element = array(
+        '#type' => 'radio',
+        '#name' => 'profile',
+        '#value' => 'default',
+        '#return_value' => "$profile->name",
+        '#title' => "$name",
+        '#description' => $details['description'],
+        '#parents' => array()
+      );
+      $group = theme('radio', $element);
+
+      $element = array(
+        '#value' => $group,
+      );
+      $form .= theme('fieldset', $element);
+
+    }
+    $element = array(
+      '#type' => 'submit',
+      '#name' => 'save',
+      '#value' => 'Save configuration',
+    );
+    $form .= theme('submit', $element);
+
+    drupal_set_title('Select an installation profile');
+    print theme('install_page', '<form action="install.php" method="post">'. $form .'</form>');
+    exit;
+  }
+  else {
+    return NULL;
+  }
+}
+
+/**
+ * Get list of all .install files.
+ *
+ * @param $module_list
+ *  An array of modules to search for their .install files.
+ */
+function drupal_get_install_files($module_list = array()) {
+  $installs = array();
+  foreach ($module_list as $module) {
+    $installs = array_merge($installs, file_scan_directory('./modules', "^$module.install$", array('.', '..', 'CVS'), 0, TRUE, 'name', 0));
+  }
+  return $installs;
+}
+
+/**
+ * An error page to display when there are no profiles available.
+ */
+function _install_no_profile_error() {
+  drupal_maintenance_theme();
+  drupal_set_title('No profiles available');
+  print theme('install_page', '<p>We were unable to find any installer profiles. Installer profiles tell us what modules to enable and what schema to install in the database. A profile is necessary to continue with the installation process.</p>');
+  exit;
+}
+
+/**
+ * Installed profile.
+ *
+ * @param profile
+ *  Name of profile to install.
+ */
+function drupal_install_profile($profile) {
+  global $db_type;
+
+  include_once './includes/file.inc';
+
+  $profile_file = "./profiles/$profile.profile";
+
+  if (!isset($profile) || !file_exists($profile_file)) {
+    _install_no_profile_error();
+  }
+
+  require_once($profile_file);
+
+  // Get a list of modules required by this profile
+  $function = $profile .'_profile_modules';
+  $module_list = $function();
+
+  // Verify that all required modules exist
+  $modules = array();
+  foreach ($module_list as $current) {
+    $module = file_scan_directory('./modules', "^$current.module$", array('.', '..', 'CVS'), 0, TRUE, 'name', 0);
+    if (empty($module)) {
+      drupal_set_message(st('The %module module is required but was not found. Please move the file %file into the <em>modules</em> subdirectory.', array('%module' => $current, '%file' => $current .'.module')), 'error');
+    }
+    else {
+      $modules = array_merge($modules, $module);
+    }
+  }
+
+  // Get a list of all .install files
+  $installs = drupal_get_install_files($module_list);
+
+  // Install schemas for profile and all its modules
+  $function = $profile .'_install';
+  if (function_exists($function)) {
+    $function();
+  }
+
+  foreach ($installs as $install) {
+    require_once $install->filename;
+    module_invoke($install->name, 'install');
+  }
+
+  // Enable the modules required by the profile
+  db_query("DELETE FROM {system} WHERE type = 'module'");
+  foreach ($modules as $module) {
+    db_query("INSERT INTO {system} (filename, name, type, description, status, throttle, bootstrap, schema_version) VALUES('%s', '%s', 'module', '', 1, 0, 0, 0)", $module->filename, $module->name);
+  }
+
+  // Update settings.php to show that the installer has already been run
+  $settings = array();
+  $settings['installed_profile'] = array(
+    'value'    => $profile,
+    'required' => TRUE
+  );
+  drupal_rewrite_settings($settings);
+}
+
+/**
+ * Page displayed when the installation is complete. Called from install.php.
+ */
+function drupal_install_complete() {
+  global $base_url, $installed_profile;
+
+  // Bootstrap newly installed Drupal, while preserving existing messages.
+  $messages = $_SESSION['messages'];
+  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
+  $_SESSION['messages'] = $messages;
+
+  // Build final page
+  drupal_maintenance_theme();
+  drupal_set_title(st('%drupal installation complete', array('%drupal' => _install_profile_name())));
+  $output = st('<p>Congratulations, %drupal has been successfully installed.</p>', array('%drupal' => _install_profile_name()));
+
+  // Load profile finalization steps
+  require_once "./profiles/$installed_profile.profile";
+  $function = $installed_profile .'_profile_final';
+  if (function_exists($function)) {
+    // More steps required
+    $output .= $function();
+  }
+  else {
+    // No more steps
+    $msg = drupal_set_message() ? 'Please review the messages above before continuing on to <a href="%url">your new site</a>.' : 'You may now visit <a href="%url">your new site</a>';
+    $output .= strtr('<p>'. $msg .'</p>', array('%url' => url('')));
+  }
+
+  // Output page
+  print theme('maintenance_page', $output);
+}
+
+/**
+ * Verify the state of the specified file.
+ *
+ * @param $file
+ *   The file to check for.
+ * @param $mask
+ *   An optional bitmask created from various FILE_* constants.
+ * @param $message_type
+ *   The type of message to create, can be error or status. Passed on to drupal_set_message as second parameter.
+ *   Set to NULL to not output any messages at all.
+ * @param $type
+ *   The type of file. Can be file (default), dir, or link.
+ * @return
+ *   TRUE on success or FALSE on failure. A messsage is set for the latter.
+ */
+function drupal_verify_install_file($file, $mask = NULL, $type = 'file') {
+  $return = TRUE;
+  // Check for files that shouldn't be there
+  if (isset($mask) && ($mask & FILE_NOT_EXIST) && file_exists($file)) {
+    return FALSE;
+  }
+  // Verify that the file is the type of file it is supposed to be
+  if (isset($type) && file_exists($file)) {
+    $check = 'is_'. $type;
+    if (!function_exists($check) || !$check($file)) {
+      $return = FALSE;
+    }
+  }
+
+  // Verify file permissions
+  if (isset($mask)) {
+    $masks = array(FILE_EXIST, FILE_READABLE, FILE_WRITABLE, FILE_EXECUTABLE, FILE_NOT_READABLE, FILE_NOT_WRITABLE, FILE_NOT_EXECUTABLE);
+    foreach ($masks as $current_mask) {
+      if ($mask & $current_mask) {
+        switch ($current_mask) {
+          case FILE_EXIST:
+            if (!file_exists($file)) {
+              if ($type == 'dir') {
+                drupal_install_mkdir($file, $mask);
+              }
+              if (!file_exists($file)) {
+                $return = FALSE;
+              }
+            }
+            break;
+          case FILE_READABLE:
+            if (!is_readable($file) && !drupal_install_fix_file($file, $mask)) {
+              $return = FALSE;
+            }
+            break;
+          case FILE_WRITABLE:
+            if (!is_writable($file) && !drupal_install_fix_file($file, $mask)) {
+              $return = FALSE;
+            }
+            break;
+          case FILE_EXECUTABLE:
+            if (!is_executable($file) && !drupal_install_fix_file($file, $mask)) {
+              $return = FALSE;
+            }
+            break;
+          case FILE_NOT_READABLE:
+            if (is_readable($file) && !drupal_install_fix_file($file, $mask)) {
+              $return = FALSE;
+            }
+            break;
+          case FILE_NOT_WRITABLE:
+            if (is_writable($file) && !drupal_install_fix_file($file, $mask)) {
+              $return = FALSE;
+            }
+            break;
+          case FILE_NOT_EXECUTABLE:
+            if (is_executable($file) && !drupal_install_fix_file($file, $mask)) {
+              $return = FALSE;
+            }
+            break;
+        }
+      }
+    }
+  }
+  return $return;
+}
+
+/**
+ * Create a directory with specified permissions.
+ *
+ * @param file
+ *  The name of the directory to create;
+ * @param mask
+ *  The permissions of the directory to create.
+ * @param $message
+ *  (optional) Whether to output messages. Defaults to TRUE.
+ *
+ * @return
+ *  TRUE/FALSE whether or not the directory was successfully created.
+ */
+function drupal_install_mkdir($file, $mask, $message = TRUE) {
+  $mod = 0;
+  $masks = array(FILE_READABLE, FILE_WRITABLE, FILE_EXECUTABLE, FILE_NOT_READABLE, FILE_NOT_WRITABLE, FILE_NOT_EXECUTABLE);
+  foreach ($masks as $m) {
+    if ($mask & $m) {
+      switch ($m) {
+        case FILE_READABLE:
+          $mod += 444;
+          break;
+        case FILE_WRITABLE:
+          $mod += 222;
+          break;
+        case FILE_EXECUTABLE:
+          $mod += 111;
+          break;
+      }
+    }
+  }
+
+  if (@mkdir($file, intval("0$mod", 8))) {
+    return TRUE;
+  }
+  else {
+    return FALSE;
+  }
+}
+
+/**
+ * Attempt to fix file permissions.
+ *
+ * @param $file
+ *  The name of the file with permissions to fix.
+ * @param $mask
+ *  The desired permissions for the file.
+ * @param $message
+ *  (optional) Whether to output messages. Defaults to TRUE.
+ *
+ * @return
+ *  TRUE/FALSE whether or not we were able to fix the file's permissions.
+ */
+function drupal_install_fix_file($file, $mask, $message = TRUE) {
+  $mod = substr(sprintf('%o', fileperms($file)), -4);
+  $prefix = substr($mod, 0, 1);
+  $mod = substr($mod, 1 ,4);
+  $masks = array(FILE_READABLE, FILE_WRITABLE, FILE_EXECUTABLE, FILE_NOT_READABLE, FILE_NOT_WRITABLE, FILE_NOT_EXECUTABLE);
+  foreach ($masks as $m) {
+    if ($mask & $m) {
+      switch ($m) {
+        case FILE_READABLE:
+          if (!is_readable($file)) {
+            $mod += 444;
+          }
+          break;
+        case FILE_WRITABLE:
+          if (!is_writable($file)) {
+            $mod += 222;
+          }
+          break;
+        case FILE_EXECUTABLE:
+          if (!is_executable($file)) {
+            $mod += 111;
+          }
+          break;
+        case FILE_NOT_READABLE:
+          if (is_readable($file)) {
+            $mod -= 444;
+          }
+          break;
+        case FILE_NOT_WRITABLE:
+          if (is_writable($file)) {
+            $mod -= 222;
+          }
+          break;
+        case FILE_NOT_EXECUTABLE:
+          if (is_executable($file)) {
+            $mod -= 111;
+          }
+          break;
+      }
+    }
+  }
+
+  if (@chmod($file, intval("$prefix$mod", 8))) {
+    return TRUE;
+  }
+  else {
+    return FALSE;
+  }
+}
+
=== modified file 'includes/module.inc'
--- includes/module.inc	
+++ includes/module.inc	
@@ -47,21 +47,32 @@ function module_list($refresh = FALSE, $
   if ($refresh) {
     unset($sorted_list);
     $list = array();
-    if ($bootstrap) {
-      $result = db_query("SELECT name, filename, throttle, bootstrap FROM {system} WHERE type = 'module' AND status = 1 AND bootstrap = 1 ORDER BY weight ASC, filename ASC");
+    if ($fixed_list = variable_get('module_list'. ($bootstrap ? '_bootstrap' : ''), NULL)) {
+      foreach ($fixed_list as $name => $module) {
+        $throttle = isset($module['throttle']) && $module['throttle'] && (variable_get('throttle_level', 0) > 0);
+        if (!$throttle) {
+          drupal_get_filename('module', $name, $module['filename']);
+          $list[$name] = $name;
+        }
+      }
     }
     else {
-      $result = db_query("SELECT name, filename, throttle, bootstrap FROM {system} WHERE type = 'module' AND status = 1 ORDER BY weight ASC, filename ASC");
-    }
-    while ($module = db_fetch_object($result)) {
-      if (file_exists($module->filename)) {
-        // Determine the current throttle status and see if the module should be
-        // loaded based on server load. We have to directly access the throttle
-        // variables, since throttle.module may not be loaded yet.
-        $throttle = ($module->throttle && variable_get('throttle_level', 0) > 0);
-        if (!$throttle) {
-          drupal_get_filename('module', $module->name, $module->filename);
-          $list[$module->name] = $module->name;
+      if ($bootstrap) {
+        $result = db_query("SELECT name, filename, throttle, bootstrap FROM {system} WHERE type = 'module' AND status = 1 AND bootstrap = 1 ORDER BY weight ASC, filename ASC");
+      }
+      else {
+        $result = db_query("SELECT name, filename, throttle, bootstrap FROM {system} WHERE type = 'module' AND status = 1 ORDER BY weight ASC, filename ASC");
+      }
+      while ($module = db_fetch_object($result)) {
+        if (file_exists($module->filename)) {
+          // Determine the current throttle status and see if the module should be
+          // loaded based on server load. We have to directly access the throttle
+          // variables, since throttle.module may not be loaded yet.
+          $throttle = ($module->throttle && variable_get('throttle_level', 0) > 0);
+          if (!$throttle) {
+            drupal_get_filename('module', $module->name, $module->filename);
+            $list[$module->name] = $module->name;
+          }
         }
       }
     }
=== modified file 'includes/theme.inc'
--- includes/theme.inc	
+++ includes/theme.inc	
@@ -431,7 +431,7 @@ function theme_maintenance_page($content
   $output = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
   $output .= '<html xmlns="http://www.w3.org/1999/xhtml">';
   $output .= '<head>';
-  $output .= ' <title>'. drupal_get_title() .'</title>';
+  $output .= ' <title>'. strip_tags(drupal_get_title()) .'</title>';
   $output .= drupal_get_html_head();
   $output .= theme_get_styles();
   $output .= '</head>';
@@ -453,17 +453,64 @@ function theme_maintenance_page($content
   return $output;
 }
 
+function theme_install_page($content) {
+  drupal_set_header('Content-Type: text/html; charset=utf-8');
+  theme('add_style', 'misc/maintenance.css');
+  drupal_set_html_head('<link rel="shortcut icon" href="'. base_path() .'misc/favicon.ico" type="image/x-icon" />');
+  $output = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
+  $output .= '<html xmlns="http://www.w3.org/1999/xhtml">';
+  $output .= '<head>';
+  $output .= ' <title>'. strip_tags(drupal_get_title()) .'</title>';
+  $output .= drupal_get_html_head();
+  $output .= theme_get_styles();
+  $output .= '</head>';
+  $output .= '<body>';
+  $output .= '<h1>' . drupal_get_title() . '</h1>';
+
+  $messages = drupal_set_message();
+  if (isset($messages['error'])) {
+    $errors = count($messages['error']) > 1 ? 'errors' : 'error';
+    $output .= "<h3>The following $errors must be resolved before you can continue the installation process:</h3>";
+    $output .= theme('status_messages', 'error');
+  }
+
+  $output .= "\n<!-- begin content -->\n";
+  $output .= $content;
+  $output .= "\n<!-- end content -->\n";
+
+  if (isset($messages['status'])) {
+    $warnings = count($messages['status']) > 1 ? 'warnings' : 'warning';
+    $output .= "<h4>The following installation $warnings should be carefully reviewed, but in most cases may be safely ignored:</h4>";
+    $output .= theme('status_messages', 'status');
+  }
+
+  $output .= '</body></html>';
+
+  return $output;
+}
+
 /**
  * Returns themed set of status and/or error messages. The messages are grouped
  * by type.
  *
+ * @param $display
+ *   (optional) Set to 'status' or 'error' to display only messages of that type.
+ *
  * @return
  *   A string containing the messages.
  */
-function theme_status_messages() {
-  if ($data = drupal_get_messages()) {
+function theme_status_messages($display = NULL) {
+  static $data;
+
+  if (!$data) {
+    $data = drupal_get_messages();
+  }
+  if ($data) {
     $output = '';
     foreach ($data as $type => $messages) {
+      if ($display && $display != $type) {
+        continue;
+      }
       $output .= "<div class=\"messages $type\">\n";
       if (count($messages) > 1) {
         $output .= " <ul>\n";
@@ -476,6 +523,7 @@ function theme_status_messages() {
         $output .= $messages[0];
       }
       $output .= "</div>\n";
+      unset($data[$type]);
     }
 
     return $output;
=== modified file 'misc/maintenance.css'
--- misc/maintenance.css	
+++ misc/maintenance.css	
@@ -6,6 +6,7 @@ body {
   border: 1px solid #bbb;
   margin: 3em;
   padding: 1em 1em 1em 128px;
+  line-height: 1.2;
 }
 h1 {
   margin: 1.6em 0 1.1em 0;
@@ -28,8 +29,15 @@ div.messages {
   margin-top: 1em;
 }
 
+div.messages li {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+}
+
 div.error {
+  background: #fdd;
   border: 1px solid #daa;
+  color: #400;
 }
 
 /* Update styles */
=== modified file 'update.php'
--- update.php	
+++ update.php	
@@ -676,6 +676,7 @@ ini_set('display_errors', TRUE);
 // Access check:
 if (($access_check == FALSE) || ($user->uid == 1)) {
 
+  $install = FALSE;
   include_once './includes/install.inc';
 
   update_fix_schema_version();
