Index: modules/update_status/update_status.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/update_status/update_status.module,v
retrieving revision 1.83.2.25
diff -u -p -u -p -r1.83.2.25 update_status.module
--- modules/update_status/update_status.module	11 Jan 2008 07:19:31 -0000	1.83.2.25
+++ modules/update_status/update_status.module	17 Jan 2008 00:57:01 -0000
@@ -626,7 +626,10 @@ function _update_status_no_data() {
  *   Extend this to include themes and theme engines when they get .info files.
  */
 function update_status_get_projects() {
-  $projects = array();
+  static $projects = array();
+  if (!empty($projects)) {
+    return $projects;
+  }
 
   // Get current list of modules.
   $files = drupal_system_listing('\.module$', 'modules', 'name', 0);
@@ -639,13 +642,22 @@ function update_status_get_projects() {
     if (empty($file->status)) {
       continue;
     }
-    $file->info = _module_parse_info_file(dirname($file->filename) .'/'. $file->name .'.info');
+    $info_filename = dirname($file->filename) .'/'. $file->name .'.info';
+    $file->info = _module_parse_info_file($info_filename);
 
     // Skip if this is broken.
     if (empty($file->info)) {
       continue;
     }
 
+    // Record the change time on the .info file itself. Note: we need to use
+    // the ctime, not the mtime (modification time) since many (all?) tar
+    // implementations will go out of their way to set the mtime on the files
+    // it creates to the timestamps recorded in the tarball. We want to see
+    // the last time the file was changed on disk, which is left alone by tar
+    // and correctly set to the time the .info file was unpacked.
+    $file->info['_info_file_ctime'] = filectime($info_filename);
+
     $info = $file->info;
     $info['check'] = TRUE;
 
@@ -1433,11 +1445,27 @@ function _update_status_build_fetch_url(
  */
 function update_status_get_available($refresh = FALSE) {
   $available = array();
-  if (($cache = cache_get('update_status_info', 'cache'))
-       && $cache->expire > time()) {
+
+  // First, make sure that none of the .info files have a change time newer
+  // than the last time we checked for available updates. If something was
+  // changed, it almost certainly means a new version was installed. Without
+  // fresh data, the logic in update_status_calculate_project_data() will be
+  // wrong and produce confusing, bogus results.
+  $needs_refresh = FALSE;
+  $last_check = variable_get('update_status_last', 0);
+  $projects = update_status_get_projects();
+  foreach ($projects as $key => $project) {
+    if ($project['info']['_info_file_ctime'] > $last_check) {
+      $needs_refresh = TRUE;
+      break;
+    }
+  }
+
+  if (!$needs_refresh && ($cache = cache_get('update_status_info', 'cache'))
+      && $cache->expire > time()) {
     $available = unserialize($cache->data);
   }
-  elseif ($refresh) {
+  elseif ($needs_refresh || $refresh) {
     $available = update_status_refresh();
   }
   return $available;
