diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 9159f71..e4add0b 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -2400,6 +2400,8 @@ function install_check_requirements($install_state) {
     $default_settings_file = './sites/default/default.settings.php';
     $file = $conf_path;
     $exists = FALSE;
+    $settings_md5 = @md5_file($settings_file);
+
     // Verify that the directory exists.
     if (drupal_verify_install_file($conf_path, FILE_EXIST, 'dir')) {
       // Check if a settings.php file already exists.
@@ -2419,12 +2421,19 @@ function install_check_requirements($install_state) {
         'title'       => t('Default settings file'),
         'value'       => t('The default settings file does not exist.'),
         'severity'    => REQUIREMENT_ERROR,
+        // TODO: We're probably overselling ourselves with this message.
         'description' => t('The @drupal installer requires that the %default-file file not be modified in any way from the original download.', array('@drupal' => drupal_install_profile_distribution_name(), '%default-file' => $default_settings_file)),
       );
     }
-    // Otherwise, if settings.php does not exist yet, we can try to copy
-    // default.settings.php to create it.
-    elseif (!$exists) {
+    // Otherwise, if settings.php does not exist yet, or if it's empty, we can
+    // try to copy default.settings.php to create it.  We could use
+    // file_get_contents() or stat() to check length, but it uses essentially
+    // zero memory to compare it with the known magic value for an empty file,
+    // so we do that, instead.  This also allows us to reuse the MD5 later for
+    // comparison with default.settings.php, if necessary.
+    elseif (!$exists || $settings_md5 == 'd41d8cd98f00b204e9800998ecf8427e') {
+      // TODO: Copy default.settings.php when settings.php is writable but the
+      // containing directory is not.
       $copied = drupal_verify_install_file($conf_path, FILE_EXIST|FILE_WRITABLE, 'dir') && @copy($default_settings_file, $settings_file);
       if ($copied) {
         // If the new settings file has the same owner as default.settings.php,
@@ -2466,6 +2475,9 @@ function install_check_requirements($install_state) {
           }
         }
       }
+      // We've potentially mucked about; let's make sure this variable is still
+      // accurate.
+      $settings_md5 = @md5_file($settings_file);
     }
 
     // If settings.php does not exist, throw an error.
@@ -2482,6 +2494,19 @@ function install_check_requirements($install_state) {
         'title'       => t('Settings file'),
         'value'       => t('The %file file exists.', array('%file' => $file)),
       );
+      // If we cannot read the default settings file, that disables this check.
+      // If that's unacceptable, the alternatives are to alert the user that we
+      // can't read the default settings file (which seems at least one level of
+      // indirection away from a reasonable alert), or hardcode the MD5 of the
+      // default settings file.
+      if (file_exists($default_settings_file) && @md5_file($default_settings_file) != $settings_md5) {
+        $requirements['settings file exists'] = array(
+          'title'       => t('Settings file'),
+          'value'       => t('%file does not match %default_file', array('%file' => $file, '%default_file' => $default_settings_file)),
+          'severity'    => REQUIREMENT_WARNING,
+          'description' => t('The %file file exists, but is not an exact copy of the %default_file file.  This is usually a good thing, because it means your settings.php file is preconfigured.  However, it could also mean that you have a corrupted settings.php file (e.g. due to different line endings, or just plain corruption).  If the installation fails, you should sanity-check %file before attempting the installation again.', array('%file' => $file, '%default_file' => $default_settings_file)),
+        );
+      }
       // If settings.php is not readable, throw an error.
       if (!$readable) {
         $requirements['settings file readable'] = array(
@@ -2546,9 +2571,16 @@ function install_display_requirements($install_state, $requirements) {
   // and indicating a desire to continue anyway. See drupal_requirements_url().
   if ($severity == REQUIREMENT_ERROR || ($severity == REQUIREMENT_WARNING && empty($install_state['parameters']['continue']))) {
     if ($install_state['interactive']) {
-      drupal_set_title(t('Requirements problem'));
       $status_report = theme('status_report', array('requirements' => $requirements));
-      $status_report .= t('Check the messages and <a href="!url">try again</a>.', array('!url' => check_url(drupal_requirements_url($severity))));
+      if ( $severity == REQUIREMENT_WARNING ) {
+        drupal_set_title(t('Requirements review'));
+        $status_report .= t('Check the messages and <a href="!retry">retry</a>, or you may choose to <a href="!cont">continue anyway</a>.', array('!retry' => check_url(drupal_requirements_url(REQUIREMENT_ERROR)), '!cont' => check_url(drupal_requirements_url($severity))));
+      }
+      else
+      {
+        drupal_set_title(t('Requirements problem'));
+        $status_report .= t('Check the messages and <a href="!url">try again</a>.', array('!url' => check_url(drupal_requirements_url($severity))));
+      }
       return $status_report;
     }
     else {
