Index: index.php
===================================================================
RCS file: /cvs/drupal/drupal/index.php,v
retrieving revision 1.77
diff -u -r1.77 index.php
--- index.php   16 Dec 2003 21:06:33 -0000      1.77
+++ index.php   23 Feb 2004 20:24:39 -0000
@@ -7,6 +7,11 @@
 
 fix_gpc_magic();
 
+if ($_GET['q'] == "favicon.ico") {
+  include_once "includes/file.inc";
+  drupal_goto(file_miscfile("favicon.ico"));
+}
+
 menu_build("system");
 
 if (menu_active_handler_exists()) {
Index: update.php
===================================================================
RCS file: /cvs/drupal/drupal/update.php,v
retrieving revision 1.135
diff -u -r1.135 update.php
--- update.php  23 Feb 2004 17:45:02 -0000      1.135
+++ update.php  23 Feb 2004 20:24:39 -0000
@@ -711,15 +711,18 @@
 }
 
 function update_page_header($title) {
+  $printfile = file_miscfile("print.css");
+  $cssfile = file_miscfile("drupal.css");
+  $iconfile = file_miscfile("druplicon-small.gif");
   $output = "<html><head><title>$title</title>";
   $output .= <<<EOF
-      <link rel="stylesheet" type="text/css" media="print" href="misc/print.css" />
+      <link rel="stylesheet" type="text/css" media="print" href="$printfile" />
       <style type="text/css" title="layout" media="Screen">
-        @import url("misc/drupal.css");
+        @import url("$cssfile");
       </style>
 EOF;
   $output .= "</head><body>";
-  $output .= "<div id=\"logo\"><a href=\"http://drupal.org/\"><img src=\"misc/druplicon-small.gif\" alt=\"Druplicon - Drupal logo\" title=\"Druplicon - Drupal logo\" /></a></div>";
+  $output .= "<div id=\"logo\"><a href=\"http://drupal.org/\"><img src=\"$iconfile\" alt=\"Druplicon - Drupal logo\" title=\"Druplicon - Drupal logo\" /></a></div>";
   $output .= "<div id=\"update\"><h1>$title</h1>";
   return $output;
 }
Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.11
diff -u -r1.11 bootstrap.inc
--- includes/bootstrap.inc      21 Feb 2004 14:08:07 -0000      1.11
+++ includes/bootstrap.inc      23 Feb 2004 20:24:39 -0000
@@ -4,25 +4,42 @@
 function conf_init() {
 
   /*
-  ** Try finding a matching configuration file by stripping the website's
-  ** URI from left to right.  If no configuration file is found, return a
-  ** default value 'conf'.
+  ** Try finding a matching configuration directory by stripping the
+  ** website's hostname from left to right and pathname from right to
+  ** left.  If no configuration file is found, return a default value
+  ** '$confdir/default'.  Example for a ficticious site installed at
+  ** http://www.drupal.org/test:
+  **
+  ** 1. www.drupal.org.test
+  ** 2. drupal.org.test
+  ** 3. www.drupal.org
+  ** 4. drupal.org
+  ** 5. default
   */
 
-  $uri = $_SERVER["PHP_SELF"];
+  static $conf = "";
 
-  $file = strtolower(strtr($_SERVER["HTTP_HOST"] . substr($uri, 0, strrpos($uri, "/")), "/:", ".."));
+  if ($conf) {
+    return $conf;
+  }
 
-  while (strlen($file) > 4) {
-    if (file_exists("includes/$file.php")) {
-      return $file;
-    }
-    else {
-      $file = substr($file, strpos($file, ".") + 1);
+  $uri = explode("/", $_SERVER["PHP_SELF"]);
+  $server = explode(".", $_SERVER["HTTP_HOST"]);
+  $confdir = "conf";
+
+  for ($i = count($uri) - 1; $i > 0; $i--) {
+    for ($j = count($server); $j > 1; $j--) {
+      $dir = implode(".", array_slice($server, -$j)) . implode(".", array_slice($uri, 0, $i));
+
+      if (file_exists("$confdir/$dir/config.php")) {
+        $conf = "$confdir/$dir";
+        return $conf;
+      }
     }
   }
 
-  return "conf";
+  $conf = "$confdir/default";
+  return $conf;
 }
 
 function variable_init($conf = array()) {
@@ -247,7 +264,7 @@
 unset($conf);
 $config = conf_init();
 
-include_once "includes/$config.php";
+include_once "$config/config.php";
 include_once "includes/database.inc";
 include_once "includes/session.inc";
 include_once "includes/module.inc";
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.326
diff -u -r1.326 common.inc
--- includes/common.inc 23 Feb 2004 07:28:18 -0000      1.326
+++ includes/common.inc 23 Feb 2004 20:24:40 -0000
@@ -110,7 +110,7 @@
   $output = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
   $output .= "<base href=\"$base_url/\" />\n";
   $output .= "<style type=\"text/css\" media=\"all\">\n";
-  $output .= "@import url(misc/drupal.css);\n";
+  $output .= "@import url(" . file_miscfile("drupal.css") . ");\n";
   $output .= "</style>\n";
 
   return $output . drupal_set_html_head();
Index: includes/file.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/file.inc,v
retrieving revision 1.9
diff -u -r1.9 file.inc
--- includes/file.inc   15 Feb 2004 15:40:06 -0000      1.9
+++ includes/file.inc   23 Feb 2004 20:24:40 -0000
@@ -343,8 +343,8 @@
         }
         elseif (ereg($mask, $file)) {
           $name = basename($file);
-          $files["$dir/$file"]->filename = "$dir/$file";
-          $files["$dir/$file"]->name = substr($name, 0, strrpos($name, '.'));
+          $files["$name"]->filename = "$dir/$file";
+          $files["$name"]->name = substr($name, 0, strrpos($name, '.'));
           if ($callback) {
             $callback("$dir/$file");
           }
@@ -356,4 +356,22 @@
   return $files;
 }
 
+/**
+ * Returns the path to a file in either the site-wide or site-specific
+ * misc/ directory.
+ *
+ * @param string $file The file whose path is requested.
+ *
+ * @return string The path to the misc file.
+ */
+function file_miscfile($file) {
+  $config = conf_init();
+
+  if (file_exists("$config/misc/$file")) {
+       return "$config/misc/$file";
+  }
+
+  return "misc/$file";
+}
+
 ?>
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.189
diff -u -r1.189 theme.inc
--- includes/theme.inc  10 Feb 2004 19:28:39 -0000      1.189
+++ includes/theme.inc  23 Feb 2004 20:24:40 -0000
@@ -197,7 +197,7 @@
  * @return a string containing the @a image output.
  */
 function theme_image($name) {
-  return "misc/$name";
+  return file_miscfile($name);
 }
 
 /**
@@ -439,7 +439,8 @@
  * @return a string containing the @a output.
  */
 function theme_xml_icon($url) {
-  return "<div class=\"xml-icon\"><a href=\"$url\"><img src=\"misc/xml.gif\" width=\"36\" height=\"14\" alt=\"". t('XML feed') ."\" /></a></div>";
+  $xmlfile = file_miscfile("xml.gif");
+  return "<div class=\"xml-icon\"><a href=\"$url\"><img src=\"$xmlfile\" width=\"36\" height=\"14\" alt=\"". t('XML feed') ."\" /></a></div>";
 }
 
 /**
Index: modules/book.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/book.module,v
retrieving revision 1.216
diff -u -r1.216 book.module
--- modules/book.module 15 Feb 2004 20:09:46 -0000      1.216
+++ modules/book.module 23 Feb 2004 20:24:40 -0000
@@ -706,7 +706,7 @@
 
   $html = "<html><head><title>$node->title</title>";
   $html .= "<base href=\"$base_url/\" />";
-  $html .= "<style type=\"text/css\">\n@import url(misc/print.css);\n</style>";
+  $html .= "<style type=\"text/css\">\n@import url(" . file_miscfile("print.css") . ");\n</style>";
   $html .= "</head><body>". $output ."</body></html>";
 
   return $html;
Index: modules/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system.module,v
retrieving revision 1.130
diff -u -r1.130 system.module
--- modules/system.module       19 Feb 2004 12:27:33 -0000      1.130
+++ modules/system.module       23 Feb 2004 20:24:40 -0000
@@ -226,28 +226,46 @@
 }
 
 function system_listing($type) {
+  $config = conf_init();
+
   // Pick appropriate directory and filetype
   switch ($type) {
     case "modules":
-      $directory = "modules";
+      $directory[] = "modules";
+
+      if (file_exists("$config/modules")) {
+        $directory[] = "$config/modules";
+      }
+
       $type = "module";
       break;
     case "themes":
     default:
-      $directory = "themes";
+      $directory[] = "themes";
+      
+      if (file_exists("$config/themes")) {
+        $directory[] = "$config/themes";
+      }
+
       $type = "theme";
       break;
   }
 
-  // Find files in the directory.
-  $files = file_scan_directory($directory, "\.$type$");
+  // Find files in the directories.
+  $files = array();
+
+  foreach ($directory as $dir) {
+    $files = array_merge($files, file_scan_directory($dir, "\.$type$"));
+  }
 
   // Extract current files from database.
   $result = db_query("SELECT filename, type, status, throttle FROM {system} WHERE type = '%s'", $type);
   while ($file = db_fetch_object($result)) {
-    if (is_object($files[$file->filename])) {
+    $basename = basename($file->filename);
+    unset($file->filename);
+    if (is_object($files[$basename])) {
       foreach ($file as $key => $value) {
-        $files[$file->filename]->$key = $value;
+        $files[$basename]->$key = $value;
       }
     }
   }
@@ -255,9 +273,9 @@
   ksort($files);
 
   if ($type == "module") {
-    $required = array("modules/admin.module", "modules/filter.module", "modules/system.module", "modules/user.module", "modules/watchdog.module");
+    $required = array("admin.module", "filter.module", "system.module", "user.module", "watchdog.module");
     // the throttle mechanism requires additional modules always be enabled
-    $throttle_required = array_merge($required, array("modules/statistics.module", "modules/throttle.module"));
+    $throttle_required = array_merge($required, array("statistics.module", "throttle.module"));
 
     $header = array(t("name"), t("description"), t("status"), t("throttle"));
   }
@@ -266,8 +284,8 @@
     $header = array(t("name"), t("description"), t("enable"), t("default"));
   }
 
-  foreach ($files as $filename => $file) {
-    include_once($filename);
+  foreach ($files as $basename => $file) {
+    include_once($file->filename);
     if ($type == "module") {
       $info->name = module_invoke($file->name, "help", "admin/system/modules#name") ? module_invoke($file->name, "help", "admin/system/modules#name") : module_invoke($file->name, "system", "name") ? module_invoke($file->name, "system", "name") : $file->name;
       $info->description = module_invoke($file->name, "help", "admin/system/modules#description") ? module_invoke($file->name, "help", "admin/system/modules#description") : module_invoke($file->name, "system", "description");
@@ -292,12 +310,12 @@
     }
 
     // Update the contents of the system table:
-    db_query("DELETE FROM {system} WHERE filename = '%s' AND type = '%s'", $filename, $type);
-    db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $info->name, $info->description, $type, $filename, $file->status, $file->throttle, $bootstrap);
+    db_query("DELETE FROM {system} WHERE name = '%s' AND type = '%s'", $info->name, $type);
+    db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $info->name, $info->description, $type, $file->filename, $file->status, $file->throttle, $bootstrap);
 
-    $row = array($info->name, $info->description, array("data" => (in_array($filename, $required) ? form_hidden("status][$filename", 1) . t("required") : form_checkbox("", "status][$filename", 1, $file->status)), "align" => "center"));
+    $row = array($info->name, $info->description, array("data" => (in_array($basename, $required) ? form_hidden("status][$file->filename", 1) . t("required") : form_checkbox("", "status][$file->filename", 1, $file->status)), "align" => "center"));
     if ($type == "module") {
-      $row[] = array("data" => (in_array($filename, $throttle_required) ? form_hidden("throttle][$filename", 0) . t("required") : form_checkbox(NULL, "throttle][$filename", 1, $file->throttle, NULL, module_exist('throttle') ? NULL : array("disabled" => "disabled"))), "align" => "center");
+      $row[] = array("data" => (in_array($basename, $throttle_required) ? form_hidden("throttle][$file->filename", 0) . t("required") : form_checkbox(NULL, "throttle][$file->filename", 1, $file->throttle, NULL, module_exist('throttle') ? NULL : array("disabled" => "disabled"))), "align" => "center");
     }
     else if ($type == "theme") {
       $row[] = array("data" => form_radio("", "theme_default", $info->name, (variable_get("theme_default",0) == $info->name) ? 1 : 0), "align" => "center");
