Merge branch 'master' of git://github.com/mono/mono
authorCarlos Alberto Cortez <calberto.cortez@gmail.com>
Sun, 25 Jul 2010 21:01:24 +0000 (23:01 +0200)
committerCarlos Alberto Cortez <calberto.cortez@gmail.com>
Sun, 25 Jul 2010 21:01:24 +0000 (23:01 +0200)
mcs/class/corlib/Microsoft.Win32/ChangeLog
mcs/class/corlib/Microsoft.Win32/UnixRegistryApi.cs

index 446ec74958cd2612fd9ff847d9be353a3ee4f49f..272e0317446a3137b97dcff4af46f44b4879c71e 100644 (file)
@@ -1,3 +1,10 @@
+2010-07-25  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * UnixRegistryApi.cs: From the static ctor of KeyHandler remove the
+       volatile keys directory if the last registered boot time has changed.
+       This way we *actually* have our volatile keys removed if the system as
+       rebooted.
+
 2010-07-19  Carlos Alberto Cortez <calberto.cortez@gmail.com>
 
        * UnixRegistryApi.cs: Remove the in-memmory approach to volatile keys,
index 8c572ced8f79177baa326e79423fe3f806b8b6d4..6d8362776cbd0f823f8c52787a6efdd0a951770e 100644 (file)
@@ -106,6 +106,11 @@ namespace Microsoft.Win32 {
                string file;
                bool dirty;
 
+               static KeyHandler ()
+               {
+                       CleanVolatileKeys ();
+               }
+
                KeyHandler (RegistryKey rkey, string basedir) : this (rkey, basedir, false)
                {
                }
@@ -260,7 +265,100 @@ namespace Microsoft.Win32 {
                        
                        return String.Concat (rkey.Name, "\\", extra);
                }
-                               
+
+               static long GetSystemBootTime ()
+               {
+                       if (!File.Exists ("/proc/stat"))
+                               return -1;
+
+                       string btime = null;
+                       string line;
+
+                       try {
+                               using (StreamReader stat_file = new StreamReader ("/proc/stat", Encoding.ASCII)) {
+                                       while ((line = stat_file.ReadLine ()) != null)
+                                               if (line.StartsWith ("btime")) {
+                                                       btime = line;
+                                                       break;
+                                               }
+                               }
+                       } catch (Exception e) {
+                               Console.Error.WriteLine ("While reading system info {0}", e);
+                       }
+
+                       if (btime == null)
+                               return -1;
+
+                       int space = btime.IndexOf (' ');
+                       long res;
+                       if (!Int64.TryParse (btime.Substring (space, btime.Length - space), out res))
+                               return -1;
+
+                       return res;
+               }
+
+               // The registered boot time it's a simple line containing the last system btime.
+               static long GetRegisteredBootTime (string path)
+               {
+                       if (!File.Exists (path))
+                               return -1;
+
+                       string line = null;
+                       try {
+                               using (StreamReader reader = new StreamReader (path, Encoding.ASCII))
+                                       line = reader.ReadLine ();
+                       } catch (Exception e) {
+                               Console.Error.WriteLine ("While reading registry data at {0}: {1}", path, e);
+                       }
+
+                       if (line == null)
+                               return -1;
+
+                       long res;
+                       if (!Int64.TryParse (line, out res))
+                               return -1;
+
+                       return res;
+               }
+
+               static void SaveRegisteredBootTime (string path, long btime)
+               {
+                       try {
+                               using (StreamWriter writer = new StreamWriter (path, false, Encoding.ASCII))
+                                       writer.WriteLine (btime.ToString ());
+                       } catch (Exception e) {
+                               Console.Error.WriteLine ("While saving registry data at {0}: {1}", path, e);
+                       }
+               }
+                       
+               // We save the last boot time in a last-btime file in every root, and we use it
+               // to clean the volatile keys directory in case the system btime changed.
+               static void CleanVolatileKeys ()
+               {
+                       long system_btime = GetSystemBootTime ();
+
+                       string [] roots = new string [] {
+                               UserStore,
+                               MachineStore
+                       };
+
+                       foreach (string root in roots) {
+                               if (!Directory.Exists (root))
+                                       continue;
+
+                               string btime_file = Path.Combine (root, "last-btime");
+                               string volatile_dir = Path.Combine (root, VolatileDirectoryName);
+
+                               if (Directory.Exists (volatile_dir)) {
+                                       long registered_btime = GetRegisteredBootTime (btime_file);
+                                       if (system_btime < 0 || registered_btime < 0 || registered_btime != system_btime)
+                                               Directory.Delete (volatile_dir, true);
+                               }
+
+                               SaveRegisteredBootTime (btime_file, system_btime);
+                       }
+               }
+       
                public static bool VolatileKeyExists (string dir)
                {
                        lock (typeof (KeyHandler)) {