Compute lucene-style scores for our hits.
[beagle.git] / Util / ExtendedAttribute.cs
blobb39e916f425fcb54e000e69939ddc9cd37ff4bff
1 //
2 // ExtendedAttribute.cs
3 //
4 // Copyright (C) 2004 Novell, Inc.
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all 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
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
27 // FIXME: This is not portable to Win32
29 using System;
30 using System.IO;
31 using System.Text;
32 using System.Runtime.InteropServices;
33 using Mono.Posix;
35 namespace Beagle.Util {
37 public class ExtendedAttribute {
39 // FIXME: Once Mono 1.1/1.2 is required, we should start using the
40 // xattr bindings which are now present in the Mono.Unix.Syscall class.
41 // The interface provided via Syscall in future Mono versions will support both
42 // Linux/FreeBSD attributes transparently.
44 // Linux xattrs
45 [DllImport (ExternalStringsHack.XattrLib, SetLastError=true)]
46 static extern int lsetxattr (string path, string name, byte[] value, uint size, int flags);
48 [DllImport (ExternalStringsHack.XattrLib, SetLastError=true)]
49 static extern int lgetxattr (string path, string name, byte[] value, uint size);
51 [DllImport (ExternalStringsHack.XattrLib, SetLastError=true)]
52 static extern int lremovexattr (string path, string name);
54 // FreeBSD extattrs
55 // Very similar to Linux xattrs, but the namespace is provided as a
56 // parameter as opposed to a string prefix to the name.
57 [DllImport (ExternalStringsHack.XattrLib, SetLastError=true)]
58 static extern int extattr_set_link (string path, int attrnamespace, string attrname, byte[] value, uint size);
60 [DllImport (ExternalStringsHack.XattrLib, SetLastError=true)]
61 static extern int extattr_get_link (string path, int attrnamespace, string attrname, byte[] value, uint size);
63 [DllImport (ExternalStringsHack.XattrLib, SetLastError=true)]
64 static extern int extattr_delete_link (string path, int attrnamespace, string attrname);
66 private static string AddPrefix (string name)
68 #if OS_LINUX
69 return "user.Beagle." + name;
70 #elif OS_FREEBSD
71 return "Beagle." + name;
72 #endif
75 static Encoding encoding = new UTF8Encoding ();
77 public static void Set (string path, string name, string value)
79 if (! FileSystem.Exists (path))
80 throw new IOException (path);
82 name = AddPrefix (name);
84 byte[] buffer = encoding.GetBytes (value);
85 #if OS_LINUX
86 int retval = lsetxattr (path, name, buffer, (uint) buffer.Length, 0);
87 #elif OS_FREEBSD
88 int retval = extattr_set_link (path, 1, name, buffer, (uint) buffer.Length);
89 #endif
90 if (retval == -1)
91 throw new IOException ("Could not set extended attribute on " + path + ": " + Syscall.strerror (Marshal.GetLastWin32Error ()));
94 public static bool Exists (string path, string name)
96 if (! FileSystem.Exists (path))
97 throw new IOException (path);
99 name = AddPrefix (name);
101 byte[] buffer = null;
102 #if OS_LINUX
103 int size = lgetxattr (path, name, buffer, 0);
104 #elif OS_FREEBSD
105 int size = extattr_get_link (path, 1, name, buffer, 0);
106 #endif
108 return size <= 0;
111 public static string Get (string path, string name)
113 if (! FileSystem.Exists (path))
114 throw new IOException (path);
116 name = AddPrefix (name);
118 byte[] buffer = null;
119 #if OS_LINUX
120 int size = lgetxattr (path, name, buffer, 0);
121 #elif OS_FREEBSD
122 int size = extattr_get_link (path, 1, name, buffer, 0);
123 #endif
124 if (size <= 0)
125 return null;
126 buffer = new byte [size];
127 #if OS_LINUX
128 int retval = lgetxattr (path, name, buffer, (uint) size);
129 #elif OS_FREEBSD
130 int retval = extattr_get_link (path, 1, name, buffer, (uint) size);
131 #endif
132 if (retval < 0)
133 throw new IOException ("Could not get extended attribute on " + path + ": " + Syscall.strerror (Marshal.GetLastWin32Error ()));
135 return encoding.GetString (buffer);
138 public static void Remove (string path, string name)
140 if (! FileSystem.Exists (path))
141 throw new IOException (path);
143 name = AddPrefix (name);
145 #if OS_LINUX
146 int retval = lremovexattr (path, name);
147 #elif OS_FREEBSD
148 int retval = extattr_delete_link (path, 1, name);
149 #endif
150 if (retval != 0)
151 throw new IOException ("Could not remove extended attribute on " + path + ": " + Syscall.strerror (Marshal.GetLastWin32Error ()));
154 // Check to see if it is possible to get and set attributes on a given file.
155 public static bool Test (string path)
157 const string test_key = "__test_key__";
158 const string test_value = "__test_value__";
160 try {
161 Set (path, test_key, test_value);
162 if (Get (path, test_key) != test_value)
163 return false;
164 Remove (path, test_key);
165 return Get (path, test_key) == null;
167 } catch (Exception ex) {
168 return false;
172 private static bool ea_support_tested = false;
173 private static bool ea_supported = false;
175 public static bool Supported {
176 get {
177 if (ea_support_tested)
178 return ea_supported;
180 ea_supported = Test (PathFinder.HomeDir);
181 ea_support_tested = true;
183 return ea_supported;