diff -upNr ./includes/bootstrap.inc /home/joshua/public_html/d7/includes/bootstrap.inc
--- ./includes/bootstrap.inc	2009-08-06 22:45:49.740609377 -0500
+++ /home/joshua/public_html/d7/includes/bootstrap.inc	2009-08-06 17:04:35.938289481 -0500
@@ -1585,6 +1585,13 @@ function drupal_installation_attempted()
 }
 
 /**
+ * Return TRUE if a Drupal recovery is being attempted.
+ */
+function drupal_recovery_attempted() {
+  return defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'recovery';
+}
+
+/**
  * Return the name of the localization function. Use in code that needs to
  * run both during installation and normal operation.
  */
diff -upNr ./includes/module.inc /home/joshua/public_html/d7/includes/module.inc
--- ./includes/module.inc	2009-08-05 11:16:41.000000000 -0500
+++ /home/joshua/public_html/d7/includes/module.inc	2009-08-06 17:05:08.516198684 -0500
@@ -299,8 +299,12 @@ function module_disable($module_list) {
         node_access_needs_rebuild(TRUE);
       }
 
-      module_load_install($module);
-      module_invoke($module, 'disable');
+      // If a recovery is in place we can assume this failed in the past.
+      if (!drupal_recovery_attempted()) {
+        module_load_install($module);
+        module_invoke($module, 'disable');
+      }
+
       db_update('system')
         ->fields(array('status' => 0))
         ->condition('type', 'module')
diff -upNr ./modules/system/system.admin.inc /home/joshua/public_html/d7/modules/system/system.admin.inc
--- ./modules/system/system.admin.inc	2009-08-05 14:40:55.000000000 -0500
+++ /home/joshua/public_html/d7/modules/system/system.admin.inc	2009-08-06 20:44:03.573635104 -0500
@@ -299,7 +299,8 @@ function system_themes_form_submit($form
   menu_rebuild();
   drupal_theme_rebuild();
   drupal_set_message(t('The configuration options have been saved.'));
-  $form_state['redirect'] = 'admin/appearance';
+
+  $form_state['redirect'] = drupal_recovery_attempted() ? 'recovery.php' : 'admin/appearance';
 
   // Notify locale module about new themes being enabled, so translations can
   // be imported. This might start a batch, and only return to the redirect
@@ -607,6 +608,12 @@ function system_modules($form_state = ar
   foreach ($files as $filename => $module) {
     $extra = array();
     $extra['enabled'] = (bool) $module->status;
+
+    // Users don't need to be able to enable modules from the recovery console.
+    if (!$extra['enabled'] && drupal_recovery_attempted()) {
+      continue;
+    }
+
     // If this module requires other modules, add them to the array.
     foreach ($module->requires as $requires => $v) {
       if (!isset($files[$requires])) {
@@ -686,6 +693,12 @@ function system_modules($form_state = ar
   );
   $form['#action'] = url('admin/structure/modules/list/confirm');
 
+  // Since modules get loaded during the validation step, validating could
+  // cause even the recovery console to be unable to remove a stubborn module.
+  if (drupal_recovery_attempted()) {
+    $form['#action'] = 'recovery.php';
+//    $form['#submit'] = 'system_modules_submit';
+  }
   return $form;
 }
 
@@ -957,6 +970,9 @@ function system_modules_submit($form, &$
   drupal_clear_js_cache();
 
   $form_state['redirect'] = 'admin/structure/modules';
+  if (drupal_recovery_attempted()) {
+    $form_state['redirect'] = 'recovery.php';
+  }
 
   // Notify locale module about module changes, so translations can be
   // imported. This might start a batch, and only return to the redirect
@@ -2207,12 +2223,21 @@ function theme_system_themes_form($form)
     $row[] = array('data' => $status, 'align' => 'center');
     if ($form['theme_default']) {
       $row[] = array('data' => drupal_render($form['theme_default'][$key]), 'align' => 'center');
-      $row[] = array('data' => drupal_render($form[$key]['operations']), 'align' => 'center');
+      if (!drupal_recovery_attempted()) {
+        $row[] = array('data' => drupal_render($form[$key]['operations']), 'align' => 'center');
+      }
+      else {
+        unset($form[$key]['operations']);
+      }
     }
     $rows[] = $row;
   }
 
-  $header = array(t('Screenshot'), t('Name'), t('Version'), t('Enabled'), t('Default'), t('Operations'));
+  $header = array(t('Screenshot'), t('Name'), t('Version'), t('Enabled'), t('Default'));
+  if (!defined('MAINTENANCE_MODE')) {
+    $header[] = t('Operations');
+  }
+
   $output = theme('table', $header, $rows);
   $output .= drupal_render_children($form);
   return $output;
diff -upNr ./modules/user/user.module /home/joshua/public_html/d7/modules/user/user.module
--- ./modules/user/user.module	2009-08-06 00:06:00.000000000 -0500
+++ /home/joshua/public_html/d7/modules/user/user.module	2009-08-06 17:07:35.238683932 -0500
@@ -1702,7 +1702,7 @@ function user_login_submit($form, &$form
   $user = user_load($form_state['uid']);
   user_login_finalize();
 
-  $form_state['redirect'] = 'user/' . $user->uid;
+  $form_state['redirect'] = drupal_recovery_attempted() ? 'recovery.php' : 'user/' . $user->uid;
 }
 
 /**
diff -upNr ./recovery.php /home/joshua/public_html/d7/recovery.php
--- /dev/null	1969-12-31 18:00:00.000000000 -0600
+++ ./recovery.php	2009-08-06 22:48:31.490586888 -0500
@@ -0,0 +1,101 @@
+<?php
+// $Id$
+
+/**
+ * Root directory of Drupal installation.
+ */
+define('DRUPAL_ROOT', getcwd());
+
+/**
+ * @file
+ * Administrative page that allows for the recovery of a damaged drupal site.
+ *
+ * Point your browser to "http://www.example.com/recover.php" and follow the
+ * instructions.
+ */
+
+/**
+ * Global flag to identify update.php run, and so avoid various unwanted
+ * operations, such as hook_init() and hook_exit() invokes, css/js preprocessing
+ * and translation, and solve some theming issues. This flag is checked on several
+ * places in Drupal code (not just update.php).
+ */
+define('MAINTENANCE_MODE', 'recovery');
+
+/**
+ * Display information explaining how to login to the recovery console
+ */
+function recovery_login_page() {
+  return '<p>In order to recover Drupal, you must be logged in as the admin user (the first user you created). You can use the form below.  If you cannot log in you will have to edit <code>settings.php</code> to bypass this access check. To do this:</p>
+<ol>
+ <li>With a text editor find the settings.php file on your system. From the main Drupal directory that you installed all the files into, go to <code>sites/your_site_name</code> if such directory exists, or else to <code>sites/default</code> which applies otherwise.</li>
+ <li>There is a line inside your settings.php file that says <code>$update_free_access = FALSE;</code>. Change it to <code>$update_free_access = TRUE;</code>.</li>
+ <li>As soon as the recover.php script is done, you must change the settings.php file back to its original form with <code>$update_free_access = FALSE;</code>.</li>
+</ol>';
+}
+
+/**
+ * Display instructions to UID 1.
+ */
+function recovery_instruction_page() {
+  return '<p>Before you continue, please keep this in mind: The recovery console is not meant for day to day maintainence.  It is only meant to be used to deactivate modules or themes which cripple a Drupal installation.</p>';
+}
+
+/**
+ * Display information form the module page.
+ */
+function recovery_module_page() {
+  return '<p>This form is designed to be used when all other attempts have failed.  To make sure that this does not fail, no part of the module is loaded.  Thus, any hooks which would normally run when disabling a module will not be run.</p><p>Also, since this form is designed for <b>removing</b> defective modules, modules which are inactive will not be displayed.</p>';
+}
+
+/* Begin Recovery Section */
+
+// Boot the core of Drupal without loading any unneccessary modules.
+require DRUPAL_ROOT . '/includes/bootstrap.inc';
+drupal_bootstrap(DRUPAL_BOOTSTRAP_CORE);
+foreach (array('system', 'filter', 'user', 'node', 'field') AS $module) {
+  drupal_load('module', $module);
+}
+drupal_maintenance_theme();
+
+// Decide which page to send us to.
+$recovery_access_allowed = !empty($update_free_access) || $user->uid == 1;
+if (!$recovery_access_allowed) {
+
+  // If we aren't authorized to use the console, give a login prompt.
+  drupal_set_title('Recovery Login');
+  $user = drupal_anonymous_user();
+  $output = recovery_login_page();
+  $output .= drupal_render(drupal_get_form('user_login'));
+}
+elseif (empty($_GET['op']) && empty($_POST)) {
+
+  // If we are authorized but haven't specified a page, show the instructions.
+  drupal_set_title('Recovery Instructions');
+  $output  = recovery_instruction_page();
+  $output .= '<p>' . l(t('Module recovery.'), 'recovery.php', array('query' => 'op=modules')) . '</p>';
+  $output .= '<p>' . l(t('Theme recovery.'), 'recovery.php', array('query' => 'op=theme')) . '</p>';
+}
+elseif (empty($_GET['op'])) {
+
+  // Data is being submitted from the modules page.
+  drupal_render(drupal_get_form('system_modules'));
+}
+elseif ($_GET['op'] == 'modules') {
+
+  // Allow for a chance to remove modules.
+  drupal_set_title('Module recovery');
+  $output  = recovery_module_page();
+  $output .= '<p>' . l(t('Return to the instructions.'), 'recovery.php') . '</p>';
+  $output .= drupal_render(drupal_get_form('system_modules'));
+}
+else {
+
+  // Allow the user to change themes.
+  $output = '<p>' . l(t('Return to the instructions.'), 'recovery.php') . '</p>';
+  $output .= drupal_render(drupal_get_form('system_themes_form'));
+}
+
+print theme('update_page', $output);
+exit(0);
+
