2 // FileAttributesStore_ExtendedAttribute.cs
4 // Copyright (C) 2004 Novell, Inc.
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
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
;
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
)
68 tmp
= ExtendedAttribute
.Get (path
, fingerprint_attr
);
70 || int.Parse (tmp
.Substring (0, 2)) != EA_VERSION
71 || (index_fingerprint
!= null && tmp
.Substring (3) != index_fingerprint
))
74 FileAttributes attr
= new FileAttributes ();
76 string uid_str
= ExtendedAttribute
.Get (path
, unique_id_attr
);
77 attr
.UniqueId
= GuidFu
.FromShortString (uid_str
);
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
);
86 attr
.FilterVersion
= int.Parse (tmp
.Substring (0, 3));
87 attr
.FilterName
= tmp
.Substring (4);
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.
100 public bool Write (FileAttributes attr
)
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
;
116 what_we_just_wrote
= ExtendedAttribute
.Get (attr
.Path
, fingerprint_attr
);
117 } catch (Exception ex
) {
120 if (what_we_just_wrote
!= tmp
)
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
));
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);
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.
152 public void Drop (string path
)
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 ()