Index: update.php
===================================================================
RCS file: /cvs/drupal/drupal/update.php,v
retrieving revision 1.190
diff -u -r1.190 update.php
--- update.php	5 Jul 2006 11:45:50 -0000	1.190
+++ update.php	13 Jul 2006 11:09:09 -0000
@@ -363,13 +363,14 @@
 
 function update_update_page() {
   // Set the installed version so updates start at the correct place.
-  $_SESSION['update_remaining'] = array();
+  // Ensure system.module's updates are run first by making it the first element.
+  $_SESSION['update_remaining'] = array('system' => '');
   foreach ($_POST['edit']['start'] as $module => $version) {
     drupal_set_installed_schema_version($module, $version - 1);
     $max_version = max(drupal_get_schema_versions($module));
     if ($version <= $max_version) {
       foreach (range($version, $max_version) as $update) {
-        $_SESSION['update_remaining'][] = array('module' => $module, 'version' => $update);
+        $_SESSION['update_remaining'][$module] = array('module' => $module, 'version' => $update);
       }
     }
   }
@@ -676,6 +677,7 @@
 // Access check:
 if (($access_check == FALSE) || ($user->uid == 1)) {
 
+  $install = FALSE;
   include_once './includes/install.inc';
 
   update_fix_schema_version();
Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.105
diff -u -r1.105 bootstrap.inc
--- includes/bootstrap.inc	10 Jul 2006 18:41:10 -0000	1.105
+++ includes/bootstrap.inc	13 Jul 2006 11:09:10 -0000
@@ -151,9 +151,9 @@
  * 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.
@@ -565,14 +565,21 @@
 /**
  * Return all messages that have been set.
  *
- * As a side effect, this function clears the message queue.
+ * @param $type
+ *   (optional) Only return messages of this type.
  */
-function drupal_get_messages() {
+function drupal_get_messages($type = NULL) {
   if ($messages = drupal_set_message()) {
-    unset($_SESSION['messages']);
+    if ($type) {
+      unset($_SESSION['messages'][$type]);
+      return array($type => $messages[$type]);
+    }
+    else {
+      unset($_SESSION['messages']);
+      return $messages;
+    }
   }
-
-  return $messages;
+  return array();
 }
 
 /**
Index: includes/database.mysql.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.mysql.inc,v
retrieving revision 1.53
diff -u -r1.53 database.mysql.inc
--- includes/database.mysql.inc	24 May 2006 20:46:56 -0000	1.53
+++ includes/database.mysql.inc	13 Jul 2006 11:09:11 -0000
@@ -53,7 +53,8 @@
   if (!$connection) {
     drupal_maintenance_theme();
     drupal_set_title('Unable to connect to database server');
-    print theme('maintenance_page', '<p>This either means that the username and password information in your <code>settings.php</code> file is incorrect or we can\'t contact the MySQL database server. This could mean your hosting provider\'s database server is down.</p>
+    print theme('maintenance_page', '<p>If you still have to install Drupal, proceed to the <a href="'. base_path() .'install.php">installation page</a>.</p>
+<p>If you have already finished installed Drupal, this either means that the username and password information in your <code>settings.php</code> file is incorrect or that we can\'t connect to the MySQL database server. This could mean your hosting provider\'s database server is down.</p>
 <p>The MySQL error was: '. theme('placeholder', mysql_error()) .'.</p>
 <p>Currently, the username is '. theme('placeholder', $url['user']) .' and the database server is '. theme('placeholder', $url['host']) .'.</p>
 <ul>
Index: includes/database.mysqli.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.mysqli.inc,v
retrieving revision 1.18
diff -u -r1.18 database.mysqli.inc
--- includes/database.mysqli.inc	24 May 2006 20:46:56 -0000	1.18
+++ includes/database.mysqli.inc	13 Jul 2006 11:09:11 -0000
@@ -45,7 +45,8 @@
   if (mysqli_connect_errno() >= 2000 || mysqli_connect_errno() == 1045) {
     drupal_maintenance_theme();
     drupal_set_title('Unable to connect to database server');
-    print theme('maintenance_page', '<p>This either means that the username and password information in your <code>settings.php</code> file is incorrect or we can\'t contact the MySQL database server through the mysqli libraries. This could also mean your hosting provider\'s database server is down.</p>
+    print theme('maintenance_page', '<p>If you still have to install Drupal, proceed to the <a href="'. base_path() .'install.php">installation page</a>.</p>
+<p>If you have already finished installed Drupal, this either means that the username and password information in your <code>settings.php</code> file is incorrect or that we can\'t connect to the MySQL database server. This could mean your hosting provider\'s database server is down.</p>
 <p>The MySQL error was: '. theme('placeholder', mysqli_error($connection)) .'.</p>
 <p>Currently, the username is '. theme('placeholder', $url['user']) .' and the database server is '. theme('placeholder', $url['host']) .'.</p>
 <ul>
Index: includes/database.pgsql.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.pgsql.inc,v
retrieving revision 1.30
diff -u -r1.30 database.pgsql.inc
--- includes/database.pgsql.inc	24 May 2006 20:46:56 -0000	1.30
+++ includes/database.pgsql.inc	13 Jul 2006 11:09:11 -0000
@@ -51,7 +51,8 @@
   if (!$connection) {
     drupal_maintenance_theme();
     drupal_set_title('Unable to connect to database');
-    print theme('maintenance_page', '<p>This either means that the database information in your <code>settings.php</code> file is incorrect or we can\'t contact the PostgreSQL database server. This could mean your hosting provider\'s database server is down.</p>
+    print theme('maintenance_page', '<p>If you still have to install Drupal, proceed to the <a href="'. base_path() .'install.php">installation page</a>.</p>
+<p>If you have already finished installed Drupal, this either means that the username and password information in your <code>settings.php</code> file is incorrect or that we can\'t connect to the PostgreSQL database server. This could mean your hosting provider\'s database server is down.</p>
 <p>The PostgreSQL error was: '. theme('placeholder', decode_entities($php_errormsg)) .'</p>
 <p>Currently, the database is '. theme('placeholder', substr($url['path'], 1)) .', the username is '. theme('placeholder', $url['user']) .', and the database server is '. theme('placeholder', $url['host']) .'.</p>
 <ul>
Index: includes/install.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/install.inc,v
retrieving revision 1.6
diff -u -r1.6 install.inc
--- includes/install.inc	11 Apr 2006 11:33:14 -0000	1.6
+++ includes/install.inc	13 Jul 2006 11:09:11 -0000
@@ -4,15 +4,29 @@
 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_EXECUTABLE',     8);
+define('FILE_NOT_EXIST',      16);
+define('FILE_NOT_READABLE',   32);
+define('FILE_NOT_WRITABLE',   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;
+// Initialize the update system if necessary
+if (!$install) {
+  // Include install files for each installed 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 +93,410 @@
 function drupal_set_installed_schema_version($module, $version) {
   db_query("UPDATE {system} SET schema_version = %d WHERE name = '%s'", $version, $module);
 }
+
+/**
+ * Loads the profile definition, extracting the profile's defined name.
+ *
+ * @return
+ *   The name defined in the profile's _profile_details() hook.
+ */
+function drupal_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');
+  }
+}
+
+/**
+ * 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;
+}
+
+/**
+ * Install a 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);
+  }
+}
+
+/**
+ * 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;
+  }
+}
+
+/**
+ * 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));
+}
\ No newline at end of file
Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.78
diff -u -r1.78 module.inc
--- includes/module.inc	28 Jun 2006 21:18:30 -0000	1.78
+++ includes/module.inc	13 Jul 2006 11:09:11 -0000
@@ -37,31 +37,42 @@
  * @param $sort
  *   By default, modules are ordered by weight and filename, settings this option
  *   to TRUE, module list will be ordered by module name.
+ * @param $fixed_list
+ *   (Optional) Override the module list with the given modules. Stays until the
+ *   next call with $refresh = TRUE.
  * @return
  *   An associative array whose keys and values are the names of all loaded
  *   modules.
  */
-function module_list($refresh = FALSE, $bootstrap = TRUE, $sort = FALSE) {
+function module_list($refresh = FALSE, $bootstrap = TRUE, $sort = FALSE, $fixed_list = NULL) {
   static $list, $sorted_list;
 
-  if ($refresh) {
+  if ($refresh || $fixed_list) {
     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) {
+      foreach ($fixed_list as $name => $module) {
+        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;
+          }
         }
       }
     }
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.302
diff -u -r1.302 theme.inc
--- includes/theme.inc	5 Jul 2006 11:45:51 -0000	1.302
+++ includes/theme.inc	13 Jul 2006 11:09:12 -0000
@@ -431,7 +431,7 @@
   $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,33 +453,69 @@
   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
+ * Return a 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()) {
-    $output = '';
-    foreach ($data as $type => $messages) {
-      $output .= "<div class=\"messages $type\">\n";
-      if (count($messages) > 1) {
-        $output .= " <ul>\n";
-        foreach($messages as $message) {
-          $output .= '  <li>'. $message ."</li>\n";
-        }
-        $output .= " </ul>\n";
-      }
-      else {
-        $output .= $messages[0];
+function theme_status_messages($display = NULL) {
+  $output = '';
+  foreach (drupal_get_messages($display) as $type => $messages) {
+    $output .= "<div class=\"messages $type\">\n";
+    if (count($messages) > 1) {
+      $output .= " <ul>\n";
+      foreach($messages as $message) {
+        $output .= '  <li>'. $message ."</li>\n";
       }
-      $output .= "</div>\n";
+      $output .= " </ul>\n";
     }
-
-    return $output;
+    else {
+      $output .= $messages[0];
+    }
+    $output .= "</div>\n";
   }
+  return $output;
 }
 
 /**
Index: misc/maintenance.css
===================================================================
RCS file: /cvs/drupal/drupal/misc/maintenance.css,v
retrieving revision 1.5
diff -u -r1.5 maintenance.css
--- misc/maintenance.css	23 Feb 2006 19:49:42 -0000	1.5
+++ misc/maintenance.css	13 Jul 2006 11:09:12 -0000
@@ -6,6 +6,7 @@
   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 @@
   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 */
