Index: cacherouter/engines/file.php
===================================================================
--- cacherouter/engines/file.php	(revision 2167)
+++ cacherouter/engines/file.php	(revision 2223)
@@ -3,6 +3,7 @@
 class fileCache extends Cache {
   var $content = array();
   var $fspath = '/tmp/filecache';
+  var $msft_invalid_file_characters = array('?','*','/','\\',':',';','<','>');
   
   function page_fast_cache() {
     return $this->fast_cache;
@@ -99,8 +100,12 @@
         fclose($fp);
       }
       else {
-        // t() may not be loaded
-        drupal_set_message(strtr('Cache write error, failed to open file "%file"', array('%file' => $file)), 'error');
+        if (function_exists('user_access') && user_access('administer site')) {
+          // t() might not be loaded
+          drupal_set_message(strtr('Cache write error, failed to open file "%file"', array('%file' => $file)), 'error');
+        }
+        // We can assume watchdog is available since we we're in the 'set' function and to get here they should have a db?
+        watchdog('cache', 'Cache write error, failed to open file "%file"', array('%file' => $file), WATCHDOG_WARNING);
       }
     }
   }
@@ -110,8 +115,10 @@
     if (strrpos($key, '*')) {
       $look_for = explode('*', $key);
       $fspath = $this->fspath;
+      //Remove those characters that MSFT hates.
+      $appendix = str_replace($this->msft_invalid_file_characters, '-', $look_for[0]);
       // Filename: abcdef12345verylongmd5code--content:123456:987654
-      $files = file_scan_directory($fspath, ".--$look_for[0].", array('.', '..', 'CVS'));
+      $files = file_scan_directory($fspath, ".--$appendix.");
       foreach ($files as $file) {
         if ($fp = fopen($file->filename, 'w')) {
           // only delete the cache file once we obtain an exclusive lock to prevent
@@ -156,13 +163,26 @@
   function key($key) {
     $table = $this->name;
     $fspath = $this->fspath;
+
+    // Make sure we have a good filename when we concatentate $hash with $appendix:
+    // * Can't be over 255 bytes (ext2, 3, 4) or 255 characters (NTFS, FAT) as per 
+    //  http://en.wikipedia.org/wiki/Comparison_of_file_systems#Limits
+    // * Can't include "? * / \ : ; < >" in NTFS and FAT as per 
+    //  http://technet.microsoft.com/en-us/library/cc722482.aspx
     $hash = md5($key);
-    // TODO make sure we always get valid filenames in the appendix
-    $appendix = str_replace(array('/'), array('-'), $key);
+    //Remove those characters that MSFT hates.
+    $appendix = str_replace($this->msft_invalid_file_characters, '-', $key);
+    $filename = $hash . '--' . $appendix;
+    if (function_exists('mb_substr')) {
+      $filename = mb_substr($filename, 0, 255, '8bit');
+    } else {
+      // We'll have to assume we're working with ASCII if mb_ extension isn't installed.
+      $filename = substr($filename, 0, 255);
+    }
     
     $this->create_directory($fspath, $hash{0});
     
-    return  "$fspath/$table/". $hash{0}. '/'. $hash. '--'. $appendix;
+    return "$fspath/$table/" . $hash{0} . '/' . $filename;
   }
   
   /**
@@ -196,7 +216,7 @@
 
   function purge($dir) {
     global $cache_lifetime;
-    $files = file_scan_directory($dir, '.', array('.', '..', 'CVS'));
+    $files = file_scan_directory($dir, '.');
     foreach ($files as $file) {
       if (filemtime($file->filename) < (time() - $cache_lifetime)) {
         if ($fp = fopen($file->filename, 'r')) {
