Fix a fd leak in knotes backend (stupid me) and some cleanup in kaddrbook backend.
[beagle.git] / beagled / FileAttributesStore_ExtendedAttribute.cs
blob1958c604a876d28f114cf7c1bc2913b353ad9076
1 //
2 // FileAttributesStore_ExtendedAttribute.cs
3 //
4 // Copyright (C) 2004 Novell, Inc.
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
27 using System;
28 using System.IO;
30 using Beagle.Util;
32 namespace Beagle.Daemon {
34 public class FileAttributesStore_ExtendedAttribute : IFileAttributesStore {
36 public static bool Disable = false;
38 private string index_fingerprint;
40 public FileAttributesStore_ExtendedAttribute (string index_fingerprint)
42 this.index_fingerprint = index_fingerprint;
45 // Version history:
46 // 1: Original
47 // 2: Replace LastIndexedTime with LastAttrTime
48 const int EA_VERSION = 2;
50 // FIXME: We should probably serialize the data into a lump and attach
51 // it to just one EA. The current method has an inherent race condition:
52 // if the file changes out from under us mid-Read or mid-Write, all sorts
53 // of weirdness could ensue.
55 const string fingerprint_attr = "Fingerprint";
56 const string unique_id_attr = "Uid";
57 const string last_mtime_attr = "MTime";
58 const string last_attrtime_attr = "AttrTime";
59 const string filter_attr = "Filter";
61 public FileAttributes Read (string path)
63 if (Disable)
64 return null;
66 try {
67 string tmp;
68 tmp = ExtendedAttribute.Get (path, fingerprint_attr);
69 if (tmp == null
70 || int.Parse (tmp.Substring (0, 2)) != EA_VERSION
71 || (index_fingerprint != null && tmp.Substring (3) != index_fingerprint))
72 return null;
74 FileAttributes attr = new FileAttributes ();
76 string uid_str = ExtendedAttribute.Get (path, unique_id_attr);
77 attr.UniqueId = GuidFu.FromShortString (uid_str);
79 attr.Path = path;
80 attr.LastWriteTime = StringFu.StringToDateTime (ExtendedAttribute.Get (path, last_mtime_attr));
82 attr.LastAttrTime = StringFu.StringToDateTime (ExtendedAttribute.Get (path, last_attrtime_attr));
84 tmp = ExtendedAttribute.Get (path, filter_attr);
85 if (tmp != null) {
86 attr.FilterVersion = int.Parse (tmp.Substring (0, 3));
87 attr.FilterName = tmp.Substring (4);
90 return attr;
92 } catch (Exception e) {
93 //Logger.Log.Debug ("Caught exception reading EAs from {0}", path);
94 //Logger.Log.Debug (e);
95 // FIXME: Do something smarter with the exception.
96 return null;
100 public bool Write (FileAttributes attr)
102 if (Disable)
103 return false;
105 try {
106 string tmp;
108 tmp = String.Format ("{0:00} {1}", EA_VERSION, index_fingerprint);
109 ExtendedAttribute.Set (attr.Path, fingerprint_attr, tmp);
111 // Try to read the EA we just set. If we
112 // can't, they won't be much use to us --- so
113 // just return false.
114 string what_we_just_wrote;
115 try {
116 what_we_just_wrote = ExtendedAttribute.Get (attr.Path, fingerprint_attr);
117 } catch (Exception ex) {
118 return false;
120 if (what_we_just_wrote != tmp)
121 return false;
123 ExtendedAttribute.Set (attr.Path, unique_id_attr, GuidFu.ToShortString (attr.UniqueId));
124 ExtendedAttribute.Set (attr.Path, last_mtime_attr,
125 StringFu.DateTimeToString (attr.LastWriteTime));
127 if (attr.HasFilterInfo) {
128 tmp = String.Format ("{0:000} {1}", attr.FilterVersion, attr.FilterName);
129 ExtendedAttribute.Set (attr.Path, filter_attr, tmp);
132 // This has to be the last thing we write out, to get LastAttrTime as close
133 // to the ctime as possible.
134 attr.LastAttrTime = DateTime.UtcNow;
135 ExtendedAttribute.Set (attr.Path, last_attrtime_attr,
136 StringFu.DateTimeToString (attr.LastAttrTime));
138 return true;
139 } catch (IOException e) {
140 // An IOException here probably means that we don't have the right
141 // permissions to set the EAs. We just fail silently and return false rather
142 // than spewing a bunch of scary exceptions.
143 //Logger.Log.Debug (e);
144 return false;
145 } catch (Exception e) {
146 Logger.Log.Debug (e, "Caught exception writing EAs to {0}", attr.Path);
147 // FIXME: Do something smarter with the exception.
148 return false;
152 public void Drop (string path)
154 if (Disable)
155 return;
157 try {
158 ExtendedAttribute.Remove (path, fingerprint_attr);
159 ExtendedAttribute.Remove (path, unique_id_attr);
160 ExtendedAttribute.Remove (path, last_mtime_attr);
161 ExtendedAttribute.Remove (path, last_attrtime_attr);
162 ExtendedAttribute.Remove (path, filter_attr);
164 } catch (Exception e) {
165 // FIXME: Do something smarter with the exception.
169 // There are no transactions for EAs
171 public void BeginTransaction ()
174 public void CommitTransaction ()